feat(gateway): show commit hash in version for non-tagged builds - #2486
Conversation
… builds When the binary is not built from an exact git tag, the user info popover now shows the short commit hash next to the version (e.g. "IronClaw v0.25.0 (88d3f63)"). Modified working trees append "-dirty". Tagged releases show just the version as before. This lets users report the exact build when filing bugs. [skip-regression-check] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request integrates git metadata into the build process to display commit hashes and repository dirty status in the gateway's version information. Changes include a new emit_git_metadata function in build.rs and updates to the web server and frontend to handle and display this data. A review comment identifies that the logic for locating the git directory in build.rs is not robust for git worktrees and suggests using git rev-parse --git-dir instead.
| // Rerun when the git HEAD changes (commit, checkout, rebase). | ||
| let git_head = root.join(".git/HEAD"); | ||
| if git_head.exists() { | ||
| println!("cargo:rerun-if-changed=.git/HEAD"); | ||
| // Also watch the ref that HEAD points to (for branch commits). | ||
| if let Ok(head) = std::fs::read_to_string(&git_head) | ||
| && let Some(refpath) = head.trim().strip_prefix("ref: ") | ||
| { | ||
| let reffile = root.join(".git").join(refpath); | ||
| if reffile.exists() { | ||
| println!("cargo:rerun-if-changed=.git/{}", refpath); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
The current logic for finding the .git/HEAD file by joining the path root.join(".git/HEAD") is not robust and will fail in environments that use git worktree. In a worktree, .git is a file, not a directory, and the actual git metadata is located elsewhere. This will cause the build script to not re-run on commits, leading to stale build information.
A more robust approach is to ask git for its directory path using git rev-parse --git-dir. This command correctly resolves the git directory path in all scenarios, including worktrees. Since this build script already shells out to git for other operations, adding one more call for robustness is a good trade-off.
| // Rerun when the git HEAD changes (commit, checkout, rebase). | |
| let git_head = root.join(".git/HEAD"); | |
| if git_head.exists() { | |
| println!("cargo:rerun-if-changed=.git/HEAD"); | |
| // Also watch the ref that HEAD points to (for branch commits). | |
| if let Ok(head) = std::fs::read_to_string(&git_head) | |
| && let Some(refpath) = head.trim().strip_prefix("ref: ") | |
| { | |
| let reffile = root.join(".git").join(refpath); | |
| if reffile.exists() { | |
| println!("cargo:rerun-if-changed=.git/{}", refpath); | |
| } | |
| } | |
| } | |
| // Rerun when the git HEAD changes (commit, checkout, rebase). | |
| if let Ok(output) = Command::new("git").args(["rev-parse", "--git-dir"]).current_dir(root).output() { | |
| if output.status.success() { | |
| let git_dir = std::path::PathBuf::from(String::from_utf8_lossy(&output.stdout).trim()); | |
| let git_head = git_dir.join("HEAD"); | |
| if git_head.exists() { | |
| println!("cargo:rerun-if-changed={}", git_head.display()); | |
| // Also watch the ref that HEAD points to (for branch commits). | |
| if let Ok(head) = std::fs::read_to_string(&git_head) | |
| && let Some(refpath) = head.trim().strip_prefix("ref: ") | |
| { | |
| let reffile = git_dir.join(refpath); | |
| if reffile.exists() { | |
| println!("cargo:rerun-if-changed={}", reffile.display()); | |
| } | |
| } | |
| } | |
| } | |
| } |
…king (#2486) Address gemini-code-assist review: the hardcoded `.git/HEAD` path fails inside git worktrees where `.git` is a file, not a directory. Use `git rev-parse --git-dir` to robustly resolve the actual git metadata directory in all environments.
Addressed review feedbackgemini-code-assist — worktree-safe git directory resolution in
|
6b06db3 to
2be67c4
Compare
Bump rustls-webpki 0.103.10 → 0.103.12 (fixes the advisory for the direct dep chain). The 0.101.7 (aws-smithy/rustls 0.21) and 0.102.8 (libsql) versions are pinned by transitive deps and cannot be bumped — add ignore entries with context.
1916511 to
fd706e0
Compare
henrypark133
left a comment
There was a problem hiding this comment.
Review: Commit hash in gateway version
One blocker remains in the current diff.
Concerning: build metadata stops updating on new commits in git worktrees
File: build.rs:142
The new watcher resolves the branch ref by joining ref: refs/heads/... onto git rev-parse --git-dir. In a git worktree, --git-dir points at .git/worktrees/<name>, but the branch ref itself lives under the common git dir (git rev-parse --git-common-dir). That means git_dir.join(refpath) never exists in worktrees, so Cargo only watches .../worktrees/<name>/HEAD. New commits on the same checked-out branch do not change that HEAD file, so build.rs will not rerun and the exposed commit hash can go stale until a clean rebuild or checkout change.
Suggested fix: resolve refs relative to --git-common-dir (or emit both --git-dir and --git-common-dir watchers) so branch advances in worktrees retrigger the build script.
In git worktrees, branch refs (e.g. refs/heads/main) live under the common git directory, not the per-worktree git directory. Resolve refs via `git rev-parse --git-common-dir` so Cargo watches the correct file and rebuilds on new commits in worktree environments. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Addressed review feedback from @henrypark133: Fix: Commit: 7dab822 |
henrypark133
left a comment
There was a problem hiding this comment.
Review: commit hash in gateway version
No verified findings in the current diff.
The worktree watcher now uses --git-common-dir for branch refs, so the earlier stale-metadata issue in git worktrees is addressed, and the gateway response/UI only surfaces the hash on non-tagged builds.
…rai#2486) * feat(gateway): show git commit hash in version display for non-tagged builds When the binary is not built from an exact git tag, the user info popover now shows the short commit hash next to the version (e.g. "IronClaw v0.25.0 (88d3f63)"). Modified working trees append "-dirty". Tagged releases show just the version as before. This lets users report the exact build when filing bugs. [skip-regression-check] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(build): use `git rev-parse --git-dir` for worktree-safe HEAD tracking (nearai#2486) Address gemini-code-assist review: the hardcoded `.git/HEAD` path fails inside git worktrees where `.git` is a file, not a directory. Use `git rev-parse --git-dir` to robustly resolve the actual git metadata directory in all environments. * fix(build): collapse nested if to satisfy clippy::collapsible_if * fix(deps): bump rustls-webpki 0.103.12, ignore RUSTSEC-2026-{0098,0099} Bump rustls-webpki 0.103.10 → 0.103.12 (fixes the advisory for the direct dep chain). The 0.101.7 (aws-smithy/rustls 0.21) and 0.102.8 (libsql) versions are pinned by transitive deps and cannot be bumped — add ignore entries with context. * fix(build): use --git-common-dir for worktree-safe ref watching (nearai#2486) In git worktrees, branch refs (e.g. refs/heads/main) live under the common git directory, not the per-worktree git directory. Resolve refs via `git rev-parse --git-common-dir` so Cargo watches the correct file and rebuilds on new commits in worktree environments. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Illia Polosukhin <ilblackdragon@gmail.com>
Summary
Changes
build.rs— newemit_git_metadata()captures short commit hash and dirty flag at compile time viaGIT_COMMIT_HASH/GIT_DIRTYenv varssrc/channels/web/server.rs— addscommit_hashfield to/api/gateway/statusresponsecrates/ironclaw_gateway/static/app.js— renders commit hash in the version line when presentTest plan
IronClaw v0.25.0 (<hash>)(<hash>-dirty)git tag v0.25.0) → verify only version is shown, no hashcargo clippy --all --all-featurespasses with zero warnings🤖 Generated with Claude Code