8

Can anyone explain why I get the following errors, and what can be a possible solution for them?

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: WorkflowScript: 20: Expected a symbol @ line 20, column 4. environment {

WorkflowScript: 17: Undefined section "error" @ line 17, column 1.
pipeline {

The code in the Jenkinsfile is as follows:

#!groovy

def application, manifest, git, environment, artifactory, sonar

fileLoader.withGit('git@<reducted>', 'v1', 'ssh-key-credential-id-number') {
   application = fileLoader.load('<reducted>');
   manifest = fileLoader.load('<reducted>');
   git = fileLoader.load('<reducted>');
   environment = fileLoader.load('<reducted>');
}

pipeline {
   agent { label 'cf_slave' }

   environment {
      def projectName = null
      def githubOrg = null
      def gitCommit = null
   }

   options {
      skipDefaultCheckout()
   }

   stages {
      stage ("Checkout SCM") {
         steps {
            checkout scm

            script {
               projectName = git.getGitRepositoryName()
               githubOrg = git.getGitOrgName()
               gitCommit = manifest.getGitCommit()
            }
         }
      }

      stage ("Unit tests") {
         steps {
            sh "./node_modules/.bin/mocha --reporter mocha-junit-reporter --reporter-options mochaFile=./testResults/results.xml"
            junit allowEmptyResults: true, testResults: 'testResults/results.xml'
         }
      }

      //stage ("SonarQube analysis") {
      //...
      //}

      // stage("Simple deploy") {
      //    steps {
      //       // Login
      //       sh "cf api <reducted>"
      //       sh "cf login -u <reducted> -p <....>"
      //       
      //       // Deploy
      //       sh "cf push" 
      //    }
      // }
   }

   post {
      // always {

      //  }
      success {
         sh "echo 'Pipeline reached the finish line!'"

         // Notify in Slack
         slackSend color: 'yellow', message: "Pipeline operation completed successfully. Check <reducted>"
      }
      failure {
         sh "echo 'Pipeline failed'"
         // Notify in Slack
         slackSend color: 'red', message: "Pipeline operation failed!"

         //Clean the execution workspace
         //deleteDir()
      }
      unstable {
         sh "echo 'Pipeline unstable :-('"
      }
      // changed {
      //    sh "echo 'Pipeline was previously failing but is now successful.'"
      // }
   }
}
Idan Adar
  • 44,156
  • 13
  • 50
  • 89

2 Answers2

9

Your Pipeline is mostly fine — adding Scripted Pipeline elements before the Declarative pipeline block is generally not a problem.

However, at the very start, you're defining an variable called environment (and git), which are basically overriding the elements declared by the various Pipeline plugins.

i.e. When you attempt to do pipeline { environment { … } }, the environment is referring to your variable declaration, which causes things to go wrong.

Rename those two variables, and you'll fix the first error message.

To fix the second error message, remove the attempts to declare variables from the environment block — this block is only intended for exporting environment variables for use during the build steps, e.g.:

environment {
    FOO = 'bar'
    BAR = 'baz'
}

The script block you have will work fine without these declarations. Alternatively, you can move those variable declarations to the top level of your script.

Christopher Orr
  • 110,418
  • 27
  • 198
  • 193
  • Thanks @christopher Orr. Can I pick your brain also for this question regarding Jenkins? http://stackoverflow.com/questions/42664863/how-to-merge-a-successful-build-of-a-pull-request-using-a-jenkinsfile – Idan Adar Mar 08 '17 at 15:10
  • Ooo nice, didn't know this one! – Jon S Mar 08 '17 at 15:53
1

If you're using declarative pipeline (which you are, e.g. the outer pipeline step), then you may only declare the pipeline on the outer layer, e.g. you can't have variable and function definitions. This is the downside of using declarative pipeline.

More info here

As I see it you can solve this the following ways:

  1. Use scripted pipeline instead
  2. Move the code at the beginning to a global pipeline library (Might be tricky to solve variable scoping if a value is used in several places, but it should be doable.
  3. Move the code at the beginning to an script step inside the pipeline and store the values as described here.
Community
  • 1
  • 1
Jon S
  • 15,846
  • 4
  • 44
  • 45
  • In other words, I need to change this to a scripted pipeline. It's not clear which of the two should one follow... or which is the recommended. – Idan Adar Mar 07 '17 at 18:27
  • If I do switch to a scripted pipeline, how can I still have the stage "labels" in the pipeline view, specifically for `checksout scm`. – Idan Adar Mar 07 '17 at 18:27
  • Apologies for the many comments. Let me get back to you with another variation of the script, soon. – Idan Adar Mar 07 '17 at 18:35
  • 1
    Instead of loading all those groovy files, you could use a shared library. That is what I do. See here: https://jenkins.io/doc/book/pipeline/shared-libraries/ – macg33zr Mar 07 '17 at 18:37
  • Possibly. I'll look into that once the Jenkinsfile actually works... :-) – Idan Adar Mar 07 '17 at 18:41
  • @Jons S, see this scripted variation of the file: http://pastebin.com/B3R4qFuD. With it, I get: `java.lang.NoSuchMethodError: No such DSL method 'Checkout SCM' found among steps [ ........`. – Idan Adar Mar 07 '17 at 18:42
  • 1
    It's `stage ("Checkout scm") {...}`, e.g. parenthesis and quotes. I've also updated my answer with possible solutions. Long term I would suggest number two, but number 1 or 2 should work. – Jon S Mar 07 '17 at 18:44
  • Well that was obvious... this is probably obvious, too? `No such DSL method 'post' found among steps`. – Idan Adar Mar 07 '17 at 19:03
  • I guess this doesn't exist either in scripted pipelines? If it doesn't, how does one catch a failure event? – Idan Adar Mar 07 '17 at 19:24
  • 1
    No it doesn't, you could use a try catch, put the success part at the end of the try clause and then the fail in the failure part in the catch clause, and then exit 1 or throw the exception onwards in the catch clause... – Jon S Mar 07 '17 at 19:25