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

Jenkins声明式流水线实现Git分支生命周期超X天通知

解决Jenkins声明式流水线中分支生命周期/构建间隔的通知问题

嗨,我来帮你搞定这个分支生命周期和构建间隔的通知逻辑!你已经搞定了成功失败场景的emailext,剩下的这两个条件其实可以通过Git命令+Jenkins内置对象来实现,我给你一步步拆解:

一、先搞定分支生命周期的计算

Jenkins本身没有直接提供分支创建时间的变量,所以我们用Git命令来获取近似的分支创建时间——取分支最早的提交时间戳,毕竟分支刚创建完一般就会有提交,这个值足够靠谱。

在流水线里加一段脚本逻辑,计算分支从创建到现在的天数:

script {
    // 获取当前分支名称
    def branchName = env.BRANCH_NAME
    // 用Git命令捞取分支最早的提交时间戳(秒级)
    def branchCreateTimestamp = sh(
        script: "git log --reverse --format=%ct ${branchName} | head -1",
        returnStdout: true
    ).trim()
    // 计算当前时间戳和分支创建时间戳的差值,转成天数
    def currentTimestamp = new Date().getTime() / 1000
    def branchAgeDays = Math.floor((currentTimestamp - branchCreateTimestamp.toLong()) / 86400)
    // 存到环境变量里,方便后面判断用
    env.BRANCH_AGE_DAYS = branchAgeDays.toString()
}

二、计算两次构建的间隔天数

这个就简单多了,Jenkins的currentBuild对象自带previousBuild属性,能拿到上次构建的时间,直接和当前构建时间做差值计算就行:

script {
    def buildIntervalDays = 0
    // 要处理第一次构建的情况(没有上次构建记录)
    if (currentBuild.previousBuild != null) {
        def previousBuildTimestamp = currentBuild.previousBuild.time.getTime() / 1000
        def currentBuildTimestamp = currentBuild.time.getTime() / 1000
        buildIntervalDays = Math.floor((currentBuildTimestamp - previousBuildTimestamp) / 86400)
    }
    env.BUILD_INTERVAL_DAYS = buildIntervalDays.toString()
}

三、整合到你的emailext通知里

把上面的计算逻辑放到流水线的post阶段,和你原来的成功/失败通知整合到一起。这里我给你写了完整的示例,你可以直接替换成你的配置:

pipeline {
    agent any
    environment {
        // 这里定义你要的阈值,比如分支超过10天、构建间隔超过7天触发通知
        BRANCH_AGE_THRESHOLD = 10
        BUILD_INTERVAL_THRESHOLD = 7
    }
    stages {
        stage('Build') {
            steps {
                // 替换成你自己的构建步骤
                echo '正在执行构建...'
            }
        }
    }
    post {
        always {
            script {
                // 先计算分支年龄
                def branchName = env.BRANCH_NAME
                def branchCreateTimestamp = sh(
                    script: "git log --reverse --format=%ct ${branchName} | head -1",
                    returnStdout: true
                ).trim()
                def currentTimestamp = new Date().getTime() / 1000
                def branchAgeDays = Math.floor((currentTimestamp - branchCreateTimestamp.toLong()) / 86400)
                
                // 再计算构建间隔天数
                def buildIntervalDays = 0
                if (currentBuild.previousBuild != null) {
                    def previousBuildTimestamp = currentBuild.previousBuild.time.getTime() / 1000
                    def currentBuildTimestamp = currentBuild.time.getTime() / 1000
                    buildIntervalDays = Math.floor((currentBuildTimestamp - previousBuildTimestamp) / 86400)
                }
                
                // 判断分支年龄是否超过阈值,触发通知
                if (branchAgeDays >= BRANCH_AGE_THRESHOLD.toInteger()) {
                    emailext (
                        to: 'your-team@example.com',
                        subject: "[Jenkins] 分支 ${branchName} 已超过 ${BRANCH_AGE_THRESHOLD} 天未更新",
                        body: """
                            分支名称:${branchName}
                            已存活天数:${branchAgeDays} 天
                            当前构建链接:${env.BUILD_URL}
                        """
                    )
                }
                
                // 判断构建间隔是否超过阈值,触发通知
                if (buildIntervalDays >= BUILD_INTERVAL_THRESHOLD.toInteger()) {
                    emailext (
                        to: 'your-team@example.com',
                        subject: "[Jenkins] 分支 ${branchName} 两次构建间隔超过 ${BUILD_INTERVAL_THRESHOLD} 天",
                        body: """
                            分支名称:${branchName}
                            上次构建时间:${currentBuild.previousBuild.time}
                            当前构建时间:${currentBuild.time}
                            间隔天数:${buildIntervalDays} 天
                            当前构建链接:${env.BUILD_URL}
                        """
                    )
                }
            }
            // 保留你原来的成功/失败通知逻辑
            success {
                emailext(/* 这里放你已有的构建成功通知配置 */)
            }
            failure {
                emailext(/* 这里放你已有的构建失败通知配置 */)
            }
        }
    }
}

几个小提醒

  • 如果是多分支流水线,env.BRANCH_NAME会自动获取当前分支,不用额外配置。
  • 要是你想更精确地获取分支创建时间(比如分支是从其他分支切出来但没立刻提交),可以试试git reflog show --date=iso ${branchName} | grep "branch: Created" | head -1,不过这个依赖Git的reflog记录,可能会被清理,所以之前的git log方式更稳妥。
  • 确保Jenkins执行节点有Git命令的权限,而且工作区能正常执行git log(比如代码已经拉取下来)。
  • 要是多个流水线都需要这个逻辑,可以把计算分支年龄和构建间隔的代码封装成Jenkins共享库函数,复用起来更方便。

内容的提问来源于stack exchange,提问作者ameya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:53:47