Skip to content

Add external alerting via Webhook, Slack, and PagerDuty notification adapters#230

Merged
thiagoesteves merged 6 commits into
mainfrom
thiagoesteves/add-notification
Jun 18, 2026
Merged

Add external alerting via Webhook, Slack, and PagerDuty notification adapters#230
thiagoesteves merged 6 commits into
mainfrom
thiagoesteves/add-notification

Conversation

@thiagoesteves

Copy link
Copy Markdown
Owner

Introduces a Foundation.Notifications subsystem that dispatches deployment lifecycle events to configured external channels. Delivery is fully async (Task.Supervisor) so no caller is ever blocked.

Three adapters are provided out of the box:

  • Foundation.Notifications.Webhook — generic HTTP POST with a JSON body
  • Foundation.Notifications.Slack — Slack Incoming Webhook with per-event
    mrkdwn formatting and emoji
  • Foundation.Notifications.PagerDuty — PagerDuty Events API v2 with automatic
    severity mapping per event type

Six events are instrumented across the system:

  • :crash_restart (Deployer.Monitor.Application)
  • :deployment_started (Deployer.Monitor.Application)
  • :deployment_complete (Deployer.HotUpgrade.Application)
  • :watchdog_threshold_exceeded (Sentinel.Watchdog)
  • :certificate_renewed (Foundation.Certificates.Manager)
  • :certificate_failed (Foundation.Certificates.Manager)

Channels are configured in deployex.yaml under a top-level notifications: list. Each entry specifies an adapter, a URL, an enabled flag, an event subscription list, and an optional adapter-specific options: map (e.g. routing_key for PagerDuty, username/icon_emoji for Slack).

Foundation.Application gains Foundation.Finch and Foundation.TaskSupervisor to support outgoing HTTP and async dispatch without depending on Deployer's supervision tree.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

…adapters

Introduces a Foundation.Notifications subsystem that dispatches deployment
lifecycle events to configured external channels. Delivery is fully async
(Task.Supervisor) so no caller is ever blocked.

Three adapters are provided out of the box:
- Foundation.Notifications.Webhook  — generic HTTP POST with a JSON body
- Foundation.Notifications.Slack    — Slack Incoming Webhook with per-event
                                      mrkdwn formatting and emoji
- Foundation.Notifications.PagerDuty — PagerDuty Events API v2 with automatic
                                       severity mapping per event type

Six events are instrumented across the system:
- :crash_restart              (Deployer.Monitor.Application)
- :deployment_started         (Deployer.Monitor.Application)
- :deployment_complete        (Deployer.HotUpgrade.Application)
- :watchdog_threshold_exceeded (Sentinel.Watchdog)
- :certificate_renewed        (Foundation.Certificates.Manager)
- :certificate_failed         (Foundation.Certificates.Manager)

Channels are configured in deployex.yaml under a top-level `notifications:`
list. Each entry specifies an adapter, a URL, an enabled flag, an event
subscription list, and an optional adapter-specific `options:` map (e.g.
routing_key for PagerDuty, username/icon_emoji for Slack).

Foundation.Application gains Foundation.Finch and Foundation.TaskSupervisor
to support outgoing HTTP and async dispatch without depending on Deployer's
supervision tree.
@thiagoesteves thiagoesteves self-assigned this Jun 18, 2026
@thiagoesteves thiagoesteves moved this to In Progress in DeployEx Project Jun 18, 2026
@thiagoesteves thiagoesteves linked an issue Jun 18, 2026 that may be closed by this pull request
Replaces the Task.Supervisor dispatch model with a proper OTP supervision
tree. Each entry in the notifications: YAML list now gets its own
Foundation.Notifications.Worker GenServer, managed by
Foundation.Notifications.Supervisor.

Key design changes:

- Foundation.Notifications.notify/2 broadcasts to a per-event PubSub topic
  ("deployex::notifications::<event>") instead of reading app env and
  spawning tasks on every call.

- Each Worker subscribes at init only to the topics matching its events
  list, so PubSub routing handles delivery without any filtering in
  handle_info. Disabled workers subscribe to nothing and are never invoked.

- Foundation.Notifications.topic/1 (was topic/0) takes the event atom and
  returns the corresponding topic string.

- Task.Supervisor removed from Foundation.Application; replaced by
  Foundation.Notifications.Supervisor.
@thiagoesteves thiagoesteves merged commit 577af85 into main Jun 18, 2026
3 checks passed
@thiagoesteves thiagoesteves deleted the thiagoesteves/add-notification branch June 18, 2026 22:13
@github-project-automation github-project-automation Bot moved this from In Progress to Done in DeployEx Project Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

External Alerting Integrations

1 participant