Drop the dependency on barichello/godot-ci as a base image (Ubuntu, ~2.4GB before this repo adds anything, most of it Android SDK/NDK weight this image never uses). Download Godot's editor and export templates directly from its official godot-builds releases instead, the same source barichello's own Dockerfile pulls from. Alpine was the first candidate considered and rejected: official Godot and Blender binaries are glibc-only, and Alpine's musl-native alternatives for both live only on its unpinned edge repo (see wayfinder tickets #4, #5, #6). A glibc-slim distro turned out not to be meaningfully smaller than Ubuntu either (#8) — but dropping barichello's Android-SDK-laden base entirely still nets a real win: local build measured 2343MB total (Godot + export templates + Blender + mingw-w64 + X11 dev libs) vs. barichello's bare base alone at 2460MB before this repo's layers were ever added. publish.yml's barichello-tag gate is replaced with a check against the godot-builds release we now actually depend on. Decided via wayfinder map #2, ticket #7: #7
123 lines
5.1 KiB
YAML
123 lines
5.1 KiB
YAML
name: Publish godot-ci image
|
|
|
|
on:
|
|
schedule:
|
|
# Midnight daily. Picks up new Godot stable releases (and, incidentally, new
|
|
# Blender stables whenever it rebuilds — see resolve step below).
|
|
- cron: '0 0 * * *'
|
|
workflow_dispatch:
|
|
inputs:
|
|
godot_version:
|
|
description: >-
|
|
Godot version to (re)build, e.g. 4.7.1 — must exist as a stable release at
|
|
https://github.com/godotengine/godot-builds/releases. Leave empty to build
|
|
the newest stable, same as the nightly run.
|
|
required: false
|
|
type: string
|
|
|
|
jobs:
|
|
publish:
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
IMAGE: git.arthurerlich.de/haylan/godot-ci
|
|
DOCKER_CLI_EXPERIMENTAL: enabled
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Log in to Gitea registry
|
|
run: echo "${{ secrets.REGISTRY_PUSH_PAT }}" | docker login git.arthurerlich.de -u haylan --password-stdin
|
|
|
|
- name: Resolve target Godot version
|
|
id: resolve
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
if [ -n "${{ inputs.godot_version }}" ]; then
|
|
VERSION="${{ inputs.godot_version }}"
|
|
UPDATE_LATEST=false
|
|
else
|
|
VERSION="$(./scripts/resolve-godot-version.sh)"
|
|
UPDATE_LATEST=true
|
|
fi
|
|
|
|
# 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
|
|
echo "::error::No godot-builds stable release for '${VERSION}'. Check https://github.com/godotengine/godot-builds/releases"
|
|
exit 1
|
|
fi
|
|
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"
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$UPDATE_LATEST" = true ] && docker manifest inspect "${IMAGE}:${VERSION}" >/dev/null 2>&1; then
|
|
echo "::notice::${VERSION} is already published and nothing changed — skipping."
|
|
echo "skip=true" >> "$GITHUB_OUTPUT"
|
|
exit 0
|
|
fi
|
|
|
|
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
|
echo "update_latest=${UPDATE_LATEST}" >> "$GITHUB_OUTPUT"
|
|
echo "skip=false" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Resolve newest Blender
|
|
if: steps.resolve.outputs.skip != 'true'
|
|
id: blender
|
|
run: echo "url=$(./scripts/resolve-blender-url.sh)" >> "$GITHUB_OUTPUT"
|
|
|
|
# Now that this workflow tracks the newest Godot/Blender instead of one
|
|
# pinned version, most nightly runs build genuinely new multi-GB layers
|
|
# instead of hitting cache — nothing here ever pruned old ones, so the
|
|
# runner's disk fills up over successive runs until a push (a blob
|
|
# write) is what finally fails. Clear stale images/build cache first.
|
|
- name: Free up runner disk
|
|
if: steps.resolve.outputs.skip != 'true'
|
|
run: docker system prune -af --volumes
|
|
|
|
- name: Build and push
|
|
if: steps.resolve.outputs.skip != 'true'
|
|
run: |
|
|
set -euo pipefail
|
|
VERSION="${{ steps.resolve.outputs.version }}"
|
|
docker build \
|
|
--build-arg GODOT_VERSION="$VERSION" \
|
|
--build-arg BLENDER_URL="${{ steps.blender.outputs.url }}" \
|
|
-t "${IMAGE}:${VERSION}" .
|
|
|
|
# Registry blob PUTs have been failing with transient 500s
|
|
# (unrelated to build correctness) — retry a few times before
|
|
# giving up.
|
|
push_with_retry() {
|
|
for attempt in 1 2 3; do
|
|
if docker push "$1"; then
|
|
return 0
|
|
fi
|
|
echo "::warning::docker push $1 failed (attempt $attempt/3), retrying..."
|
|
sleep $((attempt * 10))
|
|
done
|
|
return 1
|
|
}
|
|
|
|
push_with_retry "${IMAGE}:${VERSION}"
|
|
|
|
if [ "${{ steps.resolve.outputs.update_latest }}" = "true" ]; then
|
|
docker tag "${IMAGE}:${VERSION}" "${IMAGE}:latest"
|
|
push_with_retry "${IMAGE}:latest"
|
|
fi
|
|
|
|
# Gitea packages belong to the owner, not a repo, by default — pushing
|
|
# the image alone does NOT make it show up under this repo's Packages
|
|
# tab. Link it explicitly. Non-fatal: a failure here (e.g. already
|
|
# linked) shouldn't fail a build whose push already succeeded.
|
|
- name: Link package to this repository
|
|
if: steps.resolve.outputs.skip != 'true'
|
|
run: |
|
|
curl -sS -X POST \
|
|
-H "Authorization: token ${{ secrets.REGISTRY_PUSH_PAT }}" \
|
|
"https://git.arthurerlich.de/api/v1/packages/haylan/container/godot-ci/-/link/godot-ci" \
|
|
|| echo "link step failed (may already be linked) — check manually if needed"
|