Gitlab-plugin: Cancel running build when "Rebuild open Merge Requests"

Created on 12 Jan 2016  路  10Comments  路  Source: jenkinsci/gitlab-plugin

Hi, I'm using the option "Rebuild open Merge Requests" with "On push to source branch" in a Jenkins job. It would be really nice that when there's a new push, a running build for the same MR is aborted and a new one can start right away instead of being in the queue.

What do you think about implementing this? Thanks.

feature request fix-pending

Most helpful comment

@omehegan What is needed to make a pull request from this code? We need that feature :)

All 10 comments

+1 such feature would be useful

IMHO you do not want to cancel running build jobs, at least not when the job is running on a _Windows_ slave, as open files might not be properly closed, resulting in a messy work space.

But having build jobs waiting in _build queue_ cancelled, when a new build job is created for the same merge request makes sense to me.

I've done some implementation for this issue which is still in an experimental state. Once, I've completed and approved it to work as expected, the code will be merged to master.

@omorillo just wanted to check in about the status of this, I am reviewing old issues!

@omehegan What is needed to make a pull request from this code? We need that feature :)

This is supported natively in Jenkins if you use Pipeline jobs, so I'm going to close this request against the plugin.

Hi @omehegan , I don't know the way it can be implemented in pipeline natively, can you help me find this out?

Hi @omehegan, I have the same question as @oxygenxo. Not sure how to abort previously running job when MR is updated. Can you please add this to the documentation so that it is clear how to do this?

We have a major capacity issue due to this not being easily available.

Hi @omehegan following up on previous comment. Can you please provide some details on how this can be achieved?

@Atrifex The problem is that build will be cancelled only if it is still in queue. So already running builds (i.e. builds that occupy agent) wont' be cancelled.
We're using the following Scripted Pipeline snippet to cancel previous running build when new commits are pushed to MR (credits to @akladiev):

def cancelBuilds(int builds_to_scan=300) {
    def jobName = env.JOB_NAME
    def currentMR = env.gitlabMergeRequestIid?.toInteger()
    def currentRepoUrl = env.gitlabSourceRepoURL
    def currentBuildNumber = env.BUILD_NUMBER?.toInteger()
    def currentJob = Jenkins.instance.getItemByFullName(jobName)

    def i = 0
    for (def build : currentJob.builds) {
        if (i > builds_to_scan) {
            return null
        }
        def buildNumber = build.number?.toInteger()
        if (buildNumber < currentBuildNumber) {
            def buildMR = build.getEnvVars()["gitlabMergeRequestIid"]?.toInteger()
            def buildRepoUrl = build.getEnvVars()["gitlabSourceRepoURL"]

            if (build.isBuilding() && buildMR == currentMR && buildRepoUrl == currentRepoUrl) {
                def executor = build.getExecutor()
                def cause = new CauseOfInterruption.UserInterruption(
                    "New pre-commit build was started for current MR ${buildMR} " +
                        "(see ${this.script.env.BUILD_URL}), current build is aborted"
                )
                executor.interrupt(Result.ABORTED, cause)
                return buildNumber
            }
        }
        i++
    }
}

But it can be unsafe for Windows builds for example as @omorillo said

I use below function in Jenkinsfile to implement this feature

#!groovy
import groovy.json.*
import hudson.model.*
import jenkins.model.*

def cancelPreviousBuilds() {
  echo "Source Branch for this build is: ${gitlabSourceBranch}"
  def jobName = env.JOB_NAME
  def currentBuildNumber = env.BUILD_NUMBER.toInteger()
  def currentJob = Jenkins.instance.getItemByFullName(jobName)

  for (def build : currentJob.builds) {
    def buildBranch = build.getEnvironment()['gitlabSourceBranch']
    if (build.isBuilding() && (build.number.toInteger() < currentBuildNumber) && (buildBranch == gitlabSourceBranch)) {
      echo "Older build ${build.number} Source Branch is ${buildBranch}"
      echo "Older build still queued. Sending kill signal to build number: ${build.number}"
      build.doTerm()
    }
  }
}

cancelPreviousBuilds()
Was this page helpful?
0 / 5 - 0 ratings