終結站會
讀取昨天的 Linear 議題與 GitHub 提交記錄,整理成站會更新,並發佈到 Slack。
步驟 1:設定檢查
確認必要的環境變數已設定:
echo "LINEAR_API_KEY: ${LINEAR_API_KEY:+set}"
echo "SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL:+set}"
echo "GITHUB_REPO: ${GITHUB_REPO:-not set}"
echo "GITHUB_USERNAME: ${GITHUB_USERNAME:-not set}"
如果缺少 LINEAR_API_KEY: 停止。告訴使用者:「需要 LINEAR_API_KEY。請至 Linear → 設定 → API → 個人 API 金鑰取得,並加入至您的 .env 檔案。」
如果缺少 SLACK_WEBHOOK_URL: 停止。告訴使用者:「需要 SLACK_WEBHOOK_URL。請在 api.slack.com/apps → 您的應用程式 → 傳入 Webhook 中建立一個 Webhook,並加入至您的 .env 檔案。」
如果缺少 GITHUB_REPO: 繼續。將跳過 GitHub 提交記錄。向使用者說明此情況。
步驟 2:擷取 Linear 活動
計算昨天的日期,格式為 ISO 8601(例如 2026-04-09T00:00:00.000Z)。
取得目前使用者 ID:
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: Bearer $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "query { viewer { id name email } }"}'
從回應中擷取 id 欄位,儲存為 LINEAR_USER_ID。
擷取指派給我的議題(自昨天起有更新):
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: Bearer $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "query($since: DateTime!, $userId: ID!) { issues(first: 50, filter: { assignee: { id: { eq: $userId } } updatedAt: { gte: $since } }) { edges { node { identifier title state { name } url completedAt updatedAt createdAt } } } }",
"variables": {"since": "YESTERDAY_ISO", "userId": "LINEAR_USER_ID"}
}'
分類議題:
completedAt不為 null → 完成state.name為「In Progress」、「Started」或「In Review」→ 進行中state.name為「Cancelled」→ 跳過state.name為「Todo」或「Backlog」→ 跳過(未處理)
如果沒有議題:註記「昨天沒有 Linear 活動。」
步驟 3:擷取 GitHub 提交記錄
如果未設定 GITHUB_REPO,則靜默跳過此步驟。
如果設定了 GITHUB_REPO:
gh api "repos/$GITHUB_REPO/commits?author=${GITHUB_USERNAME:-$(gh api user --jq .login)}&since=YESTERDAY_ISO&per_page=30" \
--jq '[.[] | {message: .commit.message, url: .html_url}]'
處理提交記錄:
- 擷取每個提交訊息的第一行(第一個換行符之前的內容)
- 跳過合併提交:捨棄任何以「Merge」開頭的訊息
- 依訊息文字去重
如果已設定 GITHUB_REPO 但未傳回任何提交記錄:註記「昨天沒有找到提交記錄。」
步驟 4:格式化站會
在撰寫之前,完整閱讀 references/standup-format.md。
按照以下確切結構產出站會:
**完成**
- [ENG-123] 已完成議題的標題
- fix: commit message here
**進行中**
- [ENG-124] 進行中議題的標題
**阻礙**
無阻礙。
來自 standup-format.md 的規則:
- 不使用第一人稱代名詞(「我」、「我們」)
- 完成項目使用過去式,進行中項目使用現在進行式
- 每個 Linear 項目使用
[IDENTIFIER] Title格式 - 每個 GitHub 提交記錄使用提交訊息的第一行
- 如果沒有完成項目:在「完成」下寫「無已完成項目。」
- 如果沒有進行中項目:在「進行中」下寫「無進行中項目。」
- 如果沒有阻礙:寫「無阻礙。」
- 總字數少於 200 字
步驟 5:發佈到 Slack 或輸出
將格式化後的站會呈現給使用者。
詢問:「要發佈到 Slack,還是僅輸出?」
確認發佈時:
curl -s -X POST "$SLACK_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*站會 — DATE_HERE*\n\n*完成*\nITEMS\n\n*進行中*\nITEMS\n\n*阻礙*\nITEMS"
}
}
]
}'
使用暫存檔或 heredoc 傳遞內文,以避免 shell 引用問題(提交訊息或議題標題中的特殊字元):
cat > /tmp/standup-payload.json << 'ENDJSON'
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "STANDUP_CONTENT_HERE"
}
}
]
}
ENDJSON
curl -s -X POST "$SLACK_WEBHOOK_URL" -H "Content-Type: application/json" -d @/tmp/standup-payload.json
發佈完成後:「站會已發佈。」
選擇「僅輸出」時: 在程式碼區塊中輸出站會,方便複製貼上。