2016-11-23 32 views
13

我使用詹金斯和多分支管道。我为每个活跃的git分支都有一份工作。 新构建是通过推入git存储库触发的。我想要的是在当前分支中中止正在运行的构建,如果新分支出现在同一分支中。詹金斯 - 中止运行构建,如果新的启动

例如:我承诺并推送到分支feature1。然后BUILD_1开始在詹金斯。我做了另一次提交并推送到分支feature1BUILD_1仍在运行。我想要BUILD_1被中止并开始BUILD_2

我试着用stage concurrency=x选项和stage-lock-milestone功能,但是没有设法解决我的问题。

此外,我已阅读此线程Stopping Jenkins job in case newer one is started,但没有解决我的问题。

你知道这个解决方案吗?

+1

我们让当前的作业完成,而且我们有些情况下,如果我们从来没有(如提到的问题中所建议的)那样让队列中的工作得到清理。不喜欢中止已经开始工作的想法。 – MaTePe

+1

@MaTePe对于诸如自动测试git分支的情况,如果分支已更新,那么在分支上完成测试通常没什么好处,因为更新也需要测试。显而易见的解决方案是中止早期的测试。清理可能仍需要完成,但是资源不会浪费,从而完成不必要的测试。 – bschlueter

回答

7

实现与Execute concurrent builds if necessary

使用execute system groovy script作为第一生成步骤为您的项目工作并行运行:

import hudson.model.Result 
import jenkins.model.CauseOfInterruption 

//iterate through current project runs 
build.getProject()._getRuns().each{id,run-> 
    def exec = run.getExecutor() 
    //if the run is not a current build and it has executor (running) then stop it 
    if(run!=build && exec!=null){ 
    //prepare the cause of interruption 
    def cause = new CauseOfInterruption(){ 
     public String getShortDescription(){ 
     return "interrupted by build #${build.getId()}" 
     } 
    } 
    exec.interrupt(Result.ABORTED, cause) 
    } 
} 

,并在中断的作业会有一个日志:

Build was aborted 
interrupted by build #12 
Finished: ABORTED 
+0

听起来非常好!目前正在寻找一种将其移植到管道文件scm commits的方法 – C4stor

+0

“系统groovy脚本”在Jenkins主JVM中运行,这就是为什么它可以访问jenkins中的所有内容。但是,管道运行在分叉的JVM上,运行构建的从站上 - 我没有在文档中找到它,但很确定。 – daggett

+0

我发现这个:https://stackoverflow.com/questions/33531868/jenkins-workflow-build-information /我现在没有管道尝试,但你可以尝试使用这个表达式来获取当前的管道构建:'def build = currentBuild.rawBuild' – daggett

2

通过在全局共享库中具有以下脚本来实现它的工作:

import hudson.model.Result 
import jenkins.model.CauseOfInterruption.UserInterruption 

def killOldBuilds() { 
    while(currentBuild.rawBuild.getPreviousBuildInProgress() != null) { 
    currentBuild.rawBuild.getPreviousBuildInProgress().doKill() 
    } 
} 

,把它在我的流水线:

@Library('librayName') 
def pipeline = new killOldBuilds() 
[...] 
stage 'purge' 
pipeline.killOldBuilds() 
+0

有什么方法可以发送消息给已终止的版本吗?它发送了这个硬杀信号但没有登录谁杀死它。 –

+0

我不知道,我们现在生活在这个完整的灰色线条中,对我们来说已经足够了^^' – C4stor

4

如果有人需要它詹金斯管道多枝,它可以在Jenkinsfile做过这样的:

def abortPreviousRunningBuilds() { 
    def hi = Hudson.instance 
    def pname = env.JOB_NAME.split('/')[0] 

    hi.getItem(pname).getItem(env.JOB_BASE_NAME).getBuilds().each{ build -> 
    def exec = build.getExecutor() 

    if (build.number != currentBuild.number && exec != null) { 
     exec.interrupt(
     Result.ABORTED, 
     new CauseOfInterruption.UserInterruption(
      "Aborted by #${currentBuild.number}" 
     ) 
    ) 
     println("Aborted previous running build #${build.number}") 
    } else { 
     println("Build is not running or is current build, not aborting - #${build.number}") 
    } 
    } 
} 
+0

也许值得检查一下构建号是否低于当前值。否则,你可能会杀死更新的版本。 – danielMitD