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

Declarative: publishHTML syntax does not work in post block

      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"
                    ]
              }
          }
      }
      

          [JENKINS-41456] Declarative: publishHTML syntax does not work in post block

          Andrew Bayer added a comment -

          Your final example looks the same as the previous one?

          Andrew Bayer added a comment - Your final example looks the same as the previous one?

          Liam Newman added a comment -

          Fixed.

          Liam Newman added a comment - Fixed.

          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.

          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.

          Liam Newman added a comment -

          abayer 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.

          Liam Newman added a comment - abayer 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.

          Andrew Bayer added a comment -

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

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

          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.

          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.

          Andrew Bayer added a comment -

          Andrew Bayer added a comment - And tada, a PR -  https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/142

          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.

          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.

          Liam Newman added a comment -

          Bulk closing resolved issues.

          Liam Newman added a comment - Bulk closing resolved issues.

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

              Created:
              Updated:
              Resolved: