GitHub Actions如何在不同job之间复用构建环境?
GitHub Actions 默认每个独立job会分配独立运行环境,即便使用自托管runner,默认调度逻辑也可能将不同job分配到不同实例,无法直接继承前序job的运行环境,你可以根据自己的使用场景选择以下方案实现类似效果:
方案1:预构建自托管runner基础镜像(最推荐)
把环境准备步骤中的所有依赖(golang、nodejs、quasar cli等)直接打包进自托管runner的基础镜像,之后所有job启动时默认就具备所需依赖,完全省去每次工作流运行时的环境准备耗时,也不需要重复执行安装步骤。
这种方案最符合你并行利用runner资源的需求:前端构建job可以直接跑在预装好环境的runner1上,完成后上传spa产物,后端构建job跑在预装好环境的runner2上,下载产物后直接构建,两个runner都不需要再执行耗时的环境准备步骤。
方案2:抽离环境准备为可复用复合动作
如果不想修改runner镜像,可以把环境准备的步骤封装成仓库内的复合动作,前端和后端构建job分别引入这段步骤即可,虽然两个job都会执行一遍环境安装逻辑,但代码无需重复编写,配合apt缓存、npm缓存等能力可以大幅降低重复安装的耗时。
示例实现:
- 在仓库路径
.github/actions/setup-env/action.yml中定义复合动作:
name: 配置构建环境 runs: using: "composite" steps: - run: | apt update apt install software-properties-common -y add-apt-repository ppa:longsleep/golang-backports -y curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash - apt update && apt dist-upgrade -y apt install nodejs -y apt install golang-go -y npm install -g @quasar/cli shell: bash
- 在各构建job中直接引用即可:
steps: - uses: actions/checkout@v4 - uses: ./.github/actions/setup-env # 后续构建步骤
方案3:绑定同一常驻自托管runner实现环境复用
如果你的自托管runner是常驻进程(不是job运行完就销毁的临时实例),可以给所有相关job绑定同一个专属runner标签,并且通过needs指定依赖关系,因为所有job都跑在同一个物理runner上,环境准备阶段全局安装的依赖会保留,后续构建job可以直接使用。
示例配置:
jobs: setup-env: runs-on: [self-hosted, build-worker-1] # 指定同一个专属runner标签 steps: - name: prepare build environment run: # 你的环境安装逻辑 build-front: needs: setup-env runs-on: [self-hosted, build-worker-1] # 和前置job使用同一个runner steps: - uses: actions/checkout@v4 - name: build front working-directory: ./front run: | npm install quasar build # 上传spa产物的artifacts步骤 build-back: needs: build-front runs-on: [self-hosted, build-worker-1] steps: - uses: actions/checkout@v4 # 下载spa产物的artifacts步骤 - name: compile back working-directory: ./back run: | env GOOS=linux GOARCH=arm GOARM=5 go build -o dash.rpi deploy: needs: build-back runs-on: [self-hosted, build-worker-1] steps: # 部署步骤
注意该方案需要确保runner是常驻且不会在job结束后重置环境,同时避免其他工作流的job调度到该runner上干扰运行环境。
内容的提问来源于stack exchange,提问作者WoJ

