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>
174 lines
7.9 KiB
Markdown
174 lines
7.9 KiB
Markdown
# 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.
|