groovyjenkins-pipelineslack

Groovy: Method definition not expected here


I'm sure this is a simple fix but I'm new to programming in general and Groovy in particular.

I am trying to follow this guide to enable slack notifications in a Jenkins 2 pipeline job but pasting and customizing the final code block is giving me the following error;

Method definition not expected here. Please define the method at an appropriate place or perhaps try using a block/Closure instead.

This is my code right now, although I've substituted a few bits for security. The error is occurring at the def notifyBuild(String buildStatus = 'STARTED') { line.

node('on-demand-t2large'){
    stage ('Checkout') {
        checkout( checkout stuff here )
    }

    stage ('Build') {
        try {
            notifyBuild('STARTED')

            dir("place") {
                sh 'script name'
            } 
        }
        catch (e) {
            // If there was an exception thrown, the build failed
            currentBuild.result = "FAILED"
            throw e
        } 
        finally {
            // Success or failure, always send notifications
            notifyBuild(currentBuild.result)
        }

        def notifyBuild(String buildStatus = 'STARTED') {
            // build status of null means successful
            buildStatus =  buildStatus ?: 'SUCCESSFUL'

            // Default values
            def colorName = 'RED'
            def colorCode = '#FF0000'
            def subject = "${buildStatus}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
            def summary = "${subject} (${env.BUILD_URL})"
            def details = """<p>STARTED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p>
            <p>Check console output at &QUOT;<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>&QUOT;</p>"""

            // Override default values based on build status
            if (buildStatus == 'STARTED') {
                color = 'YELLOW'
                colorCode = '#FFFF00'
            } else if (buildStatus == 'SUCCESSFUL') {
                color = 'GREEN'
                colorCode = '#00FF00'
            } else {
                color = 'RED'
                colorCode = '#FF0000'
            }

            // Send notifications
            slackSend (channel: '@me', color: colorCode, message: summary)
        }
    } 
}

I understand from some googling that groovy doesn't accept inner class definition, but as new as I am to programming I don't know how to fix it. Any help (with explanations so I can learn!) would be appreciated.


Solution

  • Move the notifyBuild() method outside all the DSL hierarchy (node, stage, step, pipeline, etc., like so:

    pipeline {
       .
       .
       .
        node('on-demand-t2large'){
            stage ('Checkout') {
                checkout( checkout stuff here )
            }
        
        
            stage ('Build') {
                try {
                    notifyBuild('STARTED')
                
                    dir("place") {
                        sh 'script name'
                    }
                } catch (e) {
                    // If there was an exception thrown, the build failed
                    currentBuild.result = "FAILED"
                    throw e
                } finally {
                    // Success or failure, always send notifications
                    notifyBuild(currentBuild.result)
                }
            }
        }
       . 
       .
       .
    }
                
    def notifyBuild(String buildStatus = 'STARTED') {
        // build status of null means successful
        buildStatus =  buildStatus ?: 'SUCCESSFUL'
        
        // Default values
        def colorName = 'RED'
        def colorCode = '#FF0000'
        def subject = "${buildStatus}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
        def summary = "${subject} (${env.BUILD_URL})"
        def details = """<p>STARTED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p>
        <p>Check console output at &QUOT;<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>&QUOT;</p>"""
            
        // Override default values based on build status
        if (buildStatus == 'STARTED') {
            color = 'YELLOW'
            colorCode = '#FFFF00'
        } else if (buildStatus == 'SUCCESSFUL') {
            color = 'GREEN'
            colorCode = '#00FF00'
        } else {
            color = 'RED'
            colorCode = '#FF0000'
        }
            
        // Send notifications
        slackSend (channel: '@me', color: colorCode, message: summary)
    }
    

    Explanation: Most Groovy DSLs do not allow declarations inside the DSL elements. It appears the Jenkins DSL is no exception.