From 824d5a7384dea2c71319b6aba9e9893aa38b9ab0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 13:42:40 +0000 Subject: [PATCH] Add /version endpoint and GitHub Actions release workflow Co-authored-by: Ganonmaster <168445+Ganonmaster@users.noreply.github.com> --- .github/workflows/release.yml | 51 +++++++++++++++++++++++++++++++++++ build.rs | 41 ++++++++++++++++++++++++++++ src/main.rs | 1 + src/routes/mod.rs | 1 + src/routes/version.rs | 25 +++++++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 build.rs create mode 100644 src/routes/version.rs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..48aa498 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,51 @@ +name: Release + +on: + push: + tags: + - "v*" + +permissions: + contents: write + +jobs: + build-linux: + name: Build Linux release binary + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # needed so build.rs can run `git describe` + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-unknown-linux-gnu + + - name: Cache Cargo registry and build artefacts + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry/index + ~/.cargo/registry/cache + ~/.cargo/git/db + target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + + - name: Build release binary + run: cargo build --release --target x86_64-unknown-linux-gnu + + - name: Rename binary for upload + run: | + cp target/x86_64-unknown-linux-gnu/release/mikebase \ + mikebase-${{ github.ref_name }}-x86_64-linux + + - name: Upload binary to GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: mikebase-${{ github.ref_name }}-x86_64-linux + generate_release_notes: true diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..f763695 --- /dev/null +++ b/build.rs @@ -0,0 +1,41 @@ +use std::process::Command; + +fn main() { + // Emit git commit hash (short) + let commit_hash = Command::new("git") + .args(["rev-parse", "--short", "HEAD"]) + .output() + .ok() + .and_then(|o| String::from_utf8(o.stdout).ok()) + .map(|s| s.trim().to_string()) + .unwrap_or_else(|| "unknown".to_string()); + + println!("cargo:rustc-env=GIT_COMMIT_HASH={commit_hash}"); + + // Emit git tag describing the current commit (e.g. "v1.0.0" or "v1.0.0-3-gabcdef1") + // `git describe --tags --exact-match` gives the exact tag; fall back to `git describe --tags`. + let git_tag = Command::new("git") + .args(["describe", "--tags", "--exact-match"]) + .output() + .ok() + .filter(|o| o.status.success()) + .and_then(|o| String::from_utf8(o.stdout).ok()) + .map(|s| s.trim().to_string()) + .or_else(|| { + Command::new("git") + .args(["describe", "--tags"]) + .output() + .ok() + .filter(|o| o.status.success()) + .and_then(|o| String::from_utf8(o.stdout).ok()) + .map(|s| s.trim().to_string()) + }); + + let tag_value = git_tag.unwrap_or_else(|| "untagged".to_string()); + println!("cargo:rustc-env=GIT_TAG={tag_value}"); + + // Re-run if HEAD or tag refs change + println!("cargo:rerun-if-changed=.git/HEAD"); + println!("cargo:rerun-if-changed=.git/refs/tags"); + println!("cargo:rerun-if-changed=.git/packed-refs"); +} diff --git a/src/main.rs b/src/main.rs index 7a4d250..c895e51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,6 +54,7 @@ async fn main() { let app = Router::new() .route("/", get(routes::emotes::root)) + .route("/version", get(routes::version::version)) .route("/json", get(routes::emotes::list_emotes)) .route("/emotes", post(routes::emotes::create_emote)) .route("/emotes/{uuid}", put(routes::emotes::update_emote)) diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 9702490..39bf7e9 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1 +1,2 @@ pub mod emotes; +pub mod version; diff --git a/src/routes/version.rs b/src/routes/version.rs new file mode 100644 index 0000000..d0ce65c --- /dev/null +++ b/src/routes/version.rs @@ -0,0 +1,25 @@ +use axum::response::{IntoResponse, Json}; +use serde_json::json; + +/// GET /version +/// Returns the current git commit hash and tag (if present). +pub async fn version() -> impl IntoResponse { + let commit = env!("GIT_COMMIT_HASH"); + let tag = env!("GIT_TAG"); + + // `git describe --tags --exact-match` sets an exact semver-like tag when the + // commit is tagged; otherwise the build script stores "untagged". + let response = if tag == "untagged" { + json!({ + "commit": commit, + "version": null + }) + } else { + json!({ + "commit": commit, + "version": tag + }) + }; + + Json(response) +}