关于 merge-dependabot-prs
通过 `gh` CLI 检查并批量合并 Dependabot 拉取请求的技能,适用于希望按明确安全规则处理依赖更新的维护者。默认只合并通过全部检查的次要和补丁更新,并将风险较高的更新留待人工判断。
主要功能
- 01分类更新类型与 CI 状态
- 02默认仅处理次要和补丁更新
- 03默认要求检查全部通过
- 04按顺序使用 rebase 合并
- 05说明跳过请求及其原因
适用场景
- 01合并仓库中符合条件的 Dependabot 更新
- 02评估主要版本和未知版本更新
- 03查找因 CI 未完成或缺失而搁置的请求
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ hussainweb/ skills --skill merge-dependabot-prs安装后在 Claude Code 中输入/merge-dependabot-prs确认已加载。
附带文件evals/evals.jsonscripts/dependabot_prs.py
详细介绍
合并 Dependabot PR
通过 gh CLI 批量合并 Dependabot 的未关闭拉取请求,并应用保守的默认筛选条件,让常规依赖更新无需人工逐一查看差异即可合入,同时保留任何可能导致构建出问题的更新,交由人工检查。
仅当用户提出请求时才运行此技能。切勿因为在处理其他事情时注意到有未关闭的 PR,就顺手合并。合并会对外产生影响,而且不易撤销,因此始终必须由用户提出请求。
默认设置
除非用户在同一请求中另有说明,否则应用以下设置:
| 决策 | 默认设置 | 原因 |
|---|---|---|
| 版本范围 | 仅次要版本和补丁版本更新 | 主要版本更新通常包含有意引入的破坏性变更,应由人工处理。 |
| 暂缓的主要版本更新 | 评估,但不合并 | “已跳过:主要版本”无法为用户提供决策所需的信息;针对本项目简要评估风险则有帮助。 |
| CI 门禁 | 所有检查都必须成功结束 | 只有构建通过才能证明更新安全。待处理表示尚未通过,没有任何检查则表示没有证据。 |
| 工作流批准 | 始终先确认再批准 | 自动化流水线提交会导致后续运行进入 action_required 状态。批准后,运行会在仓库权限下执行代码;未经用户确认,切勿批准。 |
| 过时分支 | 旧基线上的绿色结果仅是部分证据 | CI 是针对创建分支时的提交运行的。如果基线已发生变化,运行的测试可能会减少,而且输出不会说明这一点。 |
| 合并方式 | --rebase | 保持历史记录线性;依赖更新不产生合并提交。 |
| 分支清理 | --delete-branch | Dependabot 分支用完即可删除,而且很快就会堆积起来。 |
| 仓库 | 当前工作目录中的仓库 | 用户指定其他仓库时,传入 --repo OWNER/REPO。 |
| 顺序 | 每次处理一个,按 PR 编号从小到大 | 每次合并都会推进基线分支;串行处理能让故障情况更清楚。 |
用户的表述优先于以上默认设置。常见的覆盖指令及其含义:
- “包括主要版本更新”/“全部” → 移除版本筛选;仍遵守 CI 门禁。
- “只要补丁版本” → 收紧版本筛选。
- “即使检查失败也要合并”/“不要等 CI” → 移除 CI 门禁(见下方注意事项)。
- “用 squash”/“使用合并提交” → 改用
--squash或--merge,而非--rebase。 - “保留分支” → 移除
--delete-branch。 - “只要 GitHub Actions 的”/“只要 npm” → 按生态系统筛选,可从依赖名称和 Dependabot 标签中判断。
- “合并 #42 和 #47” → 仅处理明确列出的 PR,除非用户另有说明,仍应用默认门禁。
- “直接合并,不用分析主要版本更新”/“跳过说明” → 在第 5 步中省略风险评估,仅按编号和版本报告暂缓的主要版本更新。
如果覆盖指令放宽了安全门禁——例如合并主要版本更新、在检查失败或待处理时合并,或使用 --admin 绕过分支保护——请明确说明将要合并的内容,并在执行前征得同意。用户提出放宽门禁的要求,是可以提出此操作的理由,并不是跳过确认的理由,因为这些合并正是事后发现问题时处理成本最高的情况。同样,批准需要批准的工作流(action_required)会触发其在 GitHub Actions 运行器上执行;始终说明触发执行的 PR 和提交,并在批准前征得用户确认。
工作流
1. 预检
gh auth status
如果缺少 gh 或未通过身份验证,请停止并说明情况——后续所有步骤都需要它。
然后确认仓库允许使用计划采用的合并方式:
gh repo view --json nameWithOwner,rebaseMergeAllowed,squashMergeAllowed,mergeCommitAllowed
如果禁用了 rebase 合并,不要默默改用其他方式——合并策略会改变进入历史记录的内容,因此应询问用户要使用哪种允许的方法。
2. 清点并分类
运行随附脚本。该脚本只读,能一致地处理繁琐部分:读取 Dependabot 的 updated-dependencies 提交尾注;当尾注省略 update-type 时(这种情况很常见),回退到比较 “Bumps X from A to B” 中的版本;在分组 PR 中取所有成员的最高升级级别;并将检查汇总结果归为一个词。
python3 <skill-dir>/scripts/dependabot_prs.py # current repo
python3 <skill-dir>/scripts/dependabot_prs.py --repo OWNER/REPO
python3 <skill-dir>/scripts/dependabot_prs.py --json # same data, machine-readable
每一行都会报告升级类型(patch/minor/major/unknown)、检查状态(pass/failing/pending/none)、GitHub 的合并状态,以及该 PR 是否符合默认策略。默认策略会跳过的项目都会附上原因。
有四种分类需要判断,不能盲目照做:
-
unknown升级——通常是固定到 SHA 的 GitHub Action,因此没有可供比较的版本。不能安全地假定它属于 minor。默认跳过,并列出供用户查看。 -
none检查——该 PR 没有 CI,因此没有证据表明此次升级是安全的。没有门禁不等于门禁已通过,所以应跳过,而不是在附带说明的情况下合并。报告这些 PR,并告知用户:如果仍想合并,请明确列出 PR 编号。不要提议批量合并,也不要把“合并所有 dependabot PR”视为涵盖这些 PR——没有 CI 的仓库恰恰最容易在糟糕的批量合并未被发现。当用户随后提出指定编号的请求(“合并 #29 和 #31”)时,这就是该门禁在等待的明确指示:按通常默认设置合并,无需再次确认。
-
过期分支上的
pass检查——绿色检查证明的是此次升级相对于分支创建时的提交,而不是相对于当前基线。如果分支搁置期间基线发生了变化,已运行的测试套件可能比当前基线分支上的套件少得多,而 CI 输出不会说明这一点。一次通过的运行只会报告自身的统计数据;除非你事先知道正确的统计数据,否则这些数字看起来会很完整。这只是部分证据,并不代表已获准。PR 打开超过一两天时要检查;对于 major 升级则始终要检查,因为绿色勾号往往是最主要的证据:
branch=$(gh pr view <n> --json headRefName --jq .headRefName) git fetch origin "$branch" git merge-base --is-ancestor origin/main "origin/$branch" \ && echo "based on current main" || echo "STALE — CI ran against an older base"分支过期时,比较两个树中的实际内容。测试文件通常最能说明问题:
git ls-tree -r --name-only "origin/$branch" | grep -cE '\.test\.[jt]sx?$' git ls-tree -r --name-only origin/main | grep -cE '\.test\.[jt]sx?$'由根目录 glob 收集测试的仓库最容易受影响——收集到的文件数量取决于分支的存续时间,因此过期分支会在不知情的情况下少测一些内容。真实案例:一次 vitest 升级的 CI 自豪地报告“33 passed (33)”,而基线分支有 51 个测试文件,因为其中 18 个是在该分支创建后才合入的。
如果数量不一致,应在计划中说明,而不是引用绿色勾号。修复很简单:自行发布
@dependabot recreate,等待它重新构建,然后查看新分支上的 CI——除非有 Dependabot 以外的其他人提交到了该分支(见下文“重建分支”)。切勿手动 rebase 来弥补差距。 -
action_required检查(等待批准的工作流)——工作流运行已触发(通常是因为格式化工具、锁文件生成器或迁移工具等自动化流水线步骤提交回 PR 分支),而 GitHub 将后续运行置于action_required状态(已用时 0 秒)。这不是测试失败;由于 GitHub 要求维护者批准由机器人或 Action 提交触发的运行,测试套件尚未运行。切勿悄无声息地或自动批准工作流运行。在 GitHub Actions 运行器上批准运行意味着运行的代码将获得仓库权限,因此必须由用户明确决定。找出触发该运行的提交和暂停的工作流运行,在计划中列出,并在批准前征求确认(见下文的批准工作流部分)。
3. 动手前先报告计划
用一两行准确说明你将合并哪些内容、哪些内容会保留不动,以及原因。这是让批量合并可供审查的关键:如果分类有误,就能在此时发现,而且不会造成任何损失。
将内容写成分组项目符号,置于真正的 Markdown 标题(###)下,不要使用 Markdown 表格。脚本生成的表格是给你看的;回复是给可能在终端或表格渲染效果不佳的客户端中阅读的人看的,而格式混乱的表格还不如纯列表。使用标题而非粗体标签,这样读者可以通过标题快速浏览。每个 PR 占一行——编号、依赖项、版本范围和结论——放在“Merging”和“Leaving open”这类简短标题下。
然后继续操作——明确授权“合并所有 Dependabot PR”就表示可以合并通过筛选的 PR。只有在放宽了某项门槛(见上文)、计划为空或发现异常时,才暂停并请求确认。如果某个 PR 仅因工作流运行需要批准而暂缓,请求确认是否批准该运行;你仍可继续合并其他符合条件的 PR。
4. 逐个合并
gh pr merge <number> --rebase --delete-branch
在当前目录之外操作时,添加 --repo OWNER/REPO。按 PR 编号升序合并,并在开始下一个之前检查每次操作的结果。
这里需要串行处理。每次合并都会推进基分支,因此后续 PR 可能变成 BEHIND,或在批处理中途开始发生冲突——尤其是在分支保护要求分支与最新代码保持同步的仓库中,这种情况下批次里可能只有第一个合并成功。这是预期情况,并不意味着计划失败。
如果批处理中途合并失败,继续处理其余 PR,并汇总失败项。常见原因如下:
| 失败 | 含义 | 处理方式 |
|---|---|---|
not mergeable: the merge commit cannot be created / 冲突 | 分支已发生偏移,通常是由本批次中较早的合并导致 | 报告后继续处理——在发表评论前先看下文 |
| 基分支不是最新版本(分支保护) | 仓库要求分支与最新代码保持同步 | 同上:报告后继续处理 |
API 仍报告 PR 状态为 CLEAN,但出现 Pull request is not mergeable | GitHub 缓存的可合并状态已过时——本批次中较早的合并推进了基分支,而该 PR 尚未重新评估 | 重试一次;如果仍以相同方式失败,则视为分支偏移 |
有待完成的检查时出现 Pull request is not mergeable | 基分支变更后 CI 已重新启动 | 提供自动合并选项,而不是等待:gh pr merge <n> --rebase --delete-branch --auto |
action_required / 需要批准工作流 | 流水线提交触发了后续运行,该运行暂停等待批准 | 请求用户确认,然后使用 gh api 批准并等待运行完成(见下文) |
| 需要审查 | 分支保护要求获得批准 | 报告此情况;不要自行批准,也不要在未经请求时使用 --admin |
重建分支:重新创建,而不是变基
当基础分支发生变化时,Dependabot 会对自己尚未关闭的 PR 进行变基——这是默认的
rebase-strategy。因此,对于批次执行期间常见的冲突,正确做法是将 PR 标记为需要再处理一次,然后到此为止。发表评论只会增加噪声,没有任何好处,因为本来就会进行变基。
如果有理由认为自动处理不会进行或不足以解决问题,就需要推动一下分支:例如 PR 已经过时,其绿色检查是基于较早的基础分支运行的(步骤 2);或者在之前的合并本应触发变基后,PR 仍然冲突。作出这个判断后,就采取行动——不要只是建议变基,然后让用户自己输入命令。先查看是谁向该分支提交了代码,因为这决定了你要采取什么操作:
gh pr view <n> --json commits --jq '[.commits[].authors[].login] | unique'
只有 Dependabot——自行发送重新创建命令,无需确认:
gh pr comment <n> --body "@dependabot recreate"
发送 recreate,而不是 rebase。如果分支上只有 Dependabot 的提交,重新创建不会丢弃任何内容;它会基于当前的基础分支从头重建更新——重新生成锁文件,而不是重放旧锁文件——因此既能解决分支过时的问题,也能解决变基可能无法处理的冲突。在总结中说明你对哪些 PR 发送了该命令;它们的 CI 将会重新运行,因此在本次执行期间不可合并。
有其他人提交过代码——不发送任何命令。最常见的情况是某个工作流步骤向 PR 提交了代码,例如锁文件生成器或格式化工具。Dependabot 正是为了避免覆盖这些更改,才停止对这类分支进行变基,因此 @dependabot rebase 在这种情况下不会生效。@dependabot recreate 虽然有效,但会丢弃这些额外提交的内容,因此是否重新创建应由用户决定,而不是由你决定。指出 PR 和其他提交者,解释变基无济于事,并询问是否要重新创建。
切勿手动对 Dependabot 分支进行变基。这些分支由 Dependabot 管理,手动变基会让你陷入上述“其他人向该分支推送了代码”的状态,从而阻止你试图推动的自动变基。
除非用户明确要求,否则切勿为了“清理”而关闭 Dependabot PR。关闭 PR 会告诉 Dependabot 不要再提供该更新,这个决定会产生长期影响。
批准因流水线提交而暂停的工作流
当某个工作流步骤(例如 Biome Migrate、Prettier 或锁文件生成器)向 PR 分支提交代码时,GitHub Actions 会阻止后续工作流递归运行或在无人监督的情况下运行。因此,后续工作流运行(例如 CI)会被标记为 conclusion: action_required,且耗时为 0 秒。
这不代表测试套件失败或构建损坏——这些检查只是尚未执行。但由于批准在 GitHub Actions 运行器上执行代码会授予其访问仓库的权限,绝不能自动或默默地批准工作流运行。务必先征得用户确认。
检测需要批准的运行
查找该 PR 中等待批准的工作流运行:
gh run list --commit <headSha> --json databaseId,workflowName,status,conclusion
或者列出仓库中所有等待批准的运行:
gh run list --json databaseId,workflowName,conclusion \
--jq '.[] | select(.conclusion=="action_required")'
检查分支上的最新提交,确认触发暂停运行的原因:
gh pr view <n> --json commits --jq '.commits[-1] | {author: .authors[0].login, message: .messageHeadline}'
确认并批准
在计划(步骤 3)中,在“Awaiting workflow approval”标题下列出等待批准的 PR。说明:
- PR 编号和依赖项
- 触发暂停运行的提交(例如,
github-actions[bot]提交的chore: run biome:migrate) - 哪些工作流运行正在等待批准(例如,
CI)
在批准之前,明确询问用户是否确认:
“PR #54 有一个等待批准的 CI 工作流,由
github-actions[bot]提交的chore: run biome:migrate触发。是否批准此工作流运行?”
用户确认后:
gh api -X POST /repos/:owner/:repo/actions/runs/<run-id>/approve
持续监控运行,直到完成:
gh run watch <run-id>
如果 CI 成功完成,该 PR 就满足通过检查这一门槛,可以按照常规工作流进行合并。
5. 评估暂缓处理的主要版本更新
默认情况下暂缓主要版本升级是正确的,但单独写一句“已跳过:主要版本升级”并没有给用户提供决策依据——他们只能逐个打开 PR,阅读你本来已经可以查看的内容。因此,对于版本筛选器暂缓的每个 PR(每个主要版本升级,以及最差成员为主要版本升级的任何分组 PR),都要评估该升级对这个项目的风险,并在报告中说明。评估只是提供给用户的信息;绝不会因此直接合并。即使你判断某个主要版本升级风险较低,也仍须等用户点名指定。
这项工作应在合并后进行,而不是之前——这里的任何事情都不应延误已经获准合并的升级。当计划为空、没有任何内容需要合并时,应在同一条回复中同时给出计划和评估,而不是只交付两行计划就结束;此时,评估报告是这次运行唯一有用的产出。只有在用户要求跳过时,才跳过评估。
这里也要检查是否过时(步骤 2)。长期搁置的主要版本升级最不该轻信绿勾,而且在报告中也最需要重视,因此要说明检查实际针对哪个基准运行。如果分支已过时,请发布 @dependabot recreate(遵循“重建分支”中的作者检查要求),并在重建后的分支上查看 CI,然后再撰写评估——否则,你评估升级时依据的测试套件就不再匹配项目当前状态。
先运行随附脚本,收集 Dependabot 已附加到 PR 的证据:
python3 <skill-dir>/scripts/dependabot_prs.py --notes 42 45 # --repo as usual
对于每个 PR,脚本都会输出版本范围、上游仓库、PR 涉及的文件、PR 的检查状态、纯文本格式的发行说明和变更日志,以及其中提及破坏性变更、移除内容或新运行时最低版本要求的行。要阅读完整说明,而不只是标记出来的行——标记只是辅助阅读;如果某个版本只链接到博客文章,就不会有任何标记。当正文完全没有说明时,脚本会指出这一点,并提示通过上游仓库的 gh release 查看。
然后判断这些证据对这个代码库意味着什么。以下问题通常按此顺序就能理清情况:
-
CI 是否在 PR 上通过? Dependabot 分支运行了项目的检查,以验证新的主要版本,因此绿色检查是最有力的单项证据——但要说明 CI 覆盖了什么,以及这次运行距今多久。某个仓库如果唯一的检查是代码检查工具,就无法证明运行时行为正常;几个月前的绿色结果所针对的主分支,也可能早已发生变化。红色结果同样有用:失败任务的日志通常会指出具体问题,从而将“主要版本升级”转化为“需要修改 X”。任务日志很长,因此请筛选:
gh pr checks <n> # names, states, run links gh run view --job <job-id> --log-failed | grep -iE -B3 'error|fail|cannot|not found' | head -60 -
这是什么类型的依赖? 开发工具(代码检查工具、测试运行器、打包工具、类型包)会破坏构建,而非生产环境;类型包跟随其运行时的主要版本升级,本身通常不包含变更。GitHub Action 的主要版本升级几乎总是运行时升级或输入项改名。真正需要处理的通常是框架,或代码会直接调用的库。依赖所在的清单分区和 PR 修改的文件可以告诉你它属于哪种情况——只修改锁定文件的 PR 更新的是项目不会按名称导入的传递依赖。
-
这个项目是否涉及发生变更的部分? 从说明中找出被移除或改名的内容,然后用 grep 搜索。对于库,检查导入语句和调用位置;对于 Action,检查
uses:行和输入项;对于工具,检查其配置文件。如果仓库中没有任何地方使用被移除的接口,这次主要版本升级就与项目无关。 -
新版本的最低要求是否符合项目配置? 新增对最低 Node、PHP、Python 或框架版本的要求,是最常见的隐性破坏。将其与项目声明的版本进行比较——
engines、require.php、python_requires、.nvmrc、runs.using以及 CI 矩阵。 -
升级跨度有多大? 一次跨越两个主要版本(5 → 7)意味着要应对两组破坏性变更,而 Dependabot 通常只会粘贴其中一个版本的说明——请确认具体是哪一个。 如果仓库未在本地检出,可使用
gh search code --repo OWNER/REPO "<term>"和gh api repos/OWNER/REPO/contents/<path>代替 grep。若这限制了你能验证的内容,请说明。
任何公开且只读的信息都可作为证据:上游的发布页面或公告帖、用于查看同级依赖和引擎约束的 npm view / composer show / pip index,以及失败作业的日志。只有在阅读资料无法确定问题时,才允许在仓库的临时副本中尝试升级——安装新版本并运行构建和测试;绝不能在用户检出的仓库中这样做。这通常是多此一举;如果结论依据试运行而非阅读资料,报告中应说明。
每项评估都应作为报告中“暂缓处理”标题下的一条项目符号:PR 编号、依赖项和版本范围,然后是结论,接着用一小段说明——新主版本实际会破坏什么、该项目是否会受到影响以及你如何确认(指出文件或配置键),以及 PR 要合并需要做什么(“说 merge #45”、“先迁移配置”或“等待上游 X”)。通常写三到五句话;情况确实复杂时可以更长,但每句话都应提供证据或决策,而不是复述变更日志。
使用以下三种结论之一,便于快速浏览:
- 低风险 — 破坏性变更不会影响此项目,而且你能指出证据。
- 需要先处理 — 仓库中的某项内容必须先更改,升级才安全,而且你能明确指出该内容。
- 无法确定 — 缺少说明,或用法足够动态,无法通过 grep 确定。说明需要什么信息才能确定。
只要事实如此,就选择“无法确定”。错误而自信地判定为“低风险”,比诚实承认信息不足对用户的伤害更大;这是最可能让他们不再信任报告的事。不要通过复述变更日志来凑篇幅;用户可以在 PR 中查看变更日志。他们无法从 PR 中了解变更日志与自身代码之间的联系,而这正是此步骤的全部价值。
6. 汇报结果
最后用简短、客观的总结,采用与计划相同的简单分组项目符号形式:
- 已合并:列出 PR 编号、依赖项和版本范围。
- 需要再次处理:列出遇到冲突或已过时的 PR,并说明各自处于以下三种状态中的哪一种:Dependabot 会自行重新变基(通常如此,无需处理,只需等待)、你已在该 PR 上发布
@dependabot recreate,或该 PR 正等待用户决定,因为重新创建会丢弃他人的提交。 - 等待批准:列出工作流运行等待维护者批准的 PR,注明触发该运行的提交,并说明需要做什么。
- 暂缓处理:列出各个主版本升级,并附上步骤 5 中的评估。带有安全标签的项目优先列出,并注明其安全更新属性。
- 已跳过:列出因其他原因暂缓处理的 PR(检查失败、未配置检查、版本无法验证、受到保护规则阻止),并按组归类,方便用户决定如何处理。对于未配置 CI 的项目,说明后续处理方式——用户指定 PR 编号后即可合并。
- 失败:列出所有出错项及错误信息。
指出所有被暂缓处理或跳过的安全更新。Dependabot 会为它们添加 security 标签;被跳过的主版本安全修复,是遗留事项中唯一真正需要尽快关注、而不是明天再重新运行的项目,因此它的评估应排在列表最前面。
相关机制说明
作者筛选。 Dependabot PR 的作者是 app/dependabot。这是脚本的默认设置;如果仓库使用旧版 dependabot-preview 或镜像机器人,请传入 --author。
1.0 之前的版本。 按照 semver 的规则,0.5.6 → 0.6.0 是次要版本更新,Dependabot 和此脚本也都将其归为这一类,但 1.0 之前的项目经常会在这种版本更新中发布破坏性变更。脚本会标记这些更新;请在报告中注明该标记,不要隐去。
发布说明来自 PR 正文。 Dependabot 会将上游发布说明和变更日志粘贴到折叠的 <details> 块中。清单会忽略这些内容(其中充斥着其他项目的“Bumps X from A to B”行),但 --notes 会以此为依据。有些生态系统从来没有发布说明,例如 @types/* 包;有些上游则只链接到博客文章,因此发布说明部分为空很常见,这意味着“查看上游”,而不是“没有变更”。
分组更新。 分组 PR(“Bump the npm-dependencies group with 5 updates”)会按其中风险最高的成员分类,因此组内只要有一个主要版本更新,整个 PR 就会被暂缓。这是正确的判断——PR 是原子性的,因此其风险取决于其中的最高风险。
mergeStateStatus 需要 repo token 权限范围。 如果没有该权限范围,脚本会重试并省略此字段,同时会说明这一点;因此,分支保护状态将不可见,所以请预期合并尝试可能会遇到计划无法预测的保护规则错误。
延迟计算可合并性。 新建的 PR 可能会报告 UNKNOWN;重新运行脚本即可解析。
提交元数据来自手写的 GraphQL 查询。 Dependabot 的提交尾注(update-type: version-update:semver-minor)是唯一明确写出更新类型的位置,因此脚本必须读取提交记录——但如果通过 gh pr list 同时请求 commits 和其他字段,GitHub 会直接拒绝该查询。gh 会将该字段扩展为每个 PR 的 100 个提交、每个提交的 100 位作者;无论实际 PR 数量是否达到该值,只要 --limit 大于约 48,就会超过 500,000 个节点的上限。
因此,脚本会先在列出 PR 时省略 commits,然后运行一次 gh api graphql 调用,仅请求提交消息,并为每个 PR 使用一个带别名的 pullRequest(number:)。实测一个完整的 100 个 PR 批次需要 500 个节点(上限的 0.1%)和 1 个速率限制点。不要把 commits 加回列表查询;如果要扩展 GraphQL 查询,也不要加入嵌套连接——正是这种乘数效应导致它最初失效。
如果无法获取某个 PR 的提交记录,该 PR 会回退到使用正文:版本号仍然存在,但 update-type 尾注缺失,因此更可能被归为 unknown 并暂缓处理。脚本会在该 PR 的说明中告知此情况。一个无法读取的 PR 不会导致整个批次失败——GitHub 会在返回错误的同时返回其余结果,脚本会保留所有已成功解析的结果。