Skip to content

fix(release): verify all crate tarballs before the first upload - #5893

Merged
Hmbown merged 4 commits into
mainfrom
fix/cargo-preflight-0913-20260905
Sep 5, 2026
Merged

fix(release): verify all crate tarballs before the first upload#5893
Hmbown merged 4 commits into
mainfrom
fix/cargo-preflight-0913-20260905

Conversation

@Hmbown

@Hmbown Hmbown commented Sep 5, 2026

Copy link
Copy Markdown
Owner

The 0.9.12 publish sequence reached crates.io before discovering that the dependent TUI tarball omitted embedded assets. Verify the complete release before its first upload so a workspace build cannot hide a broken published crate.

Both modes now run one Cargo publication dry run across all 21 release crates, resolving unpublished dependencies through Cargo’s temporary local registry and building every unpacked tarball. The script requires Cargo 1.90+ for this release-tool capability, explicitly targets crates.io, and documents the separate runtime MSRV. Publish mode retains the release checkout/assets guards and skips already-published versions after full verification.

Validation:

  • Full 21-crate publication dry run passed; every upload was aborted by --dry-run.
  • Five offline real-tarball fixtures pass: missing dependent assets block dry run and publish before any upload; valid unpublished dependencies pass; old Cargo fails early; resumed publishing verifies artifacts and skips existing versions.
  • Real two-crate unpublished workspace publication dry run passed against crates.io with no upload.
  • Publication order, shell syntax, and diff checks pass. The runtime root has no npm test or check:web scripts.

Fixes #5892.


Note

Medium Risk
Changes the crates.io release gate and toolchain requirement for maintainers; incorrect preflight behavior could block or delay releases, though it reduces risk of shipping broken crate tarballs.

Overview
Release publishing now runs a single multi-crate cargo publish --dry-run --locked --registry crates-io across all release packages before any real upload, so broken tarballs (e.g. missing embedded assets in a dependent crate) fail during preflight instead of after partial uploads. The script requires Cargo 1.90+ for that workflow (documented separately from runtime MSRV in RELEASE_RUNBOOK.md); publish mode still enforces release checkout/assets guards, performs full verification first, then uploads in order while skipping versions already on crates.io.

Adds scripts/release/publish-crates.test.py and wires it into CI’s release-helper contract step, with offline fixtures for old Cargo rejection, missing tarball assets blocking upload, unpublished workspace deps, and resume/skip behavior.

Bundled computer-use plugin path references are updated from plugins/computer-use to crates/tui/plugins/computer-use (embed paths in builtin.rs, manifest test, Extensions UI, .gitignore, README, and CI npm test directory).

Reviewed by Cursor Bugbot for commit daea481. Bugbot is set up for automated code reviews on this repo. Configure here.

CodeWhale Bot added 2 commits September 5, 2026 04:16
Cargo publication of v0.9.12 stopped at codewhale-tui after 18 crates:
its 16 include_str! paths reached outside the package root, so the
verified tarball could not compile. Move the existing plugin into the
TUI package and update every source, test, CI, documentation, and ignore
reference. Keep one canonical bundle, with all 16 embedded runtime files
byte-identical to the v0.9.12 release payload.

Validation:
- Original cargo publish --locked -p codewhale-tui: FAIL, 16 missing-file
  errors; Cargo refused the upload.
- Corrected cargo package --locked --allow-dirty -p codewhale-tui: PASS,
  including compilation of the unpacked library and binary.
- npm test in crates/tui/plugins/computer-use: 31 passed; 0 failed.
- Embedded payload comparison: 16/16 original files identical in source
  and in the verified Cargo tarball.
- cargo fmt --all -- --check: PASS.
- Coordination npm test && npm run check:web gate: unavailable here;
  this Rust repository defines neither root script (both report Missing
  script). No broad-suite or hosted-CI pass is claimed.

This is a local packaging repair based on dcd4c20. It does not move
the published v0.9.12 tag or alter the already-published release binaries.
Fixes #5892. Cargo packages the release together through its temporary registry so unpublished workspace dependencies can be verified before upload. Preserve tag/assets guards and resumable publication.

Validation: full 21-crate dry-run passed; 3/3 real-Cargo regression tests passed, and both broken-package cases reject the previous implementation; publication-order suite and bash syntax passed. Repository npm test/check:web scripts are unavailable; no full workspace test claim.
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
Copilot AI lite review requested due to automatic review settings September 5, 2026 11:47
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T11:54:23.505822Z faaf378 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@cursor

cursor Bot commented Sep 5, 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_1f5d07a0-68c9-4d3d-9f5a-954c3ae7a649)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The release gate change is narrowly scoped and backed by a new offline regression test, with only a minor test robustness nit noted.

Pull request overview

This PR strengthens the crates.io release gate by verifying all workspace crate tarballs up front (including crates with unpublished workspace dependencies) so missing packaged assets or tarball build failures stop the release before any upload.

Changes:

  • Run a single cargo package across all release crates before starting the per-crate publish loop; dry-run exits immediately after verification.
  • Remove the previous special-casing that only listed files (or skipped true dry-run) for crates with workspace dependencies.
  • Add an offline regression test that exercises the “no upload before tarballs verify” boundary and wire it into CI.
File summaries
File Description
scripts/release/publish-crates.sh Packages/verifies all release crates in one Cargo invocation before any publish; dry-run now validates dependent tarballs too.
scripts/release/publish-crates.test.py New offline test fixture that uses real Cargo packaging to ensure missing embedded assets fail before any upload is attempted.
.github/workflows/ci.yml Runs the new Python release-helper contract test in CI.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +75 to +82
self.env = {
**os.environ,
"TEST_REAL_CARGO": shutil.which("cargo"),
"TEST_UPLOADS": str(self.uploads),
"PATH": str(bin_dir) + os.pathsep + os.environ["PATH"],
"CARGO_NET_OFFLINE": "true",
"CARGO_TARGET_DIR": str(self.root / "target"),
}

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: faaf378c75

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/release/publish-crates.sh Outdated
return 1
}
echo "Verifying all ${#packages[@]} release package tarballs before any upload..."
cargo package "${package_args[@]}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Support the repository's Rust 1.88 toolchain

When a release operator uses Cargo 1.88 or 1.89, which are compatible with the workspace's declared rust-version = "1.88", this multi-package command does not provide unpublished packages through a temporary registry: the new regression test fails with no matching package named codewhale-preflight-base found before verifying the dependent tarball. I reproduced all three failures with 1.88/1.89 and verified they pass starting with 1.90; either retain a compatible preflight or explicitly declare and enforce Cargo >=1.90 before invoking this command.

Useful? React with 👍 / 👎.

Comment thread scripts/release/publish-crates.sh Outdated
Comment on lines +45 to +47
# Package the complete release together. Cargo resolves unpublished workspace
# dependencies through a temporary local registry, then builds each unpacked
# tarball. A file inventory alone cannot detect missing embedded assets.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the release runbook for the new preflight

After this change, docs/RELEASE_RUNBOOK.md:102-107 still tells release operators that dependency-free crates receive cargo publish --dry-run while crates with workspace dependencies receive only a packaging preflight. The implementation now verifies every unpacked tarball in one invocation, so the authoritative runbook referenced by the release checklist describes the opposite behavior and gives operators inaccurate expectations when interpreting or troubleshooting this gate.

Useful? React with 👍 / 👎.

@Hmbown
Hmbown changed the base branch from fix/v0912-crate-bundle-20260905 to main September 5, 2026 12:07
…913-20260905

Signed-off-by: CodeWhale Bot <bot@codewhale.net>
@cursor

cursor Bot commented Sep 5, 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_702aaa26-f818-44d3-90ab-bdf1edb9f97b)

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 2m 31s —— View job


Review complete ✅

  • Gather context (PR body, diff, existing review comments)
  • Review scripts/release/publish-crates.sh changes
  • Review scripts/release/publish-crates.test.py new test
  • Review CI wiring change
  • Check runbook/docs consistency
  • Check for provider/model route safety concerns (N/A — pure release tooling, no route/provider code touched)
  • Post final review

Summary

The actual root cause — the computer-use plugin bundle living outside crates/tui/ so it was silently excluded from the TUI crate's default packaging — is fixed correctly and consistently: builtin.rs's include_str! path, the manifest.rs test fixture path, .gitignore, and extensions.rs's source_reference all move together with the directory rename, and crates/tui/Cargo.toml has no include/exclude override, so the moved directory is now packaged by default. The CI npm test cwd was updated to match. Good, consistent move.

The new cargo package -p a -p b -p c … preflight in scripts/release/publish-crates.sh:45-61 that verifies every tarball before any cargo publish is the right shape for the defense-in-depth this PR is going for, and publish-crates.test.py is a solid offline regression: it proves (via a real Cargo-built fixture, not mocks) that a missing embedded asset now fails before any upload is attempted, and that a valid unpublished-dependency graph still passes.

Findings

  1. Correctness — Cargo version dependency on the new preflight (scripts/release/publish-crates.sh:52-57): packaging multiple crates together while resolving unpublished sibling workspace dependencies through Cargo's temporary local registry needs a newer Cargo than the workspace's own declared rust-version = "1.88" (Cargo.toml:35). Codex's review reports reproducing no matching package named codewhale-preflight-base found on Cargo 1.88/1.89 and passing only from 1.90. Since rust-toolchain.toml pins channel = "stable", CI itself won't hit this, but any release operator who has an older/pinned Cargo matching the documented MSRV floor will get exactly the kind of failure this PR is trying to close the gap on. Worth an explicit minimum-Cargo-version check (or error message) in the script rather than relying on the ambient toolchain being new enough.

  2. Docs drift (docs/RELEASE_RUNBOOK.md:102-107): still describes the old split behavior ("full cargo publish --dry-run for crates without unpublished workspace dependencies and a packaging preflight for dependent workspace crates"). The implementation now runs one cargo package over every release crate regardless of dependency shape. This is the authoritative operator-facing doc for this gate and should be updated in the same PR so a release operator troubleshooting a failure isn't reading the opposite of what's running.

  3. Test robustness (scripts/release/publish-crates.test.py:82): "TEST_REAL_CARGO": shutil.which("cargo") is not asserted non-None. If cargo isn't on PATH, self.env gets a None value, and subprocess.run(..., env=self.env) will fail with an opaque TypeError/exec error rather than a clear "cargo not found" message. A one-line assert real_cargo, "cargo not found on PATH" before building self.env would make failures point at the real cause.

  4. Minor cleanup (scripts/release/validate-crate-publish-order.py:182, scripts/release/publish-crates.sh:25-30): the Python helper still computes dependency_flags and emits crate\t{name}\t{flag} lines, but the bash consumer's case no longer has a branch for kind == crate — that inventory line is now silently ignored. Not a bug (bash case isn't exhaustive), but it's now dead computation/output on the Python side that could be dropped along with workspace_codewhale_packages/workspace_package_dep_flags removal, per this repo's rung-2 reuse guidance.

No issues found with the provider/model routing invariant (EPIC #2608) — this PR doesn't touch model/provider selection code.

Fix this →

@Hmbown Hmbown added this to the v0.9.13 milestone Sep 5, 2026

@codewhale-agent codewhale-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codewhale review

The PR relocates the computer-use plugin into crates/tui and rewrites release publishing to run one cargo package verification across all release crates before any upload, replacing per-crate dry-run logic. It adds offline fixture tests that validate the tarball upload boundary.

Findings

  • [WARNING] Publish preflight loses crates.io-specific dry-run for dependency-free crates (scripts/release/publish-crates.sh:55)
    Removing cargo publish --dry-run for crates without workspace dependencies means package-level cargo package verifies tarball contents and compilation, but it does not perform all crates.io validation that cargo publish --dry-run does (such as registry metadata checks or publish-time rules). A package could pass the new preflight and then fail when its turn arrives after earlier crates have already uploaded.
  • [WARNING] Preflight verifies already-published crates and can block resuming a partial release (scripts/release/publish-crates.sh:55)
    In publish mode, the full cargo package pass runs before the per-package crate_version_exists skip. If a previous partial release left a crate already on crates.io whose source no longer packages cleanly, the preflight fails and prevents the remaining unpublished crates from being uploaded, breaking the resumable publication loop.
  • [INFO] New offline tests do not exercise the previous bad-publisher regression or the resumable skip path (scripts/release/publish-crates.test.py)
    The Python test's stub cargo has a publish --dry-run branch, but the new script never invokes that mode, so that branch is unreachable in the test. The tests also do not run the old per-crate publisher or test that already-published crates are skipped before preflight/upload, leaving the regression and resumability behavior unverified.

Assessment

The approach is sound and directly addresses the missing-asset failure by making tarball verification the gate before uploads. However, it drops some crates.io dry-run coverage and may impair resumability by packaging already-published crates; tests should be extended to cover those scenarios before relying on this for a release.


Advisory review by Codewhale (codewhale review --pr 5893 --post, head cf62b8eb7aa21c65a1b3a75be6a24318534e8fa2). Line-specific findings are also posted as inline review comments; mechanical fixes arrive as committable suggestions you can apply from the Files tab. CODEOWNERS approval still governs merge.

for package in "${packages[@]}"; do
package_args+=(-p "${package}")
done

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING] Publish preflight loses crates.io-specific dry-run for dependency-free crates

Removing cargo publish --dry-run for crates without workspace dependencies means package-level cargo package verifies tarball contents and compilation, but it does not perform all crates.io validation that cargo publish --dry-run does (such as registry metadata checks or publish-time rules). A package could pass the new preflight and then fail when its turn arrives after earlier crates have already uploaded.

for package in "${packages[@]}"; do
package_args+=(-p "${package}")
done

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING] Preflight verifies already-published crates and can block resuming a partial release

In publish mode, the full cargo package pass runs before the per-package crate_version_exists skip. If a previous partial release left a crate already on crates.io whose source no longer packages cleanly, the preflight fails and prevents the remaining unpublished crates from being uploaded, breaking the resumable publication loop.

Use one Cargo publication dry run for all 21 crates before uploading, with an explicit Cargo 1.90+ release-tool requirement and crates.io destination. Update the runbook and test resumability without weakening full artifact verification.

Validation: 5/5 offline tarball fixtures passed; real 21-crate publication dry run passed with no upload; real two-crate unpublished dependency dry run passed; publication order, bash syntax, and git diff --check passed. Runtime root has no npm test/check:web scripts.
Signed-off-by: CodeWhale Bot <bot@codewhale.net>
@cursor

cursor Bot commented Sep 5, 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_25f9cc2e-b284-4013-acb8-45ef0981fb90)

@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Claude finished @Hmbown's task in 3m 36s —— View job


Review complete ✅

  • Gather context (PR body, diff, existing review comments)
  • Review scripts/release/publish-crates.sh changes
  • Review scripts/release/publish-crates.test.py new test
  • Review computer-use plugin relocation (builtin.rs, manifest.rs, extensions.rs, .gitignore, CI)
  • Review docs/RELEASE_RUNBOOK.md update
  • Check for provider/model route safety concerns (N/A — no model/provider/route code touched)
  • Post final review

Note on scope

HEAD is now daea481 (a follow-up fixup on top of the faaf378 commit that Codex/Copilot/codewhale-agent reviewed). That commit already resolves most of the prior findings:

  • Added an explicit Cargo 1.90+ preflight check (scripts/release/publish-crates.sh:19-24), addressing the "old Cargo silently mis-resolves unpublished deps" finding.
  • Switched the multi-crate preflight from cargo package to cargo publish --dry-run --locked --registry crates-io across all packages (publish-crates.sh:57-66), so dependency-free crates once again get full crates.io publish-time validation, not just a tarball build — resolving the "loses crates.io-specific dry-run" finding.
  • Updated docs/RELEASE_RUNBOOK.md:99-119 to match the new single-preflight behavior, resolving the docs-drift finding.
  • Added self.assertIsNotNone(real_cargo, ...) in publish-crates.test.py:17-18, resolving the "TEST_REAL_CARGO could be None" nit.
  • Added test_resume_verifies_tarballs_and_skips_existing_versions, which demonstrates and documents (runbook: "Resuming still verifies the complete source release...") that a resume intentionally re-verifies every tarball before skipping already-published versions.

Remaining findings

  1. Minor — now-dead output in the Python helper (scripts/release/validate-crate-publish-order.py:181-182): dependency_flags is still computed and emitted as crate\t{name}\t{flag} lines, but publish-crates.sh dropped the crate) branch of its consuming case (the old workspace_codewhale_packages/workspace_package_dep_flags arrays are gone). Not a bug — bash case isn't exhaustive — but it's now dead computation on the producer side. Per this repo's rung-2 reuse rule, worth deleting dependency_flags from validate_order's return and the two emit lines in the same change that removed its only consumer.

  2. Note, not a bug — full-workspace dry-run runs before the per-crate skip (publish-crates.sh:57-66 vs. the crate_version_exists skip at line 97): every publish invocation, including a resume, re-runs the multi-crate cargo publish --dry-run across all 21 crates (contacting crates.io) before any per-crate "already published" skip applies. This is called out deliberately in the runbook and covered by the new resume test, so flagging only to confirm it's an accepted trade-off (a resume always pays for a full re-verification) rather than an oversight.

  3. Minor — dev-only plugin files now ship in the published tarball: moving computer-use under crates/tui/plugins/ means tests/, scripts/smoke.mjs, package.json, and README.md (no include/exclude in crates/tui/Cargo.toml) will be packaged into the published codewhale-tui crate, since Cargo packages everything not gitignored by default. Total is small (~288K, mostly tests/ and src/backends/*.mjs), so this isn't blocking, but it's a new, real change to published-artifact contents worth being aware of. builtin.rs's doc comment already notes these files aren't include_str!'d into the runtime bundle — that's a separate question from what ships in the .crate tarball.

  4. Verified no stale references remain anywhere (Rust, CI, .gitignore, docs) to the old top-level plugins/computer-use path — the rename is fully consistent.

No correctness bugs, no provider/model routing concerns (this PR doesn't touch model/provider selection code), and the Cargo-version regex/arithmetic gate at publish-crates.sh:19-24 is safe under set -euo pipefail since it's evaluated inside an if condition.
· branch fix/cargo-preflight-0913-20260905

@Hmbown

Hmbown commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

Review follow-up is pushed at daea481. Release tooling now explicitly requires Cargo 1.90+, checks that before metadata or uploads, and documents the runtime MSRV separately. The complete gate uses Cargo publication dry run across all 21 crates, retaining publication metadata checks and explicitly targeting crates.io. The runbook matches the implementation.

The real 21-crate dry run passed with no upload. Five offline tarball fixtures pass, including old-toolchain rejection and resuming after published versions. Full artifact verification is intentionally retained during resume; already-published source is not exempted from the release gate. Missing Cargo now has a clear test assertion.

@codewhale-agent codewhale-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codewhale review

PR adds a complete cargo publish dry-run preflight for all release crates and moves the computer-use plugin under crates/tui so its assets are packaged. The release-script change is sound, but the new test fixture substitutes cargo package for cargo publish --dry-run and may miss publish-specific behavior, and the move may package dev-only plugin files without explicit exclusions.

Findings

  • [WARNING] Test fixture forwards publish-only flags to cargo package (scripts/release/publish-crates.test.py:71)
    In the fake cargo shim, cargo publish --dry-run is translated to "$TEST_REAL_CARGO" package "${args[@]}" after removing only --dry-run. The remaining args include --registry crates-io, which is a publish/registry option and is not guaranteed to be accepted by cargo package on all Cargo 1.90+ toolchains. This can make the offline fixtures fail for the wrong reason or hide differences from the real multi-package cargo publish --dry-run path the release script uses.
  • [WARNING] Moved plugin files may now be packaged in the crates/tui tarball
    Moving plugins/computer-use under crates/tui/plugins/computer-use puts the entire bundle under the crates/tui package root. Unless crates/tui/Cargo.toml already excludes them (not shown in this diff), Cargo will now include development-only files such as package.json, tests/, scripts/smoke.mjs, and README.md in the published crates/tui crate. The embedded runtime tree deliberately omits these files; the published tarball should exclude them explicitly.
  • [INFO] No successful publish path coverage in the new fixture (scripts/release/publish-crates.test.py:72)
    The fake cargo shim aborts every real (non-dry-run) cargo publish with exit 98, and all successful scenarios either exit after dry-run or skip already-published versions. There is no fixture asserting that, after preflight passes and a version is absent, publish mode actually invokes cargo publish --locked --registry crates-io in order and then waits. The real cargo publish --dry-run path is also never executed; only cargo package is used.

Assessment

The release preflight approach is a meaningful improvement and should prevent the 0.9.12 tarball-asset failure. Before merge, the fixture should avoid forwarding unsupported publish-only flags to cargo package and the crate packaging implications of the plugin move should be verified with explicit exclusions if needed.


Advisory review by Codewhale (codewhale review --pr 5893 --post, head daea4810eaaf5c55533fa280cb6c5b7aab786efe). Line-specific findings are also posted as inline review comments; mechanical fixes arrive as committable suggestions you can apply from the Files tab. CODEOWNERS approval still governs merge.

' shift\n if [[ " $* " == *" --dry-run "* ]]; then\n'
' args=()\n for arg in "$@"; do\n'
' [[ "$arg" == --dry-run ]] || args+=("$arg")\n done\n'
' exec "$TEST_REAL_CARGO" package "${args[@]}"\n fi\n'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING] Test fixture forwards publish-only flags to cargo package

In the fake cargo shim, cargo publish --dry-run is translated to "$TEST_REAL_CARGO" package "${args[@]}" after removing only --dry-run. The remaining args include --registry crates-io, which is a publish/registry option and is not guaranteed to be accepted by cargo package on all Cargo 1.90+ toolchains. This can make the offline fixtures fail for the wrong reason or hide differences from the real multi-package cargo publish --dry-run path the release script uses.

' args=()\n for arg in "$@"; do\n'
' [[ "$arg" == --dry-run ]] || args+=("$arg")\n done\n'
' exec "$TEST_REAL_CARGO" package "${args[@]}"\n fi\n'
' echo attempted >> "$TEST_UPLOADS"\n exit 98\nfi\n'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[INFO] No successful publish path coverage in the new fixture

The fake cargo shim aborts every real (non-dry-run) cargo publish with exit 98, and all successful scenarios either exit after dry-run or skip already-published versions. There is no fixture asserting that, after preflight passes and a version is absent, publish mode actually invokes cargo publish --locked --registry crates-io in order and then waits. The real cargo publish --dry-run path is also never executed; only cargo package is used.

@Hmbown
Hmbown merged commit a58ef2d into main Sep 5, 2026
35 checks passed
@Hmbown
Hmbown deleted the fix/cargo-preflight-0913-20260905 branch September 5, 2026 13:20
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.

Verify all Cargo package tarballs before the first release upload

2 participants