GitHub Actions builds can alert your team in Slack, but getting it right means understanding how notifications flow and what data you can actually pull from the build.

Let’s see it in action. Imagine a workflow that builds a Docker image and pushes it to a registry.

name: Docker Build and Push

on:
  push:
    branches:
      - main

jobs:
  build_and_push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:

          username: ${{ secrets.DOCKERHUB_USERNAME }}


          password: ${{ secrets.DOCKERHUB_TOKEN }}


      - name: Build and push Docker image
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: yourusername/your-repo:latest

Now, to send a Slack notification for this, we’ll use a third-party action. A popular choice is slackapi/slack-github-action.

name: Docker Build and Push with Slack Notification

on:
  push:
    branches:
      - main

jobs:
  build_and_push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:

          username: ${{ secrets.DOCKERHUB_USERNAME }}


          password: ${{ secrets.DOCKERHUB_TOKEN }}


      - name: Build and push Docker image
        id: docker_build # Give this step an ID to reference its outputs
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: yourusername/your-repo:latest

      - name: Notify Slack on success
        if: success() # Only run this step if the previous steps were successful
        uses: slackapi/slack-github-action@v1.24.0
        with:
          payload: |
            {
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",

                    "text": "✅ *Docker build and push successful* for `${{ github.repository }}`. Image: `yourusername/your-repo:latest`"

                  }
                }
              ]
            }
        env:

          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}


      - name: Notify Slack on failure
        if: failure() # Only run this step if any previous step failed
        uses: slackapi/slack-github-action@v1.24.0
        with:
          payload: |
            {
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",

                    "text": "❌ *Docker build and push failed* for `${{ github.repository }}`. See details: `${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`"

                  }
                }
              ]
            }
        env:

          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

The core problem this solves is providing immediate, actionable feedback to a team when a critical automated process like a build or deployment completes, whether it succeeds or fails. Instead of someone having to constantly check the GitHub Actions UI, a message appears directly in a team’s communication channel. The slackapi/slack-github-action leverages Slack’s Incoming Webhooks, a simple way to post messages from external sources into Slack. You configure a webhook URL in Slack and then provide that URL as a secret to your GitHub Actions workflow.

Internally, the action takes a payload argument, which is a JSON string formatted according to Slack’s Block Kit UI framework. This allows for rich, structured messages with text, buttons, images, and more. The action then makes an HTTP POST request to the provided SLACK_WEBHOOK_URL with this JSON payload. You control the message content by crafting this JSON. Key levers include:

  • payload: This is where you define the message’s content and structure using Slack’s Block Kit. You can dynamically insert data from your GitHub Actions environment using ${{ ... }} syntax.

  • if condition: This is crucial for sending notifications only on success (if: success()) or only on failure (if: failure()). You can also use always() to send a notification regardless of the outcome.

  • Environment Variables: SLACK_WEBHOOK_URL is the most important, holding your Slack webhook. Other environment variables can be passed to the action if needed by custom configurations.

  • id on preceding steps: To get specific outputs from a previous step (like a Docker image tag or build status), you assign an id to that step and then reference its outputs. For example, if the docker_build step was configured to output a digest, you could use ${{ steps.docker_build.outputs.digest }} in your Slack message.

A common point of confusion is how to conditionally send notifications. You don’t want to spam your Slack channel if a workflow has multiple independent jobs. The if: success() and if: failure() conditions are applied per step. This means if you have a notify_on_success step and a notify_on_failure step, only one of them will execute based on the overall job’s outcome (or the preceding steps’ outcome if you’re being more granular). If you want to notify after any job in a multi-job workflow, you’d place the notification step in a separate job that runs needs: [job1, job2, ...] and uses an if: always() condition.

The next challenge is often parsing complex build outputs into a human-readable format for Slack, or integrating with more advanced Slack features like message threading.

Want structured learning?

Take the full Github-actions course →