Skip to content

build: only watch git paths that exist, so the crate isn't rebuilt on every cargo run - #270

Merged
Nic-dorman merged 2 commits into
mainfrom
nic/v2-1828-build-rs-rerun-paths
Nov 3, 2026
Merged

Nic-dorman merged 2 commits into
mainfrom
nic/v2-1828-build-rs-rerun-paths

Conversation

@Nic-dorman

@Nic-dorman Nic-dorman commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Linear issue

Closes V2-1828

Summary

build.rs declared cargo:rerun-if-changed for three hard-coded paths: .git/HEAD, .git/refs/heads and .git/packed-refs. Cargo treats a rerun-if-changed path that doesn't exist as changed on every build. So whenever one is missing, every cargo invocation reruns the build script and recompiles ant-node from scratch.

Where it bites:

  • Git worktrees. There .git is a file, not a directory. Locally, CARGO_LOG=cargo::core::compiler::fingerprint=info cargo check reports stale: missing ".git/HEAD" on every run.
  • CI checkouts. One of the paths is missing there too, probably packed-refs in the shallow clone.
    • On ci: consolidate PR CI, run every test target, build the shipped binary #269's run for a8e4cb1, a prebuild step had already built all 10 integration test binaries. Each cargo test --test X afterwards still printed Compiling ant-node and spent about 2m20s rebuilding the identical binary (same hash). Its tests then ran in under a second.
    • Today's ci.yml pays this on every cargo test --test X step, which is why each PoC step takes 2–5 minutes (ubuntu ~2, macOS ~3, Windows ~4.5) for sub-second tests.

Fix: ask git for the real directories (git rev-parse --git-dir and --git-common-dir), and emit rerun-if-changed only for paths that exist. ANT_GIT_COMMIT is still refreshed when HEAD or a branch ref moves.

After review (8acb6c7): with every ref packed and no refs/heads directory, the first version watched nothing for branch refs. The next commit creates refs/heads/<branch> without touching HEAD or packed-refs, so ANT_GIT_COMMIT could go stale.

  • The watch-set logic now lives in build_support/git_watch.rs, shared by build.rs and a new test target through #[path].
  • When refs/heads is missing, it watches the nearest existing ancestor inside the common dir (normally refs/). Cargo scans that recursively, so it sees the loose ref appear. Every emitted path still exists.

Split out of the CI consolidation (#269, V2-1811) so it can land on its own. #269 carries the same commit and will drop it on rebase once this merges.

Risk tier

  • T0 — docs / tooling / CI / pure UX-output. Repo CI only.
  • T1 — client-only, no network-facing behavior change. CI + prod compat smoke.
  • T2 — node/client logic with behavioral surface, no protocol/format/economics change. Dev testnet + ADR.
  • T3 — protocol / storage format / payments / routing. T2 evidence + adversarial testing.

Compatibility

  • Wire: none
  • Storage: none
  • API: none. The only output of build.rs is the ANT_GIT_COMMIT env var, which is unchanged.

Semver impact

  • breaking
  • feature
  • fix

Test evidence

  • Before (main, in a worktree): every cargo check reruns the build script and rechecks ant-node, with the fingerprint log reporting stale: missing ".git/HEAD".
  • After: the first cargo check reruns the script, and the second is fresh (Finished … in 0.92s, nothing marked dirty). The emitted paths are the real ones: the worktree's HEAD, plus the common dir's refs/heads and packed-refs.
  • A new commit still updates ANT_GIT_COMMIT: after committing, the next cargo check reran the script and emitted the new short hash (e0afed1).
  • New tests/build_script_git_watch.rs (3 tests, real git repositories in a temp dir), run by a new ci.yml step:
    • a branch commit changes a watched path
    • refs packed and refs/heads removed: the next commit leaves HEAD and packed-refs untouched but still changes a watched path
    • in a worktree, every watched path exists and a commit is seen
  • All 3 pass locally (Windows). With the first version's logic put back, the packed-refs test fails with "the commit changed no watched path, so ANT_GIT_COMMIT would go stale", so it catches the bug review found.
  • After the change, a second cargo check is still fresh (nothing marked stale or dirty).
  • cargo fmt --check is clean, and clippy raises nothing in build.rs.
  • This PR's own CI run is the live check. It uses today's per-target ci.yml, so the Run v12 … / bootstrap-stall / crash-safety steps should drop from 2–5 min each to well under a minute.

New dependency

none

ADR

n/a

Mitigation / rollback

Revert the commit. The worst case of a bug here is a stale ANT_GIT_COMMIT in a local build; release builds come from a fresh checkout.

🤖 Generated with Claude Code

… every cargo run

build.rs declared rerun-if-changed for .git/HEAD, .git/refs/heads and
.git/packed-refs. Cargo treats a path that doesn't exist as changed on
every build, so whenever one was missing the script reran and ant-node
was recompiled from scratch on each cargo invocation. That happens in a
git worktree (.git is a file) and in CI checkouts: on PR #269 every
`cargo test --test X` spent ~2m20s recompiling ant-node for a test binary
the previous step had already built, and the per-target steps in today's
ci.yml pay the same cost (2-5 min each for sub-second tests).

The script now asks git for the real git dir and common dir, and only
watches the paths that exist. ANT_GIT_COMMIT is still refreshed when HEAD
or a branch ref moves.

Closes V2-1828

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@MaidSafe-Hermes MaidSafe-Hermes 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.

REQUEST_CHANGES — at c04cb27. Coverage: 2/2 seats reviewed (sol-1 gpt-6.1-sol xhigh; glm-1 z-ai/glm-5.3); they disagreed. I confirmed sol-1’s blocker with a Git reproduction: when refs are packed and refs/heads is absent, the build registers no watch for that directory; a later commit creates refs/heads/ but leaves HEAD and packed-refs unchanged, so Cargo can retain stale ANT_GIT_COMMIT. Please watch an existing ancestor when refs/heads is absent (without emitting a nonexistent path) and add a regression test for this transition. Location: build.rs:44. This is separate from the pending CI and Security Audit result.

… add regression tests

Review on #270: with every ref packed and no refs/heads directory, the
previous commit watched nothing for branch refs. The next commit creates
refs/heads/<branch> without touching HEAD or packed-refs, so Cargo kept a
stale ANT_GIT_COMMIT.

The watch-set logic moves to build_support/git_watch.rs, shared by
build.rs and a new test target through #[path]. When refs/heads is
missing it now watches the nearest existing ancestor inside the common
dir (normally refs/), which Cargo scans recursively and so sees the
loose ref appear. Every emitted path still exists.

tests/build_script_git_watch.rs drives real repositories:
- a branch commit changes a watched path
- refs packed, refs/heads removed: the next commit leaves HEAD and
  packed-refs untouched but still changes a watched path (fails against
  the previous version of the logic)
- in a worktree every watched path exists and a commit is seen

ci.yml runs the new target alongside the other named ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@MaidSafe-Hermes MaidSafe-Hermes 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.

APPROVE — reviewed head 8acb6c7. Coverage: 2/2 seats reviewed (sol-1 gpt-6.1-sol xhigh; glm-1 z-ai/glm-5.3); both seats approve. The prior stale ANT_GIT_COMMIT case is fixed by watching the nearest existing ancestor when refs/heads is absent, and the new packed-refs regression test covers it. Build, test, format, clippy, MSRV and other CI checks have passed. Security Audit remains failed; it is separate from this code-review verdict and remains relevant to merge readiness.

@Nic-dorman
Nic-dorman merged commit 891e08d into main Nov 3, 2026
22 of 23 checks passed
@Nic-dorman
Nic-dorman deleted the nic/v2-1828-build-rs-rerun-paths branch November 3, 2026 14:45
grumbach added a commit to grumbach/ant-node that referenced this pull request Nov 3, 2026
Main merged ADR-0020's chunk get-or-closer read (WithAutonomi#249: a node answers
`GetOrCloserRequest` with the chunk or its closest peers, and says so in
its user agent), the consolidated CI (WithAutonomi#269), and build.rs watching only git
paths that exist (WithAutonomi#270).

Conflicts:
- Cargo.toml: main pinned saorsa-core and ant-protocol at ADR-0020
  revisions in a second `[patch.crates-io]` table. This branch's table
  already patches both to their feat/peer-swarm branches, which have merged
  their mains and so carry those revisions, so the one table stays, with
  its comment saying so. Cargo.lock moves both to those branches' new
  heads.
- src/node.rs: both sides added an import from `ant_protocol`.

Beyond the conflicts:
- ant-protocol's main put get-or-closer at wire discriminants 14 and 15,
  where this branch's swarm variants had been; they now follow it, at 16
  to 21. The node tells a swarm request from its header alone
  (`is_swarm_request_bytes`), by those discriminants, so its constants move
  from 14, 16 and 18 to 16, 18 and 20. Left as they were, every
  get-or-closer request would have gone to the swarm rendezvous and stayed
  unanswered. The test that tells swarm requests apart now also checks that
  a get-or-closer request or response is not taken for one, and fails with
  the old constants.
- ADR-0026 gives the new discriminants.

`cargo test --lib` 1255 passed, 1194 without default features (its tests
also build with `-D warnings`); fmt, clippy with all targets and features
and lib-only on Rust 1.99, `cargo check --lib --no-default-features
--locked` and `RUSTDOCFLAGS="-D warnings" cargo doc --no-deps`: clean.
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.

2 participants