Răsfoiți Sursa

Notify Zulip when issue is closed or reopened

This adds optional `message_on_close` and `message_on_reopen` fields to
`triagebot.toml` to notify the Zulip topic when the issue is closed or
reopened.

Inspired by [this comment] by Ryan Levick.

[this comment]: https://rust-lang.zulipchat.com/#narrow/stream/245100-t-compiler.2Fwg-prioritization.2Falerts/topic/.2380375.20ICE.3A.20compiler.2Frustc_middle.2Fsrc.2Fty.2Fsubst.2Ers.3A568.3A17.3A.20c.E2.80.A6/near/221205328
Camelid 4 ani în urmă
părinte
comite
e9ddd628b2
2 a modificat fișierele cu 46 adăugiri și 26 ștergeri
  1. 2 0
      src/config.rs
  2. 44 26
      src/handlers/notify_zulip.rs

+ 2 - 0
src/config.rs

@@ -123,6 +123,8 @@ pub(crate) struct NotifyZulipLabelConfig {
     pub(crate) topic: String,
     pub(crate) message_on_add: Option<String>,
     pub(crate) message_on_remove: Option<String>,
+    pub(crate) message_on_close: Option<String>,
+    pub(crate) message_on_reopen: Option<String>,
     #[serde(default)]
     pub(crate) required_labels: Vec<String>,
 }

+ 44 - 26
src/handlers/notify_zulip.rs

@@ -11,6 +11,8 @@ pub(super) struct NotifyZulipInput {
 pub(super) enum NotificationType {
     Labeled,
     Unlabeled,
+    Closed,
+    Reopened,
 }
 
 pub(super) fn parse_input(
@@ -18,40 +20,54 @@ pub(super) fn parse_input(
     event: &IssuesEvent,
     config: Option<&NotifyZulipConfig>,
 ) -> Result<Option<NotifyZulipInput>, String> {
-    if let IssuesAction::Labeled | IssuesAction::Unlabeled = event.action {
-        let applied_label = &event.label.as_ref().expect("label").name;
-        if let Some(config) = config.and_then(|c| c.labels.get(applied_label)) {
-            for label in &config.required_labels {
-                let pattern = match glob::Pattern::new(label) {
-                    Ok(pattern) => pattern,
-                    Err(err) => {
-                        log::error!("Invalid glob pattern: {}", err);
-                        continue;
-                    }
-                };
-                if !event
-                    .issue
-                    .labels()
-                    .iter()
-                    .any(|l| pattern.matches(&l.name))
-                {
-                    // Issue misses a required label, ignore this event
-                    return Ok(None);
+    let applied_label = &event.label.as_ref().expect("label").name;
+
+    if let Some(config) = config.and_then(|c| c.labels.get(applied_label)) {
+        for label in &config.required_labels {
+            let pattern = match glob::Pattern::new(label) {
+                Ok(pattern) => pattern,
+                Err(err) => {
+                    log::error!("Invalid glob pattern: {}", err);
+                    continue;
                 }
+            };
+            if !event
+                .issue
+                .labels()
+                .iter()
+                .any(|l| pattern.matches(&l.name))
+            {
+                // Issue misses a required label, ignore this event
+                return Ok(None);
             }
+        }
 
-            if event.action == IssuesAction::Labeled && config.message_on_add.is_some() {
-                return Ok(Some(NotifyZulipInput {
+        match event.action {
+            IssuesAction::Labeled if config.message_on_add.is_some() => {
+                Ok(Some(NotifyZulipInput {
                     notification_type: NotificationType::Labeled,
-                }));
-            } else if config.message_on_remove.is_some() {
-                return Ok(Some(NotifyZulipInput {
+                }))
+            }
+            IssuesAction::Unlabeled if config.message_on_remove.is_some() => {
+                Ok(Some(NotifyZulipInput {
                     notification_type: NotificationType::Unlabeled,
-                }));
+                }))
+            }
+            IssuesAction::Closed if config.message_on_close.is_some() => {
+                Ok(Some(NotifyZulipInput {
+                    notification_type: NotificationType::Closed,
+                }))
+            }
+            IssuesAction::Reopened if config.message_on_reopen.is_some() => {
+                Ok(Some(NotifyZulipInput {
+                    notification_type: NotificationType::Reopened,
+                }))
             }
+            _ => Ok(None),
         }
+    } else {
+        Ok(None)
     }
-    Ok(None)
 }
 
 pub(super) async fn handle_input<'a>(
@@ -78,6 +94,8 @@ pub(super) async fn handle_input<'a>(
     let mut msg = match input.notification_type {
         NotificationType::Labeled => config.message_on_add.as_ref().unwrap().clone(),
         NotificationType::Unlabeled => config.message_on_remove.as_ref().unwrap().clone(),
+        NotificationType::Closed => config.message_on_close.as_ref().unwrap().clone(),
+        NotificationType::Reopened => config.message_on_reopen.as_ref().unwrap().clone(),
     };
 
     msg = msg.replace("{number}", &event.issue.number.to_string());