swactor/crates/ci/src/status_reporter.rs

76 lines
2 KiB
Rust
Raw Normal View History

//! StatusReporter actor: fire-and-forget Forgejo commit status updates.
//!
//! Receives status update messages and POSTs them to the Forgejo API.
use swactor::actor::{ActorInterface, Ctx};
use crate::StatusUpdate;
/// Messages the StatusReporter can receive.
#[derive(Debug, Clone)]
pub enum StatusReporterMsg {
Report {
update: StatusUpdate,
forgejo_url: String,
forgejo_token: String,
},
}
/// StatusReporter actor state.
pub struct StatusReporter;
impl StatusReporter {
pub fn new() -> Self {
Self
}
#[cfg(feature = "local")]
fn post_status(update: &StatusUpdate, forgejo_url: &str, forgejo_token: &str) {
let url = format!(
"{}/api/v1/repos/{}/{}/statuses/{}",
forgejo_url.trim_end_matches('/'),
update.repo_owner,
update.repo_name,
update.commit_sha,
);
let body = serde_json::json!({
"state": update.state,
"context": update.context,
"description": update.description,
});
let result = ureq::post(&url)
.set("Authorization", &format!("token {forgejo_token}"))
.set("Content-Type", "application/json")
.send_string(&body.to_string());
if let Err(e) = result {
eprintln!("StatusReporter: failed to post status to {url}: {e}");
}
}
}
impl ActorInterface for StatusReporter {
type Incoming = StatusReporterMsg;
type Response = ();
fn handle(&mut self, _ctx: &Ctx, msg: StatusReporterMsg) {
match msg {
StatusReporterMsg::Report {
update,
forgejo_url,
forgejo_token,
} => {
#[cfg(feature = "local")]
Self::post_status(&update, &forgejo_url, &forgejo_token);
#[cfg(not(feature = "local"))]
{
let _ = (update, forgejo_url, forgejo_token);
}
}
}
}
}