From 8c074288c6e4adf15dadee8243bf2c09f7c2133f Mon Sep 17 00:00:00 2001 From: Jan Novak Date: Thu, 8 Oct 2026 20:36:22 +0200 Subject: [PATCH] ci: gate the image build on vet/build/test, push sha tags, protect latest - check job runs go vet, go build and go test -short before the build - images are pushed as : and :sha-<12>; :latest moves only on tag pushes - GIT_COMMIT build arg and OCI source/created labels Co-Authored-By: Claude Opus 5.5 --- .gitea/workflows/build.yaml | 63 ++++++++++++++----- CLAUDE.md | 5 +- .../2026-10-08-2028-house-conventions.md | 13 +++- 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 1ceec3c..66fccac 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -11,31 +11,66 @@ on: tags: - '*' +concurrency: + group: build-${{ github.ref }} + cancel-in-progress: true + jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + - name: Vet + run: go vet ./... + - name: Build + run: go build ./... + - name: Test (short) + run: go test -short ./... + build: + needs: check runs-on: ubuntu-latest permissions: contents: read packages: write - steps: - uses: actions/checkout@v4 + - name: Compute image tags + id: meta + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + TAG="${{ inputs.tag }}" + else + TAG="${{ github.ref_name }}" + fi + echo "tag=$TAG" >> "$GITHUB_OUTPUT" + echo "sha=sha-$(echo '${{ github.sha }}' | cut -c1-12)" >> "$GITHUB_OUTPUT" + - name: Login to Gitea registry run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login -u ${{ github.actor }} --password-stdin gitea.home.hrajfrisbee.cz - name: Build and push run: | - TAG=${{ github.ref_name }} - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - TAG=${{ inputs.tag }} - fi - REPO=gitea.home.hrajfrisbee.cz/${{ github.repository }} - docker build -f Dockerfile \ - --build-arg GIT_TAG=$TAG \ - --build-arg GIT_COMMIT=${{ github.sha }} \ - --build-arg BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ) \ - -t $REPO:$TAG \ - -t $REPO:latest . - docker push $REPO:$TAG - docker push $REPO:latest + IMAGE=gitea.home.hrajfrisbee.cz/${{ github.repository }} + docker build \ + --build-arg GIT_COMMIT=$(echo '${{ github.sha }}' | cut -c1-12) \ + --label org.opencontainers.image.source=https://gitea.home.hrajfrisbee.cz/${{ github.repository }} \ + --label org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ) \ + -t "$IMAGE:${{ steps.meta.outputs.tag }}" \ + -t "$IMAGE:${{ steps.meta.outputs.sha }}" \ + . + docker push "$IMAGE:${{ steps.meta.outputs.tag }}" + docker push "$IMAGE:${{ steps.meta.outputs.sha }}" + + # Only real tag pushes move :latest — an ad-hoc dispatch of an old ref must not clobber it. + - name: Push latest (tag builds only) + if: github.event_name == 'push' + run: | + IMAGE=gitea.home.hrajfrisbee.cz/${{ github.repository }} + docker tag "$IMAGE:${{ steps.meta.outputs.tag }}" "$IMAGE:latest" + docker push "$IMAGE:latest" diff --git a/CLAUDE.md b/CLAUDE.md index 1aebf9d..6a1d374 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -209,7 +209,10 @@ Gitea Actions, workflows in `.gitea/workflows/`: - `build.yaml` builds the image and pushes it to `gitea.home.hrajfrisbee.cz/kacerr/gatewayapi-certificates-operator` on any tag push - or manual dispatch. Needs the `REGISTRY_TOKEN` repo secret. + or manual dispatch with a `tag` input. A `check` job (`go vet`, `go build`, + `go test -short`) gates the build. Every build pushes `:` and an immutable + `:sha-<12-char-commit>`; `:latest` moves only on real tag pushes. Needs the + `REGISTRY_TOKEN` repo secret. - `kubernetes-deploy.yaml` applies `deploy/` to the home-lab cluster through a Vault → Kanidm → OIDC auth chain. diff --git a/docs/plans-executions/2026-10-08-2028-house-conventions.md b/docs/plans-executions/2026-10-08-2028-house-conventions.md index b27af46..92f65a3 100644 --- a/docs/plans-executions/2026-10-08-2028-house-conventions.md +++ b/docs/plans-executions/2026-10-08-2028-house-conventions.md @@ -8,7 +8,7 @@ Plan: `docs/plans/2026-10-08-2028-house-conventions.md` - [x] Step 3 — Makefile, lint, formatting - [x] Step 4 — Module path and version identity - [x] Step 5 — Baseline tests -- [ ] Step 6 — CI build workflow +- [x] Step 6 — CI build workflow - [ ] Step 7 — Close out ## Step 1 — CLAUDE.md @@ -130,3 +130,14 @@ truncation are deliberately not asserted, so the suite does not pin behaviour th the bug-fix phase will change. `TestListenersEqual_managedFields` only asserts the four fields the comparison covers today; it says nothing about protocol, allowed routes or TLS mode. + +## Step 6 — CI build workflow + +`.gitea/workflows/build.yaml` is now a verbatim copy of the egress workflow; it has +no project-specific strings (the image name comes from `github.repository`). + +Worth noting: not run yet. The first tag push or manual dispatch is the test. Two +things could differ from egress on this repo's runner: `actions/setup-go@v5` (uh-cli +had to install Go with curl instead), and lint is not part of the `check` job, same +as egress. The unused `GIT_TAG` and `BUILD_DATE` build args are gone; +`kubernetes-deploy.yaml` is untouched.