From 7830df3dddfc44c8956034ad936b3eae31b74ad4 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sun, 4 Oct 2026 21:22:56 -0400 Subject: [PATCH 1/2] ci(ci-status): yield a contract-only run to the full run instead of waiting Pin the pr-require-checks composites to ci-workflows v0.37.0 and set yield-to-full-run, rerun-contract-only-siblings and a zero carry-forward wait on aggregate-results. ci-status gets actions: write and a 3-minute timeout. Same shape as melodic-software/medley#2115. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/pr-require-checks.yml | 36 +++++++++++++++---------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/.github/workflows/pr-require-checks.yml b/.github/workflows/pr-require-checks.yml index 686ef0f..71288c1 100644 --- a/.github/workflows/pr-require-checks.yml +++ b/.github/workflows/pr-require-checks.yml @@ -51,8 +51,9 @@ permissions: # # The cost of the branch: a contract-only run no longer queues behind the full # run whose `ci-lanes` status it carries forward, so the two race. The -# `aggregate-results` composite closes that with a bounded wait on EARLIER incomplete -# runs on the same head SHA; see `carry-forward-wait-seconds` on the job below. +# `aggregate-results` composite closes that with `yield-to-full-run`: a +# contract-only run fails at once while a full run on the same head SHA is in +# flight; see the job below. # # One hazard the branch does not remove, because no concurrency setting both # removes it and keeps supersession: the full branch is keyed on the pull @@ -93,7 +94,10 @@ jobs: needs: [validate-marketplace] if: ${{ !cancelled() }} runs-on: ubuntu-24.04 - timeout-minutes: 5 + # No run waits for another: with `yield-to-full-run` a contract-only run + # lists in-flight runs once and reads the status once, and a full run's + # ci-status runs after its lanes, so either finishes in seconds. + timeout-minutes: 3 permissions: contents: read # check-contract upserts the advisory linkage comment and moves the linkage @@ -101,14 +105,14 @@ jobs: # branch reads back on the next contract-only event. pull-requests: write statuses: write - # The carry-forward wait enumerates this workflow's runs on this head SHA. - # Under an explicit `permissions:` block every unlisted scope defaults to - # none, so without this the Actions reads 403; the composite then warns - # naming the scope and fails, it never passes. - actions: read + # `yield-to-full-run` lists this workflow's runs on the head SHA, and + # `rerun-contract-only-siblings` re-runs the red contract-only ones once + # the full run records `success`. Under an explicit `permissions:` block + # every unlisted scope defaults to none; write covers the read. + actions: write steps: - name: Check the pull-request contract - uses: melodic-software/ci-workflows/.github/actions/pr-require-checks/check-contract@fb56986808750d6856c27de78df15e150027b8dc # v0.36.0 + uses: melodic-software/ci-workflows/.github/actions/pr-require-checks/check-contract@d49c4915ba75bbc9602cc30980604cad0806334e # v0.37.0 with: token: ${{ github.token }} - name: Aggregate lane results @@ -116,12 +120,16 @@ jobs: # aggregation: the job still fails on the contract step's exit code, and # the `ci-lanes` status is on the SHA for the next contract-only run. if: ${{ !cancelled() }} - uses: melodic-software/ci-workflows/.github/actions/pr-require-checks/aggregate-results@fb56986808750d6856c27de78df15e150027b8dc # v0.36.0 + uses: melodic-software/ci-workflows/.github/actions/pr-require-checks/aggregate-results@d49c4915ba75bbc9602cc30980604cad0806334e # v0.37.0 with: - # At least 60 seconds below this job's `timeout-minutes: 5` (300s), so - # the fail-closed error is what a contract-only run reports at the - # ceiling rather than a job timeout preempting it. - carry-forward-wait-seconds: '240' + # A contract-only run never waits: while a full run on the SHA is in + # flight it fails with "superseded by full run ", and that run's + # newer ci-status decides the gate. Once the full run records + # `success` it re-runs those red contract-only runs, which then read + # the `success` and replace their red check runs. + yield-to-full-run: 'true' + rerun-contract-only-siblings: 'true' + carry-forward-wait-seconds: '0' results: ${{ join(needs.*.result, ' ') }} # The replaced inline aggregator passed only `success`, so a `skipped` # lane was already red here. From 01dd20d855b53943015ee7678aa3ea0ab3a405aa Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sun, 4 Oct 2026 21:31:13 -0400 Subject: [PATCH 2/2] ci(ci-status): re-run contract-only siblings only from a non-draft full run A draft full run skipped the lanes, so it must not re-run siblings. Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/pr-require-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-require-checks.yml b/.github/workflows/pr-require-checks.yml index 71288c1..4ecc6d0 100644 --- a/.github/workflows/pr-require-checks.yml +++ b/.github/workflows/pr-require-checks.yml @@ -128,7 +128,7 @@ jobs: # `success` it re-runs those red contract-only runs, which then read # the `success` and replace their red check runs. yield-to-full-run: 'true' - rerun-contract-only-siblings: 'true' + rerun-contract-only-siblings: ${{ github.event.pull_request.draft && 'false' || 'true' }} carry-forward-wait-seconds: '0' results: ${{ join(needs.*.result, ' ') }} # The replaced inline aggregator passed only `success`, so a `skipped`