diff --git a/.github/workflows/markdown-links.yml b/.github/workflows/markdown-links.yml index 30ce7d7..96dd262 100644 --- a/.github/workflows/markdown-links.yml +++ b/.github/workflows/markdown-links.yml @@ -6,6 +6,9 @@ on: schedule: - cron: '15 0,12 * * *' +permissions: + contents: read + jobs: markdown-link-check: runs-on: ubuntu-latest diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a189ec2..f336d1e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,6 +2,9 @@ name: Test on: [push, pull_request] +permissions: + contents: read + jobs: pytest-conda: name: pytest (conda) @@ -191,3 +194,65 @@ jobs: - name: Analyze shell scripts uses: bewuethr/shellcheck-action@v2 + + # Check that only jobs intended not to block PR auto-merge are omitted as + # dependencies of the `all-pass` job below, so that whenever a job is added, + # a decision is made about whether it must pass for PRs to merge. + all-pass-meta: + runs-on: ubuntu-latest + + env: + # List all jobs that are intended NOT to block PR auto-merge here. + EXPECTED_NONBLOCKING_JOBS: |- + all-pass + + defaults: + run: + shell: bash + + steps: + - name: Find this workflow + run: | + relative_workflow_with_ref="${GITHUB_WORKFLOW_REF#"$GITHUB_REPOSITORY/"}" + echo "WORKFLOW_PATH=${relative_workflow_with_ref%@*}" >> "$GITHUB_ENV" + + - uses: actions/checkout@v4 + with: + sparse-checkout: ${{ env.WORKFLOW_PATH }} + + - name: Get all jobs + run: yq '.jobs | keys.[]' -- "$WORKFLOW_PATH" | sort | tee all-jobs.txt + + - name: Get blocking jobs + run: yq '.jobs.all-pass.needs.[]' -- "$WORKFLOW_PATH" | sort | tee blocking-jobs.txt + + - name: Get jobs we intend do not block + run: sort <<<"$EXPECTED_NONBLOCKING_JOBS" | tee expected-nonblocking-jobs.txt + + - name: Each job must block PRs or be declared not to + run: | + sort -m blocking-jobs.txt expected-nonblocking-jobs.txt | + diff --color=always -U1000 - all-jobs.txt + + all-pass: + name: All tests pass + + needs: + - pytest-conda + - pytest-pipenv-lock + - pytest-pipenv + - lint + - shellcheck + - all-pass-meta + + runs-on: ubuntu-latest + + steps: + - name: Some failed + if: contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'failure') + run: | + false + + - name: All passed + run: | + true