gitdataai/lib/git/http/action.rs
2026-05-30 01:38:40 +08:00

102 lines
2.7 KiB
Rust

use actix_web::{HttpResponse, web};
use serde::{Deserialize, Serialize};
use crate::{
http::{HttpAppState, utils::get_repo_model},
sync::cicheck::poll_ci_task_for_repo,
};
#[derive(Debug, Deserialize)]
pub struct ActionQuery {
#[serde(default = "default_timeout")]
pub timeout: usize,
}
fn default_timeout() -> usize {
5
}
#[derive(Debug, Serialize)]
struct ActionTask {
id: String,
repo_id: String,
pipeline_name: String,
trigger: String,
}
#[derive(Debug, Serialize)]
struct ActionResponse {
status: String,
task: Option<ActionTask>,
}
pub async fn action_poll(
path: web::Path<(String, String)>,
query: web::Query<ActionQuery>,
state: web::Data<HttpAppState>,
) -> HttpResponse {
let (namespace, repo_name) = path.into_inner();
let repo_model =
match get_repo_model(&namespace, &repo_name, &state.db).await {
Ok(m) => m,
Err(_) => {
return HttpResponse::NotFound().json(ActionResponse {
status: "not_found".into(),
task: None,
});
}
};
let task_json =
poll_ci_task_for_repo(&state.sync.pool(), repo_model.id, query.timeout)
.await;
match task_json {
Some(json) => {
let hook_task: serde_json::Value = match serde_json::from_str(&json)
{
Ok(v) => v,
Err(_) => {
return HttpResponse::InternalServerError().json(
ActionResponse {
status: "error".into(),
task: None,
},
);
}
};
let task_id = hook_task
.get("id")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let pipeline_name = hook_task
.get("payload")
.and_then(|p| p.get("pipeline_name"))
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let trigger = hook_task
.get("payload")
.and_then(|p| p.get("trigger"))
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
HttpResponse::Ok().json(ActionResponse {
status: "pending".into(),
task: Some(ActionTask {
id: task_id,
repo_id: repo_model.id.to_string(),
pipeline_name,
trigger,
}),
})
}
None => HttpResponse::NoContent().finish(),
}
}