Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-49522

[withCredentials] MissingPropertyException from shared library class

    Details

    • Similar Issues:

      Description

      I am instantiating an object from within my vars (custom step (testCredentials)) shared library.  I then execute a method (getRequiredPackages) on this instance that contains withCredentials step. A groovy.lang.MissingPropertyException is thrown on the withCredentials variable (see stack trace below)

      vars/testCredentials.groovy

      #!/usr/bin/env groovy
      import com.mycorp.deployment.classes.Source
      
      def call(body) {
          def config = [:]
          body.resolveStrategy = Closure.DELEGATE_FIRST
          body.delegate = config
          body()
      
          def sourceVersion = config.version
      
          timestamps {
              node() {
                  try {
                      stage('Test Credentials') {
                          Source buildToolsSource = new Source(steps, sourceVersion)
                          buildToolsSource.getRequiredPackages(steps)
                      }
                  } catch (e) {
                      steps.sh "echo 'Error (${e}) occurred marking the build as failure.'"
                      throw e
                  } finally {
                      steps.cleanWs()
                  }
              }
          }
      }
      

      Groovy class
      /src/com/mycorp/deployment/classes/Source.groovy

      #!/usr/bin/env groovy
      package com.mycorp.deployment.classes
      
      import org.jenkinsci.plugins.workflow.cps.DSL
      
      class Source implements Serializable {
          String version
      
          Source(DSL steps, version) {
              this.version = version
          }
      
          def getRequiredPackages(DSL steps) {
              steps.withCredentials([steps.string(credentialsId: 'git-oauth-token', variable: 'GIT_OAUTH_TOKEN')]) {
                  steps.sh(returnStdout: false,
                          script: "curl -L " +
                                  "-H 'Authorization: token ${GIT_OAUTH_TOKEN}' " +
                                  "https://api.github.com/repos/mycorp/myrepo/zipball/${this.version} " +
                                  "-o _packages/myrepo-${this.version}.zip " +
                                  "-vvv"
                  )
              }
          }
      }

       
      I'm getting the following run-time exception:

      groovy.lang.MissingPropertyException: No such property: GIT_OAUTH_TOKEN for class: com.magento.deployment.classes.Source
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:53)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:458)
      at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.getProperty(DefaultInvoker.java:34)
      at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)

      Trying to access the variable via env (${env.GIT_OAUTH_TOKEN}) produces the following error:

      groovy.lang.MissingPropertyException: No such property: env for class: com.magento.deployment.classes.SourceNew
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:53)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:458)
      at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.getProperty(DefaultInvoker.java:34)
      at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
      at com.magento.deployment.classes.SourceNew.getRequiredPackages

      Workaround

      When I execute the same method from an inline script (rather than a object instance) it works fine. The following modified files works:

      vars/testCredentials.groovy

      #!/usr/bin/env groovy
      import com.mycorp.deployment.classes.Source
      import com.mycorp.deployment.scripts.Utility
      
      def call(body) {
          def config = [:]
          body.resolveStrategy = Closure.DELEGATE_FIRST
          body.delegate = config
          body()
      
          def sourceVersion = config.version
      
          timestamps {
              node() {
                  try {
                      stage('Test Credentials') {
                          Source buildToolsSource = new Source(steps, sourceVersion)
                          //buildToolsSource.getRequiredPackages(steps)
                          new Utility().getRequiredPackages(steps, buildToolsSource)
                      }
                  } catch (e) {
                      steps.sh "echo 'Error (${e}) occurred marking the build as failure.'"
                      throw e
                  } finally {
                      steps.cleanWs()
                  }
              }
          }
      }
      

      Inline script
      /src/com/mycorp/deployment/scripts/Utility.groovy

      #!/usr/bin/env groovy
      package com.mycorp.deployment.scripts
      
      import org.jenkinsci.plugins.workflow.cps.DSL
      
      import com.mycorp.deployment.classes.Source
      
      def getRequiredPackages(DSL steps, Source) {
          steps.withCredentials([steps.string(credentialsId: 'git-oauth-token', variable: 'GIT_OAUTH_TOKEN')]) {
              steps.sh(returnStdout: false,
                      script: "curl -L " +
                              "-H 'Authorization: token ${GIT_OAUTH_TOKEN}' " +
                              "https://api.github.com/repos/mycorp/myrepo/zipball/${source.version} " +
                              "-o _packages/myrepo-${source.version}.zip " +
                              "-vvv"
              )
          }
      }
      return this

       
      I am attempting to create an abstract class with implementation details that other classes can extend. It is not ideal to have to implement this type of logic (withCredentials) in a separate inline scripts to workaround this issue.

      Tested with version:

      jenkins 2.60.3
      credentials binding plugin 1.13
      credentials plugin 2.1.16

        Attachments

          Activity

          Hide
          jglick Jesse Glick added a comment -

          User error, you would need to refer to script.env.PROP in this case.

          Anyway you should not attempt to access secrets via Groovy string interpolation this way. Leave them to be defined as environment variables, expanded by the shell or other external processes.

          Show
          jglick Jesse Glick added a comment - User error, you would need to refer to script.env.PROP in this case. Anyway you should not attempt to access secrets via Groovy string interpolation this way. Leave them to be defined as environment variables, expanded by the shell or other external processes.
          Hide
          abeeskau Ann Beeskau added a comment -

          Hi Jesse Glick- Thanks for the feedback!

          When I use script.env.PROP I get this error - groovy.lang.MissingPropertyException: No such property: script for class.

          Please advise.

          Show
          abeeskau Ann Beeskau added a comment - Hi Jesse Glick - Thanks for the feedback! When I use script.env.PROP I get this error - groovy.lang.MissingPropertyException: No such property: script for class . Please advise.
          Hide
          allan_burdajewicz Allan BURDAJEWICZ added a comment -

          Ann Beeskau If you need to access global variables like env, don't use the steps variable but the script itself (i.e. this):

          Source buildToolsSource = new Source(this, sourceVersion)
          
          Show
          allan_burdajewicz Allan BURDAJEWICZ added a comment - Ann Beeskau If you need to access global variables like env , don't use the steps variable but the script itself (i.e. this ): Source buildToolsSource = new Source( this , sourceVersion)

            People

            • Assignee:
              stephenconnolly Stephen Connolly
              Reporter:
              abeeskau Ann Beeskau
            • Votes:
              1 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: