Need to pass git sha to checkout to Jenkins multi branch pipeline - jenkins-pipeline

Is it possible to use parameters to allow users to pass a git sha to a multi branch pipeline while defaulting to the head of the branch? Also I would only need to this function for the master branch.
I'm using ...
Jenkinsfile in code
Jenkins Declarative Pipeline

I was able to do this with declarative pipelines with the following...
pipeline {
options {
skipDefaultCheckout()
}
...
steps {
script {
if (GIT_REVISION=='HEAD') {
checkout scm
} else {
checkout([$class: 'GitSCM',
branches: [[name: "${params.GIT_REVISION}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [],
submoduleCfg: [],
userRemoteConfigs: [[credentialsId: 'XXXXXXX', url: 'git#github.com:xxxxx/xxxxx.git']]
])
}
...
}
}
}

Yes, this is possible, but I guess you have to use scripted pipelines instead of declarative ones.
If the current branch is the master, you configure a parameter for this build (as this isn't super intuitive, I wrote a blog article a while ago). params.INPUT_REVISION for example would then store the given revision and you can set default to HEAD or fallback to it, if the parameter is not yet specified (e.g. for the first run).
You supply this revision to the checkout(scm) step as a parameter so that it doesn't checkout the current master branch, but the specified revision.

Related

GitHub checkout with environmental variable in Jenkinsfile

In Jenkins, I have a multibranch pipeline job using a Jenkinsfile. I have disabled the default SCM checkout via:
options {skipDefaultCheckout(true)}
so that I can control the checkout for each stage and use the SSH URL from GitHub. I have a working stage that checks out the "main" branch using:
checkout([
$class: 'GitSCM',
branches: [[name: '*/main']],
extensions: [[$class: 'LocalBranch', localBranch: 'main']],
userRemoteConfigs: [[credentialsId: 'XXX', url: 'git#github.com:XXX.git']]
])
For another stage, I would like to checkout and build/test the branch that is triggered (in this case a feature branch called "feature-0001"). I have tried this (note the change for the branches and extensions lines):
checkout([
$class: 'GitSCM',
branches: [[name: env.BRANCH_NAME]],
extensions: [[$class: 'LocalBranch']],
userRemoteConfigs: [[credentialsId: XXX, url: 'git#github.com:XXX.git']]
])
but I get the following error:
Error when executing failure post condition:
java.io.IOException: Cannot retrieve Git metadata for the build
In addition, the build log also has:
git rev-parse "origin/feature-0001^{commit}" # timeout=10
git rev-parse "feature-0001^{commit}" # timeout=10
I'm not sure where the "^{commit}" comes from or if it's causing any issues.
Any guidance would be appreciated, thank you!
P.S. I have also tried many variations of BRANCH_NAME including
$env.BRANCH_NAME, ${env.BRANCH_NAME}, $BRANCH_NAME, ${BRANCH_NAME}
branches: [[name: "refs/heads/${env.BRANCH_NAME}"]] worked.
I was also using the incorrect url/credentials causing further issues.
If you want an unambiguous way to reference your branch name in the SCM checkout step, try (as explained here):
branches: [[name: 'refs/heads/${env.BRANCH_NAME}']]
The ^{commit} revision specification would therefore apply to the ref refs/heads/${env.BRANCH_NAME}
<rev>^{<type>}, e.g. v0.99.8^{commit}
A suffix ^ followed by an object type name enclosed in brace pair means dereference the object at <rev> recursively until an object of type <type> is found or the object cannot be dereferenced anymore (in which case, barf).
For example, if <rev> is a commit-ish, <rev>^{commit} describes the corresponding commit object.

Jenkins Pipeline script from SCM shares Perforce workspace with Sync inside of script (different stream/depot)

I am looking for help with with our Jenkins Pipeline setup. I had a Jenkins pipeline job working just fine, where the groovy script was checked out from a Perforce stream (in stage "Declarative: Checkout SCM") and then run. The script itself performs, at its core, a p4 sync and a p4 reconcile.
pipeline {
agent {
node {
customWorkspace "workspaces/MY_WORKSPACE"
}
}
stages {
stage('Sync') {
steps {
script {
p4sync(
charset: 'none',
credential: '1',
format: "jenkins-${NODE_NAME}-MY_WORKSPACE",
populate: syncOnly(force: false, have: true, modtime: false, parallel: [enable: false, minbytes: '1024', minfiles: '1', threads: '4'], pin: '', quiet: true, revert: true),
source: streamSource('//depot/STREAM')
)
}
}
}
stage('Reconcile') {
steps {
script {
withCredentials([usernamePassword(credentialsId: '1', passwordVariable: 'SVC_USER_PW', usernameVariable: 'SVC_USER_NAME')]) {
bat label: 'P4 reconcile', true, script:
"""
p4 -c "%P4_CLIENT%" -p "%P4_PORT%" -u ${SVC_USER_NAME} -P ${SVC_USER_PW} -s reconcile -e -a -d -f "//depot/STREAM/some/folder/location/*.file"
"""
}
}
}
}
}
}
Due to an exterior requirement, we decided to move all our pipeline script files to a separate depot on the same Perforce server and changed the pipeline script checkout accordingly.
Now, the pipeline script checkout step ("Declarative: Checkout SCM") will create a new workspace called jenkins-NODE_NAME-buildsystems (for the pipeline script depot //buildsystems) which will use the same local workspace root directory D:\some\path\workspaces\MY_WORKSPACE on the build node as the actual workspace jenkins-NODE_NAME-MY_WORKSPACE, created and synced in the first pipeline step by p4sync. This means that Perforce creates two workspaces with the same local workspace root directory (which can cause all sorts of problems in itself). In addition, in the pipeline script, the P4 environment variable P4_CLIENT points to the wrong workspace jenkins-NODE_NAME-buildsystems (so the reconcile won't work), which should only have been used by the pipeline script checkout, not by the pipeline itself.
Which brings me to my question. How can I separate the workspaces of the pipeline script checkout and of the p4sync in the pipeline script? In the pipeline I can specify a customWorkspace, but not in the Jenkins configuration for the pipeline script checkout, and the latter weirdly seems to follow that customWorkspace statement, maybe because jenkins-NODE_NAME-MY_WORKSPACE had already been opened by Perforce on the node...?
Any hints are much appreciated.
Thanks,
Stefan

Does polling work with lightweight checkout?

I'm using "checkout build script from scm" option, paired with lightweight checkout.
I would like to add repository polling to that.
This is Jenkinsfile that I use:
pipeline {
agent any
triggers {
pollSCM('H/1 * * * *')
}
stages {
stage('Checkout') {
steps {
checkout([
$class : 'GitSCM',
branches : [[name: 'master']],
userRemoteConfigs : [[url: 'file:///home/my-secret-home/workspace/pipeline-test']]])
}
}
stage('Echo!') {
steps {
sh 'echo TEST'
}
}
}
}
Although job is running, git polling log tries to convince me that 'Polling has not run yet.'
Is configuring such behavior possible at all?
No, it doesn't work.
With lightweight checkout, the mapping to the remote branches are lost, so git doesn't know where to look for further updates.
You can also confirm this by running git pull on the local repository. It returns:
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=origin/<branch> master

How do I achieve git Additional Behaviors => Checkout to specific local branch in Jenkins pipeline?

How do we achieve Git Additional Behavior in Jenkins pipeline?
Additional Behaviors
=> checkout to specific local branch
check this one http://your-Jenkins:8080/pipeline-syntax/ , you can have samples of all your installed plugins.
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'your-sub-directory']], gitTool: 'Default', submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'd767bb7a-4c1e-4654-a310-996d4ece5b02', url: 'git#github.com:yyy/xxx.git']]])
you can find the pipeline syntax in your Jenkins job slide bar Pipeline Syntax section.
1、Sample Step select checkout: Check out from version control
2、click Additional Behaviours Add button
3、select checkout to specific local branch
4、click bottom Generate Pipeline Script button,you will get pipeline script.

How to access the BRANCH_NAME variable within a Jenkins pipeline running on Windows?

I wrote a Jenkins pipeline which git clones a repository, builds feature branches code and if everything is finished successfully it should merge the branch to master.
here's the relevant code:
stage ('Merge to master') {
if(currentBuild.result == 'SUCCESS') {
bat """
cd %workspace%
echo "BRANCH_NAME: %BRANCH_NAME%"
echo "Env.BRANCH_NAME: %env.BRANCH_NAME%
git checkout master
REM git merge %GIT_BRANCH%
"""
}
}
The code which is responsible for the cloning:
stage ('Checkout SCM') { // This stage is responsible to clone the repository into Jenkins's workspace
checkout([$class: 'GitSCM', branches: [[name: '*/feature/*']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '99f978af-XXXX-XXXX-8147-2cf8f69ef864', url: 'http://TFS_SERVER:8080/tfs/DefaultCollection/PC_International/_git/repo-name']]])
}
My problem is that it seems like the BRANCH_NAME variable is not set, I've tried accessing it by %BRANCH_NAME% , %env.BRANCH_NAME%, %GIT_BRANCH% and %env.GIT_BRANCH% but to no avail.
In Jenkins build log, it looks like that:
C:\Program Files (x86)\Jenkins\workspace\Ensure>echo "BRANCH_NAME: "
"BRANCH_NAME: "
C:\Program Files (x86)\Jenkins\workspace\Ensure>echo "Env.BRANCH_NAME:
"Env.BRANCH_NAME:
C:\Program Files (x86)\Jenkins\workspace\Ensure>echo "GIT_BRANCH: "
"GIT_BRANCH: "
C:\Program Files (x86)\Jenkins\workspace\Ensure>echo "Env.GIT_BRANCH: env.GIT_BRANCH"
"Env.GIT_BRANCH: env.GIT_BRANCH"
Any idea what I'm doing wrong?
You need to interpolate the string value using the Groovy placeholders ${}, i.e. ${env.BRANCH_NAME}
This will replace the variable with the string literal before the batch script is executed. The %% notation is for interpolating windows environment variables, but env.BRANCH_NAME is Jenkins environment variable not a windows environment variable.
This worked for me:
"manage jenkins" -> "Configure System" ... scroll down to "Global Properties" and check the checkbox for "Environmental Variables".
Add your variable (i.e. Name: MY_BRANCH, value: "*/master")
Restart Jenkins
Go to your build then you can use the variable in your build configs as ${MY_BRANCH}

Resources