Skip to content

Commit 60d2d4e

Browse files
committed
Add and validate a dependent job for branch protection
GitHub branch protection rules requiring CI checks currently only support listing individual checks as required. This adds an `all-pass` job that depends on all other jobs, to simplify this. `all-pass` can thus be made a required check, in lieu of numerous others, which it takes care to ensure are treated as effectively required. This also adds an `all-pass-meta` job that checks that the `all-pass` job really depends on all intended other jobs, which currently is all other jobs in the workflow. It is intentional at this time that neither CodeQL (configured via the "default" setup) nor the Markdown links check shall be blocking. The `all-pass` job is based on the `tests-pass` job in `gitoxide`, introduced in GitoxideLabs/gitoxide#1551 by Jiahao XU (https://github.com/NobodyXu), moderately edited since, and further moderately edited in the form it appars here. In view of... - (de minimis) the small size of the code, other than the list of jobs it depends on, which is not duplicated since the jobs here differ including in their names, *and* - how widespread that specific technique appears to be, based in part on searching GitHub and examining results with the exact string `"contains(needs.*.result, 'cancelled')"`, *and* - (scènes à faire) the limited number of reasonable feasible ways the technique can be expressed ...it seems to me that that continued resemblance of fragments of the code here to the code there does not raise copyright or related problems, in the `all-pass` job. Separately, the `all-pass-meta` job is is a direct copy of the `check-blocking` job in `gitoxide`, introduced among other changes in GitoxideLabs/gitoxide#1668. The `all-pass-meta` job is a near-complete copy of `check-blocking`, with only minimal changes, and even keeps the comments naerly unchanged. Although `check-blocking` is less important than `tests-pass`, it is also significantly longer and more complex. But unlike `tests-pass`, I contributed the `check-blocking` job in `gitoxide` (without copying from a previous work to do so; and licensing it nonexclusively, with no transfer or assignment of copyright). So that specific code is fine for me to reuse here. More broadly, I intend that anyone be allowed to reuse the code of the `all-pass-meta` job (as it appears here), anywhere, with no restrictions. See the 0BSD license file that accompanies this (algorithms-python) project. Note that the code of `check-blocking` in `gitoxide` may receive modifications authored by others, may be renamed, and some other job may be renamed to it, or it might be removed and some other job with that name may arise later, etc. Such code may still only be used under the terms that it is offered; these more permissive terms do *not* apply to such code, especially if it is written by others.
1 parent 03c9eb0 commit 60d2d4e

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

.github/workflows/test.yml

+62
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,65 @@ jobs:
191191

192192
- name: Analyze shell scripts
193193
uses: bewuethr/shellcheck-action@v2
194+
195+
# Check that only jobs intended not to block PR auto-merge are omitted as
196+
# dependencies of the `all-pass` job below, so that whenever a job is added,
197+
# a decision is made about whether it must pass for PRs to merge.
198+
all-pass-meta:
199+
runs-on: ubuntu-latest
200+
201+
env:
202+
# List all jobs that are intended NOT to block PR auto-merge here.
203+
EXPECTED_NONBLOCKING_JOBS: |-
204+
all-pass
205+
206+
defaults:
207+
run:
208+
shell: bash
209+
210+
steps:
211+
- name: Find this workflow
212+
run: |
213+
relative_workflow_with_ref="${GITHUB_WORKFLOW_REF#"$GITHUB_REPOSITORY/"}"
214+
echo "WORKFLOW_PATH=${relative_workflow_with_ref%@*}" >> "$GITHUB_ENV"
215+
216+
- uses: actions/checkout@v4
217+
with:
218+
sparse-checkout: ${{ env.WORKFLOW_PATH }}
219+
220+
- name: Get all jobs
221+
run: yq '.jobs | keys.[]' -- "$WORKFLOW_PATH" | sort | tee all-jobs.txt
222+
223+
- name: Get blocking jobs
224+
run: yq '.jobs.all-pass.needs.[]' -- "$WORKFLOW_PATH" | sort | tee blocking-jobs.txt
225+
226+
- name: Get jobs we intend do not block
227+
run: sort <<<"$EXPECTED_NONBLOCKING_JOBS" | tee expected-nonblocking-jobs.txt
228+
229+
- name: Each job must block PRs or be declared not to
230+
run: |
231+
sort -m blocking-jobs.txt expected-nonblocking-jobs.txt |
232+
diff --color=always -U1000 - all-jobs.txt
233+
234+
all-pass:
235+
name: All tests pass
236+
237+
needs:
238+
- pytest-conda
239+
- pytest-pipenv-lock
240+
- pytest-pipenv
241+
- lint
242+
- shellcheck
243+
- all-pass-meta
244+
245+
runs-on: ubuntu-latest
246+
247+
steps:
248+
- name: Some failed
249+
if: contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'failure')
250+
run: |
251+
false
252+
253+
- name: All passed
254+
run: |
255+
true

0 commit comments

Comments
 (0)