Skip to content

ci: exact-pin the internal path dependencies so publish verification resolves locally - #105

Merged
AdaWorldAPI merged 1 commit into
mainfrom
claude/ruff-publish-dryrun-exact-pins
Aug 21, 2026
Merged

AdaWorldAPI merged 1 commit into
mainfrom
claude/ruff-publish-dryrun-exact-pins

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

The failure

cargo publish --workspace --dry-run has been red on every branch since 2026-08-20. The packaged ruff_graph builds against two copies of ruff_cache and cannot call cache_key:

note: there are multiple different versions of crate `ruff_cache` in the dependency graph
  --> .../index.crates.io-.../ruff_cache-0.0.10/src/cache_key.rs:74:1   <- expected trait
  ::: .../-9cf9d774767a10c8/ruff_cache-0.0.9/src/cache_key.rs:74:1      <- imported trait

The last green run on main was 2026-08-18, with no commit in between.

It is a duplicate-crate error, not an unmigrated API

The two paths in that note point at the same file and the same line. That is the tell, and the bytes confirm it:

$ diff -rq ruff_cache-0.0.9/src ruff_cache-0.0.10/src
  SRC IDENTICAL

$ diff -u ruff_cache-0.0.9/Cargo.toml ruff_cache-0.0.10/Cargo.toml
  -version = "0.0.9"   +version = "0.0.10"      (twice — the entire delta)

$ diff -rq crates/ruff_cache/src ruff_cache-0.0.10/src
  identical

ruff_cache 0.0.10 differs from 0.0.9 by two version lines in its manifest. Upstream re-releases the whole internal crate set on every ruff release whether or not a crate changed. There is no 0.0.10 API and nothing to migrate — rustc simply treats two copies of one identical trait as two distinct types.

Where the second copy comes from

ruff_linter = { version = "0.16.3", path = "crates/ruff_linter" } is a caret range. It admits upstream's 0.16.4, published 2026-08-20 18:00:49 UTC — the same release wave as ruff_cache 0.0.10 at 18:00:34 — and that release depends on ruff_cache 0.0.10. So verification pulls a second ruff_cache in behind our own.

The two registry sources in the log are worth naming: index.crates.io-… is crates.io, and -9cf9d774767a10c8 is the temporary local registry cargo publish --workspace builds from the freshly packaged members. Local resolution already works — the imported ruff_python_parser 0.0.9 comes from there despite an upstream 0.0.9 existing. Only the caret range lets an upstream release back in.

The change

Exact-pin all 36 internal path dependencies (version = "=X"), leaving the locally packaged copy as the only candidate. Root Cargo.toml only; no crate version changes, no lockfile change, no source change.

Measured, on the pinned toolchain (1.97.1, per rust-toolchain.toml)

cargo publish --workspace --dry-run, the exact CI command:

  • ruff_graph verifies clean — the crate that failed with 5 errors.
  • ruff_linter verifies clean.
  • Zero index.crates.io/ruff_* substitutions anywhere in the compile.
  • 37 crates verified before the run hit No space left on device on this sandbox (target/ at 12 G against a 511 M remainder) at ty_python_semantic. That is the local disk allowance, not a build failure; a CI runner has the headroom. Stated rather than rounded up to "green".

A rejected alternative, recorded because it measured worse

Bumping the 0.0.9 set to 0.0.10 first looked obvious. It is worse: upstream ruff_linter 0.16.4 then wins resolution and fails with 3881 errors (RuleGroup not found, group is not a member of ViolationMetadata) instead of ruff_graph's 5. Version labels chase a moving target — upstream keeps releasing. The requirement shape is the defect.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AGVLyRZNEKKBSfBDJfbY3V


Generated by Claude Code

…resolves locally

cargo publish --workspace --dry-run has been red since 2026-08-20 on
every branch. The packaged ruff_graph builds against two versions of
ruff_cache at once: our locally packaged 0.0.9, and 0.0.10 pulled from
crates.io. The second one arrives through ruff_linter. Its requirement
is a caret range, version = 0.16.3, which admits the 0.16.4 that
upstream published on 2026-08-20 18:00 UTC, and that release depends on
ruff_cache 0.0.10. The last green run on main was 2026-08-18, so the
job went red with no commit in between and will keep going red on every
upstream release.

Pin all 36 internal path dependencies exactly. During a workspace
publish cargo packages the members into a temporary local registry and
prefers it for co-published crates, which the failing log itself shows:
the imported ruff_python_parser 0.0.9 comes from that local registry
even though upstream also has a 0.0.9 on crates.io. An exact requirement
leaves the local copy as the only candidate, so no upstream release can
be substituted into the verification build.

A version bump was tried first and measured worse: relabelling the 0.0.x
set to 0.0.10 makes upstream ruff_linter 0.16.4 win the resolution and
ruff_linter fails to compile with 3881 errors instead of ruff_graph with
5. Version labels chase a moving target; the requirement shape is the
actual defect.
@cursor

cursor Bot commented Aug 21, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_c91446d5-7059-471f-ba0f-97ada26c53d8)

@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review August 21, 2026 11:03
@AdaWorldAPI
AdaWorldAPI merged commit f455078 into main Aug 21, 2026
31 of 33 checks passed
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.

2 participants