kak*_*ty3 31 git groovy jenkins multibranch-pipeline
我使用Jenkins和Multibranch Pipeline.我为每个活跃的git分支都有工作.通过推入git存储库触发新构建.我想要的是在新分支出现在同一分支中时中止当前分支中的运行构建.
例如:我提交并推送分支feature1
.然后BUILD_1
开始在詹金斯.我做了另一个提交,并feature1
在BUILD_1
仍在运行时推送到分支.我希望BUILD_1
被中止并开始BUILD_2
.
我试图使用stage concurrency=x
选项和stage-lock-milestone功能,但没有设法解决我的问题.
此外,我已经阅读了这个线程停止Jenkins工作,以防新的一个启动,但我的问题没有解决方案.
你知道任何解决方案吗?
小智 26
从 Jenkins 工作流作业插件版本 2.42 中,您可以简单地执行以下操作
// as a step in a scripted pipeline
properties([disableConcurrentBuilds(abortPrevious: true)])
// as a directive in a declarative pipeline
options { disableConcurrentBuilds abortPrevious: true }
Run Code Online (Sandbox Code Playgroud)
在评论中找到解决方案 https://issues.jenkins.io/browse/JENKINS-43353
dag*_*ett 20
为您的项目启用作业并行运行 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().iterator().each{ 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 = { "interrupted by build #${build.getId()}" as String } as CauseOfInterruption
exec.interrupt(Result.ABORTED, cause)
}
}
Run Code Online (Sandbox Code Playgroud)
在中断的工作中会有一个日志:
Build was aborted
interrupted by build #12
Finished: ABORTED
Run Code Online (Sandbox Code Playgroud)
mid*_*idN 16
如果有人在Jenkins Pipeline Multibranch中需要它,可以在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}")
}
}
}
Run Code Online (Sandbox Code Playgroud)
Bra*_*ato 15
借助Jenkins脚本安全性,此处的许多解决方案都变得困难,因为它们使用的是非白名单方法。
在Jenkinsfile的开始处有了这些里程碑式的步骤,这对我有用:
def buildNumber = env.BUILD_NUMBER as int
if (buildNumber > 1) milestone(buildNumber - 1)
milestone(buildNumber)
Run Code Online (Sandbox Code Playgroud)
结果将是:
通过在全局共享库中使用以下脚本来实现它:
import hudson.model.Result
import jenkins.model.CauseOfInterruption.UserInterruption
def killOldBuilds() {
while(currentBuild.rawBuild.getPreviousBuildInProgress() != null) {
currentBuild.rawBuild.getPreviousBuildInProgress().doKill()
}
}
Run Code Online (Sandbox Code Playgroud)
并在我的管道中调用它:
@Library('librayName')
def pipeline = new killOldBuilds()
[...]
stage 'purge'
pipeline.killOldBuilds()
Run Code Online (Sandbox Code Playgroud)
编辑:根据您想要杀死oldBuild的强度,您可以使用doStop(),doTerm()或doKill()!
基于@ C4stor的想法,我制作了此改进的版本...从@daggett的版本中可以更容易阅读
import hudson.model.Result
import hudson.model.Run
import jenkins.model.CauseOfInterruption.UserInterruption
def abortPreviousBuilds() {
Run previousBuild = currentBuild.rawBuild.getPreviousBuildInProgress()
while (previousBuild != null) {
if (previousBuild.isInProgress()) {
def executor = previousBuild.getExecutor()
if (executor != null) {
echo ">> Aborting older build #${previousBuild.number}"
executor.interrupt(Result.ABORTED, new UserInterruption(
"Aborted by newer build #${currentBuild.number}"
))
}
}
previousBuild = previousBuild.getPreviousBuildInProgress()
}
}
Run Code Online (Sandbox Code Playgroud)
添加到 Brandon Squizzato 的答案。如果有时跳过构建,上述里程碑机制将失败。在 for 循环中设置较旧的里程碑可以解决这个问题。
还要确保您的选项中没有disableConcurrentBuilds。否则管道不会到达里程碑步骤,这将不起作用。
def buildNumber = env.BUILD_NUMBER as int
for (int i = 1; i < buildNumber; i++)
{
milestone(i)
}
milestone(buildNumber)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15974 次 |
最近记录: |