Paul Campbell
067296ffab
Some checks are pending
Rust / build (push) Successful in 1m21s
Release Please / Release-plz (push) Waiting to run
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
74 lines
2.6 KiB
Rust
74 lines
2.6 KiB
Rust
//
|
|
use git_next_core::{git, server::RepoListenUrl, RegisteredWebhook, WebhookAuth, WebhookId};
|
|
|
|
use kxio::network;
|
|
use secrecy::ExposeSecret as _;
|
|
use tracing::{info, instrument, warn};
|
|
|
|
use crate::webhook;
|
|
use crate::webhook::Hook;
|
|
|
|
#[instrument(skip_all)]
|
|
pub async fn register(
|
|
repo_details: &git::RepoDetails,
|
|
repo_listen_url: &RepoListenUrl,
|
|
net: &network::Network,
|
|
) -> git::forge::webhook::Result<RegisteredWebhook> {
|
|
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, repo_listen_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;
|
|
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 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": repo_listen_url.to_string(),
|
|
},
|
|
"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::<Hook>(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()))
|
|
}
|
|
}
|
|
}
|