Skip to content

Commit 91c8e50

Browse files
daithihearnclaude
andcommitted
ci: serialise versioning runs and skip a dev deploy older than the live version
A stack merge closes its PRs a second apart; both versioning runs read the same latest tag and the two dev deploys can queue with the older tag last. The versioning workflow now runs one at a time, and the dev deploy guard skips an automatic deploy of a tag older than the one dev serves. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 2b0dc6f commit 91c8e50

3 files changed

Lines changed: 33 additions & 2 deletions

File tree

‎.github/workflows/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Automated CI/CD for Block Explorer. Dev, prod and previews all serve one static
66

77
```
88
PR merged to main
9-
→ codebase-versioning.yml tags v.X.Y.Z (increment:* label picks the bump)
9+
→ codebase-versioning.yml tags v.X.Y.Z (increment:* label picks the bump; one run at a time)
1010
→ publish-bundle.yml builds the static bundle, or finds one it already has
1111
→ deploy.yml copies it into dev's bucket and points dev at it
1212
→ prepare-release.yml leaves exactly one draft release
@@ -51,7 +51,7 @@ same bundle, so parity is structural rather than maintained by hand.
5151
| Manual dispatch | either, chosen by the `environment` input (break-glass, e.g. to roll back) |
5252

5353
**Jobs:**
54-
1. `guard` - Resolves the target, the tag and its content SHA, refuses anything not reachable from `main`, and derives the stack list below
54+
1. `guard` - Resolves the target, the tag and its content SHA, refuses anything not reachable from `main`, and derives the stack list below, and skips an automatic dev deploy of a tag older than the one dev already serves
5555
2. `terraform` - Applies each stack serially in dependency order, planning immediately before each apply
5656
3. `publish` - Copies the bundle artifact into that environment's bucket, unless the prefix is already there
5757
4. `activate` - Writes `<env>/runtime-config.json`, points the environment's hosts at the new bundle, invalidates the config, then checks the CDN by its own name

‎.github/workflows/codebase-versioning.yml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ on:
66
- main
77
types: [closed]
88

9+
# One run at a time: a stack merge closes every PR in it within a second, and
10+
# each run computes its tag from the newest one it can see.
11+
concurrency:
12+
group: codebase-versioning
13+
cancel-in-progress: false
14+
915
jobs:
1016
semantic-versioning:
1117
uses: vechain/github-actions-public/.github/workflows/semantic-versioning.yaml@c8645e5723b09ce657b865f78924b87a357df036 # v.2.3.1

‎.github/workflows/deploy.yml‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ jobs:
5656
app_sha: ${{ steps.derive.outputs.app_sha }}
5757
stacks: ${{ steps.derive.outputs.stacks }}
5858
domain: ${{ steps.derive.outputs.domain }}
59+
stale: ${{ steps.freshness.outputs.stale }}
5960
steps:
6061
- name: Checkout code
6162
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -170,11 +171,35 @@ jobs:
170171
} >> "$GITHUB_OUTPUT"
171172
echo "${TAG} carries app content ${APP_SHA}, deploying to ${domain}."
172173
174+
# Two merges landing together queue two dev deploys here, and the older
175+
# tag can be the one that runs last. Skip it rather than roll dev back.
176+
- name: Skip a dev tag older than the one dev serves
177+
id: freshness
178+
if: github.event_name == 'workflow_run'
179+
env:
180+
TAG: ${{ steps.resolve.outputs.tag }}
181+
DOMAIN: ${{ steps.derive.outputs.domain }}
182+
run: |
183+
set -euo pipefail
184+
185+
live=$(curl -fsS --max-time 15 "https://${DOMAIN}/runtime-config.json" | jq -r '.appVersion // empty' || true)
186+
stale=false
187+
if [[ "$live" =~ ^v\. ]] && [ "$live" != "$TAG" ]; then
188+
newest=$(printf '%s\n%s\n' "$TAG" "$live" | sort -V | tail -n1)
189+
if [ "$newest" = "$live" ]; then
190+
stale=true
191+
echo "::notice::${DOMAIN} already serves ${live}, newer than ${TAG}. Nothing to deploy."
192+
fi
193+
fi
194+
echo "stale=${stale}" >> "$GITHUB_OUTPUT"
195+
173196
# Serial, each stack planned immediately before its own apply — see workflows/README.md.
174197
terraform:
175198
name: Apply Terraform
176199
runs-on: ubuntu-latest
177200
needs: guard
201+
# A stale dev tag stops here; every job below needs this one.
202+
if: needs.guard.outputs.stale != 'true'
178203
permissions:
179204
id-token: write
180205
contents: read

0 commit comments

Comments
 (0)