Skip to content

GitHub Actions Slack Notifications: Failures and Approvals

Send a Slack notification when a GitHub Actions job fails, link to the run, and separate failure reporting from human approval and recovery.

Clock representing a scheduled automation workflow

A GitHub Actions Slack notification should tell someone which job failed and where to inspect it. If recovery needs permission, record that decision separately before the runner performs the operation. Posting a message does not pause a deployment or authorize a retry.

This guide starts with a small incoming-webhook example, then explains how to add human review. The notification example uses Slack directly and does not require ActionBox.

Send a failure notification from a workflow

Create an incoming webhook for a test channel using Slack's setup instructions. Store its URL in a GitHub Actions repository secret named SLACK_WEBHOOK_URL. The URL grants permission to post; keep it out of source files and logs.

Save this as .github/workflows/slack-notification-demo.yml in your own repository. It performs a harmless deliberate failure so you can inspect the notification path without changing a deployed service.

yaml
name: Slack notification demo
on: workflow_dispatch
permissions:
  contents: read
jobs:
  example:
    runs-on: ubuntu-latest
    steps:
      - name: Simulate failed work
        run: exit 1
      - name: Notify Slack after failure
        if: ${{ failure() }}
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
        run: |
          if [ -z "$SLACK_WEBHOOK_URL" ]; then
            echo "Configure SLACK_WEBHOOK_URL before running this demo."
            exit 1
          fi
          python3 - <<'PY' > slack-payload.json
          import json
          import os
          print(json.dumps({
              "text": "Demo job failed. Inspect the run: " + os.environ["RUN_URL"]
          }))
          PY
          curl --silent --show-error --fail \
            --connect-timeout 5 --max-time 15 \
            -H 'Content-Type: application/json' \
            --data-binary @slack-payload.json \
            "$SLACK_WEBHOOK_URL"

Run it manually in a disposable repository or test workflow. Expect a failed job and a message containing the run URL. Replace the deliberate failure with your real work only after checking the test result. This is a reproducible example, not a claim that we measured delivery in your Slack workspace.

The failure() condition allows the notification step to run after an earlier failure. It is not an unconditional cancellation handler. Review GitHub's status-check functions before changing the condition for a more complex workflow.

Keep the message useful and bounded

Start with the job name, affected environment, run link, and the next investigation. Avoid dumping complete logs into a channel. Logs may include customer data or operational information that everyone in the channel should not receive. A link lets authorized reviewers inspect the evidence in its original location.

Build JSON with a serializer, as the example does. Quotation marks and newlines in dynamic text should not break the payload. Pass workflow values through environment variables rather than inserting untrusted text directly into a shell program.

The example does not automatically retry a failed Slack request. If you add retries, account for the case where Slack accepted the message but the client lost the response: another attempt can create another message. A run URL helps people recognize that both messages refer to the same failure.

Troubleshoot the notification path

ObservationCheck next
Failure step ran, notification step did notStep conditions and whether execution was cancelled
Webhook secret is emptySecret name, repository access, and event restrictions
Slack rejects the requestWebhook validity, JSON payload, and response status
Slack message exists but nobody respondsChannel ownership and the requested next action
Scheduled workflow never appearedScheduler and independent missed-run monitoring

A step inside a workflow cannot report a run that never started. For scheduled jobs, pair this guide with GitHub Actions schedule troubleshooting and an independent completion expectation.

Add approval before a risky operation

A failure alert asks someone to investigate. An approval request asks someone to authorize a specific change. Describe the proposed operation, its scope, and what happens on rejection or timeout before adding buttons.

For example, a failed import may be safe to inspect immediately but unsafe to rerun without checking whether some records were already written. The integration should identify the affected batch and prevent duplicate execution. Permission to retry does not prove that the retry succeeded.

ActionBox can hold a human decision while your runner waits. Follow the GitHub approval integration for its supported contract. Reviewers can use the Slack beta after assisted setup for a Team workspace. Sending the incoming-webhook message above does not install or connect that beta integration.

For recovery operations, read actionable notifications and Action Controls. Controls depend on plan and workspace availability; the customer's integration executes and reports the operation.

Test the failure paths before relying on alerts

Check a successful run, the deliberate failure, a missing webhook secret, a rejected webhook request, and cancellation. Keep expected results beside the workflow so another maintainer can repeat the exercise. For an approval integration, also test rejection, expiry, and an execution failure after approval.

Record notification delivery, the human decision, and the execution result separately. Those observations answer different questions when the workflow needs attention again.

Create a free Source, then confirm Team beta access before connecting Slack.

Bring a developer workflow to Slack.

Create an account, confirm Team beta access, and test one request with your reviewers.