Skip to content

chore(publish): verify with cargo package, not cargo publish --dry-run (#146) - #548

Merged
avrabe merged 1 commit into
mainfrom
chore/146-publish-cargo-package
Jul 1, 2026
Merged

avrabe merged 1 commit into
mainfrom
chore/146-publish-cargo-package

Conversation

@avrabe

@avrabe avrabe commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Closes #146.

Problem

./publish verify is meant to be a fail-fast, index-free "does each publishable crate build a valid package" pre-flight before crates.io publish. The original step used cargo publish --dry-run, which resolves every path-dep version requirement against the crates.io index — so on the FIRST publish of any new version, dependents fail with the chicken-and-egg "failed to select a version for synth-core = ^x.y" (deps aren't on the registry yet). That sank the v0.7.0 verify step (dropped in #144).

scripts/publish.rs::verify had already been switched to a per-crate cargo package -p <name> loop (PR #190), but that has the same problem: cargo verify-builds each packaged crate outside the workspace, downloads its deps from the index, and fails when the new version isn't published. PR #192 then removed the CI verify step, concluding cargo package couldn't avoid the chicken-and-egg.

Empirical finding

I bumped the whole workspace to an unpublished 0.99.0 and tested:

  • cargo package -p synth-synthesis (per-crate) → fails: failed to select a version for the requirement synth-cfg = "^0.99.0" … location searched: crates.io index.
  • cargo package -p synth-cfg -p synth-core -p synth-opt -p synth-synthesis (one invocation) → succeeds: Verifying synth-synthesis v0.99.0 → Compiling synth-opt v0.99.0 / Compiling synth-core v0.99.0 (its deps) → Finished, with no Downloaded synth-* from crates.io.

Packaging the whole set together makes cargo write every member to target/package/*.crate first, then verify-build each against those local tarballs at the new version — the index is never consulted for inter-member deps. Full verify build is retained (no --no-verify), so non-compiling code is still caught. This satisfies the issue's falsification ("must pass on a clean workspace with no prior version on crates.io").

Changes

  • scripts/publish.rs — verify() now packages the entire publishable set in one cargo package -p a -p b … invocation instead of once per crate.
  • scripts/publish.rs — add synth-backend-aarch64 to CRATES_TO_PUBLISH. It is a hard, always-on dep of synth-cli (Feature challenge: add an aarch64 (host-native) backend so output runs and debugs natively on arm64 dev machines #538) that was never published; ./publish publish would fail on synth-cli's unresolved dep, and the restored verify is what surfaced this latent gap.
  • .github/workflows/publish-to-crates-io.yml — restore the ./publish verify pre-flight step and rewrite the now-incorrect comment.
  • docs/release-process.md — describe the token-free verify pre-flight; add synth-backend-aarch64 to the published-crate table.

Trade-off to note for reviewers

The restored verify step full-builds the publishable set on the publish runner (ubuntu-latest), which includes synth-verify's static-link-z3 C++ build. That runner already builds z3 during cargo publish -p synth-verify, so this is added time (z3 built twice) rather than a new failure mode; the smithy-runner disk exhaustion (#306) does not apply to ubuntu-latest. If the extra build time is unwanted, the alternative is --no-verify (packaging/metadata check only, relying on the CI Test job for compile coverage) — flagged here rather than chosen silently.

Validation

  • rustc --edition 2024 scripts/publish.rs compiles clean; rustfmt --check passes.
  • The exact command shape the script emits was verified to resolve inter-member deps locally at an unpublished 0.99.0 (above). No workspace Rust changed, so cargo fmt/clippy are unaffected.

🤖 Generated with Claude Code

#146)

`scripts/publish.rs::verify` already used `cargo package` per-crate, but
that still hits the crates.io chicken-and-egg for dependent crates on a
first publish of a new version: cargo verifies each packaged crate
outside the workspace, downloads its deps from the index, and fails when
the new version isn't published yet. Empirically confirmed at an
unpublished 0.99.0 — this is why PR #192 removed the CI verify step.

Fix: package the whole publishable set in ONE `cargo package -p a -p b …`
invocation. Cargo writes every member to target/package/*.crate first,
then verify-builds each against those local tarballs at the new version,
never touching the index. Confirmed at 0.99.0: dependents (synth-synthesis
etc.) compile against the just-packaged deps with nothing on crates.io.
Full verify build retained (no --no-verify), so non-compiling code is
still caught.

Also:
- Add synth-backend-aarch64 to CRATES_TO_PUBLISH. It is a hard, always-on
  dep of synth-cli (#538) but was never published — publish would (and
  the restored verify does) fail on synth-cli's unresolved dep. The
  restored fail-fast check is exactly what surfaced this latent gap.
- Restore the `./publish verify` pre-flight step in
  publish-to-crates-io.yml and rewrite the now-false comment (it asserted
  cargo package cannot avoid the chicken-and-egg; it can, when the whole
  set is packaged together).
- Update docs/release-process.md: describe the token-free verify
  pre-flight and add synth-backend-aarch64 to the published-crate table.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@avrabe
avrabe merged commit 42e32f3 into main Jul 1, 2026
20 checks passed
@avrabe
avrabe deleted the chore/146-publish-cargo-package branch July 1, 2026 16:30
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.

publish: change ./publish verify to use cargo package (currently dropped; lost the fail-fast metadata check)

1 participant