Commit d46f0f4e93a6
Changed files (7)
dots
config
github-notif-manager
tools
github-notif-manager
dots/config/github-notif-manager/config.yaml
@@ -64,7 +64,7 @@ rules:
filters:
repository: "openshift-pipelines/operator"
reason: "review_requested"
- action: mark_done
+ action: done
enabled: true
# ─── KEEP remaining review requests ───────────────────────────────────
@@ -82,14 +82,14 @@ rules:
- name: "Archive CI activity"
filters:
reason: "ci_activity"
- action: mark_done
+ action: done
enabled: true
# State changes (PR merged/closed) — stale fast
- name: "Archive state changes"
filters:
reason: "state_change"
- action: mark_done
+ action: done
enabled: false
# Old read notifications — general cleanup
@@ -98,5 +98,5 @@ rules:
filters:
unread: false
age_days: 7
- action: mark_done
+ action: done
enabled: true
tools/github-notif-manager/src/actions.rs
@@ -61,8 +61,7 @@ impl<'a> ActionExecutor<'a> {
// Execute the actual action
let exec_result = match action {
- Action::MarkRead => self.client.mark_thread_read(¬ification.id),
- Action::MarkDone => self.client.mark_thread_done(¬ification.id),
+ Action::Done => self.client.mark_thread_done(¬ification.id),
Action::Skip => Ok(()), // Already handled above
};
tools/github-notif-manager/src/cache.rs
@@ -93,11 +93,6 @@ impl Cache {
self.done_ids.insert(notification_id.to_string());
}
- /// Remove a notification from cache (for mark_read — keep in cache but update)
- pub fn remove(&mut self, notification_id: &str) {
- self.notifications.retain(|n| n.id != notification_id);
- }
-
/// Get the `since` parameter for incremental fetching
pub fn since_param(&self) -> Option<String> {
self.last_fetched.map(|dt| dt.to_rfc3339())
tools/github-notif-manager/src/config.rs
@@ -26,8 +26,7 @@ fn default_enabled() -> bool {
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum Action {
- MarkRead,
- MarkDone,
+ Done,
Skip,
}
@@ -120,8 +119,7 @@ impl Config {
impl std::fmt::Display for Action {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
- Action::MarkRead => write!(f, "mark_read"),
- Action::MarkDone => write!(f, "mark_done"),
+ Action::Done => write!(f, "done"),
Action::Skip => write!(f, "skip"),
}
}
tools/github-notif-manager/src/github.rs
@@ -131,26 +131,6 @@ impl GitHubClient {
Ok(notifications)
}
- /// Mark a notification thread as read
- pub fn mark_thread_read(&self, thread_id: &str) -> Result<()> {
- let url = format!("https://api.github.com/notifications/threads/{}", thread_id);
-
- let response = self
- .client
- .patch(&url)
- .header("Authorization", format!("Bearer {}", self.token))
- .header("Accept", "application/vnd.github+json")
- .header("X-GitHub-Api-Version", "2022-11-28")
- .send()
- .context("Failed to mark thread as read")?;
-
- if response.status().as_u16() != 205 {
- anyhow::bail!("Failed to mark thread as read: {}", response.status());
- }
-
- Ok(())
- }
-
/// Mark a notification thread as done (archive it)
pub fn mark_thread_done(&self, thread_id: &str) -> Result<()> {
let url = format!("https://api.github.com/notifications/threads/{}", thread_id);
tools/github-notif-manager/src/main.rs
@@ -276,7 +276,7 @@ fn cmd_process(
if !dry_run {
let done_ids: Vec<String> = results
.iter()
- .filter(|r| matches!(r.action, Action::MarkDone) && r.success)
+ .filter(|r| matches!(r.action, Action::Done) && r.success)
.map(|r| r.notification_id.clone())
.collect();
for id in &done_ids {
@@ -288,28 +288,11 @@ fn cmd_process(
cache.save(&cp)?;
// Calculate statistics
- let mut stats = std::collections::HashMap::new();
- for action in &[Action::MarkRead, Action::MarkDone, Action::Skip] {
- stats.insert(
- action.to_string(),
- (
- results
- .iter()
- .filter(|r| &r.action == action && r.success)
- .count(),
- results
- .iter()
- .filter(|r| &r.action == action && !r.success)
- .count(),
- ),
- );
- }
+ let done_ok = results.iter().filter(|r| r.action == Action::Done && r.success).count();
+ let done_fail = results.iter().filter(|r| r.action == Action::Done && !r.success).count();
+ let skip_ok = results.iter().filter(|r| r.action == Action::Skip).count();
let no_match = total_notifications - results.len();
- let (done_ok, done_fail) = stats.get("mark_done").unwrap_or(&(0, 0));
- let (read_ok, read_fail) = stats.get("mark_read").unwrap_or(&(0, 0));
- let (skip_ok, _) = stats.get("skip").unwrap_or(&(0, 0));
-
if tty {
// Display results table
let visible_results: Vec<_> = results
@@ -333,8 +316,7 @@ fn cmd_process(
for result in &visible_results {
let (action_str, action_color) = match result.action {
- Action::MarkDone => ("done", Color::Yellow),
- Action::MarkRead => ("read", Color::Blue),
+ Action::Done => ("done", Color::Yellow),
Action::Skip => ("skip", Color::DarkGrey),
};
@@ -368,17 +350,12 @@ fn cmd_process(
]);
summary.add_row(vec![
- Cell::new("Mark as Done"),
+ Cell::new("Done"),
Cell::new(done_ok).set_alignment(CellAlignment::Right),
Cell::new(done_fail).set_alignment(CellAlignment::Right),
]);
summary.add_row(vec![
- Cell::new("Mark as Read"),
- Cell::new(read_ok).set_alignment(CellAlignment::Right),
- Cell::new(read_fail).set_alignment(CellAlignment::Right),
- ]);
- summary.add_row(vec![
- Cell::new("Skipped (kept)"),
+ Cell::new("Skipped"),
Cell::new(skip_ok).set_alignment(CellAlignment::Right),
Cell::new("-").set_alignment(CellAlignment::Right),
]);
@@ -396,8 +373,8 @@ fn cmd_process(
} else {
// Non-TTY: simple log-style output
println!(
- "done={} read={} skipped={} no_match={} done_failed={} read_failed={}",
- done_ok, read_ok, skip_ok, no_match, done_fail, read_fail
+ "done={} skipped={} no_match={} failed={}",
+ done_ok, skip_ok, no_match, done_fail
);
if dry_run {
println!("mode=dry-run");
tools/github-notif-manager/config.example.yaml
@@ -10,15 +10,15 @@ rules:
filters:
repository: "owner/repo" # Exact match or pattern with *
reason: "subscribed" # Notification reason (see GitHub API docs)
- action: mark_done # mark_read, mark_done, or skip
+ action: done # done or skip
enabled: true
- # Example: Mark CI/CD notifications as read
- - name: "Auto-read CI notifications"
- description: "Mark check suite notifications as read"
+ # Example: Archive CI/CD notifications
+ - name: "Archive CI notifications"
+ description: "Archive check suite notifications"
filters:
subject_type: "CheckSuite" # Release, Issue, PullRequest, CheckSuite, etc.
- action: mark_read
+ action: done
enabled: true
# Example: Archive notifications from specific repos
@@ -26,7 +26,7 @@ rules:
description: "Auto-archive notifications from archived repositories"
filters:
repository: "owner/archived-*" # Supports wildcard patterns
- action: mark_done
+ action: done
enabled: true
# Example: Archive old read notifications
@@ -35,7 +35,7 @@ rules:
filters:
unread: false
age_days: 7 # Older than N days
- action: mark_done
+ action: done
enabled: true
# Example: Skip notifications from important repos (no action)
@@ -56,6 +56,5 @@ rules:
# - updated_after: ISO date string (YYYY-MM-DD)
# Available actions:
-# - mark_read: Mark notification as read (but keep in inbox)
-# - mark_done: Mark notification as done (archive it)
+# - done: Mark notification as done/archived (removes from inbox)
# - skip: Don't process this notification (useful for exclusions)