From 5c2b094fbea20a3259caf458ab2fb87791549ca4 Mon Sep 17 00:00:00 2001 From: kawabuchi4280 Date: Thu, 12 Feb 2026 17:31:31 +0900 Subject: [PATCH 1/5] ~enhancement add slack notification --- .github/actions/slack-notify/action.yml | 105 ++++++++++++++++ .github/workflows/deploy-gh-pages.yml | 12 ++ .github/workflows/rust.yml | 6 + .github/workflows/slack-notify.yml | 154 ++++++++++++++++++++++++ 4 files changed, 277 insertions(+) create mode 100644 .github/actions/slack-notify/action.yml create mode 100644 .github/workflows/slack-notify.yml diff --git a/.github/actions/slack-notify/action.yml b/.github/actions/slack-notify/action.yml new file mode 100644 index 0000000..86c9c2d --- /dev/null +++ b/.github/actions/slack-notify/action.yml @@ -0,0 +1,105 @@ +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 + # 警告にとどめ、CI自体は落とさない + exit 0 + fi diff --git a/.github/workflows/deploy-gh-pages.yml b/.github/workflows/deploy-gh-pages.yml index 3d9a4a6..47ac439 100644 --- a/.github/workflows/deploy-gh-pages.yml +++ b/.github/workflows/deploy-gh-pages.yml @@ -43,6 +43,12 @@ jobs: with: path: ./docs + - name: Notify Slack on Failure + if: failure() + uses: ./.github/actions/slack-notify + with: + webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} + deploy: if: github.repository == 'tanzaku/postgresql-cst-parser' needs: build @@ -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-notify + with: + webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 3fc4a59..42e2eb9 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -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-notify + with: + webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml new file mode 100644 index 0000000..3b8a1e4 --- /dev/null +++ b/.github/workflows/slack-notify.yml @@ -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="*$PR_TITLE*\n$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 "" \ + --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 From 18bfb4ec5f295619972a83f6cb7b081587002389 Mon Sep 17 00:00:00 2001 From: kawabuchi4280 Date: Thu, 12 Feb 2026 17:40:05 +0900 Subject: [PATCH 2/5] ~modify message --- .github/workflows/slack-notify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/slack-notify.yml b/.github/workflows/slack-notify.yml index 3b8a1e4..9ffc9eb 100644 --- a/.github/workflows/slack-notify.yml +++ b/.github/workflows/slack-notify.yml @@ -66,7 +66,7 @@ jobs: MERGED=$(jq -r '.pull_request.merged' event.json) URL=$(jq -r '.pull_request.html_url' event.json) - MESSAGE="*$PR_TITLE*\n$PR_BODY" + MESSAGE=$(printf "*%s*\n%s" "$PR_TITLE" "$PR_BODY") if [ "$MERGED" == "true" ]; then EMOJI="🎉"; TITLE="Merged PR #$PR_NUM"; COLOR="#6f42c1" From 6507020134dc2fb8d7c4e962768f0170fee4b73f Mon Sep 17 00:00:00 2001 From: kawabuchi4280 Date: Thu, 12 Feb 2026 19:11:32 +0900 Subject: [PATCH 3/5] ~modify rename action --- .../actions/{slack-notify => slack-failure-notify}/action.yml | 3 +-- .github/workflows/deploy-gh-pages.yml | 4 ++-- .github/workflows/rust.yml | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) rename .github/actions/{slack-notify => slack-failure-notify}/action.yml (97%) diff --git a/.github/actions/slack-notify/action.yml b/.github/actions/slack-failure-notify/action.yml similarity index 97% rename from .github/actions/slack-notify/action.yml rename to .github/actions/slack-failure-notify/action.yml index 86c9c2d..fed46b6 100644 --- a/.github/actions/slack-notify/action.yml +++ b/.github/actions/slack-failure-notify/action.yml @@ -100,6 +100,5 @@ runs: else echo "::error::Failed to send notification. HTTP Code: $HTTP_CODE" cat /tmp/slack_response.txt - # 警告にとどめ、CI自体は落とさない - exit 0 + exit 1 fi diff --git a/.github/workflows/deploy-gh-pages.yml b/.github/workflows/deploy-gh-pages.yml index 47ac439..cb610a0 100644 --- a/.github/workflows/deploy-gh-pages.yml +++ b/.github/workflows/deploy-gh-pages.yml @@ -45,7 +45,7 @@ jobs: - name: Notify Slack on Failure if: failure() - uses: ./.github/actions/slack-notify + uses: ./.github/actions/slack-failure-notify with: webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} @@ -64,6 +64,6 @@ jobs: - name: Notify Slack on Failure if: failure() - uses: ./.github/actions/slack-notify + uses: ./.github/actions/slack-failure-notify with: webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 42e2eb9..da0f92a 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -35,6 +35,6 @@ jobs: - name: Notify Slack on Failure if: failure() - uses: ./.github/actions/slack-notify + uses: ./.github/actions/slack-failure-notify with: webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }} From 60db137690eec5c4902680d3f74d3db821a07647 Mon Sep 17 00:00:00 2001 From: kawabuchi4280 Date: Thu, 12 Feb 2026 19:13:02 +0900 Subject: [PATCH 4/5] (test) force test CI failure --- .github/workflows/rust.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index da0f92a..280078d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -14,6 +14,8 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Force fail (temp) + run: exit 1 - name: Build run: cargo build --verbose - name: Run tests From 9b935e568f31f33b997adb2b0fe8fbbeb8909af2 Mon Sep 17 00:00:00 2001 From: kawabuchi4280 Date: Thu, 12 Feb 2026 19:14:25 +0900 Subject: [PATCH 5/5] ~modify revert test CI --- .github/workflows/rust.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 280078d..da0f92a 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -14,8 +14,6 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Force fail (temp) - run: exit 1 - name: Build run: cargo build --verbose - name: Run tests