19

I'm struggling to access GIT variables in my Jenkins pipeline

I need to know what GIT branch it's been checked out inside some bash code in a stage of the pipeline. I will use this to create different output file names. My pipeline is declarative, not scripted, and I'm using Jenkins 2.150.1

I tried everything I could find online but it's mostly incomplete code or for scripted pipelines. Or simply I can't put the information together.

Give how much time I spent on this, it would be nice to have a full working example that uses a declarative pipeline.

This is what I tried so far:

#1

Run git inside sh, but Jenkins checks out a commit, not a branch, resulting in a detached head

#2

Looking for environment variables from the shell, but there's none set related to GIT. This snippet

steps {
  sh 'echo $GIT_BRANCH'
}

always returns empty. I then tried on Groovy:

steps {
  echo "${env.GIT_BRANCH}"
}

prints null.

#3

In the "Global Variable Reference" there is a bit that says:

SCM-specific variables such as GIT_COMMIT are not automatically defined as environment variables; rather you can use the return value of the checkout step.

I searched online how to do it and I put together this code:

pipeline {
  stages {
    stage('Build') {
      steps {
        def scmVars = checkout([...])
        echo 'scm : the commit id is ' + scmVars.GIT_COMMIT
      }
    }
  }
}

But it fails with an exception

#4

use an environment command and try to obtain that value somehow

#5

looking for variables at other levels in the Jenkinsfile, but apparently I can do that only on scripted pipelines

#5

Tried to access the build url and API call, but I'm behing a proxy and this complicates things with the URL.

My Jenkinsfile

pipeline {
  stages {
    stage('Build') {
      steps {
        checkout([
          $class: 'GitSCM',
          doGenerateSubmoduleConfigurations: false,
          userRemoteConfigs: [[
            url: '...',
            credentialsId: '...'
          ]],
          branches: [ [name: '*/master'] ]
        ])

        sh '''
        #!/bin/bash -x
        echo $MY_GIT_BRANCH_THAT_I_CANT_FIND
        '''
      }
    }
  }
}
ColOfAbRiX
  • 1,080
  • 2
  • 12
  • 23

5 Answers5

23

Finally I found an example and I was able to understand how to do this.

I need to use a script command, obtain the Map returned by checkout and save the Map as environment variable:

stage('Checkout code') {
  steps {
    script {
      // Checkout the repository and save the resulting metadata
      def scmVars = checkout([
        $class: 'GitSCM',
        ...
      ])

      // Display the variable using scmVars
      echo "scmVars.GIT_COMMIT"
      echo "${scmVars.GIT_COMMIT}"

      // Displaying the variables saving it as environment variable
      env.GIT_COMMIT = scmVars.GIT_COMMIT
      echo "env.GIT_COMMIT"
      echo "${env.GIT_COMMIT}"
    }

    // Here the metadata is available as environment variable
    ...
  }
}
ColOfAbRiX
  • 1,080
  • 2
  • 12
  • 23
5

Quoting the docs:

GIT_BRANCH

For Git-based projects, this variable contains the Git branch that was checked out for the build (normally origin/master)

Specifically for the Pipeline plugin, there's an answer to this problem on StackOverflow:

The env.BRANCH_NAME variable contains the branch name.

As of Pipeline Groovy Plugin 2.18, you can also just use BRANCH_NAME (env isn't required but still accepted.)

This variable may be empty:

If your repository is hosted in a known service such as GitHUB, GitLab, BitBucket, etc… then there’s possibly a Jenkins plugin which knows how to work with each one of the services and supplies you with environment variables such as GIT_BRANCH, GIT_COMMIT, BUILD_TAG, etc… so it is usually best practice to use such a plugin.

But if your git repository is hosted on Microsoft TFS for example then there’s no such plugin (at the moment) which works well with the Pipeline type of Jenkins jobs.

In this case, you will probably use the “Pipeline: SCM Step” to clone the repository.

The following should fix this:

Add [$class: 'LocalBranch', localBranch: "**"] to “extentions” in your checkout step.

Source

fuero
  • 9,591
  • 1
  • 35
  • 40
1

Git env variables are not setup automatically when using checkout step. Instead they are returned as Map and we have to setup them ourself.

pipeline {
  options {
    skipDefaultCheckout true
  }
  stages {
    stage('Checkout source code') {
      steps {
        script {
          Map scmVars = checkout([/* Some checkout paramaters */])
          // Setting up GIT_* env variables manually
          scmVars.each { k, v ->
            env[k] = v
          }
        }
      }
    }
    stage('Print GIT env variables'){
      steps {
        sh 'env | grep GIT_'
      }
    }
  }
}
0

The Jenkins declarative pipeline job in a multibranch pipeline honors the git configuration of the multibranch pipeline that defined the job. Add the "Check out to matching local branch" trait to the multibranch pipeline definition if you prefer to have each job checkout a local branch with a name that matches the remote branch. Each job created in that multibranch pipeline will then checkout to a named local branch.

If you're using a declarative pipeline job that is not part of a multibranch pipeline, then you can use the git plugin's local branch extension to define the name of the local branch that should be created.

Mark Waite
  • 136
  • 3
0

I found this works well. Define an environment variable that can be used in subsequent stages.

  environment {
    GIT_COMMIT_REV=''
  }
  stages {
    stage('Configure') {
      steps {
        script {    
          GIT_COMMIT_REV = sh(returnStdout: true, script: "git log -n 1 --pretty=format:'%h'").trim()
        }
      }
    }
  }

Taken from Jenkins Pipeline Examples

Ben Courliss
  • 101
  • 2