如何使用 Pipeline 引用 Jenkinsfile 目录? [英] How can I reference the Jenkinsfile directory, with Pipeline?

查看:82
本文介绍了如何使用 Pipeline 引用 Jenkinsfile 目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 groovy 文件,我想从 Jenkinsfile 运行.

I have a groovy file, I want to run from the Jenkinsfile.

即.加载 script.groovy

但是,如果该文件与 Jenkinsfile 存储在同一目录中,我不确定如何引用它.我正在从 git 加载 Jenkinsfile.我注意到它创建了一个名为 workspace@script 的文件夹.它不会将它放在工作区目录中.我可以对文件夹进行硬编码,但我不确定这方面的规则,再次签出代码似乎有点多余.

However, I am not sure how I can reference this file if it is stored in the same directory as the Jenkinsfile. I am loading the Jenkinsfile from git. I noticed it creates a folder called workspace@script. It does not place this in the workspace directory. I could hardcode the folder but I am not sure the rules on this and it seems a little redundant to check-out the code again.

java.io.FileNotFoundException: /opt/jenkins_home/jobs/my_job/workspace/script.groovy (No such file or directory)

默认情况下,它从工作区加载,而不是 workspace@script

By default it loads from workspace, instead of workspace@script

我正在尝试将 BuildFlow 脚本转换为管道(工作流)脚本.但我发现,它不像复制和粘贴那么容易.

I am trying to convert a a BuildFlow script to a Pipeline (Workflow) script. But I am finding, it is not as easy as a copy and paste.

詹金斯文件

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(这是来自旧的构建流程,试图在管道中运行)

deploy_esb.groovy (this is from old buildflow, trying to run in a pipeline)

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)
    }
}

推荐答案

有一个场景我没有看到任何人提到.当作业应该在 Jenkins agent/slave 上而不是 ma​​ster 上运行时,这是如何加载 Groovy 脚本的.

There's one scenario that I haven't seen anyone mention. Which is how to load the Groovy scripts when the job is supposed to run on a Jenkins agent/slave, rather than on the master.

由于 master 是从 SCM 签出 Jenkins 管道项目的那个,Groovy 脚本只能在 master 的文件系统中找到.所以虽然这会起作用:

Since the master is the one that checks out the Jenkins pipeline project from SCM, the Groovy scripts are only found in the master's file system. So while this will work:

node {       
    def workspace = pwd() 
    def Bar = load "${workspace}@script/Bar.groovy"
    Bar.doSomething()
}

这只是一个快乐的巧合,因为从 SCM 克隆管道的节点与尝试在其中加载 groovy 脚本的节点相同.但是,只需添加要在其上执行的不同代理的名称:

It's only a happy coincidence because the node that clones the pipeline from SCM is the same one that attempts to load the groovy scripts in it. However, just adding the name of a different agent to execute on:

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/

仅存在于主 Jenkins 盒子上.不在运行 agent1 的框中.

Only exists on the master Jenkins box. Not in the box running agent1.

因此,如果您遇到此问题,请确保将 groovy 脚本从 master 加载到全局声明的变量中,以便代理可以使用它们:

So if you're facing this issue, make sure to load the groovy scripts from the master into globally declared variables, so the agent can then use them:

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()
}

注意:用于在节点之间传递模块的变量必须在节点块的外部声明.

Note: The variable used to pass the module between nodes must be declared outside the node blocks.

这篇关于如何使用 Pipeline 引用 Jenkinsfile 目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆