You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

当相同参数的Jenkins构建运行时,阻止新构建执行及入队

解决Pipeline项目中相同参数构建重复入队的问题

针对你遇到的问题,这里提供几个适用于Jenkins Pipeline的可行方案:

方案1:使用Pipeline脚本直接检查运行中构建

通过Jenkins内置API在Pipeline启动时检查当前项目是否有相同参数的构建正在运行,如果有则直接终止当前任务,避免进入队列。

pipeline {
    agent any
    parameters {
        string(name: 'BUILD_PARAM', description: '自定义构建参数')
    }
    stages {
        stage('校验重复构建') {
            steps {
                script {
                    // 获取当前项目下所有正在运行的构建(排除自身)
                    def runningBuilds = Jenkins.instance.getItemByFullName(env.JOB_NAME)
                        .getBuilds()
                        .findAll { it.isBuilding() && it.number != currentBuild.number }
                    
                    // 匹配相同参数的构建
                    def duplicateExists = runningBuilds.any { build ->
                        build.buildVariables.BUILD_PARAM == params.BUILD_PARAM
                    }

                    if (duplicateExists) {
                        error "检测到参数[${params.BUILD_PARAM}]的构建正在运行,终止当前任务"
                    }
                }
            }
        }
        stage('执行构建逻辑') {
            steps {
                echo "开始执行构建,参数:${params.BUILD_PARAM}"
                // 此处替换为你的实际构建步骤
            }
        }
    }
}

注意:该方案需要在Jenkins的「脚本安全」页面批准相关API调用(如Jenkins.instance.getItemByFullName等),需管理员操作。

方案2:使用Lockable Resources插件实现锁拦截

借助Lockable Resources插件,为每个参数值创建唯一锁资源,当锁被占用时直接跳过并终止任务,无需等待队列。

  1. 先在Jenkins全局配置中开启「Lockable Resources」插件,无需提前创建资源(插件支持动态生成)
  2. 在Pipeline中添加锁校验逻辑:
pipeline {
    agent any
    parameters {
        string(name: 'BUILD_PARAM', description: '自定义构建参数')
    }
    stages {
        stage('抢占参数锁') {
            steps {
                // 尝试获取对应参数的锁,若被占用则直接跳过
                lock(resource: "build-lock-${params.BUILD_PARAM}", skipIfLocked: true) {
                    echo "成功获取锁,进入构建流程"
                }
            }
            post {
                // 若锁抢占失败(步骤未执行),则终止任务
                unsuccessful {
                    error "参数[${params.BUILD_PARAM}]的构建正在运行,当前任务终止"
                }
            }
        }
        stage('执行构建逻辑') {
            steps {
                // 持有锁执行构建,避免并发
                lock(resource: "build-lock-${params.BUILD_PARAM}") {
                    echo "执行构建,参数:${params.BUILD_PARAM}"
                    // 此处替换为你的实际构建步骤
                }
            }
        }
    }
}

该方案无需启用不安全脚本,兼容性更强,适合大多数场景。

方案3:全局队列拦截脚本(管理员级)

通过全局队列监听器脚本,在任务进入队列前直接拦截相同参数的重复任务,从根源阻止入队。

在Jenkins脚本控制台(需管理员权限)执行以下脚本:

import hudson.model.*
import jenkins.model.Jenkins

// 移除已存在的监听器(避免重复添加)
Jenkins.instance.queue.queueItemListeners.each { listener ->
    if (listener.class.simpleName == 'DuplicateBuildBlocker') {
        Jenkins.instance.queue.removeQueueItemListener(listener)
    }
}

// 创建自定义队列监听器
def blocker = new QueueItemListener() {
    @Override
    void onEnterQueue(Queue.Item item) {
        // 仅处理Pipeline任务
        if (item.task instanceof org.jenkinsci.plugins.workflow.job.WorkflowJob) {
            def job = item.task as org.jenkinsci.plugins.workflow.job.WorkflowJob
            def incomingParams = item.parameters?.collectEntries { [(it.name): it.value] } ?: [:]
            
            // 检查当前项目是否有相同参数的运行中构建
            def runningDuplicates = job.builds.findAll { build ->
                build.isBuilding() && build.buildVariables == incomingParams
            }

            if (!runningDuplicates.isEmpty()) {
                item.doCancel()
                println "拦截重复任务:${job.fullName},参数:${incomingParams},已存在运行中同参数构建"
            }
        }
    }
}

// 为监听器设置名称,方便后续管理
blocker.metaClass.simpleName = 'DuplicateBuildBlocker'
Jenkins.instance.queue.addQueueItemListener(blocker)
Jenkins.instance.save()

该脚本会全局生效,所有Pipeline项目的重复参数构建都会被直接拦截,无需逐个修改任务配置。

内容的提问来源于stack exchange,提问作者PSfan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 19:50:19