返回博客

changesets Release workflow 开 PR 403——org 级 Actions 开关才是真正的墙

用 changesets 管理 monorepo 版本号,Release workflow 跑了好多次都"成功"——直到某天真的有 .changeset/*.md 待消费,workflow 突然在最后一步炸了。版本 bump 分支推上去了,CHANGELOG 也写了,唯独「开 Version Packages PR」那步 403。

现象

##[error]HttpError: GitHub Actions is not permitted to create or approve pull requests.
  • release.yml 里明明已经写了 permissions: pull-requests: write
  • changeset-release/<branch> 分支已经推上去(前面的步骤全部成功)
  • 仓库 Settings → Actions → General 里有个「Allow GitHub Actions to create and approve pull requests」复选框,但是灰的,点不动
  • 之前的 Release run 从来没报过错——那是因为那些 run 都没有待消费的 changeset,changesets action 走的是"无事可做"分支,根本不触发开 PR 这一步,自然撞不到这堵墙
坑:YAML permissions 管不了「Actions 能否建 PR」这个开关

permissions: pull-requests: write 给的是 GITHUB_TOKEN 对 PR 内容的读写能力(评论、标签、合并等),不包含「以 GitHub Actions 身份新建 PR」这个能力。这是两套独立的权限体系。

org 在 Actions 策略里关掉了「Allow GitHub Actions to create and approve pull requests」,仓库级的那个框就会变灰锁死,无论 YAML 怎么写都无济于事。

根因

GitHub 对「Actions 能否建/批 PR」有一个独立的双层开关

  1. 组织级(org owner 权限):github.com/organizations/<org>/settings/actions → Workflow permissions → 「Allow GitHub Actions to create and approve pull requests」
  2. 仓库级:只有 org 级开关打开后,仓库的那个框才解锁,仍然需要仓库管理员再勾一次

org 是上限,repo 是收口。两层任一关闭,Actions 就没有建 PR 的权力,YAML 里的 permissions 字段完全旁路不了它。

用 API 可以快速确认当前状态:

gh api /repos/<owner>/<repo>/actions/permissions/workflow
# 关键字段:can_approve_pull_request_reviews: false  ← 就是这个

正解

两级开关都要打开:

第一步,org owner 去组织 Settings → Actions 页勾选开关(这步只有 org owner 能做)。

第二步,开关解锁后,用 API 在仓库级设置(repo admin 即可):

gh api -X PUT /repos/<owner>/<repo>/actions/permissions/workflow \
  -F default_workflow_permissions=read \
  -F can_approve_pull_request_reviews=true
 
# 读回确认
gh api /repos/<owner>/<repo>/actions/permissions/workflow

default_workflow_permissions 保持 read 没问题——release.yml 已经用 per-job 的 contents/pull-requests/packages: write 声明了足够的 token 权限,真正卡的只是 can_approve_pull_request_reviews

正解:org → repo 双层打开,API 验证 can_approve_pull_request_reviews=true

两级都 ON 之后,下次有 changeset 推 main,Release workflow 会自动创建/更新 Version Packages PR,不再 403。验收标志:workflow 日志出现 🦋 success packages published successfully

当下补救(不改设置也能继续发版)

bump 分支已经推上去了,用人工账号手动开 PR 绕过 Actions 权限限制:

gh pr create \
  --base main \
  --head changeset-release/main \
  --title "Version Packages" \
  --body "Bump versions per pending changesets."

合并后 Release workflow 会以「无待消费 changeset」模式重跑 publish,publish 只用 GITHUB_TOKEN + packages:write不需要建 PR 权限,完全不受影响。

合并后记得 git pull --ff-only:远端合并删了 .changeset/*.md、bump 了 package.json,本地停在合并前再提交会把已消费的 changeset 又带回去重复 bump。

一句话外卖

Actions 的 permissions: pull-requests: write 和「Actions 能否建 PR」是两套独立开关,org 级策略是天花板,YAML 权限绕不过去。