作者将发布阶段判断封装为 MCP 工具,让编程 Agent 根据已合并的 MR 获取分支选择依据。文章解释了多版本并行时为何不能仅凭分支是否存在判断阶段,并讨论算法可能出错的情况。
以前,我经常这样交代 coding agent:
更新 develop/1.65.0。从这个分支创建 feature/<task key>。实现任务,然后创建一个合并到 develop/1.65.0 的 MR。
可到了第二天,同一个 release 可能已经进入 alpha,再过一阵又进入 beta。所以,我必须自己掌握每个 release 当前所处的阶段,每次都把正确的分支告诉 Agent。
在我的整个发布流程中,release 阶段是唯一游离于 Git、CI 和 Jira 之外的信息:它存在于大家的脑子里,以及一张由我手动更新的 Confluence 表格中。这篇文章讲的是,我如何把这件事变成可计算的信息:先在一个管理门户里供自己使用,再通过 MCP 工具提供给 Agent,以及这套算法可能在哪些地方判断出错。
先交代一下背景。在我的 Git Flow 中,每个 release 都有自己的一组分支,按 stage/version 命名,串成一条链:
develop/1.65.0 → alpha/1.65.0 → beta/1.65.0 → prod/1.65.0
多个版本会同时存在:一个在开发,一个在测试,一个在 beta,一个在线上。旧版本中的修复必须同步到更新的版本。第 1 篇介绍了这套模型,第 2 篇介绍了基于它构建的 CI 检查。
最直观的算法是“找到已存在的、阶段最靠后的分支”,但这行不通。初始化一个新 release 时,所有阶段的分支都会一次性创建。即使这个 release 才刚开始开发,prod/1.65.0 也从第一天就存在。
我们需要另一种信号:按照团队流程,什么操作意味着 release 向前推进了一个阶段?对我们来说,这个操作就是:一个 MR 被合并到对应阶段的分支。目标分支的名称是 <stage>/<version>,而且 MR 关联了一个 Jira 任务。如果有符合条件的 MR 合并到 alpha/1.65.0,就说明这个 release 已经进入 alpha。如果之后 beta/1.65.0 中也出现了这样的 MR,就说明它进入了 beta。
工具会查找标题、分支名或描述中包含 Jira key 的已合并 MR,根据 release 和阶段顺序匹配它们的目标分支,然后选出有这类证据支持、推进得最远的阶段:
Release 1.65.0
Branch Merged MR as evidence?
develop/1.65.0 yes
alpha/1.65.0 yes ← current stage
beta/1.65.0 no
prod/1.65.0 no
Result: stage = alpha, baseBranch = alpha/1.65.0

这不是 Git 普遍具备的属性,而是我们对 release 状态的定义。它之所以成立,是因为团队事先约定了这套流程。如果你的团队用其他方式推进阶段,就需要寻找其他证据。
这个定义是我事后总结出来的。最初,我只是想摆脱那张表格。正式的算法及其适用边界,是在开发工具的过程中逐渐成形的。
我不希望 Agent 根据本地 checkout 猜测 release 状态,也不希望它直接选用默认分支,或靠 prompt 记住每个项目的特殊规则。它需要一个工具,回答一个具体问题:处理这个 Jira 任务时,我应该从哪里开始,完成后又该把 MR 提交到哪里?
这个工具是一个 MCP server,我把它叫作 Delivery Manager。这个名字可能让人误会:它并不取代真正的 delivery manager。release 计划仍由人来制定,Jira 中的 Fix Version 也仍由人来设置。MCP 接收的是已经规划好的任务,负责判断该如何按照现有发布流程处理它。
给定项目、版本和 task key,它就会查询 GitLab,确定当前阶段,并返回开展工作所需的参数。大致如下:
# Fictional example; a shortened illustration of the contract,
# not the literal JSON response of the MCP.
fixVersion: 1.65.0
currentStage: alpha
baseBranch: alpha/1.65.0
baseBranchExists: true
featureBranch: feature/DEMO-123
mergeRequest:
targetBranch: alpha/1.65.0
Agent 不需要理解为什么 1.65.0 今天处于 alpha。它拿到的是经过验证的 baseBranch 和 MR 目标分支。

我给 Agent 定了一条硬性规则:不能自行选择作为开发起点的 release 分支,唯一的信息来源就是 release MCP。出现以下情况时,不能靠猜测开工:
最后一条曾在一个非常日常的场景中触发:我自己忘了把任务改到正确的状态,于是工作就停了下来。这不是工具出了错,而是它拒绝为了开始写代码而绕过流程。
这套算法并不是从 MCP 开始的。在那之前,我维护着一张 Confluence 表格:行是 release 版本号,列是阶段和操作。每当 release 向前推进,我就填上日期,去掉一个单元格的绿色背景,再给另一个单元格涂上绿色。它是否准确,全靠我来维护;而我手动抄录的每一个操作,GitLab 其实早就记录下来了。
我是一名 Android 开发者,此前从没写过 Web 管理门户。我在 ChatGPT 中讨论了这个想法,得到一份实现用的 prompt,再把它交给 coding agent。我的 gitlab-panel 门户就是这样起步的。它根据 GitLab 数据构建全貌:一张以版本为行、以阶段为列的矩阵。

这张矩阵展示了变更流动的两个方向。横向看,变更会在同一个 release 内依次经过各个阶段。纵向看,门户会检查“旧 release 中的修复必须同步到新 release”这条规则:比较相邻 release 的分支,找出旧版本中存在、新版本中却缺失的 commit,同时过滤掉 merge commit。过去,这条规则只是团队需要自觉履行的一项义务。
点击矩阵中的箭头,门户还可以发起一次“pour”。这是我们对阶段分支之间或不同 release 之间传递变更的称呼。我确认来源、目标和变更内容后,门户会使用已有的 Jira 任务,或创建一个子任务,将其移到 CodeReview 状态(如果失败就停止),从源分支创建一个临时的 feature/<KEY> 分支,再创建一个指向目标分支的 MR。我们刻意关闭了 Squash,这样之后就能通过 commit 历史检查变更如何在不同 release 之间流转。门户还会尝试启用 pipeline 成功后自动合并,但不保证一定能设置成功;有些步骤可能仍需人工处理。
门户不会决定 release 是否该进入下一阶段。测试人员反馈是否准备就绪,delivery manager 规划后续推进,并创建 pour 任务。自动化处理的是决策之后的操作。
门户和 Delivery Manager 是两个独立项目,各自拥有独立的代码库。我没有让 MCP 依赖一个正在运行的门户。
需要开发 MCP 时,我请负责门户的 Agent 说明阶段识别算法在源码中的具体位置:涉及哪些文件、方法,以及具体逻辑。然后,我把这份说明交给另一个负责构建 MCP 的 Agent,由它把这套业务思路移植过去。
所以,现在有两套实现,它们依赖同一套流程和 GitLab 历史,但彼此之间没有自动同步代码的机制。阶段顺序也是一处折中:MCP 会根据项目的 release 分支和已知阶段名称确定顺序,再将其固定在空间设置中;门户则有单独的页面来管理它。
这套计算建立在三个假设之上:
当前阶段是有证据确认、推进得最远的阶段。 一个 MR 被合并到 beta/<version>,就意味着 release 已经进入 beta。算法不会尝试根据任务名称还原业务逻辑。
release 只向前推进。 我的模型不支持从 beta 回退到 alpha,因此,已确认的最远阶段会一直被视为当前阶段。如果你的团队允许正式回退阶段,这套算法就不够用了。
没有可供确认的 MR 时,选择第一个已存在的阶段。 这是新建 release 的正常状态:所有分支都存在,但还没有进行过 pour。这是有意设定的回退规则,并不代表已经发生了某次经证实的阶段流转。

工程上也有一些限制:两套实现意味着,一旦规则改变,就必须手动把修改移植到另一套实现中。阶段检查也没有加入第 2 篇介绍的旧 jira:check CI 脚本,而是由其他工具来执行。另外,我没有测量这套方案到底节省了多少小时,因此也不会给出什么百分比。
发生了什么变化,不用数字也能说清楚。过去,我得记住 release 阶段、更新表格、向人或 Agent 解释该用哪些分支,再到 GitLab 中执行一连串操作。现在,状态来自历史记录,门户展示差异,而 Agent 会去问 MCP,不再来问我。
完整案例研究,包括 pour 向导和两个方向的流转图,可以在我的网站查看:https://hram.github.io/en/articles/hram-git-flow-ai/
后续你可以考虑屏蔽此人,和/或举报滥用行为。