Replace the fixed 4.7.1 Dockerfile/workflow pin with: - a nightly schedule that resolves the newest stable Godot (4.0+) and newest stable Blender, and builds+pushes <version> plus a floating latest tag only when the Godot version actually changed - a workflow_dispatch free-text version input to (re)build any specific Godot version on demand, always with newest-at-build-time Blender, overwriting that tag without touching latest - scripts/resolve-godot-version.sh and scripts/resolve-blender-url.sh, with shared parsing logic in scripts/lib.sh and an offline smoke test in scripts/test-lib.sh - Blender is now fetched directly from download.blender.org instead of apt (Ubuntu noble's apt package is stuck on 4.0.2) - drop the push-to-main trigger; schedule + workflow_dispatch only Scope is Godot 4.0+ only — .blend import is a Godot 4 feature, so 3.x builds have no use for the Blender toolchain this image adds. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7.9 KiB
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, ticket
#162.
Problem
export-template.yml's export job runs in barichello/godot-ci:4.7.1 and, on every single run,
apt-get installs 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:
- Create a new repo.
- Add a
Dockerfileand a publish workflow to it. - Get the image published to that repo's Gitea package (container) registry.
- Report back the final image reference so
export-template.ymlhere 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 installs, unconditionally (all of it — see 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 viaactions/cache@v3keyed onscons-${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 inrelease.yml'screate-releasejob, which is a plainubuntu-latestrunner — it does not usebarichello/godot-cior 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 onlyosslsigncode/zipremain increate-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 isgit.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 mirrorsbarichello/godot-ci's own tag scheme andProject4x'sGODOT_VERSIONenv var. A Godot version bump inProject4xmeans building and pushing a new tag here too — that coupling is intentional, not an oversight. - Pick
<new-repo-name>yourself (e.g.godot-ci-toolchainor 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(addread:packagetoo if the publish workflow ever needs to pull the image back, e.g. to test it before tagginglatest). - 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 (Project4xonly ever pulls the finished image, never pushes to it).
Dockerfile skeleton
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:
blenderis baked in unconditionally here even thoughProject4x'sENABLE_BLENDERflag 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-blendertagged 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:
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:
- 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_VERSIONrather 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.