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

Declarative: publishHTML syntax does not work in post block

    XMLWordPrintable

Details

    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

            bitwiseman Liam Newman created issue -
            abayer Andrew Bayer added a comment -

            Your final example looks the same as the previous one?

            abayer Andrew Bayer added a comment - Your final example looks the same as the previous one?
            bitwiseman Liam Newman made changes -
            Field Original Value New Value
            Description Converted this Scripted Pipeline:
            {code}
            /* 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"
                  ])

              }
            }
            {code}


            To this Declarative:
            {code}
            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"
                          ])
                    }
                }
            }
            {code}

            Fails with this output:
            {code}
            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
            {code}

            Changed Declarative to this and it succeeds ({target:} is not needed in Scripted):
            {code}
            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"
                          ])
                    }
                }
            }
            {code}
            Converted this Scripted Pipeline:
            {code}
            /* 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"
                  ])

              }
            }
            {code}


            To this Declarative:
            {code}
            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"
                          ])
                    }
                }
            }
            {code}

            Fails with this output:
            {code}
            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
            {code}

            Changed Declarative to this and it succeeds ({target:} is not needed in Scripted):
            {code}
            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"
                          ]
                    }
                }
            }
            {code}
            bitwiseman Liam Newman added a comment -

            Fixed.

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

            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.
            bitwiseman Liam Newman made changes -
            Link This issue relates to JENKINS-29711 [ JENKINS-29711 ]
            bitwiseman 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.

            bitwiseman 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.
            abayer Andrew Bayer added a comment -

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

            abayer Andrew Bayer added a comment - Moving this to htmlpublisher-plugin , since the actual problem is its @DataBoundConstructor .
            abayer Andrew Bayer made changes -
            Component/s htmlpublisher-plugin [ 15681 ]
            Component/s pipeline-model-definition-plugin [ 21706 ]
            Assignee Andrew Bayer [ abayer ] mcrooney [ mcrooney ]
            abayer Andrew Bayer made changes -
            Link This issue relates to JENKINS-43000 [ JENKINS-43000 ]
            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.

            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.
            abayer Andrew Bayer made changes -
            Component/s pipeline-model-definition-plugin [ 21706 ]
            Component/s htmlpublisher-plugin [ 15681 ]
            Assignee mcrooney [ mcrooney ] Andrew Bayer [ abayer ]
            abayer Andrew Bayer made changes -
            Status Open [ 1 ] In Progress [ 3 ]
            abayer Andrew Bayer made changes -
            Status In Progress [ 3 ] In Review [ 10005 ]
            abayer Andrew Bayer added a comment - And tada, a PR -  https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/142
            abayer Andrew Bayer made changes -
            Remote Link This issue links to "PR #142 (Web Link)" [ 15801 ]
            abayer Andrew Bayer made changes -
            Link This issue is duplicated by JENKINS-43000 [ JENKINS-43000 ]
            abayer Andrew Bayer made changes -
            Resolution Fixed [ 1 ]
            Status In Review [ 10005 ] Resolved [ 5 ]

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

            Bulk closing resolved issues.

            bitwiseman Liam Newman added a comment - Bulk closing resolved issues.
            bitwiseman Liam Newman made changes -
            Status Resolved [ 5 ] Closed [ 6 ]

            People

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

              Dates

                Created:
                Updated:
                Resolved: