fix(ci): gate build and deploy behind a committed .deploy-enabled marker
CD / Detect unsubstituted template (push) Successful in 0s
CD / Lint / Test / Vet (push) Successful in 6s
CD / Build & Import (push) Skipped
CD / Deploy via GitOps (push) Skipped

Every push to main since the first substituted commit was red at "Update
image tag in infra repo": sed: can't read k3s/apps/spatial-agent-app/
deployment.yaml. mathias/infra has no such manifest and the repo is a
hello-world MVP that should not deploy yet.

Port of doodle 32acff8/006c108/3a95cc9: guard outputs deploy_enabled from
scripts/deploy-enabled.sh (regular file, not symlink); build and deploy
require it to equal 'true', so a missing output fails closed. check and the
template guard are unchanged. No marker is committed.

Wiring test seen red on the old cd.yml (no gate), green after; removing the
clause from build.if or deploy.if makes it fail.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZkhi49hfeSqBp5aZJNXsM
This commit is contained in:
2026-10-10 10:53:27 +02:00
co-authored by Claude Sonnet 5.5
parent dd3f607744
commit 54e1db68f3
5 changed files with 239 additions and 2 deletions
+18 -2
View File
@@ -16,6 +16,7 @@ jobs:
runs-on: self-hosted
outputs:
is_template: ${{ steps.detect.outputs.is_template }}
deploy_enabled: ${{ steps.deploy.outputs.deploy_enabled }}
steps:
- uses: actions/checkout@v4
- id: detect
@@ -31,6 +32,21 @@ jobs:
# and asserts it still answers correctly.
run: |
echo "is_template=$(bash scripts/is-template.sh go.mod)" >> "$GITHUB_OUTPUT"
- id: deploy
# build and deploy run only when .deploy-enabled is committed. Before
# that there is no service: mathias/infra has no
# k3s/apps/spatial-agent-app, so deploy failed on every push to main and
# build pushed images for nothing. To deploy later: create the infra
# manifest first (an infra-lane issue), then commit .deploy-enabled.
# The logic is in scripts/deploy-enabled.sh so a test can run it.
# A missing or misspelt output compares unequal to 'true' below, so
# this fails closed. The script runs on its own line under set -e, not
# inside the echo: a command substitution there swallows its exit 2 and
# a missing directory would look like a deliberate "false".
run: |
set -euo pipefail
enabled="$(bash scripts/deploy-enabled.sh .)"
echo "deploy_enabled=${enabled}" >> "$GITHUB_OUTPUT"
check:
name: Lint / Test / Vet
@@ -73,7 +89,7 @@ jobs:
build:
name: Build & Import
needs: [guard, check]
if: needs.guard.outputs.is_template != 'true' && github.event_name != 'pull_request'
if: needs.guard.outputs.is_template != 'true' && needs.guard.outputs.deploy_enabled == 'true' && github.event_name != 'pull_request'
runs-on: self-hosted
outputs:
image-tag: ${{ steps.meta.outputs.sha-tag }}
@@ -113,7 +129,7 @@ jobs:
deploy:
name: Deploy via GitOps
needs: [guard, build]
if: needs.guard.outputs.is_template != 'true' && github.ref == 'refs/heads/main' && github.event_name == 'push'
if: needs.guard.outputs.is_template != 'true' && needs.guard.outputs.deploy_enabled == 'true' && github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: self-hosted
steps:
- name: Update image tag in infra repo