// #[cfg(test)] mod tests; mod commit; mod webhook; use crate as github; use git::forge::commit::Status; use git_next_core::{ self as core, server, ForgeNotification, RegisteredWebhook, WebhookAuth, WebhookId, }; use git_next_git as git; use derive_more::Constructor; #[derive(Clone, Debug, Constructor)] pub struct Github { repo_details: git::RepoDetails, net: kxio::network::Network, } #[async_trait::async_trait] impl git::ForgeLike for Github { fn duplicate(&self) -> Box { Box::new(self.clone()) } fn name(&self) -> String { "github".to_string() } fn is_message_authorised(&self, msg: &ForgeNotification, webhook_auth: &WebhookAuth) -> bool { github::webhook::is_authorised(msg, webhook_auth) } fn should_ignore_message(&self, message: &ForgeNotification) -> bool { let Some(event) = message.header("x-github-event") else { return false; }; if event == "ping" { tracing::info!("successfull ping received"); return true; } tracing::info!(%event, "message"); false } fn parse_webhook_body( &self, body: &core::webhook::forge_notification::Body, ) -> git::forge::webhook::Result { github::webhook::parse_body(body) } async fn commit_status(&self, commit: &git::Commit) -> Status { github::commit::status(self, commit).await } async fn list_webhooks( &self, webhook_url: &server::WebhookUrl, ) -> git::forge::webhook::Result> { github::webhook::list(self, webhook_url).await } async fn unregister_webhook(&self, webhook_id: &WebhookId) -> git::forge::webhook::Result<()> { github::webhook::unregister(self, webhook_id).await } // https://docs.github.com/en/rest/repos/webhooks?apiVersion=2022-11-28#create-a-repository-webhook async fn register_webhook( &self, webhook_url: &server::WebhookUrl, ) -> git::forge::webhook::Result { github::webhook::register(self, webhook_url).await } } #[derive(Debug, serde::Deserialize, serde::Serialize)] struct GithubStatus { pub state: GithubState, // other fields that we ignore } #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] enum GithubState { #[serde(rename = "success")] Success, #[serde(rename = "pending")] Pending, #[serde(rename = "failure")] Failure, #[serde(rename = "error")] Error, #[serde(rename = "")] Blank, } #[derive(Debug, serde::Deserialize)] struct GithubHook { id: u64, config: Config, } impl GithubHook { pub fn id(&self) -> WebhookId { WebhookId::new(format!("{}", self.id)) } pub fn url(&self) -> server::WebhookUrl { server::WebhookUrl::new(self.config.url.clone()) } } #[derive(Debug, serde::Deserialize)] struct Config { pub url: String, }