I have a Jenkins multibranch pipeline and two Git repos:
Repo 1 - Git webhook enabled. Configured as "Branch Source" for the pipeline, with filter, so only some branches are built and others are excluded.
Repo 2 - No webhook. Contains a tool that is cloned during the build process with the following code in the Jenkinsfile:
checkout(poll:false, changelog: false, scm:[$class: 'GitSCM',
branches: [[name: "master"]],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'GitLFSPull'], [$class: 'CloneOption', noTags: false, reference: '', shallow: true]],
submoduleCfg: [],
When a new commit is pushed to Repo 1, to one of the excluded branches, the webhook is executed (as expected), but then Jenkins checks for changes in both Repo 1 and Repo 2.
If Repo 2 has changes, it will start a build on one of the included branches on Repo 1, even though that branch has no changes.
How can I prevent changes to Repo 2 from starting any builds?
Related
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
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.
I have a project kuma organized with submodules:
kuma
Jenkinsfile (configured to test kuma)
locales
kumascript
Jenkinsfile (configured to test kumascript)
A bunch of other files
I'd like to configure a multi-branch pipeline in Jenkins that watches for branches on the kumascript repo, to:
Check out the master branch of kuma
Update the locales to the commit in the master branch (a regular git submodule update --init)
Update the kumascript submodule to the branch to test
Run the Jenkinsfile in the kumascript branch
Is this possible? Is there a better way to do this?
Here's what worked for me.
First, the Jekinsfile is read from the commit, before checkout, so it is easy to use the one in the kumascript submodule, and much, much harder (impossible?) to read it from a different repo.
In Jenkins 2.68 with Git plugin 3.4.1, I setup a multibranch pipeline. The one source is Git, pointing to the kumascript repository:
"Discover branches" finds branches in the repository and starts builds for them.
"Wipe out repository and force clone" works around an issue where jgit doesn't fetch a submodule repository before checking it out, and thus the target commit isn't available. It causes an error that looks like this in the Jenkins logs:
> git fetch --no-tags --progress https://github.com/mdn/kumascript +refs/heads/*:refs/remotes/origin/*
Checking out Revision 998d9e539127805742634ef1c850221cf04ca2c7 (build-with-locales-1340342)
org.eclipse.jgit.errors.MissingObjectException: Missing unknown 998d9e539127805742634ef1c850221cf04ca2c7
at org.eclipse.jgit.internal.storage.file.WindowCursor.open(WindowCursor.java:158)
at org.eclipse.jgit.lib.ObjectReader.open(ObjectReader.java:227)
at org.eclipse.jgit.revwalk.RevWalk.parseAny(RevWalk.java:859)
at org.eclipse.jgit.revwalk.RevWalk.parseCommit(RevWalk.java:772)
This issue appears to be reported in https://issues.jenkins-ci.org/browse/JENKINS-45729, and is reported fixed in Git client plugin 2.5.0.
Wiping out the repo appears to force the full fetch, and may be necessary when installing in a parent project.
Jenkins is now configured to create a build for each branch in the repository. To check it out as a submodule, the parent project will need to be manually checked out in the Jenkinsfile. I used Jenkin's "Pipeline Syntax" tool to help construct the command
After some formatting, this goes in my Jenkinsfile:
stage("Prepare") {
// Checkout Kuma project's master branch
checkout([$class: 'GitSCM',
userRemoteConfigs: [[url: 'https://github.com/mozilla/kuma']],
branches: [[name: 'refs/heads/master']],
extensions: [[$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: false,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: false]],
doGenerateSubmoduleConfigurations: false,
submoduleCfg: []
])
// Checkout KumaScript in subfolder
dir('kumascript') {
checkout scm
}
}
This checks out the kuma project and its submodules, and then uses the "vanilla" checkout to checkout the requested branch, but in the submodule directory:
From then on, if I want to run a command in the kuma repo, I run it:
stage('Build') {
sh 'make build-kumascript VERSION=latest'
}
and if I want to run it in the kumascript submodule, I wrap it in dir:
stage('Lint') {
dir('kumascript') {
sh 'make lint VERSION=latest'
sh 'make lint-macros VERSION=latest'
}
}
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.
I am relatively new to Jenkins (using 2.32). So pardon my ignorance.
In my current setup, I have 2 free-style jobs for a single project - One point to production branch (/master) and another to the Dev branch (/dev). Bitbucket is configured to invoke (webhook) Jenkins on changes.
Once the dev is built and it passes all the unit test it gets deployed to Dev Server. Eventually, all dev changes are pushed to Master via pull request. The change in Master branch triggers the Master job and deploys the artifacts to productions.
I don't feel this setup is correct and would like you experts advise on this. Having 2 jobs makes me uncomfortable. What if I want a stage release? I will need another free-style job. Doesn't make much sense.
How do I go about doing this with one job? How do you guys achieve this? Using Pipeline? Any pointers would be greatly appreciated.
TIA.
You are correct, you can manage this better with Jenkins Pipeline
What you can do is the following :
1) Checkout the code from dev branch and put it in one directory in the workspace.
2) Compile and deploy from that directory.
3) Add a manual step for approval to deploy from master branch.
4) Repeat step 1 and 2.
A sample code would look something like this:
node {
// Get code from git repo
checkout changelog: false, poll: false, scm: [$class: 'GitSCM', branches: [[name: "origin/dev"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'test-dev-dir']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '<jenkins-github-credential-id>', url: 'https://github.com/test']]]
dir('test-dir') {
// Do your stuff
}
// stage concurrency: 1, name: 'approve'
// input id: 'master-deploy', message: 'Deploy from master?', ok: 'Deploy'
// Get code from git repo
checkout changelog: false, poll: false, scm: [$class: 'GitSCM', branches: [[name: "origin/master"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'test-master-dir']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '<jenkins-github-credential-id>', url: 'https://github.com/test']]]
dir('test-master-dir') {
// Preferbably create a tag for future hotfix maybe?
// Do your stuff
}
}