如何解决GitHub多OS矩阵工作流中push时的仓库过时错误?
问题答案
是的,后面完成的作业(比如Windows)执行git push时一定会触发仓库未更新的冲突错误。
原因很简单:每个矩阵作业都是独立从仓库检出代码的,Ubuntu作业先完成push后,远程仓库的HEAD已经更新到了新的提交,而Windows作业本地的仓库还是基于旧的HEAD创建的提交,push时Git会检测到远程仓库比本地新,拒绝推送,报错类似:
error: failed to push some refs to 'github.com:your/repo.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again.
解决方法
方法一:push前拉取并合并(适合产物无冲突场景)
如果不同平台的构建产物是分开存放的(比如不同目录、不同后缀),可以在提交后先拉取远程最新代码,合并后再push。修改你的Upload步骤脚本:
- name: Upload run: | git config --global user.email "user@gmail.com" git config --global user.name "user" git add . # 防止空提交(如果没有构建产物变化的话) git diff --staged --quiet || git commit -m "Build for ${{ matrix.os }}" # 拉取远程最新代码,用rebase避免多余的合并提交 git pull --rebase origin main # 替换成你的目标分支名 git push
加入git diff --staged --quiet ||是为了避免无文件变化时触发空提交,导致后续pull出错。
方法二:统一汇总产物后提交(更推荐)
这种方案更可靠,避免多作业push的冲突:让每个矩阵作业只负责构建并上传产物到GitHub Artifacts,最后用一个单独的作业下载所有产物,统一提交push。
- 修改矩阵作业,添加上传产物步骤:
jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-20.04, windows-2019, macos-11] steps: - uses: actions/checkout@v3 # 你的构建步骤(编译、打包等)... - name: Upload build artifacts uses: actions/upload-artifact@v3 with: name: build-${{ matrix.os }} path: ./path/to/build/outputs # 替换成你的构建产物路径
- 添加一个依赖所有构建作业的汇总上传作业:
upload-all: runs-on: ubuntu-20.04 needs: build # 等待所有build作业完成 steps: - uses: actions/checkout@v3 - name: Download all platform artifacts uses: actions/download-artifact@v3 with: path: ./build-artifacts # 将每个平台的产物移动到仓库对应目录(比如按平台分类) - run: | mkdir -p ./build/ubuntu ./build/windows ./build/macos cp -r ./build-artifacts/build-ubuntu-20.04/* ./build/ubuntu/ cp -r ./build-artifacts/build-windows-2019/* ./build/windows/ cp -r ./build-artifacts/build-macos-11/* ./build/macos/ - name: Commit and push all artifacts run: | git config --global user.email "user@gmail.com" git config --global user.name "user" git add ./build/ git diff --staged --quiet || git commit -m "Add build artifacts for all platforms" git push
这个方案的优势是逻辑清晰,完全避免了多作业同时操作仓库的冲突,还能统一管理所有平台的产物。
不推荐的方法:强制push
不要用git push --force,这会直接覆盖远程仓库的提交,导致先完成的作业的产物丢失,只有在你完全确定所有作业的提交不会互相覆盖时才考虑,一般不建议使用。
额外提示
确保不同平台的构建产物不会互相覆盖,比如按平台划分目录,这样无论是合并还是统一上传都不会出现文件冲突。
内容的提问来源于stack exchange,提问作者sudoer
相关产品推荐
相关产品推荐

