Sintaxe de Pipeline Jenkins: Um Guia Abrangente para Iniciantes

Desmistifique a sintaxe de pipeline Jenkins com este guia abrangente para iniciantes. Aprenda o essencial dos pipelines Declarativos e Scripted, incluindo agentes, estágios, passos, pós-ações, ambientes, parâmetros e melhores práticas. Capacite-se a construir fluxos de trabalho CI/CD robustos e eficazes com exemplos práticos e conselhos acionáveis.

Sintaxe de Pipeline Jenkins: Um Guia Abrangente para Iniciantes

A sintaxe de Pipeline Jenkins permite descrever seu processo de build, teste e deploy em um Jenkinsfile que vive com seu código. Isso é importante porque suas alterações de pipeline podem ser revisadas, versionadas e revertidas como código de aplicação.

Se você é novo em pipelines Jenkins, comece com a sintaxe de Pipeline Declarativo. Ela é estruturada, legível e cobre a maioria dos fluxos de trabalho CI/CD sem exigir muito conhecimento de Groovy.

Pipeline Declarativo vs. Scriptado

Jenkins suporta dois estilos de pipeline.

O Pipeline Declarativo usa uma estrutura estrita pipeline { ... }. É o melhor padrão para a maioria das equipes porque o Jenkins pode validar a forma do arquivo e mostrar estágios de forma limpa na interface do usuário.

O Pipeline Scriptado usa Groovy dentro de blocos node { ... }. Ele oferece mais controle, mas é mais fácil criar pipelines difíceis de manter se sua equipe não estiver confortável com Groovy.

Use o Declarativo primeiro. Recorra ao Scriptado apenas quando precisar de lógica que o Declarativo não consegue expressar de forma limpa.

Um Pipeline Declarativo Mínimo

Um Jenkinsfile básico tem um agente, estágios e etapas:

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                echo 'Construindo a aplicação'
                sh 'mvn clean package'
            }
        }

        stage('Test') {
            steps {
                sh 'mvn test'
            }
        }
    }
}

agent any diz ao Jenkins para executar o pipeline em qualquer agente disponível. Cada stage aparece separadamente na interface do Jenkins. O bloco steps contém os comandos que o Jenkins executa.

Em agentes Windows, use bat em vez de sh:

bat 'gradlew.bat test'

A Diretiva agent

A diretiva agent decide onde o pipeline ou estágio é executado.

Executar em qualquer agente disponível:

agent any

Executar em um agente com um rótulo específico:

agent { label 'linux && docker' }

Pular um agente global e escolher um por estágio:

pipeline {
    agent none

    stages {
        stage('Build') {
            agent { label 'linux' }
            steps {
                sh './build.sh'
            }
        }
    }
}

agent none é útil quando diferentes estágios precisam de ambientes diferentes, como Linux para builds e Windows para testes de instalador.

Estágios e Etapas

Use estágios para dividir o pipeline em trabalho que um desenvolvedor possa entender de relance: checkout, build, teste, pacote, deploy.

stages {
    stage('Checkout') {
        steps {
            checkout scm
        }
    }

    stage('Testes Unitários') {
        steps {
            sh 'npm test'
        }
    }
}

Mantenha os estágios significativos. Um estágio chamado Executar com cinquenta comandos é difícil de depurar. Um pipeline com vinte pequenos estágios é barulhento. Busque estágios que correspondam a pontos de verificação reais do fluxo de trabalho.

Variáveis de Ambiente

Use environment para valores que vários estágios precisam:

pipeline {
    agent any

    environment {
        APP_NAME = 'orders-api'
        IMAGE = "registry.example.com/team/orders-api:${env.BUILD_NUMBER}"
    }

    stages {
        stage('Build Image') {
            steps {
                sh 'docker build -t "$IMAGE" .'
            }
        }
    }
}

Em strings Groovy, você pode ler variáveis através de env.APP_NAME. Em etapas de shell, o Jenkins exporta variáveis de ambiente para que $APP_NAME e $IMAGE funcionem dentro do shell.

Não coloque segredos em environment. Use Credenciais Jenkins com withCredentials.

Parâmetros

Parâmetros permitem que alguém escolha valores ao iniciar um build manualmente:

pipeline {
    agent any

    parameters {
        string(name: 'BRANCH_NAME', defaultValue: 'main', description: 'Branch Git para build')
        booleanParam(name: 'RUN_TESTS', defaultValue: true, description: 'Executar testes unitários')
        choice(name: 'DEPLOY_ENV', choices: ['dev', 'staging', 'prod'], description: 'Ambiente alvo')
    }

    stages {
        stage('Mostrar Entradas') {
            steps {
                echo "Branch: ${params.BRANCH_NAME}"
                echo "Alvo de deploy: ${params.DEPLOY_ENV}"
            }
        }
    }
}

Use parâmetros para coisas que devem variar entre execuções. Não os use para contornar a revisão de alterações de produção.

Estágios Condicionais com when

A diretiva when controla se um estágio é executado:

stage('Deploy para Produção') {
    when {
        branch 'main'
    }
    steps {
        sh './deploy-prod.sh'
    }
}

Você também pode usar uma expressão:

stage('Test') {
    when {
        expression { return params.RUN_TESTS }
    }
    steps {
        sh 'npm test'
    }
}

Coloque when no estágio, não dentro de steps.

Pós-Ações

Blocos post são executados após um estágio ou pipeline terminar. Eles são úteis para publicar relatórios de teste, arquivar evidências de build e limpar.

pipeline {
    agent any

    stages {
        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    junit 'target/surefire-reports/*.xml'
                }
            }
        }
    }

    post {
        failure {
            echo 'Pipeline falhou'
        }
        always {
            cleanWs()
        }
    }
}

junit publica resultados de teste mesmo quando os testes falham. cleanWs() vem do plugin Workspace Cleanup, então instale esse plugin antes de usá-lo.

Opções

Use options para definir o comportamento do pipeline:

pipeline {
    agent any

    options {
        timestamps()
        timeout(time: 30, unit: 'MINUTES')
        disableConcurrentBuilds()
        buildDiscarder(logRotator(numToKeepStr: '20'))
    }

    stages {
        stage('Build') {
            steps {
                sh './build.sh'
            }
        }
    }
}

Essas opções tornam os logs mais fáceis de ler, param builds travados, previnem execuções sobrepostas do mesmo job e limitam o histórico de builds antigos.

Um Pipeline Prático para Iniciantes

Este exemplo faz checkout do código, constrói um projeto Java, publica resultados de teste e arquiva o JAR empacotado:

pipeline {
    agent { label 'linux' }

    options {
        timestamps()
        timeout(time: 30, unit: 'MINUTES')
        disableConcurrentBuilds()
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }

        stage('Publicar') {
            steps {
                junit 'target/surefire-reports/*.xml'
                archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
            }
        }
    }
}

Este é um ponto de partida melhor do que um pipeline de deploy gigante. Uma vez que o build seja confiável, adicione publicação de imagem, varreduras de segurança ou estágios de deploy.

Fundamentos do Pipeline Scriptado

Um Pipeline Scriptado simples se parece com isso:

node('linux') {
    stage('Checkout') {
        checkout scm
    }

    stage('Build') {
        sh 'mvn clean package'
    }
}

Não envolva um bloco pipeline {} Declarativo dentro de um Pipeline Scriptado. Mantenha os dois estilos separados, a menos que você tenha uma razão específica e testada para misturar pequenas seções scriptadas dentro de blocos script { ... } Declarativos.

Bons Hábitos de Pipeline

Armazene o Jenkinsfile no controle de versão. Mantenha segredos nas Credenciais Jenkins. Dê aos estágios nomes que correspondam ao trabalho que eles fazem. Publique relatórios em blocos post para que falhas ainda deixem evidências úteis. Adicione timeouts antes que um build trave durante a noite.

A maioria dos problemas de pipeline para iniciantes vem de suposições ocultas: uma ferramenta existe em um agente, mas não em outro, um segredo está codificado, ou um relatório só é publicado em caso de sucesso. Torne essas suposições explícitas no pipeline, e o Jenkins se torna muito mais confiável.