如何基于标签关联分支触发不同可复用GitHub Actions工作流?
问题描述
我希望根据创建标签时对应的目标分支,触发不同的可复用GitHub Actions工作流。例如:
- 从
main分支创建标签时,触发run-on-prod-tags.yml工作流 - 从以
feature开头的分支创建标签时,触发run-on-stage-tags.yml工作流
我尝试用以下代码实现:
name: Tag Workflow on: push: tags: - '*' jobs: check-tag: runs-on: docker-runner steps: - name: checkout Source Code uses: actions/checkout@v3 with: # Disabling shallow clone is recommended for improving relevancy of reporting fetch-depth: 0 - name: Get Branch run: | echo ${{ github.ref }} raw=$(git branch -r --contains ${{ github.ref }}) branch=${raw##*/} echo "BRANCH=$branch" >> $GITHUB_ENV - run: echo ${{env.BRANCH}} build-and-deploy: needs: [check-tag] uses: ./.github/workflows/run-on-${{env.BRANCH}}-tags.yml
但这种实现存在弊端:若修改可复用工作流的文件名,当前代码会失效。我需要更稳健的实现方案,请问有什么思路吗?
附脚本输出:
可行的稳健实现思路
1. 分支-工作流映射表(推荐)
把分支到工作流的对应逻辑集中在一处,用明确的变量传递工作流文件名,后续修改文件名时只需更新映射规则,无需改动调用逻辑:
jobs: check-tag: runs-on: docker-runner outputs: workflow_file: ${{ steps.set-workflow.outputs.workflow_file }} steps: - name: checkout Source Code uses: actions/checkout@v3 with: fetch-depth: 0 - name: Determine workflow file id: set-workflow run: | # 获取标签对应的分支(优化后的逻辑,避免多分支匹配问题) commit_hash=$(git rev-parse ${{ github.ref }}) branch=$(git branch --contains $commit_hash | grep -v 'remotes/' | sed 's/* //') if [ -z "$branch" ]; then branch=$(git branch -r --contains $commit_hash | sed 's/origin\///' | head -n 1) fi # 根据分支匹配对应的工作流 case "$branch" in main) echo "workflow_file=run-on-prod-tags.yml" >> $GITHUB_OUTPUT ;; feature/*) echo "workflow_file=run-on-stage-tags.yml" >> $GITHUB_OUTPUT ;; # 可添加更多分支规则 *) echo "workflow_file=run-on-default-tags.yml" >> $GITHUB_OUTPUT ;; esac build-and-deploy: needs: [check-tag] uses: ./.github/workflows/${{ needs.check-tag.outputs.workflow_file }}
2. 矩阵+条件跳过
用矩阵定义分支与工作流的对应关系,通过条件判断只执行当前分支匹配的工作流,规则清晰易维护:
jobs: check-tag: runs-on: docker-runner outputs: branch: ${{ steps.get-branch.outputs.branch }} steps: - name: checkout Source Code uses: actions/checkout@v3 with: fetch-depth: 0 - name: Get Branch id: get-branch run: | commit_hash=$(git rev-parse ${{ github.ref }}) branch=$(git branch --contains $commit_hash | grep -v 'remotes/' | sed 's/* //') if [ -z "$branch" ]; then branch=$(git branch -r --contains $commit_hash | sed 's/origin\///' | head -n 1) fi echo "branch=$branch" >> $GITHUB_OUTPUT build-and-deploy: needs: [check-tag] strategy: matrix: include: - branch: main workflow: run-on-prod-tags.yml - branch: feature/* workflow: run-on-stage-tags.yml if: | (matrix.branch == needs.check-tag.outputs.branch) || (matrix.branch == 'feature/*' && startsWith(needs.check-tag.outputs.branch, 'feature/')) uses: ./.github/workflows/${{ matrix.workflow }}
3. 标签前缀区分(业务允许时优先)
如果团队能统一标签命名规范,比如生产环境标签用v*、预发布用feature-v*,可以直接在触发条件里区分,完全避免分支判断:
# 生产环境标签触发工作流 name: Prod Tag Workflow on: push: tags: - 'v*' jobs: build-and-deploy: uses: ./.github/workflows/run-on-prod-tags.yml
# 预发布环境标签触发工作流 name: Stage Tag Workflow on: push: tags: - 'feature-v*' jobs: build-and-deploy: uses: ./.github/workflows/run-on-stage-tags.yml
内容的提问来源于stack exchange,提问作者Berkin
相关产品推荐
相关产品推荐

