From 6d7f8233ef044ed742536f2ff567b06806a9e0bc Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Thu, 18 Jul 2024 20:51:47 +0100 Subject: [PATCH] WIP: notifications by webhook --- crates/config/src/server.rs | 65 +++++++++++++++++++ crates/config/src/tests.rs | 14 ++++ .../src/tests/receive_server_config.rs | 4 +- crates/server/server-default.toml | 4 ++ 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/crates/config/src/server.rs b/crates/config/src/server.rs index b042889..f0266ea 100644 --- a/crates/config/src/server.rs +++ b/crates/config/src/server.rs @@ -42,6 +42,7 @@ type Result = core::result::Result; pub struct ServerConfig { http: Http, webhook: Webhook, + notifications: Notification, storage: ServerStorage, pub forge: BTreeMap, } @@ -64,6 +65,10 @@ impl ServerConfig { &self.storage } + pub const fn notifications(&self) -> &Notification { + &self.notifications + } + pub const fn webhook(&self) -> &Webhook { &self.webhook } @@ -149,3 +154,63 @@ impl ServerStorage { self.path.as_path() } } + +/// Identifier for the type of Notification +#[derive( + Clone, + Default, + Debug, + derive_more::From, + PartialEq, + Eq, + PartialOrd, + Ord, + serde::Deserialize, + Copy, +)] +pub enum NotificationType { + #[default] + None, + Webhook, +} + +/// Defines the Webhook Forges should send updates to +/// Must be an address that is accessible from the remote forge +#[derive( + Clone, + Debug, + derive_more::From, + PartialEq, + Eq, + PartialOrd, + Ord, + derive_more::AsRef, + serde::Deserialize, +)] +pub struct Notification { + r#type: NotificationType, + webhook: Option, +} +impl Notification { + pub const fn none() -> Self { + Self { + r#type: NotificationType::None, + webhook: None, + } + } + pub const fn webhook(webhook: Webhook) -> Self { + Self { + r#type: NotificationType::Webhook, + webhook: Some(webhook), + } + } + + pub fn webhook_url(&self) -> Option { + self.webhook.clone().map(|x| x.url) + } +} +impl Default for Notification { + fn default() -> Self { + Self::none() + } +} diff --git a/crates/config/src/tests.rs b/crates/config/src/tests.rs index 16e337e..d0fd44d 100644 --- a/crates/config/src/tests.rs +++ b/crates/config/src/tests.rs @@ -470,6 +470,10 @@ mod server { let http_port = server_config.http()?.port(); let webhook_url = server_config.webhook().base_url(); let storage_path = server_config.storage().path(); + let notification_webhook_url = server_config + .notifications() + .webhook_url() + .unwrap_or_default(); let forge_alias = server_config .forges() .next() @@ -519,6 +523,10 @@ url = "{webhook_url}" [storage] path = {storage_path:?} +[notifications] +type = "Webhook" +webhook = {{ url = "{notification_webhook_url}" }} + [forge.{forge_alias}] forge_type = "{forge_type}" hostname = "{forge_hostname}" @@ -687,6 +695,8 @@ mod push { } mod given { + use crate::server::Notification; + use super::*; use rand::Rng as _; use std::{ @@ -710,6 +720,7 @@ mod given { ServerConfig::new( an_http(), a_webhook(), + a_notification_config(), a_server_storage(), some_forge_configs(), ) @@ -736,6 +747,9 @@ mod given { pub fn a_server_storage() -> ServerStorage { ServerStorage::new(a_name().into()) } + pub fn a_notification_config() -> Notification { + Notification::webhook(a_webhook()) + } pub fn some_forge_configs() -> BTreeMap { [(a_name(), a_forge_config())].into() } diff --git a/crates/server-actor/src/tests/receive_server_config.rs b/crates/server-actor/src/tests/receive_server_config.rs index a571988..986fc4a 100644 --- a/crates/server-actor/src/tests/receive_server_config.rs +++ b/crates/server-actor/src/tests/receive_server_config.rs @@ -1,7 +1,7 @@ // use crate::{tests::given, ReceiveServerConfig, Server}; use actix::prelude::*; -use git_next_config::server::{Http, ServerConfig, ServerStorage, Webhook}; +use git_next_config::server::{Http, Notification, ServerConfig, ServerStorage, Webhook}; use std::{ collections::BTreeMap, sync::{Arc, RwLock}, @@ -22,6 +22,7 @@ async fn when_webhook_url_has_trailing_slash_should_not_send() { // collaborators let http = Http::new("0.0.0.0".to_string(), 80); let webhook = Webhook::new("http://localhost/".to_string()); // With trailing slash + let notifications = Notification::none(); let server_storage = ServerStorage::new((fs.base()).to_path_buf()); let repos = BTreeMap::default(); @@ -35,6 +36,7 @@ async fn when_webhook_url_has_trailing_slash_should_not_send() { .do_send(ReceiveServerConfig::new(ServerConfig::new( http, webhook, + notifications, server_storage, repos, ))); diff --git a/crates/server/server-default.toml b/crates/server/server-default.toml index 2e87e42..eedef5e 100644 --- a/crates/server/server-default.toml +++ b/crates/server/server-default.toml @@ -8,6 +8,10 @@ url = "https://localhost:8080" # don't include any query path or a trailing slas [storage] path = "./data" +[notifications] +type = "WebHook" +webhook = { url = "https://localhost:9090" } + [forge] [forge.default]