GitHub Actions并发死锁求助:test与deploy工作流冲突
解决GitHub Actions并发死锁问题的可行方案
问题根源
当test工作流作为顶级流程运行并调用deploy可复用工作流时,两者若使用相同(或冲突)的并发组,会触发GitHub的死锁检测:顶级流程占用并发组后等待子流程完成,而子流程又试图抢占同一并发组,导致互相阻塞。
方案一:通过事件类型控制deploy的并发配置
在deploy.yml中,仅当工作流手动触发(workflow_dispatch)时启用独立并发控制,被其他工作流调用(workflow_call)时禁用自身并发,依赖调用方的并发规则:
# .github/workflows/deploy.yml on: workflow_call: workflow_dispatch: concurrency: # 仅手动触发时使用独立并发组,被调用时不启用自身并发控制 group: ${{ github.event_name == 'workflow_dispatch' && format('deploy-{0}', github.ref) || '' }} cancel-in-progress: true
test.yml的并发配置保持不变,例如:
# .github/workflows/test.yml on: [push] concurrency: group: test-${{ github.ref }} cancel-in-progress: true jobs: deploy: uses: ./.github/workflows/deploy.yml
方案二:通过调用参数显式控制deploy的并发
在deploy工作流中定义输入参数,允许调用方决定是否启用其独立并发控制,灵活性更强:
- 修改
deploy.yml,添加参数并配置条件式并发:
# .github/workflows/deploy.yml on: workflow_call: inputs: enable_concurrency: type: boolean default: true # 手动触发时默认启用 workflow_dispatch: concurrency: group: ${{ inputs.enable_concurrency && format('deploy-{0}', github.ref) || '' }} cancel-in-progress: true
- 在
test.yml调用deploy时,显式关闭其并发控制:
# .github/workflows/test.yml on: [push] concurrency: group: test-${{ github.ref }} cancel-in-progress: true jobs: deploy: uses: ./.github/workflows/deploy.yml with: enable_concurrency: false
效果说明
- 两种方案均能避免
test调用deploy时的死锁:deploy被调用时不启用自身并发,由test的并发规则统一控制新提交时取消pending任务。 - 手动触发
deploy时,会启用独立的deploy-<ref>并发组,实现手动触发任务的独立并发控制,新的手动触发会自动取消之前pending的手动部署任务。
内容的提问来源于stack exchange,提问作者Bruno Oliveira
相关产品推荐
相关产品推荐

