fix(plan,cargo-failure): build publish graph from manifest deps; classify dep-resolution failures as permanent (#173)#175
Conversation
…sify dep-resolution failures as permanent (#173) Two related bugs surfaced by the uselesskey workspace publish failure (#173): ## Primary: planning graph misses optional workspace deps build_plan constructed the workspace dependency DAG from cargo_metadata's feature-resolved `resolve.nodes`. That graph omits optional path+version deps that are not active under the default feature set. cargo publish, however, still needs every optional workspace path+version dep to be resolvable from the registry at publish time, so those edges must participate in publish ordering. Concretely, `uselesskey-aws-lc-rs` declares optional normal path+version deps on `uselesskey-rsa`/`uselesskey-ecdsa`/`uselesskey-ed25519`. Because those edges were absent from `resolve.nodes`, Shipper saw `uselesskey-aws-lc-rs` as indegree zero, the deterministic `BTreeSet<(name, id)>` ready queue emitted it early by name, and the plan looked alphabetical. It was actually a correct topological sort of an incomplete graph. The "publishable depends on non-publishable workspace member" guard at the same site had the same defect — same iteration source. Fix: switch both edge construction and the validation guard to use manifest-level `Package.dependencies`. Include `Normal | Build`, including optional and target-specific deps; exclude `Dev`. Path deps are resolved to workspace members via a directory→PackageId map. Not switching to `cargo metadata --all-features`: that would surface optional deps but couples planning to "all features build", an unrelated and expensive constraint. ## Secondary: ambiguous classification on dep-resolution failures `crates/shipper-cargo-failure` did not match Cargo's dep-resolution error messages, so a publish failure caused by a missing registry dep (exactly the failure mode produced by the planning bug above) fell through to `Ambiguous`. The retry loop then hid the actionable Cargo stderr behind a sequence of "publish outcome ambiguous; registry did not show version" retries. Add four permanent patterns: - `failed to select a version for the requirement` - `no matching package named` - `candidate versions found which didn't match` - `required dependency is missing from the registry` ## Tests - `build_plan_orders_optional_workspace_dependencies` — `aaa-adapter` optional-depends on `zzz-core`; alphabetical order is `aaa-adapter, zzz-core` but the correct publish order is `zzz-core, aaa-adapter`. Fails on the prior implementation. - `build_plan_rejects_optional_normal_dep_on_non_publishable_workspace_member` — same defect in the validation path. - `realworld_dep_resolution_without_verify_framing` — Cargo's dep-resolution stderr without the surrounding "failed to verify package tarball" framing. Misclassified as Ambiguous before. - `realworld_no_matching_package_named` — the package-not-found shape. Existing 234 plan tests and 190 classifier tests continue to pass.
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
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. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
✨ 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 |
|
Droid finished @EffortlessSteven's task —— View job Droid Review — PR #175 ✅Status: approved — no actionable findings. Inspected surfaces
Checks performed
Why no commentsNo publish-state or registry-truth changes outside the intended fix surface. The change is a targeted bug fix in two isolated subsystems (plan graph construction + error classification). No unsafe code introduced. No token handling, event ordering, or state projection changes. The regression tests provide direct coverage of the reported failure modes. Residual riskRegistry-side ambiguity remains; this PR does not address the broader Reconcile gap tracked in #102/#99. This is known and out of scope for #173. Validation signal
|
Summary
Fixes #173. Two related bugs, one root cause:
Primary: planning graph misses optional workspace deps
build_planincrates/shipper-core/src/plan/mod.rsconstructed the workspace dependency DAG fromcargo_metadata's feature-resolvedresolve.nodes. That graph omits optional path+version dependencies that are not active under the default feature set.cargo publish, however, still needs every optional workspace path+version dep to be resolvable from the registry at publish time, so those edges must participate in publish ordering.Concretely,
uselesskey-aws-lc-rsdeclares optional normal path+version deps onuselesskey-rsa/uselesskey-ecdsa/uselesskey-ed25519. Because those edges were absent fromresolve.nodes, Shipper sawuselesskey-aws-lc-rsas indegree zero, the deterministicBTreeSet<(name, id)>ready queue emitted it early by name, and the plan looked alphabetical. It was a correct topological sort of an incomplete graph.The "publishable depends on non-publishable workspace member" guard at the same site (
mod.rs:160-189) had the same defect — same iteration source.Fix: switch both edge construction and the validation guard to manifest-level
Package.dependencies. IncludeDependencyKind::Normal | DependencyKind::Build, including optional and target-specific deps; excludeDev. Path deps are resolved to workspace members via a directory→PackageIdmap.Not switching to
cargo metadata --all-features: that would surface optional deps but couples planning to "all features build", an unrelated and expensive constraint.Secondary: ambiguous classification on dep-resolution failures
crates/shipper-cargo-failure/src/lib.rsdid not match Cargo's dep-resolution error messages, so a publish failure caused by a missing registry dep (exactly the failure mode produced by the planning bug above) fell through toAmbiguous. The retry loop then hid the actionable Cargo stderr behind a sequence of "publish outcome ambiguous; registry did not show version" retries.Adds four permanent patterns:
failed to select a version for the requirementno matching package namedcandidate versions found which didn't matchrequired dependency is missing from the registryTests
New regression tests:
build_plan_orders_optional_workspace_dependencies—aaa-adapteroptional-depends onzzz-core. Alphabetical order isaaa-adapter, zzz-core; correct publish order iszzz-core, aaa-adapter. Fails on the prior implementation.build_plan_rejects_optional_normal_dep_on_non_publishable_workspace_member— same defect in the validation path.realworld_dep_resolution_without_verify_framing— Cargo dep-resolution stderr without the surrounding "failed to verify package tarball" framing. Misclassified asAmbiguousbefore this PR.realworld_no_matching_package_named— the package-not-found shape.Existing 234 plan tests and 190 classifier tests continue to pass.
Validation performed locally
cargo check --workspace --all-targets --locked— cleancargo clippy -p shipper-core -p shipper-cargo-failure --all-targets --locked -- -D warnings— no issuescargo fmt --all -- --check— cleancargo test -p shipper-core --lib plan::— 236 passed (234 existing + 2 new)cargo test -p shipper-cargo-failure— 192 passed (190 existing + 2 new)Snapshot
permanent_pattern_exhaustive.snapupdated with the four new patterns.Test plan
uselesskeyworkspace publish that surfaced shipper publish: plan order appears alphabetical rather than topological; first-listed crate has unmet workspace deps #173 (or the smallest reproducer the user has) to confirm the plan now orders the optional deps correctly.