fix(release): bundle macos-bundle-updater.sh inside freenet crate so cargo install works#4240
Conversation
|
The script contains the expected sentinel string on line 2, confirming the test assertion is valid. Rule Review: No issues foundRules checked: git-workflow.md, code-style.md, testing.md The PR moves
All applicable rules are satisfied:
No rule violations detected. Rule review against |
d423683 to
f1c3928
Compare
## Problem
`cargo install freenet --version 0.2.61` (and every subsequent
published version) fails to build from crates.io with an
`include_str!` "file not found" error on
`crates/core/src/bin/commands/update.rs`.
The line
`include_str!("../../../../../scripts/macos-bundle-updater.sh")`
walks five levels up — out of the freenet crate and into the
workspace-root `scripts/` directory. That path is valid in a
workspace checkout, but `cargo publish` only bundles files inside
the crate directory, so the script is absent from the registry
tarball and `cargo build` aborts before linking.
This blocks anyone installing freenet from the registry rather than
from source, including River's `cargo make sign-webapp` flow, which
shells out to `cargo install freenet` to obtain `fdev`.
## Approach
Move `scripts/macos-bundle-updater.sh` into the freenet crate at
`crates/core/scripts/macos-bundle-updater.sh` so `cargo publish`
ships it. Shorten the `include_str!` path accordingly.
Why this over alternatives — the script is the only file the
freenet binary embeds via `include_str!`; the rest of the
workspace-root `scripts/` directory is build/CI tooling that
shouldn't ride along in the published crate. A `[package].include`
allowlist or a `build.rs` that copies the file would add
configuration to maintain but would not surface the rule at the
filesystem level. Co-locating the embedded resource with its
consumer crate is the convention `cargo` was designed around.
## Testing
A bug in this class is the published `.crate` tarball missing an
embedded resource — that can't be caught by a runtime `#[test]`
alone, so this PR closes the gap with TWO tests:
1. **Unit test** — a new `#[test]` in `update.rs::tests`
re-includes the script via `include_str!` and asserts its shape
(shebang + header). Locks the path: any future refactor that
walks back outside the crate breaks compilation right here.
2. **CI gap test** — a new step in the `fmt_check` job runs
`cargo package --list -p freenet` and fails the build if
`scripts/macos-bundle-updater.sh` is missing from the would-be
tarball. This is the assertion that would actually have caught
the 0.2.61 regression before publish, and it generalizes to any
future embedded resource that gets added to the include list.
The workspace e2e harness
(`scripts/macos-bundle-swap-e2e.sh` and its `.c` stub comment)
was updated to point at the new path.
Local validation:
- `cargo fmt -- --check` clean.
- `cargo clippy -p freenet --bin freenet --tests -- -D warnings`
clean.
- New test passes:
`cargo test embedded_updater_script_resolves_inside_freenet_crate`.
- `cargo package --list -p freenet | grep -Fx scripts/macos-bundle-updater.sh`
resolves — the script is in the package contents.
The `#[cfg(target_os = "macos")]` gate on `write_updater_script`
is unchanged, so Linux builds remain unaffected.
## Why didn't CI catch this?
CI ran `cargo build` / `cargo test` against the workspace
checkout, where the workspace-root `scripts/` directory is on disk
and `include_str!` resolves. CI never built the crate from its
published `.crate` tarball, so the packaging gap was invisible. The
new `fmt_check` step closes that gap and would have failed the
0.2.61 release PR before it merged.
## Fixes
Unblocks `cargo install freenet` from crates.io and downstream
tooling that depends on it (River's `cargo make sign-webapp`).
Recommend cutting a `0.2.63` patch release after merge so
downstreams can stop vendoring around this.
[AI-assisted - Claude]
Entire-Checkpoint: 046245fb4905
f1c3928 to
8ca9efc
Compare
Internal Review SummaryRan four parallel review agents (code-first, testing, skeptical, big-picture) per the freenet:pr-creation skill. All four said land as-is is acceptable; consensus findings were addressed in the latest amend. Consensus findings (3+ reviewers)
Other findings addressed
Findings acknowledged but not actioned
Codex reviewPending — running next. [AI-assisted - Claude] |
Codex external review — skippedCodex CLI auth was expired (refresh token already used) on the machine running the review; user opted to skip the external pass given the four internal reviewers all signed off and consensus findings were addressed. The PR has been amended with the agreed-upon changes; ready for CI + human review. [AI-assisted - Claude] |
Problem
cargo install freenet --version 0.2.61(and every subsequentpublished version) fails to build from crates.io with an
include_str!"file not found" error oncrates/core/src/bin/commands/update.rs.The line
include_str!("../../../../../scripts/macos-bundle-updater.sh")walks five levels up — out of the freenet crate and into the
workspace-root
scripts/directory. That path is valid in aworkspace checkout, but
cargo publishonly bundles files insidethe crate directory, so the script is absent from the registry
tarball and
cargo buildaborts before linking.This blocks anyone installing freenet from the registry rather than
from source, including River's
cargo make sign-webappflow, whichshells out to
cargo install freenetto obtainfdev.Approach
Move
scripts/macos-bundle-updater.shinto the freenet crate atcrates/core/scripts/macos-bundle-updater.shsocargo publishships it. Shorten the
include_str!path accordingly.Why this over alternatives — the script is the only file the
freenet binary embeds via
include_str!; the rest of theworkspace-root
scripts/directory is build/CI tooling thatshouldn't ride along in the published crate. A
[package].includeallowlist or a
build.rsthat copies the file would addconfiguration to maintain but would not surface the rule at the
filesystem level. Co-locating the embedded resource with its
consumer crate is the convention
cargowas designed around.Testing
A bug in this class is the published
.cratetarball missing anembedded resource — that can't be caught by a runtime
#[test]alone, so this PR closes the gap with TWO tests:
Unit test — a new
#[test]inupdate.rs::testsre-includes the script via
include_str!and asserts itsshape (shebang + header). Locks the path: any future refactor
that walks back outside the crate breaks compilation right
here.
CI gap test — a new step in the
fmt_checkjob runscargo package --list -p freenetand fails the build ifscripts/macos-bundle-updater.shis missing from the would-betarball. This is the assertion that would actually have caught
the 0.2.61 regression before publish, and it generalizes to any
future embedded resource that gets added to the include list.
The workspace e2e harness (
scripts/macos-bundle-swap-e2e.shandits
.cstub comment) was updated to point at the new path.Local validation
cargo fmt -- --checkclean.cargo clippy -p freenet --bin freenet --tests -- -D warningsclean.cargo test embedded_updater_script_resolves_inside_freenet_crate.cargo package --list -p freenet | grep -Fx scripts/macos-bundle-updater.shresolves — the script is in the package contents.
The
#[cfg(target_os = "macos")]gate onwrite_updater_scriptis unchanged, so Linux builds remain unaffected.
Why didn't CI catch this?
CI ran
cargo build/cargo testagainst the workspacecheckout, where the workspace-root
scripts/directory is on diskand
include_str!resolves. CI never built the crate from itspublished
.cratetarball, so the packaging gap was invisible.The new
fmt_checkstep closes that gap and would have failedthe 0.2.61 release PR before it merged.
Fixes
Unblocks
cargo install freenetfrom crates.io and downstreamtooling that depends on it (River's
cargo make sign-webapp).Recommend cutting a
0.2.63patch release after merge sodownstreams can stop vendoring around this.
[AI-assisted - Claude]