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

Declarative: publishHTML syntax does not work in post block

    XMLWordPrintable

    Details

    • Similar Issues:

      Description

      Converted this Scripted Pipeline:

      /* Only keep the 10 most recent builds. */
      properties([[$class: 'BuildDiscarderProperty',
                      strategy: [$class: 'LogRotator', numToKeepStr: '10']]])
      
      stage ('Build') {
      
        node {
          // Checkout
          checkout scm
      
          // install required bundles
          sh 'bundle install'
      
          // build and run tests with coverage
          sh 'bundle exec rake build spec'
      
          // Archive the built artifacts
          archive (includes: 'pkg/*.gem')
      
          // publish html
          publishHTML ([
              allowMissing: false,
              alwaysLinkToLastBuild: false,
              keepAll: true,
              reportDir: 'coverage',
              reportFiles: 'index.html',
              reportName: "RCov Report"
            ])
      
        }
      }
      

      To this Declarative:

      pipeline {
          agent any
          options {
              buildDiscarder(logRotator(numToKeepStr:'10'))
          }
          stages {
              stage ('Build') {
                  steps {
                      // install required bundles
                      sh 'bundle install'
      
                      // build and run tests with coverage
                      sh 'bundle exec rake build spec'
                  }
              }
          }
          post {
              success {
                  // Archive the built artifacts
                  archive includes: 'pkg/*.gem'
              }
      
              always {
                  // publish html
                  publishHTML ([
                      allowMissing: false,
                      alwaysLinkToLastBuild: false,
                      keepAll: true,
                      reportDir: 'coverage',
                      reportFiles: 'index.html',
                      reportName: "RCov Report"
                    ])
              }
          }
      }
      

      Fails with this output:

      First time build. Skipping changelog.
      org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
      WorkflowScript: 28: Invalid parameter "allowMissing", did you mean "target"? @ line 28, column 17.
                         allowMissing: false,
                         ^
      
      WorkflowScript: 29: Invalid parameter "alwaysLinkToLastBuild", did you mean "target"? @ line 29, column 17.
                         alwaysLinkToLastBuild: false,
                         ^
      
      WorkflowScript: 30: Invalid parameter "keepAll", did you mean "target"? @ line 30, column 17.
                         keepAll: true,
                         ^
      
      WorkflowScript: 31: Invalid parameter "reportDir", did you mean "target"? @ line 31, column 17.
                         reportDir: 'coverage',
                         ^
      
      WorkflowScript: 32: Invalid parameter "reportFiles", did you mean "target"? @ line 32, column 17.
                         reportFiles: 'index.html',
                         ^
      
      WorkflowScript: 33: Invalid parameter "reportName", did you mean "target"? @ line 33, column 17.
                         reportName: "RCov Report"
                         ^
      
      WorkflowScript: 27: Missing required parameter: "target" @ line 27, column 13.
                     publishHTML ([
                     ^
      
      7 errors
      

      Changed Declarative to this and it succeeds (

      {target:}

      is not needed in Scripted):

      pipeline {
          agent any
          options {
              buildDiscarder(logRotator(numToKeepStr:'10'))
          }
          stages {
              stage ('Build') {
                  steps {
                      // install required bundles
                      sh 'bundle install'
      
                      // build and run tests with coverage
                      sh 'bundle exec rake build spec'
                  }
              }
          }
          post {
              success {
                  // Archive the built artifacts
                  archive includes: 'pkg/*.gem'
              }
      
              always {
                  // publish html
                  publishHTML target:[
                      allowMissing: false,
                      alwaysLinkToLastBuild: false,
                      keepAll: true,
                      reportDir: 'coverage',
                      reportFiles: 'index.html',
                      reportName: "RCov Report"
                    ]
              }
          }
      }
      

        Attachments

          Issue Links

            Activity

            Hide
            abayer Andrew Bayer added a comment -

            Your final example looks the same as the previous one?

            Show
            abayer Andrew Bayer added a comment - Your final example looks the same as the previous one?
            Hide
            bitwiseman Liam Newman added a comment -

            Fixed.

            Show
            bitwiseman Liam Newman added a comment - Fixed.
            Hide
            abayer Andrew Bayer added a comment -

            So this is a combination of magic and validation not working ideally. I'm not honestly entirely sure how this works in Scripted Pipeline, but the map of arguments gets automatically transformed into an HtmlPublisherTarget instance, which is what publishHTML expects as an argument. Declarative's validation doesn't have that ability to say "Oh, you've got a Map passed in - let's see if that can become the class the step expects as its argument" - I'll see if that's something we can add, but no promises.

            Show
            abayer Andrew Bayer added a comment - So this is a combination of magic and validation not working ideally. I'm not honestly entirely sure how this works in Scripted Pipeline, but the map of arguments gets automatically transformed into an HtmlPublisherTarget instance, which is what publishHTML expects as an argument. Declarative's validation doesn't have that ability to say "Oh, you've got a Map passed in - let's see if that can become the class the step expects as its argument" - I'll see if that's something we can add, but no promises.
            Hide
            bitwiseman Liam Newman added a comment -

            Andrew Bayer It is somewhat important that what worked in Scripted continues to work in Declarative.

            It looks like you fixed this before for JENKINS-29711 in Scripted.

            Show
            bitwiseman Liam Newman added a comment - Andrew Bayer It is somewhat important that what worked in Scripted continues to work in Declarative. It looks like you fixed this before for JENKINS-29711 in Scripted.
            Hide
            abayer Andrew Bayer added a comment -

            Moving this to htmlpublisher-plugin, since the actual problem is its @DataBoundConstructor.

            Show
            abayer Andrew Bayer added a comment - Moving this to htmlpublisher-plugin , since the actual problem is its @DataBoundConstructor .
            Hide
            abayer Andrew Bayer added a comment -

            Changed my mind! This can and should be addressed in Declarative - we should look to see if there's a sole required parameter that takes a map, and if so, translate accordingly.

            Show
            abayer Andrew Bayer added a comment - Changed my mind! This can and should be addressed in Declarative - we should look to see if there's a sole required parameter that takes a map, and if so, translate accordingly.
            Show
            abayer Andrew Bayer added a comment - And tada, a PR -  https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/142
            Hide
            scm_issue_link SCM/JIRA link daemon added a comment -

            Code changed in jenkins
            User: Andrew Bayer
            Path:
            pipeline-model-api/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTArgumentList.java
            pipeline-model-definition/pom.xml
            pipeline-model-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/parser/ModelParser.groovy
            pipeline-model-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/validator/ModelValidatorImpl.groovy
            pipeline-model-definition/src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/BasicModelDefTest.java
            pipeline-model-definition/src/test/resources/htmlPublisher.groovy
            pom.xml
            http://jenkins-ci.org/commit/pipeline-model-definition-plugin/3020057c7dabad0af4b5f5f34f4102cee274a894
            Log:
            [FIXED JENKINS-41456] Properly validate publishHTML

            Specifically, when we see that there's a sole required parameter, the
            only provided argument by the user is a map, at least one of those map
            keys doesn't have a corresponding parameter in the describable, and
            the sole required parameter's type is a describable itself, validate
            the argument map against that parameter type describable instead of
            against the parent describable. So for publishHTML, that means
            realizing `target` is an `HtmlPublisherTarget` and validating the map
            against that.

            Show
            scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Andrew Bayer Path: pipeline-model-api/src/main/java/org/jenkinsci/plugins/pipeline/modeldefinition/ast/ModelASTArgumentList.java pipeline-model-definition/pom.xml pipeline-model-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/parser/ModelParser.groovy pipeline-model-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/validator/ModelValidatorImpl.groovy pipeline-model-definition/src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/BasicModelDefTest.java pipeline-model-definition/src/test/resources/htmlPublisher.groovy pom.xml http://jenkins-ci.org/commit/pipeline-model-definition-plugin/3020057c7dabad0af4b5f5f34f4102cee274a894 Log: [FIXED JENKINS-41456] Properly validate publishHTML Specifically, when we see that there's a sole required parameter, the only provided argument by the user is a map, at least one of those map keys doesn't have a corresponding parameter in the describable, and the sole required parameter's type is a describable itself, validate the argument map against that parameter type describable instead of against the parent describable. So for publishHTML, that means realizing `target` is an `HtmlPublisherTarget` and validating the map against that.

              People

              • Assignee:
                abayer Andrew Bayer
                Reporter:
                bitwiseman Liam Newman
              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: