diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 9acf031..3a3d8b5 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -66,14 +66,23 @@ jobs: cache-from: type=registry,ref=${{ env.IMAGE }}:buildcache cache-to: type=registry,ref=${{ env.IMAGE }}:buildcache,mode=max + # The primary tag is already pushed and deployable by the time this runs: + # the image policy selects `main-`, so a failure here costs the + # SHA audit tag, not the rollout. - name: Wait for Harbor policy, then add SHA tag + shell: bash env: PRIMARY: ${{ steps.tags.outputs.primary }} QUALIFIED: ${{ steps.tags.outputs.qualified }} run: | + # Harbor's vulnerability policy blocks manifest reads while Trivy's scan + # is still Running, and `imagetools create` copies the manifest. Retry + # that copy itself rather than an `inspect` probe: a probe that passes is + # no guarantee the copy will, and under the default `bash -e` the first + # blocked copy aborted the step before its retries could run. for attempt in $(seq 1 60); do - if docker buildx imagetools inspect "$PRIMARY" >/dev/null 2>&1; then - docker buildx imagetools create --tag "$QUALIFIED" "$PRIMARY" + if docker buildx imagetools create --tag "$QUALIFIED" "$PRIMARY"; then + echo "tagged $QUALIFIED on attempt $attempt" exit 0 fi echo "waiting for Harbor scan/pull policy ($attempt/60)" diff --git a/AGENTS.md b/AGENTS.md index 51b4e9e..b737c2b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -35,6 +35,12 @@ The image does not set `BTCDATA_URL`; deployments must provide it. `BUILD_SHA` i runner, then publishes immutable linux/amd64 images to `harbor.pmagnus.cloud/btcprice/btcprice`. It embeds the short Git SHA as `APP_VERSION`. +The build pushes two tags: `main-`, then a companion `main--` for +audit. Harbor's vulnerability policy blocks manifest reads while Trivy is still scanning, so +the companion tag is retried until the scan clears. Only the first tag matters for deployment — +the Flux image policy matches `^main-<14 digits>$` — so a failure in that last step costs the +audit tag and nothing else. + Flux image automation updates the manifests in the separate `magnus/deploy` repository and Flux reconciles k3s. CI has no Kubernetes credentials. Production runs two replicas—one on hostinger and one on citadel—and is served at https://btcprice.k8s.pmagnus.cloud through ingress-nginx and diff --git a/CLAUDE.md b/CLAUDE.md index b06fb05..f39c3bf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,6 +35,12 @@ The image does not set `BTCDATA_URL`; deployments must provide it. `BUILD_SHA` i runner, then publishes immutable linux/amd64 images to `harbor.pmagnus.cloud/btcprice/btcprice`. It embeds the short Git SHA as `APP_VERSION`. +The build pushes two tags: `main-`, then a companion `main--` for +audit. Harbor's vulnerability policy blocks manifest reads while Trivy is still scanning, so +the companion tag is retried until the scan clears. Only the first tag matters for deployment — +the Flux image policy matches `^main-<14 digits>$` — so a failure in that last step costs the +audit tag and nothing else. + Flux image automation updates the manifests in the separate `magnus/deploy` repository and Flux reconciles k3s. CI has no Kubernetes credentials. Production runs two replicas—one on hostinger and one on citadel—and is served at https://btcprice.k8s.pmagnus.cloud through ingress-nginx and