1

Here's my GitHub Actions .yml script that will send a notification to Slack when a Pull Request is open, commented, merge & close, or close.

name: Pull Request Notice
on:
  pull_request:
    types:
      - opened
    branches:
      - 'main'
  issue_comment:
    types:
      - created
  workflow_dispatch:
jobs:
  open_pr:
    runs-on: ubuntu-latest
    steps:
      - name: Send Open PR Body to Slack
        uses: slackapi/slack-github-action@v1.21.0
        if: github.event.pull_request.state == 'open' || github.event.issue.pull_request.state == 'open'
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
          BODY: ${{ toJson(github.event.pull_request.body) || github.event.pull_request.body }}
        with:
          # For posting a rich message using Block Kit
          payload: |
            {
              "attachments": [
                {
                  "color": "#36a64f",
                  "blocks": [
                    {
                      "type": "header",
                      "text": {
                        "type": "plain_text",
                        "text": ":recycle: PR: ${{ github.event.repository.name }}"
                      }
                    },
                    {
                      "type": "context",
                      "elements": [
                        {
                          "text": "*${{ github.event.pull_request.created_at }}*  |  Opened by: ${{ github.event.pull_request.user.login }}",
                          "type": "mrkdwn"
                        }
                      ]
                    },
                    {
                      "type": "divider"
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*${{ github.event.pull_request.title }}*\n${{ github.event.pull_request.html_url }}"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*Branch:* `${{ github.head_ref }}`"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*Message:*"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": ${{ env.BODY }}
                      }
                    }
                  ]
                }
              ]
            }
      - name: Send Merged PR Body to Slack
        uses: slackapi/slack-github-action@v1.21.0
        if: github.event.issue.pull_request.state == 'closed' && github.event.issue.pull_request.merged
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
        with:
          # For posting a rich message using Block Kit
          payload: |
            {
              "attachments": [
                {
                  "color": "#8250df",
                  "blocks": [
                    {
                      "type": "header",
                      "text": {
                        "type": "plain_text",
                        "text": ":scorpius: PR: ${{ github.event.repository.name }}"
                      }
                    },
                    {
                      "type": "context",
                      "elements": [
                        {
                          "text": "*${{ github.event.issue.pull_request.created_at }}*  |  Merged by: ${{ github.event.issue.pull_request.user.login }}",
                          "type": "mrkdwn"
                        }
                      ]
                    },
                    {
                      "type": "divider"
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*${{ github.event.issue.pull_request.title }}*\n${{ github.event.issue.pull_request.html_url }}"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*Branch:* ${{ github.head_ref }}"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*Message:*\n${{ github.event.comment.body }}"
                      }
                    }
                  ]
                }
              ]
            }
      - name: Send Closed PR Body to Slack
        uses: slackapi/slack-github-action@v1.21.0
        if: github.event.issue.state == 'closed'
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
          BODY: ${{ toJson(github.event.comment.body) || github.event.comment.body }}
        with:
          # For posting a rich message using Block Kit
          payload: |
            {
              "attachments": [
                {
                  "color": "#cf222e",
                  "blocks": [
                    {
                      "type": "header",
                      "text": {
                        "type": "plain_text",
                        "text": ":x: PR: ${{ github.event.repository.name }}"
                      }
                    },
                    {
                      "type": "context",
                      "elements": [
                        {
                          "text": "*${{ github.event.issue.closed_at }}*  |  Closed by: ${{ github.event.comment.user.login }}",
                          "type": "mrkdwn"
                        }
                      ]
                    },
                    {
                      "type": "divider"
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*${{ github.event.issue.title }}*\n${{ github.event.issue.html_url }}"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*Branch:* ${{ github.ref_name }}"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*Comment:*"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": ${{ env.BODY }}
                      }
                    }
                  ]
                }
              ]
            }

However, it fails when the Pull Request body is empty, resulting in invalid JSON.

Github Action fail

This is due to the fact that the Slack API Text Object > text field being a "Required" field: https://api.slack.com/reference/block-kit/composition-objects#text

As you can see from my script, I'm trying to post different message based on the PR status. There is a lot of repeating code due to the if: checking.

Is there a way to perform a conditional if checking within the steps, or within the env: declaration?

For example:

env:
  COLOR: ${{ github.event.pull_request.state == 'open' ? '#36a64f' : '#cf222e' }}
  BODY: ${{ github.event.pull_request.body == null ? 'N/A' : toJson(github.event.pull_request.body) }}

Any help or suggestion to make the script better would be greatly appreciated!

kenfai
  • 393
  • 5
  • 13
  • An alternative could be to check the pull request body content in a previous job, and set the value as an output according to the context (with the pr content if present, otherwise empty), and then use this output in the JSON you're building on the next job (the `open_pr` one). – GuiFalourd Aug 29 '22 at 12:34

1 Answers1

1

The issue has been solved by placing an expression with the || OR operator within the toJson() function.

...
env:
  NA: _n/a_
with:
...
{
  "type": "section",
  "text": {
    "type": "mrkdwn",
    "text": ${{ toJson(github.event.pull_request.body || env.BODY) }}
  }
}
...

It will result in "n/a"(underscore for italicised) in the JSON property if the Pull request body is empty.

kenfai
  • 393
  • 5
  • 13