git_next_forge_github/
lib.rs1#[cfg(test)]
3mod tests;
4
5mod commit;
6mod webhook;
7
8use crate as github;
9use git_next_core::{
10 self as core, git,
11 server::{self, RepoListenUrl},
12 ForgeNotification, RegisteredWebhook, WebhookAuth, WebhookId,
13};
14
15use derive_more::Constructor;
16
17#[derive(Clone, Debug, Constructor)]
18pub struct Github {
19 repo_details: git::RepoDetails,
20 net: kxio::net::Net,
21}
22#[async_trait::async_trait]
23impl git::ForgeLike for Github {
24 fn duplicate(&self) -> Box<dyn git::ForgeLike> {
25 Box::new(self.clone())
26 }
27 fn name(&self) -> String {
28 "github".to_string()
29 }
30
31 fn is_message_authorised(&self, msg: &ForgeNotification, webhook_auth: &WebhookAuth) -> bool {
32 github::webhook::is_authorised(msg, webhook_auth)
33 }
34
35 fn should_ignore_message(&self, message: &ForgeNotification) -> bool {
36 let Some(event) = message.header("x-github-event") else {
37 return false;
38 };
39 if event == "ping" {
40 tracing::info!("successfull ping received");
41 return true;
42 }
43 tracing::info!(%event, "message");
44 false
45 }
46
47 fn parse_webhook_body(
48 &self,
49 body: &core::webhook::forge_notification::Body,
50 ) -> git::forge::webhook::Result<core::webhook::push::Push> {
51 github::webhook::parse_body(body)
52 }
53
54 async fn commit_status(
55 &self,
56 commit: &git::Commit,
57 ) -> git::forge::webhook::Result<git::forge::commit::Status> {
58 github::commit::status(self, commit).await
59 }
60
61 async fn list_webhooks(
62 &self,
63 repo_listen_url: &RepoListenUrl,
64 ) -> git::forge::webhook::Result<Vec<WebhookId>> {
65 github::webhook::list(self, repo_listen_url).await
66 }
67
68 async fn unregister_webhook(&self, webhook_id: &WebhookId) -> git::forge::webhook::Result<()> {
69 github::webhook::unregister(self, webhook_id).await
70 }
71
72 async fn register_webhook(
74 &self,
75 repo_listen_url: &RepoListenUrl,
76 ) -> git::forge::webhook::Result<RegisteredWebhook> {
77 github::webhook::register(self, repo_listen_url).await
78 }
79}
80
81#[derive(Debug, serde::Deserialize, serde::Serialize)]
82struct GithubStatus {
83 pub state: GithubState,
84 }
86#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
87enum GithubState {
88 #[serde(rename = "success")]
89 Success,
90 #[serde(rename = "pending")]
91 Pending,
92 #[serde(rename = "failure")]
93 Failure,
94 #[serde(rename = "error")]
95 Error,
96 #[serde(rename = "")]
97 Blank,
98}
99
100#[derive(Debug, serde::Deserialize)]
101struct GithubHook {
102 id: u64,
103 config: Config,
104}
105impl GithubHook {
106 pub fn id(&self) -> WebhookId {
107 WebhookId::new(format!("{}", self.id))
108 }
109 pub fn url(&self) -> server::ListenUrl {
110 server::ListenUrl::new(self.config.url.clone())
111 }
112}
113#[derive(Debug, serde::Deserialize)]
114struct Config {
115 pub url: String,
116}