Jenkins API - Get current pipeline stage of the build

Viewed 972

I'm trying to make my build pipeline more useful and I need a way to terminate previous builds if they are not finished yet.

I have the next Job definition:

pipeline {
  stages {
     stage('A'){...}
     stage('B'){...}
     stage('C'){...}
  }
}

And I need to terminate all previous builds if they are not in stage'C'.

I use Jenkins API to get previous builds for a particular job:

@NonCPS
def cancelPreviousBuilds() {
    def buildNumber = env.BUILD_NUMBER.toInteger()
    def currentJob = Jenkins.getInstance().getItemByFullName(env.JOB_NAME)
    currentJob.builds
        .find{ build -> build.isBuilding() && build.number.toInteger() < buildNumber && currentStageName(build) != 'C' }
        .each{ build -> build.doStop() }
}

So my current stopper is the implementation of currentStageName function. I'm not able to get the name of the stage. I've already found some code but it does not work well for me:

@NonCPS
def currentStageName(currentBuild) {
    FlowGraphWalker walker = new FlowGraphWalker(currentBuild.getExecution())
    for (FlowNode flowNode: walker) {
       if(flowNode.isActive()) {
          return flowNode.getDisplayName();
       }
    }
}

FlowNode object does not contain stage name it contains more narrow flow step inside the build.

So the question is: How to get the current stage of previous build for particular Jenkins job?

1 Answers

Given a FlowNode, you can check if it is the start of a stage by checking if node instanceof StepEndNode. If it is, you can use its LabelAction class to get the name of the stage:

    static String getLabel(FlowNode node) {
        LabelAction labelAction = node.getAction(LabelAction.class);
        if (labelAction != null) {
            return labelAction.getDisplayName();
        }
        return null;
    }

I don't think it's useful for your case, but you can also get it from the node that marks the end of a stage (a StepEndNode) by looking up the corresponding start node:

FlowNode startNode = ((StepEndNode) node).getStartNode();
Related