diff --git a/crates/notary/server/Cargo.toml b/crates/notary/server/Cargo.toml index cdb1e3999..bbee39e87 100644 --- a/crates/notary/server/Cargo.toml +++ b/crates/notary/server/Cargo.toml @@ -45,3 +45,7 @@ tracing-subscriber = { workspace = true, features = ["env-filter"] } uuid = { workspace = true, features = ["v4", "fast-rng"] } ws_stream_tungstenite = { workspace = true, features = ["tokio_io"] } zeroize = { workspace = true } + +[build-dependencies] +git2 = "0.19.0" +chrono.workspace = true diff --git a/crates/notary/server/build.rs b/crates/notary/server/build.rs index 15833ad97..6f97204af 100644 --- a/crates/notary/server/build.rs +++ b/crates/notary/server/build.rs @@ -1,25 +1,55 @@ -use std::{env, process::Command}; +use chrono::DateTime; +use git2::{Commit, Repository, StatusOptions}; +use std::{env, error::Error}; -fn main() { - if env::var("GIT_COMMIT_HASH").is_err() || env::var("GIT_COMMIT_TIMESTAMP").is_err() { - // Used to extract latest HEAD commit hash and timestamp for the /info endpoint - let output = Command::new("git") - .args(["show", "HEAD", "-s", "--format=%H,%cI"]) - .output() - .expect( - "Git command to get commit hash and timestamp should work during build process", - ); +fn main() -> Result<(), Box> { + if env::var("GIT_COMMIT_HASH").is_err() { + match get_commithash_with_dirty_suffix() { + Ok(commit_hash_with_suffix) => { + // Pass value as env var to the notary server + println!("cargo:rustc-env=GIT_COMMIT_HASH={commit_hash_with_suffix}"); + } + Err(e) => { + eprintln!("Failed to get commit hash in notary server build"); + eprintln!("Fix the error or configure GIT_COMMIT_HASH as environment variable"); + return Err(e.message().into()); + } + }; + } + Ok(()) +} - let output_string = String::from_utf8(output.stdout) - .expect("Git command should produce valid string output"); +fn get_commithash_with_dirty_suffix() -> Result { + let repo = Repository::discover(".")?; + let commit = get_commit(&repo)?; + let commit_hash = commit.id().to_string(); + let _timestamp = get_commit_timestamp(&commit)?; + let has_changes = check_local_changes(&repo)?; - let (commit_hash, commit_timestamp) = output_string - .as_str() - .split_once(',') - .expect("Git commit hash and timestamp string output should be comma separated"); - - // Pass these 2 values as env var to the program - println!("cargo:rustc-env=GIT_COMMIT_HASH={}", commit_hash); - println!("cargo:rustc-env=GIT_COMMIT_TIMESTAMP={}", commit_timestamp); + if has_changes { + Ok(format!("{commit_hash} (with local changes)")) + } else { + Ok(commit_hash) } } + +fn get_commit(repo: &Repository) -> Result { + let head = repo.head()?; + head.peel_to_commit() +} + +fn get_commit_timestamp(commit: &Commit) -> Result { + let timestamp = commit.time().seconds(); + let date_time = DateTime::from_timestamp(timestamp, 0) + .ok_or_else(|| git2::Error::from_str("Invalid timestamp"))?; + Ok(date_time.to_rfc2822()) +} + +fn check_local_changes(repo: &Repository) -> Result { + let mut status_options = StatusOptions::new(); + status_options + .include_untracked(false) + .include_ignored(false); + let statuses = repo.statuses(Some(&mut status_options))?; + Ok(!statuses.is_empty()) +} diff --git a/crates/notary/server/config/config.yaml b/crates/notary/server/config/config.yaml index ac680e602..0ca36a02d 100644 --- a/crates/notary/server/config/config.yaml +++ b/crates/notary/server/config/config.yaml @@ -6,7 +6,6 @@ server:

Notary Server {version}!

  • git commit hash: {git_commit_hash}
  • -
  • git commit timestamp: {git_commit_timestamp}
  • public key:
    {public_key}
health check - info
diff --git a/crates/notary/server/notary-server.Dockerfile.dockerignore b/crates/notary/server/notary-server.Dockerfile.dockerignore index b9fe8dce6..07fcd1526 100644 --- a/crates/notary/server/notary-server.Dockerfile.dockerignore +++ b/crates/notary/server/notary-server.Dockerfile.dockerignore @@ -1,12 +1,4 @@ -# exclude everything -* - -# include notary and core library dependencies -!/crates -!/Cargo.toml - -# include .git for program to get git info -!/.git - -# exclude any /target folders inside the included folders above -**/target* +# exclude Rust build artifacts +./target +./crates/wasm/pkg/ +./crates/wasm-test-runner/static/generated/ diff --git a/crates/notary/server/openapi.yaml b/crates/notary/server/openapi.yaml index 7044fbc61..680c5ecc5 100644 --- a/crates/notary/server/openapi.yaml +++ b/crates/notary/server/openapi.yaml @@ -203,11 +203,7 @@ components: gitCommitHash: description: The git commit hash of source code that this notary server is running type: string - gitCommitTimestamp: - description: The git commit timestamp of source code that this notary server is running - type: string required: - "version" - "publicKey" - "gitCommitHash" - - "gitCommitTimestamp" diff --git a/crates/notary/server/src/domain.rs b/crates/notary/server/src/domain.rs index 5485be620..407eb1a13 100644 --- a/crates/notary/server/src/domain.rs +++ b/crates/notary/server/src/domain.rs @@ -14,6 +14,4 @@ pub struct InfoResponse { pub public_key: String, /// Current git commit hash of notary-server pub git_commit_hash: String, - /// Current git commit timestamp of notary-server - pub git_commit_timestamp: String, } diff --git a/crates/notary/server/src/server.rs b/crates/notary/server/src/server.rs index 7006073fc..9b01900ad 100644 --- a/crates/notary/server/src/server.rs +++ b/crates/notary/server/src/server.rs @@ -111,7 +111,6 @@ pub async fn run_server(config: &NotaryServerProperties) -> Result<(), NotarySer .map_err(|err| eyre!("Failed to load notary public signing key for notarization: {err}"))?; let version = env!("CARGO_PKG_VERSION").to_string(); let git_commit_hash = env!("GIT_COMMIT_HASH").to_string(); - let git_commit_timestamp = env!("GIT_COMMIT_TIMESTAMP").to_string(); // Parameters needed for the root / endpoint let html_string = config.server.html_info.clone(); @@ -119,7 +118,6 @@ pub async fn run_server(config: &NotaryServerProperties) -> Result<(), NotarySer html_string .replace("{version}", &version) .replace("{git_commit_hash}", &git_commit_hash) - .replace("{git_commit_timestamp}", &git_commit_timestamp) .replace("{public_key}", &public_key), ); @@ -141,7 +139,6 @@ pub async fn run_server(config: &NotaryServerProperties) -> Result<(), NotarySer version, public_key, git_commit_hash, - git_commit_timestamp, }), ) .into_response()