diff --git a/.gitea/workflows/build-image.yml b/.gitea/workflows/build-image.yml index 7a7fa4b..e409a01 100644 --- a/.gitea/workflows/build-image.yml +++ b/.gitea/workflows/build-image.yml @@ -46,10 +46,54 @@ jobs: # --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}" + 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 diff --git a/README.md b/README.md index 46e766a..4e55920 100644 --- a/README.md +++ b/README.md @@ -49,14 +49,11 @@ Container network mode: `host` — required so job containers can reach `localho ### Job container image -All pipelines share a single pre-built Docker image: `novoyuuparosk-wiki-runner:latest`. The `Dockerfile` is at the repo root. It bakes in system deps (git, pandoc, ca-certificates) and all pipeline Python packages so job containers start instantly with no install steps. +All pipelines share a single pre-built Docker image, served from the Gitea registry at `pi5-16.local:3005/mikkeli/novoyuuparosk-wiki-runner`. The `Dockerfile` is at the repo root. It bakes in system deps (git, pandoc, ca-certificates) and all pipeline Python packages so job containers start instantly with no install steps. -The image is built manually on the Pi and stored in the local Docker daemon (`pull_image: false` in act_runner config). Rebuild after any change to the `Dockerfile` or a pipeline `requirements.txt`: +The image builds automatically via [`.gitea/workflows/build-image.yml`](.gitea/workflows/build-image.yml), which triggers on pushes that touch the `Dockerfile`, any pipeline `requirements.txt`, or that workflow itself. It uses kaniko (daemonless, unprivileged) to build and push two tags: an immutable `:` and a moving `:latest`. -```bash -docker build -t novoyuuparosk-wiki-runner:latest \ - /home/mikkeli/dev/novoyuuparosk-auto-wiki -``` +A follow-up `pin` job then rewrites the `image:` pin in each `publish-*.yml` to the new `:` and commits it back to `master` (using `FAPAT` for contents write). The publish workflows therefore always reference an immutable tag, kept current automatically — no manual bump. The pin commit only touches `workflow_call` files, so it triggers no further runs. ## Gitea Actions setup (cross-cutting)