Skip to Content
CLINotifications

Notifications

sfdt can push deployment events and org-health snapshots to Slack, Microsoft Teams, Google Chat, email, a generic webhook, or Grafana Loki — with per-channel event filtering and severity routing.

The multi-channel channels[] system is gated by notifications.enabled. The older single-Slack shape (notifications.slack.webhookUrl) is still honored when features.notifications: true. See Configuration.

Configuration

{ "features": { "notifications": true }, "notifications": { "enabled": true, "summary": { "enabled": false }, "channels": [ { "type": "slack", "name": "team-deploys", "webhookUrlEnv": "SLACK_WEBHOOK_URL", "severityThreshold": "warn", "events": ["deploy-failure", "snapshot"] }, { "type": "teams", "name": "ops", "webhookUrlEnv": "TEAMS_WEBHOOK_URL", "severityThreshold": "fail", "events": ["snapshot"] }, { "type": "googlechat", "name": "gchat-ops", "webhookUrlEnv": "GCHAT_WEBHOOK_URL", "severityThreshold": "warn", "events": ["deploy-failure", "snapshot"] }, { "type": "email", "name": "admins", "from": "ci@example.com", "to": ["admin@example.com"], "smtp": { "hostEnv": "SFDT_SMTP_HOST", "portEnv": "SFDT_SMTP_PORT", "userEnv": "SFDT_SMTP_USER", "passwordEnv": "SFDT_SMTP_PASS" }, "severityThreshold": "fail", "events": ["snapshot"] }, { "type": "webhook", "name": "loki", "format": "loki", "url": "https://logs-prod.grafana.net/loki/api/v1/push", "severityThreshold": "warn", "events": ["snapshot"] } ] } }

Secrets are referenced by env-var name, never inline. Webhook URLs and SMTP credentials are given as the name of an environment variable (webhookUrlEnv, urlEnv, SMTP *Env) — the value is read from process.env at send time and is never stored in config. Inline webhookUrl/url are still supported for back-compat but discouraged.

The same applies to webhook auth headers — use headersEnv, not headers, for anything secret.

Authenticating a webhook channel

headers takes literal values, so a token placed there is written into .sfdt/config.json. Use headersEnv instead — it maps a header name to the name of the env var holding its value:

{ "type": "webhook", "name": "n8n", "webhookUrlEnv": "HARNESS_WEBHOOK_URL", "headersEnv": { "X-Auth-Token": "HARNESS_WEBHOOK_TOKEN" } }

headersEnv overrides a literal headers entry of the same name, so an existing config can adopt it one key at a time. If a named env var is unset or empty, that channel fails with an error naming the variable — it does not fall back to sending the request unauthenticated. Other channels are unaffected.

Works with n8n Header Auth, Cloudflare Access service tokens, and any gateway expecting a shared-secret header.

Channel fields

FieldApplies toMeaning
typeallslack | teams | googlechat | email | webhook
nameallFriendly label (shown in CLI/GUI results)
webhookUrl / webhookUrlEnvslack, teams, googlechatIncoming-webhook URL (inline or env-var name)
url / urlEnvwebhookEndpoint URL (inline or env-var name)
formatwebhookjson (default) or loki (Grafana Loki push)
headerswebhookExtra HTTP headers (literal values)
headersEnvwebhookHeader name → name of the env var holding its value. Use this for auth tokens.
from, to, smtpemailSender, recipients, and SMTP env-var names
severityThresholdallMinimum snapshot severity to receive (ok | warn | error | fail)
eventsallWhich events this channel receives (omit = all)

Email uses nodemailer, an optional dependency that is lazy-loaded only when an email channel is configured.

Events & severity routing

  • Lifecycle eventsdeploy-success, deploy-failure, test-failure, release-created, harness-escalation — are sent to any channel whose events filter allows them.
  • The snapshot event (an audit/monitor run) is routed by severity: a channel receives it only when the snapshot’s worst status is at or above the channel’s severityThreshold.

Severity rank: ok < warn < error < fail.

AI executive-summary digests

Set notifications.summary.enabled = true to have snapshot notifications carry a 1–2 paragraph AI executive summary (top issue + next steps) instead of the raw findings list. It requires features.ai and an available AI provider; the summary is computed once and reused across channels, and falls back to the normal body when AI is unavailable. The wording is controlled by the editable monitor-summary prompt (see AI Providers).

Commands

sfdt notify deploy-failure --org prod --message "Release 1.4 failed" sfdt notify snapshot --type monitor # push the latest monitor snapshot sfdt notify snapshot --type audit sfdt monitor all --notify # run + notify in one step sfdt audit all --notify

See Org Health & Operations for the audit/monitor commands.

Surfaces

  • GUI — the Notifications page lists configured channels (secrets redacted), shows whether the AI summary is on, and offers a “send test to all channels” button.
  • MCPsfdt_notify pushes the latest snapshot.
  • CI — the generated pipelines run monitor all --notify on a schedule (see CI/CD Integration).
Last updated on