Groovyファイルがあり、Jenkinsfileから実行したい。
すなわち。 load script.groovy
ただし、このファイルがJenkinsfileと同じディレクトリに保存されている場合、このファイルをどのように参照できるかわかりません。 gitからJenkinsfileをロードしています。 workspace@script
というフォルダーが作成されることに気付きました。これをワークスペースディレクトリに配置しません。フォルダーをハードコーディングすることはできましたが、これに関するルールは定かではなく、コードを再度チェックアウトするのは少し冗長なようです。
Java.io.FileNotFoundException: /opt/jenkins_home/jobs/my_job/workspace/script.groovy (No such file or directory)
デフォルトでは、workspace@script
の代わりにワークスペースからロードします
BuildFlowスクリプトをパイプライン(ワークフロー)スクリプトに変換しようとしています。しかし、私はそれを見つけており、コピーアンドペーストほど簡単ではありません。
ジェンキンスファイル
node {
//get parameters from Job
def builds = builds.tokenize(",")
def ip_address_node = ip_address_node.trim()
def port_node = port_node.trim()
def branch = branch.trim()
def workspace = pwd()
stage 'Checking out code from esb repository'
git branch: branch, url: 'ssh://git@giturl/integration_bus.git'
load '../workspace@script/esb_deploybar_pipeline/deploy_esb.groovy'
}
deploy_esb.groovy(これは古いビルドフローからのもので、パイプラインで実行しようとしています)
import groovy.transform.ToString
import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode
@ToString
class BarDeploy {
String barFile
String app
String integrationServer
}
//parse csv
def csvItemsApps = new HashSet<BarDeploy>();
def csvItemsLibs = new HashSet<BarDeploy>();
def deploymentMapFile = new File(workspace + "/ESB_Deployment_Map.csv")
def isFirstLine = true
stage 'Parsing ESB Deployment CSV'
deploymentMapFile.withReader { reader ->
while(line = reader.readLine()) {
if(isFirstLine)
{
isFirstLine = false
continue
}
csvLine = line.split(",")
app = csvLine[0]
intServer = csvLine[1]
def barDeploy = new BarDeploy()
barDeploy.app = app
barDeploy.integrationServer = intServer
csvItemsApps.add(barDeploy)
//get shared libs
if(csvLine.length > 2 && csvLine[2] != null)
{
def sharedLibs = csvLine[2].split(";")
sharedLibs.each { libString ->
if(!libString.isAllWhitespace())
{
def lib = new BarDeploy()
lib.app = libString
lib.integrationServer = intServer
csvItemsLibs.add(lib)
}
};
}
}
};
//get list of bar files to deploy from html and consolidate bar files to deploy with apps in csv
for (int i = 0; i < builds.size(); i+=3)
{
if(builds[i].equals("false"))
{
//Don't deploy bar if checkbox isn't selected
continue
}
foundInCSV = false
appToDeploy = builds[i + 1]
barFileToDeploy = builds[i + 2]
iterator = csvItemsApps.iterator()
while (iterator.hasNext())
{
barDeploy = iterator.next()
if(appToDeploy.equalsIgnoreCase(barDeploy.app))
{
barDeploy.barFile = barFileToDeploy
foundInCSV = true
}
}
iterator = csvItemsLibs.iterator()
while (iterator.hasNext())
{
barDeploy = iterator.next()
if(appToDeploy.equalsIgnoreCase(barDeploy.app))
{
barDeploy.barFile = barFileToDeploy
foundInCSV = true
}
}
if(foundInCSV == false)
{
throw new RuntimeException("App: " + appToDeploy + " not found in ESB_Deployment_Map.csv. Please add CSV Entry.")
}
}
//Do deploy, deploy shared libs first
deployCSVItemsInParallel(ip_address_node,port_node,branch,env_key,csvItemsLibs)
deployCSVItemsInParallel(ip_address_node,port_node,branch,env_key,csvItemsApps)
def deploy(ip_address_node,port_node,branch,deployItem,env_key)
{
def integrationServer = deployItem.integrationServer
def app = deployItem.app
def barFile = deployItem.barFile
if(barFile == null)
{
return;
}
println("Triggering Build -> ESB App = " + app + ", Branch = "
+ branch + ", Barfile: " + barFile + ", Integration Server = " + integrationServer + ", IP Address: " + ip_address_node
+ ", Port: " + port_node + ", Env_Key: " + env_key)
build_closure = { ->
build("esb_deploybar",
ip_address_node: ip_address_node, port_node: port_node,
integrationServer: integrationServer, branch: branch, app: app, barFile: barFile, env_key: env_key)
}
return build_closure
}
def deployCSVItemsInParallel(ip_address_node,port_node,branch,env_key,csvItems)
{
def build_closures = []
iterator = csvItems.iterator()
while (iterator.hasNext())
{
barDeploy = iterator.next()
def build_closure = deploy(ip_address_node,port_node,branch,barDeploy,env_key)
if(build_closure != null)
{
build_closures.add(build_closure)
}
}
if(build_closures?.size() > 0)
{
parallel(build_closures)
}
}
Deploy_esb.groovyファイルがJenkinsfileと同じSCMに保存されている場合、次のことができます。
node {
def workspace = pwd()
load "${workspace}@script/esb_deploybar_pipeline/deploy_esb.groovy"
}
誰も言及していないシナリオが1つあります。ジョブがmasterではなくJenkins agent/slaveで実行されることになっている場合に、Groovyスクリプトをロードする方法は次のとおりです。
マスターはSCMからJenkinsパイプラインプロジェクトをチェックアウトするものであるため、Groovyスクリプトはマスターのファイルシステムにのみあります。したがって、これは機能しますが:
node {
def workspace = pwd()
def Bar = load "${workspace}@script/Bar.groovy"
Bar.doSomething()
}
SCMからパイプラインを複製するノードは、Groovyスクリプトをロードしようとするノードと同じであるため、幸運な偶然です。ただし、実行する別のエージェントの名前を追加するだけです:
node("agent1"){
def workspace = pwd()
def Bar = load "${workspace}@script/Bar.groovy"
Bar.doSomething()
}
失敗します:
Java.io.IOException: Java.io.FileNotFoundException: /Jenkins/workspace/Foo_Job@script/Bar.groovy (No such file or directory)
これは、次のパスが原因です。
/Jenkins/workspace/Foo_Job@script/
マスタージェンキンスボックスにのみ存在します。 agent1を実行しているボックスにはありません。
したがって、この問題に直面している場合、マスターからgroovyスクリプトをグローバルに宣言された変数にロードして、エージェントがそれらを使用できるようにしてください:
def Bar
node {
def workspace = pwd()
if(isUnix()){
Bar = load "${workspace}@script/Bar.groovy"
}
else{
Bar = load("..\\workspace@script\\Bar.groovy")
}
}
node("agent1"){
Bar.doSomething()
}
注:ノード間でモジュールを渡すために使用される変数は、宣言する必要があります外部ノードブロック。
このscript.groovyファイルがJenkinsfileのようにプロジェクトのルートにある場合、gitからJenkinsfileと同じフォルダーに取得されます。したがって、使用しているコマンドは正常に機能するはずです。
エラーが発生していますか?その場合、詳細を入力してください。
編集:Jenkinsfileの内容を確認できるようになりました。groovyスクリプトが存在するintegration_busというgitプロジェクトをチェックアウトしていることがわかります。次のように、チェックアウトする場所を指定できます。
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'esb_deploy']], submoduleCfg: [], userRemoteConfigs: [[url: 'ssh://git@giturl/integration_bus.git']]])
あなたが持っているものとは対照的に
git branch: branch, url: 'ssh://git@giturl/integration_bus.git'
その後、次のようにesb_deployフォルダーのgroovyスクリプトを参照できるはずです。
load 'esb_deploy/esb_deploybar_pipeline/deploy_esb.groovy'
同じ問題があった。ワークスペースdirの下にスクリプトリポジトリのコピーを取得するための余分なクローン操作が発生したため、その中のgroovyファイルに確実にアクセスできます。
dir ('SCRIPTS_DIR') {
checkout scm
commonScripts = load 'subdir/Common.groovy' // no def, so script is global
}
Jenkinsfile
内のすべてのファイル操作は、現在のワークスペース(load
内でnode
を使用する場合のデフォルトのワークスペース)に関連していると仮定できます。
したがって、ターゲットファイル(たとえばdeploy_esb.groovy
)がSCMのfoo
フォルダー内にある場合、これは追加の構成なしで機能するはずです。
git branch: branch, url: 'ssh://git@giturl/integration_bus.git'
load 'foo/deploy_esb.groovy'
または、ロードするファイルがJenkinsfile
と同じリポジトリにある場合、これ:
checkout scm
load 'foo/deploy_esb.groovy'
これは動作するはずです
load "${WORKSPACE}/../${JOB_NAME}@script/esb_deploy/esb_deploybar_pipeline/deploy_esb.groovy"