workspace, ci, docs: make every crate publishable and package them in CI #197

Merged
natsukium merged 1 commit from ci/publish-dry-run into main 2026-10-19 23:48:24 +09:00
Owner

Part of #160 (policy amendment). Builds on #196 (merged): verify.py checks the workspace version only on the binary crates.

  • Every crate under crates/ is publishable. The workspace no longer sets publish = false, and only tests/ (felis-workspace-tests) keeps it.
  • The nine library crates move to version = "0.1.0". felis-cli, felis-client and felis-daemon keep the app version (version.workspace = true). The internal [workspace.dependencies] entries carry version = "0.1.0" next to path.
  • Dev-dependencies on felis crates name path only, so cargo package drops them. A versioned one would leave the felis-client-core ↔ felis-daemon cycle unpackageable. Cargo.lock and fuzz/Cargo.lock are regenerated.
  • New just publish-dry-run (cargo publish --workspace --dry-run --allow-dirty), run by just check and pr.yml's build job. It packages all 12 crates and builds each against the others in publish order, in about 3 minutes here. If a version already exists on crates.io the dry-run only warns, so main stays green after a release.
  • Docs: workspace.md "Versioning", implementation.md (the versioning rationale, plus a new section that records lockstep versions as the rejected alternative), testing.md CI table, CONTRIBUTING.md. Comments in deny.toml and nix/make-macos-app.sh are updated too.

What the gate does not prove: it builds dependents against the local copy of each library. Once a library is on crates.io, a change to it that keeps the published version would still pass. The rule that a library whose package contents changed takes a new version before any dependent is published belongs to the release-automation item, which must land before the first real publish.

Local: cargo build --locked, lint, deny, docs-links, publish-dry-run, nextest (4329 passed), selftest, test-msrv, prose-check. Reviews (pi, sol): design PASS after three rounds, implementation PASS after two.

Part of #160 (policy amendment). Builds on #196 (merged): `verify.py` checks the workspace version only on the binary crates. - Every crate under `crates/` is publishable. The workspace no longer sets `publish = false`, and only `tests/` (`felis-workspace-tests`) keeps it. - The nine library crates move to `version = "0.1.0"`. felis-cli, felis-client and felis-daemon keep the app version (`version.workspace = true`). The internal `[workspace.dependencies]` entries carry `version = "0.1.0"` next to `path`. - Dev-dependencies on felis crates name `path` only, so `cargo package` drops them. A versioned one would leave the felis-client-core ↔ felis-daemon cycle unpackageable. `Cargo.lock` and `fuzz/Cargo.lock` are regenerated. - New `just publish-dry-run` (`cargo publish --workspace --dry-run --allow-dirty`), run by `just check` and pr.yml's build job. It packages all 12 crates and builds each against the others in publish order, in about 3 minutes here. If a version already exists on crates.io the dry-run only warns, so `main` stays green after a release. - Docs: workspace.md "Versioning", implementation.md (the versioning rationale, plus a new section that records lockstep versions as the rejected alternative), testing.md CI table, CONTRIBUTING.md. Comments in deny.toml and nix/make-macos-app.sh are updated too. What the gate does not prove: it builds dependents against the local copy of each library. Once a library is on crates.io, a change to it that keeps the published version would still pass. The rule that a library whose package contents changed takes a new version before any dependent is published belongs to the release-automation item, which must land before the first real publish. Local: `cargo build --locked`, lint, deny, docs-links, publish-dry-run, nextest (4329 passed), selftest, test-msrv, prose-check. Reviews (pi, sol): design PASS after three rounds, implementation PASS after two.
release: require the workspace version only on the binary crates
All checks were successful
darwin / detect relevant changes (pull_request) Successful in 10s
darwin / darwin docs-only no-op (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 1m11s
windows / detect relevant changes (pull_request) Successful in 9s
windows / windows docs-only no-op (pull_request) Has been skipped
pr / nix flake check (pull_request) Successful in 28s
pr / cargo build / clippy / test / deny (pull_request) Successful in 1m40s
pr / wire schema is compatible with the base (pull_request) Successful in 4s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 27s
windows / cargo clippy (Windows cross) (pull_request) Successful in 15s
windows / cargo nextest (Windows) (pull_request) Successful in 2m44s
windows / frontend smoke (Windows) (pull_request) Successful in 36s
b5c4776ec6
Under the #160 amendment the library crates take their own versions,
starting at 0.1.0, while felis-cli, felis-client and felis-daemon carry
the app version the release tag names. The tag check refused any crate
that did not inherit [workspace.package] version, so it would block the
first release with decoupled libraries. It now checks only the three
binary crates, and fails when one of them is missing rather than
passing a renamed crate silently.

Assisted-by: Claude Code
workspace, ci, docs: make every crate publishable and package them in CI
All checks were successful
fuzz / cargo fuzz nightly long-run (pull_request) Has been skipped
windows / detect relevant changes (pull_request) Successful in 9s
darwin / detect relevant changes (pull_request) Successful in 10s
windows / windows docs-only no-op (pull_request) Has been skipped
darwin / darwin docs-only no-op (pull_request) Has been skipped
bench / instruction-count regression gate (pull_request) Successful in 45s
fuzz / cargo fuzz smoke (per target) (pull_request) Successful in 50s
windows / cargo nextest (Windows) (pull_request) Successful in 2m27s
darwin / build felis (aarch64-darwin) (pull_request) Successful in 2m54s
pr / nix flake check (pull_request) Successful in 1m51s
windows / frontend smoke (Windows) (pull_request) Successful in 53s
pr / cargo build / clippy / test / deny (pull_request) Successful in 3m22s
pr / wire schema is compatible with the base (pull_request) Successful in 3s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 27s
windows / cargo clippy (Windows cross) (pull_request) Successful in 14s
722c63fe08
The #160 amendment publishes every crate under crates/, with the
libraries on their own versions and the binary crates on the app
version. Until now each member inherited publish = false and the
workspace version, so nothing could be packaged and a packaging break
would surface only at the first real publish.

The libraries move to 0.1.0, and the internal workspace dependencies
carry that version next to their paths. Dev-dependencies on felis
crates name the path alone, so cargo package drops them; a versioned
one would leave the felis-client-core <-> felis-daemon cycle
unpackageable. The new publish-dry-run gate packages all twelve crates
and builds each against the others in publish order.

Assisted-by: Claude Code
natsukium force-pushed ci/publish-dry-run from 722c63fe08
All checks were successful
fuzz / cargo fuzz nightly long-run (pull_request) Has been skipped
windows / detect relevant changes (pull_request) Successful in 9s
darwin / detect relevant changes (pull_request) Successful in 10s
windows / windows docs-only no-op (pull_request) Has been skipped
darwin / darwin docs-only no-op (pull_request) Has been skipped
bench / instruction-count regression gate (pull_request) Successful in 45s
fuzz / cargo fuzz smoke (per target) (pull_request) Successful in 50s
windows / cargo nextest (Windows) (pull_request) Successful in 2m27s
darwin / build felis (aarch64-darwin) (pull_request) Successful in 2m54s
pr / nix flake check (pull_request) Successful in 1m51s
windows / frontend smoke (Windows) (pull_request) Successful in 53s
pr / cargo build / clippy / test / deny (pull_request) Successful in 3m22s
pr / wire schema is compatible with the base (pull_request) Successful in 3s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 27s
windows / cargo clippy (Windows cross) (pull_request) Successful in 14s
to 1b2e030396
All checks were successful
fuzz / cargo fuzz nightly long-run (pull_request) Has been skipped
darwin / detect relevant changes (pull_request) Successful in 9s
windows / detect relevant changes (pull_request) Successful in 9s
darwin / darwin docs-only no-op (pull_request) Has been skipped
windows / windows docs-only no-op (pull_request) Has been skipped
bench / instruction-count regression gate (pull_request) Successful in 46s
darwin / build felis (aarch64-darwin) (pull_request) Successful in 1m12s
fuzz / cargo fuzz smoke (per target) (pull_request) Successful in 51s
pr / nix flake check (pull_request) Successful in 27s
windows / cargo nextest (Windows) (pull_request) Successful in 2m46s
windows / frontend smoke (Windows) (pull_request) Successful in 43s
pr / cargo build / clippy / test / deny (pull_request) Successful in 2m8s
pr / wire schema is compatible with the base (pull_request) Successful in 3s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 26s
windows / cargo clippy (Windows cross) (pull_request) Successful in 14s
2026-10-19 23:08:35 +09:00
Compare
natsukium deleted branch ci/publish-dry-run 2026-10-19 23:48:24 +09:00
Sign in to join this conversation.
No reviewers
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
felis-terminal/felis!197
No description provided.