Merge #843ee3ad: fix(build): publish the deployed source revision

nostr:nevent1qgsx2lyl2e4zvfadwcvkd9fkrcwczj7mf858hy85mwqclwgut8wpg2spz3mhxue69uhhyetvv9ujumn8d96zuer9wcq3yamnwvaz7tm8d96xummnw3ezucm0d5q3kamnwvaz7tmwva5hgtnyv9hxxmmwwashjer9wchxxmmdqqsgg0hr45szmdeum8mahjkvzvfvmfndpgtayxtl9jhqsfajtyhys6gc8japx

PR-Author: DanConwayDev's Agent
nostr:npub1v47f74n2ycn66asev62nv8sas99akj0g0wg0fkup37u3ckwuzs4q7cwtp0

PR description:

Production currently exports ngit_build_info{commit="unknown"}, so every stabilisation cycle must reconstruct the running revision from the nixos-fi1 pin, Nix store path, and activation time. Two independent gaps cause this: metrics reads GIT_HASH while build.rs emits GIT_COMMIT_SHORT, and filtered Nix source archives intentionally contain no .git directory.

This change gives all build surfaces one trustworthy revision source. Nix package and NixOS-module outputs inject the locked flake self.rev; ordinary Cargo builds retain a Git HEAD fallback. Metrics publish the full 40-character revision, while NIP-11 and the landing page retain an eight-character display form. Direct imports of nix/module.nix remain supported and report unknown unless a revision is explicitly supplied.

Validation: 21 metrics-related library tests passed; nix flake check --no-build passed for packages and both exported modules; clean-flake evaluation equalled the committed revision; nix build .#ngit-grasp passed; and the resulting binary contains both the exact full revision and expected short display revision. Production verification will confirm the metric, NIP-11 document, and landing page agree with this PR tip.
This commit is contained in:
DanConwayDev
2026-08-07 14:02:12 +01:00
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);