diff --git a/Cargo.lock b/Cargo.lock index eca3b2fbc..700bb2653 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -356,9 +356,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" dependencies = [ "backtrace", ] @@ -628,6 +628,15 @@ dependencies = [ "serde", ] +[[package]] +name = "build-info" +version = "1.7.0" +dependencies = [ + "anyhow", + "time", + "vergen-git2", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -1348,7 +1357,16 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" dependencies = [ - "derive_builder_macro", + "derive_builder_macro 0.12.0", +] + +[[package]] +name = "derive_builder" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f59169f400d8087f238c5c0c7db6a28af18681717f3b623227d92f397e938c7" +dependencies = [ + "derive_builder_macro 0.13.1", ] [[package]] @@ -1363,13 +1381,35 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_builder_core" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4ec317cc3e7ef0928b0ca6e4a634a4d6c001672ae210438cf114a83e56b018d" +dependencies = [ + "darling 0.14.4", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_builder_macro" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" dependencies = [ - "derive_builder_core", + "derive_builder_core 0.12.0", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870368c3fb35b8031abb378861d4460f573b92238ec2152c927a21f77e3e0127" +dependencies = [ + "derive_builder_core 0.13.1", "syn 1.0.109", ] @@ -2088,11 +2128,11 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "git2" -version = "0.16.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf7f68c2995f392c49fffb4f95ae2c873297830eb25c6bc4c114ce8f4562acc" +checksum = "1b3ba52851e73b46a4c3df1d89343741112003f0f6f13beb0dfac9e457c3fdcd" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.1", "libc", "libgit2-sys", "log", @@ -2389,7 +2429,7 @@ dependencies = [ "bincode", "crossbeam", "csv", - "derive_builder", + "derive_builder 0.12.0", "dump", "enum-iterator", "file-store", @@ -2506,7 +2546,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ "hermit-abi", - "rustix 0.38.26", + "rustix 0.38.31", "windows-sys 0.52.0", ] @@ -2628,15 +2668,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libgit2-sys" -version = "0.14.2+1.5.1" +version = "0.16.2+1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f3d95f6b51075fe9810a7ae22c7095f12b98005ab364d8544797a825ce946a4" +checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" dependencies = [ "cc", "libc", @@ -2683,9 +2723,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" dependencies = [ "cc", "libc", @@ -3122,6 +3162,7 @@ dependencies = [ "async-trait", "brotli", "bstr", + "build-info", "byte-unit", "bytes", "cargo_toml", @@ -3193,7 +3234,6 @@ dependencies = [ "url", "urlencoding", "uuid", - "vergen", "walkdir", "yaup", "zip", @@ -3530,6 +3570,15 @@ dependencies = [ "libc", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "number_prefix" version = "0.4.0" @@ -4144,15 +4193,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_users" version = "0.4.3" @@ -4343,9 +4383,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.26" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ "bitflags 2.4.1", "errno", @@ -4881,14 +4921,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.4.1", - "rustix 0.38.26", + "rustix 0.38.31", "windows-sys 0.52.0", ] @@ -4948,13 +4987,15 @@ dependencies = [ [[package]] name = "time" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe80ced77cbfb4cb91a94bf72b378b4b6791a0d9b7f09d0be747d1bdff4e68bd" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", + "libc", "num-conv", + "num_threads", "powerfmt", "serde", "time-core", @@ -5008,7 +5049,7 @@ version = "0.14.1" source = "git+https://github.com/huggingface/tokenizers.git?tag=v0.14.1#6357206cdcce4d78ffb1e0372feb456caea09375" dependencies = [ "aho-corasick", - "derive_builder", + "derive_builder 0.12.0", "esaxx-rs", "getrandom", "itertools 0.11.0", @@ -5434,18 +5475,42 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vergen" -version = "7.5.1" +version = "9.0.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21b881cd6636ece9735721cf03c1fe1e774fe258683d084bb2812ab67435749" +checksum = "107dc53b443fe8cc380798abb75ad6b7038281165109afea1f1b28bb47047ed5" dependencies = [ "anyhow", - "cfg-if", - "enum-iterator", + "derive_builder 0.13.1", "getset", + "rustversion", + "vergen-lib", +] + +[[package]] +name = "vergen-git2" +version = "1.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8875c5d71074bb67118774e3d795ab6fe77c3ae3161cb54e19104cabc49487f1" +dependencies = [ + "anyhow", + "derive_builder 0.13.1", "git2", "rustversion", - "thiserror", "time", + "vergen", + "vergen-lib", +] + +[[package]] +name = "vergen-lib" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26ebfba72ba904559f25f41ea1512335b5a46459084258cea0857549d9645187" +dependencies = [ + "anyhow", + "derive_builder 0.13.1", + "getset", + "rustversion", ] [[package]] @@ -5873,9 +5938,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.4" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acaaa1190073b2b101e15083c38ee8ec891b5e05cbee516521e94ec008f61e64" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] @@ -5904,11 +5969,11 @@ name = "xtask" version = "1.7.0" dependencies = [ "anyhow", + "build-info", "cargo_metadata", "clap", "futures-core", "futures-util", - "git2", "reqwest", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 11190025a..1d79fd196 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ members = [ "benchmarks", "fuzzers", "tracing-trace", - "xtask", + "xtask", "build-info", ] [workspace.package] diff --git a/Dockerfile b/Dockerfile index dd2cfc134..5b227e6fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ WORKDIR / ARG COMMIT_SHA ARG COMMIT_DATE ARG GIT_TAG -ENV VERGEN_GIT_SHA=${COMMIT_SHA} VERGEN_GIT_COMMIT_TIMESTAMP=${COMMIT_DATE} VERGEN_GIT_SEMVER_LIGHTWEIGHT=${GIT_TAG} +ENV VERGEN_GIT_SHA=${COMMIT_SHA} VERGEN_GIT_COMMIT_TIMESTAMP=${COMMIT_DATE} VERGEN_GIT_DESCRIBE=${GIT_TAG} ENV RUSTFLAGS="-C target-feature=-crt-static" COPY . . diff --git a/build-info/Cargo.toml b/build-info/Cargo.toml new file mode 100644 index 000000000..50854a642 --- /dev/null +++ b/build-info/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "build-info" +version.workspace = true +authors.workspace = true +description.workspace = true +homepage.workspace = true +readme.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +time = { version = "0.3.34", features = ["parsing"] } + +[build-dependencies] +anyhow = "1.0.80" +vergen-git2 = "1.0.0-beta.2" diff --git a/build-info/build.rs b/build-info/build.rs new file mode 100644 index 000000000..b1ec0ab47 --- /dev/null +++ b/build-info/build.rs @@ -0,0 +1,22 @@ +fn main() { + if let Err(err) = emit_git_variables() { + println!("cargo:warning=vergen: {}", err); + } +} + +fn emit_git_variables() -> anyhow::Result<()> { + // Note: any code that needs VERGEN_ environment variables should take care to define them manually in the Dockerfile and pass them + // in the corresponding GitHub workflow (publish_docker.yml). + // This is due to the Dockerfile building the binary outside of the git directory. + let mut builder = vergen_git2::Git2Builder::default(); + + builder.branch(true); + builder.commit_timestamp(true); + builder.commit_message(true); + builder.describe(true, true, None); + builder.sha(false); + + let git2 = builder.build()?; + + vergen_git2::Emitter::default().fail_on_error().add_instructions(&git2)?.emit() +} diff --git a/build-info/src/lib.rs b/build-info/src/lib.rs new file mode 100644 index 000000000..cfcefb4a2 --- /dev/null +++ b/build-info/src/lib.rs @@ -0,0 +1,203 @@ +use time::format_description::well_known::Iso8601; + +#[derive(Debug, Clone)] +pub struct BuildInfo { + pub branch: Option<&'static str>, + pub describe: Option, + pub commit_sha1: Option<&'static str>, + pub commit_msg: Option<&'static str>, + pub commit_timestamp: Option, +} + +impl BuildInfo { + pub fn from_build() -> Self { + let branch: Option<&'static str> = option_env!("VERGEN_GIT_BRANCH"); + let describe = DescribeResult::from_build(); + let commit_sha1 = option_env!("VERGEN_GIT_SHA"); + let commit_msg = option_env!("VERGEN_GIT_COMMIT_MESSAGE"); + let commit_timestamp = option_env!("VERGEN_GIT_COMMIT_TIMESTAMP"); + + let commit_timestamp = commit_timestamp.and_then(|commit_timestamp| { + time::OffsetDateTime::parse(commit_timestamp, &Iso8601::DEFAULT).ok() + }); + + Self { branch, describe, commit_sha1, commit_msg, commit_timestamp } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum DescribeResult { + Prototype { name: &'static str }, + Release { version: &'static str, major: u64, minor: u64, patch: u64 }, + Prerelease { version: &'static str, major: u64, minor: u64, patch: u64, rc: u64 }, + NotATag { describe: &'static str }, +} + +impl DescribeResult { + pub fn new(describe: &'static str) -> Self { + if let Some(name) = prototype_name(describe) { + Self::Prototype { name } + } else if let Some(release) = release_version(describe) { + release + } else if let Some(prerelease) = prerelease_version(describe) { + prerelease + } else { + Self::NotATag { describe } + } + } + + pub fn from_build() -> Option { + let describe: &'static str = option_env!("VERGEN_GIT_DESCRIBE")?; + Some(Self::new(describe)) + } + + pub fn as_tag(&self) -> Option<&'static str> { + match self { + DescribeResult::Prototype { name } => Some(name), + DescribeResult::Release { version, .. } => Some(version), + DescribeResult::Prerelease { version, .. } => Some(version), + DescribeResult::NotATag { describe: _ } => None, + } + } + + pub fn as_prototype(&self) -> Option<&'static str> { + match self { + DescribeResult::Prototype { name } => Some(name), + DescribeResult::Release { .. } + | DescribeResult::Prerelease { .. } + | DescribeResult::NotATag { .. } => None, + } + } +} + +/// Parses the input as a prototype name. +/// +/// Returns `Some(prototype_name)` if the following conditions are met on this value: +/// +/// 1. starts with `prototype-`, +/// 2. ends with `-`, +/// 3. does not end with `-`. +/// +/// Otherwise, returns `None`. +fn prototype_name(describe: &'static str) -> Option<&'static str> { + if !describe.starts_with("prototype-") { + return None; + } + + let mut rsplit_prototype = describe.rsplit('-'); + // last component MUST be a number + rsplit_prototype.next()?.parse::().ok()?; + // before than last component SHALL NOT be a number + rsplit_prototype.next()?.parse::().err()?; + + Some(describe) +} + +fn release_version(describe: &'static str) -> Option { + if !describe.starts_with('v') { + return None; + } + + // full release version don't contain a `-` + if describe.contains('-') { + return None; + } + + // full release version parse as vX.Y.Z, with X, Y, Z numbers. + let mut dots = describe[1..].split('.'); + let major: u64 = dots.next()?.parse().ok()?; + let minor: u64 = dots.next()?.parse().ok()?; + let patch: u64 = dots.next()?.parse().ok()?; + + if dots.next().is_some() { + return None; + } + + Some(DescribeResult::Release { version: describe, major, minor, patch }) +} + +fn prerelease_version(describe: &'static str) -> Option { + // prerelease version is in the shape vM.N.P-rc.C + let mut hyphen = describe.rsplit('-'); + let prerelease = hyphen.next()?; + if !prerelease.starts_with("rc.") { + return None; + } + + let rc: u64 = prerelease[3..].parse().ok()?; + + let release = hyphen.next()?; + + let DescribeResult::Release { version: _, major, minor, patch } = release_version(release)? + else { + return None; + }; + + Some(DescribeResult::Prerelease { version: describe, major, minor, patch, rc }) +} + +#[cfg(test)] +mod test { + use super::DescribeResult; + + fn assert_not_a_tag(describe: &'static str) { + assert_eq!(DescribeResult::NotATag { describe }, DescribeResult::new(describe)) + } + + fn assert_proto(describe: &'static str) { + assert_eq!(DescribeResult::Prototype { name: describe }, DescribeResult::new(describe)) + } + + fn assert_release(describe: &'static str, major: u64, minor: u64, patch: u64) { + assert_eq!( + DescribeResult::Release { version: describe, major, minor, patch }, + DescribeResult::new(describe) + ) + } + + fn assert_prerelease(describe: &'static str, major: u64, minor: u64, patch: u64, rc: u64) { + assert_eq!( + DescribeResult::Prerelease { version: describe, major, minor, patch, rc }, + DescribeResult::new(describe) + ) + } + + #[test] + fn not_a_tag() { + assert_not_a_tag("whatever-fuzzy"); + assert_not_a_tag("whatever-fuzzy-5-ggg-dirty"); + assert_not_a_tag("whatever-fuzzy-120-ggg-dirty"); + + // technically a tag, but not a proto nor a version, so not parsed as a tag + assert_not_a_tag("whatever"); + + // dirty version + assert_not_a_tag("v1.7.0-1-ggga-dirty"); + assert_not_a_tag("v1.7.0-rc.1-1-ggga-dirty"); + + // after version + assert_not_a_tag("v1.7.0-1-ggga"); + assert_not_a_tag("v1.7.0-rc.1-1-ggga"); + + // after proto + assert_not_a_tag("protoype-tag-0-1-ggga"); + assert_not_a_tag("protoype-tag-0-1-ggga-dirty"); + } + + #[test] + fn prototype() { + assert_proto("prototype-tag-0"); + assert_proto("prototype-tag-10"); + assert_proto("prototype-long-name-tag-10"); + } + + #[test] + fn release() { + assert_release("v1.7.2", 1, 7, 2); + } + + #[test] + fn prerelease() { + assert_prerelease("v1.7.2-rc.3", 1, 7, 2, 3); + } +} diff --git a/meilisearch/Cargo.toml b/meilisearch/Cargo.toml index fc4f5aa8b..b65c466ca 100644 --- a/meilisearch/Cargo.toml +++ b/meilisearch/Cargo.toml @@ -107,6 +107,7 @@ tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["json"] } tracing-trace = { version = "0.1.0", path = "../tracing-trace" } tracing-actix-web = "0.7.9" +build-info = { version = "1.7.0", path = "../build-info" } [dev-dependencies] actix-rt = "2.9.0" @@ -131,7 +132,6 @@ reqwest = { version = "0.11.23", features = [ sha-1 = { version = "0.10.1", optional = true } static-files = { version = "0.2.3", optional = true } tempfile = { version = "3.9.0", optional = true } -vergen = { version = "7.5.1", default-features = false, features = ["git"] } zip = { version = "0.6.6", optional = true } [features] diff --git a/meilisearch/build.rs b/meilisearch/build.rs index c839b6e33..dc24b0449 100644 --- a/meilisearch/build.rs +++ b/meilisearch/build.rs @@ -1,17 +1,4 @@ -use vergen::{vergen, Config, SemverKind}; - fn main() { - // Note: any code that needs VERGEN_ environment variables should take care to define them manually in the Dockerfile and pass them - // in the corresponding GitHub workflow (publish_docker.yml). - // This is due to the Dockerfile building the binary outside of the git directory. - let mut config = Config::default(); - // allow using non-annotated tags - *config.git_mut().semver_kind_mut() = SemverKind::Lightweight; - - if let Err(e) = vergen(config) { - println!("cargo:warning=vergen: {}", e); - } - #[cfg(feature = "mini-dashboard")] mini_dashboard::setup_mini_dashboard().expect("Could not load the mini-dashboard assets"); } diff --git a/meilisearch/src/analytics/segment_analytics.rs b/meilisearch/src/analytics/segment_analytics.rs index 55ddb4747..7dfc52900 100644 --- a/meilisearch/src/analytics/segment_analytics.rs +++ b/meilisearch/src/analytics/segment_analytics.rs @@ -473,7 +473,9 @@ impl Segment { create_all_stats(index_scheduler.into(), auth_controller.into(), &AuthFilter::default()) { // Replace the version number with the prototype name if any. - let version = if let Some(prototype) = crate::prototype_name() { + let version = if let Some(prototype) = build_info::DescribeResult::from_build() + .and_then(|describe| describe.as_prototype()) + { prototype } else { env!("CARGO_PKG_VERSION") diff --git a/meilisearch/src/lib.rs b/meilisearch/src/lib.rs index 9d9274b9d..820f1ae42 100644 --- a/meilisearch/src/lib.rs +++ b/meilisearch/src/lib.rs @@ -536,30 +536,3 @@ pub fn dashboard(config: &mut web::ServiceConfig, enable_frontend: bool) { pub fn dashboard(config: &mut web::ServiceConfig, _enable_frontend: bool) { config.service(web::resource("/").route(web::get().to(routes::running))); } - -/// Parses the output of -/// [`VERGEN_GIT_SEMVER_LIGHTWEIGHT`](https://docs.rs/vergen/latest/vergen/struct.Git.html#instructions) -/// as a prototype name. -/// -/// Returns `Some(prototype_name)` if the following conditions are met on this value: -/// -/// 1. starts with `prototype-`, -/// 2. ends with `-`, -/// 3. does not end with `-`. -/// -/// Otherwise, returns `None`. -pub fn prototype_name() -> Option<&'static str> { - let prototype: &'static str = option_env!("VERGEN_GIT_SEMVER_LIGHTWEIGHT")?; - - if !prototype.starts_with("prototype-") { - return None; - } - - let mut rsplit_prototype = prototype.rsplit('-'); - // last component MUST be a number - rsplit_prototype.next()?.parse::().ok()?; - // before than last component SHALL NOT be a number - rsplit_prototype.next()?.parse::().err()?; - - Some(prototype) -} diff --git a/meilisearch/src/main.rs b/meilisearch/src/main.rs index f1f93dd99..79ca7ec80 100644 --- a/meilisearch/src/main.rs +++ b/meilisearch/src/main.rs @@ -12,8 +12,8 @@ use is_terminal::IsTerminal; use meilisearch::analytics::Analytics; use meilisearch::option::LogMode; use meilisearch::{ - analytics, create_app, prototype_name, setup_meilisearch, LogRouteHandle, LogRouteType, - LogStderrHandle, LogStderrType, Opt, SubscriberForSecondLayer, + analytics, create_app, setup_meilisearch, LogRouteHandle, LogRouteType, LogStderrHandle, + LogStderrType, Opt, SubscriberForSecondLayer, }; use meilisearch_auth::{generate_master_key, AuthController, MASTER_KEY_MIN_SIZE}; use mimalloc::MiMalloc; @@ -163,8 +163,8 @@ pub fn print_launch_resume( analytics: Arc, config_read_from: Option, ) { - let commit_sha = option_env!("VERGEN_GIT_SHA").unwrap_or("unknown"); - let commit_date = option_env!("VERGEN_GIT_COMMIT_TIMESTAMP").unwrap_or("unknown"); + let build_info = build_info::BuildInfo::from_build(); + let protocol = if opt.ssl_cert_path.is_some() && opt.ssl_key_path.is_some() { "https" } else { "http" }; let ascii_name = r#" @@ -189,10 +189,18 @@ pub fn print_launch_resume( eprintln!("Database path:\t\t{:?}", opt.db_path); eprintln!("Server listening on:\t\"{}://{}\"", protocol, opt.http_addr); eprintln!("Environment:\t\t{:?}", opt.env); - eprintln!("Commit SHA:\t\t{:?}", commit_sha.to_string()); - eprintln!("Commit date:\t\t{:?}", commit_date.to_string()); + eprintln!("Commit SHA:\t\t{:?}", build_info.commit_sha1.unwrap_or("unknown")); + eprintln!( + "Commit date:\t\t{:?}", + build_info + .commit_timestamp + .and_then(|commit_timestamp| commit_timestamp + .format(&time::format_description::well_known::Iso8601::DEFAULT) + .ok()) + .unwrap_or("unknown".into()) + ); eprintln!("Package version:\t{:?}", env!("CARGO_PKG_VERSION").to_string()); - if let Some(prototype) = prototype_name() { + if let Some(prototype) = build_info.describe.and_then(|describe| describe.as_prototype()) { eprintln!("Prototype:\t\t{:?}", prototype); } diff --git a/meilisearch/src/routes/mod.rs b/meilisearch/src/routes/mod.rs index 249103e12..1c1465582 100644 --- a/meilisearch/src/routes/mod.rs +++ b/meilisearch/src/routes/mod.rs @@ -359,12 +359,18 @@ async fn get_version( ) -> HttpResponse { analytics.publish("Version Seen".to_string(), json!(null), Some(&req)); - let commit_sha = option_env!("VERGEN_GIT_SHA").unwrap_or("unknown"); - let commit_date = option_env!("VERGEN_GIT_COMMIT_TIMESTAMP").unwrap_or("unknown"); + let build_info = build_info::BuildInfo::from_build(); HttpResponse::Ok().json(VersionResponse { - commit_sha: commit_sha.to_string(), - commit_date: commit_date.to_string(), + commit_sha: build_info.commit_sha1.unwrap_or("unknown").to_string(), + commit_date: build_info + .commit_timestamp + .and_then(|commit_timestamp| { + commit_timestamp + .format(&time::format_description::well_known::Iso8601::DEFAULT) + .ok() + }) + .unwrap_or("unknown".into()), pkg_version: env!("CARGO_PKG_VERSION").to_string(), }) } diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index a59a79e53..0df8161ce 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -12,11 +12,11 @@ license.workspace = true [dependencies] anyhow = "1.0.79" +build-info = { version = "1.7.0", path = "../build-info" } cargo_metadata = "0.18.1" clap = { version = "4.4.14", features = ["derive"] } futures-core = "0.3.30" futures-util = "0.3.30" -git2 = { version = "0.16", default_features = false } reqwest = { version = "0.11.23", features = [ "stream", "json", @@ -26,7 +26,11 @@ serde = { version = "1.0.195", features = ["derive"] } serde_json = "1.0.111" sha2 = "0.10.8" sysinfo = "0.30.5" -time = { version = "0.3.32", features = ["serde", "serde-human-readable"] } +time = { version = "0.3.32", features = [ + "serde", + "serde-human-readable", + "macros", +] } tokio = { version = "1.35.1", features = [ "rt", "net", @@ -38,3 +42,6 @@ tracing = "0.1.40" tracing-subscriber = "0.3.18" tracing-trace = { version = "0.1.0", path = "../tracing-trace" } uuid = { version = "1.7.0", features = ["v7", "serde"] } + +[build-dependencies] +anyhow = "1.0.79" diff --git a/xtask/src/bench/env_info.rs b/xtask/src/bench/env_info.rs index 5cbeb4274..08dacf915 100644 --- a/xtask/src/bench/env_info.rs +++ b/xtask/src/bench/env_info.rs @@ -1,58 +1,4 @@ use serde::{Deserialize, Serialize}; -use time::OffsetDateTime; - -#[derive(Debug, Clone, Deserialize, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct Source { - pub repo_url: Option, - pub branch_or_tag: String, - pub commit_id: String, - pub commit_msg: String, - pub author_name: String, - pub author_email: String, - pub committer_name: String, - pub committer_email: String, -} - -impl Source { - pub fn from_repo( - path: impl AsRef, - ) -> Result<(Self, OffsetDateTime), git2::Error> { - use git2::Repository; - - let repo = Repository::open(path)?; - let remote = repo.remotes()?; - let remote = remote.get(0).expect("No remote associated to the repo"); - let remote = repo.find_remote(remote)?; - - let head = repo.head()?; - - let commit = head.peel_to_commit()?; - - let time = OffsetDateTime::from_unix_timestamp(commit.time().seconds()).unwrap(); - - let author = commit.author(); - let committer = commit.committer(); - - Ok(( - Self { - repo_url: remote.url().map(|s| s.to_string()), - branch_or_tag: head.name().unwrap().to_string(), - commit_id: commit.id().to_string(), - commit_msg: String::from_utf8_lossy(commit.message_bytes()) - .to_string() - .lines() - .next() - .map_or(String::new(), |s| s.to_string()), - author_name: author.name().unwrap().to_string(), - author_email: author.email().unwrap().to_string(), - committer_name: committer.name().unwrap().to_string(), - committer_email: committer.email().unwrap().to_string(), - }, - time, - )) - } -} #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/xtask/src/bench/mod.rs b/xtask/src/bench/mod.rs index ea17b6f69..cfc7c124f 100644 --- a/xtask/src/bench/mod.rs +++ b/xtask/src/bench/mod.rs @@ -292,8 +292,7 @@ pub fn run(args: BenchDeriveArgs) -> anyhow::Result<()> { args.log_filter.parse().context("invalid --log-filter")?; let env = env_info::Environment::generate_from_current_config(); - let (source, commit_date) = - env_info::Source::from_repo(".").context("could not get repository information")?; + let build_info = build_info::BuildInfo::from_build(); let subscriber = tracing_subscriber::registry().with( tracing_subscriber::fmt::layer() @@ -344,17 +343,18 @@ pub fn run(args: BenchDeriveArgs) -> anyhow::Result<()> { ); } - let commit_message = source.commit_msg.split('\n').next().unwrap(); + let commit_message = build_info.commit_msg.context("missing commit message")?.split('\n').next().unwrap(); let max_workloads = args.workload_file.len(); let reason: Option<&str> = args.reason.as_deref(); let response = dashboard_client .put("invocation") .json(&json!({ "commit": { - "sha1": source.commit_id, + "sha1": build_info.commit_sha1, "message": commit_message, - "commit_date": commit_date, - "branch": source.branch_or_tag + "commit_date": build_info.commit_timestamp, + "branch": build_info.branch, + "tag": build_info.describe.and_then(|describe| describe.as_tag()), }, "machine_hostname": env.hostname, "max_workloads": max_workloads,