Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rust package readiness

RustFerry has 10 workspace members: nine publishable crates and one non-publishable trusted worker. All publishable versions come from workspace.package; a release must keep them identical.

OrderPackageRoleInternal prerequisites
1rustferry-coreConfiguration, validation, assets, process controlNone
2rustferryApplication runtime APINone
3rustferry-codegenProject, capability, and asset generationrustferry-core
4rustferry-remoteRemote-build protocol, source, signing, and artifact contractsrustferry-core on Windows
5rustferry-androidDirect Android packaging backendrustferry-core, rustferry-codegen
6rustferry-appleApple generation and artifact backendrustferry-core, rustferry-codegen, rustferry-remote
7rustferry-githubGitHub transport and workflow providerrustferry-core, rustferry-remote
8rustferry-sshPinned OpenSSH transport for macOS workersrustferry-core, rustferry-remote
9cargo-ferryPublic CLIRuntime, backend, core, codegen, remote, GitHub, and SSH crates

Wait for each prerequisite version to appear in the registry index before publishing the next group. The automated release workflow never publishes to crates.io.

Manifest contract

Every crate must declare its name, version, Rust version, description, repository, homepage, documentation URL, dual-license expression, README, keywords, categories, and an explicit include set. Internal path dependencies must also carry the exact release version so Cargo removes the path when it normalizes the package.

Each crate root links LICENSE-MIT and LICENSE-APACHE to the canonical workspace files and includes both names explicitly. Cargo dereferences those links into regular files in the portable archive. The archive scanner requires both members at the package root and verifies their exact SHA-256 digests.

The committed workspace Cargo.lock is the release lock. Use --locked for every gate. Generated package archives contain only their declared source, templates, tests, and embedded docs; they must not contain target/, signing material, absolute developer paths, or missing include_bytes!/include_str! inputs.

rustferry-worker-macos is a workspace-only trusted worker and declares publish = false. Workspace checks compile and test it, but package and publish commands must explicitly exclude it.

Package gates

Run from the repository root on a clean release revision:

cargo metadata --locked --no-deps --format-version 1
python3 scripts/check-release-contract.py
cargo package --workspace --exclude rustferry-worker-macos --locked --list
cargo package --workspace --exclude rustferry-worker-macos --locked
cargo publish --workspace --exclude rustferry-worker-macos --dry-run --locked
python3 scripts/check-release-archives.py \
  --check-sources \
  --target-dir target/package-source-check \
  target/package/*.crate

cargo package --workspace --exclude rustferry-worker-macos verifies the normalized archives together, so unpublished internal dependencies resolve from the package set. The following publish --dry-run repeats registry upload checks and package verification without uploading. Do not weaken the release gate with --no-verify.

Inspect the produced archives before approving a draft:

find target/package -maxdepth 1 -name '*.crate' -print | sort
for archive in target/package/*.crate; do tar -tzf "$archive"; done

The manual draft-release workflow copies all nine .crate files into one release assembly, adds the schema, VSIX, license bundle, release notes, and SHA-256 checksums, then uploads that assembly as a workflow artifact.

Historical package results do not validate a later release revision. Re-run the package, source, license, and publish dry-run gates for all nine archives and record the resulting file counts and compressed sizes.

Publish procedure

Publishing is a separate, protected manual operation. Run a complete dry-run, then publish one crate at a time in the documented dependency order. Confirm each version with cargo info <CRATE>@<VERSION>, cargo owner --list <CRATE>, and the crates.io API before continuing. Do not use --no-verify, pass a token on the command line, bump versions, or publish from a dirty checkout.

After publication, install the CLI from the registry into an isolated Cargo root and generate/check a new project without a runtime-path environment override. This is the acceptance test for registry-based template resolution; workspace-path tests alone are insufficient.

If a publish command times out, query the registry before retrying. If a later crate fails after prerequisites are public, preserve the published boundary and do not yank merely to make the release atomic. Fix only unpublished crates when their contracts can remain compatible; otherwise prepare the next patch. Yank only for a specific security, legal, or unusable-package defect and document the reason.