// use git_next_core::{server, RegisteredWebhook, WebhookAuth, WebhookId}; use git_next_git as git; use kxio::network; use tracing::{info, warn}; use crate::webhook; use crate::webhook::Hook; #[tracing::instrument(skip_all)] pub async fn register( repo_details: &git::RepoDetails, webhook_url: &server::WebhookUrl, net: &network::Network, ) -> git::forge::webhook::Result { let Some(repo_config) = repo_details.repo_config.clone() else { return Err(git::forge::webhook::Error::NoRepoConfig); }; // remove any lingering webhooks for the same URL let existing_webhook_ids = webhook::list(repo_details, webhook_url, net).await?; for webhook_id in existing_webhook_ids { webhook::unregister(&webhook_id, repo_details, net).await?; } let hostname = &repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; use secrecy::ExposeSecret; let token = repo_details.forge.token().expose_secret(); let url = network::NetUrl::new(format!( "https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}" )); let repo_alias = &repo_details.repo_alias; let headers = network::NetRequestHeaders::new().with("Content-Type", "application/json"); let authorisation = WebhookAuth::generate(); let body = network::json!({ "active": true, "authorization_header": authorisation.header_value(), "branch_filter": format!("{{{},{},{}}}", repo_config.branches().main(), repo_config.branches().next(), repo_config.branches().dev()), "config": { "content_type": "json", "url": format!("{}/{}", webhook_url.as_ref(), repo_alias), }, "events": [ "push" ], "type": "forgejo" }); let request = network::NetRequest::new( network::RequestMethod::Post, url, headers, network::RequestBody::Json(body), 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); }; info!(webhook_id = %hook.id, "Webhook registered"); Ok(RegisteredWebhook::new( WebhookId::new(format!("{}", hook.id)), authorisation, )) } Err(e) => { warn!("Failed to register webhook"); Err(git::forge::webhook::Error::FailedToRegister(e.to_string())) } } }