首页 文章

Jenkins管道里程碑没有取消之前正在进行的构建

提问于
浏览
4

我正在尝试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'
            }
        }
    } 
}

触发此管道两次不会取消第一个作业

5 回答

  • 5

    我不认为这种行为是“如果我是一个跨越这个里程碑的新建筑,那么所有越过这个里程碑的旧版本将被取消”

    里程碑步骤的实际行为是,当最近的管道首先穿过它时,它会阻止旧管道越过该里程碑 .

  • -2

    试试这个:

    /* 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() != buildsNumber) {
                /* Than stopping it */
                build.doStop()
            }
        }
    }
    
  • 3

    根据document,我有一个简单的工作milestone plugin

    按顺序构建通过里程碑(将构建号作为分拣机字段) . 如果较新的版本已经通过里程碑,则旧版本将不会继续(它们将被中止) . 当构建通过里程碑时,任何通过上一个里程碑而不是这个里程碑的旧构建都将中止 . 一旦构建通过里程碑,它将永远不会被尚未通过里程碑的新构建中止 .

    你可以尝试这样的事情:

    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的进程,如果它当前正在运行 .

  • 2

    根据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

    我认为这是正常行为 . 如果你想要只运行工作,你可以添加

    pipeline {
        agent { label 'xxx' }
        options {
            disableConcurrentBuilds()
        }
    

    如果你想杀死当前的作业并触发一个新作业,你可以在你的构建中添加一些groovy来做到这一点 .

相关问题