Files
novoyuuparosk-auto-wiki/.gitea/workflows/build-image.yml
T
mikkeli b2714ab5af
/ build (push) Successful in 59s
/ pin (push) Successful in 10s
feat(ci): auto-pin publish workflows to freshly built runner image
build-image.yml now pushes a moving :latest tag alongside :<short-sha>,
and a follow-up pin job (running in :latest) rewrites the image pin in all
three publish-*.yml to the new sha and commits it back to master with
FAPAT. Publish workflows keep immutable sha pins, kept current with no
manual bump. No rebuild loop: the pin commit only touches workflow_call
files. Root README image-flow section updated to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:05:43 +09:00

100 lines
4.0 KiB
YAML

on:
push:
branches: [master]
paths:
- Dockerfile
- "pipelines/**/requirements.txt"
- .gitea/workflows/build-image.yml
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
container:
# Daemonless image builder: kaniko :debug plus the /bin/sleep symlink
# act needs for job-container PID 1 (see ci/Dockerfile.kaniko-act).
# No docker socket, no privileges.
image: pi5-16.local:3005/mikkeli/kaniko-act:v1.23.2-r2
steps:
- name: Fetch source, build, push
# kaniko image has no bash — busybox sh only
shell: sh
env:
# package r/w PAT (user-level secret) — registry push only
PKG_TOKEN: ${{ secrets.PKGRW_PAT }}
# per-run auto-token, read access to this repo only — source fetch
JOB_TOKEN: ${{ github.token }}
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
run: |
set -eu
HOST="${URL_TO_GITEA#http://}"
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
IMAGE="${HOST}/mikkeli/novoyuuparosk-wiki-runner"
# Source via Gitea archive API (no git/node in this image; repo is
# private — authenticate with the job's own per-run token)
wget -qO /tmp/src.tar.gz \
"http://mikkeli:${JOB_TOKEN}@${HOST}/api/v1/repos/mikkeli/novoyuuparosk-auto-wiki/archive/${GITHUB_SHA}.tar.gz"
mkdir -p /tmp/src
tar -xzf /tmp/src.tar.gz -C /tmp/src --strip-components=1
# Registry auth for the push
AUTH=$(printf '%s' "mikkeli:${PKG_TOKEN}" | base64 | tr -d '\n')
printf '{"auths":{"%s":{"auth":"%s"}}}' "${HOST}" "${AUTH}" \
> /kaniko/.docker/config.json
# --insecure: push target is the plain-HTTP Gitea registry.
# Base image pull (docker.io) stays HTTPS — no --insecure-pull.
# :latest is a convenience tag for internal CI (the pin job below
# runs in it). Publish workflows stay pinned to the immutable sha.
/kaniko/executor \
--context dir:///tmp/src \
--dockerfile /tmp/src/Dockerfile \
--destination "${IMAGE}:${SHORT_SHA}" \
--destination "${IMAGE}:latest" \
--insecure
echo "Pushed ${IMAGE}:${SHORT_SHA} and ${IMAGE}:latest"
pin:
needs: build
runs-on: ubuntu-latest
container:
# Freshly built runner image: git + GNU sed baked in, and it has no
# non-shell ENTRYPOINT, so it works as a job container as-is (unlike the
# kaniko image above). Pulls :latest that the build job just pushed.
image: pi5-16.local:3005/mikkeli/novoyuuparosk-wiki-runner:latest
steps:
- name: Repoint publish workflows at the new image tag
env:
# Full-access PAT — needs contents:write to push the pin commit.
# github.token is read-only here; PKGRW_PAT is registry-only.
FAPAT: ${{ secrets.FAPAT }}
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
run: |
set -eu
HOST="${URL_TO_GITEA#http://}"
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
git clone "http://mikkeli:${FAPAT}@${HOST}/mikkeli/novoyuuparosk-auto-wiki" repo
cd repo
for f in .gitea/workflows/publish-songs.yml \
.gitea/workflows/publish-ses.yml \
.gitea/workflows/publish-tech.yml; do
sed -i -E "s#(novoyuuparosk-wiki-runner:)[A-Za-z0-9._-]+#\1${SHORT_SHA}#" "$f"
done
if git diff --quiet; then
echo "Pins already at ${SHORT_SHA}; nothing to commit."
exit 0
fi
git config user.email "actions@novoyuuparosk.org"
git config user.name "wiki-runner image bot"
git commit -am "build: pin runner image to ${SHORT_SHA}"
# Pin commit only touches publish-*.yml (on: workflow_call) — triggers
# nothing, so no rebuild loop. Fails loudly if master moved meanwhile.
git push origin HEAD:master