26

I cannot seem to extract $GIT_COMMIT and $BRANCH_NAME from a Jenkins Workflow Checkout step.

I would like to be able to send this information through to my Gradle scripts in order to pass it onto external sources such as Static analysis etc.

Currently I try to run this:

checkout([$class: 'GitSCM', branches: [[name: '*/master']], userRemoteConfigs: [[credentialsId: '2b74a351-67d5-4d00-abd3-49842a984201', url: 'ssh://git@corporate.com:repo.git']]])

And I would like to achieve the following or something similar:

// Specified variables that can be reused
def branch = ${BRANCH_NAME}
def commit = ${GIT_COMMIT}

Or maybe this would work too:

print "BRANCH: ${BRANCH_NAME}, COMMIT: ${GIT_COMMIT}"
// or the following
print "BRANCH: ${env.BRANCH_NAME}, COMMIT: ${env.GIT_COMMIT}"

I did find the following issue which seems to be resolved but it doesn't work in version 1.15:

https://issues.jenkins-ci.org/browse/JENKINS-30252

Anyone have any ideas how to workaround this or if there's a variable I cannot find?

Nick Sonneveld
  • 3,356
  • 6
  • 39
  • 48
Oldek
  • 2,679
  • 5
  • 23
  • 25

3 Answers3

43

First of all,

def branch = ${BRANCH_NAME}

is not valid Groovy, or at least not doing what you think. Perhaps you meant

def branch = "${BRANCH_NAME}"

which would just be a silly way of writing

def branch = BRANCH_NAME

Anyway environment variables are not currently accessible directly as Groovy variables in Pipeline (there is a proposal to allow it); you need to use the env global variable:

def branch = env.BRANCH_NAME

From within an external process, such as a sh step, it is an actual environment variable, so

sh 'echo $BRANCH_NAME'

works (note that ' means Groovy is not interpolating the variable).

Now, JENKINS-30252 was referring to multibranch projects. If you created a standalone Pipeline job, this variable will not be set.

Anyway in your case your checkout step is always checking out the master branch. If you actually have a multibranch project, then your Jenkinsfile should be using

checkout scm

which will check out a commit on the correct branch (always matching the revision of Jenkinsfile itself).

As to the commit hash, pending JENKINS-26100 this is not available automatically, but you can use something like

sh 'git rev-parse HEAD > commit'
def commit = readFile('commit').trim()

to access it.

Jesse Glick
  • 24,539
  • 10
  • 90
  • 112
  • Alright, so this helps me understand the problem better. There's a few things I don't know about Groovy as mentioned above but this helps me understand the differences of quotes as well. Interesting, I will try this out! – Oldek Apr 01 '16 at 09:43
  • 2
    As to the last paragraph, see the [currently proposed syntax](https://github.com/abayer/workflow-scm-step-plugin/blob/39a28c8611c2c06e14d9e60b4a06366c57bfec18/src/main/resources/org/jenkinsci/plugins/workflow/steps/scm/GenericSCMStep/help.html). – Jesse Glick May 04 '17 at 12:25
  • "environment variables are not currently accessible directly as Groovy variables" Do you have any supporting references for this from Jenkins source? – Judy007 Jun 28 '17 at 18:36
  • @JoeyStallmeyer He also states "you need to use the env global variable". So, the environment variable `BRANCH_NAME` can be accessed with this: `env.BRANCH_NAME` (as stated in the answer). – alexbt Jul 11 '17 at 21:04
23

I have two Jenkins instances.

In both instances, GIT_COMMIT and BRANCH_NAME environment variables are not defined.

When I try to get them from the return value of checkout() call, each instance behaves differently.

Jenkins Instance 1

Jenkins version: 2.46.1

"Pipeline: SCM Step" plugin version: 2.5

Trying to access the environment variable as explained in the checkout documentation fails.

def scmVars = checkout([$class: 'GitSCM', branches: [[name: '*/master']], 
    userRemoteConfigs: [[credentialsId: '2b74a351-67d5-4d00-abd3-
    49842a984201', url: 'ssh://git@corporate.com:repo.git']]])
def commitHash = scmVars.GIT_COMMIT

scmVars returns NULL, and accessing scmVars.GIT_BRANCH fails with exception java.lang.NullPointerException: Cannot get property 'GIT_BRANCH' on null object.

So I had to do the following in order to get the branch:

sh 'git name-rev --name-only HEAD > GIT_BRANCH'
sh 'cat GIT_BRANCH'
git_branch = readFile('GIT_BRANCH').trim()
env.GIT_BRANCH = git_branch

Jenkins Instance 2

Jenkins version: 2.60.2

"Pipeline: SCM Step" plugin version: 2.6

In this instance, I could do the following with success:

def scmVars = checkout([$class: 'GitSCM', branches: [[name: '*/master']], 
    userRemoteConfigs: [[credentialsId: '2b74a351-67d5-4d00-abd3-
    49842a984201', url: 'ssh://git@corporate.com:repo.git']]])
env.GIT_COMMIT = scmVars.GIT_COMMIT
env.GIT_BRANCH = scmVars.GIT_BRANCH

So please check which approach works for your Jenkins instance and use it.

HelloWorld101
  • 3,878
  • 2
  • 34
  • 47
  • Thank you so much for your detailed explanation on failure regarding versions. I can confirm that for Jenkins Instance 2 with "Pipeline: SCM Step" plugin version: 2.5 also fails on your second explanation. On version 2.73.3 of Jenkins, so it's definitely an error on the plugin on versions below 2.6, updating it solved this – Ilhicas Feb 28 '18 at 16:26
  • @Antony Thanks a lot for this answer you have almost saved my job!!. The second approach worked for me!. :-) – Hussain K Aug 04 '20 at 04:10
1

If you want to access the BRANCH_NAME from Jenkins environment variable as a shell script, use the below snippet.

sh 'echo Branch Name: $BRANCH_NAME'

The response should be as below:

Branch Name: the_checkedout_branch

Adeel
  • 2,901
  • 7
  • 24
  • 34