删除分支时如何取消该分支正在运行的GitHub Action工作流
删除分支时自动取消对应分支运行中工作流的实现方案
不要依赖内置concurrency规则,也不用找适配delete场景的第三方Action,直接基于delete事件的原始payload拿被删分支信息,调用GitHub API主动取消对应运行任务即可,可直接复用以下配置:
完整工作流配置
name: Cancel branch workflows on delete on: delete: branches: - '**' permissions: actions: write contents: read jobs: cancel-running: runs-on: ubuntu-latest steps: - name: Cancel all pending/running workflows on deleted branch uses: actions/github-script@v7 with: script: | // 仅处理分支删除场景,忽略tag删除 if (context.event.ref_type !== 'branch') { console.log('Non-branch delete event, skip') return } const deletedBranchRef = `refs/heads/${context.event.ref}` console.log(`Processing cancelled branch ref: ${deletedBranchRef}`) // 拉取该分支下所有运行中、排队中的工作流 const [runningRuns, queuedRuns] = await Promise.all([ github.paginate(github.rest.actions.listWorkflowRunsForRepo, { owner: context.repo.owner, repo: context.repo.repo, ref: deletedBranchRef, status: 'in_progress' }), github.paginate(github.rest.actions.listWorkflowRunsForRepo, { owner: context.repo.owner, repo: context.repo.repo, ref: deletedBranchRef, status: 'queued' }) ]) const allPendingRuns = [...runningRuns, ...queuedRuns] if (allPendingRuns.length === 0) { console.log('No pending or running workflows found on deleted branch') return } // 遍历取消,跳过当前执行取消逻辑的工作流本身 for (const run of allPendingRuns) { if (run.id === context.runId) continue await github.rest.actions.cancelWorkflowRun({ owner: context.repo.owner, repo: context.repo.repo, run_id: run.id }) console.log(`Cancelled run #${run.id}: ${run.name}`) }
之前方案不生效的原因
- 内置concurrency规则的上下文在delete事件下会漂移:分支被删除后触发的工作流,默认绑定到仓库默认分支,
github.ref会直接返回默认分支的ref值,根本无法匹配到被删分支的运行任务 - 直接用
${{ github.event.ref }}作为concurrency group也无法匹配:其他工作流运行时写入的concurrency group默认用完整ref格式refs/heads/分支名,短分支名无法命中匹配规则;且concurrency仅在同一个工作流文件内生效,无法跨工作流取消其他文件下的运行任务 - 现有第三方cancel类Action普遍默认读取
github.ref作为目标分支值,没有适配delete事件的payload取值逻辑,自然无法正常工作
注意事项
- 必须给工作流配置
actions: write权限,否则调用工作流取消接口会返回403无权限 - 脚本默认跳过tag删除场景,避免误取消tag关联的工作流运行
- 逻辑中特意排除了当前取消工作流自身的运行ID,不会出现自己取消自己的异常
- 用官方维护的
actions/github-script直接写逻辑,没有第三方依赖,不会出现后续适配失效问题
内容的提问来源于stack exchange,提问作者Motti Dadison
相关产品推荐
相关产品推荐

