towerops-agent/build.rs
Graham McIntire c0fe57cd44
fix: properly inject version into Docker image builds
The agent version was always showing 0.1.0 because build.rs tried to
run 'git describe' inside the Docker build, but .git directory wasn't
copied into the image.

Changes:
- Add VERSION build arg to Dockerfile
- Pass VERSION as env var to cargo build commands
- Update GitLab CI to pass --build-arg VERSION
- Modify build.rs to prefer BUILD_VERSION env var over git commands

This ensures the version displayed by the agent matches the Docker
image tag it was built with.
2026-01-19 15:31:26 -06:00

83 lines
2.7 KiB
Rust

use std::process::Command;
fn main() {
// Compile protobuf definitions
prost_build::compile_protos(&["proto/agent.proto"], &["proto/"]).unwrap();
// Inject git-based version if available, otherwise use Cargo.toml version
// This ensures the binary version matches the Docker image tag
let version = get_version();
println!("cargo:rustc-env=BUILD_VERSION={}", version);
}
fn get_version() -> String {
// First check if BUILD_VERSION is already set (e.g., from Docker build arg)
if let Ok(version) = std::env::var("BUILD_VERSION") {
if !version.is_empty() && version != "0.1.0-unknown" {
return version;
}
}
// Try git describe - gives us the most descriptive version
// Examples:
// v0.2.0 -> "0.2.0" (exact tag)
// v0.2.0-5-g831588e -> "0.2.0.5.831588e" (5 commits after v0.2.0)
if let Ok(output) = Command::new("git")
.args(["describe", "--tags", "--always", "--dirty=-modified"])
.output()
{
if output.status.success() {
let desc = String::from_utf8_lossy(&output.stdout).trim().to_string();
// Parse git describe output
if let Some(version) = parse_git_describe(&desc) {
return version;
}
}
}
// Fallback: Try short commit hash only
if let Ok(output) = Command::new("git")
.args(["rev-parse", "--short", "HEAD"])
.output()
{
if output.status.success() {
let commit = String::from_utf8_lossy(&output.stdout).trim().to_string();
return format!("{}.{}", env!("CARGO_PKG_VERSION"), commit);
}
}
// Final fallback to Cargo.toml version
env!("CARGO_PKG_VERSION").to_string()
}
fn parse_git_describe(desc: &str) -> Option<String> {
// Strip 'v' prefix if present
let desc = desc.strip_prefix('v').unwrap_or(desc);
// Check for dirty flag
let dirty = desc.ends_with("-modified");
let desc = desc.strip_suffix("-modified").unwrap_or(desc);
if let Some((base, rest)) = desc.split_once('-') {
// Format: tag-N-ghash (e.g., "0.2.0-5-g831588e")
let parts: Vec<&str> = rest.split('-').collect();
if parts.len() == 2 {
let commit_count = parts[0];
let hash = parts[1].strip_prefix('g').unwrap_or(parts[1]);
let version = format!("{}.{}.{}", base, commit_count, hash);
return Some(if dirty {
format!("{}-modified", version)
} else {
version
});
}
}
// No commits after tag, just use the tag
Some(if dirty {
format!("{}-modified", desc)
} else {
desc.to_string()
})
}