Skip to content

publish: move settings.toml into aube-settings; pin per-crate include lists#4

Merged
jdx merged 2 commits intomainfrom
publish/crate-layout-fix
Apr 18, 2026
Merged

publish: move settings.toml into aube-settings; pin per-crate include lists#4
jdx merged 2 commits intomainfrom
publish/crate-layout-fix

Conversation

@jdx
Copy link
Copy Markdown
Contributor

@jdx jdx commented Apr 18, 2026

Summary

cargo publish --verify copies the crate to target/package/<name>-<ver>/ and re-runs the build there. aube-settings's build.rs was walking two .parent() hops up from CARGO_MANIFEST_DIR to find settings.toml at the workspace root — during publish verify those hops landed in target/, and settings.toml wasn't in the tarball anyway because cargo only packages files under the crate root.

Fix: move settings.toml into crates/aube-settings/ so it ships with the crate, and read it directly from CARGO_MANIFEST_DIR.

Also add an explicit include = [...] list to every crate's Cargo.toml. With implicit inclusion, anything tracked under a crate directory silently ends up in the published tarball. Explicit lists keep published crates minimal and prevent surprises:

crate includes
aube-settings src/**/*.rs, build.rs, settings.toml
everything else src/**/*.rs

tests/ is intentionally excluded — the integration tests aren't useful to downstream consumers.

Verified locally

  • cargo build --workspace clean
  • cargo package -p aube-settings packages + verifies (10 files)
  • cargo package -p <each other crate> --no-verify produces the expected file list (6 files each, src + Cargo metadata only)
  • cargo run -p aube-settings --bin generate-settings-docs still generates docs/settings/*.md correctly

The other crates' --verify step can't run locally because they depend on aube-settings via crates.io and it's not published yet — release-plz handles this in production by publishing in dependency order.

Test plan

  • Next release-plz run publishes aube-manifest, aube-settings, and remaining crates to crates.io without the verify-build failure.

🤖 Generated with Claude Code


Note

Low Risk
Low risk: packaging/build-script path adjustments and documentation link updates, with no runtime behavior changes beyond making cargo publish --verify succeed.

Overview
Fixes aube-settings publishing by moving settings.toml under the crate and updating build.rs (and the settings docs generator) to read it from CARGO_MANIFEST_DIR, so cargo publish --verify can run from the packaged source.

Adds explicit include = [...] lists to each crate’s Cargo.toml to tightly control what ships in published tarballs (and updates generated docs/settings/*.md links to point at the new settings.toml location).

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

… lists

cargo publish --verify copies the crate into target/package/<name>-<ver>/
and builds from there. aube-settings' build.rs read settings.toml via
two .parent() hops from CARGO_MANIFEST_DIR, landing at target/, and
settings.toml wasn't in the tarball anyway (cargo only packages files
under the crate root). Move settings.toml into crates/aube-settings/
so it ships with the crate, and read it directly from CARGO_MANIFEST_DIR.

Also add an explicit include list to every crate so future accidentally
tracked files (test corpora, generated docs, etc.) don't quietly end up
in published tarballs. Current include lists:

  - aube-settings: src/**/*.rs, build.rs, settings.toml
  - everything else: src/**/*.rs

tests/ is intentionally excluded — our integration tests aren't useful
to downstream crate consumers.
@jdx jdx enabled auto-merge (squash) April 18, 2026 18:46
@jdx jdx disabled auto-merge April 18, 2026 18:46
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 18, 2026

Greptile Summary

This PR fixes a cargo publish --verify failure for aube-settings by relocating settings.toml from the workspace root into crates/aube-settings/ and updating build.rs to read it via CARGO_MANIFEST_DIR rather than walking two parent directories up. It also adds explicit include = [...] lists to every crate's Cargo.toml to keep published tarballs minimal.

  • build.rs: settings_path now resolves from env!(\"CARGO_MANIFEST_DIR\") directly — fixes the root cause (the old .parent().parent() walk landed in target/package/ during verify, where settings.toml wasn't present)
  • crates/aube-settings/settings.toml: moved here from workspace root; content unchanged
  • crates/aube-settings/Cargo.toml: include list ensures the build script and its data file ship together
  • All other Cargo.toml files: include = [\"src/**/*.rs\"] — integration tests intentionally excluded
  • generate_settings_docs.rs: reads settings.toml correctly from the crate dir (line 32), but the hardcoded GitHub URL (line 182) still points to the old workspace-root location

Confidence Score: 4/5

Safe to merge with one small follow-up fix needed in the docs generator URL

The core fix is correct and well-reasoned — moving settings.toml into the crate and reading it via CARGO_MANIFEST_DIR is the right solution. The include lists across all crates are clean and consistent. The only concrete issue is a stale hardcoded GitHub URL in the docs generator that will produce broken links in every generated settings page; it's a one-line fix. The aube-cli [[test]] concern is low-impact.

crates/aube-settings/src/bin/generate_settings_docs.rs line 182 (stale URL); crates/aube-cli/Cargo.toml (excluded test target still declared)

Important Files Changed

Filename Overview
crates/aube-settings/build.rs Core fix: reads settings.toml from CARGO_MANIFEST_DIR directly instead of two .parent() hops; resolves cargo publish --verify breakage
crates/aube-settings/Cargo.toml Adds explicit include = ["src/**/*.rs", "build.rs", "settings.toml"] so the published tarball contains all files the build script needs
crates/aube-settings/settings.toml File moved from workspace root into the crate directory so it ships with the published tarball; content unchanged
crates/aube-settings/src/bin/generate_settings_docs.rs Updated to read settings.toml from CARGO_MANIFEST_DIR; stale GitHub URL on line 182 still points to old workspace-root location
crates/aube-settings/src/meta.rs Doc comment updated to reflect settings.toml is now crate-local; no logic changes
crates/aube-cli/Cargo.toml Adds include = ["src/**/*.rs"]; the [[test]] declaration referencing tests/e2e.rs (not included) will cause cargo test to fail for anyone who downloads the crate
crates/aube-linker/Cargo.toml Adds include = ["src/**/*.rs"]; no other changes
crates/aube-manifest/Cargo.toml Adds include = ["src/**/*.rs"]; no other changes

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[cargo publish -p aube-settings] --> B[Package crate tarball]
    B --> C["Extract to target/package/aube-settings-ver/"]
    C --> D[cargo build --verify]
    D --> E[build.rs executes]
    E --> F["PathBuf::from(CARGO_MANIFEST_DIR).join('settings.toml')"]
    F --> G["Reads crates/aube-settings/settings.toml ✅"]
    G --> H["Generates settings_meta_data.rs + settings_resolved.rs → OUT_DIR"]
    H --> I[Build succeeds]

    subgraph OLD ["Before this PR (broken)"]
        X[build.rs] --> Y["CARGO_MANIFEST_DIR.parent().parent()"]
        Y --> Z["target/package/ — settings.toml not here ❌"]
    end

    subgraph NEW ["After this PR (fixed)"]
        F
        G
    end
Loading

Comments Outside Diff (1)

  1. crates/aube-settings/src/bin/generate_settings_docs.rs, line 182 (link)

    P1 Stale GitHub link after settings.toml relocation

    settings.toml was moved from the workspace root to crates/aube-settings/settings.toml in this PR, but the URL embedded in every generated docs page still points to the old workspace-root path. Clicking this link on any published docs page will land on a 404.

    Fix in Claude Code

Fix All in Claude Code

Reviews (2): Last reviewed commit: "publish: move settings.toml into aube-se..." | Re-trigger Greptile

The 'generated from settings.toml' line in every docs/settings/*.md
page is hard-coded in the generator. After moving settings.toml into
crates/aube-settings/, the old workspace-root URL 404s. Update the
template and regenerate all five pages.
@jdx jdx merged commit 5d2fbc1 into main Apr 18, 2026
16 checks passed
@jdx jdx deleted the publish/crate-layout-fix branch April 18, 2026 19:01
jdx added a commit that referenced this pull request Apr 18, 2026
Buildkite allocates a PTY for each job so tools emit colors. hk's
spinner and mise's -v DEBUG stream both detect the TTY and flood the
log — we counted 28,432 rows on build #4's `linux / test` step, most
of them progress frames captured as newline-separated lines after
Buildkite strips the cursor-control escapes.

- mise.toml: pipe `hk check`/`hk fix` through `cat`, which breaks the
  PTY on both stdout and stderr and forces hk into its non-interactive
  path. ~10k spinner-frame rows per run go away.
- .buildkite/bootstrap.sh: drop `-v` from `mise install`. `--locked`
  stays, INFO-level output stays; the ~15k DEBUG rows from the initial
  bootstrap go away.

No wall-clock change — this is purely log hygiene so failures are
findable and the Buildkite UI loads quickly.
jdx added a commit that referenced this pull request Apr 18, 2026
## Summary

- Pipe `hk check` / `hk fix` through `cat` in `mise.toml` so hk drops
its spinner UI under Buildkite's PTY. Kills ~10k progress-frame rows per
`linux / test` run.
- Drop `-v` from `mise install` in `.buildkite/bootstrap.sh`. Kills ~15k
DEBUG-level rows from bootstrap; `--locked` and INFO output remain.

## Why

Buildkite agents run commands under a PTY so cargo/clippy emit colors.
From hk and aube's perspective `isatty(stderr) == true`, so they render
spinners. Buildkite's log capturer strips cursor-up/clear-line escapes
but keeps the text, so each animation frame becomes its own log line.

Concrete evidence from build #4's `linux / test` step:
- Total log rows: **28,432** for a single step
- `mise install -v` bootstrap alone: ~15,900 rows (DEBUG log flood)
- `hk check --all --slow`: ~10,200 rows (spinner-frame flood)
- Wall-clock breakdown unchanged — compile/lint time is ~3 minutes on a
warm cache, it was just hard to see through the noise.

Verified on warm-cache build #6 that the cache path itself is healthy
(4.4G restored, zero `Compiling` messages in `cargo test`), so the
5-minute wall clock on the cold-start build #4 wasn't a cache bug — just
a cold cargo target dir on pipeline init.

## Test plan

- [ ] Next Buildkite run on this branch: `linux / test` log rows drop
from ~28k to ~3k
- [ ] `hk check --all --slow` still runs to completion and surfaces real
lint errors (spinner gone, but the final error summary is what actually
matters)
- [ ] `mise install` still installs all tools; only the DEBUG chatter is
gone

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes how progress output is rendered in CI and modifies the
Buildkite lint command pipeline; mistakes could hide failures (mitigated
via `set -o pipefail`) or degrade progress UX.
> 
> **Overview**
> Reduces Buildkite log noise by making `aube` prefer CI-style
(append-only) progress output when running in a detected CI environment
even if stderr is a TTY (via new `is_ci` dependency).
> 
> Buildkite’s `linux / test` step now runs `mise run lint` through `cat`
with `pipefail` to prevent `hk` spinner frames from exploding log rows
while still failing the step on lint errors, and
`.buildkite/bootstrap.sh` drops verbose `mise install -v` to avoid
DEBUG-level bootstrap spam.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5cc91ed. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
jdx added a commit that referenced this pull request May 2, 2026
## Summary
Real-world failure:
[tuist/tuist#10584](tuist/tuist#10584) tried to
swap pnpm for aube and CI hit `workspace package noora at noora has no
\`version\` field` from
[crates/aube/src/commands/install/mod.rs:1869](crates/aube/src/commands/install/mod.rs:1869).
pnpm accepts the same repo without complaint.

The unconditional check predates the resolver's current `workspace:*` /
`workspace:^` / `workspace:~` / bare-`*` fallback. The comment's
collision rationale ("two unversioned members under one dep_path")
doesn't hold either: `dep_path` keys on `(name, version)` and two
members have distinct names by construction.

Fix: fall back to `"0.0.0"` when `version` is absent. `workspace:*` /
`workspace:^` / `workspace:~` / bare-`*` siblings still link locally
(those branches in `resolve_workspace` accept any ws version
regardless). A specific range like `workspace:^2.0.0` against an
unversioned member correctly fails to satisfy, matching pnpm.

## Test plan
- [x] `cargo test` (full suite green)
- [x] `cargo clippy --all-targets -- -D warnings`
- [x] `cargo fmt --check`
- [x] `mise run test:bats test/workspace.bats` — 19 pass, including the
new regression #4
- [ ] CI green on push

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jdx added a commit that referenced this pull request May 3, 2026
* Skip empty bytes_segment so the phase-2 label doesn't render a
  doubled `·  ·` separator on installs without `dist.unpackedSize`
  (Greptile P1).
* Switch ETA to fetch-window throughput: snapshot completed at the
  set_phase("fetching") boundary, then divide remaining work by
  `fetch_elapsed_ms / (completed - baseline)`. Falls back to `ETA …`
  while the baseline or fetch window are missing. Eliminates the
  pessimistic "110s ETA after a 3s resolve" case (Greptile P2).
* Reconcile estimated_bytes after filter_graph: track per-dep_path
  unpacked_size during streaming, then re-sum surviving dep_paths
  via the new InstallProgress::reconcile_estimated_bytes API.
  Mirrors the package-denominator reconcile applied next to it
  (Greptile P3).
* Apply TARBALL_COMPRESSION_RATIO in TTY refresh_bytes_segment too —
  CI mode applied it; TTY was showing the raw unpacked sum (~3.3×
  inflated) (Cursor #1).
* Refresh ETA on every inc_downloaded_bytes so it doesn't freeze
  during long downloads when no inc_total / inc_reused events fire.
  Documents the trade-off at FetchRow::drop where a refresh would
  require a larger refactor (Cursor #3).
* Style only the ✓ green on the install / no-op summaries instead
  of the whole sentence; aligns with the CI heartbeat summary's
  styling so the success cue stays sharp without bleeding green
  across the line (Cursor #4 + user request).
* Standardize the ✓ prefix on both Already-up-to-date paths
  (`print_install_summary` and `print_already_up_to_date`).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant