17

I need to pass the username of the requester of a build down to the script that is actually doing the work. Looking at the console output for a particular build, the first line is always "Started by user foo," so Jenkins is clearly keeping track of who triggered the build. So it should be possible to pass that information down to the job. The question is, how?

Amit Joshi
  • 15,448
  • 21
  • 77
  • 141
Sniggerfardimungus
  • 11,583
  • 10
  • 52
  • 97

6 Answers6

16

user30997

Please check out Jenkins Build User Vars plugin, it does what you need:

It is used to set following user build variables:

  • BUILD_USER – full name of user started build,
  • BUILD_USER_FIRST_NAME – first name of user started build,
  • BUILD_USER_LAST_NAME – last name of user started build,
  • BUILD_USER_ID – id of user started build.
Milkywayfarer
  • 910
  • 1
  • 9
  • 25
14

The username isn't put in an easy-to-fetch environment variable, but you can get it using the xml (or json or python) api - as soon as you start a build, http://[jenkins-server]/job/[job-name]/[build-number]/api/xml is populated with details:

<freeStyleBuild>
    <action>
        <cause>
            <shortDescription>Started by user foobar</shortDescription>
            <userName>foobar</userName>
        </cause>
    </action>
    <building>true</building>
    [...]
Anders Lindahl
  • 41,582
  • 9
  • 89
  • 93
4

I tried to use Jenkins Build User Vars plugin and notify a HipChat room that a build was started by a certain user, but BUILD_USER variable was not available to HipChat plugin, possibly because HipChat action happened before Build User Vars plugin injects the variable.

So I installed pre-scm-buildstep plugin and added:

enter image description here]

// Inject environment variables using Groovy

import hudson.model.*

def build = Thread.currentThread().executable
def userCause = build.getCause(hudson.model.Cause$UserIdCause)
def userName = userCause?.userId ?: 'Jenkins'

def envVars = ['BUILD_USER': userName]

for (item in envVars) {
  build.addAction(new ParametersAction([
    new StringParameterValue(item.key, item.value)
  ]))
}
warvariuc
  • 57,116
  • 41
  • 173
  • 227
  • THANK YOU. Jenkins makes this WAY harder than it should be. I don't see "Execute system Groovy script" as one of the options for "Rub buildstep before SCM runs." Any idea how to either get that or do the same thing without Groovy? – Chuck Batson Jan 20 '16 at 19:48
  • 1
    Never mind, found the Groovy plugin here: https://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin – Chuck Batson Jan 20 '16 at 19:56
3

In your Job add "Execute system Groovy script":

def yourUserName = build.causes[0].userId
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
3

I managed to get it (on Jenkins 2.58):

currentBuild.getRawBuild().getCauses()[0].getUserId()

Of course you need to set permissions in Jenkins to be able to call these methods. It's not always the 0th Cause object you are looking for, e.g. it may be another one if you replay another user's build (did not test this).

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
Attila123
  • 932
  • 8
  • 8
1
import os
import jenkinsapi.build
import jenkinsapi.jenkins

#Required Environment variables example:
#JENKINS_URL=http://jenkinsserver/
#JOB_NAME=TEST_GT
#BUILD_NUMBER=8

jenkins_inst = None

def get_jenkins_inst():
    if jenkins_inst == None:
        jenkins_url = os.environ['JENKINS_URL']
        print("Connect to jenkins " + jenkins_url)
        jenkins_inst = jenkinsapi.jenkins.Jenkins(jenkins_url)
    return jenkins_inst

def get_jenkins_job():
    jenkins_inst = get_jenkins_inst()

    jenkins_job_name = os.environ['JOB_NAME']
    print("Get jenkins job " + jenkins_job_name)
    return jenkins_inst.get_job(jenkins_job_name)

def get_jenkins_user():
    jenkins_job = get_jenkins_job()

    jenkins_buildno = int(os.environ['BUILD_NUMBER'])
    print("Get jenkins job build " + str(jenkins_buildno))
    cur_build = jenkins_job.get_build(jenkins_buildno)

    return cur_build.get_actions()['causes'][0]['userId']