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.
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
| Observation | Check next |
|---|---|
| Failure step ran, notification step did not | Step conditions and whether execution was cancelled |
| Webhook secret is empty | Secret name, repository access, and event restrictions |
| Slack rejects the request | Webhook validity, JSON payload, and response status |
| Slack message exists but nobody responds | Channel ownership and the requested next action |
| Scheduled workflow never appeared | Scheduler 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.
