Jenkins - 如何在管道启动前 运行 a stage/function?

Jenkins - How to run a stage/function before pipeline starts?

我们使用带有 BitBucket 的 Jenkins multib运行ch 管道来构建拉取请求 b运行ches 作为我们代码审查过程的一部分。

我们想中止任何排队或正在进行的构建,以便我们只 运行 并保留最新的构建 - 我为此创建了一个函数:

def call(){
    def jobName = env.JOB_NAME
    def buildNumber = env.BUILD_NUMBER.toInteger()
    def currentJob = Jenkins.instance.getItemByFullName(jobName)
    
    for (def build : currentJob.builds){
        def exec = build.getExecutor()
        if(build.isBuilding() && build.number.toInteger() != buildNumber && exec != null){
            exec.interrupt(
                Result.ABORTED,
                new CauseOfInterruption.UserInterruption("Job aborted by #${currentBuild.number}")
            )
            println("Job aborted previously running build #${build.number}")
        }
    }
}

现在在我的管道中,我想 运行 当构建被创建或推送到 PR b运行ch 触发时使用这个函数。

似乎我能做到这一点的唯一方法是将代理设置为 none,然后将其设置为每个后续阶段的正确节点。这会导致缺少环境变量等,因为 'environment' 部分 运行s 在主机上。

如果我使用 agent { label 'mybuildnode' } 那么它不会 运行 直到 agent 从当前 in-progress/running build 中释放出来。

在将代理分配为我的管道的一部分之前,有没有办法让 'cancelpreviousbuilds()' 函数变为 运行?

这大致是我目前拥有的,但由于环境变量问题而不起作用 - 我必须执行 skipDefaultCheckout 以便我可以在构建过程中手动执行它:

pipeline {
    agent none
    environment {
        VER = '1.2'
        FULLVER = "${VER}.${BUILD_NUMBER}.0"
        PROJECTPATH = "<project path>"
        TOOLVER = "2017"
    }   
    options {
        skipDefaultCheckout true
    }
    stages {
        stage('Check Builds') {
            when {
                branch 'PR-*'
            }
            steps {
                // abort any queued/in-progress builds for PR branches
                cancelpreviousbuilds()
            }
        }
        stage('Checkout') {
    
            agent {
                label 'buildnode'
            }       
            steps {         
                checkout scm        
            }
        }
    }
}

它可以正常工作并成功中止构建,但我收到与缺少环境变量相关的错误,因为我必须使用代理 none 启动管道,然后将每个阶段设置为代理标签 'buildnode' 。

我希望我的整个管道 运行 在正确的代理上,以便正确设置工作区/环境变量,但我需要一种方法来触发 cancelpreviousbuilds() 函数而不需要分配 buildnode 代理首先.

您可以尝试结合声明式管道和脚本式管道,这是可行的。

示例(注意我还没有测试过):

// this is scripted pipeline
node('master') { // use whatever node name or label you want
    stage('Cancel older builds') {
        cancel_old_builds()
    }
}

// this is declarative pipeline
pipeline {
    agent { label 'buildnode' }
    ...
}

作为一个小评论,您似乎使用了:build.number.toInteger() != buildNumber 这不仅会中止较旧的构建,还会中止较新的构建。在我们的 CI 设置中,我们决定如果已经安排了更新的构建,最好中止当前构建。