web-dev-qa-db-fra.com

Nom de l’étape d’accès pendant la construction du pipeline Jenkins

Disons que nous avons la Jenkinsfile suivante:

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

La question est de savoir comment mettre en œuvregetCurrentStageName(). Je sais que je peux obtenir un accès pour créer une exécution à l’aide de currentBuild.rawBuild. Mais comment obtenir le nom de la scène à partir de là?

J'en ai besoin pour pouvoir personnaliser les notifications par courrier électronique, de manière à pouvoir toujours récupérer le nom de stade défaillant et l'inclure dans le corps du message.

19
Aleks

Vous pouvez maintenant le faire de manière intégrée, depuis Jenkins 2.3. Ainsi: 

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

Pour plus d'informations, voir: https://issues.jenkins-ci.org/browse/JENKINS-44456

11
Jansky

Cela devrait fonctionner à partir d'une bibliothèque partagée de pipeline:

#!/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)
}

Exemple d'utilisation:

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

    stage('Stage Two'){
        echo getCurrentStage()
    }
}
6
Trevor Howard

La solution de contournement d'Aleks fonctionne bien, j'ai juste pensé que partager le code valait la peine

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")
}
4

En guise de solution de contournement, dans l'email d'échec, j'inclus un lien vers la page Pipeline Steps. Cette page montre clairement les boules vertes et rouges pour chaque étape, ce qui permet au destinataire de l’email de déterminer facilement l’étape qui a échoué.

Dans l'exemple de corps de courrier électronique suivant, le lien FlowGraphTable relie à Pipeline Steps:

def details = """<p>Job '${env.JOB_NAME}', build ${env.BUILD_NUMBER} result was ${buildStatus}.
  Please scrutinize the build and take corrective action.</p>
  <p>Quick links to the details:
  <ul>
    <li><a href="${env.JOB_URL}">${env.JOB_NAME} job main page</a></li>
    <li><a href="${env.BUILD_URL}">Build ${env.BUILD_NUMBER} main page</a></li>
    <ul>
      <li><a href="${env.BUILD_URL}console">Console output</a></li>
      <li><a href="${env.BUILD_URL}changes">Git changes</a></li>
      <li><a href="${env.BUILD_URL}flowGraphTable">Pipeline steps</a>.
          This page will show you which step failed, and give you access
          to the job workspace.</li>
    </ul>
  </ul></p>"""

Ceci est un extrait de mon implémentation de notifyBuild() que BitwiseMan de CloudBees présente dans son article, Envoi de notifications dans le pipeline .

0
John McGehee