Repository navigation
fix: break dev-dependency cycle that blocks publishing iceberg-property-macro - #3184
Conversation
…ty-macro `iceberg` depends on `iceberg-property-macro`, and the macro crate had a versioned dev-dependency on `iceberg` via `workspace = true`. When cargo packages the macro crate for publishing it must resolve `iceberg ^0.11.0` from crates.io, which does not exist until the next step, so `cargo publish --workspace` fails with "failed to select a version". This is the same failure that broke the 0.5.0 publish and it reproduces on the v0.11.0-rc.1 tag. Make the dev-dependency path-only so cargo strips it when packaging. Mark the macro crate as internal to `iceberg` in its description and README, and add a `cargo publish --workspace --dry-run` step to CI so an unpublishable crate fails on the PR instead of after the release vote. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
No unresolved blocking issues were identified.
Pull request overview
Fixes the publish-time dependency cycle for iceberg-property-macro and adds CI validation.
Changes:
- Makes the
icebergdev-dependency path-only. - Documents the crate as internal.
- Adds a workspace publish dry-run to CI.
File summaries
| File | Description |
|---|---|
crates/property-macro/README.md |
Documents internal usage. |
crates/property-macro/Cargo.toml |
Removes the versioned dependency cycle. |
.github/workflows/ci.yml |
Validates workspace publishability. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| # Dry-runs the publish.yml command to catch crates that cannot be published, | ||
| # such as packages missing files or dependency cycles between workspace crates. | ||
| - name: Check each crate can be published | ||
| run: cargo publish --workspace --all-features --dry-run |
There was a problem hiding this comment.
this will ensure we catch similar issue in CI time
There was a problem hiding this comment.
this is perfect, I was about to suggest it. thanks for adding it!
There was a problem hiding this comment.
note: we could skip the build if we want it faster with --no-verify, meaning it would just check everything resolves. but I think its worth building from the artifacts as implemented here
There was a problem hiding this comment.
Do we need to run it for every pr? Our publish workflow works on rc, so I think it would be enough to check in on publish workflow?
There was a problem hiding this comment.
@blackmwk Is your concern that it'll use up too much CI time?
We could add --no-verify, which reduces it just to resolution and *.crate file creation.
While we can move it to the publish workflow, I'd rather see us in a state where we're basically "ready" at any time to kick off a release. Front-loading things like crate setup sounds good to me.
There was a problem hiding this comment.
@blackmwk Is your concern that it'll use up too much CI time?
Yes. How about this, we do this check with --no-verify on each pr, and do this check without --no-verify on publish workflow for rc?
There was a problem hiding this comment.
i was debating this too. i think either works, just depends on preference. 😄
|
|
||
| categories = ["database"] | ||
| description = "Property derive macro for Apache Iceberg Rust" | ||
| description = "Apache Iceberg Rust property macros, internal to the iceberg crate" |
There was a problem hiding this comment.
i feel like its a good idea to call this out as "internal", but happy to revert
There was a problem hiding this comment.
+1, I agree to add internal note to description.
| iceberg = { workspace = true } | ||
| # Path-only so cargo strips it when packaging; a versioned dev-dependency would | ||
| # create a publish cycle, since `iceberg` depends on this crate. | ||
| iceberg = { path = "../iceberg" } |
There was a problem hiding this comment.
this is the main fix
dannycjones
left a comment
There was a problem hiding this comment.
lgtm! thanks for this fix and a proper guard against it happening in future
| # Dry-runs the publish.yml command to catch crates that cannot be published, | ||
| # such as packages missing files or dependency cycles between workspace crates. | ||
| - name: Check each crate can be published | ||
| run: cargo publish --workspace --all-features --dry-run |
There was a problem hiding this comment.
this is perfect, I was about to suggest it. thanks for adding it!
| # Dry-runs the publish.yml command to catch crates that cannot be published, | ||
| # such as packages missing files or dependency cycles between workspace crates. | ||
| - name: Check each crate can be published | ||
| run: cargo publish --workspace --all-features --dry-run |
There was a problem hiding this comment.
note: we could skip the build if we want it faster with --no-verify, meaning it would just check everything resolves. but I think its worth building from the artifacts as implemented here
|
|
||
| categories = ["database"] | ||
| description = "Property derive macro for Apache Iceberg Rust" | ||
| description = "Apache Iceberg Rust property macros, internal to the iceberg crate" |
There was a problem hiding this comment.
+1, I agree to add internal note to description.
The full `cargo publish --dry-run` compiles every packaged crate and took 13 minutes per PR. PR CI now runs it with `--no-verify`, which still catches dependency cycles, unresolvable versions, and missing metadata in seconds. The compiled dry-run moves to where it matters for a release: - `create_rc.sh` runs it before creating any artifact or the RC tag, so a crate that cannot be published fails RC creation. Opt out with `--check_publish 0`. - `publish.yml` runs it on RC tag pushes, which previously did nothing, so the exact tag is also checked on the MSRV toolchain the real publish uses. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The RC creation script now blocks on the publish dry-run, so the workflow run on the tag is a secondary check that does not need a manual step. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Updated the PR. We have several new gates
|
dannycjones
left a comment
There was a problem hiding this comment.
LGTM.
Also verified that create_rc.sh works fine from a nested dir.
Co-authored-by: Daniel Carl Jones <danny@danielcarl.info>
CTTY
left a comment
There was a problem hiding this comment.
Thanks for catching and fixing this!
| usage | ||
| exit 0 | ||
| ;; | ||
| --release_ref | --release-ref) |
There was a problem hiding this comment.
I think we should remove this option and always ask developers to run this on the HEAD that we want to release?
Currently there are logic like check_dependency_license() that always run on HEAD, and now we are adding check_crates_publishable
This is a separate issue though
…rty-macro (#3199) fix: break dev-dependency cycle that blocks publishing iceberg-property-macro (#3184) * fix: break dev-dependency cycle that blocks publishing iceberg-property-macro `iceberg` depends on `iceberg-property-macro`, and the macro crate had a versioned dev-dependency on `iceberg` via `workspace = true`. When cargo packages the macro crate for publishing it must resolve `iceberg ^0.11.0` from crates.io, which does not exist until the next step, so `cargo publish --workspace` fails with "failed to select a version". This is the same failure that broke the 0.5.0 publish and it reproduces on the v0.11.0-rc.1 tag. Make the dev-dependency path-only so cargo strips it when packaging. Mark the macro crate as internal to `iceberg` in its description and README, and add a `cargo publish --workspace --dry-run` step to CI so an unpublishable crate fails on the PR instead of after the release vote. * ci: split publish dry-run between PR CI, RC tags, and RC creation The full `cargo publish --dry-run` compiles every packaged crate and took 13 minutes per PR. PR CI now runs it with `--no-verify`, which still catches dependency cycles, unresolvable versions, and missing metadata in seconds. The compiled dry-run moves to where it matters for a release: - `create_rc.sh` runs it before creating any artifact or the RC tag, so a crate that cannot be published fails RC creation. Opt out with `--check_publish 0`. - `publish.yml` runs it on RC tag pushes, which previously did nothing, so the exact tag is also checked on the MSRV toolchain the real publish uses. * docs: drop RC tag workflow verification note from release guide The RC creation script now blocks on the publish dry-run, so the workflow run on the tag is a secondary check that does not need a manual step. * docs: note requirements for create_rc.sh --check_publish * Apply suggestion from @dannycjones --------- (cherry picked from commit 0aeccb8) Co-authored-by: Kevin Liu <kevinjqliu@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Which issue does this PR close?
What changes are included in this PR?
Fix publishing
iceberg-property-macroas part of the workspace release.iceberg-property-macrois new in 0.11.0 and must be published becauseicebergdepends on it. The macro crate also had a dev-dependency onicebergdeclared withworkspace = true, which gives it the workspace version.When Cargo packages the macro crate for publishing, it tries to resolve
iceberg ^0.11.0from crates.io. That version does not exist yet becauseicebergis published later in the workspace release, socargo publish --workspacefails on thev0.11.0-rc.1tag:This is the same failure mode that broke the 0.5.0 publish (#1325).
This PR:
iceberg = { path = "../iceberg" }), so Cargo strips it when packaging. This matches the pattern already used foriceberg_test_utilsacross the workspace.iceberg-property-macroas internal toicebergin its package description and README, since it is published only becauseicebergdepends on it.cargo publish --workspace --all-features --dry-run --no-verifyto thecheck_standaloneCI job, so publishing problems like dependency cycles and unresolvable versions are caught on the PR instead of during the post-vote release.--no-verifyskips compiling each packaged crate, which took 13 minutes per PR.cargo publish --workspace --all-features --dry-runtodev/release/create_rc.shas a--check_publishstep, before any artifact or the RC tag is created, so a crate that cannot be published fails RC creation.publish.ymlon RC tag pushes, which previously ran no steps, so the exact tag is also checked on the MSRV toolchain the real publish uses.Follow-ups outside this PR: cherry-pick the fix and the
create_rc.shchange to0.11.xbefore RC2, since RC2 is created from the release branch. The macro crate's first publish will also need to use an API token, since crates.io does not allow Trusted Publishing for the first version of a new crate.Are these changes tested?
cargo publish --workspace --all-features --dry-runfails on the current manifest and passes with this change, on both stable 1.95 (the publish workflow's toolchain) and the pinned nightly. The--no-verifyvariant fails on the current manifest with "circular dependency detected" in about 10 seconds.dev/release/create_rc.shwith the new step: an uncommitted change inside a crate fails withFAILED: Check crates can be publishedbefore any artifact is created, a clean tree verifies all 11 crates, and--check_publish 0skips the step.cargo test -p iceberg-property-macro --all-featurespasses with the path-only dev-dependency, including the trybuild compile-fail tests and README doctests.publish.ymlstep only runs on an RC tag push, so it is untested until RC2.AI Disclosure
Investigated and drafted with Claude Code; changes reviewed and verified by me.
🤖 Generated with Claude Code