ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Gitee自动创建PR与评审模式实践:脚本化工作流全解析

2026/10/5 4:21:01 拓冰建站 浏览量
Gitee自动创建PR与评审模式实践:脚本化工作流全解析 不知道你们团队是不是也有这样的场景代码写完推到远端接下来就是打开Gitee页面选源分支选目标分支写标题写描述然后在右侧一堆候选人名单里翻半天评审人……一次两次还能忍要是赶上迭代发布日七八个分支同时要提测你站在工位前一个一个地点鼠标点完这个忘了那个最后还得靠群消息一个个催评审。我自己被这个流程折磨过两三次之后索性写了个脚本把“自动创建PR”这件事变成了一条命令行的事同时配合仓库的评审模式让每次合入主干之前都必须有评审人明确审批通过。这篇文章就是这套玩法的完整落地记录里面有Gitee的API细节、评审模式的机制拆解也有我跑了上百次自动PR之后攒下的各种坑希望对正打算给团队规范PR流程的同学有帮助。1. 一个发布日让我决定“不手点PR了”1.1 团队里的PR流程原来一直是靠人肉完成的先说说背景。我那会儿带一个前后端一体的项目组代码都放在Gitee的私有仓库里。平时大家新建功能分支开发开发完推到远端然后按照流程要求发起PR指定至少一位评审人等评审通过再合入develop分支。这套流程听上去很标准但真正跑起来才发现问题全出在“创建PR”这个动作本身太依赖手工操作了。举个最典型的例子每次迭代收尾需求列表里可能有七八个关联MR分支这些分支对应的功能已经联调完就差发起PR到测试分支。这时候你就得挨个打开网页选源分支、选目标分支、写标题、粘贴描述模板、再找评审人。一个PR从打开页面到创建完成手快也得两三分钟七八个就是二十分钟起步。如果哪一步选错了目标分支或者漏指派了评审人回来还要反复修改、重新通知一天的时间就这么被磨掉了。更气人的是这种事情没有任何技术含量纯粹是重复劳动。我当时就在想既然创建PR的本质就是一次API调用那为什么不能让脚本替我干这件事Gitee官方有开放API网上其实也早有人封装过类似工具但多少跟我们的内部工作流分支命名规范、固定评审人名单、PR描述模板对不上最终还是得自己写一个合适的。1.2 为什么这次要单独把“评审模式”拎出来说我当时想做的不仅是用脚本创建PR而是想让创建出来的PR在“评审模式”这套规则下跑起来。如果你仔细看Gitee的仓库设置会发现PR的合入方式是可以配置的默认大家用的都是“普通模式”也就是任何人只要有权限打开PR页面就能直接点合并按钮。这对大团队来说其实是一个很大的隐患代码有没有被评审过、有没有CI状态卡着全靠个人自觉。我一直主张把“合入”这件事从“个人自觉”变成“规则强制”。为什么因为人都会偷懒迭代一忙起来评审这个环节往往会被人跳过。今天你忙不好意思麻烦别人直接把自己写的代码合进主干明天他也有样学样。等到上线前review代码才发现这波合入里混着各种没经过评审的改动想回退都难。Gitee的评审模式本质上就是在仓库层面对“谁可以合入、什么条件下可以合入”做了一套规则约束必须至少有指定数量的评审人审批通过合并按钮才会生效。这套机制如果只是靠网页端手动操作顶多是给流程加了道锁但一旦跟自动创建PR的脚本结合起来团队日常协作就会变成一条很顺的流水线代码推到远端脚本自动把PR建好并指派评审人评审人收到通知审批通过后合入。这就是我在标题里把“自动创建PR”和“评审模式”放在一起的原因这两件事分开看都只是工具合起来才是完整的工作流。2. 评审模式的基础机制三种PR模式到底差在哪2.1 Gitee仓库里PR合入方式的三种形态要理解评审模式得先看Gitee仓库的PR设置。在仓库的“管理”-“Pull Request设置”里合入方式通常会区分成三种它们的差异直接决定了合并按钮的显示逻辑和审批流程模式合入门槛适用的团队状态主要风险普通模式有仓库写权限即可直接合并小团队、极简流程没有强制评审容易直接带病合入仅评论模式不强制评审人审批有评论即可合入团队有评审习惯但不希望太严格评论不等于认可本质还是走过场评审模式必须有指定数量评审人审批通过合并按钮才可用中大型团队、需要代码质量管控流程严需要配合自动化提升效率我见过不少团队一开始用的是“普通模式”觉得大家关系好、互相信任不需要什么审批。但项目一旦到了三四个人以上普通模式就撑不住了。因为“信任”在代码评审面前是靠不住的人再细心也总有盲区规则本身才是兜底的东西。所以后来我们直接把仓库切到了评审模式并且把最少评审人数设置成了1人。2.2 评审模式的几个关键规则细节评审模式不是简单地“加一个确认弹窗”Gitee在落地这套机制时有几个细节特别值得注意。第一个细节是最少评审人数的限制。仓库管理员可以设置合并一个PR至少需要几位评审人“同意”才允许合入。这个数字不是摆设它会直接参与合并按钮的可用性计算。比如你设置了1人那么只要PR没有被任何一位指定的评审人approve即便你拥有仓库管理员权限合并按钮也可能会被置灰必须在评审人点击“同意”之后按钮才会恢复可点状态。第二个细节是指派评审人的逻辑。网页端创建PR时右侧会有一个评审人的选择框你可以指定仓库内的成员作为这个PR的评审人。但注意只有被指派的评审人他的approve操作才会被计入“已通过评审”的计数。换句话说如果你没有指派任何评审人哪怕仓库里其他人主动去评论“1”也是不算数的。这跟代码评审的直觉不太一样我第一次也是没搞明白以为只要有人评论就行了结果PR就一直卡在“待评审”状态合并不了。第三个细节是评审意见类型。Gitee的PR评审动作通常区分成“评论”“请求变更”“同意”几类。在评审模式下只有“同意”这个动作会计入通过数量。“请求变更”则会重置评审通过状态相当于评审人叫停了这个PR你需要重新修改提交后再次发起评审。这个逻辑跟行业里常见代码评审平台的做法是一致的用起来没有学习成本。2.3 评审模式为什么适合跟自动化配合把评审模式单独拎出来看它其实是给“自动化合入”提供了一套安全护栏。如果只是单纯地用脚本自动创建PR但没有评审模式兜底这个PR创建完之后依然有可能被某个人直接点掉合并按钮整个评审流程就形同虚设。反过来如果只有评审模式但没有自动化每次创建PR和指派评审人都会变成团队的时间黑洞。这两者结合起来的效果是最舒服的脚本负责把“创建PR、指定评审人、填好描述”这种机械动作干掉评审模式负责把关“谁同意、谁合入”。开发者的注意力只需要集中在真正的代码评审上而不是在界面上来回找按钮。后面第三、四章我会分别讲这两部分的实现细节。3. 自动创建PR的脚本方案关键API与幂等处理3.1 环境准备与Token获取要调Gitee的API首先要准备一个私人令牌Personal Access Token。入口在Gitee右上角头像-设置-安全设置-私人令牌。创建时可以勾选一系列权限范围对自动创建PR这个场景核心权限是pulls和projects前者用来操作PR后者用来读取仓库信息。获取Token的时候有两点容易踩坑。第一Token只会完整显示一次关闭弹窗后就再也看不到了一定要当场复制下来存好第二Token的权限范围建议遵循最小化原则如果只是做自动创建PR没必要勾选admin之类的全套权限。权限开得太大万一脚本或者机器被攻破后端仓库的管理风险就会成倍放大。准备好Token之后接下来就是直接调接口。Gitee开放API的Base URL是https://gitee.com/api/v5创建PR的接口是POST /repos/{owner}/{repo}/pulls这个owner可以是用户名也可以是组织名。下面是一个我实际在用的最小化Python脚本去掉了多余的业务逻辑保留了最核心的调用链路import requests GITEE_API https://gitee.com/api/v5 TOKEN 你的_access_token_字符串 OWNER 你的用户名或组织名 REPO 你的仓库名 def create_pr(owner, repo, title, head, base, body, reviewers, tokenTOKEN): url f{GITEE_API}/repos/{owner}/{repo}/pulls data { access_token: token, title: title, head: head, # 源分支名例如 feature/login base: base, # 目标分支名例如 develop body: body, reviewer: ,.join(reviewers), } resp requests.post(url, jsondata) if resp.status_code 201: pr resp.json() return pr[number], pr[html_url] else: raise RuntimeError(f创建PR失败: HTTP {resp.status_code} - {resp.text}) if __name__ __main__: number, url create_pr( OWNER, REPO, titlerelease/1.2.0 合并到 master, headrelease/1.2.0, basemaster, body## 变更内容\n\n- 登录模块重构\n- 订单列表性能优化, reviewers[zhangsan, lisi], ) print(fPR #{number}: {url})这个脚本比较直观head是你要合入的源分支base是目标分支reviewer是评审人列表传Gitee登录用户名多个用逗号分隔。body里可以直接用Markdown写PR描述团队如果有固定的描述模板可以在把这部分接到你们的发布流程之前先组装好。3.2 幂等处理防止脚本重复创建PR脚本能跑起来只是第一步。真正拿到生产环境用首先要解决的是幂等问题。我最初把它接到内部发布工具上时遇到过一个很尴尬的情况网络超时。脚本请求创建PRGitee服务端其实已经创建成功了但响应超时脚本这边收到的是Timeout异常。按照我当时写的逻辑异常就是失败于是自动重试结果同一个源分支和目标分支被创建出了两个PR。开发群里一下子吵翻了天两个PR的评审人不一样大家不知道该在哪个上面评审。后来我在创建PR之前加了一步查询先调用GET /repos/{owner}/{repo}/pulls?stateopen拉取当前仓库所有open状态的PR列表在代码里用head和base字段做幂等判断。如果已经存在一个源分支和目标分支都匹配的open PR直接返回已存在的PR编号不再重复创建。def find_existing_pr(owner, repo, head, base, tokenTOKEN): url f{GITEE_API}/repos/{owner}/{repo}/pulls params {access_token: token, state: open} resp requests.get(url, paramsparams) prs resp.json() for pr in prs: pr_head pr[head][ref] pr_base pr[base][ref] if pr_head head and pr_base base: return pr return None这里有一个值得注意的边界情况如果源分支是来自Fork仓库的pr[head][ref]只是分支名但此时可能存在同名分支在不同的fork仓库里。判断时最好连pr[head][repo][full_name]一起比对避免找错对象。我们的业务用不到fork仓库所以脚本里只比对分支名就够了但如果你的团队开放了外部贡献者提交建议把这层校验补全。有了幂等查询之后整个创建流程就变成了三步先查已存在PR存在就返回不存在就创建创建成功后把结果写入日志。这一步做完脚本才算真正达到了可以无人值守的状态。3.3 创建后的进阶参数标签、里程碑与自动指派除了创建PR本身Gitee的API还支持创建后二次修改部分属性比如给PR设置标签、关联里程碑。这个功能在版本分支自动化时非常有用。比如我们内部有一条自动化发布流水线版本分支release/1.2.0推送之后脚本自动创建PR到master同时给这个PR打上release标签关联当前的里程碑。这样评审人在PR列表里一眼就能看出哪些PR是发版相关的不用点进去看描述才知道。def update_pr(owner, repo, pr_number, labelsNone, milestoneNone, tokenTOKEN): url f{GITEE_API}/repos/{owner}/{repo}/pulls/{pr_number} data {access_token: token} if labels: data[labels] ,.join(labels) if milestone: data[milestone] milestone resp requests.patch(url, jsondata) if resp.status_code 200: return resp.json() raise RuntimeError(f更新PR失败: {resp.status_code} - {resp.text})为什么要单独拆一个更新方法而不是在创建时一股脑传参一方面是因为Gitee的创建接口有些属性不支持直接传另一方面是策路上更安全——先创建核心PR确保基础流程跑通再附加标签和里程碑即便附加步骤失败PR也已经创建完成不会阻断开发流程。另外还有一个容易被忽略的点**Gitee API创建PR时传的reviewer参数在创建后如果把评审人改掉旧的评审人记录会丢失。**所以如果你需要在创建后动态调整评审人建议在创建时就一次把评审人定对不要先创建后改。评审人这个属性在创建之后修改的成本比其他字段都高这也是我在实际项目里多次调整后才惊讶地发现的一个隐藏行为。4. 把自动创建与评审模式串进团队工作流4.1 触发方式从手动执行到事件驱动脚本写完之后接下来要解决的是“什么时候跑”的问题。我调研和尝试过几种方式按自动化程度从低到高排列触发方式优点缺点适合场景手动执行命令行可控性强随时可以跑依赖人记得用还是会漏脚本初期的灰度测试定时任务Crontab/定时器无需人工干预分支没准备好时会空转固定发版时间的操作CI流水线/构建后步骤紧跟代码推送事件需要有可用的CI环境团队日常开发主流程Webhook事件监听实时性最强需要单独部署监听服务对自动化时效要求高的团队我自己最终的落地方案是CI流水线触发。我们的代码托管在GiteeCI用的是Gitee官方提供的Gitee Go。在流水线里加一个Shell步骤在测试任务通过之后执行自动创建PR脚本。这样每次功能分支推上来只要单测过了脚本就自动把PR建好、指派人、打标签。一个迭代下来团队成员几乎不需要手动去网页上创建PR所有人的注意力都放在评审上。如果你所在团队的CI不在Gitee生态里比如用的是Jenkins思路也一样在构建任务里加一步执行脚本。关键点是这一步必须放在测试通过之后否则一旦构建失败或者测试挂了PR也照建不误反而给评审人带去无效通知。4.2 评审模式下合并门槛变高了谁来兜底配置了评审模式后PR合入的规则就变了必须有人approve合并按钮才可用。但这引出一个新问题万一创建PR时忘了指派评审人或者指派的评审人一直不审PR就永远卡在那里。我们团队的解法是在自动创建PR的脚本里加上人工兜底逻辑。脚本每次创建完PR除了默认指派两位固定评审人之外还会在企业微信群里推一条消息把PR的链接和标题发出来并对应的评审人。这一步操作和PR创建本身脱钩即使Gitee端审批提醒因为各种原因没送达群里这条消息也能形成二次提醒。类似的通知渠道你们可以用飞书、钉钉或者邮件总之不要让PR创建完就“石沉大海”。另外还有一个经验评审模式下仓库管理员Owner拥有“无视评审人数限制直接合并”的权限。这意味着一旦等得急了管理员完全可以跳过评审直接点合并。但一定要警惕这个权限在制度上明确一点——管理员不在万不得已的情况下不要轻易行使这个权限。因为底线一旦破例评审模式的公信力就没了所有人都会想着“反正最后都能强推合入”评审流程会重新沦为空谈。4.3 一条完整链路的实际长什么样我把这套机制跑顺之后整个协作链路看起来是这个样子开发者在本地新建功能分支比如feature/order-list-opt开发完推到Gitee远端。Gitee Go流水线自动触发依次执行代码格式化检查、单元测试、打包构建。构建成功后流水线里的Shell步骤执行自动创建PR脚本脚本判断没有同分支同目标的已有PR于是创建 PRheadfeature/order-list-opt、basedevelop指定评审人。脚本同时给这个PR打上feature标签并把PR链接推送企业微信。评审人打开PR查看代码点击“同意”。评审通过后合并按钮从灰色变成可用状态开发者或管理员点击合并功能分支合入 develop。这套链路跑通之后团队里“手动创建PR”这个动作基本消失了除非有人需要跨仓库协作才会偶尔回到网页操作。每一次合入都有对应的PR记录PR状态里都保留了审批人、审批时间、变更内容审计追溯也变得无比清晰。需要特别说明的一点是如果你把评审模式配置成“需要1人通过”但同时又开了分支保护策略那么PR会在“CI检查状态”和“评审状态”两个条件都满足之后才显示合并按钮。如果CI本身要跑很久或者CI配置失败了整个PR就会卡在“等待检查”的状态。这个不算bug而是平台自身的策略组合理解这个逻辑之后排查问题会快很多。5. 运行上百次自动PR我踩过的那些坑5.1 权限相关的坑403和404的错觉自动创建PR跑起来之后第一个遇到的典型报错是HTTP 403 Forbidden。现象是脚本每次执行都返回403但同样的账号在网页端明明可以正常创建PR。排查之后才意识到是Token权限范围的问题。Gitee的私人令牌在创建的时候可以勾选若干权限域我一开始为了方便只勾了projects漏掉了pulls。结果就是读取仓库信息正常一旦调创建PR的接口就403。解决办法很简单去私人令牌设置里重新生成Token把pulls权限勾上。但注意旧Token不能直接升级权限只能重新生成一个新的。还有一个更误导人的情况如果你在API里传的仓库名不对Gitee有时候会返回404而不是403。我一开始以为是权限问题调了半天Token最后发现是仓库名大小写不对。API路径里的仓库名必须跟Gitee上显示的大小写保持一致否则接口直接找不到目标仓库。错误码常见原因解决思路401Token无效或已过期检查Token是否被吊销或重新生成后再覆盖403Token缺少pulls权限 / 无仓库写权限重新生成Token补齐权限确认账号角色404仓库名写错 / 仓库不存在核对仓库owner和repo拼写含大小写422参数不合法 / head与base相同检查分支名、确保源分支已推送远端5.2 reviewer传的是登录名不是昵称更不是邮箱这个坑我纠结了整整一个上午。脚本跑通之后我抱着试试看的心态创建了一个测试PR指定的评审人是我自己结果PR创建成功后打开页面发现评审人那一栏是空的。我起初以为reviewer的传参格式错了换成邮箱再试还是不行换成中文昵称接口直接报422。后来查文档才彻底弄明白reviewer这个参数要传的是Gitee的登录用户名也就是用户唯一标识不是你在仓库里看到的显示昵称也不是邮箱地址。举个栗子同事平时在Gitee上叫“张三”但他的登录用户名可能是张三的拼音加一串数字比如zhangsan_1024。你在接口里传“张三”是没用的必须传zhangsan_1024这个登录名。获取登录名的方式很简单让团队成员打开自己的Gitee个人主页URL路径最后那一串基本就是登录名。还有更直接的办法调一下Gitee的用户搜索接口返回字段里的login字段就是。这个坑带来的教训是脚本里所有评审人的信息不要让人手工输入最好维护一个独立的配置文件键值对形如“姓名:登录名”到时候脚本直接读取否则每次换一个评审人就要问一遍“你的用户名是什么”效率极其感人。5.3 fork仓库的head参数格式差异如果你的团队有外部贡献者PR的head参数写法会跟同仓库的分支不一样。同仓库场景下head直接写分支名就行比如feature/login但如果源分支来自一个fork仓库head要写成fork_owner:branch_name的格式比如external_user:feature/login。我一开始没注意这个格式差异写了个脚本处理所有仓库的自动创建PR结果在外部贡献者的pr上报了422排查半天才发现是head格式问题。如果你用官方API文档的经验来判断实际上是很容易漏掉的细节因为同一个字段在不同场景下格式不同而文档一般只给一两个示例。解决思路是脚本在执行时先判断源分支是否来自fork仓库如果是就把head重构成fork_owner:branch_name的格式。判断方法也不复杂调一下仓库的branches接口看返回里的commit归属即可或者直接读取你在网页端复制分支链接时的URL格式。5.4 mergeable状态创建成功不等于可以合入这个坑是发生在把自动创建PR接到CI流水线之后我们的流水线要求PR创建成功之后马上对其进行自动合并但脚本在创建后立刻调用合并接口反而返回了409冲突。后来我在Gitee API返回的PR对象里发现了一个字段叫mergeable它表示当前PR是否具备合入条件。这个字段在PR刚创建的时候并不会立刻变成true因为平台需要时间去计算分支差异和冲突情况。如果你在创建PR后的瞬间就尝试合并平台可能还没完成冲突检测导致结果不可靠。我的做法是加了一个轮询逻辑创建PR之后每隔5秒查询一次PR详情直到mergeable不再为null或状态明确为止。如果mergeable为false说明有冲突这时候就要通知开发者去处理而不是强行合并。这个轮询的等待时间通常不会超过10秒但在大仓库上如果分支差异很大计算耗时有可能拉长所以轮询超时时间要留足。5.5 评审模式下的“合并按钮凭空消失”现象这个坑是在一次线上事故中暴露的。当时我们的自动化流水线已经跑得很顺畅一切看起来都很正常。突然有一天发布有位同事反馈PR看起来一切正常有评审人也approve了但合并按钮就是不可点击。大家一度认为是Gitee平台出了Bug。后来逐项排查才发现问题的根源在仓库设置里。我们当时给那个仓库同时配置了评审模式最少1人通过和一组分支保护策略。分支保护策略里要求PR必须关联至少一个issue而自动创建的PR没有关联任何issue。于是合并条件就卡在了“关联issue”这个隐含规则上。这个问题的排查思路其实有参考价值当你发现合并按钮异常不可点不要先怀疑平台而要从四个方向去检查——是否已满足评审人数、CI是否通过、是否配置了额外的分支保护规则、当前账号是否有足够的合并权限。把这四项列成一张表逐个对照很快就能定位卡点。现在我们的脚本里也加了一个检查函数每次创建PR之后自动fetch一次详情把所有合并条件的字段评审数、检查状态、冲突状态等打到日志里。5.6 给你的最后几条经验如果你准备在公司内部也搞这么一套自动创建PR评审模式的机制我最后想分享几条经验第一先在测试仓库里把整个链路跑通不要直接上生产仓库。找一个没有真实业务的空仓库把评审模式、分支保护全配上然后反复用脚本创建PR、改参数、看效果等彻底稳定了再复制到核心仓库。第二脚本的日志和异常报警一定要做。自动创建PR是一把利器一旦出了bug短时间内可能会创建出一堆脏PR。我的脚本里用了独立的日志文件每次创建/查询都会记录时间、参数、返回状态同时异常时会把错误信息推送到企业微信这样出问题能第一时间发现和回滚。第三评审人数不要贪多。团队小1人就够强制搞2人反而会让流程慢到所有人反感最后大家会偷偷绕过流程。我见过有团队一上来就要求“至少2人评审通过才能合并”结果一个月后PR平均等待时间从半天变成了两天团队怨声载道最后又偷偷把评审模式关了。合理的方式是先从1人评审开始等大家养成习惯后再逐步加码。第四服务账号这个问题要谨慎。有人为了“自动化程度更高”会用一个机器人账号去当评审人让机器人自动approve PR这样相当于把评审模式完全架空流程图快但质量把关也就没了。评审的意义在于有一个不同视角的人真正看过代码如果你信任的是机器审查应该去配CI里的静态扫描工具而不是伪造人工评审记录。跑了一百多次自动PR之后我现在的习惯已经变成了每次迭代收尾发版脚本里自动带上“创建PR到master”这一步评审人是固定的两个核心同学。团队从最初有人忘指派评审人到现在每一次合入主干的提交都有完整的评审记录和责任人。如果你团队里还有人每天围着PR页面点鼠标、点完还要群里催人审我建议你也花一个下午把这两件事接起来——写脚本创建PR是体力活配好评审模式才是真正立规矩。