| name | gitcode-pr |
| description | GitCode 仓库 PR 提交流程。可作为独立 subagent 运行。覆盖:创建 Issue、分支、提交、创建 PR、合并。 |
GitCode PR 提交流程
运行模式
模式 A:Subagent 模式(推荐)
作为独立 subagent 被 arkweb-architect 调用时,文件列表和提交信息已在 task 描述中提供,直接执行。
输入格式(从 task 描述中解析):
## 待提交文件
{文件路径列表}
## 提交信息
- Issue 标题:docs: {feature-name} — {description}
- Commit message: docs: {description}\n\n- {change_1}\n- {change_2}\n\nCo-Authored-By:Agent\nSigned-off-by: {git config user.name} <{git config user.email}>
- PR body: 方案概述 + 评审记录 + Closes #{issue_number}
- 分支名:docs/{feature-name}
## 仓库配置
- 仓库:{owner}/{docs_repo}
- 本地路径:{project_root}
- Token:从环境变量读取(优先 `GITCODE_TOKEN`,回退 `GITLAB_TOKEN`)
输出: Issue + PR 创建结果 → 回复 URL 和状态
模式 B:交互模式
在主 session 中直接调用,每步确认后执行。
概述
所有代码提交到 GitCode 仓库必须遵循 Issue → 分支 → 提交 → PR 流程,禁止直接 push 到 master。
仓库配置
| 仓库 | GitCode 路径 | 本地路径 |
|---|
| AI 辅助设计 | {owner}/{docs_repo} | {project_root} |
| AI Dashboard | {owner}/{dashboard_repo} | {project_root} |
| 鸿蒙知识库 | openharmony-ai-design/oh-ai-full-design | 见 memory |
API 配置
- Token: 优先 ,回退 (环境变量或 文件)
- API 基础路径:
https://gitcode.com/api/v5
- 认证方式:
PRIVATE-TOKEN header
- 调用工具: 必须使用 Python 3
urllib(见下方说明)
变量定义
| 变量 | 含义 | 取值方式 |
|---|
FORK_OWNER | fork 仓库的 owner(GitCode 用户名) | 从 git remote URL 中解析:git remote get-url origin → 提取 owner 部分(如 git@gitcode.com:{FORK_OWNER}/chromium_src.git) |
推荐使用 Python 3 urllib 调用 GitCode repos API。 部分环境的 curl(如 7.81.0)在 HTTPS 模式下可能无法正确发送 PRIVATE-TOKEN header 到 GitCode 的 /repos 路径(HTTP/2 网关兼容性问题)。如果 Python 3 不可用,可使用 curl --http1.1 强制 HTTP/1.1 作为降级方案。
标准 API 调用模板
所有 GitCode API 调用使用以下 Python 模板:
python3 -c "
import urllib.request, json, os
token = os.environ.get('GITCODE_TOKEN') or os.environ.get('GITLAB_TOKEN') or exit('Error: set GITCODE_TOKEN or GITLAB_TOKEN')
base = 'https://gitcode.com/api/v5/repos/{owner}/{repo}'
# --- 按需替换以下部分 ---
url = f'{base}/issues'
data = json.dumps({'title': 'TITLE', 'body': 'BODY'}).encode()
method = 'POST'
# --- 替换结束 ---
req = urllib.request.Request(url, data=data, method=method)
req.add_header('PRIVATE-TOKEN', token)
req.add_header('Content-Type', 'application/json')
try:
resp = urllib.request.urlopen(req, timeout=30)
result = json.loads(resp.read().decode())
print(json.dumps(result, ensure_ascii=False, indent=2))
except urllib.error.HTTPError as e:
print(f'HTTP {e.code}: {e.read().decode()[:500]}')
"
多仓库 PR 协调规则
ArkWeb 项目涉及 3 个仓库的协同提交,必须遵循以下规则:
仓库清单
| 仓库 | 上游原仓 | fork 仓库 | 本地路径 | 默认 base |
|---|
| chromium_src | openharmony-tpc/chromium_src | {FORK_OWNER}/chromium_src | {SKILL_HOME}/src | 132_trunk |
| web_webview | openharmony/web_webview | {FORK_OWNER}/web_webview | {SKILL_HOME}/deps_code/webview | master |
| arkui_ace_engine | openharmony/arkui_ace_engine | {FORK_OWNER}/arkui_ace_engine | {SKILL_HOME}/deps_code/arkui_ace_engine | master |
Issue 分组规则
同一层级的仓库共用一个 Issue,不同层级使用独立 Issue:
| 层级 | 仓库 | Issue 创建位置 |
|---|
| 引擎层 | chromium_src(独立) | openharmony-tpc/chromium_src |
| 框架层 | web_webview + arkui_ace_engine(共用) | openharmony/web_webview(在 web_webview 仓库创建,ace_engine PR 中引用同一 Issue 链接) |
PR 方向规则
所有 PR 必须从 fork 指向上游原仓,禁止 fork 内部自合并:
正确:
{FORK_OWNER}/chromium_src:feat/xxx → openharmony-tpc/chromium_src:132_trunk
{FORK_OWNER}/web_webview:feat/xxx → openharmony/web_webview:master
{FORK_OWNER}/arkui_ace_engine:feat/xxx → openharmony/arkui_ace_engine:master
错误:
{FORK_OWNER}/chromium_src:feat/xxx → {FORK_OWNER}/chromium_src:master
PR 模板强制读取规则
创建 PR body 之前,必须先读取目标仓库的 PR 模板文件。 不同仓库的模板路径和格式不同:
| 仓库 | 模板路径 |
|---|
| chromium_src | .gitcode/PULL_REQUEST_TEMPLATE.zh-CN.md |
| web_webview | .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md |
| arkui_ace_engine | .gitcode/PULL_REQUEST_TEMPLATE.md |
模板读取失败或未找到时,使用本 skill 中的默认模板。
标准提交流程顺序
1. 在每个仓库创建分支 → 提交代码 → push 到 fork 远程
2. 创建 Issue(按分组规则)
3. 读取每个仓库的 PR 模板
4. 填充模板 + 关联 Issue + 设计文档索引
5. 创建跨仓库 PR(fork → 上游原仓)
6. 互相在 PR body 中引用关联 PR 链接
标准流程
Step 0: 创建 Issue(前置必须)
创建 PR 前必须先创建 Issue。 Issue 是 PR 的追溯入口,不可跳过。
Issue 创建规则:
- 按上述「Issue 分组规则」确定在哪个仓库创建
- 同一层级的仓库共用一个 Issue
- 不同层级使用独立 Issue
- Issue body 应包含:需求描述、涉及仓库列表、关联 PR(创建后回填)
python3 -c "
import urllib.request, json, os
token = os.environ.get('GITCODE_TOKEN') or os.environ.get('GITLAB_TOKEN') or exit('Error: set GITCODE_TOKEN or GITLAB_TOKEN')
url = 'https://gitcode.com/api/v5/repos/{owner}/{repo}/issues'
data = json.dumps({'title': ISSUE_TITLE, 'body': ISSUE_BODY}).encode()
req = urllib.request.Request(url, data=data, method='POST')
req.add_header('PRIVATE-TOKEN', token)
req.add_header('Content-Type', 'application/json')
resp = urllib.request.urlopen(req, timeout=15)
result = json.loads(resp.read().decode())
print(f'Issue #{result[\"number\"]}: {result[\"html_url\"]}')
"
Issue 命名规范:
- 文档类:
docs: {简要描述}
- 功能类:
feat: {简要描述}
- 修复类:
fix: {简要描述}
- 重构类:
refactor: {简要描述}
Step 2: 创建分支并提交
cd {本地仓库路径}
git checkout master && git pull origin master
git checkout -b {type}/{short-description}
git add -A
SIGN_OFF=$(git config user.name && echo " <$(git config user.email)>")
git commit -m "{type}: {subject}
- {detail_1}
- {detail_2}
Co-Authored-By:Agent
Signed-off-by: ${SIGN_OFF}"
git push -u origin {type}/{short-description}
分支命名规范: docs/xxx / feat/xxx / fix/xxx / refactor/xxx
Commit message 规范(Conventional Commits):
type: subject
- 详细变更项 1
- 详细变更项 2
Co-Authored-By:Agent
Signed-off-by: {user.name} <{user.email}>
必填项:
Co-Authored-By:Agent — 固定格式,无尖括号无邮箱
Signed-off-by: — 使用 git config user.name 和 git config user.email 的值
Step 3: 创建 PR
创建 PR 前必须读取仓库的 PR 模板,用实际内容填充后作为 body 提交。
PR body 组成规则:
-
读取模板:从仓库本地路径读取 PR 模板文件(按优先级查找):
.gitcode/PULL_REQUEST_TEMPLATE.zh-CN.md
.gitcode/PULL_REQUEST_TEMPLATE.md
.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md
.gitee/PULL_REQUEST_TEMPLATE.md
.github/PULL_REQUEST_TEMPLATE.md
PULL_REQUEST_TEMPLATE.md
- 若以上均不存在,使用默认模板(见下方)
-
填充模板:将模板中的占位项替换为实际内容:
- 关联 Issue →
Closes #N
- 修改描述 → 需求概述 + 涉及仓库 + 变更摘要
- 入库必检项 → 按实际情况填写
- 检视闭环 → 是/否
-
附加设计文档索引:在 body 末尾附加本次工作流产出的设计文档清单,格式如下:
---
## 设计文档
- 需求提案:[proposal.md]({DOCS_REPO_URL}/blob/master/docs/features/{feature-name}/proposal.md)
- 需求基线:[{date}-{feature}-requirement.md]({DOCS_REPO_URL}/blob/master/docs/features/{feature-name}/{date}-{feature}-requirement.md)
- 架构设计:[{date}-{feature}-design.md]({DOCS_REPO_URL}/blob/master/docs/features/{feature-name}/{date}-{feature}-design.md)
- 方案评审:[{date}-{feature}-brainstorm.md]({DOCS_REPO_URL}/blob/master/docs/features/{feature-name}/{date}-{feature}-brainstorm.md)
- 设计评审:[{date}-{feature}-review.md]({DOCS_REPO_URL}/blob/master/docs/features/{feature-name}/{date}-{feature}-review.md)
- 统一规格:[spec.md]({DOCS_REPO_URL}/blob/master/docs/features/{feature-name}/spec.md)
- 代码分析:[{date}-{feature}-analysis.md]({DOCS_REPO_URL}/blob/master/analysis/{date}-{feature}-analysis.md)
- Committer 检视:[{date}-{feature}-committer-review.md]({DOCS_REPO_URL}/blob/master/docs/features/{feature-name}/{date}-{feature}-committer-review.md)
{DOCS_REPO_URL} 为 {docs_repo} 仓库的 GitCode Web URL。如果设计文档不在 GitCode 仓库中,使用本地绝对路径。
默认模板(无仓库模板时使用):
### 关联的issue:
Closes #N
### 修改描述:
{需求概述}
涉及仓库:{仓库名列表}
### 入库必检项
是否涉及非兼容变更: {是/否}
TDD自验结果: {Pass/Fail/不涉及}
XTS自验结果: {Pass/Fail/不涉及}
检视意见是否都已闭环: {是/否}
调用示例:
python3 -c "
import urllib.request, json, os
token = os.environ.get('GITCODE_TOKEN') or os.environ.get('GITLAB_TOKEN') or exit('Error: set GITCODE_TOKEN or GITLAB_TOKEN')
url = 'https://gitcode.com/api/v5/repos/{owner}/{repo}/pulls'
# body 内容由模板填充 + 设计文档索引组合而成
body = TEMPLATE_CONTENT + '\n\n---\n\n## 设计文档\n' + DOCS_INDEX
data = json.dumps({
'title': 'PR标题',
'head': '源分支名',
'base': '132_trunk', // chromium_src 用 132_trunk,其他仓库用 master
'body': body
}).encode()
req = urllib.request.Request(url, data=data, method='POST')
req.add_header('PRIVATE-TOKEN', token)
req.add_header('Content-Type', 'application/json')
resp = urllib.request.urlopen(req, timeout=30)
result = json.loads(resp.read().decode())
print(f'PR #{result[\"number\"]}: {result[\"html_url\"]}')
"
注意事项:
- 跨仓库 PR(fork → 上游):POST 到上游原仓的
/pulls 端点,head 参数必须带 owner 前缀,格式为 {fork_owner}:{branch_name}。切勿 POST 到 fork 仓库自身,否则会创建 fork 内部自合并 PR。
- 关联 Issue 在 body 中写
Closes #N
- 端点是
/pulls,不是 /merge_requests
- 创建 PR 可能较慢(后端需计算 diff),timeout 设为 30 秒
- body 内容必须包含模板填充 + 设计文档索引两部分
- 504 Backend timeout 时先查询再重试:超时可能已在服务端创建成功,先查
GET /pulls?state=open&head={branch} 确认,避免重复创建
Step 4: 合并 PR
Subagent 模式: 不自动合并,等待主 session 决策 4 确认。
交互模式: 如果用户要求合并:
python3 -c "
import urllib.request, json, os
token = os.environ.get('GITCODE_TOKEN') or os.environ.get('GITLAB_TOKEN') or exit('Error: set GITCODE_TOKEN or GITLAB_TOKEN')
url = 'https://gitcode.com/api/v5/repos/{owner}/{repo}/pulls/{pr_number}/merge'
req = urllib.request.Request(url, method='PUT')
req.add_header('PRIVATE-TOKEN', token)
req.add_header('Content-Type', 'application/json')
resp = urllib.request.urlopen(req, timeout=30)
result = json.loads(resp.read().decode())
print(f'PR merged: {result.get(\"state\", \"merged\")}')
"
GitCode API 速查
| 操作 | 方法 | 端点 |
|---|
| 创建 Issue | POST | /repos/{owner}/{repo}/issues |
| 关闭 Issue | PATCH | /repos/{owner}/{repo}/issues/{number} |
| 创建 PR | POST | /repos/{owner}/{repo}/pulls |
| 关闭 PR | PATCH | /repos/{owner}/{repo}/pulls/{number} |
| 获取 PR | GET | /repos/{owner}/{repo}/pulls/{number} |
| 合并 PR | PUT | /repos/{owner}/{repo}/pulls/{number}/merge |
关闭 Issue/PR 注意事项:
- 使用
PATCH 方法,不是 PUT
- 参数为
state_event: close(不是 state: closed)
state_event 只接受 close 或 reopen
错误处理
- 404 on
/pulls: 确认使用 repos/{owner}/{repo}/pulls
- 409: 同一分支已有 PR,检查现有 PR
- 400 body不能为空: Issue 创建时 body 至少填 "test"
- 504 Backend timeout: PR 创建超时,重试即可(可能已创建成功,先查询再重试)
- 405 Method Not Allowed: 检查 HTTP 方法是否正确(关闭操作用 PATCH,不是 PUT)
- Token 失效: 检查 或 环境变量是否设置
自动化检查清单
Subagent 回复格式
✅ gitcode-pr 完成
📋 Issue: #{number} — {title}
🔀 PR: #{number} — {title}
🔗 PR URL: {url}
📂 分支: {branch_name}
📊 状态: {open/merged}