Explicando passo a passo um arquivo Jenkinsfile

Matheus Villela Torres
4 min readFeb 28, 2020

--

Há uns meses atrás fiz uma publicação sobre criação de uma esteira CI/CD para Python usando o Jenkins (link abaixo), mas não foi explicado como escrever um pipeline como código. Nesta publicação tentarei explicar as diferenças entre pipelines (Scripted vs Declarative) e os blocos, seções e diretivas mais usuais.

Scripted vs Declarative

O pipeline do tipo Scripted foi o primeiro a ser implementado como código pelo Jenkins, escrito em groovy e tem como propósito ser uma estrutura de fácil adaptação pelo usuário, sendo de responsabilidade do desenvolvedor criar a estrutura lógica do pipeline.

Para simplificar a vida do engenheiro DevOps, foi criado posteriormente o pipeline do tipo Declarative, também escrito em groovy, mas com uma estrutura definida, e é justamente esse tipo que iremos desbravar aqui.

Outras diferenças entre estes tipos de escrita são bem descritas no link abaixo.

Desmembrando o Pipeline

Caso queira estudar a fundo todas as partes de um pipeline, recomendo a leitura da documentação oficial do Jenkins.

TODOS os pipelines do tipo Declarative começam com um bloco chamado pipeline, como dito no tópico anterior, é necessário seguir com uma estrutura.

pipeline {
/* insert Declarative Pipeline here */
}

Sections

Agent

O agent (computador) nada mais é onde será executado o seu pipeline, no caso descrito abaixo, configuramos o agent como any, ou seja, qualquer agent disponível será escolhido. Caso passe como parâmetro um label, escolhemos assim onde será realizada a execução do pipeline.

Temos dois tipos de agent, o Top Agent e o Stage Agent, a diferença é que se declarado no começo do pipeline, fora dos stages, as opções são carregadas depois de entrar no agent, já se declarado no stage, as opção serão carregadas antes do agent, verificando qualquer condição when, quando existentes.

pipeline {
agent any
}

Parâmetros do agent: any, none, label, docker, dockerfile e kubernetes.

Post

O bloco post define uma ou mais ações a serem executadas no final do pipeline ou do stage, dependendo de onde estiver declarado. O bloco post aceita qualquer uma das seguintes post-conditions: always, changed, fixed, regression, aborted, failure, success, unstable, unsuccessful, e cleanup.

Stages

Contém uma sequência de diretivas do tipo stage. É recomendado ter pelo menos uma diretriz stage. Simples assim.

Steps

A seção steps define um ou mais steps a serem executados em um stage.

Script

Aqui é onde temos a liberdade de realizar um trecho de um pipeline do tipo Scripted dentro do pipeline do tipo Declarative. Isso dá um poder enorme ao desenvolvedor DevOps. No exemplo abaixo utilizamos condicional if para tomar uma ação.

Directives

environment

Assim como o agent, o environment pode ocorrer como uma diretiva global, se for escrito fora do step, ou dentro do step, seguem abaixo as duas condições.

Global:

environment { 
PATH="/home/bitnami/miniconda3/bin:$PATH"
}

Local:

stages {
stage('Load Parameters') {
environment {
PATH="/home/bitnami/miniconda3/bin:$PATH")
}
}
}

options

A diretiva options permite configurar opções específicas do pipeline de dentro do próprio pipeline. Não entraremos a fundo aqui.

parameters

Provê uma lista de parâmetros consumíveis pelo pipeline que o usuário deve prover ao iniciar a execução do pipeline. Não entraremos a fundo aqui.

triggers

Como seu pipeline receberá o trigger, pode-se configurar recorrência temporal, mas para projetos configurados com um webhook a partir do SCM, não é necessário configurá-lo.

stage

Uma das diretivas mais importantes, aqui é configurado a etapa do seu pipeline, e está sempre contida dentro do bloco stages.

input

Ao utilizar essa diretiva, o stage irá aguardar a devolutiva do usuário. Importante caso necessite de aprovação para seguir com o pipeline. Não entraremos a fundo aqui.

when

Esta diretiva permite ao pipeline selecionar qual stage deve ser executado, baseado em condições. No exemplo abaixo vemos que existe uma validação por expressão regular no nome da branch, além de uma condição aninhada (anyOf).

stage('Example Deploy') {
when {
expression { BRANCH_NAME ==~ /(production|staging)/ }
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}

Parallel

Os stages no Declarative pipeline podem ter uma seção paralela contendo uma lista de stages aninhados a serem executados em paralelo. Observe que um stage deve ter uma e apenas uma das seguintes opções: stages, steps, parallel ou matrix.

Pronto! Passamos brevemente pelas estruturas mais utilizadas de um pipeline Jenkins. Nos vemos até a próxima publicação.

--

--