Get username logged in Jenkins from Jenkins Workflow (Pipeline) Plugin
Asked Answered
S

12

34

I am using the Pipeline plugin in Jenkins by Clouldbees (the name was Workflow plugin before), I am trying to get the user name in the Groovy script but I am not able to achieve it.

stage 'checkout svn'

node('master') {
      // Get the user name logged in Jenkins
}
Stockinet answered 9/3, 2016 at 21:9 Comment(2)
By user name logged in Jenkins, do you mean the user logged into the front-end? I.E. the one that manually (or automatically) triggers the job? Or the one actually running the job in the execution environment? Since you only distinguish this in the gray-on-gray-part of the question, the question would benefit from distinguishing this more clearly.Lugubrious
@RickMoritz you already pointed out what I meant, anyways I updated the question.Retool
C
60

Did you try installing the Build User Vars plugin? If so, you should be able to run

node {
  wrap([$class: 'BuildUser']) {
    def user = env.BUILD_USER_ID
  }
}

or similar.

Coen answered 9/3, 2016 at 21:21 Comment(6)
Thanks :) works great I didn't know about that plugin, checking the release notes I found that was the last update, support with workflow plugin ! greatRetool
I'm trying this with a pipeline job. The wiki describes there should be a Set jenkins user build variables checkmark, but that seems only to be available in Freestyle projects. Is there anything else I'm missing?Tatary
The checkbox is only for Freestyle jobs. But for Pipeline jobs, here's how to find out what's available. Scroll to wrap: General Build Wrapper in either the Snippet Generator checkbox, or your-jenkins.example.com/workflow-cps-snippetizer/dslReference page.Thresher
This is a dead link. Do you have another one for a sample?Chetnik
Please note that this plugin is listed as: user build vars pluginTatary
you are freaking awesomeCosmonautics
H
21

To make it work with Jenkins Pipeline:

Install user build vars plugin

Then run the following:

pipeline {
  agent any

  stages {
    stage('build user') {
      steps {
        wrap([$class: 'BuildUser']) {
          sh 'echo "${BUILD_USER}"'
        }
      }
    }
  }
}
Hecatomb answered 6/2, 2018 at 18:2 Comment(3)
Worked for me too but for my pipeline I didn't need steps { } wrapping the command and I changed the command to use script: I'll post my success in a separate responsePerfection
Isn't necessary to add it inside a script block?Bellini
This is old. I dont thik this needs to be done anymore.Matthias
D
21

Here's a slightly shorter version that doesn't require the use of environment variables:

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

The use of rawBuild requires that it be in a @NonCPS block.

Desman answered 1/3, 2018 at 9:30 Comment(2)
Just FYSA: This solution or similar solutions won't work if a user clicks on "Scan Multibranch Pipeline Now" side bar link for Multi-Branch scan based initiated build. It only works if a user manually clicks on "Build" or "Build with Parameters"Durrell
#67305108 has a better example for finding/setting a user if you want to set build description using BUILD_USER, when "Scan MultiBranch Pipeline Now" side-bar link in a MultiBranch Pipeline jobDurrell
I
12

It is possible to do this without a plugin (assuming JOB_BASE_NAME and BUILD_ID are in the environment):

def job = Jenkins.getInstance().getItemByFullName(env.JOB_BASE_NAME, Job.class)
def build = job.getBuildByNumber(env.BUILD_ID as int)
def userId = build.getCause(Cause.UserIdCause).getUserId()

There is also a getUserName, which returns the full name of the user.

Inspector answered 26/7, 2017 at 19:41 Comment(6)
Caveat: A job containing this script can only be run by an admin on Jenkins 2 due to security reasons. You can approve the script in Script Approval menu, though.Floccus
I'm getting this error when I try this: org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstanceCompetent
JOB_BASE_NAME and BUILD_ID are available in my environment. I already approved all the script permission, but im getting this error when using the codes above... java.lang.NullPointerException: Cannot invoke method getBuildByNumber() on null objectAnking
@Anking - you are probably having a "null" value for "job". add a "?" after the "job" symbol name in the second line. (and maybe as well on the third line after "build".)Davao
#67305108 answerDurrell
java.lang.NullPointerException: Cannot invoke method getBuildByNumber() on null objectOrjonikidze
R
8

This works for me without the Build User plugin:

// get first entry of JSONArray
def buildCause = currentBuild.getBuildCauses()[0]
def buildPrincipal = [type:"unknown", name:""]

if (buildCause._class ==~ /.+BranchEventCause/) {
  def branchCause = currentBuild.getRawBuild().getCause(jenkins.branch.BranchEventCause)
  buildPrincipal = [type:"branch",name:buildCause.shortDescription]

} else
if (buildCause._class ==~ /.+TimerTriggerCause/) {
  def timerCause = currentBuild.getRawBuild().getCause(hudson.triggers.TimerTrigger.TimerTriggerCause)
  buildPrincipal = [type:"timer", name:"Timer event"]

} else
if (buildCause._class ==~ /.+UserIdCause/) {
  def buildUserCause = currentBuild.getRawBuild().getCause(hudson.model.Cause.UserIdCause)
  buildPrincipal = [type:"user", name:buildCause.userId]

} else
// ... other causes
Roslyn answered 14/12, 2019 at 23:43 Comment(1)
I like this one, because if you are trying to pick a user to notify, when it's a UserIdCause, you use that, but if it's a branch, use the GIT_COMMITTER. Who to notify for failures to a timer-driven failure is likely nobody, or devops...Rumor
D
6
def jobUserId, jobUserName
//then somewhere
wrap([$class: 'BuildUser']) {
    jobUserId = "${BUILD_USER_ID}"
    jobUserName = "${BUILD_USER}"
}
//then
println("Started By: ${jobUserName}")

We were using this plugin : Build User Vars Plugin. More variables are available.

Discalced answered 7/8, 2018 at 11:19 Comment(3)
would you please give me more details how to implement it? I am new to Jenkins, thanks a lot in advance.Clark
can you tell me what exactly are you trying to implement?? I have stopped using jenkins since almost 1.5 years. Thats why.Discalced
thanks a lot for your reply, I already implemented it. at first, I do not know how to use def jobUsername, because I want to use it in the shared library, then I use the function get the user and return the username. thanks again.Clark
K
2
//Below is a generic groovy function to get the XML metadata for a Jenkins build.
//curl the env.BUILD_URL/api/xml parse it with grep and return the string
//I did an or true on curl, but possibly there is a better way
//echo -e "some_string \c" will always return some_string without \n char     
//use the readFile() and return the string
def GetUserId(){
 sh """
 /usr/bin/curl -k -s -u \
 \$USERNAME:\$PASSWORD -o \
 /tmp/api.xml \
 \$BUILD_URL/api/xml || true 

 THE_USERID=`cat /tmp/api.xml | grep -oP '(?<=<userId>).*?(?=</userId>)'`
 echo -e "\$THE_USERID \\c" > /tmp/user_id.txt                               
 """
def some_userid = readFile("/tmp/user_id.txt")
some_userid
}
Koah answered 31/8, 2017 at 9:34 Comment(0)
P
1

I modified @shawn derik response to get it to work in my pipeline:

    stage("preserve build user") {
            wrap([$class: 'BuildUser']) {
                GET_BUILD_USER = sh ( script: 'echo "${BUILD_USER}"', returnStdout: true).trim()
            }
        }

Then I can reference that variable later on by passing it or in the same scope as ${GET_BUILD_USER} . I installed the same plugin referenced.

Perfection answered 12/3, 2018 at 18:33 Comment(2)
no such answer from shawn derik anymore. maybe user name has changed. solution is only expected to work with "Build User Vars" plugin present.Davao
Thanks - yes, the plugin would be required.Perfection
L
1

Edit: I re-read the question - the below only gets you the user running the build (which technically is often more interesting), not the one triggering the build in the frontend (be it REST-API or WebUI). If you have Jenkins impersonation enabled, then I believe the result should be equivalent, otherwise this will only get you the user who owns the jenkins agent on the build machine.

Original answer:

Another way would be to

sh 'export jenkins_user=$(whoami)'

Downside: Linux-dependent, difficult to port across multiple agents in a single build (but then, the auth context may be different on each slave)

Upside: No need to install plugins (which on shared/large Jenkins instances can be tricky)

Lugubrious answered 5/4, 2019 at 16:15 Comment(0)
C
1

The following code is inspired by Juergen's solution but I added more possible trigger reason and display them in a formatted manner:

String getTriggerReason() {
  def buildCause = currentBuild.getBuildCauses()[0]
  if (buildCause._class ==~ /.+(BranchEventCause|BranchIndexingCause)/) {
    if (env.JOB_BASE_NAME == 'master') {
      return 'Triggered by master commit'
    } else {
      return "Triggered by ${buildCause.shortDescription}"
    }
  }
  if (buildCause._class ==~ /.+TimerTriggerCause/) {
    return 'Triggered by timer'
  }
  if (buildCause._class ==~ /.+BuildUpstreamCause/) {
    return "Triggered by build #${buildCause.upstreamBuild}"
  }
  if (buildCause._class ==~ /.+UserIdCause/) {
    def userName = buildCause.userName.replaceFirst(/\s?\(.*/, '')
    return "Triggered by user ${userName}"
  }
  return 'Unknown trigger'
}
Conscience answered 20/4, 2022 at 14:18 Comment(1)
When offers a similar range of options: jenkins.io/doc/book/pipeline/syntax/#whenRiggins
I
0

The Build User Vars Plugin is useful when you are executing the stage on an agent.

The alternative is to use the current build clause (see https://code-maven.com/jenkins-get-current-user), which also works when your stage is set with agent none.

Irk answered 22/10, 2020 at 20:28 Comment(0)
M
0

Here is an example of a generic function that returns build user for the build from which it is called, or for the build that triggered the current build:

def getBuildUser() {
    currentBuild.rawBuild.getCause(Cause.UserIdCause)?.getUserId() ?: currentBuild.rawBuild.getCause(Cause.UpstreamCause).getUpstreamCauses().get(0).getUserId()
}
Manes answered 18/7, 2023 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.