Skip to content

feat(gateway): show commit hash in version for non-tagged builds - #2486

Merged
ilblackdragon merged 6 commits into
stagingfrom
worktree-commit-hash-in-version
Apr 18, 2026
Merged

ilblackdragon merged 6 commits into
stagingfrom
worktree-commit-hash-in-version

Conversation

@serrrfirat

Copy link
Copy Markdown
Collaborator

Summary

  • Adds git commit hash to the user info popover when the build is not from a tagged release
  • Tagged releases show just "IronClaw v0.25.0"; dev builds show "IronClaw v0.25.0 (88d3f63)" or "IronClaw v0.25.0 (88d3f63-dirty)"
  • Enables users to report exact build versions when filing bugs

Changes

  • build.rs — new emit_git_metadata() captures short commit hash and dirty flag at compile time via GIT_COMMIT_HASH / GIT_DIRTY env vars
  • src/channels/web/server.rs — adds commit_hash field to /api/gateway/status response
  • crates/ironclaw_gateway/static/app.js — renders commit hash in the version line when present

Test plan

  • Build from a non-tagged commit → verify popover shows IronClaw v0.25.0 (<hash>)
  • Build with uncommitted changes → verify it shows (<hash>-dirty)
  • Build from a tagged commit (e.g. git tag v0.25.0) → verify only version is shown, no hash
  • cargo clippy --all --all-features passes with zero warnings

🤖 Generated with Claude Code

… 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>
@github-actions github-actions Bot added scope: channel/web Web gateway channel size: M 50-199 changed lines risk: medium Business logic, config, or moderate-risk modules contributor: core 20+ merged PRs labels Apr 15, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread build.rs
Comment on lines +125 to +138
// 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);
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Suggested change
// 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.
@serrrfirat

Copy link
Copy Markdown
Collaborator Author

Addressed review feedback

gemini-code-assist — worktree-safe git directory resolution in build.rs:

  • Replaced hardcoded .git/HEAD path lookup with git rev-parse --git-dir, which correctly resolves the git metadata directory in all environments (regular repos, worktrees, submodules)
  • cargo:rerun-if-changed directives now use the resolved paths instead of relative .git/... paths

@github-actions github-actions Bot added the scope: dependencies Dependency updates label Apr 15, 2026
@serrrfirat serrrfirat closed this Apr 15, 2026
@serrrfirat serrrfirat reopened this Apr 15, 2026
@serrrfirat
serrrfirat marked this pull request as draft April 15, 2026 10:19
@serrrfirat
serrrfirat marked this pull request as ready for review April 15, 2026 10:20
@serrrfirat
serrrfirat force-pushed the worktree-commit-hash-in-version branch 3 times, most recently from 6b06db3 to 2be67c4 Compare April 15, 2026 10:24
@serrrfirat serrrfirat closed this Apr 15, 2026
@serrrfirat serrrfirat reopened this Apr 15, 2026
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.

@henrypark133 henrypark133 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
@serrrfirat

Copy link
Copy Markdown
Collaborator Author

Addressed review feedback from @henrypark133:

Fix: build.rs now resolves branch refs via git rev-parse --git-common-dir instead of --git-dir. In worktrees, --git-dir points to .git/worktrees/<name> but branch refs (e.g. refs/heads/main) live under the common git directory. The watcher now looks up refs in git_common_dir first, with a fallback to git_dir for non-worktree repos.

Commit: 7dab822

@serrrfirat
serrrfirat requested a review from henrypark133 April 16, 2026 13:33
henrypark133
henrypark133 previously approved these changes Apr 17, 2026

@henrypark133 henrypark133 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@ilblackdragon
ilblackdragon merged commit 645c2eb into staging Apr 18, 2026
16 checks passed
@ilblackdragon
ilblackdragon deleted the worktree-commit-hash-in-version branch April 18, 2026 03:58
@ilblackdragon ilblackdragon mentioned this pull request Apr 18, 2026
5 of 7 tasks
@henrypark133 henrypark133 mentioned this pull request Apr 21, 2026
theredspoon pushed a commit to theredspoon/ironclaw that referenced this pull request Jun 21, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: medium Business logic, config, or moderate-risk modules scope: channel/web Web gateway channel scope: dependencies Dependency updates size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants