Access Stage name during the build in Jenkins pipeline

36,452

Solution 1

You can now do this in a built-in manner, since Jenkins 2.3. Like so:

steps {
    updateGitlabCommitStatus name: STAGE_NAME, state: 'running'
    echo '${STAGE_NAME}'
}

For more information see: https://issues.jenkins-ci.org/browse/JENKINS-44456

Solution 2

This should work from a pipeline shared library:

#!/usr/bin/env groovy

import hudson.model.Action;

import org.jenkinsci.plugins.workflow.graph.FlowNode
import org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode
import org.jenkinsci.plugins.workflow.actions.LabelAction


def getStage(currentBuild){
    def build = currentBuild.getRawBuild()
    def execution = build.getExecution()
    def executionHeads = execution.getCurrentHeads()
    def stepStartNode = getStepStartNode(executionHeads)

    if(stepStartNode){
        return stepStartNode.getDisplayName()
    }
}

def getStepStartNode(List<FlowNode> flowNodes){
    def currentFlowNode = null
    def labelAction = null

    for (FlowNode flowNode: flowNodes){
        currentFlowNode = flowNode
        labelAction = false

        if (flowNode instanceof StepStartNode){
            labelAction = hasLabelAction(flowNode)
        }

        if (labelAction){
            return flowNode
        }
    }

    if (currentFlowNode == null) {
        return null
    }

    return getStepStartNode(currentFlowNode.getParents())
}

def hasLabelAction(FlowNode flowNode){
    def actions = flowNode.getActions()

    for (Action action: actions){
        if (action instanceof LabelAction) {
            return true
        }
    }

    return false
}

def call() {
    return getStage(currentBuild)
}

Example usage:

node {
    stage('Stage One'){
        echo getCurrentStage()
    }

    stage('Stage Two'){
        echo getCurrentStage()
    }
}

Solution 3

Aleks' workaround works fine, just thought it's worth sharing the code

node ("docker") {
    def sendOk = {
        String stage -> slackSend color: 'good', message: stage + " completed, project - ${env.JOB_NAME}:1.0.${env.BUILD_NUMBER}"
    }
    def sendProblem = {
        String stage, error -> slackSend color: 'danger', message: stage + " did not succeed, project - ${env.JOB_NAME}:1.0.${env.BUILD_NUMBER}, error: ${error}, Find details here: ${env.BUILD_URL}"
    }
    def exec = {
        work, stageName -> 
            stage (stageName) {
                try {
                    work.call();
                    sendOk(stageName)
                }
                catch(error) {
                    sendProblem(stageName, error)
                    throw error
                }
            }
    }
    exec({
        git credentialsId: 'github-root', url: 'https://github.com/abc'
        dir ('src') {
            git credentialsId: 'github-root', url: 'https://github.com/abc-jenkins'
        }
        sh "chmod +x *.sh"
    }, "pull")
    exec({ sh "./Jenkinsfile-clean.sh \"1.0.${env.BUILD_NUMBER}\"" }, "clean")
    exec({ sh "./Jenkinsfile-unit.sh \"1.0.${env.BUILD_NUMBER}\"" }, "unit")
    exec({ sh "./Jenkinsfile-build.sh \"1.0.${env.BUILD_NUMBER}\"" }, "build")
    exec({ sh "./Jenkinsfile-dockerize.sh \"1.0.${env.BUILD_NUMBER}\"" }, "dockerize")
    exec({ sh "./Jenkinsfile-push.sh \"1.0.${env.BUILD_NUMBER}\"" }, "push")
    exec({ sh "./Jenkinsfile-prod-like.sh \"1.0.${env.BUILD_NUMBER}\"" }, "swarm")
}
Share:
36,452
Aleks
Author by

Aleks

Updated on November 14, 2020

Comments

  • Aleks
    Aleks over 3 years

    Let's say we have the following Jenkinsfile:

    stage name: "Cool stage"
        sh 'whoami'
    stage name: "Better stage"
        def current_stage = getCurrentStageName()
        echo "CONGRATULATIONS, you are on stage: $current_stage"
    

    The question is how to implement getCurrentStageName(). I know, that I can get an access to build run-time using currentBuild.rawBuild. But how to get stage name from that point?

    I need this for some customization in email notifications, so that I can always catch failed stage name and include it into email body.