You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:05:21