CI 通知

在 CI/CD 流程中直接使用 discli 將建置狀態、部署警示與測試摘要發送到 Discord。

問題背景

團隊已在 Discord 協作,但部署通知仍散落在 GitHub、郵件或獨立工具,造成關鍵通知被忽略,開發者可能錯過失敗部署,也不知道生產環境目前正在執行什麼。

解法

在 CI/CD 流程中加入 discli,避免額外的 webhook 或 bot 架構,僅需 pip install discord-cli-agent 並在最後執行 discli message send

完整可執行範例

基本部署通知

name: 部署並通知
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 部署到正式環境
run: |
# 在此加入你的部署步驟
echo "部署中..."
- name: 通知 Discord(成功)
if: success()
env:
DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
run: |
pip install discord-cli-agent
discli message send "#deploys" "版本 **${{ github.sha }}** 已成功部署到 production。分支:\`${{ github.ref_name }}\` | 作者:${{ github.actor }} | [查看提交](https://github.com/${{ github.repository }}/commit/${{ github.sha }})"
- name: 通知 Discord(失敗)
if: failure()
env:
DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
run: |
pip install discord-cli-agent
discli message send "#deploys" "版本 **${{ github.sha }}** 部署 **失敗**。分支:\`${{ github.ref_name }}\` | 作者:${{ github.actor }} | [檢視執行結果](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})"

含測試摘要

name: 測試並通知
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 執行測試
id: tests
run: |
# 執行測試並擷取摘要
python -m pytest --tb=short 2>&1 | tee test-output.txt
echo "result=${PIPESTATUS[0]}" >> $GITHUB_OUTPUT
- name: 通知 Discord
if: always()
env:
DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
run: |
pip install discord-cli-agent
# 抓取 pytest 最後 3 行摘要
SUMMARY=$(tail -3 test-output.txt | tr '\n' ' ')
if [ "${{ steps.tests.outputs.result }}" = "0" ]; then
STATUS="通過"
else
STATUS="失敗"
fi
discli message send "#ci" "**測試 ${STATUS}**:PR #${{ github.event.pull_request.number }}|${{ github.event.pull_request.title }}
\`\`\`
${SUMMARY}
\`\`\`
[檢視 PR](https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}) | [檢視執行結果](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})"
stages:
- deploy
- notify
deploy:
stage: deploy
script:
- echo "部署中..."
notify_success:
stage: notify
when: on_success
variables:
DISCORD_BOT_TOKEN: $DISCORD_BOT_TOKEN
script:
- pip install discord-cli-agent
- discli message send "#deploys" "版本 ${CI_COMMIT_SHORT_SHA} 已成功部署到 production。分支:${CI_COMMIT_REF_NAME} | 作者:${GITLAB_USER_LOGIN}"
notify_failure:
stage: notify
when: on_failure
variables:
DISCORD_BOT_TOKEN: $DISCORD_BOT_TOKEN
script:
- pip install discord-cli-agent
- discli message send "#deploys" "版本 ${CI_COMMIT_SHORT_SHA} 部署 **失敗**。分支:${CI_COMMIT_REF_NAME} | [檢視 pipeline](${CI_PIPELINE_URL})"
#!/bin/bash
# ci-notify.sh — 可重複使用的 CI 通知腳本。
# 用法:./ci-notify.sh <status> <channel> [details]
STATUS="${1:?用法:$0 <success|failure> <channel> [details]}"
CHANNEL="${2:?用法:$0 <status> <channel> [details]}"
DETAILS="${3:-無其他補充資訊。}"
COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
AUTHOR=$(git log -1 --format='%an' 2>/dev/null || echo "unknown")
TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M UTC")
if [ "$STATUS" = "success" ]; then
ICON="**[SUCCESS]**"
else
ICON="**[FAILURE]**"
fi
MESSAGE="${ICON} 版本 \`${COMMIT}\`,分支 \`${BRANCH}\`,作者 ${AUTHOR},時間 ${TIMESTAMP}
${DETAILS}"
discli message send "$CHANNEL" "$MESSAGE"

在任一 CI 系統直接呼叫:

Terminal window
# 成功
./ci-notify.sh success "#deploys" "142 項測試全部通過。"
# 失敗
./ci-notify.sh failure "#deploys" "驗證模組中有 3 項測試失敗。"

逐步解說

在 CI 秘密參數中存放機器人權杖

將機器人權杖加入 CI 的密鑰管理:

  • GitHub Actions: Settings(設定)> Secrets and variables(祕密與變數)> Actions > New repository secret(新增儲存庫祕密),名稱 DISCORD_BOT_TOKEN
  • GitLab CI: Settings > CI/CD > Variables,名稱 DISCORD_BOT_TOKEN,並標註為 masked

discli 會自動讀取 DISCORD_BOT_TOKEN 環境變數,不必再額外執行 discli config set

Danger

不要在工作流程檔中硬編碼機器人權杖,也不要將其提交到原始碼庫。務必使用 CI 平台的密鑰機制。

在 CI 環境安裝 discli

在發送通知前先執行 pip install discord-cli-agent,安裝 CLI 與必要相依(discord.py、click)。

- run: pip install discord-cli-agent
Tip

可快取 pip 套件,或固定版本加快執行:pip install discord-cli-agent==X.Y.Z

送出通知

使用 discli message send 指定頻道與訊息內容。discli 會自動解析 #deploys 對應的頻道 ID。

Terminal window
discli message send "#deploys" "abc1234 部署到正式環境完成。"

訊息支援 Markdown,Discord 會渲染粗體、斜體、程式碼區塊與連結。

分開處理成功與失敗

以條件式步驟在成功與失敗時推送不同訊息:

# GitHub Actions 條件
- if: success() # 只在前一步成功時執行
- if: failure() # 只在前一步失敗時執行
- if: always() # 不論結果都執行

即使部署步驟當機,也能保證失敗資訊仍會送到團隊。

每次部署建立討論串模式

在高頻部署場景,可為每次部署建立一條討論串,避免主頻道雜亂:

#!/bin/bash
# deploy-thread.sh — 每次部署建立一個討論串,儲存完整資訊。
CHANNEL="#deploys"
COMMIT=$(git rev-parse --short HEAD)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
# 發送初始訊息
RESULT=$(discli --json message send "$CHANNEL" "版本 \`${COMMIT}\`\`${BRANCH}\`)開始部署...")
MSG_ID=$(echo "$RESULT" | jq -r '.id')
# 依該訊息建立討論串
THREAD=$(discli --json thread create "$CHANNEL" "$MSG_ID" "部署 ${COMMIT}")
THREAD_ID=$(echo "$THREAD" | jq -r '.id')
# 在討論串貼上詳細資訊
discli thread send "$THREAD_ID" "**提交:** \`${COMMIT}\`
**分支:** \`${BRANCH}\`
**作者:** $(git log -1 --format='%an')
**訊息:** $(git log -1 --format='%s')
**時間:** $(date -u +\"%Y-%m-%d %H:%M UTC\")"
# ... 執行部署 ...
# 回報結果
if deploy_command_here; then
discli thread send "$THREAD_ID" "部署於 $(elapsed_time) 秒內**完成**。"
else
discli thread send "$THREAD_ID" "部署**失敗**。請檢查 CI 日誌取得細節。"