forked from clouddrove/github-shared-workflows
-
Notifications
You must be signed in to change notification settings - Fork 0
198 lines (182 loc) · 6.31 KB
/
Copy pathnotify-slack.yml
File metadata and controls
198 lines (182 loc) · 6.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
---
name: Slack Notify (CloudDrove Style)
on:
workflow_call:
inputs:
channel:
type: string
required: true
description: 'Slack channel #name or ID'
title:
type: string
required: true
description: Short action title, e.g., EKS Cluster Spin-up
status:
type: string
required: true
description: success|failed|cancelled|warning|info
fields_json:
type: string
required: false
default: '[]'
description: JSON array of {label,value}
body_md:
type: string
required: false
default: ""
description: Optional Markdown body (e.g., commands/logs)
button_text:
type: string
required: false
default: Open Run
description: 'Text label for the optional Slack button'
button_url:
type: string
required: false
default: ""
description: 'Target URL for the Slack button (shows only if set)'
logo_url:
type: string
required: false
default: https://clouddrove.com/logo.png
brand:
type: string
required: false
default: CloudDrove
description: 'Brand/logo image URL displayed in Slack blocks'
link_to_run:
type: boolean
required: false
default: true
description: 'Whether to include a "View GitHub Run" link in footer'
secrets:
SLACK_BOT_TOKEN:
required: true
description: 'Slack bot token with chat:write permission'
jobs:
send:
runs-on: ubuntu-latest
steps:
- name: Build Slack Payload
id: build
env:
CHANNEL: ${{ inputs.channel }}
TITLE: ${{ inputs.title }}
STATUS: ${{ inputs.status }}
FIELDS_JSON: ${{ inputs.fields_json }}
BODY_MD: ${{ inputs.body_md }}
BUTTON_TEXT: ${{ inputs.button_text }}
BUTTON_URL: ${{ inputs.button_url }}
LOGO_URL: ${{ inputs.logo_url }}
BRAND: ${{ inputs.brand }}
LINK_TO_RUN: ${{ inputs.link_to_run }}
REF: ${{ github.ref }}
SHA: ${{ github.sha }}
REPO: ${{ github.repository }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
ACTOR: ${{ github.actor }}
EVENT_NAME: ${{ github.event_name }}
run: |
set -e
# Emoji for status
case "${STATUS,,}" in
success) EMOJI="✅";;
failure) EMOJI="❌";;
cancelled|warning) EMOJI="⚠️";;
info|*) EMOJI="ℹ️";;
esac
SHORT_SHA=${SHA:0:7}
COMMIT_URL="https://github.com/${REPO}/commit/${SHA}"
ACTOR_URL="https://github.com/${ACTOR}"
# Default fields with clickable actor link
DEFAULT_FIELDS=$(jq -n \
--arg ref "$REF" \
--arg sha "$SHORT_SHA" \
--arg sha_url "$COMMIT_URL" \
--arg actor "@$ACTOR" \
--arg actor_url "$ACTOR_URL" \
--arg event "$EVENT_NAME" \
'[
{"label":"Ref","value":$ref},
{"label":"Commit","value": ("<" + $sha_url + "|" + $sha + ">")},
{"label":"Triggered By","value": ("<" + $actor_url + "|" + $actor + ">")},
{"label":"Event","value":$event}
]')
# Merge fields
ALL_FIELDS=$(jq -c -n \
--argjson a "${FIELDS_JSON}" \
--argjson b "${DEFAULT_FIELDS}" \
'$a + $b')
# Slack field layout
FIELD_ITEMS=$(jq -c '[ .[] | {
type: "mrkdwn",
text: ("*" + .label + "*:\n" + .value)
} ]' <<<"$ALL_FIELDS")
FIELD_BLOCK=$(jq -c -n --argjson fields "$FIELD_ITEMS" '{
type: "section",
fields: $fields
}')
# Optional body
if [ -n "$BODY_MD" ]; then
BODY_BLOCK=$(jq -c -n --arg t "$BODY_MD" \
'{ "type":"section", "text": { "type":"mrkdwn", "text": $t } }')
else
BODY_BLOCK=null
fi
if [ "$LINK_TO_RUN" = "true" ]; then
FOOTER_CONTEXT=$(jq -c -n --arg logo "$LOGO_URL" --arg brand "$BRAND" --arg url "$RUN_URL" '{
type: "context",
elements: [
{ "type": "image", "image_url": $logo, "alt_text": "brand" },
{ "type": "mrkdwn", "text": "*by \($brand)* • <\($url)|View GitHub Run>" }
]
}')
else
FOOTER_CONTEXT=$(jq -c -n --arg logo "$LOGO_URL" --arg brand "$BRAND" '{
type: "context",
elements: [
{ "type": "image", "image_url": $logo, "alt_text": "brand" },
{ "type": "mrkdwn", "text": "*by \($brand)*" }
]
}')
fi
# Optional button
if [ -n "$BUTTON_URL" ]; then
ACTIONS=$(jq -c -n --arg txt "$BUTTON_TEXT" --arg url "$BUTTON_URL" '{
type: "actions",
elements: [
{ "type":"button", "text": { "type":"plain_text", "text": $txt }, "url": $url, "style": "primary" }
]
}')
else
ACTIONS=null
fi
# Final payload
jq -n \
--arg ch "$CHANNEL" \
--arg title "$EMOJI $TITLE — ${STATUS^^}" \
--argjson fields "$FIELD_BLOCK" \
--argjson body "$BODY_BLOCK" \
--argjson actions "$ACTIONS" \
--argjson footer "$FOOTER_CONTEXT" '
def optional(x): if x != null and x != "null" then [x] else [] end;
{
channel: $ch,
blocks: (
[ { "type": "header", "text": { "type": "plain_text", "text": $title, "emoji": true } } ]
+ [ $fields ]
+ optional($body)
+ optional($actions)
+ [ $footer ]
)
}' > payload.json
echo "payload=$(jq -c . payload.json)" >> $GITHUB_OUTPUT
- name: Send to Slack
uses: slackapi/slack-github-action@v3
with:
method: chat.postMessage
payload: ${{ steps.build.outputs.payload }}
token: ${{ secrets.SLACK_BOT_TOKEN }}
unfurl_links: false
unfurl_media: false
...