feat: add build_date to health endpoint for CI deploy verification
All checks were successful
BotServer CI/CD / build (push) Successful in 4m21s

- Add BOTSERVER_BUILD_DATE env var to /api/health response
- Set build date during CI compilation via environment variable
- Enables checking deployed binary age without SSH access

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2026-04-13 11:49:10 -03:00
parent 4fb626399d
commit d1652fc413
5 changed files with 47 additions and 14 deletions

View file

@ -83,6 +83,9 @@ jobs:
working-directory: /opt/gbo/data/botserver
run: |
sccache --start-server 2>/dev/null || true
BOTSERVER_BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
export BOTSERVER_BUILD_DATE
echo "Build date: $BOTSERVER_BUILD_DATE"
cargo build -p botserver -j 8 2>&1 | tee /tmp/build.log
sccache --show-stats
ls -lh target/debug/botserver

View file

@ -1,10 +1,9 @@
use super::ModelHandler;
use std::sync::LazyLock;
use regex::Regex;
use std::sync::LazyLock;
static THINK_TAG_REGEX: LazyLock<Result<Regex, regex::Error>> = LazyLock::new(|| {
Regex::new(r"(?s)<think>.*?</think>")
});
static THINK_TAG_REGEX: LazyLock<Result<Regex, regex::Error>> =
LazyLock::new(|| Regex::new(r"(?s)<think>.*?</think>"));
pub fn strip_think_tags(content: &str) -> String {
if let Ok(re) = &*THINK_TAG_REGEX {

View file

@ -1,18 +1,25 @@
use super::deepseek_r3::strip_think_tags;
use super::ModelHandler;
use std::sync::LazyLock;
use regex::Regex;
use std::sync::LazyLock;
static ANALYSIS_MARKER_REGEX: LazyLock<Result<Regex, regex::Error>> = LazyLock::new(|| {
Regex::new(r"analysis<\|message\|>")
});
static ANALYSIS_MARKER_REGEX: LazyLock<Result<Regex, regex::Error>> =
LazyLock::new(|| Regex::new(r"analysis<\|message\|>"));
static FINAL_MARKER_REGEX: LazyLock<Result<Regex, regex::Error>> =
LazyLock::new(|| Regex::new(r"<\|message\|>final<\|message\|>"));
#[derive(Debug)]
pub struct GptOss20bHandler;
impl ModelHandler for GptOss20bHandler {
fn is_analysis_complete(&self, buffer: &str) -> bool {
buffer.contains("final") || buffer.contains("</think>")
buffer.contains("")
|| (if let Ok(re) = &*FINAL_MARKER_REGEX {
re.is_match(buffer)
} else {
false
})
}
fn process_content(&self, content: &str) -> String {
@ -20,9 +27,10 @@ impl ModelHandler for GptOss20bHandler {
if without_think.is_empty() {
return String::new();
}
match without_think.find("final") {
Some(pos) => without_think[..pos].to_string(),
None => without_think,
if let Ok(re) = &*FINAL_MARKER_REGEX {
re.replace_all(&without_think, "").to_string()
} else {
without_think
}
}
@ -31,6 +39,6 @@ impl ModelHandler for GptOss20bHandler {
re.is_match(buffer)
} else {
buffer.contains("analysis<|message|>")
}) || buffer.contains("<think>")
}) || buffer.contains("")
}
}

View file

@ -8,6 +8,23 @@ pub trait ModelHandler: Send + Sync {
fn has_analysis_markers(&self, buffer: &str) -> bool;
}
#[derive(Debug)]
pub struct PassthroughHandler;
impl ModelHandler for PassthroughHandler {
fn is_analysis_complete(&self, _buffer: &str) -> bool {
true
}
fn process_content(&self, content: &str) -> String {
content.to_string()
}
fn has_analysis_markers(&self, _buffer: &str) -> bool {
false
}
}
#[must_use]
pub fn get_handler(model_path: &str) -> Box<dyn ModelHandler> {
let path = model_path.to_lowercase();
@ -15,7 +32,9 @@ pub fn get_handler(model_path: &str) -> Box<dyn ModelHandler> {
Box::new(deepseek_r3::DeepseekR3Handler)
} else if path.contains("120b") {
Box::new(gpt_oss_120b::GptOss120bHandler::new())
} else {
} else if path.contains("20b") {
Box::new(gpt_oss_20b::GptOss20bHandler)
} else {
Box::new(PassthroughHandler)
}
}

View file

@ -17,12 +17,16 @@ pub async fn health_check(State(state): State<Arc<AppState>>) -> (StatusCode, Js
StatusCode::SERVICE_UNAVAILABLE
};
// Build timestamp set by CI via BOTSERVER_BUILD_DATE env var
let build_date = option_env!("BOTSERVER_BUILD_DATE").unwrap_or("unknown");
(
code,
Json(serde_json::json!({
"status": status,
"service": "botserver",
"version": env!("CARGO_PKG_VERSION"),
"build_date": build_date,
"database": db_ok
})),
)