I want to checkout the 2nd Repo in my Jenkins multibranch pipeline - jenkins

In my Jenkinsfile, the "checkout scm" command will checkout whatever repo I have configured in the configuration panel.
But what if I add a 2nd repo to the Jenkins file - is there any way to check that out to a sepcific directory within the workspace? The catch is that I don't want to hard-code any URLs into my Jenkinsfile. Here's an illustration of what I'm trying to achive:
stage("Checkout") {
checkout scm // Works fine, checks out the 1st consifured repo to workspace.
dir("src") {
checkout scm // Checks out the exact same repo again, but how can I change this to colone the 2nd repo instead?
}
}
Basically - what could I put instead of the 2nd "checkout scm" that would make it pull the 2nd repo configured in the Multibranch pipeline web config?
And supposing this isn't actually possible - what's even the point of allowing users to provide more than one repo in the config-form if there's no way of checking it out in the script?

Use the url found at yourjenkinshostname.com/pipeline-syntax/ to generate a step for "checkout: General SCM". After that, fill out the info for the repo you want, and click "Additional Behaviors" and add one for "Checkout to Subdirectory".
Lastly click "Generate Pipeline Script". The output from that should be useable in your Jenkinsfile. Completed, the process looks like this:
Syntax Generator Example
Alternatively, if you're used to the checkout step, the "RelativeTargetDirectory" extension class can be used to do this. A checkout step with that included looks like this:
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'test-dir']], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/jenkinsci/puppet-jenkins.git']]])
The key part being...
extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'test-dir']]
EDIT: According to issues.jenkins-ci.org/browse/JENKINS-32018, the multiple sources of a multibranch job is not for two different repositories, but rather for multiple sources of a single repository.
You'll need to hardcode in URLs, I'm afraid. On approach is to have two multibranch jobs. One has the SCM as repo A and hardcodes a checkout of repo B, the other has repo B as the SCM, and hardcodes a checkout of repo A.

Related

Jenkins save author of commit and listen for pushes

Hi I want to ask if there is possible to jenkins pipeline run every time when there is push into some repository in git. and save the author of commit into variable. My code:
stage('checkout') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxxxxxxxxxxxxx-yyyyyyyy-zzzzzzzzzz', url: 'git#website:group/project.git']]])
}
}
To your 1st question: "is possible to Jenkins pipeline run every time when there is push into some repository in git"
answer: Yes there are various way.
To make use of Webhooks. Many SCM provider like Github , BitBucket has this option
you can make use of Jenkins git plugins to do that. (refer my screen shot)
For your 2nd question: "Save the author of commit into a variable. "
answer: It seems to duplicate question with this

Jenkins: Run migrations only when migrations folder has changed

I have a pipeline script, and would like to take different actions depending on the changes of the migrations folder.
Basically would be a workflow like this
Pull changes in the repository
Check if the migrations/ folder has new migrations or changes
If changes are present, run migrations, if not, continue
I'm not sure how could I achieve this, I'm using version 2.1 and the git plugin. This repo is on a private server
There's probably a way to do it directly with the plugin, but I only get the option for included regions if I add another branch source as "Single repository & branch", so for now I implemented this solution:
I added this to my Jenkinsfile, to check for changes on the migrations/ folder
script {
env.CONTAINS_MIGRATIONS = sh (
script: 'git diff --name-only --diff-filter=AMDR --cached HEAD^',
returnStdout: true
).trim()
if (env.CONTAINS_MIGRATIONS.contains('migrations')) {
// Do migrations related stuff
}
}
I'm doing this considering that is unlikely to have filename conflicts, and if they happen is not a big deal
In your case, 'included region' feature from Git plugin should help. See this answer for details.
So, for pipeline, you can generate the correct syntax using pipeline-syntax generator (under http://<JENKINS_IP>:<JENKINS_PORT>/job/<PATH_TO_PIPELINE_JOB>/pipeline-syntax/ job in Sample Step: checkout -> SCM: Git -> Additional Behaviours -> Polling ignores commits in certain paths). It will be something like this:
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'PathRestriction', excludedRegions: '', includedRegions: 'migrations/.*']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'test', url: 'http://test.com/test.git']]])
Check this documentation for details (extensions -> includedRegions).
For job dsl syntax it will be like this:
scm {
git {
remote {
...
}
extensions {
cleanBeforeCheckout()
disableRemotePoll() // this is important for path restrictions to work
configure { git ->
git / 'extensions' / 'hudson.plugins.git.extensions.impl.PathRestriction' {
includedRegions "somepath/.*"
excludedRegions "README.md\n\\.gitignore\npom.xml"
}
}
}
}
}
Also, you can use GitHub/GitLab/BitBucket webhooks to build a project when a change is pushed to repository.
See this example for Github and BitBucket configuration and this example for GitLab configuration.
If you want to build the project only for changes in migrations folder and not for any changes in repository, you can configure comment regex for triggering a build and add this specific comment (e.g., "[changes in migrations folder]") to the commit every time you want to trigger a build.

Branch of Jenkinsfile

I'm using regular (not multibranch) pipeline job which getting Jenkinsfile from repository. And I would like to checkout the same branch in my script. Currently I could use job name as branch name:
checkout(scm: [$class: 'GitSCM', branches: [[name: env.JOB_BASE_NAME]], ...)
But it is not always convenient and it is still 2 places which should be changed - job name and branch name which is error prone. I only found open issue and suggestions to use multibranch pipeline which is overkill in my case.
Is there a way to access branch name used to checkout Jenkinsfile?
If I am getting this right , all you need to do is get the job a parameter and pass that parameter in the checkout step :
checkout changelog: false, poll: false, scm: [$class: 'GitSCM', branches: [[name: "${env.PARAM}"
Here PARAM is the name of the parameter you added in the build configuration.

In Jenkins, how can I set the "Branches to build" configuration option of the Pipeline plugin identical to the value of ${BRANCH_NAME}

As you can see in the attached screenshot, I want my pipeline to fetch the Jenkinsfile from the same branch that is passed in as a parameter and saved in the BRANCH_NAME variable:
I had to uncheck "Lightweight checkout" to make Jenkins parse the ${BRANCH_NAME} parameter under the Pipeline SCM settings:
See below:
checkout([$class: 'GitSCM', branches: [[name: "${BRANCH_NAME}"]], [[credentialsId: 'CRED_ID', url: 'https://url.goes.here']]])
To be more explicit, you could use ${params.BRANCH_NAME}

Clean builds with Multibranch Workflow

Using Multibranch Workflow, the command to check out looks like
checkout scm
I can't find a way to tell Jenkins to perform a clean checkout. By "clean," I mean it should remove all files from the workspace that aren't under version control.
I'm not sure if this answers the original question or not (I couldn't tell if the intention was to leave some files in the workspace) but why not just remove the workspace first, this would allow a clean checkout:
stage ('Clean') {
deleteDir()
}
stage ('Checkout') {
checkout scm
}
I run into the same problem and here is my workaround.
I created a new scm object for the checkout and extended the extensions with the CleanBeforeCheckout. But i kept the other configurations like branches and userRemoteConfigs.
checkout([
$class: 'GitSCM',
branches: scm.branches,
extensions: scm.extensions + [[$class: 'CleanBeforeCheckout']],
userRemoteConfigs: scm.userRemoteConfigs
])
It's still not perfect because you have to create a new object :(
First, you can not assume that a workflow job has a workspace as it was for freestyle jobs. Actually, a workflow job can use more than one workspace (one for each node or ws block).
Said that, what I'm going to propose is a kind of hacky: modify the scm object before checkout to set up a CleanCheckout extension (you will have to approve some calls there).
import hudson.plugins.git.extensions.impl.CleanCheckout
scm.extensions.replace(new CleanCheckout())
checkout scm
But I'd prefer Christopher Orr's proposal, use a shell step after checkout (sh 'git clean -fdx').
Behaviors can be added when configuring the source. clean before checkout, clean after checkout and Wipe out repository and force clone. This removes the need to add logic to the declarative / scripted pipelines.
Adding Christopher-Orr's comment as an answer to just do:
stage('Checkout') {
checkout scm
sh 'git clean -fdx'
}
Jenkins currently contains a page to generate groovy pipeline syntax. Selecting the checkout step you should be able to add all the additional options that you're used to.
I generated the following which should do what you want:
checkout poll: false, scm: [$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CleanBeforeCheckout']], submoduleCfg: [], userRemoteConfigs: [[url: 'ssh://repo/location.git']]]

Resources