-
Bug
-
Resolution: Duplicate
-
Minor
-
Powered by SuggestiMate
Here is my pipeline code:
node { checkout changelog: true, poll: true, scm: [ $class: 'GitSCM', branches: [[name: "${env.gitlabSourceRepoName}/${env.gitlabSourceBranch}"]], doGenerateSubmoduleConfigurations: false, extensions: [ [$class: 'PruneStaleBranch'], [ $class: 'PreBuildMerge', options: [ fastForwardMode: 'FF', mergeRemote: 'origin', mergeStrategy: 'default', mergeTarget: "${env.gitlabTargetBranch}" ] ], [$class: 'CleanCheckout'] ], userRemoteConfigs: [ [name: 'origin', url: 'git@gitlab.mydomain.com:user/project.git', credentialsId: '8949144f-cca9-4385-8597-ad3c14bbd7ce'], [name: "${env.gitlabSourceRepoName}", url: "${env.gitlabSourceRepoURL}", credentialsId: '8949144f-cca9-4385-8597-ad3c14bbd7ce'] ], browser: [$class: 'GitLab', repoUrl: 'http://gitlab.mydomain.com', version: '8.8'] ] echo """ |GIT_COMMIT: ${GIT_COMMIT} |GIT_BRANCH: ${GIT_BRANCH } """.stripMargin('|') }
But finally it gives me this error:
groovy.lang.MissingPropertyException: No such property: GIT_BRANCH for class: WorkflowScript
Is the environment variables still working for pipeline?
- duplicates
-
JENKINS-26100 SCM steps should return revision state
-
- Resolved
-
- is duplicated by
-
JENKINS-36436 Environment variables are always NULL
-
- Closed
-
- links to
[JENKINS-35230] The environment variables of git plugin not working in pipeline script.
Thank you. I've tried your solutions, but all of them still not working.
I can use the "GIT_*" variables in the free style jobs. such as :
branch to be published: ${GIT_BRANCH}
rev: ${GIT_COMMIT}
commit user: ${GIT_AUTHOR_NAME}<${GIT_AUTHOR_EMAIL}>
changelog:
${CHANGES, showPaths=true}
But all the variables above cannot be used in pipeline script.
There is an article on stackoverflow.com which seems to indicate this is a known limitation of either pipeline or the git plugin. Sorry, but I'm not sure which is expected to provide that.
This is affecting me as well. Does the git plugin need to be subtly adjusted to export these critical pieces of data in a new way to be accessible to serial pipeline steps?
In a custom plugin triggered after the Git step, the following are the only EnvVars available:
BUILD_DISPLAY_NAME=#9 BUILD_ID=9 BUILD_NUMBER=9 BUILD_TAG=jenkins-pipetest-9 BUILD_TIMESTAMP=2016-07-22 11:30:39 CDT BUILD_URL=http://blah:8080/job/pipetest/9/ CLASSPATH= HUDSON_HOME=/var/jenkins_home HUDSON_SERVER_COOKIE=blah HUDSON_URL=http://blah:8080/ JENKINS_HOME=/var/jenkins_home JENKINS_SERVER_COOKIE=blah JENKINS_URL=http://blah:8080/ JOB_BASE_NAME=pipetest JOB_NAME=pipetest JOB_URL=http://blah:8080/job/pipetest/
Since BUILD_TIMESTAMP is available, that implies the https://wiki.jenkins-ci.org/display/JENKINS/Build+Timestamp+Plugin plugin is able to inject env vars into the pipeline just fine, so it is possible.
rboyer nice find that the build timestamp plugin has the necessary technique in it. Are you able to review the source code of the build timestamper plugin and submit a comparable pull request for the git plugin?
Its not possible to blend them without multiple inheritance.
The timestamp plugin works via an EnvironmentContributor which is distinct from SCM: https://github.com/jenkinsci/build-timestamp-plugin/blob/master/src/main/java/com/orctom/jenkins/plugin/buildtimestamp/BuildTimestampEnvironmentContributor.java
I'm a Jenkins plugin newbie, so this is pushing the limits of what I can reason about effectively. Especially with this new pipeline layer on top.
Looks like this may be related to https://issues.jenkins-ci.org/browse/JENKINS-36436
What needs to happen to make these available in pipeline? I would hope to not have to run a sh every time I want to get the commit that triggered this pipeline.
Someone needs to research the way to publish environment variables to a pipeline, then propose a pull request (with tests) to the git plugin. Richard Boyer suggested that the timestamp plugin knows how to provide environment variables to a pipeline, so I suggested that someone might consider that as a path to an eventual pull request.
Were there any updates on this? How can I determine, for example, the branch Jenkins built?
Sorry, no progress yet. It will arrive in the git plugin eventually, since I want access to those environment variables as part of my testing of the git plugin (and git client plugin).
paralin: You can use env.BRANCH_NAME (Multi branch projects) or use this:
def branchName if(isUnix()){ branchName = sh(returnStdout: true, script: 'git rev-parse --abbrev-ref HEAD').trim() } else { branchName = bat(returnStdout: true, script: 'git rev-parse --abbrev-ref HEAD').trim() }
clausfod git rev-parse --abbrev-ref HEAD always returns HEAD for me instead of master... I guess this happens, because Jenkins always builds with a detached HEAD as described here: JENKINS-6856
pleibiger Thanks! That's sufficient as a workaround until the issue is fixed
Any news to know when is this gonna be solve ? currently it is blocking me to get the variable of `GIT_PREVIOUS_SUCCESSFUL_COMMIT`, or any of workaround can be achieve it, Thanks!
I'm in a similar situation as jubel but could get by with GIT_PREVIOUS_COMMIT or a workaround.
thomas_ramirez: Try this (maybe you need to enable "checkout to local branch")
String gitCommit = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
clausfod: Thanks but I thought that returned the equivalent of GIT_COMMIT. My goal is to identify if certain files were updated since the last build. I know how to get the list of files between two commit points but I'm missing the starting commit point.
thomas_ramirez: Can't you use the api ? For example use <joburl>/api/json?depth=1 find lastBuild and go further with this url -> <lastBuild>/api/json there you find your data, if not use lastBuild until you find a build with commits..
jubel: Can't you use the api ? For example use <joburl>/api/json?depth=1 find lastSuccessfulBuild and go further with this url -> <lastSuccessfulBuild>/api/json there you find your data
clausfod: I hadn't found that approach yet so thanks for pointing me in that direction. I'm a recent transplant from the world of .NET and TFS so everything is new.
No one is currently working on fixing this in the git plugin. I'm currently evaluating the Git LFS support pull requests. Once that is complete, I'll likely work on fixing submodule bugs and then will consider which pull requests I should evaluate after that. I doubt I will spend time coding this implementation for many months.
Hi abcfy2 markewaite tknerr and others !
Was your build already triggered by SCM event ? or all builds were only "manual triggered" ?
I not using pipeline plugin, but freestyle project
so I configured new project, already ran few build manually, and see actually no env variables line GIT_*, like described there:
https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin
so, I guess, after first "SCM triggered" build, this EnvVariables - GIT_* should become available in EnvVariable
my suggestion are:
1) to configure job on "SCM event"
2) add shell step with "echo $GIT_COMMIT"
3) check output
4) push to repo (should trigger job)
5) check output
6) let us know
Regards!
oreststetsiak, it is usually preferred that a bug report be limited to a single topic. In the case of this bug, it is specific to environment variables in a pipeline. If there is an issue with environment variables in freestyle jobs, that is a very different topic. If you're able to duplicate the issue, please submit a different bug report.
I'm not aware of cases where GIT_COMMIT is not set for the environment of a freestyle project. Refer to the environment variables description for more information on environment variables and the contexts where they are available.
Chiming in here.. This being broken has presented us with some major challenges, as we have a multi-repository setup where we'll have sibling PR's with matching branch names in our other repositories. The lack of env.GIT_BRANCH in pipelines has presented major difficulties in checking out those sibling PR's.
I was making an attempt at fixing this today by trying to follow along with the implementation at https://github.com/jenkinsci/branch-api-plugin/blob/master/src/main/java/jenkins/branch/BranchNameContributor.java - my knowledge gaps of the Jenkins source code make it difficult to figure out how to actually implement this. So, any help from other core plugin authors or maintainers would be highly appreciated.
- EnvironmentContributor seems like the right class to extend from here
- EnvironmentContributor.buildEnvironmentFor is available for both Job and Run
- BranchNameContributor gets the BranchProjectFactory of the parent job and uses it to check if this
- BranchNameContributor uses types like ContributorMetadataAction and other actions to get metadata
- How do I obtain the Git metadata associated with a Job or Run (it seems like it should be associated with a certain Run?
- Will reflection be needed to get the workflow execution and revision info from the Run?
Unfortunately, I don't have any great ideas to offer, though I suspect that jglick has a reference implementation in the mercurial plugin. You might look at buildEnvVarsFromActionable.
Jesse has tried to keep the mercurial plugin as a really good SCM reference implementation. I suspect that its implementation of exporting environment variables to pipeline jobs is also a good reference implementation.
Little bit more research into this:
- Run is an Actionable, so doing something like final BuildData buildData = run.getAction(BuildData.class); works to obtain that Action data.
- GitSCM has a method buildEnvVars that seems to compute most of the environment variables. Maybe this can be abstracted out to be usable from both points?
So, a very basic implementation that I got working locally with the Bitbucket Branch Source Plugin could look like:
package jenkins.plugins.git; import static hudson.Util.fixEmpty; import com.google.common.collect.Iterables; import hudson.EnvVars; import hudson.Extension; import hudson.model.EnvironmentContributor; import hudson.model.Run; import hudson.model.TaskListener; import hudson.plugins.git.Branch; import hudson.plugins.git.GitSCM; import hudson.plugins.git.Revision; import hudson.plugins.git.util.BuildData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import javax.annotation.Nonnull; @Extension public class GitContributor extends EnvironmentContributor { private static final Logger LOG = LoggerFactory.getLogger(GitContributor.class); @Override public void buildEnvironmentFor(@Nonnull final Run run, @Nonnull final EnvVars envs, @Nonnull final TaskListener listener) throws IOException, InterruptedException { final BuildData buildData = run.getAction(BuildData.class); // This is all essentially copy pasted from GtiSCM if (buildData != null) { final Revision rev = buildData.getLastBuiltRevision(); if (rev!=null) { Branch branch = Iterables.getFirst(rev.getBranches(), null); if (branch!=null && branch.getName()!=null) { String remoteBranchName = branch.getName(); if(remoteBranchName.startsWith("refs/remotes/")) { //Restore expected previous behaviour remoteBranchName = remoteBranchName.substring("refs/remotes/".length()); } envs.put(GitSCM.GIT_BRANCH, remoteBranchName); } String sha1 = fixEmpty(rev.getSha1String()); if (sha1 != null && !sha1.isEmpty()) { envs.put(GitSCM.GIT_COMMIT, sha1); } } } } }
jglick there looks to be a lot of potentially useful information in this ticket. The linked ticket that this was closed out and marked as a duplicate of has not been updated since November 2016, and was created in December 2014. Further, it doesn't appear to highlight the current issue with environment variables in Jenkins pipelines returning null.
Can you please elucidate on these actions?
JENKINS-26100 has always tracked this well-known limitation. Parsing git rev-parse HEAD is the typical workaround for Git.
jglick yes, but that only returns the commit. In my use case, we need the GIT_BRANCH name to checkout sibling branches in other repositories.
I don't think we can checkout to a local branch because that option is not available when the source is set to Github.
we need the GIT_BRANCH name to checkout sibling branches in other repositories
Use BRANCH_NAME.
i've tried this and it returns the PR number in github eg. PR-2424, not the actual branch name.
Sorry, while github-branch-source does record the source branch name for forked pull requests, this is not defined in scm-api and so not exposed as an environment variable by branch-api.
I don't think this issue should be marked as resolved - surely the env vars that the git plugin is documented to be setting should be being set. If they aren't, then that's a bug. I can still reproduce this on jenkins 2.67, git plugin 3.3.1
Assuming workflow-scm-step is up to date, you also need to use the return value from the checkout step. No environment variables are set.
Then there's a bug in the documentation?
Not having these env vars makes working with pipeline much harder for us since I have to manually work them out (which is difficult to do inside a sandboxed pipeline script).
jglick is the lack of env var exposing a bug, technical limitation or on purpose (as-designed)?
I am asking this because exposing important information using environment variable is the most user-friendly way. That's because environment variables can also be accessed by called bash scripts.
a bug in the documentation?
A bug in which documentation? URLs please.
is the lack of env var exposing a bug, technical limitation or on purpose (as-designed)?
As designed. checkout is a non-block-scoped step. Environment variables are only set by block-scoped steps. If you wish to pass things to external processes, use withEnv.
A bug in which documentation? URLs please
https://wiki.jenkins.io/display/JENKINS/Git+Plugin#GitPlugin-Environmentvariables
Well, that was written a long time ago of course, for freestyle projects. I have PRs in flight affecting the live documentation inside the product, which is generally more accurate than wikis.
Is this Resolved?
If there's a work around to get the environment variables for Git? Please point me to that.
For now, I'm getting the env list for Free-Style projects from the below,
<snip>
EnvVars env = run.getEnvironment(taskListener);
</snip>
hariharan yes, it is resolved. The values are returned by the pipeline checkout command as a map.
Refer to a sample Jenkinsfile that uses the returned map to perform some tests on the values of those variables.
Thanks Mark,
As suggested, I can able to get the Git details with Pipeline SCM plugin 2.6,
<snip>
map_vars = checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'admin', url: 'http://test.git.url']])|http://test.git.url%27]]]%29/]
print map_vars
</snip>
Is there a way to send/inject these details into Jenkins AbstractBuild/Run or TaskListener object? Actually I need to use these details in my plugin.
hariharan, I don't know the technique you would use to obtain those values in your plugin by calling the git plugin. Possibly @jglick could offer a suggestion?
The values will not be accessible from another plugin, by design. Your plugin may accept standard data-bound parameters, and a user’s script may pass variables from checkout (in original or modified form) to your plugin, or not.
This is not at all obvious if you just glance over: https://wiki.jenkins.io/display/JENKINS/Git+Plugin
You'd never expect that to access those ENV variables you have to capture the output of checkout.
Or am I mistaken?
shmup, the wiki is not the preferred location for Pipeline documentation. Refer to the Pipeline: SCM Step page for an example using the environment variables as a map returned from the `checkout` step. There is a Jenkins Minute video that describes it as well. You can also read about it (briefly) in the Pipeline: SCM Step plugin page.
If you'd like to add it to the Git plugin Wiki, you're welcome to do that as well.
abcfy2 I think this might be an unintended side effect of the changes in SECURITY-170, but I'm not absolutely sure of that. I don't have time right now to duplicate your pipeline job setup.
Please try the same setup in a Jenkins server that was started with the property
It may also be that there is some mistake in your referencing GIT_BRANCH without calling it env.GIT_BRANCH.