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, } pub async fn action_poll( path: web::Path<(String, String)>, query: web::Query, state: web::Data, ) -> 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(), } }