Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

git.branch in maven under jenkins pipelines is wrong evaluated to the commit #325

Open
tkleiber opened this issue Sep 22, 2017 · 19 comments

Comments

@tkleiber
Copy link

I have maven pom.xml, where I use git.branch and git.commit.id.abbrev to create database schema for my tests.

pom xml

This works fine, when I call maven in my development environment.

mvn local correct

But when maven is called from a jenkins pipeline on the same branch, then git.branch is replaced with the full commit id.

mvn jenkins wrong

This seems to be related to the detached mode of jenkins pipeline working copies of the workspace:

git branch output

@TheSnoozer
Copy link
Collaborator

Hi, thanks for reporting your problem here!

Can you provide me some more details about the following so I could potentially reproduce the issue:

  • What Jenkins version are you using?
  • What Maven version are you using?
  • What Java version are you using?
  • Based on the screenshots you are using the git-commit-id-plugin 2.2.3 - please let me know if this would be incorrect!
  • Can you post your configuration of the plugin? (e.g. are you using the native git or JGIT implementation)
  • Can you run the plugin with <verbose>true</verbose> and post the log-file?
  • How have you setup your pipeline jobs? (is this happening in a single build, or in some downstream job that got triggered by a chained pipeline-build?)

Anything on the setup side would potentially help to trace this down and get it fixed

@TheSnoozer TheSnoozer added the bug label Sep 22, 2017
@tkleiber
Copy link
Author

tkleiber commented Sep 22, 2017

mvn jenkins wrong verbose

@TheSnoozer
Copy link
Collaborator

After a first quick investigation what might be the problem...it seems that this is caused by using pipelines...
This plugin is using the environment variables that are being exposed by the jenkins-git-plugin.
However when following the pipeline examples for a maven build those environment variables are getting lost since the git clone is in a different pipeline. For me it currently seems that the Artifactory Plugin is responsible for building the pipelines (see detailed documentation).

The root cause why the commit-id is being displayed for branch is related how jenkins/hudson are cloning and using git. Usally jenkins performs a shallow clone of the repo and then checking out a specific commit (HEAD). With normal git-features AFAIK from that point we don't know on which branch we are without performing ugly git-magic (TODO investigate me). Usually the trick to get this plugin working on Jenkins/Hudson is using the exposed environment variables. When this plugin doesn't find any environment variables for the branch it will defaults to the commit-id.

The general question that seems to be the problem here:
Should environment variables from pipleline A be exposed to pipeline B?
However this isn't a question for this plugin...I'll investigate where I can report bugs/feature requests for the pipeline-plugins it seems https://www.jfrog.com/jira/projects/HAP/issues is a right place...

My pipeline-script being used for testing:

node {
    // Get Artifactory server instance, defined in the Artifactory Plugin administration page.
    def server = Artifactory.server "SERVER_ID"
    // Create an Artifactory Maven instance.
    def rtMaven = Artifactory.newMavenBuild()
    def buildInfo

    stage('Clone sources') {
        git url: 'https://github.com/jfrogdev/project-examples.git'
    }

    stage('Artifactory configuration') {
        // Tool name from Jenkins configuration
        rtMaven.tool = "maven3.3.9"
        // Set Artifactory repositories for dependencies resolution and artifacts deployment.
        // rtMaven.deployer releaseRepo:'libs-release-local', snapshotRepo:'libs-snapshot-local', server: server
        // rtMaven.resolver releaseRepo:'libs-release', snapshotRepo:'libs-snapshot', server: server
    }

    stage('Maven build') {
        buildInfo = rtMaven.run pom: 'maven-example/pom.xml', goals: 'clean install'
    }
    
    stage('Build printenv') {
        sh 'printenv'
    }
}

@TheSnoozer
Copy link
Collaborator

TheSnoozer commented Sep 22, 2017

Issue related with:
https://issues.jenkins-ci.org/browse/JENKINS-30252
https://issues.jenkins-ci.org/browse/JENKINS-26100
https://stackoverflow.com/questions/32789619/jenkins-multibranch-pipeline-what-is-the-branch-name-variable/37085196#37085196
https://stackoverflow.com/questions/43770058/jenkins-pipeline-branch-name-returns-null
https://stackoverflow.com/questions/36304208/jenkins-workflow-checkout-accessing-branch-name-and-git-commit/36332154#36332154
https://stackoverflow.com/questions/39589360/how-to-access-git-branch-name-from-pipeline-job

https://www.tikalk.com/devops/evaluate-git-branch-jenkins-pipeline-gitscm/
https://stackoverflow.com/questions/35873902/accessing-scm-git-variables-on-a-jenkins-pipeline-job

This requires some more investigation since it seems that there is a difference between running in a single pipeline VS multibranch pipeline...

Edit:
Note the what jenkins (for a job that is called Pipeline) has to say about the BRANCH-environment variable:
http://localhost:8080/job/Pipeline/pipeline-syntax/globals#env
For a multibranch project, this will be set to the name of the branch being built, for example in case you wish to deploy to production from master but not from feature branches; if corresponding to some kind of change request, the name is generally arbitrary (refer to CHANGE_ID and CHANGE_TARGET).

https://jenkins.io/doc/pipeline/steps/workflow-scm-step/#checkout-general-scm#code-checkout-code-general-scm

@TheSnoozer
Copy link
Collaborator

TheSnoozer commented Sep 23, 2017

Just as an update to summarize:

  • I got it to working with a single pipeline only with a parametrized build configuration (not ideal but works)
pipeline {
    agent any
    parameters {
        string(defaultValue: 'master', description: 'branch', name: 'branch')
    }
    environment { 
        GIT_BRANCH = "${params.branch}"
    }
    
    stages {
        stage('Clone sources') {
            steps {
                checkout([$class: 'GitSCM',
                 branches: [[name: "${params.branch}"]],
                 userRemoteConfigs: [[url: 'https://github.com/ktoso/maven-git-commit-id-plugin', 
                                      credentialsId: 'xxx']]
                 ])

                // not working - why?
                // git branch: '${params.branch}', url: 'https://github.com/ktoso/maven-git-commit-id-plugin.git'
            }
        }
        
        stage('Maven build'){
            steps {
                sh 'mvn clean install -B'
                sh 'mvn clean initialize -Pdemo -B'
                sh 'bash -c \'[[ -f target/testing.properties ]] && cat target/testing.properties || terminate 1;\''
            }
        }
        
        stage('Build printenv'){
            steps {
                sh 'printenv'
            }
        }
    }
}
  • Not sure if there are any other workarounds for single pipeline builds, but based on the documents I found on stackoverflow and in the jenkins documentation the $GIT_BRANCH is only being exposed when using a Multibranch-Pipeline. As outlined above when the plugin is not finding the branch it defaults back to the commit.

I'll do some more investigation with the Multibranch-Pipeline if the branch is being determined correctly....

@TheSnoozer
Copy link
Collaborator

Alright; I'll stop investigating this further.....
There are 10928321 tickets on Jenkins that ask for this to be implemented somehow but regardless what I found it doesn't seem to work without the dirty parametrized build hack...

Tested the following without any success (besides defining the extra parameter):

  • full definition of checkout
checkout([$class: 'GitSCM', branches: [[name: "*/${params.branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/ktoso/maven-git-commit-id-plugin.git']]])
  • full definition of checkout, but without branches definition
checkout([$class: 'GitSCM', doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/ktoso/maven-git-commit-id-plugin.git']]])
  • short checkout with branch specifier
git branch: 'master', url: 'https://github.com/ktoso/maven-git-commit-id-plugin.git'
  • short checkout without branch specifier
git url: 'https://github.com/ktoso/maven-git-commit-id-plugin.git'

I won't test this for a multi-branch projects since I'll open a ticket with jenkis. The plugin is behaving correctly, but jenkins fails to give the plugin the required information :-(

Just as a side node, I noticed that whatever is being defined as param is also getting exposed as environment-variable and thus there is no need to specify an additional environment block inside the groovy script; simply use GIT_BRANCH instead of branch aka.:

pipeline {
    agent any
    parameters {
        string(defaultValue: 'master', description: 'branch', name: 'GIT_BRANCH')
    }
    
    stages {
        stage('Clone sources') {
            steps {
                git branch: "${params.GIT_BRANCH}", url: 'https://github.com/ktoso/maven-git-commit-id-plugin.git'
            }
        }
        
        stage('Build printenv'){
            steps {
                sh 'printenv'
            }
        }
    }
}

Just note, that this does not work for the first build, unless you specify manually that the build is parametrized and use the same parameters as in the groovy script - feel free to open issues with jenkins on this one.

PS:
Not sure if this return values thingy https://stackoverflow.com/a/45845221/7890667 aka. https://issues.jenkins-ci.org/browse/JENKINS-26100 hasn't reached the LTS version yet

@TheSnoozer
Copy link
Collaborator

@tkleiber
Copy link
Author

I have used now following workaround in my pom.xml for maven

<properties>
  <branch>${git.branch}</branch>
</properties>

From jenkins pipeline I call now following step

steps {
  sh 'mvn clean verify -Dbranch=$BRANCH_NAME'
}

In my development environment I call mvn without -DBranch, as there maven-git-commit-id-plugin works fine.

@TheSnoozer
Copy link
Collaborator

Thanks for the feedback and glad you found another workaround!
I'll keep the issue open just to increase the awareness that something doesn't work properly....plus unfortunately there is nothing within the plugin to get this fixed.

@s17t
Copy link

s17t commented Feb 24, 2019

This is still an issue. It can be fixed with workaround in #325 (comment)

@kokorin
Copy link

kokorin commented Dec 9, 2020

I have used now following workaround in my pom.xml for maven

<properties>
  <branch>${git.branch}</branch>
</properties>

From jenkins pipeline I call now following step

steps {
  sh 'mvn clean verify -Dbranch=$BRANCH_NAME'
}

In my development environment I call mvn without -DBranch, as there maven-git-commit-id-plugin works fine.

It's possible to overwrite branch in a more simple way: -Dgit.branch=CUSTOM

@jaydenlin
Copy link

got the same issue ...

@f2963155
Copy link

I also have the same issue. Is there a solution?

@venky2291
Copy link

If you get solution for this issue. Kindly share it here.

@TheSnoozer
Copy link
Collaborator

Workarounds are available:
#325 (comment)
#325 (comment)

Ask jenkins to implement this correctly.

@venky2291
Copy link

venky2291 commented May 26, 2024

@TheSnoozer Sure, Thanks for your response. One quick question, which environment variable will be used to capture the value of git.branch in git.properties during the Maven build process on Jenkins?

@TheSnoozer
Copy link
Collaborator

See: https://github.com/git-commit-id/git-commit-id-plugin-core/blob/master/src/main/java/pl/project13/core/cibuild/HudsonJenkinsBuildServerData.java#L52

First this plugin ties GIT_LOCAL_BRANCH after that GIT_BRANCH.
Which is btw what is documented under https://plugins.jenkins.io/git/#plugin-content-environment-variables

@venky2291
Copy link

@TheSnoozer , Thanks for the quick response. I would like to know if there is any difference between git-commit-id-maven-plugin and git-commit-id-plugin-core. I noticed that both repositories are part of the git-commit-id project.

@TheSnoozer
Copy link
Collaborator

git-commit-id-plugin-core == Shared library code for all git-commit-id-*plugin(s)
git-commit-id-maven-plugin == uses git-commit-id-plugin-core to provide functionality to the maven world
git-commit-id-gradle-plugin == uses git-commit-id-plugin-core to (eventually) provide functionality to the gradle world

So if you search any logic implementation it is likely encoded in git-commit-id-plugin-core, while when you search maven related logic it is solely encoded in the git-commit-id-maven-plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants