Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions .github/actions/slack-failure-notify/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: "Slack Notify on Failure"
description: "Send a notification to Slack when a job fails"
inputs:
webhook_url:
description: "Slack Webhook URL"
required: true
status:
description: "Job status (failure, success, etc.)"
required: false
default: "failure"

runs:
using: "composite"
steps:
- name: Send Notification
shell: bash
env:
SLACK_WEBHOOK_URL: ${{ inputs.webhook_url }}
STATUS: ${{ inputs.status }}
REPO: ${{ github.repository }}
WORKFLOW: ${{ github.workflow }}
run_id: ${{ github.run_id }}
run_number: ${{ github.run_number }}
actor: ${{ github.actor }}
ref_name: ${{ github.ref_name }}
sha: ${{ github.sha }}
server_url: ${{ github.server_url }}
run: |
# Webhook URL の検証
if [ -z "$SLACK_WEBHOOK_URL" ]; then
echo "::warning::SLACK_WEBHOOK_URL is not set. Skipping notification."
exit 0
fi

# 変数準備
SHORT_SHA="${sha:0:7}"
WORKFLOW_URL="${server_url}/${REPO}/actions/runs/${run_id}"
COMMIT_URL="${server_url}/${REPO}/commit/${sha}"

# タイトルと色の決定
if [ "$STATUS" == "success" ]; then
COLOR="good"
TITLE="✅ CI Succeeded"
ICON=":white_check_mark:"
else
COLOR="danger"
TITLE="🚨 CI Failed"
ICON=":x:"
fi

# JSONペイロードの構築 (jqを使用してエスケープ処理を自動化)
PAYLOAD=$(jq -nc \
--arg username "GitHub CI/CD" \
--arg icon "$ICON" \
--arg text "$TITLE" \
--arg color "$COLOR" \
--arg actor "$actor" \
--arg status "$STATUS" \
--arg workflow "$WORKFLOW" \
--arg workflow_url "$WORKFLOW_URL" \
--arg repo "$REPO" \
--arg repo_url "${server_url}/${REPO}" \
--arg branch "$ref_name" \
--arg commit_url "$COMMIT_URL" \
--arg short_sha "$SHORT_SHA" \
--arg run_number "$run_number" \
--argjson ts "$(date +%s)" \
'{
username: $username,
icon_emoji: $icon,
text: $text,
attachments: [
{
color: $color,
author_name: $actor,
title: ("Workflow " + $workflow + " " + $status),
title_link: $workflow_url,
fields: [
{ title: "Repository", value: ("<" + $repo_url + "|" + $repo + ">"), short: true },
{ title: "Branch", value: ("`" + $branch + "`"), short: true },
{ title: "Commit", value: ("<" + $commit_url + "|`" + $short_sha + "`>"), short: true },
{ title: "Run Number", value: ("#" + $run_number), short: true }
],
footer: ("<" + $workflow_url + "|👉 View Logs and Details>"),
footer_icon: "https://github.githubassets.com/favicon.ico",
ts: $ts
}
]
}'
)

# 送信実行
HTTP_CODE=$(echo "$PAYLOAD" | curl -X POST -H 'Content-type: application/json' \
-d @- "$SLACK_WEBHOOK_URL" \
-w '%{http_code}' \
-s -o /tmp/slack_response.txt)

if [ "$HTTP_CODE" -eq 200 ]; then
echo "✅ Notification sent (HTTP 200)"
else
echo "::error::Failed to send notification. HTTP Code: $HTTP_CODE"
cat /tmp/slack_response.txt
exit 1
fi
12 changes: 12 additions & 0 deletions .github/workflows/deploy-gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ jobs:
with:
path: ./docs

- name: Notify Slack on Failure
if: failure()
uses: ./.github/actions/slack-failure-notify
with:
webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}

deploy:
if: github.repository == 'tanzaku/postgresql-cst-parser'
needs: build
Expand All @@ -55,3 +61,9 @@ jobs:
if: ${{ !env.ACT }}
id: deployment
uses: actions/deploy-pages@v4

- name: Notify Slack on Failure
if: failure()
uses: ./.github/actions/slack-failure-notify
with:
webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
6 changes: 6 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,9 @@ jobs:
run: cargo clippy -p parser-generator -- -D warnings
- name: Clippy (postgresql-cst-parser)
run: cargo clippy -p postgresql-cst-parser -- -D warnings

- name: Notify Slack on Failure
if: failure()
uses: ./.github/actions/slack-failure-notify
with:
webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
154 changes: 154 additions & 0 deletions .github/workflows/slack-notify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
name: Slack Notification
on:
push:
branches: ["**"]
pull_request:
types: [opened, closed, reopened]
issue_comment:
types: [created]

jobs:
notify:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Send Notification to Slack
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
EVENT_NAME: ${{ github.event_name }}
REPO: ${{ github.repository }}
ACTOR: ${{ github.actor }}
EVENT_JSON: ${{ toJson(github.event) }}
run: |
if [ -z "$SLACK_WEBHOOK_URL" ]; then
echo "::warning::SLACK_WEBHOOK_URL is not set."
exit 0
fi

# イベント情報を一時ファイルへ保存 (クォート問題回避のため)
printf '%s' "$EVENT_JSON" > event.json

# 共通変数の設定
TS=$(date +%s)
COLOR="#999999"

# イベントごとの処理
case "$EVENT_NAME" in
push)
EMOJI="🚀"
REF_NAME="${GITHUB_REF_NAME}"
COMMIT_MSG=$(jq -r '.head_commit.message' event.json)
COMMIT_URL=$(jq -r '.head_commit.url' event.json)
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)

TITLE="Push to \`$REF_NAME\`"
MESSAGE="$COMMIT_MSG"
COLOR="good"
URL="$COMMIT_URL"

FIELDS=$(jq -n \
--arg sha "$SHORT_SHA" \
--arg url "$COMMIT_URL" \
--arg actor "$ACTOR" \
'[
{"title":"Commit", "value":"<\($url)|`\($sha)`>", "short":true},
{"title":"Author", "value":$actor, "short":true}
]')
;;

pull_request)
ACTION=$(jq -r '.action' event.json)
PR_NUM=$(jq -r '.pull_request.number' event.json)
PR_TITLE=$(jq -r '.pull_request.title' event.json)
PR_BODY=$(jq -r '.pull_request.body // ""' event.json | head -c 200)
MERGED=$(jq -r '.pull_request.merged' event.json)

URL=$(jq -r '.pull_request.html_url' event.json)
MESSAGE=$(printf "*%s*\n%s" "$PR_TITLE" "$PR_BODY")

if [ "$MERGED" == "true" ]; then
EMOJI="🎉"; TITLE="Merged PR #$PR_NUM"; COLOR="#6f42c1"
elif [ "$ACTION" == "opened" ]; then
EMOJI="📬"; TITLE="New PR #$PR_NUM"; COLOR="warning"
elif [ "$ACTION" == "closed" ]; then
EMOJI="🚫"; TITLE="Closed PR #$PR_NUM"; COLOR="#999999"
else
EMOJI="🔄"; TITLE="PR $ACTION #$PR_NUM"; COLOR="warning"
fi

FIELDS=$(jq -n \
--arg head "$(jq -r '.pull_request.head.ref' event.json)" \
--arg base "$(jq -r '.pull_request.base.ref' event.json)" \
'[
{"title":"Branch", "value":"`\($head)` → `\($base)`", "short":true}
]')
;;

issue_comment)
EMOJI="💬"
ISSUE_NUM=$(jq -r '.issue.number' event.json)
COMMENT_BODY=$(jq -r '.comment.body' event.json)
URL=$(jq -r '.comment.html_url' event.json)
COLOR="#007bff"

if [ "$(jq -r '.issue.pull_request != null' event.json)" == "true" ]; then
TITLE="Comment on PR #$ISSUE_NUM"
else
TITLE="Comment on Issue #$ISSUE_NUM"
fi

MESSAGE="$COMMENT_BODY"
FIELDS="[]"
;;

*)
EMOJI="ℹ️"
TITLE="Event: $EVENT_NAME"
MESSAGE="Triggered by $ACTOR"
URL="https://github.com/$REPO"
FIELDS="[]"
;;
esac

# Payload 生成 (jqで安全に構築)
PAYLOAD=$(jq -nc \
--arg username "GitHub Notifications" \
--arg icon ":github:" \
--arg text "$EMOJI Notification from $REPO" \
--arg color "$COLOR" \
--arg title "$TITLE" \
--arg url "$URL" \
--arg message "$MESSAGE" \
--arg footer "<https://github.com/$REPO|$REPO>" \
--argjson fields "${FIELDS:-[]}" \
--argjson ts "$TS" \
'{
username: $username,
icon_emoji: $icon,
text: $text,
attachments: [{
color: $color,
title: $title,
title_link: $url,
text: $message,
fields: $fields,
footer: $footer,
ts: $ts
}]
}')

# 送信処理(エラーハンドリング付き)
HTTP_CODE=$(echo "$PAYLOAD" | curl -X POST -H 'Content-type: application/json' \
-d @- "$SLACK_WEBHOOK_URL" \
-w '%{http_code}' \
-s -o /tmp/slack_response.txt)

if [ "$HTTP_CODE" -eq 200 ]; then
echo "✅ Notification sent (HTTP 200)"
else
echo "::error::Failed to send notification. HTTP Code: $HTTP_CODE"
cat /tmp/slack_response.txt
exit 1
fi