Я экспериментирую с конвейером и вехами Jenkins и не могу понять, почему Jenkins не отменяет предыдущую сборку, когда новая сборка пересекает веху.

Пример Jenkinsfile

pipeline {
    agent any

    parameters {
        booleanParam(defaultValue: true, description: '', name: 'userFlag')
    }

    stages {
        stage("foo") {
            steps {
                milestone(ordinal: 1, label: "BUILD_START_MILESTONE")
                sh 'sleep 1000'
            }
        }
    } 
}

Двойной запуск этого конвейера не отменяет 1-е задание

8
puneeth 4 Сен 2017 в 20:07

4 ответа

Попробуй это:

/* This method should be added to your Jenkinsfile and called at the very beginning of the build*/
@NonCPS
def cancelPreviousBuilds() {
    def jobName = env.JOB_NAME
    def buildNumber = env.BUILD_NUMBER.toInteger()
    /* Get job name */
    def currentJob = Jenkins.instance.getItemByFullName(jobName)

    /* Iterating over the builds for specific job */
    for (def build : currentJob.builds) {
        /* If there is a build that is currently running and it's not current build */
        if (build.isBuilding() && build.number.toInteger() != buildNumber) {
            /* Than stopping it */
            build.doStop()
        }
    }
}
11
sshepel 14 Мар 2019 в 13:23

Опираясь на ответ @ D.W., я нашел простой шаблон, который работает. Похоже, что вписывается в пулю № 3 Д. (который является официальным документом): When a build passes a milestone, Jenkins aborts older builds that passed the previous milestone but not this one.

Добавление более ранней вехи, что все пройдет, а затем один за другим, что будет ждать, заставит все работать так, как вы думаете. В моем случае:

steps {
  milestone 1
  input 'ok'
  milestone 2
}

Создайте две активные сборки и одобрите только вторую. Вы увидите, что первый автоматически отменяется, потому что сборка 2 прошла milestone 2 первой. Попробуйте убрать milestone 1, и вы увидите, что сборка 1 не отменяется, когда сборка 2 проходит milestone 2.

Добавление раннего этапа удовлетворяет требованию. Похоже, что сборка должна пройти любой этап, прежде чем будущий этап, пройденный более новой сборкой, приведет к ее отмене.

0
Max Cascone 20 Май 2020 в 17:42

Согласно https://jenkins.io/blog/2016/10 / 16 / stage-lock-milestone /, пара «milestone ()» работает для меня, чтобы убить предыдущие задания, пока конвейер запускался на время,

stage('Build') {    
    // The first milestone step starts tracking concurrent build order
    milestone()
    node {
        echo "Building"
    }}

// The Deploy stage does not limit concurrency but requires manual input
// from a user. Several builds might reach this step waiting for input.
// When a user promotes a specific build all preceding builds are aborted,
// ensuring that the latest code is always deployed.
stage('Deploy') {
    timeout(time: 60, unit: 'SECONDS') {input "Deploy?"}    
    milestone()
    node {
        echo "Deploying"
    }
}

Последняя веха помогает убить предыдущие сборки, если достигнута, скажем, кнопка развертывания, нажатая для вышеуказанного случая. Или заблокированный ресурс освобожден для случая ниже,

// This locked resource contains both Test stages as a single concurrency Unit.
// Only 1 concurrent build is allowed to utilize the test resources at a time.
// Newer builds are pulled off the queue first. When a build reaches the
// milestone at the end of the lock, all jobs started prior to the current
// build that are still waiting for the lock will be aborted
lock(resource: 'myResource', inversePrecedence: true){
  node('test') {
    stage('Unit Tests') {
      echo "Unit Tests"
    }
    stage('System Tests') {
      echo "System Tests"
    }
  }
  milestone()
}
0
RayTM 13 Фев 2018 в 10:10

У меня есть простая работа с плагином вехи, согласно document:

  • Сборки проходят этапы по порядку (принимая номер сборки в качестве поля сортировки).
  • Старые сборки не будут продолжаться (они будут прерваны), если более новая сборка уже прошла этап.
  • Когда сборка проходит этап, любая более старая сборка, которая прошла предыдущий этап, но не эта, прерывается.
  • Как только сборка проходит этап, она никогда не будет прервана новой сборкой, которая еще не прошла этап.

Вы можете попробовать что-то вроде этого:

pipeline {
    agent any
    stages {
        stage('Stop Old Build') {
            steps {
                milestone label: '', ordinal:  Integer.parseInt(env.BUILD_ID) - 1
                milestone label: '', ordinal:  Integer.parseInt(env.BUILD_ID)
            }
        }
    }
}

Вы можете поместить это в начале любого конвейера.

Предположим, вы только начали новую сборку, # 5. Первый этап будет использоваться для прохождения второго этапа №4, а второй этап (из №5) будет использован для уничтожения процесса №4, если он в данный момент выполняется.

7
D.W 15 Окт 2018 в 06:42