Introduction GitHub Actions is a powerful tool that allows you to automate workflows directly from your GitHub repository. One common use case is sending notifications to a Slack channel whenever a certain event occurs, such as a successful or failed build. This blog post will walk you through the steps to set up Slack notifications in GitHub Actions, format the message with detailed information about the workflow run, and dynamically include details such as commit hashes, authors, and build duration. Step-by-Step Guide to Set Up Slack Notifications Using Incoming Webhook 1. Setting Up a Slack Incoming Webhook Before you can send notifications to Slack, you need to set up an Incoming Webhook: Create a Slack App: Go to the Slack API: Applications, and create a new app for your workspace. Enable Incoming Webhooks: Once the app is created, go to the "Incoming Webhooks" section, and click "Activate Incoming Webhooks". Create a Webhook URL: Click on "Add New Webhook to Workspace", select the channel you want to post to and click "Allow". This will generate a Webhook URL. Store Your Webhook URL in GitHub Secrets: Copy the Webhook URL, and add it to your GitHub repository as a secret: Go to your GitHub repository. Click on Settings > Secrets and variables > Actions. Click New repository secret and add a new secret named SLACK_WEBHOOK_URL with your Webhook URL as the value. 2. Creating Your GitHub Actions Workflow Next, you'll create a GitHub Actions workflow file to send notifications to Slack. Here's a step-by-step breakdown of the YAML configuration: 2.1 Basic Setup Create a new file in your repository under .github/workflows/slack_notification.yml. name: Slack Notification run-name: Pushing notification on Slack channel on: [push] name: This defines the name of the workflow. run-name: This is the name that will be displayed in the GitHub Actions interface when this workflow runs. on: Specifies the event that triggers this workflow. In this case, it runs on every push. 2.2 Define the Jobs Next, define the job that will send the Slack notification: jobs: Notify-Slack-Channel: runs-on: ubuntu-latest jobs: A workflow consists of one or more jobs that run sequentially or in parallel. Notify-Slack-Channel: This is a custom name for our job. runs-on: Specifies the type of runner to execute the job. Here, ubuntu-latest is used. 2.3 Calculate Build Start Time To dynamically calculate the build duration, we first capture the build start time: steps: - name: Calculate build start time id: build_start_time run: echo "BUILD_START_TIME=$(date +%s)" >> $GITHUB_ENV steps: A job contains a series of steps. name: Describes what this step does. id: Used to reference this step's outputs later. run: Runs command-line scripts. Here, we use date +%s to get the current Unix timestamp and save it to an environment variable ($GITHUB_ENV). 2.4 Checkout Code To ensure that the workflow has access to the repository’s code, use the checkout action: - name: Checkout code uses: actions/checkout@v2 uses: Indicates the use of an action defined in another repository. actions/checkout@v2 checks out the repository code. 2.5 Calculate Build Duration Calculate the time taken for the job to complete: - name: Calculate build duration id: calculate_duration run: | end_time=$(date +%s) duration=$((end_time - $BUILD_START_TIME)) echo "duration=$duration" >> $GITHUB_ENV echo "::set-output name=duration::$duration" end_time=$(date +%s): Captures the current time at the end of the build. duration: Computes the difference between the start and end times to get the build duration. $GITHUB_ENV: Outputs the duration to the environment variable for use in later steps. 2.6 Get Short Commit Hash To shorten the commit hash to just the first 7 characters: - name: Get short commit hash id: short_commit run: echo "SHORT_SHA=${GITHUB_SHA:0:7}" >> $GITHUB_ENV SHORT_SHA=${GITHUB_SHA:0:7}: Extracts the first 7 characters of the commit hash. 2.7 Send Slack Notification Finally, use the slackapi/slack-github-action to send the formatted Slack message: - name: Send custom JSON data to Slack workflow id: slack uses: slackapi/slack-github-action@v1.26.0 with: payload: | { "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "*:white_check_mark: Succeeded GitHub Actions*" } }, { "type": "section", "fields": [ { "type": "mrkdwn", "text": "*Repo*\n<https://github.com/${{ github.repository }}|${{ github.repository }}>" }, { "type": "mrkdwn", "text": "*Commit*\n<${{ github.event.head_commit.url }}|${{ env.SHORT_SHA }}>" }, { "type": "mrkdwn", "text": "*Author*\n${{ github.event.head_commit.author.name }}" }, { "type": "mrkdwn", "text": "*Job*\n`${{ github.job }}`" }, { "type": "mrkdwn", "text": "*Event Name*\n`${{ github.event_name }}`" }, { "type": "mrkdwn", "text": "*Workflow*\n`${{ github.workflow }}`" }, { "type": "mrkdwn", "text": "*Build Logs*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Logs>" }, { "type": "mrkdwn", "text": "*Took*\n`${{ steps.calculate_duration.outputs.duration }} sec`" }, { "type": "mrkdwn", "text": "*Message*\n${{ github.event.head_commit.message }}" } ] } ] } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK with.payload: The JSON-formatted payload that defines the structure and content of the Slack message. mrkdwn: Slack's markup syntax to format text, which allows bolding with *text*, links with <url|text>, and more. env: Environment variables used within the workflow. This is how the Slack notification looks like - Key Features Dynamic Content: The payload dynamically pulls in relevant GitHub Actions data like repository name, commit hash, author, job name, event name, workflow name, build logs link, build duration, and commit message. Formatted Slack Message: The Slack message is formatted using Slack's Block Kit to make it readable and structured. Error Handling: Ensures that sensitive information (like Slack webhook URL) is stored securely using GitHub Secrets. Conclusion By following the steps above, you can automate Slack notifications from GitHub Actions to keep your team informed about the status of your workflows. The notification is dynamically populated with key information about the run, short commit hashes, and build durations, providing a comprehensive overview directly in Slack. Now, you're all set to keep your team updated with every push! Feel free to share this post with anyone who might find it useful. Happy automating! 🚀 Introduction GitHub Actions is a powerful tool that allows you to automate workflows directly from your GitHub repository. One common use case is sending notifications to a Slack channel whenever a certain event occurs, such as a successful or failed build. This blog post will walk you through the steps to set up Slack notifications in GitHub Actions, format the message with detailed information about the workflow run, and dynamically include details such as commit hashes, authors, and build duration. Step-by-Step Guide to Set Up Slack Notifications Using Incoming Webhook 1. Setting Up a Slack Incoming Webhook Before you can send notifications to Slack, you need to set up an Incoming Webhook: Create a Slack App: Go to the Slack API: Applications, and create a new app for your workspace. Enable Incoming Webhooks: Once the app is created, go to the "Incoming Webhooks" section, and click "Activate Incoming Webhooks". Create a Webhook URL: Click on "Add New Webhook to Workspace", select the channel you want to post to and click "Allow". This will generate a Webhook URL. Store Your Webhook URL in GitHub Secrets: Copy the Webhook URL, and add it to your GitHub repository as a secret: Go to your GitHub repository. Click on Settings > Secrets and variables > Actions. Click New repository secret and add a new secret named SLACK_WEBHOOK_URL with your Webhook URL as the value. Create a Slack App : Go to the Slack API: Applications , and create a new app for your workspace. Create a Slack App Slack API: Applications Enable Incoming Webhooks : Once the app is created, go to the " Incoming Webhooks " section, and click " Activate Incoming Webhooks ". Enable Incoming Webhooks Incoming Webhooks Activate Incoming Webhooks Create a Webhook URL : Click on " Add New Webhook to Workspace ", select the channel you want to post to and click " Allow ". This will generate a Webhook URL. Create a Webhook URL Add New Webhook to Workspace Allow Store Your Webhook URL in GitHub Secrets : Copy the Webhook URL, and add it to your GitHub repository as a secret: Go to your GitHub repository. Click on Settings > Secrets and variables > Actions. Click New repository secret and add a new secret named SLACK_WEBHOOK_URL with your Webhook URL as the value. Store Your Webhook URL in GitHub Secrets Go to your GitHub repository. Click on Settings > Secrets and variables > Actions. Click New repository secret and add a new secret named SLACK_WEBHOOK_URL with your Webhook URL as the value. Go to your GitHub repository. Click on Settings > Secrets and variables > Actions . Settings Secrets and variables Actions Click New repository secret and add a new secret named SLACK_WEBHOOK_URL with your Webhook URL as the value. New repository secret SLACK_WEBHOOK_URL 2. Creating Your GitHub Actions Workflow Next, you'll create a GitHub Actions workflow file to send notifications to Slack. Here's a step-by-step breakdown of the YAML configuration: 2.1 Basic Setup Create a new file in your repository under .github/workflows/slack_notification.yml . .github/workflows/slack_notification.yml name: Slack Notification run-name: Pushing notification on Slack channel on: [push] name: Slack Notification run-name: Pushing notification on Slack channel on: [push] name: This defines the name of the workflow. run-name: This is the name that will be displayed in the GitHub Actions interface when this workflow runs. on: Specifies the event that triggers this workflow. In this case, it runs on every push. name : This defines the name of the workflow. name run-name : This is the name that will be displayed in the GitHub Actions interface when this workflow runs. run-name on : Specifies the event that triggers this workflow. In this case, it runs on every push. on 2.2 Define the Jobs Next, define the job that will send the Slack notification: jobs: Notify-Slack-Channel: runs-on: ubuntu-latest jobs: Notify-Slack-Channel: runs-on: ubuntu-latest jobs: A workflow consists of one or more jobs that run sequentially or in parallel. Notify-Slack-Channel: This is a custom name for our job. runs-on: Specifies the type of runner to execute the job. Here, ubuntu-latest is used. jobs : A workflow consists of one or more jobs that run sequentially or in parallel. jobs Notify-Slack-Channel : This is a custom name for our job. Notify-Slack-Channel runs-on : Specifies the type of runner to execute the job. Here, ubuntu-latest is used. runs-on ubuntu-latest 2.3 Calculate Build Start Time To dynamically calculate the build duration, we first capture the build start time: steps: - name: Calculate build start time id: build_start_time run: echo "BUILD_START_TIME=$(date +%s)" >> $GITHUB_ENV steps: - name: Calculate build start time id: build_start_time run: echo "BUILD_START_TIME=$(date +%s)" >> $GITHUB_ENV steps: A job contains a series of steps. name: Describes what this step does. id: Used to reference this step's outputs later. run: Runs command-line scripts. Here, we use date +%s to get the current Unix timestamp and save it to an environment variable ($GITHUB_ENV). steps : A job contains a series of steps. steps name : Describes what this step does. name id : Used to reference this step's outputs later. id run : Runs command-line scripts. Here, we use date +%s to get the current Unix timestamp and save it to an environment variable ( $GITHUB_ENV ). run date +%s $GITHUB_ENV 2.4 Checkout Code To ensure that the workflow has access to the repository’s code, use the checkout action: - name: Checkout code uses: actions/checkout@v2 - name: Checkout code uses: actions/checkout@v2 uses: Indicates the use of an action defined in another repository. actions/checkout@v2 checks out the repository code. uses : Indicates the use of an action defined in another repository. actions/checkout@v2 checks out the repository code. uses actions/checkout@v2 2.5 Calculate Build Duration Calculate the time taken for the job to complete: - name: Calculate build duration id: calculate_duration run: | end_time=$(date +%s) duration=$((end_time - $BUILD_START_TIME)) echo "duration=$duration" >> $GITHUB_ENV echo "::set-output name=duration::$duration" - name: Calculate build duration id: calculate_duration run: | end_time=$(date +%s) duration=$((end_time - $BUILD_START_TIME)) echo "duration=$duration" >> $GITHUB_ENV echo "::set-output name=duration::$duration" end_time=$(date +%s): Captures the current time at the end of the build. duration: Computes the difference between the start and end times to get the build duration. $GITHUB_ENV: Outputs the duration to the environment variable for use in later steps. end_time=$(date +%s) : Captures the current time at the end of the build. end_time=$(date +%s) duration : Computes the difference between the start and end times to get the build duration. duration $GITHUB_ENV : Outputs the duration to the environment variable for use in later steps. $GITHUB_ENV 2.6 Get Short Commit Hash To shorten the commit hash to just the first 7 characters: - name: Get short commit hash id: short_commit run: echo "SHORT_SHA=${GITHUB_SHA:0:7}" >> $GITHUB_ENV - name: Get short commit hash id: short_commit run: echo "SHORT_SHA=${GITHUB_SHA:0:7}" >> $GITHUB_ENV SHORT_SHA=${GITHUB_SHA:0:7}: Extracts the first 7 characters of the commit hash. SHORT_SHA=${GITHUB_SHA:0:7} : Extracts the first 7 characters of the commit hash. SHORT_SHA=${GITHUB_SHA:0:7} 2.7 Send Slack Notification Finally, use the slackapi/slack-github-action to send the formatted Slack message: slackapi/slack-github-action - name: Send custom JSON data to Slack workflow id: slack uses: slackapi/slack-github-action@v1.26.0 with: payload: | { "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "*:white_check_mark: Succeeded GitHub Actions*" } }, { "type": "section", "fields": [ { "type": "mrkdwn", "text": "*Repo*\n<https://github.com/${{ github.repository }}|${{ github.repository }}>" }, { "type": "mrkdwn", "text": "*Commit*\n<${{ github.event.head_commit.url }}|${{ env.SHORT_SHA }}>" }, { "type": "mrkdwn", "text": "*Author*\n${{ github.event.head_commit.author.name }}" }, { "type": "mrkdwn", "text": "*Job*\n`${{ github.job }}`" }, { "type": "mrkdwn", "text": "*Event Name*\n`${{ github.event_name }}`" }, { "type": "mrkdwn", "text": "*Workflow*\n`${{ github.workflow }}`" }, { "type": "mrkdwn", "text": "*Build Logs*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Logs>" }, { "type": "mrkdwn", "text": "*Took*\n`${{ steps.calculate_duration.outputs.duration }} sec`" }, { "type": "mrkdwn", "text": "*Message*\n${{ github.event.head_commit.message }}" } ] } ] } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - name: Send custom JSON data to Slack workflow id: slack uses: slackapi/slack-github-action@v1.26.0 with: payload: | { "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "*:white_check_mark: Succeeded GitHub Actions*" } }, { "type": "section", "fields": [ { "type": "mrkdwn", "text": "*Repo*\n<https://github.com/${{ github.repository }}|${{ github.repository }}>" }, { "type": "mrkdwn", "text": "*Commit*\n<${{ github.event.head_commit.url }}|${{ env.SHORT_SHA }}>" }, { "type": "mrkdwn", "text": "*Author*\n${{ github.event.head_commit.author.name }}" }, { "type": "mrkdwn", "text": "*Job*\n`${{ github.job }}`" }, { "type": "mrkdwn", "text": "*Event Name*\n`${{ github.event_name }}`" }, { "type": "mrkdwn", "text": "*Workflow*\n`${{ github.workflow }}`" }, { "type": "mrkdwn", "text": "*Build Logs*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Logs>" }, { "type": "mrkdwn", "text": "*Took*\n`${{ steps.calculate_duration.outputs.duration }} sec`" }, { "type": "mrkdwn", "text": "*Message*\n${{ github.event.head_commit.message }}" } ] } ] } env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK with.payload: The JSON-formatted payload that defines the structure and content of the Slack message. mrkdwn: Slack's markup syntax to format text, which allows bolding with *text*, links with <url|text>, and more. env: Environment variables used within the workflow. with.payload : The JSON-formatted payload that defines the structure and content of the Slack message. with.payload mrkdwn : Slack's markup syntax to format text, which allows bolding with *text* , links with <url|text> , and more. mrkdwn *text* <url|text> env : Environment variables used within the workflow. env This is how the Slack notification looks like - Key Features Dynamic Content: The payload dynamically pulls in relevant GitHub Actions data like repository name, commit hash, author, job name, event name, workflow name, build logs link, build duration, and commit message. Dynamic Content : The payload dynamically pulls in relevant GitHub Actions data like repository name, commit hash, author, job name, event name, workflow name, build logs link, build duration, and commit message. Dynamic Content Formatted Slack Message: The Slack message is formatted using Slack's Block Kit to make it readable and structured. Formatted Slack Message : The Slack message is formatted using Slack's Block Kit to make it readable and structured. Formatted Slack Message Error Handling: Ensures that sensitive information (like Slack webhook URL) is stored securely using GitHub Secrets. Error Handling : Ensures that sensitive information (like Slack webhook URL) is stored securely using GitHub Secrets. Error Handling Conclusion By following the steps above, you can automate Slack notifications from GitHub Actions to keep your team informed about the status of your workflows. The notification is dynamically populated with key information about the run, short commit hashes, and build durations, providing a comprehensive overview directly in Slack. Now, you're all set to keep your team updated with every push! Feel free to share this post with anyone who might find it useful. Happy automating! 🚀