如何通过声明式流水线从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
相关产品推荐
相关产品推荐

