cnb-rs pr edit
cnb-rs pr edit <NUMBER> [flags]大一统修改 PR 属性:一次性改标题 / 描述 / 评审人 / 处理人 / 标签,借鉴 gh pr edit 的设计哲学。所有需要的 API 调用并发执行(tokio::join_all),任一失败立即累计并以非零退出码结束。
pr update是本命令的别名(向后兼容现有脚本),新代码请直接用pr edit。
选项
文本字段
-t, --title <TITLE>:修改标题-b, --body <BODY>:修改描述
评审人 / 处理人
--add-reviewer <USERNAME>:添加评审人(可重复传或逗号分隔;CNB 限单次最多 8 人)--remove-reviewer <USERNAME>:移除评审人--add-assignee <USERNAME>:添加处理人(同上限制)--remove-assignee <USERNAME>:移除处理人
标签(三组互斥)
--add-label <NAME>:增量添加标签--remove-label <NAME>:按 name 移除标签(CNB API 单次只能删一个,CLI 循环调)--set-labels <NAME,NAME>:全量替换所有标签;与--add/--remove/--clear互斥--clear-labels:清空所有标签;与其它 label flag 互斥
互斥规则由 clap 在 flag 层校验,违反时 exit 2 + 友好错误信息。
至少需要传一个修改 flag,否则报错(避免误用「光给 NUMBER 不带任何 flag」)。
继承的全局选项:
--repo <REPO>:指定仓库路径(格式:group/repo)--domain <DOMAIN>:指定目标域名(默认:cnb.cool)
输出约定
- stderr:
⚙ 正在并发执行 N 个修改操作...:执行前显示总数- 每个成功的操作打
✓ 已更新 <op>(op 是title/body/add-reviewer/remove-label等) - 每个失败的操作打
✗ <op> 失败:<err> - 全部完成后如果有失败再打
错误: K 个修改操作失败(成功 M)
- stdout:始终输出 PR URL(即使部分失败,给 URL 让用户去 Web 端继续处理)
- 退出码:全部成功 → 0;任一失败 → 1;clap 参数错误 → 2
示例
bash
# 改标题 + 加 reviewer + 加 label,一次性提交三个并发请求
$ cnb-rs pr edit 42 \
-t "feat: 新增 OAuth2 登录" \
--add-reviewer alice,bob \
--add-label feature,priority-high
⚙ 正在并发执行 3 个修改操作...
✓ 已更新 title/body
✓ 已更新 add-reviewer
✓ 已更新 add-label
https://cnb.cool/org/repo/-/pulls/42
# 全量替换标签
$ cnb-rs pr edit 42 --set-labels feature,wip
# 清空所有标签
$ cnb-rs pr edit 42 --clear-labels
# 只改 body
$ cnb-rs pr edit 42 -b "$(cat NEW_DESCRIPTION.md)"
# 移除处理人 + 加另一人,原子完成
$ cnb-rs pr edit 42 --remove-assignee alice --add-assignee bob
# 不带任何 flag:报错
$ cnb-rs pr edit 42
错误: 至少要传一个修改选项:-t/-b/--add-X/--remove-X/--set-labels/--clear-labels
# 互斥 flag:clap 在 flag 层拒绝
$ cnb-rs pr edit 42 --add-label bug --set-labels foo
error: the argument '--add-label <NAME>' cannot be used with '--set-labels <NAME>'API 调用映射
CLI flag 各自对应独立的 endpoint,按需调;没传的 flag 完全不发请求:
| flag | API | 方法 |
|---|---|---|
-t/-b 任一 | ${API}/repos/{repo}/-/pulls/{n} | PATCH |
--add-reviewer | ${API}/repos/{repo}/-/pulls/{n}/reviewers | POST |
--remove-reviewer | ${API}/repos/{repo}/-/pulls/{n}/reviewers | DELETE(with body) |
--add-assignee | ${API}/repos/{repo}/-/pulls/{n}/assignees | POST |
--remove-assignee | ${API}/repos/{repo}/-/pulls/{n}/assignees | DELETE(with body) |
--add-label | ${API}/repos/{repo}/-/pulls/{n}/labels | POST |
--remove-label <X> | ${API}/repos/{repo}/-/pulls/{n}/labels/{X} | DELETE × N(循环) |
--set-labels | ${API}/repos/{repo}/-/pulls/{n}/labels | PUT |
--clear-labels | ${API}/repos/{repo}/-/pulls/{n}/labels | DELETE |
所有 future 用 futures::future::join_all 并发;同一 PR 上不同 endpoint 互不冲突。
为什么不像 issue 模块拆 4 个子命令组?
issue 用 issue assigners {get/add/remove/set} / issue label {list/add/set/remove/clear} / issue properties {get/set/list} 多个 CRUD 子命令组。pr 走 gh CLI 的大一统路线:
- 命令更少(13 个子命令 vs 拆出来后的 20+)
- 多属性一次性变更更高效(创建 PR 时常见场景:title + label + reviewer 三件套)
- 学习成本更低(
--help一次看完所有可改属性) - issue 模块已稳定不重构;两个模块的设计哲学差异在
.windsurf/docs/2026-05-17-pr-design.md§1 说明
状态切换不在 edit 范围
pr edit 不修改 PR 状态(state)。请用专门的命令:
老的 pr update --state flag 已在本版本移除(P0-2 时已 deprecate warning)。