如何保留正在运行的GitHub Action任务并取消旧排队任务?
解决GitHub Actions并发配置导致Terraform状态锁的问题
一、实现“保留已启动任务,仅运行排队中最新任务”的方案
你当前用的cancel-in-progress: true会直接取消正在运行的任务,这才引发了Terraform状态锁。要实现保留已启动任务、只取消排队里的旧任务,可以这么做:
调整并发基础配置
把concurrency改成不取消正在运行的任务:concurrency: group: my-job cancel-in-progress: false这时候新触发的任务会进入排队队列,不会打断正在运行的任务,但默认所有排队任务都会挨个执行。
加个步骤取消旧排队任务
在workflow开头加一步,用GitHub CLI取消同仓库里状态为queued、且比当前任务早的旧排队任务,确保只有最新的排队任务能运行:- name: 取消旧排队任务 if: github.event_name == 'push' && github.ref == 'refs/heads/main' run: | gh run list --repo ${{ github.repository }} --status queued --json id,runNumber --jq '.[] | select(.runNumber < ${{ github.run_number }}) | .id' | xargs -I {} gh run cancel {} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
二、避免Terraform状态锁的其他方案
要是不想调整并发排队的逻辑,也可以用这些方法避免任务取消导致的状态锁:
任务取消时自动解锁状态
在Terraform执行步骤之后,加一个专门针对任务取消场景的解锁步骤,确保状态锁能被释放:- name: Terraform Apply id: apply run: terraform apply -auto-approve env: TF_IN_AUTOMATION: "true" - name: 任务取消时解锁Terraform状态 if: cancelled() run: terraform force-unlock -force $(terraform state show lock_info | grep ID | awk '{print $2}') env: TF_IN_AUTOMATION: "true"设置状态锁超时时间
在Terraform命令里加上-lock-timeout参数,让Terraform获取锁失败时先等一会儿再重试,别直接报错:terraform apply -auto-approve -lock-timeout=10m用远程状态管理服务
换成Terraform Cloud/Enterprise,或者AWS S3+DynamoDB这类远程状态存储方案,它们会自动处理状态锁的超时释放——就算任务意外取消,锁也会在设定时间后自动解除。
内容的提问来源于stack exchange,提问作者danie
相关产品推荐
相关产品推荐

