Category Archives: Nerd

Jenkins Pipeline + Slack

Para el desarrollo de Get-On usamos varias herramientas muy copadas, pero estamos enamorados especialmente de dos: Jenkins y Slack.

Hace un tiempo hicimos el upgrade a la versión 2.x de Jenkins y empezamos a usar el pipeline y su famoso Jenkinsfile . Hasta ahí, todo iba perfecto, hasta que caímos en la cuenta que cuando un build fallaba, no nos avisaba en nuestro canal de Slack. Ni tampoco nos avisaba cuando arreglábamos el problema.

Y no había nadie a quien culpar, solo que nuestro Jenkinsfile era muy básico.

Notificar algo por Slack desde el Jenkinsfile es algo realmente fácil. Lo que no es tan fácil es que te avise solamente si cambió el estado del build (se rompió o se volvió a arreglar, o fallaron los tests que no venían fallando, etc). Y eso es lo que queríamos lograr.

Creamos un archivo slack.groovy que luego vamos a cargar y a consumir desde el Jenkinsfile. La única magia, es que en el mustNotify pregunta si hay algún cambio entre el  build actual y el resultado del anterior.

slack.groovy

def getLastBuildStatus() {
    return currentBuild.rawBuild.getPreviousBuild()?.getResult().toString()
}

def notifyToSlack(String buildStatus = 'STARTED') {
    buildStatus =  buildStatus ?: 'SUCCESS'
    if (mustNotify(buildStatus)) {
        def color = getColorByStatus(buildStatus)
        slackSend(message: "${env.JOB_NAME} - #${env.BUILD_NUMBER} - ${buildStatus}",
                channel: "#your-channel", color: color, token: "yourToken")
        return
    }
    echo "No debe notificar por Slack"
}

def getColorByStatus(String buildStatus = 'STARTED') {
    if (buildStatus == 'STARTED') {
        //amarillo
        colorCode = '#FFFF00'
    } else if (buildStatus == 'SUCCESS') {
        //verde
        colorCode = '#00FF00'
    } else {
        //rojo
        colorCode = '#FF0000'
    }
    return colorCode;
}

def mustNotify(String buildStatus) {
    def lastBuildStatus = getLastBuildStatus()
    return !buildStatus.equals(lastBuildStatus)
}

return this

Y en el Jenkinsfile directamente lo consumimos de esta manera

Jenkinsfile

#!groovy

stage 'build and tests'

def project
def slack

node {
    def workspace = pwd()
    slack   = load "${workspace}@script/slack.groovy"
    project = load "${workspace}@script/project.groovy"

    try {
        //get things done
    } catch (e) {
        currentBuild.result = "FAILED"
        throw e
    } finally {
        slack.notifyToSlack(currentBuild.result)
    }
}

Y ya con eso solamente, logramos el anhelado deseo de obtener notificaciones solamente cuando el estado cambia. También podés verlo en este Gist.

Vale mencionar que este fragmento de código nos sirvió mucho también.

PD: perdón por los magic strings

Juan Lagostena
Follow me

Juan Lagostena

Director I+D at Bitsense
Director de Investigacion y Desarrollo en Bitsense.
Estudió en la Facultad de Ingeniería de la Universidad de Buenos Aires y es docente de la misma carrera pero en la Universidad Nacional de Avellaneda.
También es bastante nerd, hincha de Quilmes y activo colaborador del proyecto Nahual.
Juan Lagostena
Follow me

Latest posts by Juan Lagostena (see all)