Jenkins – parte 3

jenkins-1_abertura

Esta é a última parte desta série sobre o Jenkins e é também onde justamente tudo aquilo ensaiado na parte anterior será efetivamente colocada em prática com a criação de um job contendo várias etapas, com execução disparada por um outro e, para encerrar algo mais complexo que o Freestyle Project, a execução em pipeline.

Então é iniciar a máquina virtual com vagrant up para começar a usá-lo.

Enquanto a máquina virtual é iniciada algumas rápidas palavras sobre a interface com o usuário do Jenkins.

Sobre a interface

Deliberadamente estou evitando de detalhá-la, explicar onde todas as coisas se encontram ou mesmo o que cada opção disponível faz. Tudo or um motivo muito bem simples: o Jenkins atualmente tem a mesma aparência do Hudson (a ferramenta no qual ele foi baseado)¹ e existe um projeto interno, o Blue Ocean, cujo objetivo é recriar esta mesma interface.

(¹) Mais uma daquelas histórias sobre o destino de projetos mantidos pela Sun Microsystems após a aquisição da Oracle.

Sofisticando um job

É possível executar mais do que uma ação dentro de um job. Isto é feito justamente acrescentando novos campos Execute Shell dentro de Build. Por exemplo, vá em create new jobs ou New Item, nomeie este novo job como “git-example-2”. Vá até a última opção, que copia as configurações de  um job já existente — eba! –, digite “git-example” para indicar quem será copiado e em seguida pressione o botão OK.

Na página do job altere a ramificação — branch — do repositório Git para usar “testing” ao invés de “master” para coisas diferentes acontecerem:

jenkins-3_git-example-2-1

Em seguida acrescente o script que cuidará da tarefa de realizar os testes no código:

jenkins-3_git-example-2-2

O Jenkins cuidará de executá-los na sequência:

jenkins-3_git-example-2-3.png

A desvantagem deste caso será a de sempre precisar consultar o Console Output para saber exatamente em qual etapa um eventual problema aconteceu.

Jobs engatilhados

A alternativa é separá-los e tornar a execução do segundo job dependente da do primeiro — é possível definir até o estado desejado. Neste caso duplique o job anterior, o “git-example-2”, com o nome de “git-example-build” e altere a Execute Shell com a rotina de testes para:

cp git-example/example /tmp
cp git-example/test /tmp

Assim ela passará a copiar tanto o binário gerado quanto o script de testes para o “/tmp” — assim, também, não precisarei descobrir onde no sistema de arquivos fica exatamente o workspace (os arquivos) deste job.

jenkins-3_git-example-build

Aí é criar um novo job como Freestyle project chamando “git-example-test”.

Em Build Triggers marque a opção Build after other projects are built e indique “git-example-build” como o job (projeto) que deve ser observado:

jenkins-3_git-example-test-1

Por último, em Build, insira o script que executará rotina de testes:

jenkins-3_git-example-test-2.png

Agora sempre que o job “git-example-build” for executado com sucesso o Jenkins automaticamente chamará o “git-example-test” para executar a rotina de testes.

O que pode ser constatado nos logs:

jenkins-3_git-example-test-3

Haverá referências (“Started by upstream project …”) tanto para quem invocou como para quem foi invocado.

Pipelines

Mas e se você precisar interligar mais do que dois (ou três) jobs? Ou precisar de uma visão do conjunto daquilo que está sendo executado? A opção é usar o pipeline — e que anteriormente se chamava workflow — onde você encadeia ações a serem executadas como compilação, teste, implantação etc como se estivesse interligando jobs uns aos outros.

Criando um pipeline

Na versão a 2.32.X,um pipeline pode ser criado da seguinte forma.

Vá em create new jobs ou New Item, nomeie o job como “pipeline-example”, selecione Pipeline e pressione o botão OK. Em Build Triggers deixe marcada a opção Pool SCM e com o valor:

H/5 * * * *

Em Pipeline selecione Pipeline script from SCM em Definition e como SCM o Git. O repositório é o mesmo, o “https://github.com/plainspooky/jenkins.git”, e a diferença está na ramificação utilizada, a “*/jenkinsfile”².

jenkins-3_pipeline-example-1.png

Daí pressione o botão Save para finalizar a criação deste job.

(2) Sim, estou usando o Git para guardar diversas versões dos arquivos, uma para cada tipo de job sendo utilizado.

O arquivo Jenkinsfile

O Jenkinsfile contém a definição do que será realizado em uma pipeline e utiliza uma linguagem específica para descrever as ações que no caso específico deste exemplo é assim:

pipeline {
    agent any 

    stages {
        stage('Build') { 
            steps { 
                sh 'cd git-example ; sh ./build' 
            }
        }
        stage('Test'){
            steps {
                sh 'cd git-example ; sh ./test'
            }
        }
        stage('Deploy') {
            steps {
                sh 'echo "Deploy..."'
            }
        }
    }
}

Nele estão definidos três estágios — em stage — que serão executados sequencialmente e que são:

  • Build — Se encarrega de compilar o programa;
  • Test — Executa a rotina de “teste unitário” (sim com aspas mesmo) e
  • Deploy — Apenas escreve ‘Deploy’ mas poderia colocar o binário, compactá-lo para mandar por e-mail etc mas eu estava totalmente sem imaginação! 🙂

Esta mesma definição poderá ser inserida diretamente usando a opção Pipeline script em Definition mas achei prático deixá-la diretamente no repositório — Qual das duas usar? Dependerá diretamente das características do projeto.

O pipeline em ação

Com tudo devidamente configurado o job executou uma primeira vez (#9) e sem erros. Logo depois inseri alguns erros propositais no código só para depois ir consertando (#10, #11 e #12).

jenkins-3_pipeline-example-2

Do ponto de vista das ações que foram executados no pipeline elas são idênticas às execuções dos outros jobs. A diferença aqui, além de defini-las em uma linguagem própria, é que elas estão totalmente integradas e a informação gerada centralizada em um único ponto.

Intervenção humana

E se algum passo manual for necessário? Uma autorização ou mesmo algo que ocorra por fora do Jenkins?

É possível implementar uma pausa dentro do próprio job com o comando input.No caso do exemplo anterior edite o arquivo “Jenkinsfile” e entre os estágios Sanity check e Test e Deploy inclua:

       ...
       stage('Sanity check') {
            steps {
                input "Tudo parece ok?"
            }
        }
        ...

Quando o processamento chegar ao estágio chamado de Sanity check o processamento do job será pausado e o Jenkins ficará aguardando que um ser humano informe que tudo está certo pressionando Proceed para que que ele prossiga ou então Abort para interrompê-lo.

jenkins-3_pipeline-example-3

Neste caso, após a confirmação ele retorna à execução normal do job até encerrá-lo ou encontrar mais um outro comando input.

jenkins-3_pipeline-example-4

Claro, o tempo esperando pela resposta não será considerado para fins de registro.

Finalizando

Aqui se encerra esta introdução ao Jenkins contemplando instalação, configuração, conexão ao Git (apesar de ter usado um repositório no GitHub outros serviços podem ser utilizados do mesmo jeito), crianção de jobs bem simples, de jobs “não tão simples” e até mesmo a configuração de uma pipeline.

É certo que meus exemplos foram deixados relativamente simples para justamente não tirar o foco da ferramenta. O mesmo também se aplica aos plugins do Jenkins que nem chegaram a ser utilizados mas que conseguem expandir consideravelmente as funcionalidades da ferramenta.

Não se esqueça do vagrant halt para encerrar a máquina virtual e até!

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s