GitHub 主仓库同步到部署仓库,再对接 Vercel:一次完整的部署与排障实录
最近我在处理一个前端项目部署问题时,踩了不少坑。
我的目标其实很明确:
- 日常开发继续在自己的 主 GitHub 仓库里进行
- 新建一个 部署仓库
- 让 Vercel 只监听部署仓库
- 避免因为免费版、提交身份、第三方工具提交等问题,导致 Vercel 无法正确识别最新 commit 并触发部署
最终,这套方案跑通了。
顺便也把中间遇到的各种报错和修复过程完整记录下来,给后面遇到类似问题的朋友一个参考。
顺带一提,我这次排查和部署的是一个服装视频生成相关项目,线上站点是:https://runwaymotion.com
一、为什么要拆成“主仓库 + 部署仓库”
很多人一开始会直接让 Vercel 连接自己的开发仓库,这在简单场景下没问题。
但如果你遇到这些情况,就容易出问题:
- 多个工具在不同环境里提交代码
- commit author 不统一
- GitHub 提交来自自动化工具
- Vercel 免费版在某些协作场景下对触发识别不稳定
- 不希望部署逻辑和开发逻辑完全绑死
所以更稳妥的做法是:
架构拆分
- 主仓库:日常开发、提交、协作都在这里
- 部署仓库:专门给 Vercel 使用
- GitHub Actions:主仓库自动同步代码到部署仓库
- Vercel:只连接部署仓库并自动部署
整体流程如下:
↓
GitHub Actions 自动同步
↓
部署仓库(给 Vercel 使用)
↓
Vercel 自动部署
这样做之后,开发和部署就彻底解耦了。
二、这套方案的核心目标
我这次要解决的问题,本质上是:
1. 保留原有 GitHub 开发习惯
主仓库继续正常开发,不影响现有流程。
2. 给 Vercel 一个“干净”的部署源
Vercel 只看部署仓库,不再直接盯主仓库。
3. 避免提交身份和触发链路问题
第三方工具、自动化提交、不同机器上的 commit,不再直接影响 Vercel 的部署识别。
三、实际实施步骤
1. 新建一个部署仓库
在 GitHub 新建一个空仓库,例如:
- 主仓库:
runwaymotion - 部署仓库:
runwaymotion-vercel
这里有个点很多人容易担心:
空仓库可以直接推送
部署仓库不需要提前初始化 README,也不需要手动 first commit。
它可以是一个完全空的仓库,后续直接通过 git push 推送进去。
2. 在主仓库里配置 GitHub Actions
在主仓库中创建工作流文件:
目标是:
- 主仓库更新后自动触发
- 自动把代码同步到部署仓库
- 部署仓库收到新代码后,Vercel 自动部署
3. 创建 GitHub Token
为了让 GitHub Actions 能向部署仓库推送代码,需要生成一个 Token。
我在排查过程中试过两类:
- fine-grained token
- classic PAT
从实际排障体验来说,如果你只是想先快速打通同步链路,classic PAT 会更直接一些。
4. 把 Token 存到主仓库 Secrets
在主仓库里添加一个 Secret:
路径:
SettingsSecrets and variablesActionsNew repository secret
这个 secret 后面会被 GitHub Actions 用来推送部署仓库。
5. Vercel 只连接部署仓库
这一步非常关键:
不要再让 Vercel 连接主仓库
而是改成:
- Vercel 只连接
runwaymotion-vercel - 主仓库只负责开发
- 部署仓库专门负责上线
这样以后只要主仓库代码变化,GitHub Actions 同步到部署仓库,Vercel 就能在部署仓库层面触发自动部署。
四、最开始的同步方案
最初使用的 GitHub Actions 配置大概是这样的:
name: Sync to Vercel Repo on: push: branches: - main jobs: sync: runs-on: ubuntu-latest steps: - name: Checkout source repo uses: actions/checkout@v4 with: fetch-depth: 0 - name: Push to deploy repo env: TARGET_REPO: https://x-access-token:${{ secrets.VERCEL_DEPLOY_REPO_TOKEN }}@github.com/你的用户名/你的部署仓库.git run: | git config user.name "sync-bot" git config user.email "your-email@example.com" git remote add deploy "$TARGET_REPO" git push deploy HEAD:main --force
这个思路没问题,但实际执行时遇到了一连串报错。
五、完整排障过程
下面按顺序把这次遇到的问题都记下来。
问题 1:exit code 128
第一次跑 GitHub Actions 时,日志报错:
同时还看到一条提醒:
这里很容易误判
实际上:
exit code 128才是真正的失败- Node.js 20 那段只是提醒,不一定是本次失败主因
处理方式
先把:
升级成:
这样可以顺手规避 Node 20 的弃用提醒,也更稳一点。
问题 2:Repository not found
后面很快又遇到报错:
fatal: repository 'https://github.com/xxx/xxx.git/' not found
第一反应通常会怀疑:
- 仓库地址写错
- 用户名写错
- 仓库名写错
- 部署仓库没初始化
但这里要特别说明:
空仓库未初始化,不会导致这个报错
GitHub 的空仓库是可以直接接受第一次 push 的。
所以“仓库是空的”不是问题根因。
真正可疑的方向
更大的可能是:
- Token 没权限访问目标仓库
- Secret 没生效
- 实际使用的认证凭证不是你以为的那个
问题 3:把仓库改成 Public 后,变成 403
为了继续缩小问题范围,我把部署仓库临时改成 Public。
结果错误变成了:
fatal: unable to access 'https://github.com/xxx/xxx.git/': The requested URL returned error: 403
这个报错特别关键。
它说明了两件事
第一,仓库路径其实没问题。
第二,当前 push 时实际使用的身份是:
而不是我自己配置的 PAT。
问题 4:actions/checkout 默认凭证覆盖了自定义 Token
继续分析后发现,问题出在:
这个 Action 默认会把认证信息持久化到本地 Git 配置里。
结果就是:
- 我后面虽然加了带 token 的远程地址
-
但 push 的时候,Git 还是优先用了默认的
github-actions[bot]
修复方式
在 checkout 这一步加上:
persist-credentials: false
修改后如下:
- name: Checkout source repo uses: actions/checkout@v5 with: fetch-depth: 0 persist-credentials: false
这个参数很关键
它的作用是:
- 只拉代码
- 不把默认认证信息写进 Git 配置
- 后续
git push时才会真正使用我们手动配置的 token
这一步,是整次排查里最关键的修复点之一。
问题 5:PAT 无法更新 workflow 文件
当认证链路终于打通之后,又遇到了一个新报错:
这个错误其实是“好消息”
因为它说明:
- 现在已经不是仓库找不到的问题了
- 也不是 token 完全没权限的问题了
- 而是 push 的内容里包含了
.github/workflows/... - GitHub 不允许没有
workflowscope 的 PAT 去修改 workflow 文件
也就是说,同步链路基本已经打通,只差最后一步权限处理。
六、这个问题的两种解决方式
方案 A:给 PAT 增加 workflow 权限
如果你想把 .github/workflows 也一起同步到部署仓库,那就需要:
- 使用 classic PAT
- 勾选
repo - 勾选
workflow
这样就可以完整镜像整个仓库。
优点
- 仓库内容完全一致
- 不需要额外处理文件排除
缺点
- Token 权限更大
- 部署仓库其实不一定需要 workflow 文件
方案 B:同步时排除 .github/workflows
这是我最终更推荐的方案。
因为部署仓库只是给 Vercel 用的,通常并不需要主仓库里的 GitHub Actions 工作流。
优点
- 不需要额外的
workflowscope - 更安全
- 部署仓库更干净
- 更符合“只作为部署镜像仓库”的定位
七、最终采用的 GitHub Actions 配置
最后跑通的版本如下:
name: Sync to Vercel Repo on: push: branches: - master jobs: sync: runs-on: ubuntu-latest steps: - name: Checkout source repo uses: actions/checkout@v5 with: fetch-depth: 0 persist-credentials: false - name: Configure Git run: | git config user.name "vercel-sync-bot" git config user.email "your-email@example.com" - name: Verify secret exists env: TOKEN: ${{ secrets.VERCEL_DEPLOY_REPO_TOKEN }} run: | if [ -z "$TOKEN" ]; then echo "VERCEL_DEPLOY_REPO_TOKEN is empty" exit 1 fi echo "Secret exists" - name: Remove workflow files before sync run: | rm -rf .github/workflows - name: Add deploy remote env: TARGET_REPO: https://x-access-token:${{ secrets.VERCEL_DEPLOY_REPO_TOKEN }}@github.com/你的GitHub用户名/你的部署仓库名.git run: | git remote remove deploy 2>/dev/null || true git remote add deploy "$TARGET_REPO" git remote -v - name: Commit cleanup if needed run: | git add -A git diff --cached --quiet || git commit -m "Remove workflow files for deploy mirror" - name: Push to deploy repo run: | git push deploy HEAD:master --force
八、每一段配置的实际作用
actions/checkout@v5
拉取主仓库代码。
persist-credentials: false
阻止 github-actions[bot] 的默认认证覆盖自定义 PAT。
Verify secret exists
检查 VERCEL_DEPLOY_REPO_TOKEN 是否为空,避免排查半天才发现 Secret 根本没配置。
rm -rf .github/workflows
防止同步 workflow 文件时触发 workflow scope 限制。
git remote add deploy
添加部署仓库远程地址。
git push deploy HEAD:master --force
把当前主仓库的内容强制同步到部署仓库。
九、为什么这里要使用 --force
部署仓库的定位不是开发仓库,而是:
- 主仓库的镜像
- Vercel 的上游部署源
所以这里使用:
git push deploy HEAD:master --force
是合理的。
原因
- 保证部署仓库始终和主仓库一致
- 避免历史分叉
- 避免同步冲突
注意
部署仓库不应该手动改代码。
因为下次同步时,这些改动会被覆盖掉。
十、这次排障里最关键的经验总结
1. exit code 128 只是结果,不是根因
一定要往前翻红字,看真正失败的是哪一步。
2. Repository not found 不一定真的是仓库不存在
很多时候是:
- token 没权限
- 仓库对当前认证主体不可见
- 实际用的不是你以为的 token
3. 出现 github-actions[bot] 时,要优先怀疑默认凭证覆盖
如果日志里出现:
denied to github-actions[bot]
那通常说明当前 Git 操作用的是 Actions 默认身份,不是你的自定义凭证。
4. 空仓库不需要初始化
它完全可以直接接受第一次 push。
5. workflow 文件同步会触发额外权限要求
如果同步内容包含 .github/workflows/*.yml,GitHub 会要求 token 拥有 workflow 相关权限,否则就会被拒绝。
十一、最终结果
这套方案最终成功实现了:
- 主仓库继续正常开发
- 部署仓库专门给 Vercel 使用
- GitHub Actions 自动同步代码
- Vercel 只监听部署仓库
- 成功绕开了认证、权限和触发链路中的多个坑
对我来说,这比直接让 Vercel 连接主仓库更稳,也更适合后续持续维护。
如果你也在做类似的前端项目,或者在处理自动部署、GitHub 同步、Vercel 部署链路相关问题,可以参考我这套思路。
我的项目线上地址也放在这里,方便需要的人看看实际效果:https://runwaymotion.com。
十二、一句话总结
这次问题的本质,不是 Vercel 本身,而是:
GitHub Actions 同步到部署仓库时的认证链路和权限控制
真正关键的修复点,只有三个:
actions/checkout@v5persist-credentials: false- 排除
.github/workflows,避免 workflow 权限限制
把这三点处理好,“主仓库开发 + 部署仓库给 Vercel” 这套方案就能稳定跑通。

浙公网安备 33010602011771号