name: build-hello-app on: push: branches: [main] paths: - "apps/hello-app/src/**" jobs: build-and-push: runs-on: docker # kaniko builds the image itself with no daemon and no special host # privileges, so the runner host only ever needs a rootless Podman # socket to launch this container — never docker.sock, never sudo. container: image: gcr.io/kaniko-project/executor:debug options: --entrypoint "" outputs: tag: ${{ steps.build.outputs.tag }} steps: # actions/checkout@v4 needs a Node.js runtime, which this minimal # kaniko image doesn't have (no package manager to add it either) - # fetch the repo as a plain tarball from Forgejo's archive endpoint # instead, using the tools that are actually present (wget, tar). - name: Checkout (manual - no git/node in this image) run: | echo "workspace is: ${{ github.workspace }}" mkdir -p "${{ github.workspace }}" wget --header="Authorization: token ${{ secrets.FORGEJO_TOKEN }}" \ -O "${{ github.workspace }}/source.tar.gz" \ "https://git.boglabob.com/${{ github.repository }}/archive/${{ github.sha }}.tar.gz" tar -xzf "${{ github.workspace }}/source.tar.gz" --strip-components=1 -C "${{ github.workspace }}" rm "${{ github.workspace }}/source.tar.gz" - name: Write registry auth run: | mkdir -p /kaniko/.docker AUTH=$(printf '%s:%s' "${{ vars.FORGEJO_USER }}" "${{ secrets.FORGEJO_TOKEN }}" | base64 -w0) printf '{"auths":{"git.boglabob.com":{"auth":"%s"}}}' "$AUTH" > /kaniko/.docker/config.json - name: Inject build info run: | SHORT_SHA="${GITHUB_SHA::7}" BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) sed -i "s/__GIT_SHA__/$SHORT_SHA/; s/__BUILD_TIME__/$BUILD_TIME/" apps/hello-app/src/index.html - name: Build and push id: build run: | TAG="main-${GITHUB_SHA::7}-$(date +%s)" echo "tag=$TAG" >> "$GITHUB_OUTPUT" /kaniko/executor \ --context="${{ github.workspace }}/apps/hello-app/src" \ --dockerfile="${{ github.workspace }}/apps/hello-app/src/Dockerfile" \ --destination="git.boglabob.com/${{ vars.FORGEJO_ORG }}/hello-app:$TAG" \ --destination="git.boglabob.com/${{ vars.FORGEJO_ORG }}/hello-app:latest" # Flux's ImageUpdateAutomation (image-automation.yaml) should be doing this # commit-back step instead - its $imagepolicy Setters marker in # deployment.yaml is correctly formatted and verified against Flux's own # docs, ImagePolicy correctly resolves each new tag, and every other part # of the chain works, but it never actually commits (always reports # "repository up-to-date" with nothing to change) for reasons that # resisted a lengthy investigation - even a from-scratch Flux bootstrap # against a fresh controller instance didn't change the behavior. # ImageRepository/ImagePolicy are kept for visibility into what tag is # available; this job does the actual commit as a working substitute. update-deployment-tag: needs: build-and-push runs-on: docker container: image: alpine/git steps: - name: Commit new image tag to deployment.yaml run: | git config --global user.email "flux@boglabob.com" git config --global user.name "fluxcdbot" git clone "https://${{ vars.FORGEJO_USER }}:${{ secrets.FORGEJO_TOKEN }}@git.boglabob.com/${{ github.repository }}.git" repo cd repo TAG="${{ needs.build-and-push.outputs.tag }}" sed -i "s|\(image: git.boglabob.com/${{ vars.FORGEJO_ORG }}/hello-app:\)[^ ]*|\1$TAG|" apps/hello-app/deployment.yaml git add apps/hello-app/deployment.yaml git diff --cached --quiet || git commit -m "chore(hello-app): auto-update image to $TAG" git push