You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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触发实时清理

这是最及时的方案,适合需要立刻清理制品的场景:

  1. 在你的Git服务(GitHub/GitLab/Gitea等)上配置Webhook,当分支被删除时,发送请求到Jenkins的流水线触发URL。
  2. 创建一个参数化声明式流水线,接收被删除分支的名称作为参数,然后编写清理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:54:38