git-commit-id / git-commit-id-maven-plugin

Maven plugin which includes build-time git repository information into an POJO / *.properties). Make your apps tell you which version exactly they were built from! Priceless in large distributed deployments... :-)
http://www.kto.so
GNU Lesser General Public License v3.0
1.61k stars 300 forks source link

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

Open tkleiber opened 6 years ago

tkleiber commented 6 years ago

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 commented 6 years ago

Hi, thanks for reporting your problem here!

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

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

tkleiber commented 6 years ago

mvn jenkins wrong verbose

TheSnoozer commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

Just as an update to summarize:

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

TheSnoozer commented 6 years ago

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):

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 commented 6 years ago

See: https://issues.jenkins-ci.org/browse/JENKINS-47226

tkleiber commented 6 years ago

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 commented 6 years ago

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 commented 5 years ago

This is still an issue. It can be fixed with workaround in https://github.com/git-commit-id/maven-git-commit-id-plugin/issues/325#issuecomment-331601044

kokorin commented 3 years ago

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 commented 2 years ago

got the same issue ...

f2963155 commented 8 months ago

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

venky2291 commented 3 months ago

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

TheSnoozer commented 3 months ago

Workarounds are available: https://github.com/git-commit-id/git-commit-id-maven-plugin/issues/325#issuecomment-331601044 https://github.com/git-commit-id/git-commit-id-maven-plugin/issues/325#issuecomment-466770708

Ask jenkins to implement this correctly.

venky2291 commented 2 months ago

@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 commented 2 months ago

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 commented 2 months ago

@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 commented 2 months ago

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.