---
created: "2026-03-17"
type: resource
tags: [resource, engineering, workflow, azure-devops, jira, slack, billo]
source: "C:/Users/yaoji/git/Billo/release-workflow/SKILL.md"
---

# Billo Release & PR Review Workflow

## 概述

基于 Azure DevOps + Jira + Slack 的半自动化发布和 PR review 工作流。通过告知 Claude PR 链接或指令触发，自动执行 code review、Jira 状态变更、PR merge、release notes 生成、Slack 通知等操作。

## 工具栈

| 工具 | 用途 |
|------|------|
| Azure DevOps CLI (`az`) | PR 管理、repo 操作 |
| jira-cli v1.7.0 | Jira ticket 状态变更、link 记录 |
| jq | JSON 处理（release-staging.json）|
| Slack Incoming Webhook | 发送 release 通知 |
| git worktree | PR code review 隔离环境 |

## 配置信息

- **Jira**: https://billolife.atlassian.net
- **Azure DevOps**: https://dev.azure.com/billodev / Project: Billo App Platform
- **本地 Repo 根目录**: `C:/Users/yaoji/git/Billo/`
- **Skill 文件**: `C:/Users/yaoji/git/Billo/release-workflow/SKILL.md`
- **Staging 文件**: `C:/Users/yaoji/git/Billo/release-workflow/release-staging.json`
- **Release 归档**: `C:/Users/yaoji/git/Billo/release-workflow/releases/`

## Branch 命名规则

格式：`{任意前缀}/{TICKET_ID}_{description}`

```
feature/ALLPOST-4028_login-page
feat/ALLPOST-4028_login-page
bug/ALLPOST-4029_fix-logout-redirect
fix/ALLPOST-4030_crash
chore/ALLPOST-4031_cleanup
```

Ticket ID 提取正则：
```bash
TICKET_ID=$(echo "$BRANCH" | sed -E 's#[^/]+/([A-Z]+-[0-9]+)_.*#\1#')
```

## Jira 状态流转

```
Dev in Progress
      ↓  (PR 给 Claude review)
  code review
      ↓  (review 有 comment → REQUEST CHANGES)
Code review comment
      ↓  (review 通过 → 用户确认 merge)
Ready for stage (2)
      ↓  (release PR merge to main)
Done
```

---

## 触发关键词速查

| 你说的 | Claude 执行 |
|--------|------------|
| PR 链接 | 工作流一+四（review → 你确认 → merge + Jira + staging）|
| `"准备 release"` | 工作流二：创建 release PR |
| `"release PR merged"` | 工作流三：Jira Done + Slack + 归档 |

---

## 工作流一+四（合并）：PR Review + Merge

**触发**：给 Claude Azure DevOps PR 链接

### 阶段一：Review（自动执行）

```
1. 解析 PR URL → repo、branch、ticket ID
2. 移动 Jira ticket → "code review"（无 ticket ID 则跳过）
3. git fetch branch + 创建 worktree（C:/Users/yaoji/git/_reviews/pr-{PR_ID}）
4. code-reviewer agent 分析所有变更 .cs 文件
5. 输出结构化报告（CRITICAL / HIGH / MEDIUM / LOW）
```

**结果分支：**

```
       REQUEST CHANGES                    APPROVE
             ↓                               ↓
移动 Jira → "Code review comment"    告知用户，等待确认
列出所有 issues
等待开发者修复后重新提交
```

### 阶段二：Merge（用户确认后执行）

```
6.  Merge PR（az repos pr update --status completed）
7.  移动 Jira ticket → "Ready for stage (2)"
8.  在 Jira ticket 上记录 PR remote link
9.  获取 ticket summary
10. 计算版本号（releases/ 最新版本 patch +1）
11. 追加 ticket 信息到 release-staging.json
12. 清理 worktree
```

---

## 工作流二：准备 Release

**触发**：告知 Claude `"准备 release"`

**执行步骤**：
1. 读取 `release-staging.json`
2. 显示 ticket 列表供确认
3. 创建 `develop → main` PR，描述包含所有 ticket 列表

---

## 工作流三：Release 完成

**触发**：告知 Claude `"release PR merged"`

**执行步骤**：
1. Merge release PR
2. 所有 ticket 状态移动 → `Done`
3. 发送 Slack 通知
4. 归档 `release-staging.json` → `releases/vX.X.X.json`
5. 重置 `release-staging.json` 准备下个版本

**Slack 消息格式**（rich_text Block Kit）：

```
Release - Billo.Platform.Document (2026-03-17)   ← 加粗标题
• ALLPOST-4219  Test release bot                  ← bullet + 可点击 Jira 链接
• ALLPOST-4220  Fix login redirect
```

> [!important]
> 使用 Slack `rich_text` Block Kit（非 `mrkdwn`），避免 Windows 环境下 emoji 和中文乱码，bullet 和换行正常渲染。

---

## release-staging.json 格式

```json
{
  "version": "v1.0.0",
  "repo": "Billo.Platform.Document",
  "started_at": "2026-03-17",
  "tickets": [
    {
      "id": "ALLPOST-4219",
      "summary": "Test release bot",
      "pr_id": "10460",
      "pr_url": "https://dev.azure.com/billodev/...",
      "pr_title": "chore: trigger release bot test",
      "branch": "feature/ALLPOST-4219_test_release_bot",
      "merged_at": "2026-03-17"
    }
  ]
}
```

## 版本号规则

- 自动从 `releases/` 目录读取最新版本，patch +1
- 例：最新 `v1.0.2` → 下个版本 `v1.0.3`
- 首次（`releases/` 为空）→ `v1.0.0`

---

## 环境变量（~/.bashrc）

```bash
export JIRA_API_TOKEN="..."
export JIRA_AUTH_TYPE=basic
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
export AZURE_DEVOPS_EXT_PAT="..."
export PATH="/c/Program Files/Microsoft SDKs/Azure/CLI2/wbin:/c/Users/yaoji/AppData/Local/Microsoft/WinGet/Links:/c/Users/yaoji/bin:/usr/bin:/bin:$PATH"
```

## Related

- [[OpenClaw-Skill-Reference]]
- [[Everything Claude Code 完整指南]]
