Jenkins is an automation server. It allows for all kinds of automations. It is primarily used for Build automation, Continuous Integration, and Continuous Deployment.

  1. Install Jenkins on Ubuntu (using Vagrant)
  2. Vagrant for Jenkins on Ubuntu
  3. Jenkins Pipeline - Hello World
  4. Jenkins Pipeline: running external programs with sh or bat, returnStdout, trim
  5. Jenkins Pipeline: Send e-mail notifications
  6. Jenkins Pipeline: Add some text to the job using shortText
  7. Jenkins CLI: create node
  8. Jenkins Pipeline BuildUser plugin
  9. Jenkins Pipeline - set and use environment variables
  10. Jenkins Pipeline: git checkout using reference to speed up cloning large repositories
  11. Jenkins report the name of the stage that failed
  12. Triggers from Version Control Systems
  13. Report failures.
  14. Send alerts
  15. Collect test coverage data.
  16. Jenkins slides

Add badges

   manager.addBadge("error.gif", "Failed build")

Run external code, capture output

script {
      v = sh(script: 'echo " 42"; echo', returnStdout: true).trim()
      echo v
      echo "a${v}b"
}

bat for windows.

catch and print error in jenkins

jenkins exception try - catch

https://fraaargh.wordpress.com/2018/06/20/get-a-jobs-console-logfile-from-a-jenkins-pipeline/

pipeline {
   agent none
   stages {
       stage ('Catch crash') {
           agent { label 'master'}
           steps {
               echo "before crash"
               script {
                   try {
                       sh 'exit 1'
                   } catch (err) {
                       echo "exception caught, going on"
                       println err // java.lang.ClassCastException:
org.jenkinsci.plugins.workflow.steps.EchoStep.message expects class java.lang.String but received
class hudson.AbortException
                   }
               }
               echo "after crash"
           }
       }
       stage ('Continue after crash') {
           agent { label 'master'}
           steps {
               echo "stage after crash"
           }
       }
   }
}

                    try {
                        //sh "ls -l no_such"
                        a = 10
                        b = 0
                        c = a/b
                    }
                    catch(Exception ex) {
                         //currentBuild.result = 'FAILURE'
                        println("exception")
                        println(ex) // hudson.AbortException: script returned exit code 2
                        println(ex.toString())
                        println(ex.getMessage())
                        println(ex.getStackTrace())
                    }

dir and tmp are problematic

  stages {
       stage ('Run external exe') {
           agent { label 'master'}
           steps {
               sh 'pwd'
               dir('/tmp/gabor') {
                   echo "inside"
                   sh 'pwd'
                   //sh 'sudo ./do-something.py'
               }
               sh 'pwd'
               //sh "sudo sh -c 'cd /tmp; ./do-something.py; cd -'"
           }
       }

examples/jenkins/mkdir_exception.txt

java.io.IOException: Failed to mkdirs: /tmp@tmp/durable-e569697c
        at hudson.FilePath.mkdirs(FilePath.java:1170)
        at org.jenkinsci.plugins.durabletask.FileMonitoringTask$FileMonitoringController.<init>(FileMonitori
ngTask.java:156)
        at org.jenkinsci.plugins.durabletask.BourneShellScript$ShellController.<init>(BourneShellScript.java
:198)
        at org.jenkinsci.plugins.durabletask.BourneShellScript$ShellController.<init>(BourneShellScript.java
:190)
        at org.jenkinsci.plugins.durabletask.BourneShellScript.launchWithCookie(BourneShellScript.java:111)
        at org.jenkinsci.plugins.durabletask.FileMonitoringTask.launch(FileMonitoringTask.java:86)
        at org.jenkinsci.plugins.workflow.steps.durable_task.DurableTaskStep$Execution.start(DurableTaskStep
.java:182)
        at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:229)
        at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:153)
        at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
        at sun.reflect.GeneratedMethodAccessor1989.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:157)
        at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
        at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterc
eptor.java:133)
        at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:155)
        at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:159)
        at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:129)
        at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:129)
        at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
        at WorkflowScript.run(WorkflowScript:16)

Jenkins / Groovy - define functions and call them with parameters

def report(status) {
   println "status=${status}"
}

and call them

report("text")

Environment variables on Linux

sh 'printenv'
sh 'env'

Input during the process

pipeline {
   agent { label 'master' }
   stages {
       stage('build') {
           steps {
               echo "Hello World!"
               //input("Continue?")
               echo "OK"
               //input(
               //    message: 'Was this successful?', parameters: [
               //   [$class: 'BooleanParameterDefinition', defaultValue: true, description: '',
name: 'Please confirm you agree with this']
               //])

       /*
               script {
                   res = input(
                       message: 'Was this successful?', parameters: [
                       [$class: 'BooleanParameterDefinition', defaultValue: false, description:
'', name: 'Apple'],
                       [$class: 'BooleanParameterDefinition', defaultValue: false, description:
'', name: 'Banana']
                   ])
                                      print(res)
               }
*/
               script {
                   values = ['Apple', 'Banana', 'Peach']
                   parameters = []
                   values.each {
                       echo it
                       parameters.add( [$class: 'BooleanParameterDefinition', defaultValue:
false, description: '', name: it ] )
                   }

                   res = input(
                       message: 'Was this successful?', parameters: parameters
                   )
                                                         print(res)
               }


               //                input(
//                    message: 'What now?', parameters: [
//                        [$class: 'AppDetectorParamaterDefinition')
//                ])
                                  //echo result
                              // python scripts/aws_instances.py --what selftest --command start
           }
       }
   }
}

git Backup

gist

List agents by name and by label

def jenkins = Jenkins.instance
def computers = jenkins.computers
computers.each {
   //  println "${it.displayName} ${it.hostName}"
}

def labels = jenkins.getLabels()
labels.each {
   println "${it.displayName}"
}

Other

echo bat(returnStdout: true, script: 'set')

build(job: 'RevertServerAutomationCloud', parameters: [
     string(name: 'VM_SNAPSHOT', value: 'CleanDb')
])

how to include one jenkinsfile in another one?

how to avoid repetititon?

stage('Revert agent 100')
         {
             steps
                     {
                     }
         }

 stage('Revert agent 102')
         {
             steps
                     {

                     }
         }

how do try - catch and repeat interact?

vSphere buildStep: [$class: 'RevertToSnapshot', snapshotName: "${params.VM_SNAPSHOT}", vm: "${params.VM_NAME}"], serverName: '192.168.1.1'

httpRequest authentication: 'df8-b86d-3272', consoleLogResponseBody: true, httpMode: 'POST', ignoreSslErrors: true, responseHandle: 'NONE', url:
"http://192.168.1.1:8080/computer/${params.AGENT_NAME}/doDisconnect?offlineMessage=bye", validResponseCodes: '100:404'

Active Choices Parameter

examples/jenkins/array_list.txt

try {
   List<String> subnets = new ArrayList<String>()
   def subnetsRaw = "gcloud compute networks subnets list --project=${GCE_PROJECT} --network=corp-development --format=(NAME)".execute().text
   for (subnet in  subnetsRaw.split()) {
       subnets.add(subnet)
   }
   return subnets
} catch (Exception e) {
   print e
   print "There was a problem fetching the artifacts"
}

Options

   options {
       ansiColor('xterm')
       timestamps()
   }

Scripts

Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (org.jenkinsci.plugins.workflow.cps.EnvActionImpl keys). Administrators can decide whether to approve or reject this signature.

archiveArtifacts can be called multiple times

archiveArtifacts artifacts: 'mydata.json', onlyIfSuccessful: true
writeJSON(file: 'otherfile.log', json: data, pretty: 4)
archiveArtifacts artifacts: '*.log', onlyIfSuccessful: true

Environment variable values must either be single quoted, double quoted, or function calls.

They cannot be earlier defined environment variables or parameter values. We can however overcome this limitation by calling a function and passing the values to it.

examples/jenkins/exceptions.jenkinsfile

pipeline {
   agent none
   options {
       ansiColor('xterm')
       timestamps()
   }
   parameters {
       string(name: 'machine', defaultValue: 'asos', description: 'Some text input')
       string(name: 'size',   defaultValue: '23', description: 'Some number input')
   }
   environment {
       answer = 42
       // machine_name = params.machine  // -> Environment variable values must either be single quoted, double quoted, or function calls.
       machine_name = set_machine_name(params.machine)
   }
   stages {
       stage('try') {
           agent { label 'master' }
           steps {
               script {
                   sh "hostname"
                   print("params.machine=${params.machine}")
                   print("params.size=${params.size}")
                   print("env.answer=${env.answer}")
                   print("env.machine_name=${env.machine_name}")

               }
           }
       }
       stage('try-agent') {
           agent { label 'jenkins-simple-slave' }
           steps {
               script {
                   sh "hostname"
               }
           }
       }
   }
}

def set_machine_name(value) {
   return value
}


Jenkins environment

Even if there is an exception in the environment section Jenkins will still run the "success" part of the post section. Same problem if there is an exception on one of the functions.

To overcome this we create an environment variable as the last step in the environment section and then we check that variable using

if (! binding.hasVariable('environment_is_set')) { error("Environment failed to set properly") }

That does not help in case there is an exception in the functions.

http_request

response = httpRequest discovery_url
println response
config_str = response.getContent()
for (item in config.sources) {
  item.value
  item.key

Sending e-mail problem fixed

https://stackoverflow.com/questions/20188456/how-to-change-the-security-type-from-ssl-to-tls-in-jenkins

* Sending e-mail In Manage Jenkins - Configure System in the Extended mail section set the SMTP: smtp.office365.com Domain name: @company.com Advanced: Use SMTP Authentication: + User Name: cicdserver@company.com Password: SMTP port: 587 E-mail notification section: SMTP server: smtp.office365.com Default user e-mail suffix: @company.com Advanced User Name: cicdserver@company.com Password: SMTP port: 587

Shut down Jenkins (via the Windows services) Open the file: C:\Program Files (x86)\Jenkins\jenkins.xml and change the arguments line to be:

examples/jenkins/arguments.txt

<arguments>-Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle  -Dmail.smtp.starttls.enable=true -jar
"%BASE%\jenkins.war" --httpPort=8080 --webroot="%BASE%\war"</arguments>

(specifically add: -Dmail.smtp.starttls.enable=true ) Then start Jenkins again.

Client was not authenticated to send anonymous mail Error sending to the following VALID addresses

examples/jenkins/variables.Jenkinsfile

pipeline {
   agent none
   stages {
       stage('try') {
           agent { label 'master' }
           steps {
               script {
                   //some_strange_name = null
                   //print(some_strange_name)
                   if (true) {
                       print("creating variable")
                       some_strange_name = 1
                   }
                   print(some_strange_name)

                   if (binding.hasVariable('some_strange_name')) {
                       print("has some_strange_name")
                       print(some_strange_name)
                   } else {
                       print("DOES NOT have some_strange_name")
                   }
               }
           }
       }
       stage('try again') {
           agent { label 'master' }
           steps {
               script {
                   if (binding.hasVariable('some_strange_name')) {
                       print("has some_strange_name")
                       print(some_strange_name)
                   } else {
                       print("DOES NOT have some_strange_name")
                   }
               }
           }
       }
   }
}

Parallel stages

examples/jenkins/parallel.Jenkinsfile

pipeline {
   agent { label 'master' }
   stages {
       stage('before') {
           steps {
               println("before")
           }
       }
       stage('para') {
           parallel {
               stage('apple') {
                   steps {
                       println("apple 1")
                       sleep(20 * Math.random())
                       println("apple 2")
                   }
               }
               stage('banana') {
                   steps {
                       println("banana 1")
                       sleep(20 * Math.random())
                       println("banana 2")
                   }
               }
               stage('peach') {
                   steps {
                       println("peach 1")
                       sleep(20 * Math.random())
                       println("peach 2")
                   }
               }
           }
       }
       stage('after') {
           steps {
               println("after")
           }
       }
   }
}

Skip steps

Jenkins pipeline stop early with success How to indicate that a job is successful pipeline conditional step stage

examples/jenkins/skip_step.Jenkinsfile

pipeline {
   agent none
   options {
       ansiColor('xterm')
       timestamps()
   }
   parameters {
       booleanParam(defaultValue: false, description: 'Checkbox', name: 'yesno')
   }
   stages {
       stage('first') {
           agent { label 'master' }
           steps {
               script {
                   println("first before")
                   println(params.yesno)
                   done = true
                   return
                   println("first after")
               }
           }
       }
       stage('second') {
           agent { label 'master' }
           when {
               expression {
                  return ! done;
               }
           }
           steps {
               script {
                   println("second")
               }
           }
       }
   }
}

examples/jenkins/worker_job.Jenkinsfile

import java.text.SimpleDateFormat
pipeline {
   agent none
   options {
       ansiColor('xterm')
       timestamps()
   }
   parameters {
       string(name: 'machine', defaultValue: '', description: 'Name of the machine')
       string(name: 'size',   defaultValue: '23', description: 'The size')
       choice(choices: ['Mercury', 'Venus', 'Earth', 'Mars'], description:  'Pick a planet', name: 'planet')
   //}
   stages {
       stage('try') {
           agent { label 'master' }
           steps {
               script {
                   sh "hostname"

                   def data = readJSON text: '{}'
                   data.name = "test-529" as String
                   data.date = new java.text.SimpleDateFormat('yyyyMMddHHmmss').format(new Date())
                   writeJSON(file: 'mydata.json', json: data, pretty: 4)
                   archiveArtifacts artifacts: 'mydata.json', onlyIfSuccessful: true

                   //error("Fail after first artifact")

                   writeJSON(file: 'otherfile.log', json: data, pretty: 4)
                   archiveArtifacts artifacts: '*.log', onlyIfSuccessful: true
               }
           }
       }
   }
}

jenkins sh commnad fails - jenkins stops

examples/jenkins/sh_fails.jenkinsfile

pipeline {
   agent { label 'master' }
   stages {
       stage('only') {
           steps {
               println("one")
               sh "ls -l"
               println("two")
               sh "ls -l no_such"
               println("three")
           }
       }
   }
}

Repository branch filter for Git

It will start multiple jobs if more than one branch was pushed out. It is triggered even if there were no new commits in the branch that was pushed out

By default it will run every branch matching the filter, even if that branch was last changed 2 years ago. This can be a problem if for some reason your have hundreds or thousands of historical branches.

:^origin/(work|dev)-.*

You can limit this by selecting another option and setting the ancestry date to limit how many days you are ready to go back in time.

  • Strategy for choosing what to build
  • Choosing strategy: Ancestry
  • Maximum Age of Commit: 1

In a pipeline

examples/jenkins/branch_filter_age_limit.jenkinsfile


checkout([
    $class: 'GitSCM',
    branches: [[name: '*/master']],
    doGenerateSubmoduleConfigurations: false,
    extensions: [[
        $class: 'BuildChooserSetting',
        buildChooser: [$class: 'AncestryBuildChooser', ancestorCommitSha1: '', maximumAgeInDays: 1]
    ]],
    submoduleCfg: [],
    userRemoteConfigs: [[]]
])

Jenkins Pipeline code reuse

https://cleverbuilder.com/articles/jenkins-shared-library/ https://jenkins.io/doc/book/pipeline/shared-libraries/

Exceptions

When you encounter one of those 40-lines long Java stack-traces, look for WorkflowScript to locate the source of the problem.

examples/jenkins/exception_catching.jenkinsfile

pipeline {
    agent { label 'master' }
    stages {
        stage('only') {
            steps {
                script {
                    println("one")
                    sh "ls -l"
                    println("two")

                    try {
                        //sh "ls -l no_such"
                        a = 10
                        b = 0
                        c = a/b

                    }
                    catch(Exception ex) {
                         //currentBuild.result = 'FAILURE'
                        println("exception")
                        println(ex) // hudson.AbortException: script returned exit code 2
                        println(ex.toString())
                        println(ex.getMessage())
                        println(ex.getStackTrace())
                    }

                    //} catch(ArrayIndexOutOfBoundsException ex) {
                    //println("Catching the Array out of Bounds exception");
                    //}catch(Exception ex) {

                    println("three")
                    is_it_the_answer(42)
                    echo "try again"
                    is_it_the_answer(23)
                }
            }
        }
        stage('second') {
            steps {
                script {
//                    if (manager.logContains("three")) {
//                        manager.addWarningBadge("tres")
//                    } else {
//                        manager.addWarningBadge("nem harom")
//                    }

                }
            }
        }
    }
}

def is_it_the_answer(n) {
    if (n == 42) {
        return 'yes'
    }
    throw new Exception('Nope')
}


                    try {
                        is_it_the_answer(23)
                    } catch (err) {
                        print(err)
                        print(err.getMessage())
                    }



Jenkins parse console output

The logContains can parse the log created be the previous stages (but not the current stage) It can also be used in a post-action.

"manager" is org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildRecorder$BadgeManager@41fe3861

Postbuild plugin

examples/jenkins/parse_console_output.jenkinsfile

        stage('second') {
            steps {
                script {
                    if (manager.logContains("three")) {
                        manager.addWarningBadge("drei")
                    } else {
                        manager.addWarningBadge("kein drei")
                    }
                }
            }
        }


         print("A disk image was created: zorg-1552278641")

         def matcher = manager.getLogMatcher(/.* (zorg-\d+).*/)
         print(matcher)
         if (matcher?.matches()) {
             def image_name = matcher.group(1)
             print(image_name)
             manager.addShortText(image_name)
         }


readJSON

no such dsl method

jenkins build step

https://jenkins.io/doc/pipeline/steps/pipeline-build-step/

jenkins collect status from invoked jobs

examples/jenkins/status_from_build.Jenkinsfile


pipeline {
    agent { label 'master' }
    stages {
        stage('only') {
            steps {
                script {
                    println("BEFORE")
                    results = []
                    try {
                        def result = build job: "experiment-subproject", wait: true
                        println(result) // org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper
                        println(result.getId())
                    } catch(err) {
                        println("ERROR caught")
                        println(err) // hudson.AbortException: experiment-subproject #4 completed with status FAILURE (propagate: false to ignore)
                        // https://javadoc.jenkins-ci.org/hudson/AbortException.html
                        println(err.getMessage())
                        println(err.getStackTrace())
                        println(err.getCause())
                        println(err.getLocalizedMessage())
                        println(err.toString())
                    }
                    println("AFTER")

                    def res = build job: "experiment-subproject", wait: false
                    println(res) // null

                    rep = build job: "experiment-subproject", wait: true, propagate: false
                    println(rep) // org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper
                    println(rep.getId())
                    println(rep.getResult()) // FAILURE
                    println(rep.getDurationString())
                    results.push(rep)

                    //sh "ls -l"
                    //println("two")
                    //} catch(ArrayIndexOutOfBoundsException ex) {
                    //println("Catching the Array out of Bounds exception");
                    //}catch(Exception ex) {

                    //println("three")
                    //print("A disk image was created: jenkins-agent-1554 and then more")
                    //is_it_the_answer(42)
                    //echo "try again"
                    //try {
                    //    is_it_the_answer(23)
                    //} catch (err) {
                    //   print(err)
                    //    print(err.getMessage())
                    //}
                }
            }
        }
        stage('second') {
            steps {
                script {
                    echo "hi"
                    println(rep.getId())
                    println(rep.getResult()) // FAILURE
                    println(rep.getProjectName())
                    println(rep.getDisplayName())

                    def res = build job: "experiment-subproject", wait: true, propagate: false
                    results.push(res)

//                    if (manager.logContains("three")) {
//                        manager.addWarningBadge("tres")
//                    } else {
//                        manager.addWarningBadge("nem harom")
//                    }
                    //def image_name = ''
                    //def matcher = manager.getLogMatcher(/.* (jenkins-agent-(\d+)).*/)
                    //print(matcher)
                    //if (matcher?.matches()) {
                    //    image_name = matcher.group(1)
                    //    println(image_name)
                    //    manager.addShortText(image_name)
                    //    println(image_name.getClass())
                    //}
                    //do_sg(image_name)
                }
            }
        }
        stage ('gitz') {
            agent { label 'build-small' }
            steps {
                script {
                    results.each {
                         println(it)
                         println(it.getId())
                         println(it.getResult()) // FAILURE
                         println(it.getProjectName())
                         println(it.getAbsoluteUrl())
                    }
                }
            }
        }
    }
}

def is_it_the_answer(n) {
    if (n == 42) {
        return 'yes'
    }
    throw new Exception('Nope')
}

def do_sg(name) {
    print("do_sg with $name")
}

links and badges

https://jenkins.io/doc/pipeline/steps/badge/ manager.addBadge("star-gold.gif", "Successful build")

https://jenkins.io/doc/pipeline/steps/

https://jenkins.io/doc/pipeline/steps/pipeline-build-step/#-build-%20build%20a%20job

https://jenkins.io/doc/pipeline/steps/pipeline-input-step/

               script {
                    manager.addShortText("\n${params.cluserName}", "black", "yellow", "0px", "white")
                    manager.addShortText("${params.clusterId}-${params.command}", "black", "lightgreen", "0px", "white")
                    manager.addShortText("${params.services}", "black", "AliceBlue", "0px", "white")
                    if (params.usage) {
                        manager.addShortText("${params.usage}", "DimGray", "AliceBlue", "0px", "white")
                    }
                }

Elapsed time

examples/jenkins/elapsed_time.Jenkinsfile

import groovy.time.TimeCategory
import groovy.time.TimeDuration

pipeline {
    agent { label 'master' }
    stages {
        stage('first') {
            steps {
                script {
                    start = new Date()
                    echo "in first"
                }
            }
        }
        stage('second') {
            steps {
                script {
                    echo "in second"
                }
            }
        }
    }
    post {
        always {
            echo "in post always"
            script {
                def stop = new Date()
                TimeDuration td = TimeCategory.minus( stop, start )
                println("Elapsed time: $td")
            }

        }
        failure {
            echo "in post failure"
        }
    }
}

Serialize regex

After a regex matching Jenkins sometimes wants to serialize the object, but it cannot do it and thus is raises an exception. (I have not yet figured out when does this happen.)

examples/jenkins/serialize_regex.Jenkinsfile

pipeline {
    agent { label 'master' }
    stages {
        stage('first') {
            steps {
                script {
                    echo "in first"
                    def text = """This is some long test
                    with more than 1
                    rows.
                    """
                    def match = (text =~ /\bsome\b/)
                    println("still first")
                    check_me()
                }
            }
        }
        stage('second') {
            steps {
                script {
                    echo "in second"
                }
            }
        }
    }
    post {
        always {
            echo "in post always"
        }
        failure {
            echo "in post failure"
        }
    }
}

def check_me() {
    println("in check")
    def text = """This is some long test
        with more than 1
        rows.
    """
    def match = (text =~ /\bsome\b/)
}


Send mail

emailext (
    subject: "Test by Gabor",
    body: "Test from Gabor",
    to: 'foo@bar.com',
    from: 'jenkins-noreply@example.com',
    listId: 'gabor-experimental',
)

Jenkins - check if host is accessible

last started stage

//   last_started = env.STAGE_NAME

Early stop

jenkins - skip rest of the current stage, early end of current stage - stop the whole job reporting error

return  // skipping rest of the current stage, running next stage
error("Some error message")  // raise an exception stop the whole job