如何在Jenkins中执行分支修剪代码及分支删除后制品清理
问题1:如何在Jenkins中执行“Prune stale remote-tracking branches”对应的代码?
其实有两种实用方式,看你是想自动触发还是手动在流水线里控制时机:
方式1:通过Git插件自动修剪
如果你是在配置Jenkins项目的SCM(比如自由风格项目或流水线的checkout步骤),Git插件自带「Prune stale remote-tracking branches」选项。勾选之后,每次拉取代码时,Jenkins会自动执行git fetch --prune,帮你清理本地那些对应远程已删除的追踪分支,不用额外写代码。
方式2:在声明式流水线中手动执行命令
如果需要在流水线的特定阶段手动触发修剪,可以直接用sh步骤(Windows环境用bat)执行Git命令:
单独修剪远程追踪分支
这个命令只会清理本地失效的远程追踪分支,不会拉取新代码:
pipeline { agent any stages { stage('Prune Stale Branches') { steps { script { // 确保当前目录是代码仓库(一般checkout后自动切换) sh 'git remote prune origin' } } } } }
拉取代码同时修剪
如果想在拉取最新代码的同时完成修剪,用这个命令更高效:
sh 'git fetch --prune origin'
注意:要保证Jenkins代理节点安装了Git,且当前工作目录是你的代码仓库路径。
问题2:分支删除后执行额外清理代码,声明式流水线有可用的钩子或插件吗?
Jenkins本身没有直接监听「分支被删除」的内置钩子,但我们可以通过两种可靠的方式实现需求:
方案1:Git Webhook触发实时清理
这是最及时的方案,适合需要立刻清理制品的场景:
- 在你的Git服务(GitHub/GitLab/Gitea等)上配置Webhook,当分支被删除时,发送请求到Jenkins的流水线触发URL。
- 创建一个参数化声明式流水线,接收被删除分支的名称作为参数,然后编写清理AMIs、Docker镜像、Terraform资源的逻辑。
示例流水线代码:
pipeline { agent any // 定义参数,接收被删除的分支名 parameters { string(name: 'DELETED_BRANCH', description: '要清理制品的已删除分支名称') } stages { stage('清理AWS AMIs') { steps { script { // 根据分支标签查找并删除AMI,替换成你的实际逻辑 sh """ AMI_ID=$(aws ec2 describe-images --filters "Name=tag:Branch,Values=${params.DELETED_BRANCH}" --query 'Images[0].ImageId' --output text 2>/dev/null) if [ ! -z "\$AMI_ID" ]; then aws ec2 deregister-image --image-id \$AMI_ID echo "已删除AMI: \$AMI_ID" else echo "未找到对应分支的AMI" fi """ } } } stage('清理Docker镜像') { steps { script { // 删除本地镜像 sh "docker rmi my-registry.com/my-project:${params.DELETED_BRANCH} || true" // 删除远程仓库镜像(示例适配Harbor/GitLab Registry) sh """ DIGEST=$(skopeo inspect docker://my-registry.com/my-project:${params.DELETED_BRANCH} --format '{{.Digest}}' 2>/dev/null) if [ ! -z "\$DIGEST" ]; then curl -X DELETE -u "username:password" https://my-registry.com/v2/my-project/manifests/\$DIGEST echo "已删除远程Docker镜像: my-registry.com/my-project:${params.DELETED_BRANCH}" else echo "未找到对应分支的Docker镜像" fi """ } } } stage('清理Terraform资源') { steps { script { dir('terraform-deploy') { // 初始化Terraform,切换工作空间并销毁资源 sh "terraform init || true" sh "terraform workspace select ${params.DELETED_BRANCH} || true" sh "terraform destroy -auto-approve -var branch=${params.DELETED_BRANCH} || true" sh "terraform workspace delete ${params.DELETED_BRANCH} || true" } } } } } post { always { echo "分支${params.DELETED_BRANCH}的制品清理流程已完成" } } }
方案2:定时扫描已删除分支并清理
如果你的Git服务不支持Webhook,或者不需要实时清理,可以创建一个定时运行的流水线,定期检查哪些本地分支的上游远程分支已被删除,自动执行清理:
示例代码:
pipeline { agent any // 每天凌晨1点运行一次 triggers { cron('0 1 * * *') } stages { stage('识别已删除的分支') { steps { script { // 拉取最新远程分支信息并修剪 sh 'git fetch --prune origin' // 找出所有上游已不存在的本地分支 def deletedBranches = sh( script: """ git for-each-ref --format='%(refname:short)' refs/heads | while read branch; do if ! git rev-parse --verify --quiet origin/\$branch >/dev/null; then echo \$branch fi done """, returnStdout: true ).trim().split('\n') if (deletedBranches.size() > 0) { echo "发现已删除的分支:${deletedBranches.join(', ')}" // 遍历每个分支执行清理 deletedBranches.each { branch -> echo "开始清理分支${branch}的制品..." cleanUpArtifacts(branch) } } else { echo "没有找到已删除的分支,无需清理" } } } } } } // 封装清理逻辑的公共函数 def cleanUpArtifacts(String branch) { // 清理AMIs sh """ AMI_ID=$(aws ec2 describe-images --filters "Name=tag:Branch,Values=${branch}" --query 'Images[0].ImageId' --output text 2>/dev/null) [ ! -z "\$AMI_ID" ] && aws ec2 deregister-image --image-id \$AMI_ID || echo "无对应AMI" """ // 清理Docker镜像 sh "docker rmi my-registry.com/my-project:${branch} || true" // 清理Terraform资源 dir('terraform-deploy') { sh "terraform init || true" sh "terraform workspace select ${branch} || true" sh "terraform destroy -auto-approve -var branch=${branch} || true" sh "terraform workspace delete ${branch} || true" } }
注意事项
- 确保Jenkins代理节点拥有足够权限:比如AWS访问权限、Docker镜像仓库的读写权限、Terraform执行权限等。
- 可以在清理步骤中加入错误捕获(比如
|| true或Jenkins的catchError步骤),避免单个资源清理失败导致整个流水线中断。 - 如果使用Webhook,要确保Jenkins能接收Git服务的请求(比如配置防火墙、反向代理)。
内容的提问来源于stack exchange,提问作者xenoterracide
相关产品推荐
相关产品推荐

