23

We have been using Jenkins for Continuous Integration for some time. A typical build job specifies the SVN repository and credentials in the "Source Code Management" section, then in the "Build Triggers" section we enable "Poll SCM" with a polling schedule of every 10 minutes (H/10 * * * *). We have updated to the latest version of Jenkins and are looking to set up pipeline builds. A typical pipeline script looks like:

node {
    stage 'Build'
    build job: 'MyApplication Build'
    stage 'Deploy to test environment'
    build job: 'MyApplication Deploy', parameters: [
        [$class: 'StringParameterValue', name: 'DatabaseServer', value: 'DatabaseServer1'],
        [$class: 'StringParameterValue', name: 'WebServer', value: 'WebServer1']
    ]
    stage 'RunIntegrationTests'
    build job: 'MyApplication Test', parameters: [
        [$class: 'StringParameterValue', name: 'DatabaseServer', value: 'DatabaseServer1'],
        [$class: 'StringParameterValue', name: 'WebServer', value: 'WebServer1']
    ]
}

When the pipeline job is triggered manually then everything runs fine, however we would like this pipeline to be run every time a new revision is checked in to the SVN repository. The pipeline configuration does have a "poll SCM" build trigger option, but does not have a "Source Code Management" section where you can specify your repository. How can we achieve this?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Jon Lawson
  • 582
  • 1
  • 6
  • 16

6 Answers6

18

Using a Jenkins Declarative Pipeline script, you can configure a job to poll an SVN repository URL every 10 minutes as follows:

pipeline {
    agent any
    triggers {
        pollSCM 'H/10 * * * *'
    }
    stages {
        stage('checkout') {
            steps {
                checkout([
                    $class: 'SubversionSCM', 
                    additionalCredentials: [], 
                    excludedCommitMessages: '', 
                    excludedRegions: '', 
                    excludedRevprop: '', 
                    excludedUsers: '', 
                    filterChangelog: false, 
                    ignoreDirPropChanges: false, 
                    includedRegions: '', 
                    locations: [[
                        credentialsId: 'mySvnCredentials', 
                        depthOption: 'infinity',
                        ignoreExternalsOption: true, 
                        local: '.', 
                        remote: 'http://example.com/svn/url/trunk']], 
                    workspaceUpdater: [$class: 'CheckoutUpdater']
                ])
            }
        }
    }
}

The pollSCM trigger should automatically poll all SCM Repository URLs associated with your build, including URLs specified by checkout steps, the URL of your Declarative Pipeline script from SCM, and the URL of your Global Pipeline Libraries. If you truly want the pipeline to be run for every single revision however, you'll need to set up a post-commit hook instead.

akaRem
  • 7,326
  • 4
  • 29
  • 43
heenenee
  • 19,914
  • 1
  • 60
  • 86
  • Will this poll the entire pipeline stage ? – Akki Mar 24 '17 at 20:45
  • @Akki I believe it remembers URLs once they are executed by a step in any stage. – heenenee Mar 24 '17 at 21:07
  • It seems that `includedRegions` (haven't tested other options) is ignored when polling. No matter what `includedRegions` is set to any checkins to the specified locations will trigger a build. Any suggestions? – Adam Nov 11 '17 at 01:08
  • 1
    @Adam Based on this [issue](https://issues.jenkins-ci.org/browse/JENKINS-36195) and [question](https://stackoverflow.com/questions/37294781/configuration-of-includedregions-in-jenkinsfile), it seems `includedRegions` is currently unsupported. A workaround would be to do a checkout on each included region separately. Outside of that, nothing obvious comes to mind. – heenenee Nov 12 '17 at 05:10
  • 1
    Could you _please_ state an authoritative source for the claim *"The pollSCM trigger should automatically poll all SCM Repository URLs associated with your build"*?! I have been searching high and low and came up empty-handed. Handbook doesn't mention this (except it's in some place where `pollSCM` is _not_ mentioned). – 0xC0000022L Jun 27 '19 at 12:25
  • 1
    Documentation on Jenkins plugins is kind of a crapshoot. This answer is not based on any "authoritative source", it is based on observed behavior. I have had jobs that varied Subversion repository URLs over time and the polling log showed it was polling all of them. – heenenee Jun 27 '19 at 18:54
10

The solution that I have found to work is:

  1. Move the pipeline script into a file (the default is JenkinsFile) and store this in the root of my project in SubVersion.
  2. Set my pipeline job definition source to "Pipeline script from SCM", enter the details of where to find my project in SubVersion as per a normal Jenkins build job, and set the Script Path to point at the JenkinsFile containing the pipeline script.
  3. Set the build trigger of the pipeline job to "Poll SCM" and enter a schedule.
  4. Manually run the pipeline job

It seemed to be step 4, manually running the pipeline job that caused the poll trigger to pick up the correct repository to poll. Before that it didn't seem to know where to look.

Jon Lawson
  • 582
  • 1
  • 6
  • 16
  • do you have the groovy line used to set the build trigger property in step 3? i imagine that would be nested within the `properties();` method? – tarabyte Sep 17 '16 at 07:50
  • I think that will only work when there is a change in the Jenkinsfile itself though... – Philippe May 23 '17 at 14:54
  • So based on that really the solution is to have the pipeline project trigger regularly (in addition to polling the SCM) in order to get that first "manual" run going? – 0xC0000022L Jun 27 '19 at 12:28
7

As an alternative to when the pipeline script is not part of the project or is defined in the job, you can add poll: true to your checkout stage.

Example:

stage('checkout') {
    checkout(
        changelog: true, 
        poll: true, /*This is the important option*/
        scm: [
            $class: 'SubversionSCM', 
            filterChangelog: false, 
            ignoreDirPropChanges: false,
            locations: [...], /*ommited for obvious reasons*/
            workspaceUpdater: [$class: 'CheckoutUpdater']
        ])
}

After the first run it will start polling from this SCM also as from the SCM where the pipeline is if it is the case.

This option is documented at https://jenkins.io/doc/pipeline/steps/workflow-scm-step/#code-checkout-code-general-scm , in the very end of the page without details.

4

I think you need a Checkout stage before before your Build stage, which consists of the SCM information. This allows the job to Poll SCM at the desired interval and run the pipeline.

You can even use Pipeline script, without having the pipeline codes to store as a JenkinsFile in SCM.

Below is my SVN Checkout stage pipeline code before my Build stage:

stage('Checkout') {
    checkout([$class: 'SubversionSCM', 
        additionalCredentials: [], 
        excludedCommitMessages: '', 
        excludedRegions: '', 
        excludedRevprop: '', 
        excludedUsers: 'buildbot', 
        filterChangelog: false, 
        ignoreDirPropChanges: false, 
        includedRegions: '', 
        locations: [[credentialsId: 'b86bc2b6-994b-4811-ac98-0f35e9a9b114', 
            depthOption: 'infinity', 
            ignoreExternalsOption: true, 
            local: '.', 
            remote: "http://svn/something/trunk/"]],
        workspaceUpdater: [$class: 'UpdateUpdater']])
}

Works for my pipeline job though. Hope this helps.

zionyx
  • 1,927
  • 19
  • 14
4

So, we had A LOT of problems getting this to work. Here is how we solved the problem:

In Jenkins you make a Pipeline Job. The only contents that are required in this job are:

  • POLL SCM (with some arbitrary value such as @monthly)
  • Where the job should find your Jenkinsfile

Every other setting goes into the Jenkinsfile. However:

  triggers {
pollSCM('@monthly')}

Should STILL be specified in your Jenkinsfile even though it is already specified in your job.

However, as zionyx said you need to checkout before you do anything else. In our case we wanted to avoid this for many reasons. Luckily it still works if you have: depthOption: 'empty'.

Finally, you need to manually start the first job run.

We made a little function that you can perhaps use:

def checkoutSVN(Boolean ignoreExternalsOption, String local, String remote, String updater) {
checkout([$class: 'SubversionSCM', 
    additionalCredentials: 
    [[credentialsId: 'get-this-from-your-jenkins', 
    realm: '<https://your-server> CollabNet Subversion Repository']], 
    excludedCommitMessages: '', 
    excludedRegions: '', 
    excludedRevprop: '', 
    excludedUsers: '', 
    filterChangelog: false, 
    ignoreDirPropChanges: false, 
    includedRegions: '', 
    locations: [[credentialsId: 'get-this-from-your-jenkins', 
    depthOption: 'empty', 
    ignoreExternalsOption: ignoreExternalsOption, 
    local: local, 
    remote: remote]], 
    quietOperation: false,
    workspaceUpdater: [$class: updater]])}
DHummel
  • 132
  • 1
  • 12
-2

Facts

  • Jenkins Pipeline does not have the option to be triggered from SCM.
  • Jenkins Job does have the option to be Triggered from SCM.

=> The simplest way to achieve this is:

  1. Create a Jenkins JOB that is Triggered from SCM.
  2. Configure Jenkin Pipeline to be triggered after Jenkins Job build.

That's it!

Gonzalo Gallotti
  • 2,413
  • 3
  • 23
  • 28
  • 1
    The "does" and "does not" refer to the capability of the Jenkins Pipeline? Experience? Secret knowledge about something? It would be good to give a source for your "Facts". Thanks. – 0xC0000022L Jun 27 '19 at 12:22