//! Version information and a daily check for new releases. use crate::app::App; use serde_json::{Value, json}; use std::sync::{Arc, Mutex}; use std::time::Duration; pub use codecraft_core::version::VERSION; /// Git commit the image was built from (Docker build arg GIT_COMMIT). pub fn commit() -> &'static str { option_env!("CODECRAFT_COMMIT").unwrap_or("") } #[derive(Default)] pub struct UpdateState { pub latest: Mutex>, } use codecraft_core::version::newer; async fn check(app: &App) -> Option { let url = app.config().server.update_url.clone(); if url.is_empty() { return None; } let v: Value = crate::provider::http_client().get(&url).timeout(Duration::from_secs(20)).send().await.ok()?.json().await.ok()?; let tag = v["tag_name"].as_str()?.to_string(); if !newer(&tag, VERSION) { return None; } Some(json!({"version": tag.trim_start_matches('v'), "url": v["html_url"], "notes": v["body"].as_str().unwrap_or("").chars().take(4000).collect::(), "published_at": v["published_at"]})) } pub fn spawn_checker(app: Arc) { tokio::spawn(async move { tokio::time::sleep(Duration::from_secs(60)).await; loop { let found = check(&app).await; *app.update.latest.lock().unwrap() = found; tokio::time::sleep(Duration::from_secs(24 * 3600)).await; } }); }