use crate::{self as github, webhook};
use git_next_core::{git, server::RepoListenUrl, RegisteredWebhook, WebhookAuth, WebhookId};
use serde_json::json;
pub async fn register(
github: &github::Github,
repo_listen_url: &RepoListenUrl,
) -> git::forge::webhook::Result<RegisteredWebhook> {
let repo_details = &github.repo_details;
if repo_details.repo_config.is_none() {
return Err(git::forge::webhook::Error::NoRepoConfig);
};
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();
match net
.post(format!(
"https://api.{hostname}/repos/{}/hooks",
repo_details.repo_path
))
.headers(github::webhook::headers(repo_details.forge.token()))
.body(
json!({
"name": "web",
"active": true,
"events": ["push"],
"config": {
"url": repo_listen_url.to_string(),
"content_type": "json",
"secret": authorisation.to_string(),
"insecure_ssl": "0",
}
})
.to_string(),
)
.send()
.await
{
Err(e) => {
tracing::warn!("Failed to register webhook");
Err(git::forge::webhook::Error::FailedToRegister(e.to_string()))
}
Ok(response) => {
match response.json::<github::GithubHook>().await {
Err(_) => {
#[cfg(not(tarpaulin_include))]
return Err(git::forge::webhook::Error::NetworkResponseEmpty);
}
Ok(hook) => {
tracing::info!(webhook_id = %hook.id, "Webhook registered");
Ok(RegisteredWebhook::new(
WebhookId::new(format!("{}", hook.id)),
authorisation,
))
}
}
}
}
}