PullNotifier Logo

PullNotifier

GitHub ActionsSlackCI/CDDevOps

Slack GitHub Actions: The Complete Guide

How to send Slack notifications from GitHub Actions — with step-by-step setup, YAML examples, Block Kit templates, and best practices for every approach.

Last updated: February 2026

·

18 min read

Tweet

Table of Contents

1. What Are Slack GitHub Actions?2. Three Approaches Compared3. Method 1: Incoming Webhook4. Method 2: Bot Token (Slack API)5. Method 3: Slack Workflow Builder6. Complete YAML Workflow Examples7. Rich Messages with Block Kit8. Advanced Configurations9. Popular GitHub Actions for Slack10. Best Practices11. Troubleshooting12. Skip the YAML: Use PullNotifier13. FAQ

Other Tools

Stacked PRs GuideCode Coverage GuideGit Commit Message GuideMerge Request vs Pull RequestIntegrate GitLab with Slack
See all tools →
PullNotifier — Pull request alerts directly on Slack

What Are Slack GitHub Actions?

Slack GitHub Actions are workflow steps in GitHub Actions that send notifications, alerts, or data to Slack channels. They let you automate Slack messages triggered by GitHub events — pushes, pull requests, deployments, releases, CI/CD results, and more — all defined in your repository's YAML workflow files.

Instead of manually posting build results or deployment status in Slack, you define a workflow step that automatically sends a formatted message whenever the event occurs. The most common tool for this is the official slackapi/slack-github-action, maintained by Slack, which supports three different integration methods.

Why automate Slack notifications from CI/CD?

Teams that automate status notifications respond to failures 60% faster and spend less time context-switching between GitHub and Slack. Real-time alerts mean your team knows the moment something breaks — not whenever someone remembers to check GitHub.

Common use cases

Pull request notifications

Notify your team when PRs are opened, reviewed, or merged. Include PR title, author, and direct links.

CI/CD build status

Alert on test failures or successful builds. Use conditional steps to only notify on failure.

Deployment alerts

Announce production deployments with environment, version, and commit details to your ops channel.

Release announcements

Automatically post release notes to Slack when a new GitHub release is published.

Failure-only alerts

Skip the noise — only send Slack messages when workflows fail, so your team can respond fast.

Scheduled monitoring

Run health checks on a cron schedule and post results to Slack. Great for uptime monitoring.


Three Approaches to Slack GitHub Actions

There are three ways to send Slack notifications from GitHub Actions. Each has different tradeoffs around simplicity, flexibility, and features:

FeatureIncoming WebhookBot Token (API)Workflow Builder
Setup complexityLowMediumMedium
Channel targetingFixed (one per webhook)Any channel (dynamic)Configured in Slack
Message updatesNoYes (chat.update)No
Threaded repliesNoYes (thread_ts)No
File uploadsNoYes (files.uploadV2)No
User lookupsNoYes (users.lookupByEmail)No
DMs to usersNoYesNo
Block Kit supportYesYesLimited
Auth methodWebhook URLxoxb- OAuth tokenTrigger URL
Slack plan neededFreeFreePaid
Best forSimple, single-channel alertsAdvanced, multi-channel workflowsTriggering Slack automations

Method 1: Incoming Webhook (Simplest)

Incoming Webhooks are the simplest way to get Slack notifications from GitHub Actions. Each webhook is tied to a specific channel — you post a JSON/YAML payload to the webhook URL, and Slack delivers the message. No bot user or OAuth scopes needed.

Part A: Create the Slack Webhook

1

Create a Slack App

Go to api.slack.com/apps and click Create New App. Select From scratch, enter an app name (e.g., "GitHub Actions Notifier"), and choose your workspace. Click Create App.

2

Enable Incoming Webhooks

In the left sidebar, click Incoming Webhooks. Toggle Activate Incoming Webhooks to On.

3

Add a Webhook to a Channel

Click Add New Webhook to Workspace at the bottom of the page. Select the target channel (e.g., #ci-alerts) from the dropdown and click Allow. Copy the generated webhook URL — it looks like:

https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

Part B: Add the Webhook to GitHub

4

Store the Webhook as a GitHub Secret

In your GitHub repository, navigate to Settings > Secrets and variables > Actions. Click New repository secret.

  • Name: SLACK_WEBHOOK_URL
  • Value: paste the webhook URL from the previous step

Click Add secret. The URL is now encrypted and accessible in your workflows via ${{ secrets.SLACK_WEBHOOK_URL }}.

5

Add a Workflow Step

In your .github/workflows/ directory, add a notification step to your workflow YAML:

.github/workflows/notify.yml

name: Notify Slack
on:
  push:
    branches: [main]

jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - name: Send Slack notification
        uses: slackapi/slack-github-action@v2.1.1
        with:
          webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
          webhook-type: incoming-webhook
          payload: |
            text: "New push to main by ${{ github.actor }}"
            blocks:
              - type: "section"
                text:
                  type: "mrkdwn"
                  text: ":rocket: *Push to main*\nBy: ${{ github.actor }}\nRepo: ${{ github.repository }}""
6

Test It

Push a commit to your main branch. Within seconds, a notification should appear in your Slack channel. Check the GitHub Actions log for the notification step if nothing arrives.

Webhook limitations

Each webhook is locked to a single channel. You cannot update messages, post threads, upload files, or send DMs. For those features, use the Bot Token method below.


Method 2: Bot Token / Slack API (Most Powerful)

The Bot Token approach gives you full access to the Slack API — post to any channel, update messages, send threaded replies, upload files, look up users by email, and send DMs. It requires a few more setup steps but unlocks the most flexibility.

1

Create a Slack App (if you haven't already)

Go to api.slack.com/apps, click Create New App > From scratch, name your app, and select your workspace.

2

Add Bot Token Scopes

Navigate to OAuth & Permissions in the left sidebar. Under Bot Token Scopes, add the scopes you need:

ScopePurpose
chat:writePost messages to channels
chat:write.publicPost to channels without joining
files:writeUpload files
users:read.emailLook up users by email

At minimum, you need chat:write. Add others as needed for your use case.

3

Install the App & Copy the Token

Click Install to Workspace at the top of the OAuth & Permissions page. After authorizing, copy the Bot User OAuth Token (starts with xoxb-).

4

Invite the Bot to Your Channel

In Slack, go to the channel where you want notifications and type /invite @YourBotName. The bot must be in the channel to post messages (unless you added the chat:write.public scope).

5

Store the Token and Channel ID as GitHub Secrets

Add two secrets in your GitHub repository (Settings > Secrets > Actions):

  • SLACK_BOT_TOKEN — the xoxb- token
  • SLACK_CHANNEL_ID — the channel ID (right-click channel name > Copy link, the ID is the last segment)
6

Add the Workflow Step

.github/workflows/notify.yml

- name: Notify Slack
  uses: slackapi/slack-github-action@v2.1.1
  with:
    method: chat.postMessage
    token: ${{ secrets.SLACK_BOT_TOKEN }}
    payload: |
      channel: ${{ secrets.SLACK_CHANNEL_ID }}
      text: "Build ${{ job.status }} for ${{ github.repository }}"
      blocks:
        - type: "section"
          text:
            type: "mrkdwn"
            text: "*Build ${{ job.status }}*\nRepo: ${{ github.repository }}\nBranch: `${{ github.ref_name }}`"

Method 3: Slack Workflow Builder

Slack Workflow Builder lets you create automations directly inside Slack. You can trigger a Slack workflow from GitHub Actions by sending data to a webhook trigger URL. The workflow then runs steps you define in Slack — like posting a formatted message, creating a channel, or starting an approval process.

This approach is best when you want Slack-side logic — like routing notifications based on data, requesting approvals, or triggering multi-step Slack workflows from a GitHub event.

Workflow Builder Trigger Example

- name: Trigger Slack Workflow
  uses: slackapi/slack-github-action@v2.1.1
  with:
    webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
    webhook-type: webhook-trigger
    payload: |
      status: "${{ job.status }}"
      repository: "${{ github.repository }}"
      branch: "${{ github.ref_name }}"
      actor: "${{ github.actor }}"
      run_url: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"

Complete YAML Workflow Examples

Copy-paste these workflow files into your .github/workflows/ directory. Each example is a complete, self-contained workflow that you can customize for your project.

Basic push notification (Webhook)

on: push
name: Slack Notification on Push
on:
  push:
    branches: [main]

jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - name: Notify Slack
        uses: slackapi/slack-github-action@v2.1.1
        with:
          webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
          webhook-type: incoming-webhook
          payload: |
            text: "New push to main by ${{ github.actor }}"
            blocks:
              - type: "section"
                text:
                  type: "mrkdwn"
                  text: ":rocket: *New push to main*\nRepo: `${{ github.repository }}`\nBy: ${{ github.actor }}\nCommit: `${{ github.sha }}`"

Rich Messages with Block Kit

Slack's Block Kit lets you build richly formatted messages with sections, headers, fields, buttons, images, and more. Block Kit payloads work with both Incoming Webhooks and the Bot Token method.

Key block types

Block TypePurposeExample Use
headerLarge, bold title text"CI Build Result"
sectionText content with optional fieldsRepo, branch, status details
actionsInteractive buttons"View Run" / "Review PR" buttons
contextSecondary, smaller textTimestamps, author attribution
dividerHorizontal rule separatorBetween sections
imageFull-width imageCharts, screenshots

Slack mrkdwn vs Markdown

Slack uses its own markup format called mrkdwn — not standard Markdown. Key differences: bold is *text*, italic is _text_, strikethrough is ~text~, and links use <url|text> (not [text](url)). Code blocks use triple backticks.

Example: Full Block Kit message

blocks:
  - type: "header"
    text:
      type: "plain_text"
      text: "Deployment Complete"
  - type: "section"
    fields:
      - type: "mrkdwn"
        text: "*Status:*\n:white_check_mark: Success"
      - type: "mrkdwn"
        text: "*Environment:*\nProduction"
      - type: "mrkdwn"
        text: "*Branch:*\n`main`"
      - type: "mrkdwn"
        text: "*Deployed by:*\n${{ github.actor }}"
  - type: "actions"
    elements:
      - type: "button"
        text:
          type: "plain_text"
          text: "View Deployment"
        url: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
      - type: "button"
        text:
          type: "plain_text"
          text: "Open Repository"
        url: "${{ github.server_url }}/${{ github.repository }}"
  - type: "context"
    elements:
      - type: "mrkdwn"
        text: "Commit: `${{ github.sha }}` | ${{ github.repository }}""

Advanced Configurations

Update an existing message (in-place)

Post a "deployment in progress" message, then update it when the deployment finishes. This reduces channel noise by keeping everything in one message.

Message update pattern

- name: Post initial message
  id: slack_initial
  uses: slackapi/slack-github-action@v2.1.1
  with:
    method: chat.postMessage
    token: ${{ secrets.SLACK_BOT_TOKEN }}
    payload: |
      channel: ${{ secrets.SLACK_CHANNEL_ID }}
      text: ":hourglass_flowing_sand: Deployment in progress..."

# ... your deployment steps here ...

- name: Update message with result
  uses: slackapi/slack-github-action@v2.1.1
  with:
    method: chat.update
    token: ${{ secrets.SLACK_BOT_TOKEN }}
    payload: |
      channel: ${{ secrets.SLACK_CHANNEL_ID }}
      ts: "${{ steps.slack_initial.outputs.ts }}"
      text: ":white_check_mark: Deployment complete!"

Threaded replies

Post a parent message and then add replies in a thread — useful for multi-step deployments where you want to track progress without spamming the channel.

Threaded replies

- name: Post parent message
  id: parent
  uses: slackapi/slack-github-action@v2.1.1
  with:
    method: chat.postMessage
    token: ${{ secrets.SLACK_BOT_TOKEN }}
    payload: |
      channel: ${{ secrets.SLACK_CHANNEL_ID }}
      text: ":rocket: Deployment started for v1.2.0"

- name: Post thread reply
  uses: slackapi/slack-github-action@v2.1.1
  with:
    method: chat.postMessage
    token: ${{ secrets.SLACK_BOT_TOKEN }}
    payload: |
      channel: ${{ secrets.SLACK_CHANNEL_ID }}
      thread_ts: "${{ fromJSON(steps.parent.outputs.response).ts }}"
      text: ":white_check_mark: Database migration complete"

DM the commit author

Look up the commit author by email and send them a direct message — useful for notifying developers about build failures on their commits.

DM commit author

- name: Look up Slack user by email
  id: lookup
  uses: slackapi/slack-github-action@v2.1.1
  with:
    method: users.lookupByEmail
    token: ${{ secrets.SLACK_BOT_TOKEN }}
    payload: |
      email: ${{ github.event.pusher.email }}

- name: DM the author
  if: ${{ steps.lookup.outputs.ok }}
  uses: slackapi/slack-github-action@v2.1.1
  with:
    method: chat.postMessage
    token: ${{ secrets.SLACK_BOT_TOKEN }}
    payload: |
      channel: "${{ fromJSON(steps.lookup.outputs.response).user.id }}"
      text: ":warning: Your commit to ${{ github.repository }} failed CI"
      blocks:
        - type: "section"
          text:
            type: "mrkdwn"
            text: ":x: *CI Failed* on your commit to `${{ github.ref_name }}`\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View the failed run>"

Conditional notifications by branch

Branch-based routing

- name: Notify production channel
  if: github.ref == 'refs/heads/main' && success()
  uses: slackapi/slack-github-action@v2.1.1
  with:
    webhook: ${{ secrets.SLACK_PROD_WEBHOOK }}
    webhook-type: incoming-webhook
    payload: |
      text: ":white_check_mark: Production deploy successful"

- name: Notify staging channel
  if: github.ref == 'refs/heads/develop'
  uses: slackapi/slack-github-action@v2.1.1
  with:
    webhook: ${{ secrets.SLACK_STAGING_WEBHOOK }}
    webhook-type: incoming-webhook
    payload: |
      text: ":construction: Staging deploy complete"

File upload to Slack

Upload test report

- name: Upload test report
  uses: slackapi/slack-github-action@v2.1.1
  with:
    method: files.uploadV2
    token: ${{ secrets.SLACK_BOT_TOKEN }}
    payload: |
      channel_id: ${{ secrets.SLACK_CHANNEL_ID }}
      filename: "test-report.txt"
      file: "./test-results/report.txt"


Best Practices for Slack GitHub Actions

1

Store secrets securely

Never hard-code webhook URLs or bot tokens in workflow files. Always use GitHub Secrets (Settings > Secrets and variables > Actions). GitHub encrypts secrets using Libsodium sealed boxes.

2

Always include a text fallback

When using Block Kit blocks, always include a top-level text field alongside your blocks array. The text serves as a fallback for notifications, accessibility readers, and Slack clients that cannot render blocks.

3

Use conditional notifications

Use if: failure() for failure-only alerts to reduce notification fatigue. Use if: always() when you want notifications regardless of outcome. Place notification steps at the end of your job.

4

Route to the right channels

Send deployment alerts to #deploys, CI failures to #ci-alerts, and release notes to #releases. Avoid dumping everything into a single channel — it leads to alert fatigue.

5

Use channel IDs, not names

When using the Bot Token method, pass the channel ID (e.g., C01234ABCDE) rather than the channel name. Channel IDs are stable — names can change and break your workflow.

6

Include actionable links

Always include a link back to the GitHub Actions run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}. This lets teammates jump directly to the relevant context.

7

Escape dynamic content

Use ${{ toJSON(value) }} to safely escape strings containing special characters — especially commit messages that may include quotes, newlines, or Slack mrkdwn syntax.

Security reminder

Never commit webhook URLs or bot tokens to your repository. GitHub Secrets are encrypted using Libsodium sealed boxes and are automatically redacted from workflow logs. Use descriptive secret names like SLACK_DEPLOY_WEBHOOK or SLACK_CI_BOT_TOKEN to avoid confusion.


Troubleshooting

Common issues when setting up Slack GitHub Actions and how to fix them:


Skip the YAML: Use PullNotifier for GitHub Slack Notifications

GitHub Actions Slack integrations are powerful — but they require YAML configuration, webhook management, and ongoing maintenance for every notification you want. If your primary need is pull request notifications in Slack, there's a faster way.

PullNotifier sends real-time GitHub PR notifications directly to Slack — new PRs, review requests, approvals, CI status changes, and merges — with zero YAML, zero webhook setup, and zero maintenance. It takes 30 seconds to set up and works with both public and private repositories.

30-second setup

Single-message PR updates

No YAML or webhooks


Frequently Asked Questions

What are Slack GitHub Actions?

Slack GitHub Actions are GitHub Actions workflow steps that send notifications or data to Slack channels. They let you automate Slack messages triggered by GitHub events like pushes, pull requests, deployments, and CI/CD pipeline results — all defined in YAML workflow files.

How do I send a Slack notification from GitHub Actions?

The simplest way is to use the official slackapi/slack-github-action with an Incoming Webhook. Create a Slack app, enable Incoming Webhooks, copy the webhook URL, store it as a GitHub secret, and add a step in your workflow YAML that sends a message using the webhook. See the step-by-step guide above for detailed instructions.

Should I use a webhook or a bot token for Slack GitHub Actions?

Use an Incoming Webhook for simple, single-channel notifications (deploy alerts, build status). Use a Bot Token when you need advanced features like posting to multiple channels, updating messages, sending threaded replies, uploading files, or looking up users by email. Webhooks are simpler to set up; bot tokens are more powerful.

Which GitHub Action for Slack is best?

The official slackapi/slack-github-action (v2) is recommended for most teams. It supports all three integration methods, has built-in retry logic, and is actively maintained by Slack. For simpler setups, rtCamp/action-slack-notify offers a quick env-var-driven configuration. For status-based conditional notifications, ravsamhq/notify-slack-action provides template variables.

Can I send Slack notifications only when a GitHub Actions workflow fails?

Yes. Use the if: failure() condition on your Slack notification step. This ensures the step only runs when a previous step in the job has failed. You can also use if: success() for success-only messages, or if: always() to send regardless of outcome.

How do I update an existing Slack message from GitHub Actions?

Use the Bot Token method with the chat.postMessage API to send an initial message, capture the ts (timestamp) output, then use chat.update with the same ts to modify the message in place. This is useful for "deployment in progress → deployment complete" patterns that reduce channel noise.

Can I send Slack messages to multiple channels from GitHub Actions?

With the Bot Token method, yes — add separate steps for each channel, changing the channel parameter. With Incoming Webhooks, you need a separate webhook URL for each channel. The Bot Token approach is more flexible for multi-channel notifications.

Is there a no-code alternative to Slack GitHub Actions?

Yes. PullNotifier sends GitHub pull request notifications to Slack without any YAML configuration. It takes 30 seconds to set up, handles PR events automatically (new PRs, reviews, approvals, CI status, merges), and delivers real-time alerts to your Slack channels. No webhook setup or workflow files needed.

How do I format Slack messages from GitHub Actions?

Slack uses its own markup format called mrkdwn (not standard Markdown). Bold is *text*, italic is _text_, and links are <url|text>. For rich layouts, use Block Kit — a JSON/YAML structure with sections, headers, buttons, and more. Design messages visually at app.slack.com/block-kit-builder.

What is the difference between slack-github-action v1 and v2?

Version 2 introduced several breaking changes: webhook-type must be explicitly set, method is required for API calls, token is now a step input (not just an env var), YAML payloads are supported alongside JSON, and template variable replacement is disabled by default. V2 also added retry logic, proxy support, and improved error handling. See the migration section in the official docs.



Other Tools

See all tools →
PullNotifier — Pull request alerts directly on Slack
PullNotifier Logo

PullNotifier

© 2026 PullNotifier. All rights reserved