From c394ca556fe5720a29809c4eac3186d691bb2797 Mon Sep 17 00:00:00 2001 From: jross Date: Mon, 8 Jun 2026 11:02:06 -0600 Subject: [PATCH 1/3] ci: trigger CD (Production) on release publish, not tag push Switch the workflow trigger from push of v*.*.* tags to the GitHub release `published` event so production only deploys when a release is actually cut (e.g. via release-please), not on every matching tag push. Check out the release tag explicitly and use github.event.release.tag_name for APP_VERSION since github.ref on a release event points to the default branch, not the tag. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/CD_production.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/CD_production.yml b/.github/workflows/CD_production.yml index 507776ec..87c73e28 100644 --- a/.github/workflows/CD_production.yml +++ b/.github/workflows/CD_production.yml @@ -1,11 +1,8 @@ name: CD (Production) on: - push: - tags: - - 'v*.*.*' # GA releases: v1.0.0, v1.4.2 - - 'v*.*.*-*' # SemVer pre-releases: v1.0.0-rc.1 - - 'v*.*.*[a-z]*' # PEP 440 pre-releases: v1.0.0rc1, v1.0.0b2 (release-please-python form) + release: + types: [published] permissions: contents: read @@ -21,6 +18,7 @@ jobs: uses: actions/checkout@v6.0.3 with: fetch-depth: 0 + ref: ${{ github.event.release.tag_name }} - name: Install uv in container uses: astral-sh/setup-uv@v8.2.0 @@ -69,7 +67,7 @@ jobs: - name: Render App Engine configs env: - APP_VERSION: ${{ github.ref_name }} + APP_VERSION: ${{ github.event.release.tag_name }} ENVIRONMENT: "production" CLOUD_SQL_INSTANCE_NAME: "${{ secrets.CLOUD_SQL_INSTANCE_NAME }}" CLOUD_SQL_DATABASE: "${{ vars.CLOUD_SQL_DATABASE }}" From ca546e379ab192e3c15eb3edc0482f21aeb19111 Mon Sep 17 00:00:00 2001 From: jross Date: Mon, 8 Jun 2026 11:06:31 -0600 Subject: [PATCH 2/3] ci: gate CD (Production) to version-shaped release tags Preserve the safety rail the previous push.tags trigger provided. A release.published event will fire for any tag, so add: - job-level if: startsWith(tag, 'v') as a cheap pre-filter - first-step bash regex (^v[0-9]+\.[0-9]+\.[0-9]+(-.+|[a-z].*)?$) that fails the run on a mismatch Matches the original v*.*.*, v*.*.*-*, v*.*.*[a-z]* patterns so an ad-hoc release on a non-version tag no longer deploys to production. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/CD_production.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/CD_production.yml b/.github/workflows/CD_production.yml index 87c73e28..5dc41bf7 100644 --- a/.github/workflows/CD_production.yml +++ b/.github/workflows/CD_production.yml @@ -10,10 +10,24 @@ permissions: jobs: production-deploy: + # Safety rail: only deploy when the release tag is version-shaped + # (v*.*.*, v*.*.*-*, v*.*.*[a-z]*). startsWith() is a cheap pre-filter; + # the "Validate release tag" step enforces the strict regex. + if: startsWith(github.event.release.tag_name, 'v') + runs-on: ubuntu-latest environment: production steps: + - name: Validate release tag matches version pattern + env: + TAG: ${{ github.event.release.tag_name }} + run: | + if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.+|[a-z].*)?$ ]]; then + echo "Release tag '$TAG' does not match the v*.*.* pattern. Refusing to deploy." + exit 1 + fi + - name: Check out source repository uses: actions/checkout@v6.0.3 with: From 7e88172f4b872db01298c55ab2fa1b737075303f Mon Sep 17 00:00:00 2001 From: jross Date: Mon, 8 Jun 2026 11:07:13 -0600 Subject: [PATCH 3/3] ci: use refs/tags/ prefix when checking out the release tag actions/checkout's ref accepts ambiguous short names. If a branch were ever created with the same name as a release tag, the deploy would check out the branch instead of the tagged commit. Use the fully-qualified refs/tags/ form to remove the ambiguity. Co-Authored-By: Claude Opus 4.7 --- .github/workflows/CD_production.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CD_production.yml b/.github/workflows/CD_production.yml index 5dc41bf7..33d96184 100644 --- a/.github/workflows/CD_production.yml +++ b/.github/workflows/CD_production.yml @@ -32,7 +32,9 @@ jobs: uses: actions/checkout@v6.0.3 with: fetch-depth: 0 - ref: ${{ github.event.release.tag_name }} + # Fully-qualified tag ref avoids ambiguity if a branch is ever + # created with the same name as the release tag. + ref: refs/tags/${{ github.event.release.tag_name }} - name: Install uv in container uses: astral-sh/setup-uv@v8.2.0