fix: recover root release provenance safely#1770
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a provenance-only recovery path to the release-please GitHub Actions workflow to regenerate/attach provenance artifacts for already-published modelaudit releases without attempting to rebuild or republish immutable PyPI artifacts. The recovery flow is designed to bind to a specific previously successful publish/verify run and the intended tag, validate artifact integrity against PyPI digests, and fail closed on unsafe archive contents before generating a recovery attestation and SBOM.
Changes:
- Adds a
root_provenance_run_idworkflow_dispatchinput and corresponding “provenance recovery” execution mode inrelease-please.yml. - Introduces a dedicated
root-provenance-recoveryjob that verifies the source run/tag relationship, downloads the original build artifacts, validates them against PyPI, and emits a recovery attestation + SBOM. - Expands the release workflow test suite and updates maintainer documentation to cover provenance recovery.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
tests/test_release_workflow.py |
Adds extensive workflow-structure assertions and executable tests for provenance-only recovery guardrails and failure-closed artifact verification. |
docs/agents/release-process.md |
Documents when/how to run provenance-only recovery and the safety constraints it enforces. |
.github/workflows/release-please.yml |
Adds the provenance recovery input, guards release creation during recovery, tightens provenance job gating, and implements the new root provenance recovery job. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1770 +/- ##
==========================================
+ Coverage 76.25% 76.27% +0.01%
==========================================
Files 217 217
Lines 115193 115278 +85
Branches 27107 27124 +17
==========================================
+ Hits 87845 87928 +83
- Misses 19974 19975 +1
- Partials 7374 7375 +1 🚀 New features to boost your workflow:
|
…ot-provenance-20260720
…ot-provenance-20260720
…ot-provenance-20260720
…ot-provenance-20260720
|
Codex Review: Something went wrong. Try again later by commenting “@codex review”. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Performance BenchmarksCompared
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 99a7c3580e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ] | ||
|
|
||
| assert len(picklescan_requirements) == 1 | ||
| assert picklescan_requirements[0].startswith(f"modelaudit-picklescan>={picklescan_project['version']},") |
There was a problem hiding this comment.
Keep picklescan-only releases independent
When a picklescan-only patch bumps the sibling from, for example, 0.1.9 to 0.1.10, the root requirement >=0.1.9,<0.2.0 still accepts it, but this exact-floor assertion fails CI. Maintainers would have to modify the root dependency—and consequently trigger an unnecessary root release—even though the release process says the components bump independently; validate that the sibling satisfies the declared range rather than requiring every sibling version to become the new floor.
AGENTS.md reference: AGENTS.md:L14-L21
Useful? React with 👍 / 👎.
Summary
Adds a provenance-only recovery path for the already-published root releases without attempting to republish immutable PyPI artifacts. The recovery is bound to the original successful publish/verify run and the intended release tag, rejects unrelated or moved source/tag histories, permits only the two known workflow/test repair files between tag and source, validates exact artifact hashes and tagged metadata, and fails closed on unsafe or ambiguous archive members before generating the recovery integrity attestation and SBOM.
The intended recoveries are:
v0.2.50from run29787069929(fa350d96d2e00e0d54c47f282b7f8e0f9660e077)v0.2.51from run29787493719(ba9cba9568f52ed8464b7a95c46d366e7ba25c6c)Both original runs completed
build,publish-pypi, andverify-pypisuccessfully; their provenance gates were skipped, which this PR truthfully recovers.Validation
actionlint -no-color .github/workflows/release-please.ymlprettier --check .github/workflows/release-please.yml docs/agents/release-process.mdgit diff --check107 passedintests/test_release_workflow.py, including executable negative cases for source/tag divergence, unexpected repair deltas, invalid metadata, archive aliases/collisions, links, devices, and bounded-size failuresNo scanner detections or package constraints are weakened.