From 10ebee389e1625febb340de3c7d4b78dd90bf201 Mon Sep 17 00:00:00 2001 From: qpismont Date: Tue, 2 Jun 2026 19:52:50 +0000 Subject: [PATCH] started gitea api impl --- src/api.rs | 18 ++++++++++++++---- src/bot.rs | 39 ++++++++++++++++++++++++++++++++++++--- src/env.rs | 3 +++ src/gitea.rs | 26 ++++++++++++++++++++++++++ src/main.rs | 19 ++++++++++--------- src/state.rs | 7 ++----- 6 files changed, 91 insertions(+), 21 deletions(-) diff --git a/src/api.rs b/src/api.rs index a62d234..e98f736 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,9 +1,10 @@ use axum::body::{Bytes, to_bytes}; -use axum::extract::{FromRef, FromRequest}; -use axum::response::{IntoResponse, Response}; +use axum::extract::{FromRef, FromRequest, State}; +use axum::response::IntoResponse; use axum::routing::{get, post}; use axum::{Json, Router}; use hmac::{Hmac, KeyInit, Mac}; +use reqwest::StatusCode; use serde_json::Value; use sha2::Sha256; use subtle::ConstantTimeEq; @@ -31,8 +32,17 @@ async fn root() -> &'static str { "Hi, i'm Herald :)" } -async fn webhook(WebhookExtract(wb): WebhookExtract) -> Result { - Ok("lol".into_response()) +async fn webhook( + State(app_state): State, + WebhookExtract(wb): WebhookExtract, +) -> Result { + app_state + .bot_tx + .send(wb) + .await + .map_err(anyhow::Error::from)?; + + Ok((StatusCode::CREATED, "Task started")) } pub struct WebhookExtract(pub WebhookType); diff --git a/src/bot.rs b/src/bot.rs index 6e9ed0f..cccdd35 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -1,13 +1,46 @@ -use crate::{env::EnvConfig, gitea::WebhookType}; +use crate::{ + env::EnvConfig, + errors::AppError, + gitea::{GiteaAPI, ReviewPayload, WebhookType}, +}; pub struct Bot { config: EnvConfig, + gitea_api: GiteaAPI, } impl Bot { pub fn new(config: EnvConfig) -> Self { - Self { config } + Self { + gitea_api: GiteaAPI::new(&config.gitea_url), + config, + } } - pub async fn exec(&self, webhook: WebhookType) {} + pub async fn start( + &self, + mut rx: tokio::sync::mpsc::Receiver, + ) -> anyhow::Result<()> { + while let Some(wb) = rx.recv().await { + self.exec(wb).await; + } + + Ok(()) + } + + pub async fn exec(&self, webhook: WebhookType) { + let exec_result = match webhook { + WebhookType::Review(review_payload) => self.exec_review(review_payload), + } + .await; + + match exec_result { + Ok(_) => println!("Task completed"), + Err(_) => println!("Task errored"), + } + } + + pub async fn exec_review(&self, review_payload: ReviewPayload) -> Result<(), AppError> { + Ok(()) + } } diff --git a/src/env.rs b/src/env.rs index e4a8d1a..9be6803 100644 --- a/src/env.rs +++ b/src/env.rs @@ -7,6 +7,7 @@ pub struct EnvConfig { pub webhook_secret: String, pub open_router_api_key: String, pub bot_name: String, + pub gitea_url: String, } pub fn load_config() -> anyhow::Result { @@ -16,12 +17,14 @@ pub fn load_config() -> anyhow::Result { let bot_name = try_get_env("BOT_NAME")?; let webhook_secret = try_get_env("WEBHOOK_SIG_HEADER_SECRET")?; let open_router_api_key = try_get_env("OPEN_ROUTER_API_KEY")?; + let gitea_url = try_get_env("GITEA_URL")?; Ok(EnvConfig { http_port, webhook_secret, bot_name, open_router_api_key, + gitea_url, }) } diff --git a/src/gitea.rs b/src/gitea.rs index b5ab824..4e716df 100644 --- a/src/gitea.rs +++ b/src/gitea.rs @@ -3,6 +3,26 @@ use serde_json::Value; use crate::errors::AppError; +pub struct GiteaAPI { + base_url: String, +} + +impl GiteaAPI { + pub fn new(base_url: &str) -> Self { + Self { + base_url: String::from(base_url), + } + } + + pub async fn comment(&self, full_name: &str, index: u64) -> anyhow::Result { + Ok(1) + } + + pub async fn edit_comment(&self, full_name: &str, id: u64) -> anyhow::Result<()> { + Ok(()) + } +} + #[derive(Debug)] pub enum WebhookType { Review(ReviewPayload), @@ -12,6 +32,7 @@ pub enum WebhookType { pub struct ReviewPayload { pub action: String, pub pull_request: PullRequest, + pub repository: Repository, pub comment: Comment, } @@ -33,6 +54,11 @@ pub struct User { pub id: u64, } +#[derive(Deserialize, Debug)] +pub struct Repository { + pub full_name: String, +} + impl WebhookType { pub fn from_event(event: &str, bot_name: &str, json: Value) -> Result { let wb = match event { diff --git a/src/main.rs b/src/main.rs index 83830ed..00b02c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,4 @@ -use std::sync::Arc; - -use tokio::sync::Mutex; - -use crate::{bot::Bot, state::AppState}; +use crate::{bot::Bot, gitea::WebhookType, state::AppState}; mod api; mod bot; @@ -15,11 +11,16 @@ mod state; #[tokio::main] async fn main() -> anyhow::Result<()> { let config = env::load_config()?; + let bot = Bot::new(config.clone()); + + let (tx, rx) = tokio::sync::mpsc::channel::(1); let app_state = AppState { - bot: Arc::new(Mutex::new(Bot::new(config.clone()))), - config: config, + bot_tx: tx, + config, }; - api::start(app_state).await -} + tokio::try_join!(bot.start(rx), api::start(app_state))?; + + Ok(()) +} \ No newline at end of file diff --git a/src/state.rs b/src/state.rs index 28c3bfe..4b9cc02 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,10 +1,7 @@ -use std::sync::Arc; -use tokio::sync::Mutex; - -use crate::{bot::Bot, env::EnvConfig}; +use crate::{env::EnvConfig, gitea::WebhookType}; #[derive(Clone)] pub struct AppState { - pub bot: Arc>, + pub bot_tx: tokio::sync::mpsc::Sender, pub config: EnvConfig, }