Skip to content

Commit 73bef98

Browse files
chore(backport): backport notify-slack to version 4.7 (#7724)
1 parent 5ab4a9a commit 73bef98

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# This workflow will post to Slack when a PR is labeled with "notify-slack".
2+
# It will notify the appropriate reviewers based on the current UTC hour.
3+
# It also ensures that Slack is not notified multiple times for the same PR.
4+
# The reviewers are defined in a Base64 encoded JSON file stored in a GitHub secret.
5+
# After notifying, it records the notification in the PR comments and securely deletes the reviewers file.
6+
# The workflow is designed to be efficient and secure, ensuring that sensitive information is handled properly.
7+
8+
name: Ready for Review
9+
10+
on:
11+
pull_request:
12+
types: [labeled]
13+
14+
permissions:
15+
pull-requests: write
16+
17+
concurrency:
18+
group: readyforreviewci-${{ github.ref }}
19+
cancel-in-progress: true
20+
21+
jobs:
22+
notify-slack:
23+
if: contains(github.event.pull_request.labels.*.name, 'notify-slack')
24+
runs-on: ubuntu-latest
25+
26+
steps:
27+
- name: Check for prior Slack notification comment
28+
id: check
29+
run: |
30+
COMMENTS=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
31+
https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments)
32+
33+
COMMENT_ID=$(echo "$COMMENTS" | jq '.[] | select(.body | contains("<!-- slack-notified -->")) | .id')
34+
35+
if [ -n "$COMMENT_ID" ]; then
36+
echo "Slack already notified."
37+
echo "notified=true" >> $GITHUB_OUTPUT
38+
echo "comment_id=$COMMENT_ID" >> $GITHUB_OUTPUT
39+
else
40+
echo "notified=false" >> $GITHUB_OUTPUT
41+
fi
42+
43+
- name: Exit if already notified
44+
if: steps.check.outputs.notified == 'true'
45+
continue-on-error: true
46+
run: echo "Slack already notified — skipping remaining steps."
47+
48+
- name: Decode reviewer config (Base64)
49+
if: steps.check.outputs.notified == 'false'
50+
id: config
51+
run: |
52+
echo "${{ secrets.REVIEWER_CONFIG_B64 }}" | base64 -d > reviewers.json
53+
54+
- name: Choose Reviewers From Config
55+
if: steps.check.outputs.notified == 'false'
56+
id: pick
57+
run: |
58+
HOUR=$(date -u +'%H')
59+
DAY=$(date -u +%a | tr '[:upper:]' '[:lower:]')
60+
echo "UTC Hour: $HOUR | Day: $DAY"
61+
62+
REVIEWERS=""
63+
64+
for reviewer in $(jq -r 'keys[]' reviewers.json); do
65+
START=$(jq -r ".\"$reviewer\".start" reviewers.json)
66+
END=$(jq -r ".\"$reviewer\".end" reviewers.json)
67+
SLACK_ID=$(jq -r ".\"$reviewer\".slack_id" reviewers.json)
68+
69+
if jq -e ".\"$reviewer\".days" reviewers.json > /dev/null; then
70+
DAYS=$(jq -r ".\"$reviewer\".days[]" reviewers.json | tr '\n' ' ')
71+
[[ "$DAYS" != *"$DAY"* ]] && continue
72+
fi
73+
74+
if [ "$HOUR" -ge "$START" ] && [ "$HOUR" -lt "$END" ]; then
75+
REVIEWERS+="<@$SLACK_ID> "
76+
fi
77+
done
78+
79+
if [ -z "$REVIEWERS" ]; then
80+
REVIEWERS="<!here> _(No reviewers available — notifying team)_"
81+
fi
82+
83+
echo "reviewers=$REVIEWERS" >> $GITHUB_OUTPUT
84+
85+
- name: Notify Slack
86+
if: steps.check.outputs.notified == 'false'
87+
uses: rtCamp/action-slack-notify@v2.3.3
88+
env:
89+
SLACK_WEBHOOK: ${{ secrets.SLACK_PRIVATE_TEAM_WEBHOOK }}
90+
SLACK_USERNAME: "spectromate"
91+
SLACK_ICON_EMOJI: ":robot_panic:"
92+
SLACK_COLOR: "#A020F0"
93+
SLACK_MESSAGE: |
94+
:review: *<${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}>* is ready for review!
95+
Pinging: ${{ steps.pick.outputs.reviewers }}
96+
97+
- name: Create or Update Slack comment manually
98+
if: steps.check.outputs.notified == 'false'
99+
run: |
100+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
101+
BODY="✅ Slack reviewers notified at $TIMESTAMP \n <!-- slack-notified -->"
102+
103+
if [ -n "${{ steps.check.outputs.comment_id }}" ]; then
104+
echo "Updating existing comment..."
105+
curl -s -X PATCH -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
106+
-H "Accept: application/vnd.github.v3+json" \
107+
-d "$(jq -nc --arg body "$BODY" '{body: $body}')" \
108+
https://api.github.com/repos/${{ github.repository }}/issues/comments/${{ steps.check.outputs.comment_id }}
109+
else
110+
echo "Creating new comment..."
111+
curl -s -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
112+
-H "Accept: application/vnd.github.v3+json" \
113+
-d "$(jq -nc --arg body "$BODY" '{body: $body}')" \
114+
https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments
115+
fi
116+
117+
- name: Securely overwrite and delete reviewers.json
118+
if: always()
119+
run: |
120+
if [ -f reviewers.json ]; then
121+
echo "Shredding reviewers.json"
122+
dd if=/dev/urandom of=reviewers.json bs=1 count=$(stat -c%s reviewers.json) conv=notrunc status=none
123+
rm -f reviewers.json
124+
echo "Secure deletion complete."
125+
else
126+
echo "No reviewers.json file to delete."
127+
fi
128+
129+
- name: Final Job Status Summary
130+
if: always()
131+
run: |
132+
if [ "${{ steps.check.outputs.notified }}" == "true" ]; then
133+
echo "✅ Job completed: Slack was already notified (comment updated if needed)."
134+
else
135+
echo "✅ Job completed: Slack notification was posted successfully."
136+
fi

0 commit comments

Comments
 (0)