How to disable automatic build from scm change in Jenkinsfile

岁酱吖の 提交于 2019-12-03 01:43:44

If you're using a Multibranch Pipeline, you should be able to do this on the job's Configure page:

  1. Scroll down to "Branch Sources"
  2. Under "Property strategy", choose "Named branches get different properties"
  3. Click "Add exception", enter "master" as the branch name
  4. Click "Add property", choose "Suppress automatic SCM triggering"
  5. Save

That would prevent changes to the master branch from triggering a build of the corresponding job.

For declarative pipelines, use the when directive with a triggeredBy condition, e.g.

when { triggeredBy 'TimerTrigger' }

With the multibranch pipeline, I could not figure out a way to prevent the next build being triggered. As a workaround, I added the following code to my Jenkinsfile (using scripted syntax), to abort the following build if the only changes contain "[ci-skip]" in the commit message:

def abortBuildIfTriggeredBySkippableCommit() {
    def changeSetCount = 0;
    def ciSkipCount = 0;
    if (currentBuild.changeSets != null) {
        for (changeSetList in currentBuild.changeSets) {
            for (changeSet in changeSetList) {
                changeSetCount++;
                if (changeSet.msg.contains('[ci-skip]')) {
                    ciSkipCount++;
                }
            }
        }
    }

    if (changeSetCount > 0 && changeSetCount == ciSkipCount) {
        currentBuild.result = 'NOT_BUILT'
        error("Stopping to prevent auto trigger. All commits contained [ci-skip]")
    }
}

Note that this code assumes you are using the git plugin, and that the objects in currentBuild.changeSets will be GitChangeSetList.

This is what I came up with. I was hoping for something less messy, but this does seem to work:

I have this as the build's properties:

properties([
    pipelineTriggers([cron('H H 7 * *')])
])

I then have this function that defines the source of the build:

// check if the job was started by a timer
@NonCPS
def jobStartedByWhat() {
def startedByWhat = ''
try {
    def buildCauses = currentBuild.rawBuild.getCauses()
    for ( buildCause in buildCauses ) {
        if (buildCause != null) {
            def causeDescription = buildCause.getShortDescription()
            echo "shortDescription: ${causeDescription}"
            if (causeDescription.contains("Started by timer")) {
                startedByWhat = 'timer'
            }
            if (causeDescription.contains("Started by user")) {
                startedByWhat = 'user'
            }
        }
    }
} catch(theError) {
    echo "Error getting build cause: ${theError}"
}

return startedByWhat
}

def startedByWhat = jobStartedByWhat()

I can then evaluate the function at runtime so that if a build gets triggered because of a merge to master, it will not actually run:

node {
try {
    checkout scm

    if (env.BRANCH_NAME == 'master') {
        if (startedByWhat == 'timer' || startedByWhat == 'user') {
 ..... RUN THE BUILD .....
    } else {
.... EXIT WITHOUT RUNNING THE BUILD ....

I stumbled upon this as well. IMO an acceptable solution would be a filter for commit messages when checking out source code - this feature exists for regular Jobs but is missing for multibranch pipelines, see https://issues.jenkins-ci.org/browse/JENKINS-48296.

For those not using the git plugin, this method is a workaround for scripted pipelines (inspired by scarswell's answer):

def abortBuildIfTriggeredBySkippableCommit() {
    lastCommitMessage = sh(
        script: "${gitBinary} --no-pager log -1 --pretty=%B",
        returnStdout: true
    )
    if (lastCommitMessage != null && 
        lastCommitMessage.toString().contains('[maven-release-plugin]')) {
        currentBuild.result = 'ABORTED'
        error("Stopping build, it was triggered by the maven release plugin")
    }
}

If you are using Pipeline script from SCM then comment out the triggers section(either SCMPoll/BuildPeriodically option ) in Jenkins file as shown below.

//triggers {cron ('H/15 * * * *')} //pipelineTriggers([pollSCM('H/15 * * * *')])

If you are using Pipeline script then disable the PollSCM/Build periodically(whichever is used) option.

One could disable the scm build trigger by disabling the webhook notification from git.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!