From beed64aefda262572691e75a8236000d49456967 Mon Sep 17 00:00:00 2001 From: David Charlot Date: Fri, 9 Oct 2026 03:39:02 -0400 Subject: [PATCH] ci: does a skipped job report a commit status? open-standards gates expensive path-filtered workflows behind a `relevant` job, so dependent jobs skip when a change does not touch that standard. If a skipped job reports no status, those contexts stay pending forever and a branch rule requiring them can never be satisfied. Four jobs, paired. gate-false -> dep-of-false should skip; gate-true -> dep-of-true should run. The second pair is the control: if needs-outputs were simply broken here and always read empty, every dependent would skip and the result would look the same. dep-of-true running is what makes the skip mean "the output said false". dep-literal isolates a self-skip with no needs edge, and dep-matrix mirrors wai-pack's three-leg matrix to show whether each leg reports its own context. Co-Authored-By: Claude Opus 5 --- .forgejo/workflows/skip-status-probe.yml | 92 ++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 .forgejo/workflows/skip-status-probe.yml diff --git a/.forgejo/workflows/skip-status-probe.yml b/.forgejo/workflows/skip-status-probe.yml new file mode 100644 index 0000000..d1b828e --- /dev/null +++ b/.forgejo/workflows/skip-status-probe.yml @@ -0,0 +1,92 @@ +name: skip-status-probe + +# Does a SKIPPED job report a commit status on this forge? +# +# open-standards gates expensive path-filtered workflows behind a `relevant` +# job: the dependent jobs carry `needs: relevant` + an `if:` on its output, so +# they skip when the change does not touch that standard. If a skipped job +# reports no status at all, every one of those contexts stays permanently +# pending and a branch-protection rule that requires them can never be +# satisfied — the PR becomes unmergeable. That is the question this answers, +# before the pattern is rolled out past the one workflow that has it. +# +# Four jobs, and the pairing is the point: +# gate-false -> dep-of-false expected SKIP +# gate-true -> dep-of-true expected RUN +# The second pair is the control. Without it, a skip proves nothing: if +# `needs.*.outputs.*` were simply broken here and always read empty, EVERY +# dependent would skip and the result would look identical. dep-of-true +# running is what makes dep-of-false's skip mean "the output said false". +# +# dep-literal isolates a job skipped by its own `if: false`, with no `needs` +# edge, to tell the two skip causes apart. +# +# dep-matrix mirrors the real shape under test: wai-pack's dependent jobs are +# a three-platform matrix, so the required contexts are per-leg. Whether each +# leg reports its own status, or the matrix collapses to one row, decides how +# many contexts go missing. + +on: + push: + paths: + - ".forgejo/workflows/skip-status-probe.yml" + pull_request: + paths: + - ".forgejo/workflows/skip-status-probe.yml" + +concurrency: + group: skip-status-probe-${{ github.ref }} + cancel-in-progress: true + +jobs: + gate-false: + name: probe · gate emitting false + runs-on: linux + outputs: + touched: ${{ steps.decide.outputs.touched }} + steps: + - id: decide + run: echo "touched=false" >> "$GITHUB_OUTPUT" + + gate-true: + name: probe · gate emitting true + runs-on: linux + outputs: + touched: ${{ steps.decide.outputs.touched }} + steps: + - id: decide + run: echo "touched=true" >> "$GITHUB_OUTPUT" + + dep-of-false: + name: probe · dependent of a false gate (expect SKIP) + needs: gate-false + if: needs.gate-false.outputs.touched == 'true' + runs-on: linux + steps: + - run: echo "FAIL - this job should not have run" + + dep-of-true: + name: probe · dependent of a true gate (expect RUN) + needs: gate-true + if: needs.gate-true.outputs.touched == 'true' + runs-on: linux + steps: + - run: echo "control - outputs propagate, so a skip above means false" + + dep-literal: + name: probe · skipped by its own literal false (expect SKIP) + runs-on: linux + if: false + steps: + - run: echo "FAIL - this job should not have run" + + dep-matrix: + name: probe · skipped matrix leg ${{ matrix.leg }} (expect SKIP) + needs: gate-false + if: needs.gate-false.outputs.touched == 'true' + runs-on: linux + strategy: + matrix: + leg: [alpha, beta, gamma] + steps: + - run: echo "FAIL - this job should not have run" -- 2.54.0 (Apple Git-157)