计时器触发作业时如何在 Jenkins 中获取 BUILD_USER?

How to get the BUILD_USER in Jenkins when job triggered by timer?

我想在 post 工作电子邮件中显示触发 Jenkins 工作的用户。这可以通过使用插件 Build User Vars Plugin 和环境变量 BUILD_USER 来实现。 但是当作业被调度程序触发时,这个变量不会被初始化。

我们怎样才能做到这一点?我知道我们有一个名为 - EnvInject Plugin 的插件,可以使用...

但我只是想知道我们如何使用它并实现解决方案...

来自 email-ext plugin 的令牌 $BUILD_CAUSE 就是您要找的东西。

当您在电子邮件内容配置中点击 ? 后的 Attach build log 组合框时,您可以看到完整的内容令牌参考.

一些标记是由插件添加的,但这个应该默认可用。

编辑:正如 bishop 在评论中指出的那样,当使用 EnvInject plugin 时,$BUILD_CAUSE 标记的行为发生了变化。

这可以使用 Jenkins Build User Vars Plugin 来完成,它公开了一组环境变量,包括启动构建的用户。 它提供环境变量,如 BUILD_USER_ID、EMAIL 等

当登录用户手动触发构建时,该用户的用户 ID 在 BUILD_USER_ID 环境变量中可用。

但是,当 Jenkins 计时器/调度程序自动触发构建时,不会替换/初始化此环境变量。

附上截图了解详情

这可以通过使用条件构建步骤插件/运行 条件插件向作业注入条件来解决,我们可以在每个作业中添加一个条件来初始化变量 BUILD_USER_ID只有当构建是由计时器或调度程序引起或触发时,通过使用正则表达式设置条件..

我正在使用 'Execute Shell' 和 'Env Inject' 插件的组合,如下所示:

  1. 创建一个 'Execute Shell' 构建步骤,使用 shell 参数替换写入默认值并将该值回显到文件中。下面的屏幕截图中突出显示的示例。
  2. 使用 'Env Inject' 文件读取该文件作为要设置的属性。

Build user vars plugin 对我不起作用,所以我做了一个快速而肮脏的 hack:

BUILD_CAUSE_JSON=$(curl --silent ${BUILD_URL}/api/json | tr "{}" "\n" | grep "Started by")
BUILD_USER_ID=$(echo $BUILD_CAUSE_JSON | tr "," "\n" | grep "userId" | awk -F\" '{print }')
BUILD_USER_NAME=$(echo $BUILD_CAUSE_JSON | tr "," "\n" | grep "userName" | awk -F\" '{print }')

安装 'Build User Vars Plugin' 并像下面这样使用:- [参见 https://plugins.jenkins.io/build-user-vars-plugin ]

请务必勾选 Build Environment 下的 Set jenkins user build variables 复选框以了解 Jenkins 作业的配置。

我想向我的 slack/flock 组之一触发构建启动器信息,因此我使用以下方式通过以声明方式编写来获取构建启动器电子邮件和名称。

我只是打印到这里,你可以用来存储在一些环境变量中,或者写在一个文件中,根据自己的方便给出文件路径..

pipeline {
environment {
    BRANCH_NAME = "${env.BRANCH_NAME}"
    }
agent any

stages{
        stage('Build-Initiator-Info'){
                sh 'echo $(git show -s --pretty=%ae)'
                sh 'echo $(git show -s --pretty=%an)'
        }
           }
}

还要详细说明 . The Conditional Build Step plugin now supports the Build Cause directly - it requires the Run Condition Plugin

如果您想通过计时器检测构建何时开始,您可以 select 运行? Build 的值CauseBuild Cause of: TimerTrigger

这比使用正则表达式更简单、更可靠。您还可以检测其他触发器,例如当构建是源代码管理提交的结果时,您可以 select: SCMTrigger.

这会获取在 Jenkins 管道作业中单击 "Build Now" 的用户名。

@NonCPS
def getBuildUser() {
    return currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId()
}

我发现类似但确实在 Jenkins 2 上工作。1.x 并且很容易理解。 无需任何插件即可运行。

if (currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause')['userId']){
    // Will be run only if someone user triggers build
    // Because in other cases this contructions returns null
}

您可以在此构造中使用 类 描述的任何 here。 它们将是 returns 个具有可用值的地图。

对于声明性管道语法,这是一个基于@Kevin 回答的快速技巧。 对于声明式管道,您需要将它们包含在一个节点中,否则您将收到错误/构建失败

node {
    def BUILD_FULL = sh (
        script: 'curl --silent '+buildURL+' | tr "{}" "\n" | grep -Po \'"shortDescription":.*?[^\\]"\' | cut -d ":" -f2',
        returnStdout: true
        )

    slackSend channel: '#ci-cd',
          color: '#000000',
          message: "The pipeline was ${BUILD_FULL}  ${GIT_COMMIT_MSG} "

}

输出将通过 git 简短描述

发送到您的 Slack 频道的 Slack 通知

下面这个对我有用。

安装"user build vars plugin"

Build Name  =   ${BUILD_NUMBER}_${TICKET}_${ENV,var="BUILD_USER_ID"}

简单的解决方案(无插件)!!

方法一:通过Shell

BUILD_TRIGGER_BY=$(curl -k --silent ${BUILD_URL}/api/xml | tr '<' '\n' | egrep '^userId>|^userName>' | sed 's/.*>//g' | sed -e '1s/$/ \//g' | tr '\n' ' ')
echo "BUILD_TRIGGER_BY: ${BUILD_TRIGGER_BY}"

方法二:通过Groovy

node('master') {
BUILD_TRIGGER_BY = sh ( script: "BUILD_BY=$(curl -k --silent ${BUILD_URL}/api/xml | tr '<' '\n' | egrep '^userId>|^userName>' | sed 's/.*>//g' | sed -e '1s/$/ \/ /g'); if [[ -z ${BUILD_BY} ]]; then BUILD_BY=$(curl -k --silent ${BUILD_URL}/api/xml | tr '<' '\n' | grep '^shortDescription>' | sed 's/.*user //g;s/.*by //g'); fi; echo ${BUILD_BY}", returnStdout: true ).trim()
echo "BUILD_TRIGGER_BY: ${BUILD_TRIGGER_BY}"
}

方法 3:通过 Groovy

BUILD_TRIGGER_BY = "${currentBuild.getBuildCauses()[0].shortDescription} / ${currentBuild.getBuildCauses()[0].userId}"
echo "BUILD_TRIGGER_BY: ${BUILD_TRIGGER_BY}"

输出:

Started by user Admin / user@example.com

注意:输出将同时是用户 ID 和用户名

无插件 ->

def cause = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause')
echo "userName: ${cause.userName}"

我已经编写了一个 groovy 脚本来提取 started by,它可以正确获取源代码,无论是用户、scm 还是计时器(可以添加更多)。它将递归地导航构建树以获取“原始”'started by' 原因 https://github.com/Me-ion/jenkins_build_trigger_cause_extractor

我创建了一个函数,return 触发的作业名称:

String getTriggeredJob(CURRENT_BUILD) {

  if (CURRENT_BUILD.upstreamBuilds.size() > 0) {

    TRIGGERED_JOB = CURRENT_BUILD.upstreamBuilds[0].projectName

    if (!TRIGGERED_JOB.isEmpty()) {
      return TRIGGERED_JOB
    }
  } 

  return "Self"
}

CURRENT_BUILD 是环境变量 currentBuild

如何 return 用户名和 UserId:

用户名:currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserName()

用户 ID:currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId()