Skip to content

docs(contributing): correct pep.rst's release gating description (#956) - #957

Merged
JarryShaw merged 1 commit into
mainfrom
docs/956-pep-release-gating
Oct 1, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
docs/956-pep-release-gating

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner

Please follow the guide below

  • Searched for similar pull requests
  • Followed the coding style (make pylint, make mypy, make isort)
  • make test passes, and a test case covers the change
  • Added a changelog entry under docs/source/changelog/ and regenerated CHANGELOG.md, if the change is user-visible — N/A — documentation prose only, no library behaviour change

What is the purpose of your pull request?

  • fix — corrects a defect
  • feat — adds a feature
  • perf — changes performance, not behaviour
  • refactor — changes neither behaviour nor performance
  • test — tests only
  • docs — documentation only
  • ci — workflows or build tooling
  • chore — anything else

Description of your pull request and other information

Closes #956. pep.rst described the release gating as it was before #888 changed it, in the present tense.

What was wrong. The page said all four publishing jobs gate on startsWith(github.ref_name, 'v') || PCAPKIT_TAG_EXISTS == 'false', and that this is why "all four jobs skip" on an ordinary commit. Only github reads PCAPKIT_TAG_EXISTS, at create-release.yml:343. The other three read their own target:

job gates on line
tag PCAPKIT_CONDA_TAG_EXISTS :447
pypi PCAPKIT_PYPI_COMPLETE :525
conda PCAPKIT_CONDA_COMPLETE :625

And a guard the page omitted entirely. Each of those three also requires github — and conda also requires tag — to have succeeded or skipped rather than failed. That is what stops an upstream job's legitimate skip cascading into skipping a job whose own evidence says it still has work to do, which is the failure #888 was about. A reader of the old text would not have known the guard existed.

What the rewrite keeps. The shared shape, because it is the genuine common fact: gate on the v* ref, or on evidence the target still needs publishing. The three per-job conditions are named by what they check rather than by their literal boolean expressions, so the page cannot re-acquire a condition string that drifts the way this one did.

Cross-page consistency. releasing.rst:109 already states the same rule as a prohibition — do not gate a release job on whether the v* tag exists — so the two pages contradicted each other, with the wrong one reading as the description of the system. They now agree. releasing.rst is untouched; #953 owns it.

Verification. tests/project/test_release_gates.py already pins this exact shape — test_github_still_gates_on_the_v_tag_it_creates, test_tag_gates_on_its_own_conda_tag_evidence, test_pypi_gates_on_its_own_file_count_evidence, test_conda_gates_on_its_own_aggregate_evidence, test_evidence_gated_jobs_survive_a_legitimately_skipped_predecessor. It passes unchanged: 34 tests, 23 subtests, re-derived as 34 tests, OK under plain unittest. So the facts were already tested; only the prose disagreed. No test pins pep.rst's text. The edited block parses under docutils.

Not verified: no sphinx-build was run, so a cross-reference regression in the edited block is possible. No workflow file was changed.

@JarryShaw JarryShaw added docs Pull requests that change documentation only (docs: subject prefix) review: pending No verdict for the current head - never reviewed, or the head moved since the last one labels Oct 1, 2026
@JarryShaw
JarryShaw force-pushed the docs/956-pep-release-gating branch from 0016387 to 6bf5baa Compare October 1, 2026 04:30
@JarryShaw

Copy link
Copy Markdown
Owner Author

NEEDS CHANGES at 00163872a — opus cross-review, round 1. Three real findings, all confirmed against the workflow and the test file before acting, all fixed at 6bf5baa94.

  1. "Only github reads PCAPKIT_TAG_EXISTS" was false file-wide. release_status reads it at :877 and consumes it at :927 and :984, gating only on !cancelled() at :863. True of gating, not of reading — now "gates on". The point lands harder than a word usually would: the sentence I replaced was an over-broad absolute about this exact output, so a second over-broad absolute is the wrong repair.
  2. "to have succeeded or skipped rather than failed" landed on the gloss the workflow exists to forbid. The real clause is == 'success' || == 'skipped', which also excludes cancelled. create-release.yml:121-128 says so explicitly, and test_release_gates.py:624 asserts != 'failure' must not appear. Dropped the tail; the cancelled exclusion is now stated as the reason for the spelling.
  3. The list of extra requirements read as exhaustive and omitted needs.version_check.result == 'success', which is in all three conditions and is load-bearing: !cancelled() disables the default success() over the whole needs: list, so it has to be re-added by hand. Now named.

Also took its gloss on pypi: PCAPKIT_PYPI_COMPLETE is a count against an expected 8, not an identity check, so "holds every file" overstated it. Now "PyPI's file count for the version has reached the expected total", matching releasing.rst.

It verified the four conditions independently, walked both an ordinary commit and a version bump through all four, and confirmed test_release_gates.py — 34 passed / 23 subtests, re-derived as 34 OK. Useful detail for anyone re-running it: python -m unittest tests.project.test_release_gates fails with ModuleNotFoundError under PYTHONSAFEPATH=1; unittest discover -t . -s tests/project -p test_release_gates.py is the form that works.

It also found that releasing.rst:176-177 is wrong about the same guard — it states !cancelled() && needs.<job>.result != 'failure', which no job uses. I verified: the only two occurrences of that spelling in the workflow are comments explaining why it is not used. Filing separately rather than widening this PR, since #953 owns that file.

One suggestion I declined: replacing the cascade-guard sentence with a :doc: pointer to releasing.rst. Shorter, but it would point a corrected paragraph at an uncorrected one. Reconsider once that issue is fixed.

Round 2 running against 6bf5baa94. Staying at review: pending.

The page claimed all four publishing jobs are gated on
`startsWith(github.ref_name, 'v') || PCAPKIT_TAG_EXISTS == 'false'`,
and that an ordinary commit makes "all four jobs skip" for that
reason. Only `github` gates on `PCAPKIT_TAG_EXISTS`
(create-release.yml:343). The other three gate on their own target:

- `tag` on `PCAPKIT_CONDA_TAG_EXISTS` (:447)
- `pypi` on `PCAPKIT_PYPI_COMPLETE` (:525)
- `conda` on `PCAPKIT_CONDA_COMPLETE` (:625)

Three things the page left out, all load-bearing:

- each of those three also requires `version_check` to have strictly
  succeeded, because `!cancelled()` suppresses the `success()` Actions
  prepends over the whole `needs:` list;
- `github` -- and for `conda` also `tag` -- must have succeeded or
  skipped, which is what stops a legitimate skip cascading;
- naming those two states rather than writing `!= 'failure'` is what
  makes a cancelled dependency skip the job below it cleanly instead
  of running it against an artefact never produced (:121-128, pinned
  by test_release_gates.py:624).

The shared shape is kept, since it is the true common fact: gate on
the `v*` ref, or on evidence the target still needs publishing. The
three per-job conditions are named by what they check rather than by
their literal expressions, so the page does not re-acquire a boolean
that can drift.

tests/project/test_release_gates.py pins this shape and passes
unchanged: 34 tests, 23 subtests, re-derived as 34 under plain
unittest.
@JarryShaw
JarryShaw force-pushed the docs/956-pep-release-gating branch from 378acfb to 32d20fc Compare October 1, 2026 04:34
@JarryShaw

Copy link
Copy Markdown
Owner Author

NEEDS CHANGES at 6662c832f… correction: at 6bf5baa94 — opus cross-review, round 2. One blocker, and it was in the one sentence I wrote from scratch.

My fix for round-1 finding 2 stated the mechanism backwards. I had written that the two-state spelling "keeps a cancelled upstream job from" cascade-skipping a job that still has work. It does the opposite, deliberately. Traced through conda (:621-625) with tag cancelled and the run itself not cancelled: !cancelled() is true (it reads the run, not the dependency), (tag == 'success' || tag == 'skipped') is false, so conda skips even though PCAPKIT_CONDA_COMPLETE == 'false'. Under the rejected != 'failure' it would run, into actions/checkout with ref: conda-<version>+0 for a tag never pushed. The clean skip is what the spelling buys; != 'failure' is what trades it away — create-release.yml:126-128 and test_release_gates.py:589-594 both say it in that direction.

Its diagnosis of the cause is the useful part: the paragraph credited the whole anti-cascade mechanism to "accepting a skip" while never naming !cancelled(), so it had no vocabulary for what happens to a cancelled dependency — which is how the clause came out inverted. Fixed at 32d20fc97 by naming both steps.

The other three fixes it re-checked and passed, including the one I most expected to have over-corrected: version_check is strict == 'success' with no || 'skipped', correctly distinguished from how github is treated two clauses later.

Two corrections to my own earlier statements, both material. #953 is merged (31b01dbc5, 04:25:22Z) — I had reported it open with two failing checks. And the PR had picked up a Merge branch 'main' commit, so it was two commits rather than the single amended one I described. Rebased onto 31b01dbc5; it is one commit again, +17/−5, pep.rst only.

And #953 merged without fixing releasing.rst's guard, so #958 is no longer blocked behind it — it is now the only thing standing between main and a page that misstates the guard. Verified on main at :173-175. Worth noting for whoever checks: grep "!= 'failure'" finds only the correct unit-tests occurrence at :171, because the wrong one wraps across a line break.

Round 3 running against 32d20fc97. Staying at review: pending.

@JarryShaw

Copy link
Copy Markdown
Owner Author

GOOD TO GO at 32d20fc97 — opus cross-review, round 3. No new defects; the paragraph has converged after two real ones.

I verified its structural claims myself: git diff --stat 31b01dbc5...32d20fc97 is pep.rst alone, +20/−5, a single commit sitting directly on main, and git diff 31b01dbc5 32d20fc97 -- .github/ tests/ is empty. So round 1's reading of the four if: conditions and the 34-test pass carry forward by construction — it deliberately did not re-run them, which is the right call.

On the repaired sentence it went further than confirming the direction. It checked whether "running against an artefact that was never produced" generalises beyond conda, and it does: pypi has an active ref: v${{ … }} checkout at :543, so a cancelled github under != 'failure' would send it to a tag that does not exist. tag's own checkout ref is commented out at :458, so for tag the harm differs in kind — it would push conda-<version>+0 for a Release never created — but is the same category. conda is simply the sharpest case.

It also confirmed the two-step framing is an improvement rather than a repair: with !cancelled() present the if: is evaluated as written, so the hand-written == 'success' || == 'skipped' is where the cascade could be reintroduced — == 'success' alone would skip pypi behind a legitimately skipped github again.

Two notes I am not acting on, and why.

Still unverified by anyone: no sphinx-build has been run on this page at any round. docutils parses the block cleanly, which is weaker evidence.

One thing worth your attention beyond this PR: main currently ships one page stating this guard correctly and one stating it wrongly. #958 is what closes #956's subject properly, and a worker is on it.

Labelled review: good-to-go. CI is still running on this head, so not ready to merge yet — and the merge is yours.

@JarryShaw JarryShaw added review: good-to-go Cross-review at the current head says ready; CI state is separate and removed review: pending No verdict for the current head - never reviewed, or the head moved since the last one labels Oct 1, 2026
@JarryShaw
JarryShaw merged commit 9722ba0 into main Oct 1, 2026
63 checks passed
@JarryShaw
JarryShaw deleted the docs/956-pep-release-gating branch October 1, 2026 05:16
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Oct 1, 2026
@JarryShaw JarryShaw added this to the 1.5 milestone Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Pull requests that change documentation only (docs: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

docs(contributing): pep.rst describes the pre-#888 release gating as current

1 participant