config(git): 引入develop长期开发分支模型和git工作流自动化

This commit is contained in:
2026-06-11 15:24:38 +08:00
parent 3b851a195e
commit ac7a3abda9
12 changed files with 781 additions and 72 deletions
+37 -1
View File
@@ -148,7 +148,43 @@ node .claude/skills/gitea-collab/gitea.js --role reviewer issue labels <number>
---
## 7. 汇报模板
## 7. PR 查询
非 PM 角色可以查看 PR 状态(创建和合并由 PM 负责):
```bash
# 列出 PR
node .claude/skills/gitea-collab/gitea.js --role <角色名> pr list
# 查看 PR 详情
node .claude/skills/gitea-collab/gitea.js --role <角色名> pr get <number>
```
---
## 8. Git 工作流
所有 agent 在 `develop` 长期开发分支上工作:
```bash
# 开始工作时:确保在 develop 上
bash .claude/scripts/git-workflow.sh ready
# 提交代码/文档
bash .claude/scripts/git-workflow.sh commit <type> <scope> "中文描述"
# 推送到远程
bash .claude/scripts/git-workflow.sh push
# 查看当前状态
bash .claude/scripts/git-workflow.sh status
```
详见 `.claude/refs/GIT-GUIDE-LITE.md` 的"自动化工作流"章节。
---
## 9. 汇报模板
### 策划汇报
+21
View File
@@ -222,6 +222,27 @@ class GiteaAPI {
});
}
// ====== Pull Requests ======
listPullRequests(params = {}) {
return this.request('GET', '/pulls', null, { state: 'open', limit: 50, ...params });
}
getPullRequest(number) {
return this.request('GET', `/pulls/${number}`);
}
createPullRequest(data) {
return this.request('POST', '/pulls', data);
}
mergePullRequest(number, data = {}) {
return this.request('POST', `/pulls/${number}/merge`, {
Do: data.style || 'merge',
...data,
});
}
// ====== 辅助方法 ======
/** 通过名称查找标签,返回 ID(不存在则返回 null) */
+83
View File
@@ -520,6 +520,84 @@ cmd.pipeline = {
},
};
// ──────── pr ────────
cmd.pr = {
async list(api, opts) {
const params = {};
if (opts.options.state) params.state = opts.options.state;
if (opts.options.base) params.base = opts.options.base;
if (opts.options.head) params.head = opts.options.head;
const prs = await api.listPullRequests(params);
out(prs);
if (!opts.options.json) {
outText(`\n🔀 Pull Requests (${prs.length || 0})\n`);
if (!prs || !prs.length) { outText(' (无)'); return; }
table(
['#', '标题', '状态', 'Base', 'Head', '合并'],
prs.map(p => [
p.number,
truncate(p.title, 35),
p.state,
p.base?.ref || '—',
p.head?.ref || '—',
p.merged ? '✅' : '—',
])
);
}
},
async get(api, opts) {
const num = opts.rest[0];
if (!num) { fail('用法: pr get <number>'); return; }
const pr = await api.getPullRequest(num);
out(pr);
if (!opts.options.json) {
outText(`\n🔀 PR #${pr.number}: ${pr.title}`);
outText(` 状态: ${pr.state}`);
outText(` ${pr.base?.ref} ← ${pr.head?.ref}`);
outText(` 合并: ${pr.merged ? '✅ 已合并' : '❌ 未合并'}`);
if (pr.body) {
outText(`\n--- Body ---\n${pr.body.slice(0, 500)}${pr.body.length > 500 ? '…' : ''}`);
}
}
},
async create(api, opts) {
const base = opts.options.base || 'main';
const head = opts.options.head;
const title = opts.options.title;
const body = opts.options.body || '';
if (!head || !title) {
fail('用法: pr create --head <分支> --title "标题" [--base main] [--body "描述"]');
return;
}
const pr = await api.createPullRequest({ base, head, title, body });
out(pr);
if (!opts.options.json) {
ok(`PR #${pr.number} 已创建: ${pr.title}`);
outText(` ${pr.html_url}`);
}
},
async merge(api, opts) {
const num = opts.rest[0];
if (!num) { fail('用法: pr merge <number> [--style merge|squash|rebase]'); return; }
const style = opts.options.style || 'merge';
const pr = await api.getPullRequest(num);
if (pr.merged) { fail(`PR #${num} 已合并,无需重复操作`); return; }
if (pr.mergeable === false) { fail(`PR #${num} 存在冲突,无法自动合并。请先解决冲突。`); return; }
const result = await api.mergePullRequest(num, { style });
out(result);
if (!opts.options.json) ok(`PR #${num} 已合并 (${style})`);
},
};
// ──────── test ────────
cmd.test = {
@@ -682,6 +760,11 @@ Gitea CLI — 项目管理工具
pipeline status 查看当前流水线进度
pipeline update <#> 更新 Pipeline 字段 --field <阶段|当前迭代> --value <值>
pr list 列出 Pull Requests [--state open|closed|all] [--base <分支>] [--head <分支>]
pr get <#> 查看 PR 详情
pr create 创建 PR --head <分支> --title "标题" [--base main] [--body "描述"]
pr merge <#> 合并 PR [--style merge|squash|rebase]
test 验证所有 API 接口
角色自动映射:
+30 -1
View File
@@ -218,7 +218,36 @@ Pipeline Tracker 是一个 Meta Issue,仅记录**无法从 Issue/Milestone 推
---
## 8. 标签体系
## 8. PR 操作(发布合并)
迭代完成时,PM 负责创建 develop → main 的 PR:
```bash
# 列出当前 PR
node .claude/skills/gitea-pm/gitea.js --role pm pr list
# 创建发布 PR
bash .claude/scripts/git-workflow.sh release "迭代名称"
# 或手动创建
node .claude/skills/gitea-pm/gitea.js --role pm pr create \
--base main --head develop \
--title "Merge develop → main: 迭代名称" \
--body "发布描述"
# 查看 PR 详情
node .claude/skills/gitea-pm/gitea.js --role pm pr get <number>
# 合并 PR(用户审查确认后)
node .claude/skills/gitea-pm/gitea.js --role pm pr merge <number> --style merge
# 合并后同步
bash .claude/scripts/git-workflow.sh post-release
```
---
## 9. 标签体系
从 `gitea-config.json` 的 `labels` 字段定义。`label init` 命令从此配置创建标签。
+21
View File
@@ -222,6 +222,27 @@ class GiteaAPI {
});
}
// ====== Pull Requests ======
listPullRequests(params = {}) {
return this.request('GET', '/pulls', null, { state: 'open', limit: 50, ...params });
}
getPullRequest(number) {
return this.request('GET', `/pulls/${number}`);
}
createPullRequest(data) {
return this.request('POST', '/pulls', data);
}
mergePullRequest(number, data = {}) {
return this.request('POST', `/pulls/${number}/merge`, {
Do: data.style || 'merge', // merge | squash | rebase
...data,
});
}
// ====== 辅助方法 ======
/** 通过名称查找标签,返回 ID(不存在则返回 null) */
+86
View File
@@ -520,6 +520,87 @@ cmd.pipeline = {
},
};
// ──────── pr ────────
cmd.pr = {
async list(api, opts) {
const params = {};
if (opts.options.state) params.state = opts.options.state;
if (opts.options.base) params.base = opts.options.base;
if (opts.options.head) params.head = opts.options.head;
const prs = await api.listPullRequests(params);
out(prs);
if (!opts.options.json) {
outText(`\n🔀 Pull Requests (${prs.length || 0})\n`);
if (!prs || !prs.length) { outText(' (无)'); return; }
table(
['#', '标题', '状态', 'Base', 'Head', '合并'],
prs.map(p => [
p.number,
truncate(p.title, 35),
p.state,
p.base?.ref || '—',
p.head?.ref || '—',
p.merged ? '✅' : '—',
])
);
}
},
async get(api, opts) {
const num = opts.rest[0];
if (!num) { fail('用法: pr get <number>'); return; }
const pr = await api.getPullRequest(num);
out(pr);
if (!opts.options.json) {
outText(`\n🔀 PR #${pr.number}: ${pr.title}`);
outText(` 状态: ${pr.state}`);
outText(` ${pr.base?.ref} ← ${pr.head?.ref}`);
outText(` 合并: ${pr.merged ? '✅ 已合并' : '❌ 未合并'}`);
outText(` 创建: ${pr.created_at?.slice(0, 10)}`);
outText(` 更新: ${pr.updated_at?.slice(0, 10)}`);
if (pr.body) {
outText(`\n--- Body ---\n${pr.body.slice(0, 500)}${pr.body.length > 500 ? '…' : ''}`);
}
}
},
async create(api, opts) {
const base = opts.options.base || 'main';
const head = opts.options.head;
const title = opts.options.title;
const body = opts.options.body || '';
if (!head || !title) {
fail('用法: pr create --head <分支> --title "标题" [--base main] [--body "描述"]');
return;
}
const pr = await api.createPullRequest({ base, head, title, body });
out(pr);
if (!opts.options.json) {
ok(`PR #${pr.number} 已创建: ${pr.title}`);
outText(` ${pr.html_url}`);
}
},
async merge(api, opts) {
const num = opts.rest[0];
if (!num) { fail('用法: pr merge <number> [--style merge|squash|rebase]'); return; }
const style = opts.options.style || 'merge';
// 先检查 PR 状态
const pr = await api.getPullRequest(num);
if (pr.merged) { fail(`PR #${num} 已合并,无需重复操作`); return; }
if (pr.mergeable === false) { fail(`PR #${num} 存在冲突,无法自动合并。请先解决冲突。`); return; }
const result = await api.mergePullRequest(num, { style });
out(result);
if (!opts.options.json) ok(`PR #${num} 已合并 (${style})`);
},
};
// ──────── test ────────
cmd.test = {
@@ -682,6 +763,11 @@ Gitea CLI — 项目管理工具
pipeline status 查看当前流水线进度
pipeline update <#> 更新 Pipeline 字段 --field <阶段|当前迭代> --value <值>
pr list 列出 Pull Requests [--state open|closed|all] [--base <分支>] [--head <分支>]
pr get <#> 查看 PR 详情
pr create 创建 PR --head <分支> --title "标题" [--base main] [--body "描述"]
pr merge <#> 合并 PR [--style merge|squash|rebase]
test 验证所有 API 接口
角色自动映射: