簡體   English   中英

Jenkins - 在單個作業中多次加載 groovy 腳本,但具有不同的階段

[英]Jenkins - load groovy script multiple times in a single job but with different stages

我有一個 Jenkins 管道,它可以在腳本管道中構建和部署任務。 管道維護在中央存儲庫中。 對於每個部署階段,它都會等待用戶輸入,等待時間可能長達數天。 在等待期間,如果管道腳本發生更改,我希望在部署批准(用戶輸入)后加載最新的腳本。

腳本的第一個load步驟工作正常,當我再次嘗試加載時,出現以下錯誤。 GroovyClassLoader 似乎拋出了這個錯誤。

我試圖通過currentBuild.rawBuild.getExecution().loadedScripts loadedScripts的腳本,但這沒有幫助。 有沒有辦法實現我在每個階段重新加載腳本的用例? 任何指針都會有所幫助。

java.lang.LinkageError: loader org.jenkinsci.plugins.workflow.cps.CpsGroovyShell$CleanGroovyClassLoader @8d141543 attempted duplicate class definition for Script1. (Script1 is in unnamed module of loader org.jenkinsci.plugins.workflow.cps.CpsGroovyShell$CleanGroovyClassLoader

// pipeline.groovy
def config 
node('agent') {
    stage('build') {
        config = loadScripts()
        echo 'perform some tasks'
    }
    stage('deploy-dev') {
        input message: 'approve'
        config = loadScripts()
        echo 'perform some tasks'
    }
    stage('deploy-sit') {
        input message: 'approve'
        config = loadScripts()
        echo 'perform some tasks'
    }
}

def loadScripts() {
    checkout scm
    config = load 'somepath/external.groovy'
    return config
}

// somepath/external.groovy

class JobConfig {
    def someDataVar1
    def someDataVar2
}

def sayHello() {
    println 'hello'
}

return this

在此處輸入圖像描述

也許我不完全理解你的問題(在這種情況下,我道歉),但我不明白為什么你的 'somepath/external.groovy' 不是一個簡單的 groovy 庫,(像這樣: http://rtyler .github.io/jenkins.io/doc/book/pipeline/shared-libraries/ ),在管道開始時聲明為已使用,然后您的 JobConfig 和 sayHello 可以根據需要多次調用並具有不同的行為基於一些參數 - 比如舞台名稱。

簡短的回答是共享庫旨在解決此類問題。 如果這不是一個選項,那么您的腳本文件的一些重組可能會解決這個問題作為一種解決方法。

您收到的錯誤表明您正在重新定義一個不允許的同名類。 由於您第二次加載相同的腳本,這與兩次加載同名的類基本相同。

選項 1 是將您的管道拆分為多個管道,這些管道都攝取相同的配置。 對於等待用戶輸入繼續的長時間運行的管道,我個人從來沒有好運過。 相反,您可以將您的管道拆分為一個“構建”管道,該管道基本上加載您的配置並運行構建步驟,然后當您准備好部署時,您運行一個加載配置的“deploy-dev”管道,然后運行部署開發步驟。 然后是另一個對“deploy-sit”執行相同操作的管道。

// pipeline-build.groovy
def config 
node('agent') {
    stage('build') {
        config = loadScripts()
        echo 'perform some tasks'
    }
}

def loadScripts() {
    checkout scm
    config = load 'somepath/external.groovy'
    return config
}

// pipeline-deploy-dev.groovy
def config 
node('agent') {
    stage('deploy-dev') {
        input message: 'approve'
        config = loadScripts()
        echo 'perform some tasks'
    }
}

def loadScripts() {
    checkout scm
    config = load 'somepath/external.groovy'
    return config
}

// pipeline-deploy-sit.groovy
def config 
node('agent') {
    stage('deploy-sit') {
        input message: 'approve'
        config = loadScripts()
        echo 'perform some tasks'
    }
}

def loadScripts() {
    checkout scm
    config = load 'somepath/external.groovy'
    return config
}

選項 2 是將腳本拆分為多個腳本。 一個腳本將包含類定義,並且只會在管道頂部加載一次。 然后其他腳本將包含每個管道步驟將使用的其他每個方法。 這看起來像這樣:

// pipeline.groovy
def config 
node('agent') {
    loadScript("somepath/JobConfig.groovy")
    stage('build') {
        config = loadScript("somepath/Build.groovy")
        echo 'perform some tasks'
    }
    stage('deploy-dev') {
        input message: 'approve'
        config = loadScript("somepath/DeployDev.groovy")
        echo 'perform some tasks'
    }
    stage('deploy-sit') {
        input message: 'approve'
        config = loadScript("somepath/DeploySit.groovy")
        echo 'perform some tasks'
    }
}

def loadScript(def script) {
    checkout scm
    config = load script
    return config
}

然后,當您加載后面的腳本時,它們可以更新並加載,而無需重新定義初始類定義或重新定義單個方法(我想這也是一個問題)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM