Add /api/version endpoint for upgrade convergence checks
Reports crate version + compile-time BUILD_GIT_HASH as JSON. The gateway will poll this after `upgrade all` to verify each sled is actually running the published artifact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
This commit is contained in:
@@ -63,6 +63,23 @@ pub fn health_handler() -> poem::Response {
|
||||
poem::Response::builder().status(StatusCode::OK).body("ok")
|
||||
}
|
||||
|
||||
/// Version probe — reports the crate version and compile-time git hash.
|
||||
///
|
||||
/// Used by the gateway to verify that an upgrade converged: after `upgrade all`
|
||||
/// the gateway polls this endpoint until the reported `git_hash` matches the
|
||||
/// published artifact's hash (or times out).
|
||||
#[poem::handler]
|
||||
pub fn version_handler() -> poem::Response {
|
||||
let body = serde_json::json!({
|
||||
"version": env!("CARGO_PKG_VERSION"),
|
||||
"git_hash": option_env!("BUILD_GIT_HASH").unwrap_or("unknown"),
|
||||
});
|
||||
poem::Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.content_type("application/json")
|
||||
.body(body.to_string())
|
||||
}
|
||||
|
||||
/// Assemble the full Poem route tree (WebSocket, MCP, OAuth, assets, webhooks).
|
||||
pub fn build_routes(
|
||||
ctx: AppContext,
|
||||
@@ -77,6 +94,7 @@ pub fn build_routes(
|
||||
|
||||
let mut route = Route::new()
|
||||
.at("/health", get(health_handler))
|
||||
.at("/api/version", get(version_handler))
|
||||
.at("/ws", get(ws::ws_handler))
|
||||
.at("/crdt-sync", get(crate::crdt_sync::crdt_sync_handler))
|
||||
.at("/rpc", post(rpc_http_handler))
|
||||
@@ -335,6 +353,27 @@ mod tests {
|
||||
let _endpoint = build_routes(ctx, None, None, 3001, None);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn version_endpoint_reports_version_and_git_hash() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let ctx = context::AppContext::new_test(tmp.path().to_path_buf());
|
||||
let app = build_routes(ctx, None, None, 3001, None);
|
||||
let cli = poem::test::TestClient::new(app);
|
||||
|
||||
let resp = cli.get("/api/version").send().await;
|
||||
resp.assert_status_is_ok();
|
||||
let text = resp.0.into_body().into_string().await.unwrap();
|
||||
let body: serde_json::Value = serde_json::from_str(&text).unwrap();
|
||||
assert_eq!(
|
||||
body.get("version").and_then(|v| v.as_str()),
|
||||
Some(env!("CARGO_PKG_VERSION"))
|
||||
);
|
||||
assert!(
|
||||
body.get("git_hash").and_then(|v| v.as_str()).is_some(),
|
||||
"git_hash must be present: {body}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_routes_accepts_custom_port() {
|
||||
// Verify build_routes compiles and runs with a non-default port,
|
||||
|
||||
Reference in New Issue
Block a user