7

Despite following this answer and others, I am unable to successfully use a local groovy file in my Jenkinsfile (both are in the same repository).

def deployer = null
...
...
...
pipeline {
   agent {
      label 'cf_slave'
   }

   options {
      skipDefaultCheckout()
      disableConcurrentBuilds()
   }

   stages {
      stage ("Checkout SCM") {
         steps {
            checkout scm
         }
      }
      ...
      ...
      ...
      stage ("Publish CF app") {
          steps {
              script {
                  STAGE_NAME = "Publish CF app"
                  deployer = fileLoader.load ('deployer')

                  withCredentials(...) {   
                      if (BRANCH_NAME == "develop") {
                          ...
                          ...
                          ...
                      } else {
                          deployer.generateManifest()
                      }
                  }
              }
          }
      }
      ...
      ...
  }

deployer.groovy:

#!/usr/bin/env groovy

def generateManifest() {
   sh "..."
   echo "..."
}

In the console log (stack):

[Pipeline] stage
[Pipeline] { (Publish CF app)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
before loading groovy file
[Pipeline] echo
Loading from deployer.groovy
[Pipeline] load
[Pipeline] // load
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage

Update:

It seems the problem was not with loading the file but rather with the contents of the file, where I execute the following which apparently does not play well:

sh "node $(pwd)/config/mustacher manifest.template.yml config/environments/common.json config/environments/someFile.json"
echo "..."

When only the echo is there, this is the stack.

So not the sh "node ..." nor the echo work. Even changing it just to sh "pwd" fails as well. What could it be? the syntax in the file? the way it is called in the pipeline?

If I will make the same node call in the pipeline (for example in the withCredentials if statement, it works.

Community
  • 1
  • 1
Idan Adar
  • 44,156
  • 13
  • 50
  • 89
  • tried with single quotes? ie: `sh 'node $(pwd)/config/mustacher manifest.template.yml config/environments/common.json config/environments/someFile.json'` – tim_yates Mar 14 '17 at 22:14
  • @tim_yates, I will try this, but what about it also failing with a simple `echo "test"`? Update: same as before... "Cannot invoke method generateManifest() on null object" – Idan Adar Mar 14 '17 at 22:21
  • Try replacing the `echo` with `println` --on the theory that the external file needs to be raw Groovy, not Jenkins DSL. – MarkHu Mar 14 '17 at 23:51
  • @MarkHu, same error (null object). At this point I will attempt a suggestion to load the file via a shared library instead of fileLoader. Lets see if it makes a difference. – Idan Adar Mar 15 '17 at 05:32
  • ... which did not help either. – Idan Adar Mar 15 '17 at 15:26
  • For Declarative Pipeline, you generally don't need the `checkout scm` stage - it is done automatically for you by the `agent` directive. – BitwiseMan Mar 16 '17 at 17:03
  • Right, but I did add disableDefaultCheckout. Does it still do it in this case? I wanted to have it done not-automatically – Idan Adar Mar 16 '17 at 17:04
  • Try adding a `return this` to the bottom of your `deployer.groovy` file, or just a `this` so that the script object is returned. Also, change your `load` step to use full name of Groovy file like `load('deployer.groovy')`. – mkobit Mar 17 '17 at 02:22

1 Answers1

3

Add a return this to the bottom of the deployer.groovy file, and then change you load step to use relative path and extension to groovy file like load('deployer.groovy').

The return this is documented on jenkins.io:

Takes a filename in the workspace and runs it as Groovy source text. The loaded file can contain statements at top level or just load and run a closure. For example:

def pipeline
node('slave') {
    pipeline = load 'pipeline.groovy'
    pipeline.functionA()
}
pipeline.functionB()

pipeline.groovy

def pipelineMethod() {
  ...code
}
    
return this

Where pipeline.groovy defines functionA and functionB functions (among others) before ending with return this

USer22999299
  • 5,284
  • 9
  • 46
  • 78
mkobit
  • 43,979
  • 12
  • 156
  • 150
  • Thank you. If you will note in my question, I have added at the bottom an update where I am able to load the file, but executing code in it fails, such as even an `echo` or a `node` call. The `return` is supposed to resolve this? – Idan Adar Mar 25 '17 at 18:39
  • @IdanAdar I _believe_ it should. I think I ran into this same issue, and adding a `return this` to the end of the file fixed it because of however Jenkins compiles it. – mkobit Mar 25 '17 at 18:44