Can I augment scm in Jenkinsfile? - jenkins

It's taken me ages to understand what checkout scm really means in Jenkinsfile (checkout is a function and scm is a default global variable by the way).
Now that I've understood it, I want to augment scm for example to increase the timeout for a particular checkout or to set sparseCheckoutPaths. Is this possible? If so, how?

For Git, checkout scm is basically equivalent to :
checkout([
$class: 'GitSCM',
branches: scm.branches,
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
extensions: scm.extensions,
userRemoteConfigs: scm.userRemoteConfigs
])
If you want to add sparse checkout to the existing scm, what you would do is something like:
checkout([
$class: 'GitSCM',
branches: scm.branches,
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
extensions: scm.extensions + [$class: 'SparseCheckoutPaths', sparseCheckoutPaths:[[$class:'SparseCheckoutPath', path:'path/to/file.xml']]],
userRemoteConfigs: scm.userRemoteConfigs
])
Even better, you can define a custom step, sparseCheckout in a shared library.
def call(scm, files) {
if (scm.class.simpleName == 'GitSCM') {
def filesAsPaths = files.collect {
[path: it]
}
return checkout([$class : 'GitSCM',
branches : scm.branches,
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
extensions : scm.extensions +
[[$class: 'SparseCheckoutPaths', sparseCheckoutPaths: filesAsPaths]],
submoduleCfg : scm.submoduleCfg,
userRemoteConfigs : scm.userRemoteConfigs
])
} else {
// fallback to checkout everything by default
return checkout(scm)
}
}
Then you call it with:
sparseCheckout(scm, ['path/to/file.xml'])

You can definitely customize the checkout scm command to add more flexibility. Check out this link for all of the options - https://jenkins.io/doc/pipeline/steps/workflow-scm-step/
Timeouts:
$class: CheckoutOption timeout::::
Specify a timeout (in minutes) for checkout.
This option overrides the default timeout of 10 minutes.
You can change the global git timeout via the property org.jenkinsci.plugins.gitclient.Git.timeOut (see JENKINS-11286). Note that property should be set on both master and slave to have effect (see JENKINS-22547).
Type: int
SparseCheckoutPaths:
$class: SparseCheckoutPaths
Specify the paths that you'd like to sparse checkout. This may be used for saving space (Think about a reference repository). Be sure to use a recent version of Git, at least above 1.7.10

Related

how to override default Jenkins Git plugin checkout with pipeline code?

I have jenkins multibranch pipeline with jenkins git plugin.
When the new pull requested is created a new PR job starts, and checkout of the repository is done automatically. The problem is sometimes it hits timeout (networking).
I try to do retry in pipeline by using GitSCM code with some conditionals:
checkout([
$class: 'GitSCM',
branches: scm.branches,
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
extensions: scm.extensions + [[$class: 'CloneOption', noTags: false, reference: '', shallow: false]],
submoduleCfg: [],
userRemoteConfigs: scm.userRemoteConfigs
])
}
It repeats the checkout just fine, but I still need to disable the first default checkout from the plugin(if it fails the job fails). How do I do that? How do I override the built-in checkout?
skipDefaultCheckout option should disable default checkout. E.g.:
options { skipDefaultCheckout() }
Read more here about it: https://www.jenkins.io/doc/book/pipeline/syntax/#available-options

Jenkins: Can we checkout the submodules with user defined branch

I have a peculiar requirement, I need to change the branch name of the submodule which is mentioned in the .gitmodule file.
ex:
consider below is my .gitmodule file.
[submodule "submodule"]
path = aiml/core/model/modelcollection
url = ssh://git#git.myorg.com/project/repo.git
branch = module1
I am using Jenkins checkout function as below.
checkout([
$class: 'GitSCM',
branches: [[name: 'develop']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: true,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: false]
],
submoduleCfg: [],
userRemoteConfigs: [[url: "git#git.myorg.com/project/repo.git"]]
])
My case: I need to change the branch name which is already mentioned in .gitmodule (i.e module1) to a different branch name example "module2". Is this possible while using the Jenkins checkout function?
Is there any other way to fulfil the above requirement?
Note: Just a curious add on the question. Can we add two entries in .gitmodule and clone only one based on the need. Is this possible with Jenkins checkout.

Jenkins Pipeline checkout branch which can parameterised

I am trying to write a stage in Jenkinsfile where I'll pass the branch name from the Jenkins job to checkout the code at a specific location.
stage("Prepare") {
steps {
checkout([$class: 'GitSCM',
branches: [[name: '*/master' ]],
extensions: scm.extensions,
userRemoteConfigs: [[
url: 'https://gitlab.example.com/user/example_repo.git',
credentialsId: 'my-gitlab-repo-creds'
]]
])
}
}
Also, how can we define the location where to checkout the project.
You're missing the power of the SCM checkout step. In turn, your pipeline is missing some important configuration to get what you want:
pass the branch name from the Jenkins job to checkout the code
define the location where to checkout the project
This can all be done. I'll explain the options used to accomplish this.
1) Pass the branch name to checkout step
You can achieve this with the BRANCH_NAME environment variable.
2) Define project checkout location
Add the following extension and get rid of the scm.extensions value.
extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'myrepo']]
Specify a local directory (relative to the workspace root) where the Git repository will be checked out. If left empty, the workspace root itself will be used.
For the branches option,
The safest way is to use the refs/heads/ syntax. This way the expected branch is unambiguous.
For example:
branches: [[name: 'refs/heads/${env.BRANCH_NAME}']]
Piecing it all together,
checkout(
[
$class: 'GitSCM',
extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'example_repo']],
branches: [[name: 'refs/heads/${env.BRANCH_NAME}']],
userRemoteConfigs: [
[
url: 'https://gitlab.example.com/user/example_repo.git',
credentialsId: 'my-gitlab-repo-creds',
name: 'origin'
]
]
]
)
The above code will checkout the ${env.BRANCH_NAME} branch of https://gitlab.example.com/user/example_repo.git to the $WORKSPACE_DIR/example_repo folder.

how to execute jenkins pipeline from config file

I have a generic multibranch project that I use on about 100 different git repos. The jenkins jobs are automatically generated and the only difference is the git repo.
Since they all build in the same way and I don't want to copy the same jenkins groovy file in all repos, I use "Build configuration -> mode -> by default jenkinsfile".
It breaks the rule to put the jenkinsfile in SCM as I would prefer to do. To minimize the impact, I would like that groovy file to only checkout the "real" jenkinsfile and execute it.
I use that script:
pipeline {
agent {label 'docker'}
stages {
stage('jenkinsfile checkout') {
steps {
checkout([$class: 'GitSCM',
branches: [[name: 'master']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'RelativeTargetDirectory',
relativeTargetDir: 'gipc_synthesis']],
submoduleCfg: [],
userRemoteConfigs: [[url: 'ssh://git#camtl1bitmirror.gad.local:7999/mtlstash/mvt/gipc_synthesis.git']]]
)
}
}
stage('Load user Jenkinsfile') {
//agent any
steps {
load 'gipc_synthesis/jenkins/synthesis_job.groovy'
}
}
}
}
The problem I have with that is I can't have another pipeline in the groovy file I am loading. I don't want to define only functions but really the whole pipeline in that file. Any solution to that problem? I am also interested in solution that would completely avoid the whole issue.
Thank you.
You can have a shared library with your pipeline inside:
// my-shared.git: vars/build.groovy
def call(String pathToGit) // and maybe additional params
{
pipeline {
agent { ... }
stages {
stage('jenkinsfile checkout') {
steps {
checkout([$class: 'GitSCM',
branches: [[name: 'master']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'RelativeTargetDirectory',
relativeTargetDir: 'gipc_synthesis']],
submoduleCfg: [],
userRemoteConfigs: [[url: pathToGit]]]
)
}
}
}
}
}
and use it in your Jenkinsfile e.g. like this:
#!groovy
#Library('my-shared') _
def pathToGit = 'ssh://git#camtl1bitmirror.gad.local:7999/mtlstash/mvt/gipc_synthesis.git'
build(pathToGit)

Checkout repository based on Tag in the Jenkins Workflow plugin

With the Jenkins Workflow Plugin, I can checkout a repository based on branch. However, I would like to checkout a repository based on a tag.
This is my current configuration for checking out the master branch
node {
git url: src, branch: 'master'
}
Now I would like to achieve to check out tag 3.6.1. I tried to change the branch to a tag, but that won't work. Neither is there something in the documentation regarding checking out on tag.
Is this currently possible? Am I overseeing something?
references;
https://github.com/jenkinsci/workflow-plugin
https://github.com/jenkinsci/workflow-plugin/blob/master/scm-step/README.md
https://github.com/jenkinsci/workflow-plugin/blob/master/scm-step/src/main/resources/org/jenkinsci/plugins/workflow/steps/scm/GitStep/config.jelly
https://github.com/jenkinsci/workflow-plugin/blob/master/scm-step/src/main/java/org/jenkinsci/plugins/workflow/steps/scm/GitStep.java
Just found the answer myself by crawling through the issue list. Seems like they won't change it; https://issues.jenkins-ci.org/browse/JENKINS-27018
This is the suggested solution;
checkout scm: [$class: 'GitSCM', userRemoteConfigs: [[url: src]], branches: [[name: 'refs/tags/3.6.1']]], poll: false
This works:
checkout scm: [$class: 'GitSCM', userRemoteConfigs: [[url: repoURL,
credentialsId: credential]], branches: [[name: tag-version]]],poll: false
Not This:
checkout scm: [$class: 'GitSCM', userRemoteConfigs: [[url: repoURL],
[credentialsId: credential]], branches: [[name: tag-version]]],poll: false
noTags: false does the trick.
checkout([$class: 'GitSCM', branches: [[name: githash ]],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'CloneOption',
depth: 0,
noTags: false,

Resources