Skip to content

Commit 2217fa4

Browse files
ppputtyokawabuchi4280
andauthored
feat: add slack notification (#33)
* ~enhancement add slack notification * ~modify message * ~modify rename action * (test) force test CI failure * ~modify revert test CI --------- Co-authored-by: kawabuchi4280 <k.kawabuchi.z8@future.co.jp>
1 parent d252fb2 commit 2217fa4

File tree

4 files changed

+276
-0
lines changed

4 files changed

+276
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: "Slack Notify on Failure"
2+
description: "Send a notification to Slack when a job fails"
3+
inputs:
4+
webhook_url:
5+
description: "Slack Webhook URL"
6+
required: true
7+
status:
8+
description: "Job status (failure, success, etc.)"
9+
required: false
10+
default: "failure"
11+
12+
runs:
13+
using: "composite"
14+
steps:
15+
- name: Send Notification
16+
shell: bash
17+
env:
18+
SLACK_WEBHOOK_URL: ${{ inputs.webhook_url }}
19+
STATUS: ${{ inputs.status }}
20+
REPO: ${{ github.repository }}
21+
WORKFLOW: ${{ github.workflow }}
22+
run_id: ${{ github.run_id }}
23+
run_number: ${{ github.run_number }}
24+
actor: ${{ github.actor }}
25+
ref_name: ${{ github.ref_name }}
26+
sha: ${{ github.sha }}
27+
server_url: ${{ github.server_url }}
28+
run: |
29+
# Webhook URL の検証
30+
if [ -z "$SLACK_WEBHOOK_URL" ]; then
31+
echo "::warning::SLACK_WEBHOOK_URL is not set. Skipping notification."
32+
exit 0
33+
fi
34+
35+
# 変数準備
36+
SHORT_SHA="${sha:0:7}"
37+
WORKFLOW_URL="${server_url}/${REPO}/actions/runs/${run_id}"
38+
COMMIT_URL="${server_url}/${REPO}/commit/${sha}"
39+
40+
# タイトルと色の決定
41+
if [ "$STATUS" == "success" ]; then
42+
COLOR="good"
43+
TITLE="✅ CI Succeeded"
44+
ICON=":white_check_mark:"
45+
else
46+
COLOR="danger"
47+
TITLE="🚨 CI Failed"
48+
ICON=":x:"
49+
fi
50+
51+
# JSONペイロードの構築 (jqを使用してエスケープ処理を自動化)
52+
PAYLOAD=$(jq -nc \
53+
--arg username "GitHub CI/CD" \
54+
--arg icon "$ICON" \
55+
--arg text "$TITLE" \
56+
--arg color "$COLOR" \
57+
--arg actor "$actor" \
58+
--arg status "$STATUS" \
59+
--arg workflow "$WORKFLOW" \
60+
--arg workflow_url "$WORKFLOW_URL" \
61+
--arg repo "$REPO" \
62+
--arg repo_url "${server_url}/${REPO}" \
63+
--arg branch "$ref_name" \
64+
--arg commit_url "$COMMIT_URL" \
65+
--arg short_sha "$SHORT_SHA" \
66+
--arg run_number "$run_number" \
67+
--argjson ts "$(date +%s)" \
68+
'{
69+
username: $username,
70+
icon_emoji: $icon,
71+
text: $text,
72+
attachments: [
73+
{
74+
color: $color,
75+
author_name: $actor,
76+
title: ("Workflow " + $workflow + " " + $status),
77+
title_link: $workflow_url,
78+
fields: [
79+
{ title: "Repository", value: ("<" + $repo_url + "|" + $repo + ">"), short: true },
80+
{ title: "Branch", value: ("`" + $branch + "`"), short: true },
81+
{ title: "Commit", value: ("<" + $commit_url + "|`" + $short_sha + "`>"), short: true },
82+
{ title: "Run Number", value: ("#" + $run_number), short: true }
83+
],
84+
footer: ("<" + $workflow_url + "|👉 View Logs and Details>"),
85+
footer_icon: "https://github.githubassets.com/favicon.ico",
86+
ts: $ts
87+
}
88+
]
89+
}'
90+
)
91+
92+
# 送信実行
93+
HTTP_CODE=$(echo "$PAYLOAD" | curl -X POST -H 'Content-type: application/json' \
94+
-d @- "$SLACK_WEBHOOK_URL" \
95+
-w '%{http_code}' \
96+
-s -o /tmp/slack_response.txt)
97+
98+
if [ "$HTTP_CODE" -eq 200 ]; then
99+
echo "✅ Notification sent (HTTP 200)"
100+
else
101+
echo "::error::Failed to send notification. HTTP Code: $HTTP_CODE"
102+
cat /tmp/slack_response.txt
103+
exit 1
104+
fi

.github/workflows/deploy-gh-pages.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ jobs:
4343
with:
4444
path: ./docs
4545

46+
- name: Notify Slack on Failure
47+
if: failure()
48+
uses: ./.github/actions/slack-failure-notify
49+
with:
50+
webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
51+
4652
deploy:
4753
if: github.repository == 'tanzaku/postgresql-cst-parser'
4854
needs: build
@@ -55,3 +61,9 @@ jobs:
5561
if: ${{ !env.ACT }}
5662
id: deployment
5763
uses: actions/deploy-pages@v4
64+
65+
- name: Notify Slack on Failure
66+
if: failure()
67+
uses: ./.github/actions/slack-failure-notify
68+
with:
69+
webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}

.github/workflows/rust.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,9 @@ jobs:
3232
run: cargo clippy -p parser-generator -- -D warnings
3333
- name: Clippy (postgresql-cst-parser)
3434
run: cargo clippy -p postgresql-cst-parser -- -D warnings
35+
36+
- name: Notify Slack on Failure
37+
if: failure()
38+
uses: ./.github/actions/slack-failure-notify
39+
with:
40+
webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}

.github/workflows/slack-notify.yml

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
name: Slack Notification
2+
on:
3+
push:
4+
branches: ["**"]
5+
pull_request:
6+
types: [opened, closed, reopened]
7+
issue_comment:
8+
types: [created]
9+
10+
jobs:
11+
notify:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v3
16+
17+
- name: Send Notification to Slack
18+
env:
19+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
20+
EVENT_NAME: ${{ github.event_name }}
21+
REPO: ${{ github.repository }}
22+
ACTOR: ${{ github.actor }}
23+
EVENT_JSON: ${{ toJson(github.event) }}
24+
run: |
25+
if [ -z "$SLACK_WEBHOOK_URL" ]; then
26+
echo "::warning::SLACK_WEBHOOK_URL is not set."
27+
exit 0
28+
fi
29+
30+
# イベント情報を一時ファイルへ保存 (クォート問題回避のため)
31+
printf '%s' "$EVENT_JSON" > event.json
32+
33+
# 共通変数の設定
34+
TS=$(date +%s)
35+
COLOR="#999999"
36+
37+
# イベントごとの処理
38+
case "$EVENT_NAME" in
39+
push)
40+
EMOJI="🚀"
41+
REF_NAME="${GITHUB_REF_NAME}"
42+
COMMIT_MSG=$(jq -r '.head_commit.message' event.json)
43+
COMMIT_URL=$(jq -r '.head_commit.url' event.json)
44+
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
45+
46+
TITLE="Push to \`$REF_NAME\`"
47+
MESSAGE="$COMMIT_MSG"
48+
COLOR="good"
49+
URL="$COMMIT_URL"
50+
51+
FIELDS=$(jq -n \
52+
--arg sha "$SHORT_SHA" \
53+
--arg url "$COMMIT_URL" \
54+
--arg actor "$ACTOR" \
55+
'[
56+
{"title":"Commit", "value":"<\($url)|`\($sha)`>", "short":true},
57+
{"title":"Author", "value":$actor, "short":true}
58+
]')
59+
;;
60+
61+
pull_request)
62+
ACTION=$(jq -r '.action' event.json)
63+
PR_NUM=$(jq -r '.pull_request.number' event.json)
64+
PR_TITLE=$(jq -r '.pull_request.title' event.json)
65+
PR_BODY=$(jq -r '.pull_request.body // ""' event.json | head -c 200)
66+
MERGED=$(jq -r '.pull_request.merged' event.json)
67+
68+
URL=$(jq -r '.pull_request.html_url' event.json)
69+
MESSAGE=$(printf "*%s*\n%s" "$PR_TITLE" "$PR_BODY")
70+
71+
if [ "$MERGED" == "true" ]; then
72+
EMOJI="🎉"; TITLE="Merged PR #$PR_NUM"; COLOR="#6f42c1"
73+
elif [ "$ACTION" == "opened" ]; then
74+
EMOJI="📬"; TITLE="New PR #$PR_NUM"; COLOR="warning"
75+
elif [ "$ACTION" == "closed" ]; then
76+
EMOJI="🚫"; TITLE="Closed PR #$PR_NUM"; COLOR="#999999"
77+
else
78+
EMOJI="🔄"; TITLE="PR $ACTION #$PR_NUM"; COLOR="warning"
79+
fi
80+
81+
FIELDS=$(jq -n \
82+
--arg head "$(jq -r '.pull_request.head.ref' event.json)" \
83+
--arg base "$(jq -r '.pull_request.base.ref' event.json)" \
84+
'[
85+
{"title":"Branch", "value":"`\($head)` → `\($base)`", "short":true}
86+
]')
87+
;;
88+
89+
issue_comment)
90+
EMOJI="💬"
91+
ISSUE_NUM=$(jq -r '.issue.number' event.json)
92+
COMMENT_BODY=$(jq -r '.comment.body' event.json)
93+
URL=$(jq -r '.comment.html_url' event.json)
94+
COLOR="#007bff"
95+
96+
if [ "$(jq -r '.issue.pull_request != null' event.json)" == "true" ]; then
97+
TITLE="Comment on PR #$ISSUE_NUM"
98+
else
99+
TITLE="Comment on Issue #$ISSUE_NUM"
100+
fi
101+
102+
MESSAGE="$COMMENT_BODY"
103+
FIELDS="[]"
104+
;;
105+
106+
*)
107+
EMOJI="ℹ️"
108+
TITLE="Event: $EVENT_NAME"
109+
MESSAGE="Triggered by $ACTOR"
110+
URL="https://github.com/$REPO"
111+
FIELDS="[]"
112+
;;
113+
esac
114+
115+
# Payload 生成 (jqで安全に構築)
116+
PAYLOAD=$(jq -nc \
117+
--arg username "GitHub Notifications" \
118+
--arg icon ":github:" \
119+
--arg text "$EMOJI Notification from $REPO" \
120+
--arg color "$COLOR" \
121+
--arg title "$TITLE" \
122+
--arg url "$URL" \
123+
--arg message "$MESSAGE" \
124+
--arg footer "<https://github.com/$REPO|$REPO>" \
125+
--argjson fields "${FIELDS:-[]}" \
126+
--argjson ts "$TS" \
127+
'{
128+
username: $username,
129+
icon_emoji: $icon,
130+
text: $text,
131+
attachments: [{
132+
color: $color,
133+
title: $title,
134+
title_link: $url,
135+
text: $message,
136+
fields: $fields,
137+
footer: $footer,
138+
ts: $ts
139+
}]
140+
}')
141+
142+
# 送信処理(エラーハンドリング付き)
143+
HTTP_CODE=$(echo "$PAYLOAD" | curl -X POST -H 'Content-type: application/json' \
144+
-d @- "$SLACK_WEBHOOK_URL" \
145+
-w '%{http_code}' \
146+
-s -o /tmp/slack_response.txt)
147+
148+
if [ "$HTTP_CODE" -eq 200 ]; then
149+
echo "✅ Notification sent (HTTP 200)"
150+
else
151+
echo "::error::Failed to send notification. HTTP Code: $HTTP_CODE"
152+
cat /tmp/slack_response.txt
153+
exit 1
154+
fi

0 commit comments

Comments
 (0)