Escrevendo Pipelines Scripted do Jenkins

Beginner

Introdução

O Jenkins suporta dois estilos de Pipeline. O Declarative Pipeline utiliza um bloco estruturado pipeline { ... }, enquanto o Scripted Pipeline utiliza código Groovy com chamadas de node, stage e steps. O Scripted Pipeline é útil quando um fluxo de trabalho exige um controle de fluxo Groovy mais direto.

Neste laboratório, você criará um job de Pipeline chamado scripted-pipeline-demo, executará um pipeline scripted simples e, em seguida, o atualizará com uma condição if e um bloco de limpeza try/finally.

Escrevendo um Pipeline Scripted Básico

Nesta etapa, você escreverá a primeira versão de um Scripted Pipeline. O bloco node solicita que o Jenkins aloque um executor e um workspace. Dentro dele, o stage nomeia uma parte visível do fluxo de trabalho, e o sh executa um comando shell.

Crie o arquivo /home/labex/project/scripted-pipeline.groovy:

cat > /home/labex/project/scripted-pipeline.groovy <<'GROOVY'
node {
    stage('Prepare') {
        echo 'Preparing scripted pipeline'
        sh 'pwd'
    }

    stage('Build') {
        echo 'Building with scripted syntax'
        sh 'echo Compiling scripted pipeline demo'
    }
}
GROOVY

Exiba o arquivo com números de linha para revisar a estrutura:

nl -ba /home/labex/project/scripted-pipeline.groovy

Você deverá ver um bloco node contendo os estágios Prepare e Build.

Criando um Job de Pipeline a partir do Script

Nesta etapa, você criará um job de Pipeline no Jenkins que armazena o script Groovy inline. Os jobs de Pipeline do Jenkins são salvos como XML em /var/jenkins_home/jobs. O Python fará o escape XML do script Groovy antes de gravar a configuração do job, garantindo que caracteres como aspas e chaves sejam preservados com segurança.

Gere a configuração do job de Pipeline:

python3 - <<'PY'
from html import escape
from pathlib import Path

script = Path("/home/labex/project/scripted-pipeline.groovy").read_text()
config = f"""<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job">
  <actions/>
  <description>Run a Jenkins scripted Pipeline example.</description>
  <keepDependencies>false</keepDependencies>
  <properties/>
  <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps">
    <script>{escape(script)}</script>
    <sandbox>true</sandbox>
  </definition>
  <triggers/>
  <disabled>false</disabled>
</flow-definition>
"""
Path("/home/labex/project/scripted-pipeline-config.xml").write_text(config)
PY

Copie a configuração do job para o Jenkins e recarregue:

docker exec jenkins mkdir -p /var/jenkins_home/jobs/scripted-pipeline-demo
docker cp /home/labex/project/scripted-pipeline-config.xml jenkins:/var/jenkins_home/jobs/scripted-pipeline-demo/config.xml
/home/labex/project/reload-jenkins.sh

Confirme se o Jenkins consegue carregar o job de Pipeline:

curl -fsS http://localhost:8080/job/scripted-pipeline-demo/api/json | grep -o '"name":"scripted-pipeline-demo"'

Executando o Pipeline Scripted

Nesta etapa, você disparará o job de Pipeline e inspecionará o resultado. O Jenkins protege as requisições POST com um crumb, portanto, o primeiro comando solicita um crumb e reutiliza o cookie jar correspondente.

Dispare o primeiro build:

CRUMB=$(curl -fsS -c /tmp/jenkins-scripted-build.cookies 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
curl -fsS -b /tmp/jenkins-scripted-build.cookies -H "$CRUMB" -X POST http://localhost:8080/job/scripted-pipeline-demo/build

Aguarde até que o build #1 termine:

until curl -fsS http://localhost:8080/job/scripted-pipeline-demo/1/api/json >/tmp/scripted-build-1.json 2>/dev/null && grep -q '"building":false' /tmp/scripted-build-1.json; do
  echo "Waiting for scripted pipeline build #1..."
  sleep 3
done

Verifique o resultado do build:

curl -fsS http://localhost:8080/job/scripted-pipeline-demo/1/api/json | grep -o '"result":"SUCCESS"'

O resultado bem-sucedido comprova que o Jenkins aceitou a sintaxe do Scripted Pipeline e executou os comandos shell.

Adicionando Fluxo de Controle Groovy

Nesta etapa, você atualizará o Scripted Pipeline com fluxo de controle Groovy. O bloco if decide se o estágio Test deve ser executado. O bloco try/finally garante que a mensagem de limpeza seja executada mesmo se um estágio falhar.

Substitua o script do pipeline por uma versão mais rica:

cat > /home/labex/project/scripted-pipeline.groovy <<'GROOVY'
node {
    def runTests = true

    try {
        stage('Prepare') {
            echo 'Preparing scripted pipeline'
            sh 'pwd'
        }

        stage('Build') {
            echo 'Building with scripted syntax'
            sh 'echo Compiling scripted pipeline demo'
        }

        if (runTests) {
            stage('Test') {
                echo 'Tests enabled by Groovy condition'
                sh 'echo Running scripted pipeline tests'
            }
        }
    } finally {
        echo 'Pipeline cleanup complete'
    }
}
GROOVY

Regere a configuração do job e recarregue o Jenkins:

python3 - <<'PY'
from html import escape
from pathlib import Path

script = Path("/home/labex/project/scripted-pipeline.groovy").read_text()
config = f"""<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job">
  <actions/>
  <description>Run a Jenkins scripted Pipeline example.</description>
  <keepDependencies>false</keepDependencies>
  <properties/>
  <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps">
    <script>{escape(script)}</script>
    <sandbox>true</sandbox>
  </definition>
  <triggers/>
  <disabled>false</disabled>
</flow-definition>
"""
Path("/home/labex/project/scripted-pipeline-config.xml").write_text(config)
PY
docker cp /home/labex/project/scripted-pipeline-config.xml jenkins:/var/jenkins_home/jobs/scripted-pipeline-demo/config.xml
/home/labex/project/reload-jenkins.sh

Confirme se a configuração atualizada do job contém o texto do novo estágio Test:

docker exec jenkins grep -n 'Tests enabled by Groovy condition' /var/jenkins_home/jobs/scripted-pipeline-demo/config.xml

Inspecionando o Log do Pipeline Atualizado

Nesta etapa, você executará o Scripted Pipeline atualizado e inspecionará a saída do console. O log deve mostrar a mensagem condicional do estágio Test e a mensagem de limpeza do bloco finally.

Dispare o segundo build:

CRUMB=$(curl -fsS -c /tmp/jenkins-scripted-build.cookies 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
curl -fsS -b /tmp/jenkins-scripted-build.cookies -H "$CRUMB" -X POST http://localhost:8080/job/scripted-pipeline-demo/build

Aguarde até que o build #2 termine:

until curl -fsS http://localhost:8080/job/scripted-pipeline-demo/2/api/json >/tmp/scripted-build-2.json 2>/dev/null && grep -q '"building":false' /tmp/scripted-build-2.json; do
  echo "Waiting for scripted pipeline build #2..."
  sleep 3
done

Imprima as linhas importantes do console:

curl -fsS http://localhost:8080/job/scripted-pipeline-demo/2/consoleText | grep -E 'Tests enabled|Running scripted pipeline tests|Pipeline cleanup complete|Finished: SUCCESS'

Abra o Firefox na interface Desktop e visite http://localhost:8080/job/scripted-pipeline-demo/2/console. A página do console deve exibir a saída do estágio Test e a mensagem de limpeza.

Saída do console do Jenkins scripted Pipeline

Resumo

Você escreveu um Jenkins Scripted Pipeline com os steps node, stage, echo e sh, executou-o como um job de Pipeline e, em seguida, adicionou fluxo de controle Groovy com if e try/finally. Você verificou ambas as versões do Pipeline através dos resultados de build do Jenkins e da saída do console.