Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
# the web UI for no gain.
#
# The security link exists because ``SECURITY.md`` asks reporters not to open a
# public issue for anything exploitable, and until now the chooser offered no way
# to comply -- the only visible route was the public bug template.
# public issue for anything exploitable, and without it the chooser would offer
# no way to comply -- the only visible route would be the public bug template.

blank_issues_enabled: true

Expand Down
2 changes: 1 addition & 1 deletion .github/coverage.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Coverage configuration for the one coverage-measured leg of unit-tests.yml
# (`test`, Python 3.15), passed with `--rcfile`. Coverage reads a single config
# file, so this repeats pyproject.toml's [tool.coverage.*] settings and adds the
# three below on top. tests/project/test_coverage_rcfile.py asserts every
# four below on top. tests/project/test_coverage_rcfile.py asserts every
# pyproject setting is repeated here unchanged.
#
# parallel -- each process writes its own .coverage.* file, merged afterwards
Expand Down
8 changes: 4 additions & 4 deletions .github/python-versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
# and proposes each change, and the ruleset 23497679 edit it needs, as a PR.
#
# Tiers: supported (blocking), ktlo (end-of-life, non-blocking), pre-release
# (non-blocking; none listed today) and experimental (non-blocking, a workflow
# of their own; see below). `runner` is the image a version needs when
# (non-blocking; python_versions.py refuses it) and experimental (non-blocking, a
# workflow of their own; see below). `runner` is the image a version needs when
# ubuntu-latest cannot provide it. `latest` is the newest supported CPython,
# which the single-interpreter jobs run on. See docs/source/contributing/workflows.rst.

Expand Down Expand Up @@ -62,8 +62,8 @@ job = "conda"
where = "Conda environment creation and activation: with.python-version"
value = "3.15"

# As for create-release.yml's conda job: conda-forge's conda has no py315 build
# yet.
# As for create-release.yml's conda job: conda-forge's conda has no py315
# build.
[[exemptions]]
workflow = "cron-conda.yml"
job = "conda-dist"
Expand Down
16 changes: 8 additions & 8 deletions .github/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
# matching on the `type(scope):` subject prefix this project actually uses, so
# the type a pull request announces in its title cannot reach this file.
#
# A labelling programme has since put a type label on every merged pull request
# (zero exceptions, and every new one too), so the old survey this file cited --
# 40 pull requests, mostly untyped, hence a bare Dependencies/catch-all split --
# is stale, and a category per label is now possible. Sampling 334 merged pull
# requests (`gh pr list --state merged --limit 400`) gives the frequency below;
# zero carry no type label:
# Merged pull requests carry a type label, set by hand, which is what makes a
# category per label possible -- an earlier survey of 40 pull requests,
# mostly untyped, supported only a bare Dependencies/catch-all split.
#
# Sampling 334 merged pull requests (`gh pr list --state merged --limit 400`)
# gives the frequency below; zero carry no type label:
#
# fix 124, dependencies 97, breaking 50, ci 41, test 31, docs 28, feat 12,
# release 10, chore 9, perf 7, const 2, refactor 2
Expand Down Expand Up @@ -67,8 +67,8 @@
# of everything else on a first read. This file takes the former; flip its
# position in the list below if that judgement is wrong.
#
# `*` catches whatever matches none of the categories above -- currently
# nothing, since every merged pull request carries a type label, but it stays
# `*` catches whatever matches none of the categories above -- nothing in the
# sample, since every pull request in it carries a type label, but it stays
# last regardless so an unlabelled future pull request still lands somewhere
# instead of silently vanishing from the notes.
#
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
# against a commit the Unit Tests workflow is already testing, and it bought
# nothing: CodeQL reads the source, so its findings do not depend on the test
# suite passing. Worse, it meant a failing test suppressed the security
# analysis for that commit. Static analysis now runs on its own.
# analysis for that commit. Static analysis runs on its own.
analyze:
name: Analyze
runs-on: ubuntu-latest
Expand Down
46 changes: 23 additions & 23 deletions .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ name: Create Release
# #1705: a group holds one pending run and cancels it when another joins, so a
# run whose Vendor Update did not conclude ``success`` -- one ``version_check``
# skips, so it releases nothing -- is keyed on its own ``github.run_id``. Keyed on
# the ref, such a run, 38499295798, displaced the pending 38499150441. Now only a
# the ref, such a run, 38499295798, displaced the pending 38499150441. So only a
# run that may release can wait in ``main``'s group or displace the one waiting
# there, evaluating ``main``'s newer tip instead. A tag push keeps its tag's group.
# GitHub documents the one pending run, and ``github.run_id`` as unique per run:
Expand All @@ -32,8 +32,8 @@ concurrency:
cancel-in-progress: false

# Every job below with an effect outside this run declares a deployment
# ``environment:``, but as of #887 only one of them -- ``github-release`` --
# carries a required reviewer. Four jobs still get four environments rather than
# ``environment:``, but only one of them -- ``github-release`` -- carries a
# required reviewer (#887). Four jobs still get four environments rather than
# one shared ``release``, for credential and blast-radius separation, not for
# approval count:
#
Expand All @@ -43,7 +43,7 @@ concurrency:
# pypi -> pypi an upload to PyPI, and to TestPyPI
# conda -> anaconda an upload to anaconda.org/jarryshaw
#
# Approving the GitHub Release is now the release's *only* approval.
# Approving the GitHub Release is the release's *only* approval.
# ``tag`` and ``pypi`` both carry ``needs: [ github, ... ]``, and ``conda`` needs
# ``tag`` and ``github`` too, so nothing downstream of ``github`` can start before
# that approval lands, and rejecting it leaves nothing tagged and nothing
Expand All @@ -52,7 +52,7 @@ concurrency:
#
# The other three environments keep their names -- ``pypi``'s matters because
# PyPI trusted publishing matches its OIDC claim against it -- and keep their
# secret scoping, they just no longer hold a required reviewer of their own. Do
# secret scoping, they just hold no required reviewer of their own. Do
# not add one back to any of them without re-examining the ``needs:`` chain: a
# reviewer on ``conda-tag`` with its old ``needs: [ version_check ]`` is exactly
# the bug #887 fixed, because it let the commit-to-``main`` and ``conda-*`` tag
Expand Down Expand Up @@ -100,7 +100,7 @@ concurrency:
# ``workflow_run``-triggered attempt reads a tag that already exists and skips
# every job, reporting green. ``github`` still uses that guard for its own
# artefact -- the tag it checks is the one it is about to create -- but ``tag``,
# ``pypi`` and ``conda`` now each read their own evidence instead: ``tag`` checks
# ``pypi`` and ``conda`` each read their own evidence instead: ``tag`` checks
# for the ``conda-<version>+0`` tag it creates, ``pypi`` checks PyPI's file count
# for the version against the count expected, and ``conda`` both checks Anaconda's
# aggregate count as a job-level cost saver and, per leg, whether that leg's own
Expand All @@ -114,7 +114,7 @@ concurrency:
# ``tag``), and GitHub Actions skips a job whose ``needs:`` included a job that
# itself skipped, *before* that job's own ``if:`` is even evaluated -- unless the
# ``if:`` calls a status-check function itself. ``github`` legitimately skips
# whenever its own tag already exists, which is exactly the retry case this fix is
# whenever its own tag already exists, which is exactly the retry case #888 is
# for, so ``tag``, ``pypi`` and ``conda`` all reach for the same escape hatch
# ``unit-tests``'s callers already use for the identical problem --
# ``cron-vendor.yml``, ``deploy-pages.yml`` and ``cron-conda.yml`` all open with
Expand Down Expand Up @@ -149,15 +149,15 @@ concurrency:
# is going to be published. Every successful Vendor Update triggers this
# workflow, and most of them leave ``__version__`` alone, so the gate used to
# run on commits Unit Tests had already passed only for all four jobs below to
# skip (eight times on 2026-10-05 alone). ``unit-tests`` now runs when the ref
# skip (eight times on 2026-10-05 alone). ``unit-tests`` runs when the ref
# is a ``v*`` tag or *any* of the four evidence outputs is not ``'true'``,
# which covers every case in which ``github``, ``tag``, ``pypi`` or ``conda``
# could run: each of them runs only on a ``v*`` ref or on its own evidence
# reading ``'false'``. ``!= 'true'`` rather than ``== 'false'`` is deliberate --
# an evidence output nothing set runs the gate rather than skipping it, which
# can cost a run but never a release.
#
# Moving the gate off the front of the chain means it no longer gates by
# Moving the gate off the front of the chain means it does not gate by
# position, so every publishing job names it instead: ``github`` lists it in
# ``needs:`` and keeps the implicit ``success()`` (its ``if:`` calls no
# status-check function), and ``tag``, ``pypi`` and ``conda`` -- whose
Expand Down Expand Up @@ -221,12 +221,12 @@ jobs:
# read leaves it unset, and ``version_check`` runs as before.
#
# The concurrency group above cannot see this: it reads only the event, and
# that Vendor Update concluded ``success``, so the run still joins ``main``'s
# group and can still displace a run pending there, as before. It used to
# evaluate ``main``'s newer tip in its place; it now releases nothing, so the
# displaced run's release waits for the next run on ``main`` -- the tip's own
# Vendor Update if the tip's Unit Tests run has not completed yet, else the
# next push's or Saturday's.
# that Vendor Update concluded ``success``, so the run joins
# ``main``'s group and can displace a run pending there. It releases
# nothing in that run's place, so the displaced run's release waits for
# the next run on ``main``: the tip's own Vendor Update if the tip's
# Unit Tests run has not completed yet, else the next push's or
# Saturday's.
vendor_update:
name: Triggering Vendor Update
runs-on: ubuntu-latest
Expand Down Expand Up @@ -446,10 +446,10 @@ jobs:
# Python 3.14 -- every earlier interpreter (3.9 through 3.13,
# measured directly) raises `IndentationError: unexpected indent`
# on the leading whitespace this YAML block scalar's own
# indentation would otherwise force onto the source. This step
# runs before `actions/setup-python@v7`, so `python3` here is
# whatever the runner image ships (3.12 on ubuntu-latest as of
# writing), not 3.14. Feeding one line per `printf` argument
# indentation would otherwise force onto the source. This job's
# setup-python step installs `latest` first, but the snippet does
# not lean on that; the conda job's check runs before its own.
# Feeding one line per `printf` argument
# keeps each line's YAML indentation off the actual Python source
# `python3 -` reads from stdin, so nothing is indented that
# Python did not itself put there.
Expand Down Expand Up @@ -786,7 +786,7 @@ jobs:
runs-on: ubuntu-latest
# Pushes a commit to ``main`` and the ``conda-*`` tag. ``permissions: {}``
# does not constrain it -- the write goes through the deploy key and PAT below,
# not the run's token. It carried its own required reviewer until #887; now it
# not the run's token. It has no required reviewer of its own (#887), and
# depends on ``github`` rather than on ``version_check`` alone, precisely so
# the single ``github-release`` approval still gates it -- without that
# ``needs:``, this job would start the moment ``version_check`` finished,
Expand Down Expand Up @@ -954,7 +954,7 @@ jobs:
# ``id-token: write`` that *enables* trusted publishing was re-added below, so
# the block read as disabled as a unit when only its gate still was. #887
# removed this environment's own required reviewer; it is gated only
# transitively now, through ``needs: [ github, unit-tests, version_check ]``
# transitively, through ``needs: [ github, unit-tests, version_check ]``
# below, and the name still matters because PyPI's trusted-publishing claim
# match is keyed on it.
#
Expand Down Expand Up @@ -991,7 +991,7 @@ jobs:
# axis, whose wheels version_check counts. The KTLO tier -- end-of-life,
# still built and published but never blocking -- is added by
# ``include``, without the versions that need an older runner than this
# job's ``ubuntu-latest``: Python 3.10 language level today. Each step
# job's ``ubuntu-latest``, leaving the 3.10 language level. Each step
# that can fail on one carries `continue-on-error: ${{ matrix.ktlo ==
# true }}`, the step-level form, so ``needs.pypi.result`` cannot see it
# -- see the same choice in unit-tests.yml's ``test`` job. #1672: each
Expand Down Expand Up @@ -1190,7 +1190,7 @@ jobs:
# Uploads to anaconda.org/jarryshaw with ``ANACONDA_TOKEN``. This job never had
# an ``environment:`` at all, not even a commented one, so it was the half of
# #641 that was not written down as a thing to turn on. #887 later removed
# this environment's own required reviewer; gating is transitive now, through
# this environment's own required reviewer; gating is transitive, through
# ``needs: [ tag, github, unit-tests, version_check ]`` below. See the note
# above ``jobs:``.
#
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/cron-conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ concurrency:
cancel-in-progress: false

jobs:
# Only earns its runners on the schedule trigger now: `Unit Tests` has no
# Only earns its runners on the schedule trigger: `Unit Tests` has no
# schedule trigger of its own, so Saturday's cron run is the one case left
# where nothing else has already verified this tree. `workflow_run` carries
# its own verdict instead -- see `conda-update` below.
Expand Down Expand Up @@ -95,7 +95,7 @@ jobs:
# skip. `!cancelled()` rather than `always()` so that cancelling the run
# still cancels the update; a gate that actually failed still blocks.
#
# The `workflow_run` clause is the real gate for a push to main now: it
# The `workflow_run` clause is the real gate for a push to main: it
# reads the verdict `Unit Tests` already reached instead of re-running it,
# and `verdict` says whether that verdict covers the commit checked out
# below (#1643). `.event == 'push'` and `.head_branch == 'main'`
Expand Down Expand Up @@ -162,7 +162,7 @@ jobs:
# which raises unless that distribution is installed here -- and that
# file names `dpkt`, `scapy`, `pyshark`, `requests` and `beautifulsoup4`
# with no marker. #910 narrowed `all` to core addons only, so those five
# now come from `dev` instead; without it this step would install
# come from `dev` instead; without it this step would install
# cleanly and the next one would crash on the first missing name.
- name: Install and Setup
run: |
Expand Down Expand Up @@ -219,7 +219,7 @@ jobs:
# drops it as "previously applied", while `files_changed` still reads
# 'true'. Conda Update 38325136710 and 38325153882 were such a pair, both
# on 2e941bbb7 and raised 2 s after two different `Unit Tests` runs, for
# 9083163f5 and for 01151b13f, completed; `verdict` now refuses both.
# 9083163f5 and for 01151b13f, completed; `verdict` refuses both.
# Asking about that file rather than "is a commit left to push" also
# covers a rebase that keeps part of the commit but drops its bump: that
# remainder would land under a build already tagged, so it is not pushed,
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/cron-vendor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ on:
workflows: ["Unit Tests"]
types: [completed]

# Least privilege by default now that `workflow_run` is in the trigger list --
# Least privilege by default, since `workflow_run` is in the trigger list --
# that event can be raised by a pull request's `Unit Tests` run completing, so
# the ambient token this workflow gets should default to nothing rather than
# whatever the repository's default is. Both jobs below already declare their
Expand Down Expand Up @@ -44,7 +44,7 @@ concurrency:
cancel-in-progress: false

jobs:
# Only earns its runners on the schedule trigger now: `Unit Tests` has no
# Only earns its runners on the schedule trigger: `Unit Tests` has no
# schedule trigger of its own, so Saturday's cron run is the one case left
# where nothing else has already verified this tree. `workflow_run` carries
# its own verdict instead -- see `vendor-update` below.
Expand Down Expand Up @@ -100,7 +100,7 @@ jobs:
# skip. `!cancelled()` rather than `always()` so that cancelling the run
# still cancels the update; a gate that actually failed still blocks.
#
# The `workflow_run` clause is the real gate for a push to main now: it
# The `workflow_run` clause is the real gate for a push to main: it
# reads the verdict `Unit Tests` already reached instead of re-running it,
# and `verdict` says whether that verdict covers the commit checked out
# below (#1643). `.event == 'push'` and `.head_branch == 'main'`
Expand Down Expand Up @@ -203,7 +203,7 @@ jobs:
# would already have failed to create the log file at all --
# `cat` on a missing file returns 1 under `-e` and would abort the
# whole step right here, exactly the "one dead crawler kills every
# good regeneration" failure mode this PR exists to remove.
# good regeneration" failure mode this handling exists to remove.
cat "$RUNNER_TEMP/vendor-stderr.log" >&2 || true

if [ "$vendor_exit" -ne 0 ]; then
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/deploy-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ concurrency:
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
# Only earns its runners on the schedule trigger now: `Unit Tests` has no
# Only earns its runners on the schedule trigger: `Unit Tests` has no
# schedule trigger of its own, so Saturday's cron run is the one case left
# where nothing else has already verified this tree, and a gate is still
# needed. Pull requests never published anyway, and `workflow_run` carries
Expand Down Expand Up @@ -94,12 +94,12 @@ jobs:
deploy-pages:
needs: [ unit-tests, verdict ]
# `needs` cannot itself be conditional, so a skipped gate (pull requests,
# and now `workflow_run`) has to be accepted explicitly -- by default this
# and `workflow_run`) has to be accepted explicitly -- by default this
# job would inherit the skip. `!cancelled()` rather than `always()` so that
# cancelling the run still cancels the docs build; a gate that actually
# failed still blocks.
#
# The `workflow_run` clause is the real gate for a push to main now: it
# The `workflow_run` clause is the real gate for a push to main: it
# reads the verdict `Unit Tests` already reached instead of re-running it,
# and `verdict` says whether that verdict covers the commit checked out
# below (#1643). `.event == 'push'` and `.head_branch == 'main'`
Expand Down
Loading
Loading