Merge branch 'main' into research/mingw-w64-alpine

This commit is contained in:
2026-08-06 22:31:24 +00:00
4 changed files with 52 additions and 194 deletions
+10 -6
View File
@@ -9,9 +9,9 @@ on:
inputs: inputs:
godot_version: godot_version:
description: >- description: >-
Godot version to (re)build, e.g. 4.7.1 — must exist as a Godot version to (re)build, e.g. 4.7.1 — must exist as a stable release at
barichello/godot-ci tag (https://hub.docker.com/r/barichello/godot-ci/tags). https://github.com/godotengine/godot-builds/releases. Leave empty to build
Leave empty to build the newest stable, same as the nightly run. the newest stable, same as the nightly run.
required: false required: false
type: string type: string
@@ -40,12 +40,16 @@ jobs:
UPDATE_LATEST=true UPDATE_LATEST=true
fi fi
if ! docker manifest inspect "barichello/godot-ci:${VERSION}" >/dev/null 2>&1; then # This image no longer depends on barichello/godot-ci as a base — it downloads Godot
# directly from godot-builds' own GitHub releases (see Dockerfile), so the gate here
# is against *that* release existing, not a third party's Docker tag.
RELEASE_URL="https://github.com/godotengine/godot-builds/releases/download/${VERSION}-stable/Godot_v${VERSION}-stable_linux.x86_64.zip"
if ! curl -fsSL -o /dev/null -r 0-0 "$RELEASE_URL"; then
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "::error::No barichello/godot-ci tag for '${VERSION}'. Check https://hub.docker.com/r/barichello/godot-ci/tags" echo "::error::No godot-builds stable release for '${VERSION}'. Check https://github.com/godotengine/godot-builds/releases"
exit 1 exit 1
fi fi
echo "::notice::Newest Godot stable is ${VERSION} but barichello/godot-ci has no matching tag yet — skipping, will retry tomorrow." echo "::notice::Newest Godot stable is ${VERSION} but its godot-builds release isn't up yet — skipping, will retry tomorrow."
echo "skip=true" >> "$GITHUB_OUTPUT" echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0 exit 0
fi fi
+28 -9
View File
@@ -1,16 +1,25 @@
# GODOT_VERSION selects the barichello/godot-ci base tag (Godot 4.0+ only — see # GODOT_VERSION is a stable Godot release tag (e.g. "4.7.1", no "-stable" suffix — Godot 4.0+
# docs/handoff/godot-ci-custom-image.md). BLENDER_URL is the tarball to bake in; # only, see docs/handoff/godot-ci-custom-image.md). BLENDER_URL is the tarball to bake in.
# .gitea/workflows/publish.yml always resolves both at build time via # .gitea/workflows/publish.yml always resolves both at build time via
# scripts/resolve-godot-version.sh and scripts/resolve-blender-url.sh. The # scripts/resolve-godot-version.sh and scripts/resolve-blender-url.sh. The defaults below are
# defaults below are only a fallback for a plain local `docker build`. # only a fallback for a plain local `docker build`.
#
# Godot itself is downloaded straight from its official GitHub releases (godot-builds), the same
# source barichello/godot-ci's own Dockerfile uses — this image no longer depends on that image
# as a base. Decided via wayfinder map https://git.arthurerlich.de/haylan/godot-ci/issues/2,
# ticket https://git.arthurerlich.de/haylan/godot-ci/issues/7: Alpine was considered and rejected
# (official Godot/Blender binaries are glibc-only, and Alpine's musl-native alternatives live
# only on its unpinned `edge` repo); a plain glibc-slim base doesn't cost the compatibility risk.
ARG GODOT_VERSION=4.7.1 ARG GODOT_VERSION=4.7.1
FROM barichello/godot-ci:${GODOT_VERSION} FROM debian:bookworm-slim
ARG GODOT_VERSION
ARG BLENDER_URL=https://download.blender.org/release/Blender4.2/blender-4.2.3-linux-x64.tar.xz ARG BLENDER_URL=https://download.blender.org/release/Blender4.2/blender-4.2.3-linux-x64.tar.xz
RUN apt-get update && apt-get install -y --no-install-recommends \ RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl unzip xz-utils \
libfontconfig1 \ libfontconfig1 \
build-essential scons pkg-config xz-utils curl \ build-essential scons pkg-config \
libx11-dev libxcursor-dev libxinerama-dev libgl1-mesa-dev \ libx11-dev libxcursor-dev libxinerama-dev libgl1-mesa-dev \
libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev libwayland-dev \ libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev libwayland-dev \
mingw-w64 \ mingw-w64 \
@@ -21,9 +30,19 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix \ && update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix \
&& update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix \ && update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix \
&& rm -rf /var/lib/apt/lists/* \ && rm -rf /var/lib/apt/lists/* \
# Blender is not bundled in barichello/godot-ci, and Ubuntu's apt package lags # Godot editor + export templates, straight from the official release (same URL shape
# (stuck on 4.0.2 on noble) — install the resolved tarball straight from # barichello/godot-ci's own Dockerfile uses) — stable releases only, matching what
# download.blender.org instead of `apt-get install blender`. # scripts/resolve-godot-version.sh resolves.
&& curl -fsSLO "https://github.com/godotengine/godot-builds/releases/download/${GODOT_VERSION}-stable/Godot_v${GODOT_VERSION}-stable_linux.x86_64.zip" \
&& curl -fsSLO "https://github.com/godotengine/godot-builds/releases/download/${GODOT_VERSION}-stable/Godot_v${GODOT_VERSION}-stable_export_templates.tpz" \
&& mkdir -p "/root/.local/share/godot/export_templates/${GODOT_VERSION}.stable" \
&& unzip -q "Godot_v${GODOT_VERSION}-stable_linux.x86_64.zip" \
&& mv "Godot_v${GODOT_VERSION}-stable_linux.x86_64" /usr/local/bin/godot \
&& unzip -q "Godot_v${GODOT_VERSION}-stable_export_templates.tpz" \
&& mv templates/* "/root/.local/share/godot/export_templates/${GODOT_VERSION}.stable/" \
&& rm -rf "Godot_v${GODOT_VERSION}-stable_linux.x86_64.zip" "Godot_v${GODOT_VERSION}-stable_export_templates.tpz" templates \
# Blender is not bundled anywhere here — install the resolved tarball straight from
# download.blender.org instead of an apt package.
&& curl -fsSL "$BLENDER_URL" -o /tmp/blender.tar.xz \ && curl -fsSL "$BLENDER_URL" -o /tmp/blender.tar.xz \
&& mkdir -p /opt/blender \ && mkdir -p /opt/blender \
&& tar -xJf /tmp/blender.tar.xz -C /opt/blender --strip-components=1 \ && tar -xJf /tmp/blender.tar.xz -C /opt/blender --strip-components=1 \
+14 -6
View File
@@ -1,9 +1,17 @@
# godot-ci # godot-ci
Custom image extending `barichello/godot-ci` with the Godot export-template toolchain and Blender A `debian:bookworm-slim`-based image with Godot, its export-template toolchain, and Blender
pre-installed, so `Project4x`'s `export-template.yml` doesn't `apt-get install` them on every pre-installed, so `Project4x`'s `export-template.yml` doesn't `apt-get install` them on every
release run. release run.
Godot is downloaded directly from its official [godot-builds
releases](https://github.com/godotengine/godot-builds/releases) rather than from a base image —
this repo previously extended `barichello/godot-ci` (Ubuntu-based) but moved off it to shed that
dependency's weight. Alpine was considered and rejected first: official Godot and Blender
binaries are glibc-only, and Alpine's musl-native alternatives for both live only on its unpinned
`edge` repo — not a safe bet for a nightly-rebuilding image. See [wayfinder map
#2](https://git.arthurerlich.de/haylan/godot-ci/issues/2) for the full research trail.
Built from the handoff spec at `Project4x`'s `docs/handoff/godot-ci-custom-image.md`; scope and Built from the handoff spec at `Project4x`'s `docs/handoff/godot-ci-custom-image.md`; scope and
versioning have since moved on from that spec — see below. versioning have since moved on from that spec — see below.
@@ -22,13 +30,13 @@ this image's Blender toolchain).
- **Nightly (midnight, `schedule:`)**: resolves the newest *stable* Godot release - **Nightly (midnight, `schedule:`)**: resolves the newest *stable* Godot release
(`scripts/resolve-godot-version.sh`) and the newest stable Blender (`scripts/resolve-godot-version.sh`) and the newest stable Blender
(`scripts/resolve-blender-url.sh`), and rebuilds+pushes `<version>` + `latest` only if that (`scripts/resolve-blender-url.sh`), and rebuilds+pushes `<version>` + `latest` only if that
Godot version isn't already published. If `barichello/godot-ci` hasn't tagged the new Godot Godot version isn't already published. If godot-builds hasn't published that release's assets
version yet, the run skips (with a notice, not a failure) and retries the next night. yet, the run skips (with a notice, not a failure) and retries the next night.
- **Manual (`workflow_dispatch`)**: type a Godot version (e.g. `4.6.3`) to (re)build and push that - **Manual (`workflow_dispatch`)**: type a Godot version (e.g. `4.6.3`) to (re)build and push that
exact tag, always with whatever Blender is newest at build time. Overwrites the tag if it exact tag, always with whatever Blender is newest at build time. Overwrites the tag if it
already exists. Does **not** touch `latest`. Fails clearly if `barichello/godot-ci` has no already exists. Does **not** touch `latest`. Fails clearly if godot-builds has no matching
matching tag — check release — check its [releases list](https://github.com/godotengine/godot-builds/releases)
[its tag list](https://hub.docker.com/r/barichello/godot-ci/tags) first. first.
Blender has no official "latest stable" API — `resolve-blender-url.sh` scrapes Blender has no official "latest stable" API — `resolve-blender-url.sh` scrapes
`download.blender.org/release/`. `scripts/test-lib.sh` is an offline smoke test for the parsing `download.blender.org/release/`. `scripts/test-lib.sh` is an offline smoke test for the parsing
-173
View File
@@ -1,173 +0,0 @@
# Handoff spec: custom godot-ci image
Status: **done, and superseded** — the `godot-ci` repo this spec asked for exists and is built.
Its versioning has since moved past what's written below: instead of one Dockerfile pinned to
`4.7.1`, it now auto-tracks the newest stable Godot (4.0+) and newest stable Blender on a nightly
schedule, with a manual `workflow_dispatch` to (re)build any specific version. See that repo's
`README.md` for the current behavior; this file is kept for the original problem statement and
scope rationale, not as a source of truth on tags/versions. Decided via wayfinder map
[#158](https://git.arthurerlich.de/haylan/Project4x/issues/158), ticket
[#162](https://git.arthurerlich.de/haylan/Project4x/issues/162).
## Problem
`export-template.yml`'s `export` job runs in `barichello/godot-ci:4.7.1` and, on every single run,
`apt-get install`s a from-source Godot export-template toolchain before it can build anything. That
install is pure dead time repeated on every release. A custom image extending
`barichello/godot-ci:4.7.1` with the toolchain pre-installed removes it.
## What this spec is for
A fresh Gitea agent session, given only this file, must be able to:
1. Create a new repo.
2. Add a `Dockerfile` and a publish workflow to it.
3. Get the image published to that repo's Gitea package (container) registry.
4. Report back the final image reference so `export-template.yml` here can be pointed at it.
No other context from this repo should be required.
## Scope: what goes in the image
Everything `export-template.yml`'s "Update and install dependencies" step currently
`apt-get install`s, unconditionally (all of it — see [Decisions](#decisions) below for why the
narrower alternative was rejected):
```
libfontconfig1
build-essential scons pkg-config xz-utils curl
# Linux leg:
libx11-dev libxcursor-dev libxinerama-dev libgl1-mesa-dev \
libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev libwayland-dev
# Windows leg:
mingw-w64
# + these two update-alternatives calls, baked in at image build time:
update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix
update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
# conditionally, when ENABLE_BLENDER is on:
blender
```
Current source of truth for this list: `.gitea/workflows/export-template.yml` in
`haylan/Project4x`, "Update and install dependencies" step. **Re-check that step before building**
— it may have drifted since this spec was written.
### What stays out of the image
- **The SCons object cache** (`.scons_cache`, restored via `actions/cache@v3` keyed on
`scons-${GODOT_VERSION}-${artifact_name}`). This is build _state_, not a package — baking it into
the image would pin it to image-build time instead of the actual release run, going stale
immediately.
- **`nsis` / `osslsigncode`.** These do NOT belong in this image. They run in `release.yml`'s
`create-release` job, which is a plain `ubuntu-latest` runner — it does not use
`barichello/godot-ci` or any container at all. (Earlier drafts of this ticket assumed they were
part of the export container's toolchain; that was wrong. The NSIS installer has since been
removed entirely — see ADR 0001's superseded note — so only `osslsigncode`/`zip` remain in
`create-release`, and neither is expensive enough to justify its own image.)
## Registry path and versioning
- **Registry:** this Gitea instance's container/package registry (`git.arthurerlich.de`), scoped
to the new repo you create — Gitea packages are per-repo/owner, so the path is
`git.arthurerlich.de/haylan/<new-repo-name>`.
- **Tag:** pin to the Godot version only, e.g. `git.arthurerlich.de/haylan/<new-repo-name>:4.7.1`.
This mirrors `barichello/godot-ci`'s own tag scheme and `Project4x`'s `GODOT_VERSION` env var. A
Godot version bump in `Project4x` means building and pushing a new tag here too — that coupling
is intentional, not an oversight.
- Pick `<new-repo-name>` yourself (e.g. `godot-ci-toolchain` or similar); it isn't fixed by this
spec.
## Auth: PAT required
Confirmed for this Gitea instance: `GITEA_TOKEN` (the automatic per-run Actions token) **cannot**
push to the package/container registry. The new repo's publish workflow needs a **Personal Access
Token** stored as a repo secret (e.g. `REGISTRY_PUSH_PAT`).
- **Scope needed:** `write:package` (add `read:package` too if the publish workflow ever needs to
pull the image back, e.g. to test it before tagging `latest`).
- Generate it from the account that should own the published packages, under
Settings → Applications → Generate New Token, with only that scope checked.
- Document the token's owner/scope in the new repo's README once created — this repo
(`Project4x`) has no record of it and shouldn't need one; the coupling is one-way
(`Project4x` only ever pulls the finished image, never pushes to it).
## Dockerfile skeleton
```dockerfile
FROM barichello/godot-ci:4.7.1
RUN apt-get update && apt-get install -y --no-install-recommends \
libfontconfig1 \
build-essential scons pkg-config xz-utils curl \
libx11-dev libxcursor-dev libxinerama-dev libgl1-mesa-dev \
libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev libwayland-dev \
mingw-w64 \
blender \
&& update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix \
&& update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix \
&& rm -rf /var/lib/apt/lists/*
```
Notes for whoever builds this:
- `blender` is baked in unconditionally here even though `Project4x`'s `ENABLE_BLENDER` flag is
currently `"false"` — the image can't cheaply branch on a flag it doesn't know about at build
time, and the package is small next to the rest of this list. If that turns out to add
meaningful image size/pull time for a project that never flips the flag on, split into a second
`-blender` tagged variant instead.
- Combine into one `RUN` (as above) so it's a single image layer — no benefit to splitting these
across layers here.
## Publish workflow skeleton
New repo, `.gitea/workflows/publish.yml`:
```yaml
name: Publish godot-ci image
on:
push:
branches: [main]
paths: [Dockerfile]
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Log in to Gitea registry
run: echo "${{ secrets.REGISTRY_PUSH_PAT }}" | docker login git.arthurerlich.de -u <owner-username> --password-stdin
- name: Build and push
run: |
docker build -t git.arthurerlich.de/haylan/<new-repo-name>:4.7.1 .
docker push git.arthurerlich.de/haylan/<new-repo-name>:4.7.1
```
Fill in `<owner-username>` and `<new-repo-name>` once the repo exists.
## How `Project4x` would then reference the new image
One-line change in `.gitea/workflows/export-template.yml`:
```diff
- container: barichello/godot-ci:4.7.1
+ container: git.arthurerlich.de/haylan/<new-repo-name>:4.7.1
```
The "Update and install dependencies" step's `apt-get install` calls for the baked-in packages
become redundant at that point (harmless no-ops — `apt-get install` on an already-installed
package is a fast no-op, so removing them is a cleanup, not a correctness requirement) and can be
trimmed in a follow-up ticket once the image is live and proven.
## Decisions
- **Bake-in scope:** everything in the current apt-get list, not a narrower "slow packages only"
subset — keeps the image and `export-template.yml`'s toolchain description in exact sync, so
there's only one place (this spec + the Dockerfile) to update when the list changes, instead of
maintaining a second smaller list that drifts from the first.
- **Tag scheme:** pinned to `GODOT_VERSION` rather than tracking image/toolchain revisions
independently — simpler to reason about, and this repo's own SCons cache is already keyed the
same way, so a Godot bump already forces everything else to rebuild in lockstep.