GitHub Actions多作业如何共享代码 避免检出非预期提交
GitHub Actions多作业checkout相关问题解答
问题1:运行中产生新提交会不会被checkout拉取?
默认配置下不会。
GitHub Actions在工作流被触发的瞬间,就会把本次运行对应的精确提交SHA固定到github.sha上下文变量中,actions/checkout@v3默认行为就是检出这个固定的SHA,而非直接拉取触发分支的最新HEAD,所以工作流启动之后推到仓库的新提交,完全不会影响当前运行中作业的代码版本。
只有当你手动修改了checkout步骤的ref参数(比如显式写了ref: main指定拉取分支头),才会出现拉取到运行中新提交的版本漂移问题。
规避方法非常简单:
- 非必要不要自定义checkout的
ref参数,保持默认配置即可自动锁定触发时的提交版本 - 如果确实需要自定义ref逻辑,显式指定
ref: ${{ github.sha }}就能彻底锁死代码版本 - 跨工作流复用、可复用工作流调用场景下,把触发时的SHA作为入参传递给被调用工作流,同样可以避免版本漂移
问题2:多作业共享代码的方案选择
你现在每个作业单独配置checkout的写法没有任何副作用,是GitHub官方推荐的标准实现,完全可以保留。
首先明确一个前提:GitHub Actions的每个作业都运行在完全独立的全新运行环境上,作业之间默认文件系统完全隔离,不存在天然的文件共享通道。针对你提到的几个方案,适用场景和优缺点非常明确:
- 不推荐用
actions/cache传递源代码:这个动作的设计定位是存储依赖缓存(比如Maven本地仓库、npm依赖目录这类体积大、对版本一致性要求不极端严格的内容),本身有单仓库缓存大小上限、自动淘汰策略、key匹配逻辑,很容易出现拉到旧版本代码、缓存损坏的问题,完全不适合存储需要严格版本匹配的源代码。 actions/upload-artifact+actions/download-artifact组合仅适用于特定场景:只有当前序作业对源代码做了修改(比如执行了代码生成、打了源码补丁、生成了需要和源码配合使用的构建产物),后续作业需要用到修改后的内容时,才适合用artifact传递。如果只是传递未修改的原生仓库代码,这套方案比直接checkout慢得多(需要走artifact的上传、下载流程),还会受artifact存储大小、保留期限的限制,性价比极低。
如果你的仓库体积特别大,觉得每个作业checkout耗时太长,直接优化checkout步骤的参数即可,不需要换方案:- 加
fetch-depth: 1配置开启浅克隆,不拉取完整的Git提交历史,能大幅缩短拉取时间 - 有Git LFS大文件的场景,配置按需拉取LFS文件,不需要全量拉取所有大文件
- 加
配置优化参考
你当前的配置只需要做小幅调整即可,这里给个优化后的示例,顺便修正了deploy步骤里的脚本名拼写错误、补全了作业依赖避免构建失败时仍然执行部署:
name: my_job on: [push] jobs: build_and_test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: fetch-depth: 1 # 浅克隆提速 - uses: actions/setup-java@v3 with: distribution: 'adopt' java-version: '17' cache: 'maven' - name: test run: ./mvnw clean verify - name: build run: ./mvnw package deploy: runs-on: ubuntu-latest needs: build_and_test # 依赖构建测试作业,避免无效部署 steps: - uses: actions/checkout@v3 with: fetch-depth: 1 - name: infrastructure run: ./script/infrastructure.sh - name: deploy app run: ./script/deploy_app.sh # 修正原配置里的delploy拼写错误
内容的提问来源于stack exchange,提问作者Samson
相关产品推荐
相关产品推荐

