From 4f5dbada1e9eeabf9eb5fa0ab6eecbe9669d2896 Mon Sep 17 00:00:00 2001 From: Lisandro Crespo Date: Mon, 10 Aug 2026 10:15:32 -0500 Subject: [PATCH 1/2] Report release tag version in healthcheck --- .github/workflows/package.yml | 5 +++++ Dockerfile | 9 +++++++-- crates/client-api/src/routes/health.rs | 5 ++++- tools/release/src/targets/docker.rs | 3 +++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 8263871133b..d9dcd2cd749 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -64,6 +64,11 @@ jobs: - name: Install rust target run: rustup target add ${{ matrix.target }} + - name: Set release version + if: startsWith(github.ref, 'refs/tags/') + shell: bash + run: echo "SPACETIMEDB_VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_ENV" + - name: Add signtool.exe to PATH if: ${{ runner.os == 'Windows' }} shell: pwsh diff --git a/Dockerfile b/Dockerfile index e37332b8af1..bda3bbece8a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,6 +4,8 @@ FROM rust:bookworm AS builder WORKDIR /usr/src/app COPY . . +ARG SPACETIMEDB_RELEASE_VERSION + # If we're in a git submodule, we'll have a corrupted/nonfunctional .git file instead of a proper .git directory. # To make the errors more sane, remove .git entirely. RUN if [ -f .git ]; then \ @@ -13,7 +15,11 @@ RUN if [ -f .git ]; then \ exit 1; \ fi -RUN cargo build -p spacetimedb-standalone -p spacetimedb-cli --release --locked +RUN if [ -n "$SPACETIMEDB_RELEASE_VERSION" ]; then \ + SPACETIMEDB_VERSION="$SPACETIMEDB_RELEASE_VERSION" cargo build -p spacetimedb-standalone -p spacetimedb-cli --release --locked; \ + else \ + cargo build -p spacetimedb-standalone -p spacetimedb-cli --release --locked; \ + fi FROM rust:bookworm @@ -62,4 +68,3 @@ EXPOSE 3000 # Define the entrypoint ENTRYPOINT ["spacetime"] - diff --git a/crates/client-api/src/routes/health.rs b/crates/client-api/src/routes/health.rs index 5bb5ad14b3a..47153bf5974 100644 --- a/crates/client-api/src/routes/health.rs +++ b/crates/client-api/src/routes/health.rs @@ -3,7 +3,10 @@ use axum::extract::State; use axum::response::IntoResponse; use http::StatusCode; -static VERSION: &str = env!("CARGO_PKG_VERSION"); +static VERSION: &str = match option_env!("SPACETIMEDB_VERSION") { + Some(version) => version, + None => env!("CARGO_PKG_VERSION"), +}; static PACKAGE_NAME: &str = env!("CARGO_PKG_NAME"); pub async fn health( diff --git a/tools/release/src/targets/docker.rs b/tools/release/src/targets/docker.rs index 2028f33624e..9543eb034ac 100644 --- a/tools/release/src/targets/docker.rs +++ b/tools/release/src/targets/docker.rs @@ -111,6 +111,7 @@ impl DockerRelease { println!("Building for platforms: linux/amd64, linux/arm64"); let version_tag = format!("{}:{}", image_repo, self.version); + let healthcheck_version = self.version.strip_prefix('v').unwrap_or(&self.version); // Build and push the multi-platform image let mut cmd = Command::new("docker"); @@ -121,6 +122,8 @@ impl DockerRelease { "linux/amd64,linux/arm64", "-t", &version_tag, + "--build-arg", + &format!("SPACETIMEDB_RELEASE_VERSION={healthcheck_version}"), "--push", ".", ]); From 90a90aee4d57bb44c6953f35ce1595bcbf9951aa Mon Sep 17 00:00:00 2001 From: Lisandro Crespo Date: Mon, 10 Aug 2026 10:34:40 -0500 Subject: [PATCH 2/2] Add unit tests --- crates/client-api/src/routes/health.rs | 27 ++++++++++++++++++++++---- tools/ci/src/main.rs | 1 + tools/release/src/targets/docker.rs | 21 +++++++++++++++++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/crates/client-api/src/routes/health.rs b/crates/client-api/src/routes/health.rs index 47153bf5974..5e611d7e9aa 100644 --- a/crates/client-api/src/routes/health.rs +++ b/crates/client-api/src/routes/health.rs @@ -3,12 +3,16 @@ use axum::extract::State; use axum::response::IntoResponse; use http::StatusCode; -static VERSION: &str = match option_env!("SPACETIMEDB_VERSION") { - Some(version) => version, - None => env!("CARGO_PKG_VERSION"), -}; +static VERSION: &str = selected_version(option_env!("SPACETIMEDB_VERSION"), env!("CARGO_PKG_VERSION")); static PACKAGE_NAME: &str = env!("CARGO_PKG_NAME"); +const fn selected_version(release_version: Option<&'static str>, cargo_version: &'static str) -> &'static str { + match release_version { + Some(version) => version, + None => cargo_version, + } +} + pub async fn health( State(ctx): State, ) -> axum::response::Result { @@ -50,3 +54,18 @@ where use axum::routing::get; axum::Router::new().route("/", get(health::)) } + +#[cfg(test)] +mod tests { + use super::selected_version; + + #[test] + fn selected_version_uses_release_version_when_present() { + assert_eq!(selected_version(Some("2.7.0-hotfix3"), "2.7.0"), "2.7.0-hotfix3"); + } + + #[test] + fn selected_version_falls_back_to_cargo_version() { + assert_eq!(selected_version(None, "2.8.0"), "2.8.0"); + } +} diff --git a/tools/ci/src/main.rs b/tools/ci/src/main.rs index 469d085bf5e..93842e3a297 100644 --- a/tools/ci/src/main.rs +++ b/tools/ci/src/main.rs @@ -591,6 +591,7 @@ fn main() -> Result<()> { "unreal" ) .run()?; + cmd!("cargo", "test", "--manifest-path", "tools/release/Cargo.toml").run()?; // Bindings snapshot tests rely on the unstable feature, // as they compile and test APIs which are gated behind that feature, // e.g. procedures, HTTP handlers. diff --git a/tools/release/src/targets/docker.rs b/tools/release/src/targets/docker.rs index 9543eb034ac..f3504259135 100644 --- a/tools/release/src/targets/docker.rs +++ b/tools/release/src/targets/docker.rs @@ -4,6 +4,10 @@ use std::process::Command; use std::thread; use std::time::{Duration, Instant}; +fn healthcheck_version(release_version: &str) -> &str { + release_version.strip_prefix('v').unwrap_or(release_version) +} + pub struct DockerRelease { pub version: String, pub dry_run: bool, @@ -111,7 +115,7 @@ impl DockerRelease { println!("Building for platforms: linux/amd64, linux/arm64"); let version_tag = format!("{}:{}", image_repo, self.version); - let healthcheck_version = self.version.strip_prefix('v').unwrap_or(&self.version); + let healthcheck_version = healthcheck_version(&self.version); // Build and push the multi-platform image let mut cmd = Command::new("docker"); @@ -212,3 +216,18 @@ impl ReleaseTarget for DockerRelease { "docker" } } + +#[cfg(test)] +mod tests { + use super::healthcheck_version; + + #[test] + fn healthcheck_version_strips_leading_v() { + assert_eq!(healthcheck_version("v2.7.0-hotfix3"), "2.7.0-hotfix3"); + } + + #[test] + fn healthcheck_version_keeps_version_without_leading_v() { + assert_eq!(healthcheck_version("2.7.0-hotfix3"), "2.7.0-hotfix3"); + } +}