Repository navigation
fix(release): align release inventories with the crates.io publish plan - #1376
Conversation
`crate-publish-plan.py list` emits 20 crates, but every hand-maintained
crates.io inventory carried only 17. `graphforge-discovery`,
`graphforge-observability`, and `graphforge-portable-oci` were missing, so
offline rehearsal rejected the assembled candidate with "unexpected crates.io
package identity". The same three crates also shipped no NOTICE, which
`release_candidate_manifest._validate_crate` requires inside every packaged
`.crate`, so both halves land together.
- add the three crates to `release_candidate_manifest.CRATES`,
`clean-env-verify.DEFAULT_CRATES`, and
`verify_package_licenses.CARGO_PUBLISH_CRATES`, restating each inventory in
the publish plan's topological order
- add the three crate directories to `license_check.CARGO_PACKAGE_DIRS`, which
also extends NOTICE_COPIES coverage
- add `crates/graphforge-{discovery,observability,portable-oci}/NOTICE`, byte
identical to the other 17 crates and the workspace root
- fail closed on future drift: `test-crate-publish-plan.py` now asserts every
inventory equals `crate-publish-plan.py list`, that the license gate covers
each publishable crate directory, and that each one has a NOTICE
- keep the `DEFAULT_CRATES` shape assertion in `test-clean-env-verify.py` and
update it to 20, naming the three recovered crates
- derive the 26/17 node and package counts in the release candidate,
registry, and rehearsal tests from the inventories instead of hardcoding
- refresh publication-order.md and release-artifact-record.md: the release is
29 nodes over 20 crates, and the printed order was missing
`graphforge-value` and `graphforge-portable-oci`
Closes #1373
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Problem
python3 scripts/ci/crate-publish-plan.py listemits 20 crates. Everyhand-maintained crates.io inventory carried 17.
graphforge-discovery,graphforge-observability, andgraphforge-portable-ociwere missing, so theoffline rehearsal rejected the assembled candidate:
The same three crates also shipped no
NOTICE, whichrelease_candidate_manifest._validate_craterequires inside every packaged.crate, so fixing only the inventory moved the failure one step along. Bothhalves land here.
Changes
release_candidate_manifest.CRATES,clean-env-verify.DEFAULT_CRATES, andverify_package_licenses.CARGO_PUBLISH_CRATESnow hold all 20 crates,restated in the publish plan's topological order.
license_check.CARGO_PACKAGE_DIRScovers the three crate directories, whichalso extends
NOTICE_COPIES(identical-content check) and thelicense-file.workspace/repository.workspacemanifest assertions to them.crates/graphforge-discovery/NOTICE,crates/graphforge-observability/NOTICE,and
crates/graphforge-portable-oci/NOTICEadded, byte-identical to the other17 crates and the workspace root (all 20 crate NOTICE files now hash to
ab29064bf950b34ee9a12d9e9fb2798d).scripts/ci/test-crate-publish-plan.pyfails closed on future drift: eachinventory must equal
crate-publish-plan.py list, the license gate must coverevery publishable crate directory, and every publishable crate must have a
NOTICE. Verified negatively by deleting one entry — the test fails with adiff of expected vs found.
scripts/ci/test-clean-env-verify.pykeeps itsDEFAULT_CRATESshapeassertion, updated to 20 and naming the three recovered crates.
26-node /17-package literals in the release candidate, registry, andrehearsal tests are now derived from the inventories, so they track the
publish set instead of going stale.
docs/development/publication-order.mdandrelease-artifact-record.md: therelease is 29 nodes over 20 crates, and the printed order was missing
graphforge-valueandgraphforge-portable-oci.Deriving the inventories from
crate-publish-plan.pyat runtime was consideredand rejected: those inventories are the fail-closed identity allowlist for
offline candidate validation, and computing them from the on-disk
crates/tree would let a partial or tampered checkout redefine what the gate accepts.
The explicit lists stay, with a test that fails when they diverge.
Verification
Packaged archive proof
Each archive was then run through the real gate that rejected them before:
The
.cratefiles were deleted afterwards.Other inventories checked
scripts/publish_dry_run.py:FALLBACK_CARGO_ORDERholds a stale 16-crate list(missing
graphforge-value,graphforge-discovery,graphforge-observability,graphforge-portable-oci). It is only reachedwhen
scripts/ci/crate-publish-plan.pyis absent from the branch, which is nolonger possible, so it is dead and left untouched rather than becoming a fifth
list to maintain. Worth deleting separately.
config/gate-registry.jsondoes not enumerate crates;make gate-registry-checkpasses unchanged.
docs/development/bazel-migration-ledger.md) andtools/bazel/parity/migration_target_map.jsonalready map all three crates.Closes #1373
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.