2016-11-23 31 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