矩阵场景下GitHub Actions构建与发布的正确执行顺序
实现多平台构建并统一创建GitHub Release的解决方案
需求
- 为多个平台构建可执行制品
- 创建GitHub Release并关联所有构建完成的制品
最初的尝试与问题
最初将构建和发布放在同一个矩阵作业中,每个平台构建完成后都会触发Release创建,导致GitHub返回“Release已存在”的错误,配置如下:
name: "Release" on: push: branches: "*" tags: - "*" permissions: contents: write jobs: release: name: Release runs-on: ${{ matrix.target.host || 'ubuntu-latest' }} strategy: fail-fast: false matrix: go-version: ["1.21.x"] target: - os: linux - os: windows ext: .exe - os: freebsd - os: android - os: darwin host: macos-latest steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v4 with: # cache: # - description: Used to specify whether caching is needed. Set to true, if you'd like to enable caching. # default: false go-version-file: "go.mod" cache-dependency-path: | go.sum - name: Install Fyne-cross # working-directory: fyne-cross run: go install github.com/fyne-io/fyne-cross@latest # attempt to use "go install" but fallback to "go get" - name: Install Fyne run: | go install fyne.io/fyne/v2/cmd/fyne@latest || go get fyne.io/fyne/v2/cmd/fyne@latest - name: Install Podman if: ${{ runner.os == 'macos' }} run: | brew install podman podman machine init podman machine start - name: "Build MastoTool (${{ matrix.target.os }}, ${{ matrix.go-version }})" run: | fyne-cross \ ${{ matrix.target.os }} \ ${{ matrix.target.args }} \ -name mastotool${{ matrix.target.ext }} \ -app-id com.github.PaulWaldo.mastotool - uses: ncipollo/release-action@v1 with: artifacts: fyne-cross/dist/**/mastotool*
拆分作业后的新问题
将构建和发布拆分为两个独立作业后,release作业无法获取到artifacts作业生成的制品,因为作业之间的文件系统是相互隔离的,配置如下:
name: "Release" on: push: branches: "*" tags: - "*" permissions: contents: write jobs: artifacts: name: Create Artifacts runs-on: ${{ matrix.target.host || 'ubuntu-latest' }} strategy: fail-fast: false matrix: go-version: ["1.21.x"] target: - os: linux - os: windows ext: .exe - os: freebsd - os: android # Darwin not working right now # - os: darwin # host: macos-latest steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v4 with: # cache: # - description: Used to specify whether caching is needed. Set to true, if you'd like to enable caching. # default: false go-version-file: "go.mod" cache-dependency-path: | go.sum - name: Install Fyne-cross # working-directory: fyne-cross run: go install github.com/fyne-io/fyne-cross@latest # attempt to use "go install" but fallback to "go get" - name: Install Fyne run: | go install fyne.io/fyne/v2/cmd/fyne@latest || go get fyne.io/fyne/v2/cmd/fyne@latest - name: Install Podman if: ${{ runner.os == 'macos' }} run: | brew install podman podman machine init podman machine start - name: "Build MastoTool (${{ matrix.target.os }}, ${{ matrix.go-version }})" run: | fyne-cross \ ${{ matrix.target.os }} \ ${{ matrix.target.args }} \ -name mastotool${{ matrix.target.ext }} \ -app-id com.github.PaulWaldo.mastotool release: name: Create Release needs: artifacts runs-on: "ubuntu-latest" steps: - run: ls -lR fyne-cross/dist - uses: ncipollo/release-action@v1 with: artifacts: fyne-cross/dist/**/mastotool*
可行的解决方案
通过上传/下载工作流制品实现作业间的文件共享,等待所有平台构建完成后统一创建Release,最终可正常运行的配置如下:
name: "Release" on: push: branches: "*" tags: - "*" permissions: contents: write jobs: artifacts: name: Create Artifacts runs-on: ${{ matrix.target.host || 'ubuntu-latest' }} strategy: fail-fast: false matrix: go-version: ["1.21.x"] target: - os: linux - os: windows ext: .exe - os: freebsd - os: android # Darwin not working right now # - os: darwin # host: macos-latest steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v4 with: cache: true go-version-file: "go.mod" cache-dependency-path: | go.sum - name: Install Fyne-cross # working-directory: fyne-cross run: go install github.com/fyne-io/fyne-cross@latest # attempt to use "go install" but fallback to "go get" - name: Install Fyne run: | go install fyne.io/fyne/v2/cmd/fyne@latest || go get fyne.io/fyne/v2/cmd/fyne@latest - name: Install Podman if: ${{ runner.os == 'macos' }} run: | brew install podman podman machine init podman machine start - name: "Build MastoTool (${{ matrix.target.os }}, ${{ matrix.go-version }})" # Place build targets in "/home/runner/work/mastotool/mastotool/fyne-cross/dist/linux-amd64/mastotool.tar.xz" run: | fyne-cross \ ${{ matrix.target.os }} \ ${{ matrix.target.args }} \ -name mastotool-${{ matrix.target.os }}${{ matrix.target.ext }} \ -app-id com.github.PaulWaldo.mastotool ls -lR fyne-cross/dist - name: Archive production artifacts uses: actions/upload-artifact@v3 with: name: mastotool path: fyne-cross/dist/${{ matrix.target.os }}*/* release: name: Create Release needs: artifacts runs-on: "ubuntu-latest" steps: - name: Download all workflow run artifacts uses: actions/download-artifact@v3 - run: ls -lR - uses: ncipollo/release-action@v1 with: artifacts: mastotool/*/*
关键修改点
- 在
artifacts作业中添加actions/upload-artifact步骤,将每个平台的构建产物上传到GitHub工作流制品库 - 在
release作业中使用actions/download-artifact下载所有上传的制品,确保发布时能获取到全平台产物 - 修改构建产物命名规则,加入平台标识(如
mastotool-linux),避免不同平台产物文件名冲突 - 启用Go模块缓存,减少重复依赖下载,提升构建效率
内容的提问来源于stack exchange,提问作者Paul Waldo
相关产品推荐
相关产品推荐

