diff --git a/.github/workflows/on-release.yml b/.github/workflows/on-release.yml index b6c893fe..a3a98c0b 100644 --- a/.github/workflows/on-release.yml +++ b/.github/workflows/on-release.yml @@ -69,30 +69,19 @@ jobs: - name: Build run: cargo build --release --locked --bin stateless-validator --bin debug-trace-server - - name: Verify the binaries - # stateless-validator carries a clap version (`#[clap(version)]`), so - # it is a gate: the built binary must report the tag's version, which - # also catches a tag / Cargo.toml mismatch nothing else checks here. - # debug-trace-server has no version flag; `--help` proves it loads and - # runs (a missing library or a crash fails the step) without gating. - run: | - set -euo pipefail - expected="stateless-validator ${TAG#v}" - actual="$(target/release/stateless-validator --version)" - if [[ "$actual" != "$expected" ]]; then - if [[ "$DRY_RUN" == "true" ]]; then - # A rehearsal reports what a real run would refuse, and carries on. - echo "::warning::built binary reports '$actual', expected '$expected' — a real release would stop here" - else - echo "::error::built binary reports '$actual', expected '$expected'; refusing to publish a mislabeled binary" - exit 1 - fi - fi - target/release/debug-trace-server --help > /dev/null - for b in stateless-validator debug-trace-server; do - echo "$b: $(stat -c %s target/release/$b) bytes" - done - echo "$actual" + # stateless-validator carries a clap version (`#[clap(version)]`), so + # it is a gate: the built binary must report the tag's version, which + # also catches a tag / Cargo.toml mismatch nothing else checks here. + - uses: megaeth-labs/.github/.github/actions/release-verify-version@main + with: + command: target/release/stateless-validator --version + version: ${{ env.TAG }} + dry_run: ${{ env.DRY_RUN }} + + - name: Check debug-trace-server runs + # No version flag to gate on; `--help` proves it loads and runs (a + # missing library or a crash fails the step, dry run or not). + run: target/release/debug-trace-server --help > /dev/null - uses: megaeth-labs/.github/.github/actions/release-assets@main with: diff --git a/.github/workflows/release-candidate.yml b/.github/workflows/release-candidate.yml index 8c9e4c29..3a09fbb8 100644 --- a/.github/workflows/release-candidate.yml +++ b/.github/workflows/release-candidate.yml @@ -23,6 +23,14 @@ permissions: jobs: propose: if: github.event_name == 'workflow_dispatch' + # One proposal at a time: two dispatches would race on the candidate + # branch. Job-level, not workflow-level: every PR closing on the default + # branch also starts this workflow, and a workflow-wide group would let + # that noise evict a queued release run (one pending run per group). + # A skipped job holds no slot in a job-level group. + concurrency: + group: ${{ github.workflow }}-propose + cancel-in-progress: false runs-on: ubuntu-latest steps: - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 @@ -57,6 +65,11 @@ jobs: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'chore/release-candidate-') && github.event.pull_request.user.login == 'mega-maxwell[bot]' + # One cut at a time, never cancelled: pull_request.closed does not refire. + # Job-level for the reason given on `propose`. + concurrency: + group: ${{ github.workflow }}-cut + cancel-in-progress: false runs-on: ubuntu-latest steps: - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index 676e988c..4ab64b42 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -23,6 +23,13 @@ jobs: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'chore/release-settle-') && github.event.pull_request.user.login == 'mega-maxwell[bot]' + # One publish per release branch: the tag guard and the tag push are two + # steps, so a re-run must queue behind a run in flight, never overlap it. + # Job-level: other PRs closing on the release branch also start this + # workflow, and must not evict a queued publish (one pending per group). + concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.base.ref }} + cancel-in-progress: false runs-on: ubuntu-latest steps: - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3 diff --git a/.github/workflows/release-settle.yml b/.github/workflows/release-settle.yml index c552ab71..6f13dcc3 100644 --- a/.github/workflows/release-settle.yml +++ b/.github/workflows/release-settle.yml @@ -18,6 +18,12 @@ on: required: true type: string +# One settle per version: two dispatches for the same version would both +# force-push the same settle branch. Queue, never cancel. +concurrency: + group: ${{ github.workflow }}-${{ inputs.version }} + cancel-in-progress: false + permissions: contents: read