fix: make internal test-helper deps path-only in workspace.dependencies#569
Conversation
`cargo publish` of every published workspace crate that consumes a
test-helper via `[dev-dependencies] foo = { workspace = true }` was
failing with:
error: failed to prepare local package for uploading
Caused by: no matching package named \`uselesskey-test-support\` found
location searched: crates.io index
because the `workspace.dependencies` entries for `uselesskey-test-support`,
`uselesskey-test-grid`, and `uselesskey-feature-grid` carried
`version = "0.7.0"`. Even for dev-deps, cargo requires the workspace
version constraint to resolve against crates.io during publish — and
these three crates are explicitly `publish = false`, so they never reach
crates.io.
Strip `version` from the three entries and keep them path-only. Cargo
treats path-only dev-deps as workspace-only and strips them from the
published manifest, which is the right behavior:
- `uselesskey-test-support` — used as `[dev-dependencies]` by
`uselesskey-entropy`, `uselesskey-core`, `uselesskey-core-x509`,
`uselesskey-core-keypair`, `uselesskey-core-keypair-material`,
`uselesskey-core-id`.
- `uselesskey-test-grid` — used as `[dev-dependencies]` by
`uselesskey-bdd` (also `publish = false`).
- `uselesskey-feature-grid` — workspace-only.
Verified:
cargo publish --dry-run -p uselesskey-core --allow-dirty
# was: error ... no matching package \`uselesskey-test-support\`
# now: warning: aborting upload due to dry run (clean)
This unblocks the v0.7.0 publish recovery. With workspace verification
succeeding for `uselesskey-core` and its sibling crates, shipper should
now walk the DAG without the spurious test-helper gap.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
Shipper 0.3.0-rc.2 emits the publish plan in alphabetical-looking order rather than topological order (EffortlessMetrics/shipper#173). With \`uselesskey-aws-lc-rs\` at position 1 and \`uselesskey-core\` at #2, shipper's linear walk fails immediately because cargo publish of aws-lc-rs requires uselesskey-ecdsa (#22) and other deps to already be on crates.io. The owner of shipper will fix this in the next patch. Until then, revert both \`release.yml\` and \`publish-retry.yml\` to use \`cargo xtask publish\`. The PUBLISH_CRATES order is correct after #565, and the test-helper dev-dep fix in #569 removes the cargo verification gap that the original cargo xtask path also tripped over. Keep \`.shipper/\` in \`.gitignore\` and the existing \`Quality gate\` / \`Publish preflight\` / \`Publish dry-run\` steps in preflight job — those are unaffected by the shipper revert and still useful. After this PR merges, retag v0.7.0 on the new main HEAD and let \`release.yml\` run end-to-end. shipper#173 stays open for the next release cycle.
The v0.7.0 release lane failed because `[workspace.dependencies]` had `version = "0.7.0"` declared on three internal `publish = false` crates (`uselesskey-test-support`, `uselesskey-test-grid`, `uselesskey-feature-grid`). Even though those entries were only consumed as `[dev-dependencies]`, `cargo publish` resolves the workspace version constraint against crates.io and fails with `no matching package named ...`. PR #569 stripped the offending `version` fields to fix the instance, but the class of bug — a versioned workspace.dependencies entry pointing at a non-publishable crate — could silently recur the next time someone bumps versions across the manifest. This adds `verify_no_versioned_publish_false_deps()`: it parses the workspace `Cargo.toml`, walks every `[workspace.dependencies]` inline-table entry that declares both `path` and `version`, opens the referenced crate's `Cargo.toml`, and bails if `[package].publish` is `false`. All violations are collected and reported together so the fix is a single pass. The check is wired into both `publish_check()` and `run_publish_preflight()` (as a new `preflight:publish-false-dep-guard` step) so it runs ahead of any cargo packaging work and on the cheap gate PRs already run. A unit test asserts the function returns `Ok(())` on the current workspace (post-#569). If anyone re-introduces a `version` field on a path that resolves to a `publish = false` crate, the test and the preflight gate both fail before a tag push can land.
The v0.7.0 release lane failed because `[workspace.dependencies]` had `version = "0.7.0"` declared on three internal `publish = false` crates (`uselesskey-test-support`, `uselesskey-test-grid`, `uselesskey-feature-grid`). Even though those entries were only consumed as `[dev-dependencies]`, `cargo publish` resolves the workspace version constraint against crates.io and fails with `no matching package named ...`. PR #569 stripped the offending `version` fields to fix the instance, but the class of bug — a versioned workspace.dependencies entry pointing at a non-publishable crate — could silently recur the next time someone bumps versions across the manifest. This adds `verify_no_versioned_publish_false_deps()`: it parses the workspace `Cargo.toml`, walks every `[workspace.dependencies]` inline-table entry that declares both `path` and `version`, opens the referenced crate's `Cargo.toml`, and bails if `[package].publish` is `false`. All violations are collected and reported together so the fix is a single pass. The check is wired into both `publish_check()` and `run_publish_preflight()` (as a new `preflight:publish-false-dep-guard` step) so it runs ahead of any cargo packaging work and on the cheap gate PRs already run. A unit test asserts the function returns `Ok(())` on the current workspace (post-#569). If anyone re-introduces a `version` field on a path that resolves to a `publish = false` crate, the test and the preflight gate both fail before a tag push can land.
Summary
v0.7.0 publish blocker. Every `cargo publish` of a workspace crate that consumes a test-helper via `[dev-dependencies] foo = { workspace = true }` was failing:
```
error: failed to prepare local package for uploading
Caused by: no matching package named `uselesskey-test-support` found
location searched: crates.io index
```
The `workspace.dependencies` entries for the three internal test-helper crates carried `version = "0.7.0"`:
```toml
uselesskey-test-grid = { path = "crates/uselesskey-test-grid", version = "0.7.0" }
uselesskey-test-support = { path = "crates/uselesskey-test-support", version = "0.7.0" }
uselesskey-feature-grid = { path = "crates/uselesskey-feature-grid", version = "0.7.0" }
```
Even for dev-deps, cargo requires the workspace version constraint to resolve against crates.io during publish — but all three crates are `publish = false` and never reach crates.io.
Fix
Strip `version` from those three entries — keep them path-only. Cargo strips path-only dev-deps from the published manifest, which is the correct behavior for workspace-internal test helpers.
Validation
Before:
```
$ cargo publish --dry-run -p uselesskey-core --allow-dirty
error: failed to prepare local package for uploading
Caused by:
no matching package named `uselesskey-test-support` found
```
After:
```
$ cargo publish --dry-run -p uselesskey-core --allow-dirty
Packaging uselesskey-core v0.7.0 (...)
... (clean) ...
warning: aborting upload due to dry run
```
Why this only surfaced now
The three crates were given workspace versions during the v0.7.0 fold-into-srp work so they could be referenced consistently via `{ workspace = true }`. Pre-v0.7.0 they were only referenced via direct paths and the version mismatch never bit. The shipper migration in #566 made the failure visible because shipper actually runs `cargo package` per crate at preflight.
Recovery sequence
After this PR merges, delete + retag `v0.7.0` on the new main HEAD and re-trigger publish-retry. The 3 crates already on crates.io at 0.7.0 (`uselesskey-core-hmac-spec`, `uselesskey-jwk`, `uselesskey-core-jwk`) stay where they are; shipper reconciles.
Test plan