Skip to content

fix: make internal test-helper deps path-only in workspace.dependencies#569

Merged
EffortlessSteven merged 1 commit into
mainfrom
fix/workspace-internal-deps-path-only
May 11, 2026
Merged

fix: make internal test-helper deps path-only in workspace.dependencies#569
EffortlessSteven merged 1 commit into
mainfrom
fix/workspace-internal-deps-path-only

Conversation

@EffortlessSteven

Copy link
Copy Markdown
Member

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

  • CI green
  • After merge: dry-run `publish-retry.yml` on retagged v0.7.0 — plan should not show test-helper publish requirements
  • Live shipper publish completes the remaining ~50 crates

`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.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@EffortlessSteven has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 30 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a03c2c25-a495-4ed8-84fe-e3e2442f96c3

📥 Commits

Reviewing files that changed from the base of the PR and between ec5956f and 2d4ab7a.

📒 Files selected for processing (1)
  • Cargo.toml
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/workspace-internal-deps-path-only

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@EffortlessSteven EffortlessSteven merged commit 69ab4b4 into main May 11, 2026
6 checks passed
@EffortlessSteven EffortlessSteven deleted the fix/workspace-internal-deps-path-only branch May 11, 2026 12:43
EffortlessSteven added a commit that referenced this pull request May 11, 2026
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.
EffortlessSteven added a commit that referenced this pull request May 11, 2026
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.
EffortlessSteven added a commit that referenced this pull request May 11, 2026
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.
@EffortlessSteven EffortlessSteven mentioned this pull request May 11, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant