Trigger on only one of multiple polled SCMs in a Jenkinsfile - jenkins

My Jenkinsfile has two SCM checkouts, primary, and secondary. I only want to have the build triggered when commits are made in primary. I've set the poll argument in the obvious way, but it does not seem to be honored; the build gets triggered when commits are made to either repository.
node {
stage("checkout") {
checkout scm: [$class: "MercurialSCM", source: "/var/jenkins_home/hg/primary", subdir: "hg/primary", clean: true], poll: true
checkout scm: [$class: "MercurialSCM", source: "/var/jenkins_home/hg/secondary", subdir: "hg/secondary", clean: true], poll: false
}
stage("do something") {
echo 'Hello World'
sh 'sleep 30s'
echo 'Done'
}
}

I could not figure out how to do this from within Jenkinsfile only.
To solve this problem for myself, I ended up creating a separate Jenkins job (Free Style project, not pipeline) which was setup to Poll SCM on the primary repo. This job does nothing except in the Post-build Actions it triggers my actual Jenkins Pipeline job which loads the Jenkinsfile like you showed.
The trigger passes a Predefined parameter set to the change ID that the poller found. In my case it was Git so I set change=${GIT_COMMIT}.
In my Pipeline job, I created a String parameter called change.
In my Jenkinsfile, I used env.change in the checkout line to checkout the specific commit.

Related

What does the pollSCM trigger refer to in this Jenkinsfile?

Consider the following setup using Jenkins 2.176.1:
A new pipeline project named Foobar
Poll SCM as (only) build trigger, with: H/5 * * * * ... under the assumption that this refers to the SCM configured in the next step
Pipeline script from SCM with SCM Git and a working Git repository URL
Uncheck Lightweight checkout because of JENKINS-42971 and JENKINS-48431 (I am using build variables in the real project and Jenkinsfile; also this may affect how pollSCM works, so I include this step here)
Said repository contains a simple Jenkinsfile
The Jenkinsfile looks approximately like this:
#!groovy
pipeline {
agent any
triggers { pollSCM 'H/5 * * * *' }
stages {
stage('Source checkout') {
steps {
checkout(
[
$class: 'GitSCM',
branches: [],
browser: [],
doGenerateSubmoduleConfigurations: false,
extensions: [],
submoduleCfg: [],
userRemoteConfigs: [
[
url: 'git://server/project.git'
]
]
]
)
stash 'source'
}
}
stage('OS-specific binaries') {
parallel {
stage('Linux') {
agent { label 'gcc && linux' }
steps {
unstash 'source'
echo 'Pretending to do a build here'
}
}
stage('Windows') {
agent { label 'windows' }
steps {
unstash 'source'
echo 'Pretending to do a build here'
}
}
}
}
}
}
My understanding so far was that:
a change to the Jenkinsfile (not the whole repo) triggers the pipeline on any registered agent (or as configured in the pipeline project).
said agent (which is random) uses the pollSCM trigger in the Jenkinsfile to trigger the pipeline stages.
But where does the pollSCM trigger poll (what SCM repo)? And if it's a random agent then how can it reasonably detect changes across poll runs?
then the stages are being executed on the agents as allocated ...
Now I am confused what refers to what. So here my questions (all interrelated which is why I keep it together in one question):
The pipeline project polls the SCM just for the Jenkinsfile or for any changes? The repository in my case is the same (for Jenkinsfile and source files to build binaries from).
If the (project-level) polling triggers at any change rather than changes to the Jenkinsfile
Does the pollSCM trigger in the Jenkinsfile somehow automagically refer to the checkout step?
Then ... what would happen, would I have multiple checkout steps with differing settings?
What determines what repository (and what contents inside of that) gets polled?
... or is this akin to the checkout scm shorthand and pollSCM actually refers to the SCM configured in the pipeline project and so I can shorten the checkout() to checkout scm in the steps?
Unfortunately the user handbook didn't answer any of those questions and pollSCM has a total of four occurrences on a single page within the entire handbook.
I'll take a crack at this one:
The pipeline project polls the SCM just for the Jenkinsfile or for any
changes? The repository in my case is the same (for Jenkinsfile and
source files to build binaries from).
The pipeline project will poll the repo for ANY file changes, not just the Jenkinsfile. A Jenkinsfile in the source repo is common practice.
If the (project-level) polling triggers at any change rather than
changes to the Jenkinsfile Does the pollSCM trigger in the Jenkinsfile
somehow automagically refer to the checkout step?
Your pipeline will be executed when a change to the repo is seen, and the steps are run in the order that they appear in your Jenkinsfile.
Then ... what would happen, would I have multiple checkout steps with
differing settings?
If you defined multiple repos with the checkout step (using multiple checkout SCM calls) then the main pipeline project repo would be polled for any changes and the repos you define in the pipeline would be checked out regardless of whether they changed or not.
What determines what repository (and what contents inside of that)
gets polled? ... or is this akin to the checkout scm shorthand and
pollSCM actually refers to the SCM configured in the pipeline project
and so I can shorten the checkout() to checkout scm in the steps?
pollSCM refers to the pipeline project's repo. The entire repo is cloned unless the project is otherwise configured (shallow clone, lightweight checkout, etc.).
The trigger defined as pollSCM polls the source-control-management (SCM), at the repository and branch in which this jenkinsfile itself (and other code) is located.
For Pipelines which are integrated with a source such as GitHub or BitBucket, triggers may not be necessary as webhooks-based integration will likely already be present. The triggers currently available are cron, pollSCM and upstream.
It works for a multibranch-pipeline as trigger to execute the pipeline.
When Jenkins polls the SCM, exactly this repository and branch, and detects a change (i.e. new commit), then this Pipeline (defined in jenkinsfile) is executed.
Usually then the following SCM Step checkout will be executed, so that the specified project(s) can be built, tested and deployed.
See also:
SCM Poll in jenkins multibranch pipeline
SehllHacks(2020): Jenkins: Scan Multibranch Pipeline Without Build

How to trigger a Jenkins Pipeline on Git commit

I'm setting up Jenkins pipeline for my .Net Core application.
Jenkins multibranch pipeline build gets trigger on Git commit if I am configuring the checkout SCM in multibranch Pipeline configuration. But multibranch Pipeline build is not getting trigger on git commit if I checkout SCM explicitly inside Jenkins Declarative Pipeline script.
Is there any way to resolve this issue?
Below is the checkout command which I am using inside the script:
checkout([$class: 'GitSCM', branches: [], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CleanCheckout'], [$class: 'PruneStaleBranch']], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'credential-id', url: 'my/git/ssh/url']]])
To get the build triggered on new git commit you should first enable SCM polling in your pipeline script by adding proper triggers directive to your Jenkinsfile:
triggers {
pollSCM 'H/2 * * * *'
}
This will poll your SCM for any changes every two minutes. If a change is detected since the last build your job will be triggered to build the changes.
Polling is the easiest way to get what you want. However, you should consider using post-commit hook instead of polling. Using polling Jenkins has to periodically check SCM for the changes. In case of post-commit hook, Jenkins will be notified about the changes by SCM if necessary. It's prefered over polling because it will relieve the number of required requests and the traffic from Jenkins towards SCM repository.
After configuring post-commit hook, the triggers directive should be modified by providing an empty string as cron parameter to pollSCM trigger.
triggers {
pollSCM ''
}
It can be confusing but this empty string is required to enable post-commit hooks requests to be handled by the job. It's also not very well documented by Jenkins docs.

Jenkins will not continue pipeline after updating via Mercurial plugin

I'm trying to setup a CI process using Jenkins with the source code being held in Mercurial, so I have the Jenkins Mercurial Plugin installed.
It's a simple pipeline script just now which polls my repository every 10 minutes. Using the checkout command below and hitting Build Now on my job it successfully clones my repository and continues with the pipeline as expected. It also successfully sets up polling and I can see from the polling log that it is checking the repository for changes every 10 minutes.
checkout changelog: true, poll: true, scm: [$class: 'MercurialSCM', credentialsId: 'xxx', installation: 'TortoiseHg', source: 'C:\\Path\\to\\repo']
However, when I push to my repository, Jenkins on next running the job spots these changes, pulls them down but then reports back 'No changes' and so the job stops. I expected that at this point the job would continue because there are changes. Of course if there were no changes I would expect it to stop the job at this point.
The Mercurial Polling Log shows the changes have been pulled but hg update has not been run. This is confirmed by looking at the Jenkins-created-repo in the Tortoise Workbench. However, even putting a hook in Mercurial configuration in Jenkins such that it does update after pulling does not fix the issue. Jenkins still reports 'No changes' after the checkout step.
So after the initial build, which works fine, Jenkins never runs the job all the way through again. It always bails out after the checkout step because despite pulling down any changes it reports there are none.
I have checked the permissions and everything seems fine, the fact that it completely runs on demand and can subsequently pull also suggests there is nothing wrong with the pipeline or elsewhere.
Any suggestions as to how to get the job to continue after the checkout stage would be much appreciated.
Below is an example pipeline script:
pipeline {
agent any
triggers {
pollSCM '*/10 * * * *'
}
stages {
stage('Checkout') {
steps {
checkout changelog: true, poll: true, scm: [$class: 'MercurialSCM', credentialsId: 'xxx', installation: 'TortoiseHg', source: 'C:\\Path\\to\\repo']
}
}
stage('Build') {
steps {
echo Continuing with build...
}
}
}
UPDATE I have noticed that if I manually build after the poll has pulled down but not updated the local repository the job then updates the repository and the build continues as normal.
It looks like you have omitted to specify a branch in your scm checkout. Are you using the default branch in HG?
This Jenlins issue and the source code show that if you are not using the deault branch, you'll likely not see your changes pulled down even if the references are there.
If you are trying to build a non default branch give this a try
checkout changelog: true, poll: true, scm: [$class: 'MercurialSCM', branches: [[name: '*/yourbranch']], credentialsId: 'xxx', installation: 'TortoiseHg', source: 'C:\\Path\\to\\repo']

Jenkins pipeline not polling mercurial branch

Jenkins version 2.89.4
I have a pipeline that should checkout my code and test it everytime a commit is pushed.
stage('Code checkout') {
dir("${env.HG_NODE_DIRECTORY}") {
checkout([$class: 'MercurialSCM',
credentialsId: '...',
clean: true,
disableChangeLog: true,
installation: '(Default)',
source: 'ssh://hg#bitbucket.org/team/project'])
}
}
I have a webhook on my Bitbucket project that should trigger this builds, but they are not triggering.
The only job that triggers is one I created as a test, where I have my checkout configured the old way, directly into the job configuration, with no pipeline.
Is this a bug? Can I somehow trigger this kind of pipeline by SCM polling?
EDIT: I had to create a job with "normal" SCM configuration to then trigger the other jobs.

Trigger workflow on Github push - Pipeline plugin - Multibranch configuration

We are using the pipeline plugin with multibranch configuration for our CD.
We have checked in the Jenkinsfile which works off git.
git url: "$url",credentialsId:'$credentials'
The job works fine, but does not auto trigger when a change is pushed to github.
I have set up the GIT web hooks correctly.
Interestingly, when I go into a branch of the multibranch job and I click "View Configuration", I see that the "Build when a change is pushed to Github" is unchecked. There is no way to check it since I can not modify the configuration of the job (since it takes from parent) and the same option is not there in parent.
Any ideas how to fix this?
For declarative pipelines try:
pipeline {
...
triggers {
githubPush()
}
...
}
For me this enables the checkbox "GitHub hook trigger for GITScm polling", but polling is not actually required. This requires the GitHub plugin.
I found a way to check the checkbox "Build when a change is pushed to Github".
This line did the trick:
properties([pipelineTriggers([[$class: 'GitHubPushTrigger'], pollSCM('H/15 * * * *')])])
I think the polling is needed to make it work. Would be nice if no polling is needed.
Here's a Jenkinsfile example with this implemented:
#!/usr/bin/env groovy
node ('master'){
stage('Build and Test') {
properties([pipelineTriggers([[$class: 'GitHubPushTrigger'], pollSCM('H/15 * * * *')])])
checkout scm
env.PATH = "${tool 'Maven 3'}/bin:${env.PATH}"
sh 'mvn clean package'
}
}
For declarative pipelines, try this:
pipeline {
agent any
triggers {
pollSCM('') //Empty quotes tells it to build on a push
}
}
If you use Stash for example you can register a Post-Receive WebHook where you have to insert your URL form Jenkins like : http://jenkinsHost:9090/git/notifyCommit?url=ssh://git#gitHost:1234/test.git
In your jenkins Job you have to set at least the Build trigger "Poll SCM".
And set a polling time of e.g 5 mins.
This enables also the automatic branch indexing for your multibranch project configuration.
Resorting to polling adds latency - time that it takes for a build to start and hence finish giving back a result.
It seemed to me that the basic plugins have a low level of abstraction, so I switched to the Github Organization Folder plugin, which depends on all of them and sets up an organization hook for triggering builds branches and/or pull requests.
Before I start, I would like to emphasize that I had no previous experience with Jenkins so far, so there might be a bunch of better solutions out there.
What I wanted to achieve in a nutshell:
After every push made to a Bitbucket repo(test2), on every branch,
pull and build another Bitbucket repo(test1), from an identical
branch name and right after that, build test2 using test1 as a
dependency.
How I managed to achieve that?
I started a new job with type 'Multibranch Pipeline'
I added the following Jenkinsfile to test2:
pipeline {
agent any
stages {
stage('build') {
steps {
dir('test1') {
git branch: BRANCH_NAME, url: 'git#bitbucket.org:user/test1.git', credentialsId: 'credentials_id'
}
sh('build_process')
}
}
}
}
I come across the issue that you can't set up a Bitbucket hook for pipelines
I added Bitbucket Branch Source Plugin to Jenkins
I selected Bitbucket at 'Branch Sources' when setting up the job
I added credentials and put a checkmark to Auto-register webhook
Under 'Scan Multibranch Pipeline Triggers' I put a checkmark to Periodically if not otherwise run, with an interval of 1 min
I added a webhook to my Bitbucket repo
I updated all my plugins, restarted Jenkins and it's ready to go
Other plugins I have installed: Bitbucket Plugin, Pipeline plugin. Hope this helps for somebody, I did manage to solve it this way after hours of struggling without the Bitbucket Branch Source Plugin.
node{
stage('Build and Test') {
properties([pipelineTriggers([[$class: 'GitHubPushTrigger'], pollSCM('* * * * *')])])
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxx-xxx-xxxx[your credentails Id]', url: 'https://github.com/git']]])
echo 'Build and Test has been done'
}
}

Resources