fix(build): publish the deployed source revision

Production ngit_build_info reports commit="unknown", forcing every stabilisation cycle to reconstruct the running revision from the deployment pin, store path, and activation time. The metrics reader also expected GIT_HASH while build.rs emitted GIT_COMMIT_SHORT.

Use one full GIT_COMMIT compile-time value for metrics and retain its eight-character form for NIP-11 and the landing page. Nix package and module outputs inject the locked flake revision because filtered Nix sources do not contain .git; ordinary Cargo builds continue to derive HEAD from Git.

Correctness assumes production consumes ngit-grasp through its exported flake module, which captures self.rev. Direct module imports remain supported but deliberately report unknown when no revision is supplied. Runtime configuration and deployment policy are unchanged.

Validated with the 21 metrics-related library tests, nix flake check --no-build, and evaluation of the dirty-tree revision injection. A clean Nix package build and production endpoint verification follow on this committed revision.
This commit is contained in:
DanConwayDev
2026-08-07 12:05:40 +00:00
parent 662491c99c
commit 57bc76ea69
5 changed files with 42 additions and 15 deletions
+3
View File
@@ -59,6 +59,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Published the source revision in build metrics, NIP-11 metadata, and the
landing page for Nix-built releases, where the filtered source archive does
not contain Git metadata.
- Stopped routine client connection resets without a WebSocket close handshake
from being reported as server errors, while retaining other embedded-relay
failures at their original severity.
+25 -12
View File
@@ -1,20 +1,33 @@
use std::process::Command;
use std::{env, process::Command};
fn main() {
// Get the short git commit hash
let output = Command::new("git")
.args(["rev-parse", "--short", "HEAD"])
.output();
if let Ok(output) = output {
if output.status.success() {
let commit = String::from_utf8_lossy(&output.stdout);
let commit = commit.trim();
println!("cargo:rustc-env=GIT_COMMIT_SHORT={}", commit);
}
if let Some(commit) = build_revision() {
let short: String = commit.chars().take(8).collect();
println!("cargo:rustc-env=GIT_COMMIT={commit}");
println!("cargo:rustc-env=GIT_COMMIT_SHORT={short}");
}
// Nix builds inject the locked flake revision because their source archive
// intentionally excludes .git. Development builds fall back to Git.
println!("cargo:rerun-if-env-changed=NGIT_BUILD_REVISION");
// Re-run if HEAD changes (new commits)
println!("cargo:rerun-if-changed=.git/HEAD");
println!("cargo:rerun-if-changed=.git/refs/heads/");
}
fn build_revision() -> Option<String> {
env::var("NGIT_BUILD_REVISION")
.ok()
.filter(|revision| !revision.is_empty() && revision != "unknown")
.or_else(|| {
let output = Command::new("git")
.args(["rev-parse", "HEAD"])
.output()
.ok()?;
output
.status
.success()
.then(|| String::from_utf8_lossy(&output.stdout).trim().to_owned())
.filter(|revision| !revision.is_empty())
})
}
+11 -1
View File
@@ -8,6 +8,12 @@
};
outputs = { self, nixpkgs, rust-overlay, flake-utils }:
let
sourceRevision =
if self ? rev then self.rev
else if self ? dirtyRev then self.dirtyRev
else "unknown";
in
(flake-utils.lib.eachDefaultSystem (system:
let
overlays = [ (import rust-overlay) ];
@@ -44,6 +50,7 @@
pname = "ngit-grasp";
version = "2.0.0";
src = ./.;
NGIT_BUILD_REVISION = sourceRevision;
cargoLock = {
lockFile = ./Cargo.lock;
};
@@ -80,7 +87,10 @@
};
})) // {
# NixOS module for deployment
nixosModules.default = import ./nix/module.nix;
nixosModules.default = { ... }: {
imports = [ ./nix/module.nix ];
_module.args.ngitGraspSourceRevision = sourceRevision;
};
nixosModules.ngit-grasp = self.nixosModules.default;
};
}
+2 -1
View File
@@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }:
{ config, lib, pkgs, ngitGraspSourceRevision ? "unknown", ... }:
with lib;
@@ -8,6 +8,7 @@ let
pname = "ngit-grasp";
version = "2.0.0";
src = ../.;
NGIT_BUILD_REVISION = ngitGraspSourceRevision;
cargoLock = {
lockFile = ../Cargo.lock;
};
+1 -1
View File
@@ -832,7 +832,7 @@ impl MetricsInner {
build_info
.with_label_values(&[
env!("CARGO_PKG_VERSION"),
option_env!("GIT_HASH").unwrap_or("unknown"),
option_env!("GIT_COMMIT").unwrap_or("unknown"),
])
.set(1.0);