Rebase合并PR后如何复用PR校验时生成的二进制文件?
解决Rebase & Merge下复用PR构建缓存的问题
能不能让actions/checkout拉取rebased提交?
不行。Rebase & Merge的本质是将PR中的提交逐个变基到main分支的最新提交之上,生成全新的提交ID——这些提交只有在合并操作完成后才会存在于仓库中。GitHub支持拉取的预合并提交是针对Merge Commit模式的临时合并节点,而变基后的提交没有这类预生成的临时版本,因此actions/checkout无法拉取一个尚未创建的提交。
复用PR构建缓存的解决方案
核心思路是用不受变基影响的标识作为缓存键,替代提交ID。这里最可靠的是提交的树对象ID(Tree ID)——它由提交的文件内容哈希生成,只要提交的文件内容不变,无论怎么变基、修改提交元数据,Tree ID都不会改变。
步骤1:在PR工作流中用Tree ID缓存构建产物
在PR的校验工作流里,生成Tree ID并以此作为缓存键的核心部分:
jobs: pr-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # 获取当前提交的Tree ID - name: Get commit Tree ID id: get-tree-id run: echo "tree_id=$(git rev-parse HEAD^{tree})" >> $GITHUB_OUTPUT # 构建snapshot(替换为你的实际构建命令) - name: Build snapshot run: ./build-snapshot.sh # 用Tree ID作为缓存键存储构建产物 - name: Cache snapshot artifacts uses: actions/cache@v3 with: path: ./snapshot-output key: snapshot-${{ steps.get-tree-id.outputs.tree_id }}
步骤2:在main分支工作流中用Tree ID恢复缓存
当PR通过Rebase & Merge合并到main后,main分支的新提交虽然ID变了,但Tree ID和PR中的提交完全一致。在main分支的snapshot发布工作流中,同样获取Tree ID并匹配缓存:
jobs: publish-snapshot: runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 # 获取当前提交的Tree ID - name: Get commit Tree ID id: get-tree-id run: echo "tree_id=$(git rev-parse HEAD^{tree})" >> $GITHUB_OUTPUT # 从缓存中恢复PR阶段的构建产物 - name: Restore snapshot artifacts from cache uses: actions/cache@v3 with: path: ./snapshot-output key: snapshot-${{ steps.get-tree-id.outputs.tree_id }} # 发布snapshot到外部托管平台(替换为你的实际发布命令) - name: Publish snapshot run: ./publish-snapshot.sh
额外优化:结合PR编号避免缓存冲突
如果担心不同PR出现相同Tree ID的极端情况,可以在缓存键中加入PR编号进一步区分:
# PR工作流中的缓存键 key: snapshot-pr${{ github.event.pull_request.number }}-${{ steps.get-tree-id.outputs.tree_id }} # main分支工作流中,先获取合并的PR编号再拼接缓存键 - name: Get merged PR number id: get-pr-number run: echo "pr_number=$(gh pr view --json number --jq .number)" >> $GITHUB_OUTPUT env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Restore snapshot artifacts from cache uses: actions/cache@v3 with: path: ./snapshot-output key: snapshot-pr${{ steps.get-pr-number.outputs.pr_number }}-${{ steps.get-tree-id.outputs.tree_id }}
这样既保证了缓存的唯一性,又能精准匹配PR的构建产物。
内容的提问来源于stack exchange,提问作者flyx
相关产品推荐
相关产品推荐

