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

如何通过声明式流水线从Active Directory获取提交者邮箱

嘿,刚好我之前帮团队解决过几乎一模一样的需求!你已经搭好了Jenkins多分支流水线,现在要抓上次构建以来的SVN提交者邮箱发修复邮件,给你两个实用的方案,看哪个更适配你的场景:

方案1:用Jenkins内置变更集+AD插件直接关联邮箱

这个方案最省心,前提是你的SVN提交用户名和Jenkins AD认证的用户名完全一致(毕竟同事用AD凭据登录,大概率提交代码也是用同一个账号)。核心思路是从Jenkins的构建变更集里提取提交者,再通过Jenkins的用户API拉取AD同步过来的邮箱。

Jenkinsfile代码示例(声明式流水线)

pipeline {
    agent any
    stages {
        // 其他阶段:拉取代码、构建、SonarQube测试...
        
        stage('Collect Committer Emails') {
            steps {
                script {
                    // 提取上次到当前构建的所有唯一提交者
                    def uniqueCommitters = []
                    currentBuild.changeSets.each { changeSet ->
                        changeSet.items.each { commit ->
                            // 这里注意:item.author.displayName 或 item.author.id,取决于你SVN配置的用户名格式
                            def committerId = commit.author.id
                            if (!uniqueCommitters.contains(committerId)) {
                                uniqueCommitters.add(committerId)
                            }
                        }
                    }

                    // 把用户名转换成邮箱,存入环境变量方便后续使用
                    def committerEmails = []
                    uniqueCommitters.each { username ->
                        try {
                            def jenkinsUser = User.get(username)
                            def emailProperty = jenkinsUser.getProperty(EmailAddressProperty.class)
                            if (emailProperty && emailProperty.address) {
                                committerEmails.add(emailProperty.address)
                            } else {
                                echo "⚠️ 警告:用户 ${username} 未配置邮箱"
                            }
                        } catch (Exception e) {
                            echo "❌ 获取 ${username} 邮箱失败:${e.message}"
                        }
                    }

                    // 用逗号拼接邮箱列表,后续发邮件直接用
                    env.COMMITTER_EMAIL_LIST = committerEmails.join(',')
                    echo "✅ 需要通知的提交者邮箱:${env.COMMITTER_EMAIL_LIST}"
                }
            }
        }

        stage('Send Fix Notification') {
            // 可以加个条件:只有SonarQube质量门失败时才发邮件
            when {
                expression { currentBuild.result == 'FAILURE' || sonarQubeQualityGate.status == 'ERROR' }
            }
            steps {
                mail to: env.COMMITTER_EMAIL_LIST,
                     subject: "[Jenkins] 分支 ${env.BRANCH_NAME} 构建/Sonar检测异常,请修复",
                     body: """
                     您好:
                     您提交的代码在最新构建中出现问题,请访问 ${env.BUILD_URL} 查看详情并及时修复。
                     """
            }
        }
    }
}

注意事项

  • 确保流水线有Overall/Read权限:Jenkins需要允许流水线访问用户信息,否则会抛出权限异常。可以在「全局安全配置」里调整流水线的权限,或者用角色权限插件精细化配置。
  • 处理首次构建:如果是分支的第一次构建,currentBuild.previousBuild会是null,这时候changeSets会包含所有历史提交者,你可以根据需求决定是否跳过通知,或者全部通知。
方案2:SVN命令行+LDAP查询(适配用户名不一致场景)

如果你的SVN提交用户名和AD用户名不匹配(比如用了别名),或者不想依赖Jenkins用户API,可以用SVN命令行拉取变更记录,再通过LDAP查询直接获取邮箱。

Jenkinsfile代码示例

pipeline {
    agent any
    stages {
        // 其他阶段...
        
        stage('Fetch Committers via SVN & LDAP') {
            steps {
                script {
                    // 获取上次构建的SVN版本号,首次构建则取初始版本
                    def lastRevision = currentBuild.previousBuild ? 
                        currentBuild.previousBuild.changeSets[0].items[0].revision : '0'
                    def currentRevision = currentBuild.changeSets[0].items[0].revision

                    // 用SVN命令提取唯一提交者
                    def svnCommitters = sh(
                        script: "svn log -r ${lastRevision}:${currentRevision} --quiet --xml | grep '<author>' | sed 's/<author>//g;s/<\\/author>//g' | sort | uniq",
                        returnStdout: true
                    ).trim().split('\n')

                    // 调用LDAP查询邮箱(替换成你的AD服务器信息)
                    def committerEmails = []
                    svnCommitters.each { svnUsername ->
                        // 这里假设SVN用户名对应AD的sAMAccountName,根据实际字段调整
                        def email = sh(
                            script: "ldapsearch -x -H ldap://your-ad-server:389 -b 'dc=your-domain,dc=com' '(sAMAccountName=${svnUsername})' mail | grep 'mail:' | awk '{print \$2}'",
                            returnStdout: true
                        ).trim()
                        if (email) {
                            committerEmails.add(email)
                        } else {
                            echo "⚠️ 未找到 ${svnUsername} 的LDAP邮箱记录"
                        }
                    }

                    env.COMMITTER_EMAIL_LIST = committerEmails.join(',')
                }
            }
        }

        // 发邮件阶段同方案1...
    }
}

注意事项

  • Jenkins节点需要安装svn和ldapsearch命令:确保运行流水线的Agent机器上有这两个工具,并且能访问你的AD服务器。
  • LDAP权限配置:确保执行ldapsearch的用户有查询AD用户信息的权限,避免认证失败。
额外优化建议
  • 过滤重复邮箱:如果同一个用户多次提交,方案里的uniqueCommitters已经做了去重,避免重复发邮件。
  • 结合Sonar质量门:只有当Sonar检测不通过或者构建失败时才触发邮件,减少无效通知(方案1的when条件已经示例了这种逻辑)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:21:06