如何在GitHub Workflow中通过条件值简化重复发布逻辑?
优化GitHub Workflow重复代码的方案
问题描述
现有GitHub Workflow中,针对三种事件场景(master分支推送、拉取请求、标签推送)的发布步骤存在大量重复,仅参数值有差异。需要合并重复步骤,通过条件动态设置参数来实现以下需求:
- 提交推送到master分支时,以
latest标签发布 - 标签推送到仓库时,使用标签自身名称发布
- 拉取请求(PR)以其分支名称发布
原始重复代码示例:
name: Build LaTeX document & latexdiff to previous tagged version. on: push: branches: [master] pull_request: workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - name: Build stuff ... ... - name: Upload results (master latest) uses: "marvinpinto/action-automatic-releases@latest" with: repo_token: "${{ secrets.GITHUB_TOKEN }}" automatic_release_tag: "latest" prerelease: true draft: true title: "Build" files: | result if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} - name: Upload results (pull request) uses: "marvinpinto/action-automatic-releases@latest" with: repo_token: "${{ secrets.GITHUB_TOKEN }}" automatic_release_tag: github.ref_name prerelease: true draft: true title: "Build" files: | result if: ${{ github.event_name == 'pull_request' }} - name: Upload results (tag) uses: "marvinpinto/action-automatic-releases@latest" with: repo_token: "${{ secrets.GITHUB_TOKEN }}" automatic_release_tag: github.ref_name prerelease: false draft: false title: "Build" files: | result if: ${{ github.ref_type == 'tag' }}
优化方案:用条件表达式合并步骤
利用GitHub Actions的内置条件表达式,将三个重复的发布步骤合并为一个,动态设置每个参数的值,既精简代码又便于维护。
优化后的完整Workflow
name: Build LaTeX document & latexdiff to previous tagged version. on: push: branches: [master] tags: ['*'] # 补充监听标签推送事件 pull_request: workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - name: Build stuff ... ... - name: Upload results uses: marvinpinto/action-automatic-releases@latest with: repo_token: ${{ secrets.GITHUB_TOKEN }} # 动态生成发布标签:master推送用latest,其余场景用ref名称 automatic_release_tag: >- ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' ? 'latest' : github.ref_name }} # 仅正式标签发布时设为非预发布,其余场景保持预发布状态 prerelease: ${{ github.ref_type != 'tag' }} # 仅正式标签发布时设为非草稿,其余场景保持草稿状态 draft: ${{ github.ref_type != 'tag' }} title: "Build" files: | result # 限定仅在目标场景下执行该步骤 if: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/master') || github.event_name == 'pull_request' || github.ref_type == 'tag' }}
关键逻辑说明
- 发布标签:通过三元表达式判断场景,master分支推送时使用
latest,PR和标签推送时直接使用github.ref_name(PR对应分支名,标签对应标签名) - 预发布与草稿状态:利用
github.ref_type != 'tag'实现反向判断,只有标签推送时关闭预发布和草稿,其余场景保持开启 - 执行条件:通过逻辑或合并三种目标场景,确保该步骤仅在需要发布的事件触发时运行
可选方案:用环境变量拆分复杂逻辑
如果觉得参数内的表达式可读性不足,可以先通过一个步骤定义环境变量,再在发布步骤中引用,让逻辑更清晰:
name: Build LaTeX document & latexdiff to previous tagged version. on: push: branches: [master] tags: ['*'] pull_request: workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - name: Build stuff ... ... - name: Set release parameters id: set_params run: | # 确定发布标签 if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == "refs/heads/master" ]]; then echo "RELEASE_TAG=latest" >> "$GITHUB_OUTPUT" else echo "RELEASE_TAG=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" fi # 确定预发布和草稿状态 if [[ "${{ github.ref_type }}" == "tag" ]]; then echo "PRERELEASE=false" >> "$GITHUB_OUTPUT" echo "DRAFT=false" >> "$GITHUB_OUTPUT" else echo "PRERELEASE=true" >> "$GITHUB_OUTPUT" echo "DRAFT=true" >> "$GITHUB_OUTPUT" fi - name: Upload results uses: marvinpinto/action-automatic-releases@latest with: repo_token: ${{ secrets.GITHUB_TOKEN }} automatic_release_tag: ${{ steps.set_params.outputs.RELEASE_TAG }} prerelease: ${{ steps.set_params.outputs.PRERELEASE }} draft: ${{ steps.set_params.outputs.DRAFT }} title: "Build" files: | result if: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/master') || github.event_name == 'pull_request' || github.ref_type == 'tag' }}
内容的提问来源于stack exchange,提问作者lrnv
相关产品推荐
相关产品推荐

