build

build & current build

import hudson.model.*

timestamps { ansiColor('xterm') {
  node('controller') {
    def parameters = currentBuild.rawBuild?.actions.find{ it instanceof ParametersAction }?.parameters
    parameters.each {
      println "parameter ${it.name}:"
      println it.dump()
      println "-" * 80
    }
  }
}}

useful info:

method hudson.model.Run getPreviousBuild
method hudson.model.Run getResult
method org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper getRawBuild
if( ! hudson.model.Result.SUCCESS.equals(currentBuild.rawBuild.getPreviousBuild()?.getResult()) ) {
  echo "last build failed"
}

Stop the current build

stop current

// stop and show status to UNSTABLE
if ( 'UNSTABLE' == currentBuild.result ) {
  currentBuild.getRawBuild().getExecutor().interrupt(Result.UNSTABLE)
}
  • or

    // stop and show status to NOT_BUILT
    if ( 'ABORTED' == currentBuild.result ) {
      currentBuild.rawBuild.executor.interrupt( Result.NOT_BUILT )
    }
  • or

    import hudson.model.Result
    import hudson.model.Run
    import jenkins.model.CauseOfInterruption
    
    Run previousBuild = currentBuild.getPreviousBuildInProgress()
    while ( previousBuild ) {
      if ( previousBuild.isInProgress() && previousBuild.getExecutor() ) {
        println ">> aborting previous build #${previousBuild.number}"
        def cause = { "interrupted by build #${currentBuild.getId()}" as String } as CauseOfInterruption
        previousBuild.getExecutor().interrupt( Result.ABORTED, cause )
      }
      previousBuilds = currentBuild.getPreviousBuildInProgress()
    }
  • abort previous running build

    import hudson.model.Result
    import hudson.model.Run
    import jenkins.model.CauseOfInterruption
    
    def abortPreviousBuilds() {
      Run previousBuild = currentBuild.getPreviousBuildInProgress()
    
      while (previousBuild != null) {
        if (previousBuild.isInProgress()) {
          def executor = previousBuild.getExecutor()
          if (executor != null) {
            println ">> Aborting older build #${previousBuild.number}"
            def cause = { "interrupted by build #${currentBuild.getId()}" as String } as CauseOfInterruption
            executor.interrupt(Result.ABORTED, cause)
          }
        }
        previousBuild = previousBuild.getPreviousBuildInProgress()
      }
    }
  • or Stopping Jenkins job in case newer one is started

    import hudson.model.Result
    import jenkins.model.CauseOfInterruption
    
    //iterate through current project runs
    build.getProject()._getRuns().each { id, run ->
      def exec = run.getExecutor()
      //if the run is not a current build and it has executor (running) then stop it
      if( run!=build && exec!=null ) {
        //prepare the cause of interruption
        def cause = new CauseOfInterruption() {
          public String getShortDescription() {
            return "interrupted by build #${build.getId()}"
          }
        }
        exec.interrupt( Result.ABORTED, cause )
      }
    }
    
    //just for test do something long...
    Thread.sleep(10000)

stop all

Thread.getAllStackTraces().keySet().each() {
  t -> if (t.getName()=="YOUR THREAD NAME" ) { t.interrupt(); }          // or t.stop();
}

// and
Jenkins.instance.getItemByFullName("JobName")
                .getBuildByNumber(JobNumber)
                .finish(
                        hudson.model.Result.ABORTED,
                        new java.io.IOException("Aborting build")
                );

get current build info

[!TIP] reference:

get BUILD_NUMBER

Jenkins.instance.getItemByFullName(env.JOB_NAME).getLastBuild().getNumber().toInteger()
  • get previous build number

    currentBuild.previousBuild.number

get build id of lastSuccessfulBuild

  • get via api

    sh """
      curl -sSLg 'https://<jenkins.domain.com>/job/<job-name>/api/json' -o 'output.json'
    """
    def data = readJSON file: 'output.json'
    println data.lastSuccessfulBuild.number
  • get via Jenkins.instance.getItemByFullName(env.JOB_NAME)

    Jenkins.instance.getItemByFullName(env.JOB_NAME).lastSuccessfulBuild.number
  • get last build id

    Jenkins.instance.getItemByFullName(env.JOB_NAME).getLastBuild().getNumber().toInteger()

trigger downstream builds

timestamps { ansiColor('xterm') {
  node( 'controller' ) {
    stage( 'trigger downstream' ) {
      buildRes = build job: '/marslo/downstream',
                       propagate: false,
                       parameters: [
                         string( name: 'stringParams', value: 'string'      ) ,
                         string( name: 'choiceParams', value: 'validChoice' ) ,
                         booleanParam( name: 'booleanParams', value: false  ) ,
                       ]
      String log = """
              result : ${buildRes.result}
                 url : ${buildRes.absoluteUrl}
        build number : ${buildRes.number.toString()}
      """
      println log

    } // stage : trigger downstream
  } // node : controller
}} // ansiColor | timestamps

trigger downstream with active choice parameters

/marslo/sandbox

timestamps { ansiColor('xterm') {
  podTemplate( cloud: 'DevOps Kubernetes' ) { node( POD_LABEL ) {
    List<ParameterValue> newParams = [
      [$class: 'StringParameterValue' , name: 'lastName'  , value: 'Jiao'    ] ,
      [$class: 'StringParameterValue' , name: 'firstName' , value: 'Marslo'  ] ,
      [$class: 'StringParameterValue' , name: 'provinces' , value: 'Gansu'   ] ,
      [$class: 'StringParameterValue' , name: 'cities'    , value: 'Lanzhou,Dingxi' ] ,
      [$class: 'BooleanParameterValue', name: 'notify', value: false]
    ]
    def res = build ( job: '/marslo/sandbox' ,
                      propagate  : false ,
                      wait       : true  ,
                      parameters: newParams
                    )
    println """
            result : ${res.result}
               url : ${res.absoluteUrl}
      build number : ${res.number.toString()}
    """
  }} // node | podTemplate
}} // ansiColor | timestamp

def changeLogSets = currentBuild.changeSets
for ( int i = 0; i < changeLogSets.size(); i++ ) {
  def entries = changeLogSets[i].items
  for ( int j = 0; j < entries.length; j++ ) {
    def entry = entries[j]
    echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
    def files = new ArrayList(entry.affectedFiles)
    for ( int k = 0; k < files.size(); k++ ) {
      def file = files[k]
      echo "  ${file.editType.name} ${file.path}"
    }
  }
}
  • Pipeline Supporting APIs Plugin older than 2.2

    def changeLogSets = currentBuild.rawBuild.changeSets
    for ( int i = 0; i < changeLogSets.size(); i++ ) {
      def entries = changeLogSets[i].items
      for ( int j = 0; j < entries.length; j++ ) {
        def entry = entries[j]
        echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
        def files = new ArrayList(entry.affectedFiles)
        for ( int k = 0; k < files.size(); k++ ) {
          def file = files[k]
          echo "  ${file.editType.name} ${file.path}"
        }
      }
    }

others

  • Thread.currentThread().executable

    import hudson.model.*
    
    def build = Thread.currentThread().executable
    def buildNumber = build.number
    def workspace   = build.getEnvVars()["WORKSPACE"]'
    def jobname     = build.getEnvVars()["JOB_NAME"]
    ...

stage and build

warnError

node( 'controller' ) {
  warnError( 'Script failed!' ) {
    sh( 'false' )
  }
}

stage( 'false' ) {
  catchError(
    buildResult : 'SUCCESS',
        message : 'stage failed, but build succeed',
    stageResult : 'FAILURE'
  ){
    sh label: env.STAGE_NAME,
       script: 'exit 2'
  }
}
  • or just be simply:

     catchError( buildResult: 'SUCCESS', stageResult: 'FAILURE' ) {
       sh( 'false' )
     }
  • set unstable

    catchError( message: 'script failed', buildResult: 'UNSTABLE', stageResult: 'UNSTABLE' ) {
      sh( 'false' )
    }

Signals an error. Useful if you want to conditionally abort some part of your program. You can also just throw new Exception(), but this step will avoid printing a stack trace

error( 'failed the build' )

Prints a message to the log and sets the overall build result and the stage result to UNSTABLE. The message will also be associated with the stage result and may be shown in visualizations.

unstable( 'unstable the build' )

get stage of a build

  • get stage name

    stage( 'build' ) {
      println "${env.STAGE_NAME}"
    }
  • get all stages of a build

    WorkflowRun run = Jenkins.instance.getItemByFullName("####YOUR_JOB_NAME####")._getRuns()[0]
    FlowExecution exec = run.getExecution()
    PipelineNodeGraphVisitor visitor = new PipelineNodeGraphVisitor(run)
    def flowNodes = visitor.getPipelineNodes()
    
    for (Iterator iterator = flowNodes.iterator(); iterator.hasNext();) {
      def node = iterator.next()
      if (node.getType() == FlowNodeWrapper.NodeType.STAGE) {
        String stageName = node.getDisplayName()
        def stageResult = node.getStatus().getResult()
    
        println "Result of stage ${stageName} is ${stageResult}"
      }
    }

    or

    import org.jenkinsci.plugins.workflow.graph.FlowGraphWalker
    import org.jenkinsci.plugins.workflow.graph.FlowNode
    
    try {
      // just for demo, a success step and a failure step
      node {
        sh 'true'
        sh 'false'
      }
    } finally {
      FlowGraphWalker walker = new FlowGraphWalker(currentBuild.rawBuild.getExecution())
      for (FlowNode flowNode: walker) {
        // do whatever you want with flowNode
        echo flowNode.dump()
      }
    }

Build Result

reference

isWorthThan

import hudson.model.Result

ansiColor( 'xterm' ) {
  List r = [ 'SUCCESS', 'UNSTABLE', 'FAILURE', 'NOT_BUILT', 'ABORTED' ]

  r.each { b ->
    println " ~~> ${b}"
    Result base = Result.fromString(b)
    ( r - b ).each { o ->
      Result x = Result.fromString(o)
      res = base.isWorseThan(x)
      color.echo( "${res ? 'green' : 'red'}", "${base} isWorthThan ${x} : ${res}" )
    }
  }
} // ansiColor

Last updated