Notify Slack channel about upcoming releases #21
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Notify Slack channel about upcoming release | |
# This workflow notifies Slack channel about upcoming releases. | |
# | |
# ToDo | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.event.number }} | |
cancel-in-progress: true | |
on: | |
pull_request: | |
# TODO: uncomment | |
# branches: | |
# - release | |
types: | |
# Default types that triggers a workflow: | |
# - https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request | |
- opened | |
- synchronize | |
- reopened | |
# Additional types that we want to handle: | |
- closed | |
jobs: | |
notify: | |
runs-on: [ ubuntu-latest ] | |
steps: | |
- id: status-emoji | |
run: | | |
if [ "${{ github.event.action }}" == "opened" ] || [ "${{ github.event.action }}" == "reopened" ]; then | |
EMOJI=":new:" | |
elif [ "${{ github.event.action }}" == "closed" ]; then | |
if [ "${{ github.event.pull_request.merged }}" == "true" ]; then | |
EMOJI=":pr-merged:" | |
else | |
EMOJI=":no_entry_sign:" | |
fi | |
elif [ "${{ github.event.action }}" == "synchronize" ]; then | |
EMOJI=":hammer_and_wrench:" | |
else | |
EMOJI=":new:" | |
fi | |
echo "emoji=${EMOJI}" >> $GITHUB_OUTPUT | |
- uses: actions/github-script@v6 | |
id: commitlist | |
with: | |
retries: 5 | |
result-encoding: string | |
github-token: ${{ secrets.CI_ACCESS_TOKEN }} | |
script: | | |
// Slack Message layout is created with https://app.slack.com/block-kit-builder | |
const urlForPr = function (prNumber) { | |
// TODO: revert back | |
// return `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/pull/${prNumber}` | |
return `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/pull/${prNumber}` | |
} | |
const linkify = function (text) { | |
return text.replace(/#(\d+)/g, (match, prNumber) => { return `<${urlForPr(prNumber)}|#${prNumber}>` }) | |
} | |
# PRs for tests | |
# https://github.com/neondatabase/neon/pull/5202 | |
# https://github.com/neondatabase/cloud/pull/6724 | |
const { data: pullRequest } = await github.rest.pulls.get({ | |
owner: context.repo.owner, | |
// repo: context.repo.repo, | |
repo: "cloud", | |
// pull_number: context.payload.number, | |
// TODO: revert back | |
pull_number: 6724 | |
}); | |
const header = `"${pullRequest.title}" is coming :tada:` | |
const { data: commits } = await github.rest.pulls.listCommits({ | |
owner: context.repo.owner, | |
// repo: context.repo.repo, | |
repo: "cloud", | |
// pull_number: context.payload.number, | |
// TODO: revert back | |
pull_number: 6724 | |
}); | |
const blocks = [] | |
blocks.push({ | |
type: "header", | |
text: { | |
type: "plain_text", | |
text: header, | |
}, | |
}, | |
{ | |
type: "context", | |
elements: [ | |
{ | |
type: "mrkdwn", | |
// text: `Release PR: ${urlForPr(context.payload.number)`, | |
// TODO: revert back | |
text: `Release PR: <${urlForPr(6724)}|${urlForPr(6724)}>`, | |
}, | |
], | |
}) | |
let messageBody = "" | |
for (const commit of commits) { | |
const message = commit.commit.message.replace(/\r\n/g, "\n") | |
const title = message.split("\n\n", 1)[0] | |
messageBody += `- ${linkify(title)}\n` | |
} | |
blocks.push({ | |
"type": "divider" | |
}, { | |
type: "section", | |
text: { | |
type: "mrkdwn", | |
text: messageBody, | |
}, | |
}, { | |
"type": "divider" | |
}, { | |
type: "context", | |
elements: [{ | |
type: "mrkdwn", | |
// TODO: use PR updated time | |
text: `${{ steps.status-emoji.outputs.emoji }} Updated at <!date^${Math.floor(Date.now() / 1000)}^{date_num} {time_secs} (local time)|${new Date().toISOString()}>`, | |
}], | |
}) | |
const slackMessage = { | |
text: header, | |
blocks, | |
} | |
return JSON.stringify(slackMessage) | |
- uses: actions/cache/restore@v3 | |
id: posted-message | |
with: | |
path: release-notify.json | |
key: release-notify-${{ github.event.number }}.json | |
- id: message-id | |
run: | | |
if [ -f release-notify.json ]; then | |
UPDATE_TS=$(cat release-notify.json | jq --raw-output '.ts') | |
else | |
UPDATE_TS="" | |
fi | |
echo "update-ts=${UPDATE_TS}" >> $GITHUB_OUTPUT | |
- uses: slackapi/slack-github-action@v1 | |
id: slack | |
env: | |
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} | |
with: | |
channel-id: "C05QQ9J1BRC" # #test-release-notifications | |
update-ts: ${{ steps.message-id.outputs.update-ts }} | |
payload: ${{ steps.commitlist.outputs.result }} | |
- if: steps.posted-message.outputs.cache-hit != 'true' | |
run: | | |
echo '{"ts": "${{ steps.slack.outputs.ts }}"}' > release-notify.json | |
- uses: actions/cache/save@v3 | |
if: steps.posted-message.outputs.cache-hit != 'true' | |
with: | |
path: release-notify.json | |
key: release-notify-${{ github.event.number }}.json | |
- uses: actions/github-script@v6 | |
if: always() && github.event.action == 'closed' | |
with: | |
retries: 5 | |
script: | | |
github.rest.actions.deleteActionsCacheByKey({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
key: "release-notify-${{ github.event.number }}.json" | |
}); |