Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I reference the Jenkinsfile directory, with Pipeline?

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

ie. load script.groovy

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) 

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

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.

Jenkinsfile

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 (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)     } } 
like image 720
CodyK Avatar asked May 20 '16 18:05

CodyK


People also ask

What is dir () in Jenkins?

echo is used to print a message. The following code shows the echo method in addition to the ways you can use to call methods. dir is used to change the current working directory. Any codes that exist inside the dir block are executed within that directory. pwd is used to return the current working directory.

How do you write Jenkinsfile for pipeline?

To create a simple pipeline from the Jenkins interface, perform the following steps: Click New Item on your Jenkins home page, enter a name for your (pipeline) job, select Pipeline, and click OK. In the Script text area of the configuration screen, enter your pipeline syntax.


2 Answers

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.

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

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

Will fail, resulting in:

java.io.IOException: java.io.FileNotFoundException: /Jenkins/workspace/Foo_Job@script/Bar.groovy (No such file or directory) 

This is because this path:

/Jenkins/workspace/Foo_Job@script/ 

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

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.

like image 88
Mig82 Avatar answered Oct 05 '22 01:10

Mig82


If deploy_esb.groovy file is stored in the same SCM as the Jenkinsfile you can do:

node {           def workspace = pwd()     load "${workspace}@script/esb_deploybar_pipeline/deploy_esb.groovy" } 
like image 28
Anton Shishkin Avatar answered Oct 05 '22 02:10

Anton Shishkin