diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 491d7d55..eac932f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,16 @@ on: concurrency: group: ci-${{ github.ref }} - cancel-in-progress: true + # ⚠️ THE CONDITION IS THE LOAD-BEARING HALF. This workflow also fires on a push to `main` and + # `develop`, and THAT run is the one a merge is read against. An unconditional cancel throws it + # away when a second push lands behind it, leaving a check that reported NOTHING -- and a + # cancelled check reads as noise rather than as a failure. + # + # Outside a pull request the group then only SERIALIZES: two runs stay off one ref, for free. + # The cancel stays where it pays -- a pull request whose later push has overtaken the run in + # flight, which is where GitHub's per-job minute rounding actually bills for an answer about a + # tree that no longer exists. + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: lint: @@ -110,4 +119,4 @@ jobs: | xcbeautify --renderer github-actions || exit $? else echo "::notice::No SpacemanTests scheme yet — skipping test run." - fi + fi \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c2e67752..6149a482 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,6 +21,22 @@ on: default: true type: boolean +concurrency: + # ⚠️ SERIALIZE, NEVER CANCEL -- this is a release. The run is started by a `v*` tag push or by + # hand, and both are deliberate acts somebody is waiting on the result of. A cancelled release + # run leaves a check that reported nothing, and a cancelled check reads as noise rather than + # as a failure, so the release ends up measured by an absence. + # + # The fleet's usual form is `cancel-in-progress: ${{ github.event_name == 'pull_request' }}`, + # and it is right wherever a pull request can start the workflow. It cannot here: `on:` carries + # a tag push and `workflow_dispatch` only, so that expression would be false on every run this + # file can have -- a line that reads as a live decision and is a constant. Written as the + # constant it would be, which is what this repository's siblings do in the same situation. + # + # The group still earns its place: two releases must not run against one ref at once. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + permissions: contents: write @@ -230,4 +246,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: sparkle-release-${{ env.RELEASE_VERSION }} - path: release-artifacts/ + path: release-artifacts/ \ No newline at end of file