started gitea api impl

This commit is contained in:
2026-06-02 19:52:50 +00:00
parent 1f60f6572f
commit 10ebee389e
6 changed files with 91 additions and 21 deletions
+14 -4
View File
@@ -1,9 +1,10 @@
use axum::body::{Bytes, to_bytes}; use axum::body::{Bytes, to_bytes};
use axum::extract::{FromRef, FromRequest}; use axum::extract::{FromRef, FromRequest, State};
use axum::response::{IntoResponse, Response}; use axum::response::IntoResponse;
use axum::routing::{get, post}; use axum::routing::{get, post};
use axum::{Json, Router}; use axum::{Json, Router};
use hmac::{Hmac, KeyInit, Mac}; use hmac::{Hmac, KeyInit, Mac};
use reqwest::StatusCode;
use serde_json::Value; use serde_json::Value;
use sha2::Sha256; use sha2::Sha256;
use subtle::ConstantTimeEq; use subtle::ConstantTimeEq;
@@ -31,8 +32,17 @@ async fn root() -> &'static str {
"Hi, i'm Herald :)" "Hi, i'm Herald :)"
} }
async fn webhook(WebhookExtract(wb): WebhookExtract) -> Result<Response, AppError> { async fn webhook(
Ok("lol".into_response()) State(app_state): State<AppState>,
WebhookExtract(wb): WebhookExtract,
) -> Result<impl IntoResponse, AppError> {
app_state
.bot_tx
.send(wb)
.await
.map_err(anyhow::Error::from)?;
Ok((StatusCode::CREATED, "Task started"))
} }
pub struct WebhookExtract(pub WebhookType); pub struct WebhookExtract(pub WebhookType);
+36 -3
View File
@@ -1,13 +1,46 @@
use crate::{env::EnvConfig, gitea::WebhookType}; use crate::{
env::EnvConfig,
errors::AppError,
gitea::{GiteaAPI, ReviewPayload, WebhookType},
};
pub struct Bot { pub struct Bot {
config: EnvConfig, config: EnvConfig,
gitea_api: GiteaAPI,
} }
impl Bot { impl Bot {
pub fn new(config: EnvConfig) -> Self { 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<WebhookType>,
) -> 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(())
}
} }
+3
View File
@@ -7,6 +7,7 @@ pub struct EnvConfig {
pub webhook_secret: String, pub webhook_secret: String,
pub open_router_api_key: String, pub open_router_api_key: String,
pub bot_name: String, pub bot_name: String,
pub gitea_url: String,
} }
pub fn load_config() -> anyhow::Result<EnvConfig> { pub fn load_config() -> anyhow::Result<EnvConfig> {
@@ -16,12 +17,14 @@ pub fn load_config() -> anyhow::Result<EnvConfig> {
let bot_name = try_get_env("BOT_NAME")?; let bot_name = try_get_env("BOT_NAME")?;
let webhook_secret = try_get_env("WEBHOOK_SIG_HEADER_SECRET")?; let webhook_secret = try_get_env("WEBHOOK_SIG_HEADER_SECRET")?;
let open_router_api_key = try_get_env("OPEN_ROUTER_API_KEY")?; let open_router_api_key = try_get_env("OPEN_ROUTER_API_KEY")?;
let gitea_url = try_get_env("GITEA_URL")?;
Ok(EnvConfig { Ok(EnvConfig {
http_port, http_port,
webhook_secret, webhook_secret,
bot_name, bot_name,
open_router_api_key, open_router_api_key,
gitea_url,
}) })
} }
+26
View File
@@ -3,6 +3,26 @@ use serde_json::Value;
use crate::errors::AppError; 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<u64> {
Ok(1)
}
pub async fn edit_comment(&self, full_name: &str, id: u64) -> anyhow::Result<()> {
Ok(())
}
}
#[derive(Debug)] #[derive(Debug)]
pub enum WebhookType { pub enum WebhookType {
Review(ReviewPayload), Review(ReviewPayload),
@@ -12,6 +32,7 @@ pub enum WebhookType {
pub struct ReviewPayload { pub struct ReviewPayload {
pub action: String, pub action: String,
pub pull_request: PullRequest, pub pull_request: PullRequest,
pub repository: Repository,
pub comment: Comment, pub comment: Comment,
} }
@@ -33,6 +54,11 @@ pub struct User {
pub id: u64, pub id: u64,
} }
#[derive(Deserialize, Debug)]
pub struct Repository {
pub full_name: String,
}
impl WebhookType { impl WebhookType {
pub fn from_event(event: &str, bot_name: &str, json: Value) -> Result<Self, AppError> { pub fn from_event(event: &str, bot_name: &str, json: Value) -> Result<Self, AppError> {
let wb = match event { let wb = match event {
+10 -9
View File
@@ -1,8 +1,4 @@
use std::sync::Arc; use crate::{bot::Bot, gitea::WebhookType, state::AppState};
use tokio::sync::Mutex;
use crate::{bot::Bot, state::AppState};
mod api; mod api;
mod bot; mod bot;
@@ -15,11 +11,16 @@ mod state;
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {
let config = env::load_config()?; let config = env::load_config()?;
let bot = Bot::new(config.clone());
let (tx, rx) = tokio::sync::mpsc::channel::<WebhookType>(1);
let app_state = AppState { let app_state = AppState {
bot: Arc::new(Mutex::new(Bot::new(config.clone()))), bot_tx: tx,
config: config, config,
}; };
api::start(app_state).await tokio::try_join!(bot.start(rx), api::start(app_state))?;
}
Ok(())
}
+2 -5
View File
@@ -1,10 +1,7 @@
use std::sync::Arc; use crate::{env::EnvConfig, gitea::WebhookType};
use tokio::sync::Mutex;
use crate::{bot::Bot, env::EnvConfig};
#[derive(Clone)] #[derive(Clone)]
pub struct AppState { pub struct AppState {
pub bot: Arc<Mutex<Bot>>, pub bot_tx: tokio::sync::mpsc::Sender<WebhookType>,
pub config: EnvConfig, pub config: EnvConfig,
} }