如何在GitLab触发新流水线时取消旧流水线并解决Helm升级冲突
自动取消GitLab特定环境的活跃升级流水线,解决Helm并发冲突
方法1:利用GitLab CI内置的资源组与取消配置
这是最简洁的方案,通过resource_group和cancel-in-progress参数强制特定环境的部署作业串行执行,自动取消同环境正在运行的旧作业。
在你的Helm部署Job中添加如下配置:
helm-upgrade: stage: deploy environment: name: 你的目标环境名 # 比如production/staging action: start script: - helm upgrade --install 你的应用名 ./charts/你的应用目录 # 定义资源组,同一组的作业只能串行执行 resource_group: 你的环境名-deploy # 比如production-deploy # 自动取消同资源组中正在运行的旧作业 cancel-in-progress: true
原理说明
resource_group:将同一环境的部署作业归入同一资源组,GitLab会确保同一时间只有该组内的一个作业在运行cancel-in-progress: true:当新流水线触发时,GitLab会自动取消该资源组内所有正在运行的旧作业,直接启动新作业
方法2:通过GitLab API自定义取消逻辑
如果需要更精细的控制(比如只取消特定分支、特定类型的作业),可以在流水线启动时调用GitLab API主动取消旧的活跃流水线。
步骤1:创建CI/CD变量
在项目的「Settings → CI/CD → Variables」中添加GITLAB_TOKEN,该令牌需要拥有api权限(可以创建项目级的访问令牌,权限勾选「read_api」和「write_pipeline」)。
步骤2:添加前置取消脚本
在部署Job之前新增一个前置Job,用于查询并取消目标环境的旧活跃流水线:
cancel-old-pipelines: stage: pre-deploy image: alpine/curl:latest before_script: - apk add jq # 安装jq用于解析JSON响应 script: # 查询当前项目中,目标环境下、当前分支的正在运行的流水线 - | OLD_PIPELINES=$(curl --silent --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$CI_API_V4_URL/projects/$CI_PROJECT_ID/pipelines?status=running&environment=你的目标环境名&ref=$CI_COMMIT_BRANCH" | \ jq -r '.[] | .id') # 遍历取消旧流水线(排除当前流水线) - | for PIPELINE_ID in $OLD_PIPELINES; do if [ "$PIPELINE_ID" != "$CI_PIPELINE_ID" ]; then echo "取消流水线ID: $PIPELINE_ID" curl --silent --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ "$CI_API_V4_URL/projects/$CI_PROJECT_ID/pipelines/$PIPELINE_ID/cancel" fi done rules: - if: $CI_COMMIT_BRANCH == '你的部署分支' # 比如main/master helm-upgrade: stage: deploy needs: [cancel-old-pipelines] # 依赖前置取消Job environment: name: 你的目标环境名 action: start script: - helm upgrade --install 你的应用名 ./charts/你的应用目录
注意事项
- 确保
GITLAB_TOKEN的权限足够,避免API调用失败 - 可以根据需要调整API查询参数,比如过滤特定的作业名称或流水线标签
- 若使用私有GitLab实例,确保
CI_API_V4_URL指向正确的实例地址
内容的提问来源于stack exchange,提问作者Francis Nahounou
相关产品推荐
相关产品推荐

