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
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ jobs:
working-directory: release-bundle
run: sha256sum --check artifact-sha256.txt
- name: Publish through the configured PyPI Trusted Publisher
uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1, node24
uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3, node24
with:
packages-dir: release-bundle/dist/
print-hash: true
Expand Down
6 changes: 4 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,12 @@ Post-stable invariants:
state read-only, and stop. Do not use another main push or recovery path
until the exact external state is known and recovery is separately
authorized.
Keep the PyPI publisher v1.14.1 pinned to the reviewed commit whose
Keep the PyPI publisher v1.14.3 pinned to the reviewed commit whose
composite action uses the Node 24 `setup-python` fallback. The workflow
checker must reject any other publisher SHA without changing the top-level
workflow, job, environment, or Trusted Publisher identity.
workflow, job, environment, or Trusted Publisher identity. Publisher upgrades
must update the workflow pin, semantic-checker constants, regression tests,
and current maintenance guidance together after reviewing upstream changes.
10. `README.md` is the distribution long description and must remain accurate
before and after publication. Use `python -m pip install cometapi`,
unversioned project links, and publication-neutral maintenance language.
Expand Down
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ direct wheel build with the locked Twine validator. Change the metadata format
or backend pin only together with verified support in the validation and
publication tools.

Dependabot can update a protected publisher Action SHA before its semantic
contract has been reviewed. Review the upstream action definition and runtime
dependencies, then update the workflow SHA and version comment,
`PYPI_PUBLISH_ACTION_SHA` and `PYPI_PUBLISH_ACTION_VERSION` in
`scripts/check_workflows.py`, regression coverage, and current maintenance
guidance in the same pull request. Run the complete checks above and retain the
exact-SHA rejection tests. Do not remove the guard or relax release conditions,
permissions, or protected-environment requirements to make an update pass.

If a check is unavailable, say so in the pull request rather than describing
it as passing.

Expand Down
15 changes: 10 additions & 5 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,17 @@ whose immutable action metadata selects `node24`. The semantic
checker rejects any other pin so the workflow cannot silently regress to the
deprecated Node 20 runtime.

The direct PyPI publisher v1.14.1 is pinned to the reviewed commit. Its only
action-definition change from the previously reviewed publisher is the
conditional `setup-python` fallback moving from Node 20 to Node 24; the
The direct PyPI publisher v1.14.3 is pinned to
`7245906fb61fa33a13554f9d5fb856fe61758086`. The reviewed
[upstream comparison](https://github.com/pypa/gh-action-pypi-publish/compare/ba38be9e461d3875417946c167d0b5f3d385a247...7245906fb61fa33a13554f9d5fb856fe61758086)
retains the composite action definition and Node 24 `setup-python` fallback.
Its runtime updates include Twine, Sigstore, and certifi plus hashed dependency
constraints. The certifi and Sigstore update addresses
[GHSA-5xjx-3w67-w9x9](https://github.com/pypa/gh-action-pypi-publish/security/advisories/GHSA-5xjx-3w67-w9x9).
The semantic checker requires this exact publisher SHA while preserving the
top-level `publish.yml`, `publish` job, `pypi` environment, and Trusted
Publisher identity remain unchanged. The semantic checker requires this exact
publisher SHA.
Publisher identity. Local CI does not exercise OIDC publication or attestations;
those require the separately authorized release workflow.

The job invokes the pinned action release-only first with
`skip-github-pull-request: true`. That step cannot continue on error and is
Expand Down
4 changes: 2 additions & 2 deletions scripts/check_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
RELEASE_PLEASE_ACTION_VERSION = "5.0.0"
RELEASE_PLEASE_ACTION_RUNTIME = "node24"
RELEASE_PLEASE_ACTION = f"googleapis/release-please-action@{RELEASE_PLEASE_ACTION_SHA}"
PYPI_PUBLISH_ACTION_SHA = "ba38be9e461d3875417946c167d0b5f3d385a247"
PYPI_PUBLISH_ACTION_VERSION = "1.14.1"
PYPI_PUBLISH_ACTION_SHA = "7245906fb61fa33a13554f9d5fb856fe61758086"
PYPI_PUBLISH_ACTION_VERSION = "1.14.3"
PYPI_PUBLISH_ACTION_RUNTIME = "node24"
PYPI_PUBLISH_ACTION = f"pypa/gh-action-pypi-publish@{PYPI_PUBLISH_ACTION_SHA}"
RELEASE_PLEASE_BRIDGE_VERSION = "0.1.0-alpha.1"
Expand Down
15 changes: 12 additions & 3 deletions tests/test_release_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,13 +500,22 @@ def test_pypi_publisher_uses_reviewed_node24_action() -> None:
check_publish_workflow(text, LIVE_SMOKE_WORKFLOW.read_text(encoding="utf-8"))


def test_pypi_publisher_rejects_another_full_sha() -> None:
@pytest.mark.parametrize(
"unreviewed_sha",
[
"ba38be9e461d3875417946c167d0b5f3d385a247",
"dc37677b2e1c63e2034f94d8a5b11f265b73ba33",
"cef221092ed1bacb1cc03d23a2d87d1d172e277b",
],
ids=["prior-1.14.1", "prior-1.14.2", "unreviewed"],
)
def test_pypi_publisher_rejects_another_full_sha(unreviewed_sha: str) -> None:
text = PUBLISH_WORKFLOW.read_text(encoding="utf-8").replace(
PYPI_PUBLISH_ACTION,
"pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b",
f"pypa/gh-action-pypi-publish@{unreviewed_sha}",
1,
)
with pytest.raises(RuntimeError, match=r"pypa/gh-action-pypi-publish@ba38be9"):
with pytest.raises(RuntimeError, match=re.escape(PYPI_PUBLISH_ACTION)):
check_publish_workflow(text, LIVE_SMOKE_WORKFLOW.read_text(encoding="utf-8"))


Expand Down
Loading