diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a661fbd..1e0fb2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,8 @@ jobs: test: name: Build and test ${{ matrix.label }} runs-on: ${{ matrix.runner }} + env: + GIT_SHA: ${{ github.sha }} strategy: fail-fast: false diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e1b08f7..9e88b77 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -18,6 +18,8 @@ jobs: contents: read env: VERSION: ${{ github.ref_name }} + BEAM_VERSION: ${{ github.ref_name }} + GIT_SHA: ${{ github.sha }} strategy: fail-fast: false matrix: diff --git a/beam-init-api/src/lib.rs b/beam-init-api/src/lib.rs index 0c21fb1..4badc9a 100644 --- a/beam-init-api/src/lib.rs +++ b/beam-init-api/src/lib.rs @@ -123,6 +123,15 @@ pub enum ServiceStatus { Error(String), } +/// Version information for beam-init +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct VersionResponse { + /// The version reported by beam-init + pub version: String, + /// The commit sha beam-init was compiled from + pub sha: String, +} + impl std::fmt::Display for ServiceStatus { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/beam-init-client/src/blocking.rs b/beam-init-client/src/blocking.rs index fd4ae74..695d0ec 100644 --- a/beam-init-client/src/blocking.rs +++ b/beam-init-client/src/blocking.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use std::io::Read; use std::path::Path; -use beam_init_api::{CreateService, Service, ServiceStatus}; +use beam_init_api::{CreateService, Service, ServiceStatus, VersionResponse}; use reqwest::{Method, StatusCode}; use serde::Serialize; use serde::de::DeserializeOwned; @@ -116,6 +116,10 @@ impl Client { self.get_raw(&path) } + pub fn version(&self) -> Result { + self.get("/version") + } + fn request(&self, method: Method, path: &str) -> reqwest::blocking::RequestBuilder { debug_assert!(path.starts_with('/')); self.client diff --git a/beam-init/src/api_impl.rs b/beam-init/src/api_impl.rs index 07a6486..d3486f5 100644 --- a/beam-init/src/api_impl.rs +++ b/beam-init/src/api_impl.rs @@ -16,7 +16,7 @@ use tokio_stream::StreamExt; use crate::Event; use crate::services::{self, ServiceError, ServiceManager, StartReason}; use beam_init::system::cerr; -use beam_init_api::{API_SOCKET_PATH, CreateService, ServiceStatus}; +use beam_init_api::{API_SOCKET_PATH, CreateService, ServiceStatus, VersionResponse}; #[allow(clippy::enum_variant_names)] #[derive(Debug)] @@ -109,6 +109,7 @@ pub fn bind_api_socket(tx_event: mpsc::Sender) -> io::Result<()> { .route("/service/{name}/thaw", post(thaw_service)) .route("/service/{name}/show", post(show_service)) .route("/service/{name}/logs", get(service_logs)) + .route("/version", get(version)) .with_state(tx_event); tokio::spawn(async move { @@ -286,6 +287,14 @@ async fn service_logs( rx.await.expect("main task crashed") } +async fn version() -> Response { + Json(VersionResponse { + version: crate::VERSION.to_string(), + sha: crate::GIT_SHA.to_string(), + }) + .into_response() +} + impl From<&crate::services::Service> for beam_init_api::Service { fn from(value: &crate::services::Service) -> Self { Self { diff --git a/beam-init/src/bin/beamctl.rs b/beam-init/src/bin/beamctl.rs index 13fd597..dd130db 100644 --- a/beam-init/src/bin/beamctl.rs +++ b/beam-init/src/bin/beamctl.rs @@ -7,6 +7,15 @@ use clap_complete::{Shell, generate}; use beam_init_api::Probe; use beam_init_client::blocking::Client; +const VERSION: &str = match option_env!("BEAM_VERSION") { + Some(version) => version, + None => env!("CARGO_PKG_VERSION"), +}; +const GIT_SHA: &str = match option_env!("GIT_SHA") { + Some(sha) => sha, + None => "unknown", +}; + #[cfg(feature = "unstable-pty")] mod terminal; @@ -99,6 +108,8 @@ enum Command { /// Shell to generate completions for. shell: Shell, }, + /// Show the version of beamctl and beam-init + Version, } // Defaults are from https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/core/v1/defaults.go. @@ -270,6 +281,11 @@ fn main() { generate(shell, &mut command, "beamctl", &mut std::io::stdout()); } + Command::Version => { + println!("beamctl: Version: {} - SHA: {}", VERSION, GIT_SHA); + let resp = client.version().unwrap_or_else(show_error_and_exit); + println!("beam-init: Version: {} - SHA: {}", resp.version, resp.sha); + } } } diff --git a/beam-init/src/main.rs b/beam-init/src/main.rs index 05e3f1c..7aa780b 100644 --- a/beam-init/src/main.rs +++ b/beam-init/src/main.rs @@ -18,6 +18,14 @@ mod logs; mod services; mod signal_stream; +pub(crate) const VERSION: &str = match option_env!("BEAM_VERSION") { + Some(version) => version, + None => env!("CARGO_PKG_VERSION"), +}; +pub(crate) const GIT_SHA: &str = match option_env!("GIT_SHA") { + Some(sha) => sha, + None => "unknown", +}; /// If true we will print log messages that may contain sensitive information. /// /// Set to true using the `BEAM_INIT_ENABLE_DEBUG_LOGS=1` env var.