git-next/crates/forge-github/src/lib.rs

119 lines
3 KiB
Rust
Raw Normal View History

//
#[cfg(test)]
mod tests;
mod commit;
mod webhook;
use crate as github;
use git::forge::commit::Status;
use git_next_config as config;
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<dyn git::ForgeLike> {
Box::new(self.clone())
}
fn name(&self) -> String {
"github".to_string()
}
fn is_message_authorised(
&self,
msg: &config::ForgeNotification,
webhook_auth: &config::WebhookAuth,
) -> bool {
github::webhook::is_authorised(msg, webhook_auth)
}
fn should_ignore_message(&self, message: &config::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: &config::webhook::forge_notification::Body,
) -> git::forge::webhook::Result<config::webhook::push::Push> {
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: &config::server::WebhookUrl,
) -> git::forge::webhook::Result<Vec<config::WebhookId>> {
github::webhook::list(self, webhook_url).await
}
async fn unregister_webhook(
&self,
webhook_id: &config::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: &config::server::WebhookUrl,
) -> git::forge::webhook::Result<config::RegisteredWebhook> {
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) -> config::WebhookId {
config::WebhookId::new(format!("{}", self.id))
}
pub fn url(&self) -> config::server::WebhookUrl {
config::server::WebhookUrl::new(self.config.url.clone())
}
}
#[derive(Debug, serde::Deserialize)]
struct Config {
pub url: String,
}