Schedule icon
Request icon
Return icon
Switch icon
Log icon
SlackIncomingWebhook icon

Netlify Deploy Failure Sentinel

Read a Netlify site's deploys every hour, change nothing, and alert Slack when production failed to deploy, failures pile up or a build is stuck.

Categories
Infrastructure

When a Netlify production deploy fails, nothing looks broken: the site keeps serving the last good build, the merge is green in Git, and the only trace is a red deploy in the Netlify UI that nobody is watching. The fix the team thinks is live never shipped. The same happens more quietly with deploy previews that fail on every branch, or a build that sits in the queue for an hour. This blueprint turns a scheduled, read-only call to the Netlify API into a deploy health gate: io.kestra.plugin.core.http.Request reads the site's recent deploys, one jq query finds the latest production result, the failure rate and builds that are stuck, and the result routes to a quiet log or a Slack alert.

How it works

  1. list_deploys (io.kestra.plugin.core.http.Request) calls GET /api/v1/sites/{site_id}/deploys?per_page=100 with a bearer token, which returns the most recent deploys of every context (production, deploy previews, branch deploys). It is a read: nothing is built, published, locked or rolled back. Retries cover short network blips, and allowFailed plus allowFailure keep an API error from aborting the flow so it can be reported instead.
  2. summarize_deploys (io.kestra.plugin.core.debug.Return) first guards for a missing or non-200 response (UNREACHABLE). Otherwise one jq query keeps deploys whose created_at is inside the lookback window, treats ready and error as finished, and counts other non-skipped states (enqueued, building, uploading, processing, ...) as in flight, flagging the ones older than stuck_minutes. It also picks the latest finished deploy with context == "production" from the whole page. A failed latest production deploy is CRITICAL; a failure rate at or above warning_failure_rate, or any stuck build, is WARNING; no finished deploy in the window is LOW_VOLUME; otherwise HEALTHY.
  3. route_by_deploys (io.kestra.plugin.core.flow.Switch) branches on that classification: HEALTHY and LOW_VOLUME log quietly, WARNING posts a Slack note, CRITICAL and UNREACHABLE page Slack. A defaults fallback logs anything unexpected.
  4. log_audit_result (io.kestra.plugin.core.log.Log) writes one audit line per run with the HTTP status and the full summary.
  5. The flow-level errors block pages Slack if the flow itself fails, and the hourly_check trigger runs at 25 minutes past every hour, shipped disabled: true.

What you get

  • An hourly, read-only check of a Netlify site's deploys with no custom scripting and no extra plugin to install.
  • A status output (HEALTHY / WARNING / CRITICAL / LOW_VOLUME / UNREACHABLE) other flows can gate on, for example to hold a release announcement until production really deployed.
  • Slack messages with the production branch and commit, the Netlify error message, the failure rate and the number of stuck builds.
  • An audit line on every run, separate from Slack.

Who it's for

  • Frontend and platform teams that ship sites and apps on Netlify.
  • Agencies running many client sites, one execution per site ID.
  • Teams that already run their release and alerting workflows in Kestra.

Why orchestrate this with Kestra

Netlify can email or post a notification per deploy event, but it does not tell you that the last production deploy is still failing an hour later, that one deploy in three fails, or that a build has been queued for 45 minutes. Kestra turns a plain, read-only API call into a scheduled, typed classification with retries, a failure path and an execution history, and the same flow runs against any number of sites by changing site_id.

Prerequisites

  • A Netlify site and a personal access token from User settings > Applications (read access to the team that owns the site).
  • The site's API ID from Site configuration > General > Site details.
  • A Slack incoming webhook for the WARNING, CRITICAL, UNREACHABLE and flow-failure alerts.

Secrets

  • NETLIFY_AUTH_TOKEN: a Netlify personal access token for a user on the team that owns the site.
  • SLACK_WEBHOOK: Slack incoming webhook used for every alert branch and the flow-failure alert.

In Kestra OSS, secrets are supplied as environment variables prefixed SECRET_ and base64-encoded, for example SECRET_NETLIFY_AUTH_TOKEN=$(echo -n 'your-netlify-token' | base64), and read back with {{ secret('NETLIFY_AUTH_TOKEN') }}. Use the Enterprise secrets backend for encryption at rest and access control.

Quick start

  1. Add NETLIFY_AUTH_TOKEN and SLACK_WEBHOOK as secrets.
  2. Set site_id and run the flow manually; compare the counts and the production line in the logs with the site's Deploys page.
  3. Push a commit that breaks the build on a branch to see a failure counted, then revert it.
  4. Enable hourly_check.

How to extend

  • Loop over several sites with io.kestra.plugin.core.flow.ForEach and one site_id per item.
  • Judge production only by filtering the jq on context == "production", or give deploy previews their own limit.
  • Store the last production deploy ID in a KV store and alert only when a new failure appears.
  • Trigger a retry with POST /api/v1/sites/{site_id}/builds from a separate, approved flow when production failed on a transient error.

Inputs

  • site_id: type STRING, default your-site-id.
  • lookback_hours: type INT, default 24.
  • warning_failure_rate: type FLOAT, default 20.0 (percent).
  • stuck_minutes: type INT, default 45.

Outputs

  • status: one of HEALTHY, WARNING, CRITICAL, LOW_VOLUME, UNREACHABLE.
  • Example path: {{ fromJson(outputs.summarize_deploys.value).production_error }} for the error of a failed production deploy.

Links

Pitfalls

  • Only the first page (100 deploys, newest first) is read; a site with more than 100 deploys in the window needs page paging or a shorter window.
  • The production result comes from the latest finished production deploy on that page, so a site with no production deploy in its last 100 deploys reports none.
  • This flow only reads; it never triggers a build, publishes, locks or restores a deploy.
See How

New to Kestra?

Use blueprints to kickstart your first workflows.