diff --git a/.github/workflows/pytest-matrix.yml b/.github/workflows/pytest-matrix.yml index f3fdcba..3abe73a 100644 --- a/.github/workflows/pytest-matrix.yml +++ b/.github/workflows/pytest-matrix.yml @@ -7,17 +7,23 @@ name: pytest-matrix # original), and the python-version matrix / runner label are identical # across every caller today, so nothing needs to be parameterized yet. # CODECOV_TOKEN must be available to the caller (secrets: inherit). +# +# CALLERS MUST USE THE JOB ID `pytest-matrix`. Copy the stub from +# workflow-templates/pytest-matrix.yml; do not write your own. The check name +# GitHub renders is " / ", so the caller's job id +# IS the branch-protection context prefix: name it anything else and that repo +# emits a check name no other repo emits, which means a bespoke required-check +# list for it forever. See the README's "Caller job ids" section. on: workflow_call: {} jobs: pytest-matrix: - # Job name is a REQUIRED status check on scitex-stats' develop/main - # branch protection today (as "pytest-matrix-on-ubuntu-py3.11" etc, - # no caller-job prefix). Under workflow_call the check name GitHub - # renders is " / " — branch protection - # required-check strings will need updating post-migration (see PR). + # This name is the SECOND half of the required status check. The full context + # a caller emits is "pytest-matrix / pytest-matrix-on-ubuntu-py3.11" (given the + # mandated caller job id above). Renaming this breaks branch protection in + # every repo at once — reconcile protection in the same change if you ever do. name: pytest-matrix-on-ubuntu-py${{ matrix.python-version }} runs-on: [self-hosted, Linux, X64, spartan-cpu] timeout-minutes: 30 diff --git a/README.md b/README.md index d5a6156..3c649fc 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,14 @@ Under `.github/workflows/`, called from a leaf repo like: ```yaml jobs: - call: - uses: scitex-ai/.github/.github/workflows/.yml@main + pytest-matrix: # <-- the job id is load-bearing. See "Caller job ids" below. + uses: scitex-ai/.github/.github/workflows/pytest-matrix.yml@main secrets: inherit ``` +Copy the stub from [`workflow-templates/`](workflow-templates/) rather than +writing one — it also shows up under *Actions → New workflow* in every repo. + - `pytest-matrix.yml` — pytest across the supported Python versions. - `import-smoke.yml` — bare-install import smoke test. - `quality-audit.yml` — `scitex-dev ecosystem audit-all` quality gate. @@ -21,6 +24,56 @@ jobs: - `cla.yml` — CLA Assistant + owner direct-push bypass. - `auto-merge-to-develop.yml` — auto-merge green PRs targeting `develop`. +## Caller job ids — DO NOT INVENT THEM + +**The caller's job id is the branch-protection context prefix.** GitHub names the +status check of a reusable-workflow call: + +``` +" / " +``` + +So a repo that calls `pytest-matrix.yml` from a job it named `test` emits +`test / pytest-matrix-on-ubuntu-py3.11`, while one that named it `pytest-matrix` +emits `pytest-matrix / pytest-matrix-on-ubuntu-py3.11`. Different repos, different +required-check names, and **one protection list can no longer serve the ecosystem** — +every repo needs a bespoke list, hand-read off a real PR, forever. + +Use exactly these job ids. They are what the already-migrated repos emit today +(`scitex-dict`, `scitex-ui`, `scitex-todo`, `scitex-scholar`), so adopting them +is a no-op for those repos rather than fresh churn: + +| reusable workflow | caller job id | resulting status check | +|---|---|---| +| `pytest-matrix.yml` | `pytest-matrix` | `pytest-matrix / pytest-matrix-on-ubuntu-py3.{11,12,13}` | +| `import-smoke.yml` | `import-smoke` | `import-smoke / import-smoke-on-ubuntu-py3-12` | +| `quality-audit.yml` | `quality-audit` | `quality-audit / audit` | +| `rtd-sphinx-build.yml` | `docs-sphinx` | `docs-sphinx / docs-sphinx` | + +`cla.yml` and `auto-merge-to-develop.yml` are exempt: neither emits a prefixed +required check (the CLA status is posted by the action as a plain `CLAssistant` +commit status, and auto-merge gates nothing), so their caller job id is not +load-bearing. + +### Migrating a repo onto these workflows + +Adopting a reusable workflow **renames that repo's status checks** (the prefix is +added). Branch protection must be reconciled in the same change, or the repo goes +green-but-unmergeable — every check passing, `mergeStateStatus: BLOCKED`, no error +anywhere. + +1. Open the migration PR and let CI run. +2. **Read the emitted check names off that real PR.** Never guess them. +3. Compare with `required_status_checks.contexts` on **each** protected branch + (`main` *and* `develop` — they drift apart). +4. Reconcile — *reconcile*, not blanket-flip. Some repos already had protection + set to the post-migration names in anticipation, and need no change at all; + others still carry the pre-migration names and do. + +Note `scitex-dev`: its protection was deliberately set back to the **bare** +(pre-migration) names as an interim to unblock merges. When it migrates, its +protection must be flipped **to the prefixed names in the same change**. + PyPI publish/release workflows stay local to each leaf repo — PyPI trusted publishing (OIDC) does not support `workflow_call` reusable workflows (`invalid-publisher` error), so that job must run in a workflow file that diff --git a/workflow-templates/pytest-matrix.properties.json b/workflow-templates/pytest-matrix.properties.json new file mode 100644 index 0000000..66aa160 --- /dev/null +++ b/workflow-templates/pytest-matrix.properties.json @@ -0,0 +1,7 @@ +{ + "name": "SciTeX pytest-matrix (Spartan)", + "description": "Canonical caller for the org reusable pytest-matrix workflow. Runs pytest on the self-hosted Spartan runners across py3.11/3.12/3.13. Do not rename the job id — it is the branch-protection context prefix.", + "iconName": "octicon check-circle", + "categories": ["Continuous integration", "Python"], + "filePatterns": ["pyproject.toml$"] +} diff --git a/workflow-templates/pytest-matrix.yml b/workflow-templates/pytest-matrix.yml new file mode 100644 index 0000000..01197f5 --- /dev/null +++ b/workflow-templates/pytest-matrix.yml @@ -0,0 +1,38 @@ +name: tests + +# CANONICAL CALLER STUB — copy this verbatim. Do not rename the job. +# +# The job id `pytest-matrix` is NOT cosmetic. GitHub names the status check of a +# reusable-workflow call: +# +# " / " +# +# so the job id below IS the branch-protection context prefix. With `pytest-matrix` +# every repo in the ecosystem emits exactly: +# +# pytest-matrix / pytest-matrix-on-ubuntu-py3.11 +# pytest-matrix / pytest-matrix-on-ubuntu-py3.12 +# pytest-matrix / pytest-matrix-on-ubuntu-py3.13 +# +# One required-status-check list then serves every repo. Rename the job to +# `test`, `call`, `ci`, … and that repo emits `test / pytest-matrix-on-ubuntu-py3.11` +# instead — a bespoke protection list for that repo, forever, and a merge that +# blocks silently until someone hand-reads the new names off a real PR. + +on: + push: + branches: [main, develop] + pull_request: + branches: [main, develop] + schedule: + - cron: "0 17 * * *" # nightly, off-peak + workflow_dispatch: + +concurrency: + group: tests-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + pytest-matrix: # <-- DO NOT RENAME (see above) + uses: scitex-ai/.github/.github/workflows/pytest-matrix.yml@main + secrets: inherit