Skip to content

ci: terminal 'all checks green' aggregate — the branch-protection gate #32

ci: terminal 'all checks green' aggregate — the branch-protection gate

ci: terminal 'all checks green' aggregate — the branch-protection gate #32

Workflow file for this run

name: lint
on:
push:
branches: [main]
pull_request:
# One run per branch/PR-head at a time: pushing to a branch with an open
# PR would otherwise run every job twice (push + pull_request events);
# a new run cancels the stale one.
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
jobs:
versions:
name: emit version matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.emit.outputs.matrix }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
with:
ruby-version: "3.2"
- id: emit
run: echo "matrix=$(tools/versions)" >> "$GITHUB_OUTPUT"
lint:
name: lint ${{ matrix.version }}
needs: versions
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.versions.outputs.matrix) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
with:
ruby-version: "3.2"
bundler-cache: true
- name: validate manifests against schema
run: bundle exec tools/validate_manifests
# Fetch the pinned tarball, verify its sha256, extract, assert a
# CPython source tree — and, for a patched line, git apply --check
# every patch the line's manifest selects (tools/lint).
- name: verify tarball + tree sanity + patches apply-clean
run: tools/lint "${{ matrix.version }}"
# The PR-time compile gate: one leg per (version x
# patch-carrying scenario) — tools/versions --smoke. This is where the
# msys2/ucrt64 patch series meets a real ucrt64 toolchain; the release
# gate (release-src.yml's smoke) re-runs the changed lines at the tag.
smoke-legs:
name: emit the compile-smoke matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.emit.outputs.matrix }}
leg_count: ${{ steps.emit.outputs.leg_count }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
with:
ruby-version: "3.2"
- id: emit
run: |
matrix=$(tools/versions --smoke)
{
echo "matrix=$matrix"
# The count drives the smoke job's if: guard (an unguarded
# empty matrix poisons the run conclusion).
echo "leg_count=$(jq '.include | length' <<< "$matrix")"
} >> "$GITHUB_OUTPUT"
echo "compile-smoke legs: $(jq -r '.include[] | "\(.version)/\(.platform)"' <<< "$matrix" | paste -sd' ' -)"
smoke:
name: smoke ${{ matrix.version }} (${{ matrix.platform }})
needs: smoke-legs
if: needs.smoke-legs.outputs.leg_count != '0'
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.smoke-legs.outputs.matrix) }}
uses: ./.github/workflows/_compile-smoke.yml
with:
version: ${{ matrix.version }}
platform: ${{ matrix.platform }}
runs_on: ${{ matrix.platform == 'windows-msys' && 'windows-2022' || 'ubuntu-latest' }}
# The terminal aggregate — and the branch-protection gate. The lint
# and smoke legs are dynamic matrices whose check names shift with
# every version bump, so protection pins this job's stable name
# instead of any leg's. Green means: both emitters computed, every
# lint leg passed, and every emitted smoke leg passed (no smoke legs
# at all gates on the emitters + lint).
verify:
name: all checks green
needs: [versions, lint, smoke-legs, smoke]
if: always() && !cancelled()
runs-on: ubuntu-latest
steps:
- name: Gate on the legs
run: |
set -euo pipefail
echo "versions: ${{ needs.versions.result }}"
echo "lint: ${{ needs.lint.result }}"
echo "smoke-legs: ${{ needs.smoke-legs.result }}"
echo "smoke: ${{ needs.smoke.result }} (legs=${{ needs.smoke-legs.outputs.leg_count }})"
[ "${{ needs.versions.result }}" = "success" ]
[ "${{ needs.lint.result }}" = "success" ]
[ "${{ needs.smoke-legs.result }}" = "success" ]
if [ "${{ needs.smoke-legs.outputs.leg_count }}" != "0" ] && [ "${{ needs.smoke.result }}" != "success" ]; then
echo "::error::not every compile-smoke leg succeeded: ${{ needs.smoke.result }}"
exit 1
fi