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/[email protected]
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/[email protected]
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/[email protected]
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.
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!
CodePudding user response:
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.