Multi-channel events with per-repository rules and severities #10

Closed
opened 2026-10-25 20:40:28 +00:00 by Gilles · 0 comments
Owner

Per-repository rules that raise events with a severity (alert, warning, info) and deliver them over one or more channels. Every raised event is recorded and listed on a summary page, even when its rule has no channel enabled. New-report notifications are just one kind of info event (supersedes #11).

Rules (EventRule, per Project)

  • name, enabled, severity alert / warning / info (defaulted from the trigger, editable)
  • filters: report type (or any), ref kind + ref pattern (e.g. master, release/*, any PR)
  • trigger (+ JSON params), with its default severity:
    • status becomes fail → alert; becomes warn → warning
    • regression ok → fail → alert; recovery fail → ok → info
    • coverage below a threshold, or dropping by more than X points → warning
    • more than N failing tests → alert
    • report processing error → warning
    • new report processed → info
  • channels, each optional: web (in-app), desktop (Web Push), email, Mattermost, PR comment
  • recipients (web, desktop, email): Argus users chosen on the rule + free email addresses; any user with read level can also follow a rule for themselves
  • rules managed with the project write level

Events

  • Event (rule, severity, project, ref, type, triggering report/aggregate, message, date) + one EventDelivery per channel (sent / failed / skipped + error) + per-user read state for the web channel
  • de-duplication for state triggers: per (rule, ref, type) state, a failing event is raised once until recovery; "new report" fires every time, with optional grouping of a CI matrix (same commit, a few seconds apart)
  • state triggers evaluated at the end of recompute_aggregate (all variants combined), "new report" at the end of process_report; one Celery task per channel with retries

Channels

  • Web: bell in the header with the unread count (light polling GET /api/events/?unread=1), mark as read / mark all as read.
  • Desktop: Web Push (VAPID keys, pywebpush), PushSubscription per user/browser, POST /api/push/subscribe|unsubscribe, service worker in the SPA.
  • Email: EmailMultiAlternatives (HTML + text) through poulpinou (INSTALLED_APPS, migration, beat task, bump to 1.1.0).
  • Mattermost: bot account (MATTERMOST_URL, MATTERMOST_BOT_TOKEN via _secret). GET /api/mattermost/channels/ to pick the channel, posts via POST /api/v4/posts, attachment coloured by severity.
  • PR comment: only for ref_kind = pr (otherwise delivery skipped). Forgejo POST/PATCH issue comments with the service token; one comment per PR and rule, updated in place via a hidden marker <!-- argus-event:{rule_id} -->. Requires write:issue scope on FORGEJO_API_TOKEN.
  • Severity shown everywhere (icon/colour/subject prefix).

Richer upload metadata (argus/upload-action)

  • send the CI run URL and the actor with each upload; new optional fields in ReportUploadSerializer + Report; used in event messages.

API

  • CRUD /api/projects/<owner>/<repo>/event-rules/ (write), follow/unfollow (read), "test rule" action (sends without recording)
  • GET /api/projects/<owner>/<repo>/events/ and GET /api/events/ (read; filters: project, rule, severity, trigger, delivery state, period, unread; paginated)

Frontend (argus/frontend)

  • "Événements" tab in the project settings: rule list + form (trigger, severity, filters, channels, Mattermost channel picker, recipients)
  • summary pages /events and /:owner/:repo/events, filterable by severity, with per-channel delivery state
  • header bell + dropdown; user page to enable desktop notifications in the current browser

Tests

pytest (each trigger, default severities, de-duplication, grouping, each channel mocked, permissions, covers markers + features.catalog.yaml), vitest + msw (settings tab, summary page, bell), upload-action tests for the new fields, one e2e scenario (rule → failing report → event listed and in the bell).

Delivered as PRs on argus/backend, argus/frontend and argus/upload-action.

Per-repository rules that raise **events** with a **severity** (`alert`, `warning`, `info`) and deliver them over one or more channels. Every raised event is recorded and listed on a summary page, even when its rule has no channel enabled. New-report notifications are just one kind of `info` event (supersedes #11). ## Rules (`EventRule`, per `Project`) - name, `enabled`, **severity** `alert` / `warning` / `info` (defaulted from the trigger, editable) - filters: report type (or any), ref kind + ref pattern (e.g. `master`, `release/*`, any PR) - trigger (+ JSON params), with its default severity: - status becomes `fail` → alert; becomes `warn` → warning - regression ok → fail → alert; recovery fail → ok → info - coverage below a threshold, or dropping by more than X points → warning - more than N failing tests → alert - report processing error → warning - **new report processed** → info - channels, each optional: web (in-app), desktop (Web Push), email, Mattermost, PR comment - recipients (web, desktop, email): Argus users chosen on the rule + free email addresses; any user with **read** level can also follow a rule for themselves - rules managed with the project **write** level ## Events - `Event` (rule, severity, project, ref, type, triggering report/aggregate, message, date) + one `EventDelivery` per channel (`sent` / `failed` / `skipped` + error) + per-user read state for the web channel - de-duplication for state triggers: per (rule, ref, type) state, a failing event is raised once until recovery; "new report" fires every time, with optional grouping of a CI matrix (same commit, a few seconds apart) - state triggers evaluated at the end of `recompute_aggregate` (all variants combined), "new report" at the end of `process_report`; one Celery task per channel with retries ## Channels - **Web**: bell in the header with the unread count (light polling `GET /api/events/?unread=1`), mark as read / mark all as read. - **Desktop**: Web Push (VAPID keys, `pywebpush`), `PushSubscription` per user/browser, `POST /api/push/subscribe|unsubscribe`, service worker in the SPA. - **Email**: `EmailMultiAlternatives` (HTML + text) through poulpinou (`INSTALLED_APPS`, migration, beat task, bump to 1.1.0). - **Mattermost**: bot account (`MATTERMOST_URL`, `MATTERMOST_BOT_TOKEN` via `_secret`). `GET /api/mattermost/channels/` to pick the channel, posts via `POST /api/v4/posts`, attachment coloured by severity. - **PR comment**: only for `ref_kind = pr` (otherwise delivery `skipped`). Forgejo `POST/PATCH` issue comments with the service token; one comment per PR and rule, updated in place via a hidden marker `<!-- argus-event:{rule_id} -->`. Requires `write:issue` scope on `FORGEJO_API_TOKEN`. - Severity shown everywhere (icon/colour/subject prefix). ## Richer upload metadata (argus/upload-action) - send the CI run URL and the actor with each upload; new optional fields in `ReportUploadSerializer` + `Report`; used in event messages. ## API - `CRUD /api/projects/<owner>/<repo>/event-rules/` (write), follow/unfollow (read), "test rule" action (sends without recording) - `GET /api/projects/<owner>/<repo>/events/` and `GET /api/events/` (read; filters: project, rule, severity, trigger, delivery state, period, unread; paginated) ## Frontend (argus/frontend) - "Événements" tab in the project settings: rule list + form (trigger, severity, filters, channels, Mattermost channel picker, recipients) - summary pages `/events` and `/:owner/:repo/events`, filterable by severity, with per-channel delivery state - header bell + dropdown; user page to enable desktop notifications in the current browser ## Tests pytest (each trigger, default severities, de-duplication, grouping, each channel mocked, permissions, `covers` markers + `features.catalog.yaml`), vitest + msw (settings tab, summary page, bell), upload-action tests for the new fields, one e2e scenario (rule → failing report → event listed and in the bell). Delivered as PRs on argus/backend, argus/frontend and argus/upload-action.
Gilles changed title from Multi-channel alerts with per-repository rules to Multi-channel events with per-repository rules and severities 2026-10-25 20:46:05 +00:00
Sign in to join this conversation.
No description provided.