// use crate::{self as github, webhook}; use git_next_core::{git, server::RepoListenUrl, RegisteredWebhook, WebhookAuth, WebhookId}; use kxio::network; // https://docs.github.com/en/rest/repos/webhooks?apiVersion=2022-11-28#create-a-repository-webhook pub async fn register( github: &github::Github, repo_listen_url: &RepoListenUrl, ) -> git::forge::webhook::Result { let repo_details = &github.repo_details; if repo_details.repo_config.is_none() { return Err(git::forge::webhook::Error::NoRepoConfig); }; // remove any lingering webhooks for the same URL let existing_webhook_ids = webhook::list(github, repo_listen_url).await?; for webhook_id in existing_webhook_ids { webhook::unregister(github, &webhook_id).await?; } let net = &github.net; let hostname = repo_details.forge.hostname(); let authorisation = WebhookAuth::generate(); let request = network::NetRequest::new( network::RequestMethod::Post, network::NetUrl::new(format!( "https://api.{hostname}/repos/{}/hooks", repo_details.repo_path )), github::webhook::headers(repo_details.forge.token()), network::RequestBody::Json(network::json!({ "name": "web", "active": true, "events": ["push"], "config": { "url": repo_listen_url.as_ref(), "content_type": "json", "secret": authorisation.to_string(), "insecure_ssl": "0", } })), network::ResponseType::Json, None, network::NetRequestLogging::None, ); let result = net.post_json::(request).await; match result { Ok(response) => { let Some(hook) = response.response_body() else { #[cfg(not(tarpaulin_include))] // request response is Json so response_body never returns None return Err(git::forge::webhook::Error::NetworkResponseEmpty); }; tracing::info!(webhook_id = %hook.id, "Webhook registered"); Ok(RegisteredWebhook::new( WebhookId::new(format!("{}", hook.id)), authorisation, )) } Err(e) => { tracing::warn!("Failed to register webhook"); Err(git::forge::webhook::Error::FailedToRegister(e.to_string())) } } }