-
Notifications
You must be signed in to change notification settings - Fork 62
feat: Add version information to CLI tools #1551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add version information to CLI tools #1551
Conversation
edbcfb5
to
4b17bce
Compare
4b17bce
to
c24db43
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1551 +/- ##
============================
============================
☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Adding a @frobware are you sure this is working as expected? If I check out your PR and do $ ./target/debug/bpfman -V
bpfman 0.5.6 (c24db43080 https://github.com/bpfman/bpfman 2025-05-20T15:45:23Z) rustc 1.85.1 (4eb161250 2025-03-15) If I then make the tree dirty - by adding a $ ./target/debug/bpfman -V
bpfman 0.5.6 (c24db43080 https://github.com/bpfman/bpfman 2025-05-20T15:45:23Z) rustc 1.85.1 (4eb161250 2025-03-15) The I commit my change, rebuild, and get the following output: $ ./target/debug/bpfman -V
bpfman 0.5.6 (c24db43080 https://github.com/bpfman/bpfman 2025-05-20T15:45:23Z) rustc 1.85.1 (4eb161250 2025-03-15) I believe this is because of the following: pub fn generate_version_info() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=Cargo.toml");
println!("cargo:rerun-if-env-changed=BPFMAN_BUILD_TIMESTAMP");
println!("cargo:rustc-env=BPFMAN_BUILD_INFO={}", build_info_string());
} That's only ever going to re-compute the version information if build.rs is changed, or |
In CI, I believe this would be acceptable. In development, I did implement reruns for .git and HEAD branch changes, but this caused Cargo to relink even when there were no changes. A change followed by |
This change introduces version information to all bpfman's CLI binaries, enabling the --version flag on all top-level commands. The version details provide valuable build context for debugging and support. The implementation: - Creates a new shared 'buildinfo' crate to centralise version generation logic - Produces detailed version information including: * Package version from Cargo.toml * Git commit hash with dirty state indicator * Build timestamp * Rust compiler version - Exposes a minimal public API through a single generate_version_info() function - Enables --version/-V flags for all CLI tools (bpfman, bpfman-rpc, bpfman-ns, bpf-metrics-exporter) - Uses namespaced BPFMAN_BUILD_INFO environment variable for version info - Preserves the existing behaviour in subcommands (no version flags at subcommand level) - Handles tarball builds gracefully by omitting git information when unavailable If the BPFMAN_BUILD_TIMESTAMP environment variable is set and not empty, its value is used as the build timestamp in the computed version string. This can be useful in CI environments, where setting a fixed timestamp ensures that all produced binaries from a given build pipeline share the same version timestamp for traceability and reproducibility. The version string also includes the Git repository origin (as configured for the 'origin' remote), enabling clear distinction between upstream, downstream, and forked builds. This is especially useful for debugging and support scenarios where identical commit hashes might exist across different remotes. The repository URL is automatically detected at build time from the output of `git config --get remote.origin.url`, and is omitted if unavailable (e.g., in a tarball or detached source build). Example output: % cargo run -p bpfman -- --version Compiling buildinfo v0.5.6 (/home/aim/src/github.com/bpfman/bpfman/buildinfo) Compiling bpfman v0.5.6 (/home/aim/src/github.com/bpfman/bpfman/bpfman) Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.39s Running `target/debug/bpfman --version` bpfman 0.5.6 (65a2c97270-dirty https://github.com/frobware/bpfman 2025-05-16T14:48:03Z) rustc 1.88.0-nightly (b45dd71d1 2025-04-30) Signed-off-by: Andrew McDermott <amcdermo@redhat.com>
I added src to the trigger: pub fn generate_version_info() {
println!("cargo:rerun-if-changed=src");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=Cargo.toml");
println!("cargo:rerun-if-env-changed=BPFMAN_BUILD_TIMESTAMP");
println!("cargo:rustc-env=BPFMAN_BUILD_INFO={}", build_info_string());
} Plus some testing: #!/usr/bin/env bash
print_build_info() {
for bin in bpfman bpfman-ns bpfman-rpc; do
./target/debug/"$bin" -V
done
}
modify_src() {
local bin="$1"
local file="$bin/src/lib.rs"
if [[ -f "$file" ]]; then
echo "// dummy change to trigger rebuild" >> "$file"
echo "Touched: $file"
else
echo "File not found: $file"
fi
} Initial build
Note slight variations in the build timestamps. To be expected. Re-run:
Touch one of the triggers, in this case
|
c24db43
to
fa17c15
Compare
The edge case where you make a change, build, then commit, then build again could be addressed by adding: println!("cargo:rerun-if-changed=.git/HEAD"); and that does work:
However, running
which is admittedly a bit weird if the trigger is based on timestamps:
|
@frobware thanks! looks like this is working as expected now. LGTM |
Fixes #1398.
This PR introduces standardised version information to all of bpfman’s CLI binaries (except bpf-log-exporter, which has no prior argument parsing), making the --version and -V flags available for all top-level commands.
All CLI tools now embed standardised version metadata using a shared buildinfo crate and a single API (generate_version_info()) called from each binary’s build script. The version string includes the package version (from Cargo.toml), the Git commit hash (with a dirty-state indicator if the working tree is not clean), the build timestamp (overridable via environment variable for CI), the Rust compiler version, and the Git repository origin URL (from the origin remote).
The version strings provide valuable context for debugging, support, and reproducibility.
Examples
Changing the Rust toolchain is reflected in the version string:
Set a custom build timestamp (e.g., in CI):
Summary
cargo clean
before building).