From 6948e0cc90d0244bcc594cb882e4fecb9b018511 Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Tue, 4 Mar 2025 21:02:31 +0500 Subject: [PATCH 01/12] Set up GHA build --- .github/workflows/build.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..55402bf --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,17 @@ +name: Build + +on: push + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Build + run: cargo build --verbose From 9357fc851d5d76d820ddb3fc518f0b8eeb442ff2 Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Thu, 6 Mar 2025 12:52:26 +0500 Subject: [PATCH 02/12] Generate build info for 'buildinfo-cli' project --- .github/workflows/build.yml | 6 ++++++ ci/install-buildinfo | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100755 ci/install-buildinfo diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 55402bf..e20c64f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,5 +13,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Install buildinfo + run: ./ci/install-buildinfo + + - name: Produce build info + run: buildinfo ./buildinfo-cli + - name: Build run: cargo build --verbose diff --git a/ci/install-buildinfo b/ci/install-buildinfo new file mode 100755 index 0000000..77b1163 --- /dev/null +++ b/ci/install-buildinfo @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -eu + +readonly cmd=~/.local/bin/buildinfo + +mkdir -p "$(dirname "$cmd")" +curl -Lo "$cmd" 'https://github.com/suprematic/buildinfo/releases/download/v0.1.0-alpha/buildinfo' +chmod +x "$cmd" From c095a232c61d71daff0def782fd7033079dee76e Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Tue, 4 Mar 2025 19:51:20 +0500 Subject: [PATCH 03/12] Ignore 'target' dir in project root --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target From 1781f62539dedf2db7d4a3a8ed303315e13e37b1 Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Tue, 4 Mar 2025 20:16:04 +0500 Subject: [PATCH 04/12] Put datetime in UTC timezone into 'build.timestamp' of 'local' build environment --- buildinfo-cli/src/build.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildinfo-cli/src/build.rs b/buildinfo-cli/src/build.rs index ce315da..7a6a072 100644 --- a/buildinfo-cli/src/build.rs +++ b/buildinfo-cli/src/build.rs @@ -57,8 +57,8 @@ fn codebuild_build_info() -> Result { } fn local_build_environment() -> Result { - static TIMESTAMP: std::sync::LazyLock> = - std::sync::LazyLock::new(|| chrono::Local::now()); + static TIMESTAMP: std::sync::LazyLock> = + std::sync::LazyLock::new(|| chrono::Utc::now()); Ok(BuildInfo { environment: BuildEnvironment::Local, From 3485d430c4f582f55210510f2db1abf384754f1c Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Thu, 6 Mar 2025 15:01:50 +0500 Subject: [PATCH 05/12] Fix error when executing in GitHub Actions build --- Cargo.lock | 2 +- buildinfo-cli/Cargo.toml | 2 +- buildinfo-cli/src/build.rs | 14 +++++++++----- ci/install-buildinfo | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a0a1660..b60ad64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,7 +94,7 @@ dependencies = [ [[package]] name = "buildinfo-cli" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "buildinfo", diff --git a/buildinfo-cli/Cargo.toml b/buildinfo-cli/Cargo.toml index a757f49..2e95c5a 100644 --- a/buildinfo-cli/Cargo.toml +++ b/buildinfo-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "buildinfo-cli" -version = "0.1.0" +version = "0.1.1" edition = "2021" [dependencies] diff --git a/buildinfo-cli/src/build.rs b/buildinfo-cli/src/build.rs index 7a6a072..672db06 100644 --- a/buildinfo-cli/src/build.rs +++ b/buildinfo-cli/src/build.rs @@ -29,12 +29,19 @@ fn build_environment() -> BuildEnvironment { } } +fn timestamp() -> String { + let timestamp: std::sync::LazyLock> = + std::sync::LazyLock::new(|| chrono::Utc::now()); + + timestamp.to_rfc3339() +} + fn github_build_info() -> Result { Ok(BuildInfo { environment: BuildEnvironment::GitHub, trigger: var("GITHUB_ACTOR")?, number: var("GITHUB_RUN_NUMBER")?.parse()?, - timestamp: var("GITHUB_RUN_AT")?, + timestamp: timestamp(), }) } @@ -57,14 +64,11 @@ fn codebuild_build_info() -> Result { } fn local_build_environment() -> Result { - static TIMESTAMP: std::sync::LazyLock> = - std::sync::LazyLock::new(|| chrono::Utc::now()); - Ok(BuildInfo { environment: BuildEnvironment::Local, trigger: whoami::username(), number: 1, - timestamp: TIMESTAMP.to_rfc3339(), + timestamp: timestamp(), }) } diff --git a/ci/install-buildinfo b/ci/install-buildinfo index 77b1163..7f176a7 100755 --- a/ci/install-buildinfo +++ b/ci/install-buildinfo @@ -5,5 +5,5 @@ set -eu readonly cmd=~/.local/bin/buildinfo mkdir -p "$(dirname "$cmd")" -curl -Lo "$cmd" 'https://github.com/suprematic/buildinfo/releases/download/v0.1.0-alpha/buildinfo' +curl -Lo "$cmd" 'https://github.com/suprematic/buildinfo/releases/download/v0.1.1-alpha/buildinfo' chmod +x "$cmd" From 727e1bf66923e7ffd4828f6112b83cd45511cd69 Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Tue, 11 Mar 2025 17:53:20 +0500 Subject: [PATCH 06/12] Add 'as_string' property to project info --- buildinfo-cli/src/main.rs | 1 + buildinfo-cli/src/project.rs | 39 ++++++++++++++++++++++++++++-------- buildinfo/src/lib.rs | 1 + 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/buildinfo-cli/src/main.rs b/buildinfo-cli/src/main.rs index 66754ad..4706827 100644 --- a/buildinfo-cli/src/main.rs +++ b/buildinfo-cli/src/main.rs @@ -29,6 +29,7 @@ mod v1 { project: ProjectInfo { name: project_info.name.clone(), version: project_info.version.clone(), + as_string: project_info.as_string.clone(), }, git: RepoInfo { diff --git a/buildinfo-cli/src/project.rs b/buildinfo-cli/src/project.rs index 47b9ce1..994d261 100644 --- a/buildinfo-cli/src/project.rs +++ b/buildinfo-cli/src/project.rs @@ -17,6 +17,7 @@ pub struct ProjectInfo { pub name: String, pub version: String, pub target_path: PathBuf, + pub as_string: String, } fn project_type() -> ProjectType { @@ -35,6 +36,10 @@ fn project_type() -> ProjectType { } } +fn as_string(name: &str, version: &str) -> String { + format!("{} v{}", name, version) +} + fn rust_project_info() -> Result { let cargo_toml = slurp::read_all_to_string("Cargo.toml")?; let cargo_toml = toml::from_str::(&cargo_toml)?; @@ -42,6 +47,7 @@ fn rust_project_info() -> Result { let package = &cargo_toml["package"]; let name = package["name"].as_str().unwrap_or("unknown").to_string(); let version = package["version"].as_str().unwrap_or("unknown").to_string(); + let as_string = as_string(&name, &version); let target_path = current_dir()?.join("src/buildinfo.json"); @@ -50,6 +56,7 @@ fn rust_project_info() -> Result { name, version, target_path, + as_string, }) } @@ -67,13 +74,18 @@ fn java_project_info() -> Result { let pom_xml = slurp::read_all_to_string("pom.xml")?; let pom_xml = fast_xml::de::from_str::(&pom_xml)?; + let name = format!("{}/{}", pom_xml.group_id, pom_xml.artifact_id); + let version = pom_xml.version; + let as_string = as_string(&name, &version); + let target_path = current_dir()?.join("src/main/resources/META-INF/buildinfo.json"); Ok(ProjectInfo { project_type: ProjectType::Java, - name: format!("{}/{}", pom_xml.group_id, pom_xml.artifact_id), - version: pom_xml.version, + name, + version, target_path, + as_string }) } @@ -85,11 +97,14 @@ fn javascript_project_info() -> Result { .as_str() .unwrap_or("unknown") .to_string(); + let version = project_json["version"] .as_str() .unwrap_or("unknown") .to_string(); + let as_string = as_string(&name, &version); + let target_path = current_dir()?.join("src/buildinfo.json"); Ok(ProjectInfo { @@ -97,6 +112,7 @@ fn javascript_project_info() -> Result { name, version, target_path, + as_string }) } @@ -105,11 +121,18 @@ pub fn project_info() -> Result { ProjectType::Rust => rust_project_info(), ProjectType::Java => java_project_info(), ProjectType::JavaScript => javascript_project_info(), - ProjectType::Other => Ok(ProjectInfo { - project_type: ProjectType::Other, - name: "unknown".to_string(), - version: "unknown".to_string(), - target_path: current_dir()?.join("buildinfo.json"), - }), + ProjectType::Other => { + let name = "unknown".to_string(); + let version = "unknown".to_string(); + let as_string = as_string(&name, &version); + + Ok(ProjectInfo { + project_type: ProjectType::Other, + name, + version, + as_string, + target_path: current_dir()?.join("buildinfo.json"), + }) + }, } } diff --git a/buildinfo/src/lib.rs b/buildinfo/src/lib.rs index f6b8c21..a65deea 100644 --- a/buildinfo/src/lib.rs +++ b/buildinfo/src/lib.rs @@ -6,6 +6,7 @@ pub mod v1 { pub struct ProjectInfo { pub name: String, pub version: String, + pub as_string: String, } #[derive(Debug, Serialize, Deserialize)] From f1b0a1c8e67572457fc25e943ed8ecacd2874931 Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Tue, 11 Mar 2025 19:11:35 +0500 Subject: [PATCH 07/12] Add 'as_string' property to git info --- buildinfo-cli/src/git.rs | 46 +++++++++++++++++++++++++++++++-------- buildinfo-cli/src/main.rs | 2 ++ buildinfo/src/lib.rs | 2 ++ 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/buildinfo-cli/src/git.rs b/buildinfo-cli/src/git.rs index c77b7da..896ce12 100644 --- a/buildinfo-cli/src/git.rs +++ b/buildinfo-cli/src/git.rs @@ -9,6 +9,13 @@ pub struct GitInfo { pub reference: String, pub repository: String, pub dirty: bool, + pub as_string: String, +} + +fn as_string(commit: &str, dirty: bool, reference: &str) -> String{ + let short_commit = &commit[..7]; + let dirty = if dirty { "#dirty" } else { "" }; + format!("commit: {}{}, ref: {}", short_commit, dirty, reference) } fn local_build_info() -> Result { @@ -25,38 +32,59 @@ fn local_build_info() -> Result { .count() > 0; + let as_string = as_string(&commit, dirty, &reference); + Ok(GitInfo { commit, reference, repository, dirty, + as_string, }) } fn github_build_info() -> Result { + let commit = var("GITHUB_SHA")?; + let reference = var("GITHUB_REF_NAME")?; + let dirty = false; + let as_string = as_string(&commit, dirty, &reference); + Ok(GitInfo { - commit: var("GITHUB_SHA")?, - reference: var("GITHUB_REF_NAME")?, + commit, + reference, repository: var("GITHUB_REPOSITORY")?, - dirty: false, + dirty, + as_string, }) } fn bitbucket_build_info() -> Result { + let commit = var("BITBUCKET_COMMIT")?; + let reference = var("BITBUCKET_BRANCH").or_else(|_| var("BITBUCKET_TAG"))?; + let dirty = false; + let as_string = as_string(&commit, dirty, &reference); + Ok(GitInfo { - commit: var("BITBUCKET_COMMIT")?, - reference: var("BITBUCKET_BRANCH").or_else(|_| var("BITBUCKET_TAG"))?, + commit, + reference, repository: var("BITBUCKET_REPO_FULL_NAME")?, - dirty: false, + dirty, + as_string, }) } fn codebuild_build_info() -> Result { + let commit = var("CODEBUILD_RESOLVED_SOURCE_VERSION")?; + let reference = var("CODEBUILD_SOURCE_VERSION").unwrap_or_else(|_| "undefined".to_string()); + let dirty = false; + let as_string = as_string(&commit, dirty, &reference); + Ok(GitInfo { - commit: var("CODEBUILD_RESOLVED_SOURCE_VERSION")?, - reference: var("CODEBUILD_SOURCE_VERSION").unwrap_or_else(|_| "undefined".to_string()), + commit, + reference, repository: var("CODEBUILD_SOURCE_REPO_URL")?, - dirty: false, + dirty, + as_string, }) } diff --git a/buildinfo-cli/src/main.rs b/buildinfo-cli/src/main.rs index 4706827..f55a9b7 100644 --- a/buildinfo-cli/src/main.rs +++ b/buildinfo-cli/src/main.rs @@ -37,7 +37,9 @@ mod v1 { reference: git_info.reference.clone(), commit: git_info.commit.clone(), dirty: git_info.dirty, + as_string: git_info.as_string.clone(), }, + build: BuilderInfo { timestamp: build_info.timestamp.clone(), number: build_info.number, diff --git a/buildinfo/src/lib.rs b/buildinfo/src/lib.rs index a65deea..7b6aa82 100644 --- a/buildinfo/src/lib.rs +++ b/buildinfo/src/lib.rs @@ -17,6 +17,8 @@ pub mod v1 { #[serde(skip_serializing_if = "std::ops::Not::not")] pub dirty: bool, + + pub as_string: String, } #[derive(Debug, Serialize, Deserialize)] From f956c840c52e9d5853645efd4997100cd2cc5b81 Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Tue, 11 Mar 2025 19:24:50 +0500 Subject: [PATCH 08/12] Add 'as_string' property to build info --- buildinfo-cli/src/build.rs | 53 +++++++++++++++++++++++++++++--------- buildinfo-cli/src/main.rs | 1 + buildinfo/src/lib.rs | 1 + 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/buildinfo-cli/src/build.rs b/buildinfo-cli/src/build.rs index 672db06..1b1d66d 100644 --- a/buildinfo-cli/src/build.rs +++ b/buildinfo-cli/src/build.rs @@ -15,6 +15,7 @@ pub struct BuildInfo { pub trigger: String, pub number: u32, pub timestamp: String, + pub as_string: String, } fn build_environment() -> BuildEnvironment { @@ -36,39 +37,67 @@ fn timestamp() -> String { timestamp.to_rfc3339() } +fn as_string(number: u32, timestamp: &str, trigger: &str) -> String { + format!("build #{} at {} by {}", number, timestamp, trigger) +} + fn github_build_info() -> Result { + let trigger = var("GITHUB_ACTOR")?; + let number = var("GITHUB_RUN_NUMBER")?.parse()?; + let timestamp = timestamp(); + let as_string = as_string(number, ×tamp, &trigger); + Ok(BuildInfo { environment: BuildEnvironment::GitHub, - trigger: var("GITHUB_ACTOR")?, - number: var("GITHUB_RUN_NUMBER")?.parse()?, - timestamp: timestamp(), + trigger, + number, + timestamp, + as_string, }) } fn bitbucket_build_info() -> Result { + let trigger = var("BITBUCKET_BUILD_CREATOR")?; + let number = var("BITBUCKET_BUILD_NUMBER")?.parse()?; + let timestamp = var("BITBUCKET_BUILD_CREATED_ON")?; + let as_string = as_string(number, ×tamp, &trigger); + Ok(BuildInfo { environment: BuildEnvironment::BitBucket, - trigger: var("BITBUCKET_BUILD_CREATOR")?, - number: var("BITBUCKET_BUILD_NUMBER")?.parse()?, - timestamp: var("BITBUCKET_BUILD_CREATED_ON")?, + trigger, + number, + timestamp, + as_string, }) } fn codebuild_build_info() -> Result { + let trigger = var("CODEBUILD_INITIATOR")?; + let number = var("CODEBUILD_BUILD_NUMBER")?.parse()?; + let timestamp = var("CODEBUILD_START_TIME")?; + let as_string = as_string(number, ×tamp, &trigger); + Ok(BuildInfo { environment: BuildEnvironment::CodeBuild, - trigger: var("CODEBUILD_INITIATOR")?, - number: var("CODEBUILD_BUILD_NUMBER")?.parse()?, - timestamp: var("CODEBUILD_START_TIME")?, + trigger, + number, + timestamp, + as_string, }) } fn local_build_environment() -> Result { + let trigger = whoami::username(); + let number = 1; + let timestamp = timestamp(); + let as_string = as_string(number, ×tamp, &trigger); + Ok(BuildInfo { environment: BuildEnvironment::Local, - trigger: whoami::username(), - number: 1, - timestamp: timestamp(), + trigger, + number, + timestamp, + as_string, }) } diff --git a/buildinfo-cli/src/main.rs b/buildinfo-cli/src/main.rs index f55a9b7..43ce8c6 100644 --- a/buildinfo-cli/src/main.rs +++ b/buildinfo-cli/src/main.rs @@ -51,6 +51,7 @@ mod v1 { BuildEnvironment::CodeBuild => "codebuild", } .to_string(), + as_string: build_info.as_string.clone(), }, properties: HashMap::new(), diff --git a/buildinfo/src/lib.rs b/buildinfo/src/lib.rs index 7b6aa82..619a3e6 100644 --- a/buildinfo/src/lib.rs +++ b/buildinfo/src/lib.rs @@ -27,6 +27,7 @@ pub mod v1 { pub timestamp: String, pub number: u32, pub trigger: String, + pub as_string: String, } #[derive(Debug, Serialize, Deserialize)] From 4cb63b3052856e69cc834cfcaec0aa05684a6283 Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Tue, 11 Mar 2025 19:34:41 +0500 Subject: [PATCH 09/12] Add 'as_string' top level property --- buildinfo-cli/src/main.rs | 20 +++++++++++++------- buildinfo/src/lib.rs | 2 ++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/buildinfo-cli/src/main.rs b/buildinfo-cli/src/main.rs index 43ce8c6..d0a8acb 100644 --- a/buildinfo-cli/src/main.rs +++ b/buildinfo-cli/src/main.rs @@ -25,22 +25,21 @@ mod v1 { git_info: &super::git::GitInfo, project_info: &super::project::ProjectInfo, ) -> BuildInfo { - BuildInfo { - project: ProjectInfo { + let project = ProjectInfo { name: project_info.name.clone(), version: project_info.version.clone(), as_string: project_info.as_string.clone(), - }, + }; - git: RepoInfo { + let git = RepoInfo { repository: git_info.repository.clone(), reference: git_info.reference.clone(), commit: git_info.commit.clone(), dirty: git_info.dirty, as_string: git_info.as_string.clone(), - }, + }; - build: BuilderInfo { + let build = BuilderInfo { timestamp: build_info.timestamp.clone(), number: build_info.number, trigger: build_info.trigger.clone(), @@ -52,8 +51,15 @@ mod v1 { } .to_string(), as_string: build_info.as_string.clone(), - }, + }; + + let as_string = format!("{} ({}, {})", project.as_string, git.as_string, build.as_string); + BuildInfo { + project, + git, + build, + as_string, properties: HashMap::new(), } } diff --git a/buildinfo/src/lib.rs b/buildinfo/src/lib.rs index 619a3e6..b8f7472 100644 --- a/buildinfo/src/lib.rs +++ b/buildinfo/src/lib.rs @@ -38,6 +38,8 @@ pub mod v1 { #[serde(skip_serializing_if = "HashMap::is_empty")] pub properties: HashMap, + + pub as_string: String, } } From f8bb19a7db79daea15de3dd7b30ae87ecfdfc1d3 Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Tue, 11 Mar 2025 19:57:03 +0500 Subject: [PATCH 10/12] Upload built 'buildinfo' executable to artifacts --- .github/workflows/build.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e20c64f..5748056 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,4 +20,11 @@ jobs: run: buildinfo ./buildinfo-cli - name: Build - run: cargo build --verbose + run: cargo build --release --verbose + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: buildinfo + path: ./target/release/buildinfo + if-no-files-found: error From d80c4e6d369f0437f5c2f51f48bd651bb8a49088 Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Tue, 11 Mar 2025 20:34:31 +0500 Subject: [PATCH 11/12] Update version to 0.2.0 --- Cargo.lock | 2 +- buildinfo-cli/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b60ad64..4e9cb48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,7 +94,7 @@ dependencies = [ [[package]] name = "buildinfo-cli" -version = "0.1.1" +version = "0.2.0" dependencies = [ "anyhow", "buildinfo", diff --git a/buildinfo-cli/Cargo.toml b/buildinfo-cli/Cargo.toml index 2e95c5a..9ca0792 100644 --- a/buildinfo-cli/Cargo.toml +++ b/buildinfo-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "buildinfo-cli" -version = "0.1.1" +version = "0.2.0" edition = "2021" [dependencies] From 8ae1c2f7e7657d41b54f6334cbae13872062d071 Mon Sep 17 00:00:00 2001 From: Sergey Kozhevnikov Date: Tue, 11 Mar 2025 20:40:13 +0500 Subject: [PATCH 12/12] Print buldinfo during build --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5748056..c96f5b6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,10 @@ jobs: run: ./ci/install-buildinfo - name: Produce build info - run: buildinfo ./buildinfo-cli + working-directory: ./buildinfo-cli + run: | + buildinfo + cat ./src/buildinfo.json - name: Build run: cargo build --release --verbose