diff --git a/.gitea/workflows/spike-registry.yml b/.gitea/workflows/spike-registry.yml new file mode 100644 index 0000000..3eeb306 --- /dev/null +++ b/.gitea/workflows/spike-registry.yml @@ -0,0 +1,117 @@ +name: SPIKE — registry build and push + +# THROWAWAY. Delete this file when #237 is answered, whichever way it goes. +# +# It exists to answer three questions that cannot be answered by reading +# anything in this repository, before a design is built on assumptions about +# them. #233 was designed on an assumption about the build context and broke +# every Portainer deploy; this is the correction to that habit. +# +# 1. Can a job on this runner run `docker build` at all? The other workflows +# use `services:`, which proves the runner can *start* containers, not +# that a job can build images. That needs a Docker socket or buildx. +# 2. Can it push to this Gitea's container registry? The packages API answers +# and lists nothing, so the registry has never been used here and +# "enabled" is unconfirmed. +# 3. How long does the real image take to build here? Not a nice-to-know: +# backend-integration.yml is manual because a job once held this runner +# for 3h12m, and any design that builds on every merge to main lands on +# the same runner. +# +# workflow_dispatch only. It cannot fire on push or pull request, so merging it +# changes nothing until someone presses the button. +on: + workflow_dispatch: + +env: + REGISTRY: gitea.bermudalamb.synology.me + # Gitea's container registry namespaces by owner: //. + IMAGE: gitea.bermudalamb.synology.me/bermudalamb/redefined-designs + +jobs: + spike: + runs-on: ubuntu-latest + # The same reasoning as backend-integration.yml: not a performance budget, + # a stop so that a hang costs minutes rather than hours of a runner that + # everything else queues behind. + timeout-minutes: 25 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + # First, and never failing, so that a failure in any later step is still + # informative rather than just "it did not work". + - name: Question 1 — what can this runner do? + continue-on-error: true + run: | + echo "--- docker client/daemon ---" + docker version || echo "NO DOCKER CLI OR DAEMON" + echo "--- buildx ---" + docker buildx version || echo "NO BUILDX" + echo "--- socket ---" + ls -l /var/run/docker.sock || echo "NO DOCKER SOCKET" + echo "--- disk ---" + df -h / | tail -1 + + # Reported as a boolean, never printed. If this says NO, the login below + # will fail and the fix is to add the secret, not to change the workflow. + - name: Is a token available? + continue-on-error: true + run: | + if [ -n "${{ secrets.GITEA_TOKEN }}" ]; then + echo "GITEA_TOKEN is present" + else + echo "GITEA_TOKEN is EMPTY — add a repo secret with package write scope" + fi + + - name: Question 2a — log in to the registry + run: | + echo "${{ secrets.GITEA_TOKEN }}" \ + | docker login "$REGISTRY" -u "${{ github.actor }}" --password-stdin + + # A trivial image first, deliberately. It separates "can this runner build + # and push anything" from "does our real Dockerfile work here" — if the + # real build fails later, this having passed says the plumbing is fine and + # the problem is ours. + - name: Question 2b — build and push a trivial image + run: | + mkdir -p /tmp/spike + printf 'FROM alpine:3.20\nRUN echo spike > /spike.txt\n' > /tmp/spike/Dockerfile + docker build -t "$IMAGE:spike-trivial" /tmp/spike + docker push "$IMAGE:spike-trivial" + echo "pushed $IMAGE:spike-trivial" + + # The real thing, timed. The tag records the commit so that the pulled + # image can be checked against what was built — which is the whole point + # of the design this spike is testing. + - name: Question 3 — build the real image and time it + run: | + SHORT_SHA="$(git rev-parse --short HEAD)" + echo "building $IMAGE:spike-$SHORT_SHA" + START=$(date +%s) + docker build -t "$IMAGE:spike-$SHORT_SHA" . + END=$(date +%s) + echo "REAL BUILD TOOK $((END - START)) SECONDS" + docker push "$IMAGE:spike-$SHORT_SHA" + echo "pushed $IMAGE:spike-$SHORT_SHA" + + # Proves the commit can actually be baked in, which is the reason for the + # whole exercise. In a Gitea Actions checkout .git is present, unlike in + # Portainer's build context — that difference is exactly what #235 was. + - name: Does the built image know its own commit? + continue-on-error: true + run: | + SHORT_SHA="$(git rev-parse --short HEAD)" + echo "git says: $SHORT_SHA" + echo "image says:" + docker run --rm "$IMAGE:spike-$SHORT_SHA" cat dist/buildInfo.json || echo "no stamp" + + - name: What to do next + if: always() + run: | + echo "If the pushes succeeded, try pulling from Portainer:" + echo " 1. Portainer > Registries > Add registry > Custom" + echo " URL: $REGISTRY (username + a token with package read)" + echo " 2. docker pull $IMAGE:spike-trivial" + echo "Then delete this workflow and the spike-* packages. See #237."