DevTools

Cheatsheet Jenkins

Servidor de automação CI/CD para builds, testes e deploys

Voltar às linguagens
Jenkins
72 cards encontrados
Categorias:
Versões:

Pipeline


9 cards
Pipeline declarativo
pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh 'npm install'
                sh 'npm run build'
            }
        }
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
    }
}

# Estrutura fixa e legível.
# É o formato recomendado.

O pipeline declarativo tem estrutura fixa: pipeline > stages > stage > steps. É o formato recomendado pela legibilidade. agent any define onde executar. Cada stage agrupa passos lógicos do CI/CD.

Environment
environment {
    APP_ENV = 'production'
    DB_HOST = 'db.exemplo.com'
    VERSION = sh(
        script: 'git rev-parse --short HEAD',
        returnStdout: true).trim()
}

stages {
    stage('Build') {
        steps {
            echo "Versão: ${env.VERSION}"
            sh 'echo $APP_ENV'
        }
    }
}

# Também pode ser por stage:
stage('Deploy') {
    environment { DEPLOY_TARGET = 'aws' }
}

environment define variáveis de ambiente. sh(returnStdout: true) captura output de comandos (ex: hash do git). Acede via env.NOME ou $NOME no shell. Pode ser global ou por stage.

Milestone e lock
options {
    disableConcurrentBuilds()
}

stages {
    stage('Deploy') {
        steps {
            // Lock: exclusividade num recurso
            lock('servidor-producao') {
                sh './deploy.sh'
            }

            // Milestone: ordena builds
            milestone(1)
            sh './notificar.sh'
            milestone(2)
        }
    }
}

# lock requer plugin "Lockable Resources"
# milestone aborta builds antigos

disableConcurrentBuilds evita builds simultâneos do mesmo job. lock() (plugin Lockable Resources) dá exclusividade sobre um recurso partilhado. milestone() garante ordem e aborta builds ultrapassados. Essenciais para deploys seguros.

Pipeline scriptado
node {
    stage('Checkout') {
        checkout scm
    }
    stage('Test') {
        try {
            sh 'npm test'
        } catch (Exception e) {
            echo 'Testes falharam'
            throw e
        }
    }
}

# Mais flexível (Groovy puro):
# - if/else, loops, try/catch nativos
# - Sem estrutura fixa
# - Mais difícil de manter
#
# O declarativo cobre 95% dos casos.

O pipeline scriptado usa Groovy puro dentro de node. É mais flexível (if/else, try/catch nativos) mas menos legível. O declarativo cobre a maioria dos casos. Usa script { } dentro do declarativo quando precisas de lógica Groovy.

Diretivas principais
pipeline {
    agent any              // onde executar
    options { }            // comportamento
    parameters { }         // inputs de build
    environment { }        // variáveis
    tools { }              // ferramentas
    triggers { }           // gatilhos

    stages {
        stage('X') {
            when { }       // condição
            input { }      // aprovação
            steps { }      // comandos
            post { }       // pós-ações
        }
    }

    post { }               // pós-ações global
}

O declarativo tem diretivas fixas: agent, options, parameters, environment, tools, triggers, stages e post. Dentro de cada stage: when, input, steps, post.

Options
options {
    timeout(time: 30, unit: 'MINUTES')
    disableConcurrentBuilds()
    buildDiscarder(
        logRotator(numToKeepStr: '10'))
    timestamps()
    retry(2)
    skipDefaultCheckout(true)
    ansiColor('xterm')
}

# timeout: aborta após 30 min
# disableConcurrentBuilds: 1 build de cada vez
# buildDiscarder: guarda só 10 builds
# timestamps: hora em cada linha de log
# retry: repete em caso de falha

options define comportamento global. timeout aborta builds longos. disableConcurrentBuilds evita execuções simultâneas. buildDiscarder limita builds guardados. timestamps e ansiColor melhoram os logs.

Tools
# Pré-configurar em:
# Manage Jenkins > Tools

tools {
    nodejs 'NodeJS-20'
    jdk 'JDK-17'
    maven 'Maven-3.9'
    gradle 'Gradle-8'
}

stages {
    stage('Build') {
        steps {
            // node, java, mvn estão no PATH
            sh 'node --version'
            sh 'mvn clean package'
        }
    }
}

# O Jenkins instala/configura
# as ferramentas automaticamente

tools adiciona ferramentas ao PATH do build. Configura em Manage Jenkins > Tools (nome + versão). Suporta nodejs, jdk, maven, gradle. O Jenkins pode instalá-las automaticamente.

Parâmetros
parameters {
    string(name: 'BRANCH',
        defaultValue: 'main',
        description: 'Branch a buildar')
    booleanParam(name: 'DEPLOY',
        defaultValue: false)
    choice(name: 'ENV',
        choices: ['dev', 'staging', 'prod'])
    password(name: 'SENHA',
        defaultValue: '')
}

stages {
    stage('Deploy') {
        steps {
            echo "Branch: ${params.BRANCH}"
            echo "Ambiente: ${params.ENV}"
        }
    }
}

parameters cria campos no formulário de build. Tipos: string, booleanParam, choice, password. Acede via params.NOME. O primeiro build cria os campos; os seguintes mostram o formulário.

Script block (Groovy)
stage('Lógica') {
    steps {
        script {
            def resultado = sh(
                script: 'cat versao.txt',
                returnStdout: true).trim()

            if (resultado.startsWith('2.')) {
                echo 'Versão maior!'
            } else {
                echo 'Versão antiga'
            }

            ['a', 'b', 'c'].each { item ->
                echo "Item: ${item}"
            }
        }
    }
}

# script { } permite Groovy completo
# dentro do pipeline declarativo

script { } abre um bloco Groovy dentro do declarativo. Permite if/else, loops e variáveis (def). Essencial para lógica complexa que o declarativo não cobre. Usa com moderação para manter legibilidade.

Stages e Steps


9 cards
Steps comuns
steps {
    sh 'comando bash'          // Linux/Mac
    bat 'comando windows'      // Windows
    powershell 'Get-ChildItem' // PowerShell

    echo "Mensagem no log"
    sleep(time: 10, unit: 'SECONDS')

    // Capturar output:
    def out = sh(
        script: 'ls -la',
        returnStdout: true)

    // Falhar propositadamente:
    error("Algo correu mal")
}

sh executa bash, bat executa Windows CMD, powershell executa PowerShell. echo imprime. sh(returnStdout: true) captura output. error() falha o build com mensagem. sleep pausa.

Artefactos
stage('Build') {
    steps {
        sh 'npm run build'
        // Guardar artefactos do build:
        archiveArtifacts artifacts: 'dist/**',
            fingerprint: true
    }
}

post {
    success {
        archiveArtifacts 'build/*.jar'
    }
}

// Noutro job, descarregar:
// copyArtifacts projectName: 'job-build',
//     filter: 'dist/**'

// Artefactos ficam na página do build

archiveArtifacts guarda ficheiros do build (binários, relatórios) no Jenkins. fingerprint: true permite rastrear. copyArtifacts (plugin) descarrega noutro job. Útil para passar binários entre stages de deploy.

Retry e timeout em steps
steps {
    // Repetir até 3 vezes:
    retry(3) {
        sh 'npm install'
    }

    // Timeout só neste passo:
    timeout(time: 5, unit: 'MINUTES') {
        sh './testes-lentos.sh'
    }

    // Esperar por condição:
    waitUntil {
        def r = sh(script: 'curl -s http://app/health',
            returnStatus: true)
        return r == 0
    }
}

# retry: útil para comandos instáveis
# waitUntil: polling até sucesso

retry(n) repete um passo até n vezes — útil para comandos instáveis (npm, downloads). timeout limita um passo específico. waitUntil faz polling até a condição ser verdadeira (ex: esperar que um serviço arranque).

Checkout e Git
steps {
    // Checkout do SCM configurado no job:
    checkout scm

    // Git explícito:
    git branch: 'main',
        url: 'https://github.com/user/repo'

    // Com credenciais:
    git branch: 'main',
        url: 'git@github.com:user/repo.git',
        credentialsId: 'ssh-key-id'

    // Comandos git manuais:
    sh 'git log --oneline -5'
    sh 'git rev-parse --short HEAD'
}

checkout scm usa o repositório configurado no job (padrão em Multibranch). git faz checkout explícito com branch e URL. credentialsId autentica. Comandos git manuais dão o hash do commit e histórico.

Testes e relatórios
stage('Testes') {
    steps {
        sh 'npm test -- --ci --reporters=jest-junit'
    }
    post {
        always {
            // Publicar resultados JUnit:
            junit 'reports/junit.xml'

            // Cobertura (plugin Cobertura):
            publishHTML(target: [
                reportDir: 'coverage/lcov-report',
                reportFiles: 'index.html',
                reportName: 'Cobertura'
            ])
        }
    }
}

# junit mostra gráfico de testes no job
# Sempre em post > always (mesmo se falhar)

junit publica resultados de testes (requer XML no formato JUnit). Mostra gráficos e tendências no job. Publica em post > always para capturar mesmo quando os testes falham. publishHTML publica relatórios de cobertura.

Parallel stages
stage('Testes') {
    parallel {
        stage('Unit') {
            steps { sh 'npm run test:unit' }
        }
        stage('E2E') {
            steps { sh 'npm run test:e2e' }
        }
        stage('Lint') {
            steps { sh 'npm run lint' }
        }
    }
}

# Os 3 stages correm em simultâneo.
# Se um falhar, os outros continuam
# (failFast: false por padrão).

# Para abortar todos ao primeiro erro:
# failFast true

parallel executa stages em simultâneo — ideal para testes independentes. Reduz muito o tempo total. Por padrão, uma falha não aborta os outros. failFast true aborta todos ao primeiro erro. Cada stage paralelo pode ter o seu próprio agent.

Stash e unstash
stage('Build') {
    steps {
        sh 'npm run build'
        // Guardar ficheiros para depois:
        stash name: 'build-output',
            includes: 'dist/**'
    }
}

stage('Deploy') {
    agent { label 'prod-server' }
    steps {
        // Recuperar noutro agente:
        unstash 'build-output'
        sh './deploy.sh'
    }
}

# stash/unstash partilha ficheiros
# entre stages/agentes diferentes

stash guarda ficheiros temporariamente; unstash recupera. Essencial quando stages correm em agentes diferentes (o workspace não é partilhado). Para ficheiros grandes ou persistentes prefere archiveArtifacts.

Input (aprovação manual)
stage('Deploy Prod') {
    input {
        message "Fazer deploy para produção?"
        ok "Sim, deploy!"
        submitter 'admin,devops'
        parameters {
            string(name: 'NOTA', defaultValue: '')
        }
    }
    steps {
        echo "Nota: ${params.NOTA}"
        sh './deploy.sh prod'
    }
}

# O pipeline pausa até alguém aprovar.
# submitter restringe quem pode aprovar.

input pausa o pipeline para aprovação manual — essencial antes de deploys em produção. submitter restringe quem pode aprovar. Pode aceitar parameters adicionais. O build fica em espera até alguém clicar em ok.

Workspace e diretórios
steps {
    // Diretório atual (workspace):
    echo "Workspace: ${env.WORKSPACE}"

    // Executar noutro diretório:
    dir('frontend') {
        sh 'npm install'
        sh 'npm run build'
    }

    // Diretório temporário:
    ws('/tmp/build-area') {
        sh 'make'
    }

    // Criar ficheiro:
    writeFile file: 'versao.txt',
        text: "${env.BUILD_NUMBER}"

    // Ler ficheiro:
    def conteudo = readFile('versao.txt')
}

dir() executa passos noutro diretório. ws() muda o workspace. writeFile/readFile manipulam ficheiros sem shell. env.WORKSPACE é o diretório raiz do build. Útil para monorepos com várias pastas.

Triggers


9 cards
Cron (agendamento)
triggers {
    // Build diário às 2h (dias úteis):
    cron('H 2 * * 1-5')

    // A cada 15 minutos:
    cron('H/15 * * * *')

    // Domingo à meia-noite:
    cron('H 0 * * 0')
}

# Formato: MINUTO HORA DIA MÊS DIA_SEMANA
#
# H = hash — distribui a carga
# (evita todos os jobs à mesma hora)
#
# H/15 = a cada 15 min (hora variável)

cron agenda builds periódicos. Formato: MINUTO HORA DIA MÊS DIA_SEMANA. O H (hash) distribui a carga para evitar picos. H/15 executa a cada 15 minutos. Ideal para builds noturnos e tarefas regulares.

Sintaxe cron Jenkins
# MINUTO HORA DIA MÊS DIA_SEMANA

H/15 * * * *    # a cada 15 min
H 2 * * 1-5     # 2h, segunda a sexta
H 0 * * 0       # domingo à meia-noite
H 8 1 * *       # dia 1 de cada mês, 8h
H */4 * * *     # a cada 4 horas
0 12 * * 1      # segunda ao meio-dia (exato)

# Campos:
# MINUTO: 0-59   HORA: 0-23
# DIA: 1-31      MÊS: 1-12
# DIA_SEMANA: 0-7 (0 e 7 = domingo)

# H = hash (distribui carga)
# * = qualquer valor
# 1-5 = intervalo   */4 = passo

A sintaxe cron do Jenkins tem 5 campos: MINUTO HORA DIA MÊS DIA_SEMANA. H distribui a carga; usa 0 para hora exata. Suporta intervalos (1-5) e passos (*/4). Dia da semana: 0 e 7 são domingo.

Desativar e silenciar
options {
    // Não executar builds concorrentes:
    disableConcurrentBuilds()

    // Desativar o job (via UI ou API):
    // http://jenkins/job/NOME/disable
    // http://jenkins/job/NOME/enable
}

// Silenciar um stage (sem log verboso):
stage('Limpeza') {
    steps {
        sh 'rm -rf cache/'
    }
}

// Pausar builds durante manutenção:
// Manage Jenkins > "Quiet Down"
// (termina builds ativos, não inicia novos)

disableConcurrentBuilds evita builds simultâneos. Desativa jobs via UI ou API (/disable). Quiet Down põe o Jenkins em manutenção — termina builds ativos e não inicia novos. Útil para atualizações do servidor.

Poll SCM
triggers {
    // Verificar mudanças no Git
    // a cada 5 minutos:
    pollSCM('H/5 * * * *')
}

# pollSCM faz "git ls-remote" periódico.
# Só dispara build se houver mudanças.

# Comparação:
# - cron:    build sempre (mesmo sem mudanças)
# - pollSCM: build só se houver commit novo

# pollSCM consome recursos do servidor.
# Prefere webhooks quando possível.

pollSCM verifica o repositório periodicamente e só dispara build se houver mudanças. Usa a mesma sintaxe do cron. Consome recursos (polling). Prefere webhooks quando o Git server suporta.

Webhook genérico
triggers {
    // GitLab:
    gitlab(triggerOnPush: true,
        triggerOnMergeRequest: true)

    // Bitbucket:
    bitbucketPush()
}

# Webhook genérico (qualquer serviço):
# URL do job + /build:
# http://jenkins/job/MEU-JOB/build
#
# Com token de segurança:
# http://jenkins/job/MEU-JOB/build?token=SEGREDO
#
# No job: Build Triggers >
#   "Trigger builds remotely"
#   Authentication Token: SEGREDO

Para GitLab usa gitlab(), para Bitbucket usa bitbucketPush(). Qualquer serviço pode disparar via URL /job/NOME/build com um token de segurança. Ativa "Trigger builds remotely" no job e define o token.

GitHub webhook
triggers {
    githubPush()
}

# Configuração no GitHub:
# Repo > Settings > Webhooks > Add webhook
# Payload URL:
#   http://jenkins:8080/github-webhook/
# Content type: application/json
# Events: Just the push event

# O Jenkins precisa do plugin "GitHub".
# O URL termina SEMPRE em /github-webhook/

# Vantagem sobre pollSCM:
# - Instantâneo (push, não polling)
# - Sem carga no servidor

githubPush() dispara o build via webhook. Configura no GitHub em Settings > Webhooks com o URL http://jenkins/github-webhook/. É instantâneo (push) e não consome recursos com polling. Requer o plugin GitHub.

Trigger por parâmetros
# Disparar com parâmetros via API:
curl -X POST \
  -u "user:token" \
  "http://jenkins/job/DEPLOY/buildWithParameters?ENV=prod&BRANCH=main"

# No Jenkinsfile, os parâmetros
# chegam automaticamente:
parameters {
    string(name: 'ENV', defaultValue: 'dev')
    string(name: 'BRANCH', defaultValue: 'main')
}

stages {
    stage('Deploy') {
        steps {
            echo "Deploy ${params.ENV} de ${params.BRANCH}"
        }
    }
}

Dispara builds parametrizados via buildWithParameters na API. Os valores chegam em params.NOME. Útil para integrar com scripts externos, chatops e outras ferramentas. Combina com token para segurança.

Upstream (outro job)
triggers {
    // Executar quando 'job-pai' terminar:
    upstream(
        upstreamProjects: 'job-pai',
        threshold: hudson.model.Result.SUCCESS
    )
}

# threshold: resultado mínimo
# - Result.SUCCESS
# - Result.UNSTABLE
# - Result.FAILURE

# Vários projetos:
# upstreamProjects: 'job-a, job-b'

# Cria cadeias de jobs:
# build-lib -> build-app -> deploy

upstream dispara o job quando outro termina. threshold define o resultado mínimo (geralmente SUCCESS). Aceita múltiplos projetos separados por vírgula. Permite criar cadeias de dependência entre jobs.

Multibranch triggers
// Em Multibranch Pipeline, os triggers
// são configurados na organização/pasta,
// não no Jenkinsfile.

// O Jenkinsfile deteta o contexto:
when {
    branch 'main'           // só main
}

when {
    changeRequest()         // só em PRs
}

when {
    branch pattern: 'release/.*',
        comparator: 'REGEXP'
}

// Multibranch cria um job por branch
// e faz scan periódico do repositório
// (ou via webhook)

Em Multibranch Pipeline, o Jenkins cria um job por branch/PR automaticamente. O scan do repositório é configurado na pasta. Usa when no Jenkinsfile para controlar que branches executam. changeRequest() deteta pull requests.

Agentes e Nós


9 cards
Tipos de agent
pipeline {
    // Qualquer nó disponível:
    agent any

    // Sem nó global (define por stage):
    agent none

    // Nó com label específica:
    agent { label 'linux' }

    // Dentro de contentor Docker:
    agent {
        docker { image 'node:20' }
    }

    // Nó específico pelo nome:
    agent { node { label 'build-server-1' } }
}

agent define onde o pipeline executa. any usa qualquer nó. none obriga a definir por stage. label seleciona nós com essa etiqueta. docker executa dentro de um contentor. É obrigatório no pipeline ou em cada stage.

Adicionar agente SSH
# Manage Jenkins > Nodes > New Node

# Nome: build-linux-1
# Type: Permanent Agent

# Configuração:
# - Remote root directory: /home/jenkins
# - Labels: linux docker
# - Launch method:
#   "Launch agents via SSH"
# - Host: 192.168.1.50
# - Credentials: chave SSH ou user/pass

# O Jenkins instala o agente
# automaticamente via SSH e liga-o.

# Verificar ligação em:
# Manage Jenkins > Nodes > (nó) > Log

Adiciona agentes em Manage Jenkins > Nodes > New Node. Define o diretório raiz remoto, labels e o método de lançamento (SSH para Linux). O Jenkins instala e liga o agente automaticamente. Verifica o estado no log do nó.

Dockerfile agent
// Construir e usar uma imagem
// a partir de um Dockerfile do repo:
agent {
    dockerfile {
        filename 'Dockerfile.ci'
        dir 'docker'
        additionalBuildArgs '--build-arg VERSAO=2'
    }
}

stages {
    stage('Build') {
        steps {
            // Ambiente definido no Dockerfile
            sh 'minha-ferramenta --version'
        }
    }
}

// O Jenkins faz o build da imagem
// e executa o pipeline dentro dela.

dockerfile constrói uma imagem a partir de um Dockerfile do repositório e executa o pipeline dentro dela. filename e dir localizam o ficheiro. Permite ambientes de build totalmente customizados e versionados.

Docker agent
agent {
    docker {
        image 'node:20-alpine'
        args '-v /tmp/cache:/root/.npm'
        reuseNode true
        registryUrl 'https://registry.exemplo.com'
        registryCredentialsId 'registry-creds'
    }
}

stages {
    stage('Build') {
        steps {
            // node/npm já estão instalados
            sh 'node --version'
            sh 'npm ci'
        }
    }
}

O docker agent executa o build dentro de um contentor — sem instalar ferramentas no servidor. args passa opções (ex: volumes para cache). reuseNode reusa o contentor entre stages. registryUrl usa registos privados.

Workspace e customWorkspace
agent {
    node {
        label 'linux'
        customWorkspace '/opt/builds/meu-projeto'
    }
}

stages {
    stage('Build') {
        steps {
            // Workspace padrão:
            // /home/jenkins/workspace/NOME-JOB
            echo "Em: ${env.WORKSPACE}"
        }
    }
}

# customWorkspace define um diretório
# fixo em vez do workspace automático.
# Útil quando o caminho é importante
# (ex: licenças, configs absolutas).

O workspace padrão é ~/workspace/NOME-JOB. customWorkspace define um diretório fixo — útil quando o caminho absoluto importa. Requer agent { node { } }. O workspace é partilhado entre stages do mesmo agente.

Agent por stage
pipeline {
    agent none

    stages {
        stage('Build Frontend') {
            agent { docker { image 'node:20' } }
            steps { sh 'npm run build' }
        }

        stage('Build Backend') {
            agent { docker { image 'maven:3.9' } }
            steps { sh 'mvn package' }
        }

        stage('Deploy') {
            agent { label 'prod-server' }
            steps { sh './deploy.sh' }
        }
    }
}

Com agent none no topo, cada stage define o seu próprio agente. Permite usar ferramentas diferentes por etapa (Node para frontend, Maven para backend). O deploy pode correr num servidor específico via label.

Executores (executors)
# Cada nó tem N executors —
# o número de builds em paralelo.

# Configurar:
# Manage Jenkins > Nodes > (nó) > Configure
# "# of executors": 4

# Regras práticas:
# - Servidor de builds: 1-2 por CPU core
# - Builds pesados: menos executors
# - Builds leves: mais executors

# Se todos os executors estão ocupados,
# os builds ficam em fila (Build Queue).

# Monitorizar em:
# Manage Jenkins > Nodes
# (coluna "Build Queue")

Executors definem quantos builds correm em paralelo num nó. Configura por nó (1-2 por core é razoável). Builds pesados pedem menos executors. Quando todos estão ocupados, os builds ficam na Build Queue. Monitoriza em Nodes.

Labels e nós
# Configurar labels:
# Manage Jenkins > Nodes > (nó) > Configure
# Labels: linux docker build

# Expressões de label:
agent { label 'linux && docker' }   // ambos
agent { label 'linux || mac' }      // qualquer
agent { label '!windows' }          // exceto

# Agentes podem ser:
# - O próprio servidor (built-in node)
# - Máquinas SSH (Linux/Mac)
# - Máquinas Windows (JNLP agent)
# - Contentores Kubernetes (plugin)

# Vê os nós em:
# Manage Jenkins > Nodes

Labels etiquetam nós para seleção (linux, docker). Suporta expressões: &&, ||, !. Agentes podem ser máquinas SSH, Windows (JNLP) ou pods Kubernetes. Gere em Manage Jenkins > Nodes.

Kubernetes agents
// Plugin: Kubernetes
// Cria pods efémeros por build

agent {
    kubernetes {
        yaml '''
            apiVersion: v1
            kind: Pod
            spec:
              containers:
              - name: node
                image: node:20
                command: ['sleep', 'infinity']
        '''
    }
}

stages {
    stage('Build') {
        steps {
            container('node') {
                sh 'npm ci && npm test'
            }
        }
    }
}

O plugin Kubernetes cria pods efémeros para cada build — escala automaticamente. Define o pod em YAML com os contentores necessários. container() seleciona o contentor. Os pods são destruídos após o build. Ideal para CI em grande escala.

Variáveis e Ambiente


9 cards
Variáveis embutidas
steps {
    echo "Build: ${env.BUILD_NUMBER}"
    echo "Job: ${env.JOB_NAME}"
    echo "URL: ${env.BUILD_URL}"
    echo "Workspace: ${env.WORKSPACE}"
    echo "Branch: ${env.BRANCH_NAME}"
    echo "Nó: ${env.NODE_NAME}"
    echo "Jenkins: ${env.JENKINS_URL}"
}

// Resultado do build (em post/script):
// currentBuild.result
// currentBuild.currentResult

// Lista completa:
// http://jenkins/pipeline-syntax/globals#env

O Jenkins expõe variáveis automáticas em env: BUILD_NUMBER, JOB_NAME, BUILD_URL, WORKSPACE, BRANCH_NAME. currentBuild dá o resultado. A lista completa está em pipeline-syntax/globals.

withCredentials
steps {
    // Bloco que expõe credenciais
    // só durante a execução:
    withCredentials([
        usernamePassword(
            credentialsId: 'docker-creds',
            usernameVariable: 'USER',
            passwordVariable: 'PASS')
    ]) {
        sh 'docker login -u $USER -p $PASS'
    }

    // Secret text:
    withCredentials([
        string(credentialsId: 'api-token',
            variable: 'TOKEN')
    ]) {
        sh 'curl -H "Authorization: $TOKEN" ...'
    }
}

withCredentials expõe credenciais apenas dentro do bloco — mais seguro que environment global. usernamePassword define user e pass. string para tokens. As variáveis são mascaradas no log e limpas no fim do bloco.

Ficheiro .env e configs
steps {
    // Carregar variáveis de um ficheiro:
    script {
        def props = readProperties file: 'build.properties'
        env.APP_VERSION = props['version']
    }

    // Criar ficheiro de configuração:
    writeFile file: '.env', text: """
APP_ENV=${params.ENV}
DB_HOST=${env.DB_HOST}
VERSION=${env.BUILD_NUMBER}
"""

    sh 'cat .env'

    // Limpar no fim:
    // post { always { sh 'rm -f .env' } }
}

// readProperties lê ficheiros .properties

readProperties (Pipeline Utility Steps) lê ficheiros de configuração. writeFile gera ficheiros .env com valores do build. Lembra de limpar ficheiros com segredos em post > always. Padrão comum para configurar aplicações.

Environment block
environment {
    APP_ENV = 'production'
    DB_HOST = 'db.exemplo.com'
    VERSION = '1.2.3'

    // Calcular de um comando:
    GIT_HASH = sh(
        script: 'git rev-parse --short HEAD',
        returnStdout: true).trim()

    // Usar credencial:
    DB_PASS = credentials('db-password')
}

stage('Build') {
    environment {
        BUILD_TARGET = 'release'  // só neste stage
    }
    steps {
        sh 'echo $APP_ENV $GIT_HASH'
    }
}

environment define variáveis globais ou por stage. sh(returnStdout: true) captura output de comandos. credentials() injeta segredos com segurança. No shell acede via $NOME; no Groovy via env.NOME.

Variáveis de build dinâmicas
steps {
    script {
        // Definir variável dinâmica:
        env.TIMESTAMP = sh(
            script: 'date +%Y%m%d%H%M%S',
            returnStdout: true).trim()

        env.IMAGE_TAG = "${env.BUILD_NUMBER}-${env.GIT_HASH}"

        // Ler de ficheiro:
        env.VERSION = readFile('versao.txt').trim()
    }

    echo "Tag: ${env.IMAGE_TAG}"
    sh 'docker build -t app:$IMAGE_TAG .'
}

// env.X = ... cria variáveis em runtime
// (só dentro de script { })

Dentro de script { } podes criar variáveis dinâmicas com env.NOME = valor. Útil para timestamps, tags de imagem e valores calculados. Combina sh(returnStdout) e readFile para obter valores de comandos e ficheiros.

Credentials
# Criar credencial:
# Manage Jenkins > Credentials >
#   System > Global credentials > Add
# Tipos: Username/password, Secret text,
#        SSH key, Certificate

environment {
    DOCKER_PASS = credentials('docker-pass')
    API_KEY = credentials('api-key-id')
    SSH = credentials('deploy-ssh-key')
}

steps {
    sh 'docker login -u user -p $DOCKER_PASS'
    sh 'curl -H "X-Key: $API_KEY" https://api'
}

# O Jenkins mascara os valores no log
# (aparecem como ****)

Credentials guardam segredos com segurança. Cria em Manage Jenkins > Credentials. Tipos: username/password, secret text, SSH key. Injeta com credentials(id). O Jenkins mascara os valores nos logs automaticamente.

Mascarar segredos
steps {
    // wrap que mascara qualquer valor:
    wrap([$class: 'MaskPasswordsBuildWrapper']) {
        sh 'echo $MINHA_SENHA'  // aparece ****
    }

    // Boas práticas:
    // 1. Nunca usar echo em segredos
    // 2. Usar credentials() / withCredentials
    // 3. Não passar segredos por parâmetros
    //    de build (ficam no histórico)
    // 4. Limpar ficheiros com segredos:
    sh 'rm -f .env'

    // Segredos em artefactos ou logs
    // ficam visíveis para sempre!
}

Segredos requerem cuidado: usa credentials()/withCredentials (mascarados automaticamente). Nunca faças echo de passwords. Não passes segredos por parâmetros de build (ficam no histórico). Remove ficheiros .env antes de arquivar.

Parâmetros em steps
parameters {
    string(name: 'BRANCH', defaultValue: 'main')
    choice(name: 'ENV', choices: ['dev', 'prod'])
    booleanParam(name: 'DEPLOY', defaultValue: false)
}

stages {
    stage('Deploy') {
        steps {
            sh "git checkout ${params.BRANCH}"
            sh "./deploy.sh ${params.ENV}"

            script {
                if (params.DEPLOY) {
                    echo 'A fazer deploy...'
                } else {
                    echo 'Deploy desativado'
                }
            }
        }
    }
}

Acede aos parâmetros via params.NOME. Em strings Groovy usa ${params.BRANCH}. Booleanos funcionam em if. Os parâmetros aparecem no formulário "Build with Parameters". Valida inputs antes de usar em comandos.

Propriedades do build
steps {
    script {
        // Info do build atual:
        echo "Número: ${currentBuild.number}"
        echo "Resultado: ${currentBuild.currentResult}"
        echo "Duração: ${currentBuild.duration}"
        echo "URL: ${currentBuild.absoluteUrl}"

        // Causa do build:
        def causa = currentBuild.getBuildCauses()
        echo "Causa: ${causa}"

        // Definir resultado manualmente:
        // currentBuild.result = 'UNSTABLE'

        // Mudar a descrição do build:
        currentBuild.description = "Deploy ${params.ENV}"
    }
}

currentBuild dá metadados do build: number, currentResult, duration, getBuildCauses(). Podes definir result manualmente (ex: UNSTABLE) e mudar a description. Útil para relatórios e lógica condicional.

Condições e Pós-ações


9 cards
when (condições)
stage('Deploy') {
    when {
        branch 'main'
    }
    steps { sh './deploy.sh' }
}

stage('Deploy PR') {
    when {
        changeRequest()
    }
    steps { echo 'Build de PR' }
}

stage('Release') {
    when {
        tag 'v*'
    }
    steps { sh './release.sh' }
}

// O stage só executa se a condição
// for verdadeira (senão é "skipped")

when executa o stage condicionalmente. Condições comuns: branch, tag, changeRequest() (PRs). Se falso, o stage aparece como "skipped". Essencial para pipelines que se comportam diferente por branch.

Notificações Slack
post {
    failure {
        slackSend channel: '#dev',
            color: 'danger',
            message: "FALHOU: ${env.JOB_NAME} #${env.BUILD_NUMBER} - ${env.BUILD_URL}"
    }
    success {
        slackSend channel: '#dev',
            color: 'good',
            message: "OK: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
    }
}

# Configurar:
# Manage Jenkins > System >
#   Slack > Workspace + Token
# O plugin "Slack Notification" é preciso

slackSend envia mensagens para o Slack. Configura o workspace e token em Manage Jenkins > System. Usa color (good/danger) e inclui BUILD_URL para link direto. Coloca em post para notificar por resultado.

Resultados do build
steps {
    script {
        // Marcar como instável
        // (não falha o pipeline):
        currentBuild.result = 'UNSTABLE'

        // Falhar com mensagem:
        // error('Algo correu mal')
    }
}

// Significado dos resultados:
// SUCCESS  - tudo correu bem
// UNSTABLE - testes falharam, mas
//            o build "passou"
// FAILURE  - algo falhou
// ABORTED  - cancelado manualmente

// unstable é típico quando testes
// falham mas queres continuar o deploy

Resultados: SUCCESS, UNSTABLE, FAILURE, ABORTED. UNSTABLE indica testes falhados sem bloquear — útil para continuar o pipeline. Define com currentBuild.result. error() força FAILURE.

when com expressões
stage('Deploy') {
    when {
        expression { params.DEPLOY == true }
    }
    steps { sh './deploy.sh' }
}

stage('Prod') {
    when {
        allOf {
            branch 'main'
            expression { params.ENV == 'prod' }
        }
    }
    steps { sh './deploy-prod.sh' }
}

stage('Testes') {
    when {
        not { branch 'main' }
    }
    steps { sh 'npm test' }
}

// allOf = E, anyOf = OU, not = negação

expression { } permite condições Groovy arbitrárias. Combina com allOf (E), anyOf (OU) e not (negação). expression dá flexibilidade total — compara parâmetros, variáveis e qualquer lógica.

Notificações por email
post {
    failure {
        emailext(
            subject: "FALHOU: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
            body: """Build falhou.
            Ver: ${env.BUILD_URL}""",
            to: 'dev@empresa.com',
            attachLog: true
        )
    }
    success {
        emailext subject: 'Build OK',
            to: 'dev@empresa.com'
    }
}

# Configurar SMTP:
# Manage Jenkins > System > E-mail
# Plugin: "Email Extension"

emailext (plugin Email Extension) envia emails ricos. Configura SMTP em Manage Jenkins > System. attachLog anexa o log do build. Suporta templates HTML, anexos e listas de destinatários. Notifica em post > failure.

when com mudanças
// Só executar se certos ficheiros
// mudaram desde o último build:
stage('Backend') {
    when {
        changeset "src/main/**"
    }
    steps { sh 'mvn package' }
}

stage('Frontend') {
    when {
        changeset "frontend/**"
    }
    steps { sh 'npm run build' }
}

// Comparar com branch:
stage('Deploy') {
    when {
        branch pattern: "release/.*",
            comparator: "REGEXP"
    }
    steps { sh './deploy.sh' }
}

changeset executa o stage só se ficheiros específicos mudaram — ideal para monorepos (build só do que mudou). branch pattern com REGEXP faz matching avançado. Reduz tempo de build em repositórios grandes.

Retry e timeout
options {
    // Timeout global do pipeline:
    timeout(time: 1, unit: 'HOURS')
    // Repetir pipeline em falha:
    retry(2)
}

stages {
    stage('Instalar') {
        steps {
            // Retry só neste passo:
            retry(3) {
                sh 'npm install'
            }
        }
    }
    stage('Testes longos') {
        options {
            timeout(time: 20, unit: 'MINUTES')
        }
        steps { sh 'npm run test:e2e' }
    }
}

timeout aborta builds que excedem o tempo (global ou por stage). retry repete em caso de falha (útil para passos instáveis). Ambos podem ser aplicados em options globais, de stage, ou como steps. Previnem builds presos.

Post actions
pipeline {
    agent any
    stages { /* ... */ }

    post {
        success {
            echo 'Build OK!'
        }
        failure {
            echo 'Build falhou!'
        }
        unstable {
            echo 'Testes falharam'
        }
        always {
            echo 'Sempre executa'
            cleanWs()
        }
        aborted {
            echo 'Foi cancelado'
        }
    }
}

post define ações por resultado do build. Condições: success, failure, unstable, aborted, always. always executa sempre (ideal para limpeza). Pode ser global ou por stage.

Limpeza (cleanWs)
post {
    always {
        // Limpar o workspace:
        cleanWs()

        // Ou apagar só certos padrões:
        cleanWs(patterns: [
            [pattern: 'node_modules/**', type: 'INCLUDE'],
            [pattern: '.git/**', type: 'EXCLUDE']
        ])
    }
}

// Alternativa manual:
// sh 'rm -rf ${env.WORKSPACE}/*'

// cleanWs() liberta espaço em disco.
// Recomendado em agentes com pouco espaço.

cleanWs() limpa o workspace após o build — liberta espaço em disco. Coloca em post > always. Aceita patterns para incluir/excluir caminhos. Essencial em agentes com armazenamento limitado ou builds grandes.

Docker e Avançado


9 cards
Build e push Docker
stage('Docker') {
    steps {
        script {
            def img = docker.build("minhaapp:${env.BUILD_NUMBER}")

            docker.withRegistry('https://registry.exemplo.com', 'registry-creds') {
                img.push()
                img.push('latest')
            }
        }
    }
}

// docker.build() constrói a imagem
// withRegistry autentica no registry
// push() envia com tag específica e latest

docker.build() constrói a imagem. docker.withRegistry() autentica num registry privado usando credenciais. img.push() envia — faz push com o BUILD_NUMBER e com latest. Padrão clássico de CI para contentores.

Pipeline completo (exemplo)
pipeline {
    agent { docker { image 'node:20' } }

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

    stages {
        stage('Install') {
            steps { sh 'npm ci' }
        }
        stage('Test') {
            steps { sh 'npm test' }
            post { always { junit 'reports/*.xml' } }
        }
        stage('Build') {
            steps { sh 'npm run build' }
        }
        stage('Deploy') {
            when { branch 'main' }
            steps { sh './deploy.sh' }
        }
    }

    post {
        failure { slackSend channel: '#dev', color: 'danger',
            message: "Falhou: ${env.JOB_NAME}" }
        always { cleanWs() }
    }
}

Exemplo completo: docker agent, options de timeout e concorrência, stages de install/test/build/deploy, when para só fazer deploy na main, junit para relatórios, notificação Slack e cleanWs. Um bom template inicial.

Boas práticas
// 1. Jenkinsfile no repo (Pipeline as Code)
// 2. Builds rápidos (< 10 min) — usa cache
// 3. Testes cedo (fail fast)
// 4. Stages paralelos quando possível
// 5. Nunca guardar segredos no Jenkinsfile
// 6. cleanWs() para libertar espaço
// 7. timeout em tudo (evita builds presos)
// 8. Notificar só em falhas (evita ruído)
// 9. Usar docker agents (ambientes limpos)
// 10. Versionar e rever o Jenkinsfile

// Cache de dependências:
// agent { docker {
//   image 'node:20'
//   args '-v cache-npm:/root/.npm'
// }}

Boas práticas: Pipeline as Code, builds rápidos com cache, testes cedo (fail fast), stages paralelos, nunca guardar segredos no Jenkinsfile, cleanWs(), timeout em tudo, notificar só em falhas, docker agents para ambientes limpos.

Docker Compose
stage('Testes integrados') {
    steps {
        // Subir stack de dependências:
        sh 'docker compose up -d db redis'

        // Esperar a BD ficar pronta:
        sh 'sleep 10'

        // Correr testes:
        sh 'docker compose exec -T web npm test'

        // Limpar:
        sh 'docker compose down -v'
    }
}

// -T em exec (sem TTY, necessário no CI)
// down -v remove volumes
// Sempre limpar em post > always

docker compose sobe dependências (BD, Redis) para testes integrados. Usa -T em exec (sem TTY no CI). Limpa com down -v em post > always. Permite testes realistas sem instalar serviços no agente.

Debug e logs
steps {
    // Ver variáveis de ambiente:
    sh 'printenv'

    // Verificar ferramentas:
    sh 'node --version && npm --version'
    sh 'which docker'

    // Logs coloridos (plugin AnsiColor):
    // options { ansiColor('xterm') }

    // Ver o pipeline gerado:
    // Job > "Pipeline Syntax" >
    //   "Declarative Directive Generator"

    // Replay: editar e re-executar
    // um build falhado (Job > Build > Replay)

    // Validar Jenkinsfile:
    // Job > "Pipeline Syntax" >
    //   "Validate Pipeline"
}

Para debug: printenv mostra variáveis, verifica versões de ferramentas. O Replay permite editar e re-executar um build falhado. O Declarative Directive Generator gera snippets. Valida o Jenkinsfile antes de commitar.

Shared Libraries
// Repo da lib: vars/deploy.groovy
def call(String ambiente) {
    echo "Deploy para ${ambiente}"
    sh "./deploy.sh ${ambiente}"
}

// Jenkinsfile:
@Library('minha-lib') _

pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                deploy('production')
            }
        }
    }
}

// Configurar:
// Manage Jenkins > System >
//   Global Pipeline Libraries

Shared Libraries permitem reutilizar código entre pipelines. Cria ficheiros vars/nome.groovy num repo separado. Importa com @Library e chama como função. Configura em Global Pipeline Libraries. Elimina duplicação de lógica de deploy.

Segurança do pipeline
// 1. Rever mudanças no Jenkinsfile (PR)
//    antes de merge — é código!

// 2. Proteger branches:
//    properties([
//      [$class: 'BranchProtectionProperty']
//    ])

// 3. Não executar código de PRs
//    sem sandbox:
//    Manage Jenkins > Security >
//    "Script Security"

// 4. Credenciais com scope limitado:
//    (Job-specific em vez de Global)

// 5. Princípio do menor privilégio:
//    agentes de build não devem ter
//    acesso a produção

// 6. Auditar com plugin Audit Trail

Segurança: trata o Jenkinsfile como código (revê em PR). Usa Script Security para sandbox de código não confiável. Credenciais com scope por job. Agentes de build não devem aceder a produção. Audita com Audit Trail.

Multibranch Pipeline
# New Item > Multibranch Pipeline

# Branch Sources: GitHub/GitLab/Bitbucket
#   (com credenciais)

# O Jenkins:
# 1. Faz scan do repositório
# 2. Cria um job por branch com Jenkinsfile
# 3. Cria jobs para Pull Requests
# 4. Remove jobs de branches apagados

# No Jenkinsfile, deteta o contexto:
when { branch 'main' }        // só main
when { changeRequest() }      // só PRs
when { tag 'v*' }             // só tags

# Scan automático + webhooks

Multibranch Pipeline cria automaticamente um job por branch e PR que tenha Jenkinsfile. Faz scan periódico e reage a webhooks. Remove jobs de branches apagados. Usa when para diferenciar comportamento. Padrão moderno de CI.

Backup do Jenkins
# Tudo está em JENKINS_HOME:
# - Docker: volume jenkins_home
# - Linux: /var/lib/jenkins

# Backup simples (parar o serviço):
sudo systemctl stop jenkins
tar -czf jenkins-backup-$(date +%F).tar.gz \
  /var/lib/jenkins
sudo systemctl start jenkins

# Ou copiar só o essencial:
# - jobs/ (configurações dos jobs)
# - config.xml (config global)
# - secrets/ e credentials.xml
# - users/

# Plugins: lista em
# Manage Jenkins > Plugins > Installed

# Restore: extrair para JENKINS_HOME
# e reiniciar o serviço

Todo o estado está em JENKINS_HOME (/var/lib/jenkins). Faz backup com o serviço parado (tar do diretório). O essencial: jobs/, config.xml, credentials.xml, secrets/. Restaura extraindo e reiniciando.

Instalação e Setup


9 cards
Instalar com Docker
# Forma mais simples — Docker:
docker run -d \
  --name jenkins \
  -p 8080:8080 \
  -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  jenkins/jenkins:lts

# Aceder:
# http://localhost:8080

# Obter password inicial:
docker exec jenkins \
  cat /var/jenkins_home/secrets/initialAdminPassword

# O volume jenkins_home persiste
# toda a configuração e jobs

A forma mais fácil é via Docker com a imagem jenkins/jenkins:lts. A porta 8080 é a interface web e 50000 é para agentes. O volume jenkins_home persiste tudo. A password inicial fica em secrets/initialAdminPassword.

Jenkinsfile no repositório
# Boa prática: Pipeline as Code
# Ficheiro "Jenkinsfile" na raiz do repo

# No job Jenkins:
# Definition: Pipeline script from SCM
# SCM: Git
# Repository URL: https://github.com/user/repo
# Script Path: Jenkinsfile

# Vantagens:
# - Versionado com o código
# - Revisto em pull requests
# - Histórico de mudanças
# - Único fonte de verdade

# O Jenkins faz checkout automático
# e executa o Jenkinsfile do branch

A boa prática é Pipeline as Code — guardar o pipeline num Jenkinsfile na raiz do repositório. No job usa Pipeline script from SCM. Fica versionado, revisto em PRs e é a única fonte de verdade. O Jenkins faz o checkout automaticamente.

Estrutura de um job
# Anatomia de um Pipeline job:
#
# General:
#   - Description, GitHub project
# Build Triggers:
#   - Quando executar (cron, webhook)
# Pipeline:
#   - Definition, Script/SCM
# Post-build Actions:
#   - Notificações, artefactos

# Tipos de item:
# - Freestyle project (legado, simples)
# - Pipeline (recomendado)
# - Multibranch Pipeline (por branch)
# - Folder (organizar jobs)
# - Organization Folder (GitHub org)

# Organiza jobs em Folders por equipa

Um job tem secções: General, Build Triggers, Pipeline e Post-build. Prefere Pipeline sobre Freestyle. Multibranch cria jobs por branch automaticamente. Organiza com Folders por equipa ou projeto.

Instalar em Linux
# Ubuntu/Debian:
# 1. Instalar Java (requerido):
sudo apt install openjdk-17-jre

# 2. Adicionar repositório Jenkins:
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key \
  | sudo tee /usr/share/keyrings/jenkins-keyring.asc

echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
  https://pkg.jenkins.io/debian-stable binary/" \
  | sudo tee /etc/apt/sources.list.d/jenkins.list

# 3. Instalar:
sudo apt update
sudo apt install jenkins

# 4. Iniciar:
sudo systemctl start jenkins
sudo systemctl enable jenkins

O Jenkins requer Java (JRE 17+). Adiciona o repositório oficial com a chave GPG. systemctl gere o serviço. A configuração fica em /var/lib/jenkins. Prefere o canal debian-stable (LTS).

Gerir plugins
# Manage Jenkins > Plugins

# Abas:
# - Updates: atualizações disponíveis
# - Available: instalar novos
# - Installed: gerir existentes

# Plugins populares:
# - Git, GitHub, GitLab
# - Docker Pipeline
# - Pipeline Utility Steps
# - Slack Notification
# - Email Extension
# - JUnit, Cobertura (testes)
# - AnsiColor (logs coloridos)

# Manage Jenkins > Plugins > Available
# (reiniciar pode ser necessário)

Plugins estendem o Jenkins. Gere em Manage Jenkins > Plugins. Essenciais: Git, Docker Pipeline, Pipeline Utility Steps. Para notificações: Slack e Email Extension. Mantém os plugins atualizados por segurança.

Setup inicial (wizard)
# 1. Aceder a http://localhost:8080
# 2. Introduzir password inicial:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword

# 3. Instalar plugins sugeridos
#    (ou selecionar manualmente)

# 4. Criar utilizador admin

# 5. Configurar URL do Jenkins

# Plugins essenciais pós-instalação:
# - Pipeline
# - Git
# - Docker Pipeline
# - Credentials Binding
# - Blue Ocean (UI moderna, opcional)

O wizard inicial pede a password de initialAdminPassword. Instala os plugins sugeridos. Cria um utilizador admin em vez de usar admin padrão. Os plugins Pipeline, Git e Docker Pipeline são essenciais para CI/CD.

Utilizadores e segurança
# Manage Jenkins > Security

# Realm (autenticação):
# - Jenkins users (interno)
# - LDAP / Active Directory
# - GitHub OAuth

# Authorization (permissões):
# - Logged-in users can do anything
# - Matrix-based security (recomendado)
# - Project-based Matrix

# Criar utilizador:
# Manage Jenkins > Users > Create User

# Boas práticas:
# - Nunca usar admin para builds
# - Criar tokens de API em vez de passwords
# - Auditar com Audit Trail plugin

Configura segurança em Manage Jenkins > Security. O Realm define a autenticação (interno, LDAP, OAuth). A Matrix-based security dá controlo fino de permissões. Usa tokens de API em vez de passwords para automação.

Criar primeiro Pipeline
# 1. New Item > Pipeline > OK
# 2. Em "Pipeline":
#    Definition: Pipeline script
# 3. Colar no editor:

pipeline {
    agent any
    stages {
        stage('Olá') {
            steps {
                echo 'Olá, Jenkins!'
            }
        }
    }
}

# 4. Save > Build Now
# 5. Ver output em "Console Output"

Cria um Pipeline em New Item. Começa com Pipeline script colado no editor. agent any executa em qualquer nó. echo imprime no log. Build Now executa e Console Output mostra o resultado.

Tokens de API
# Gerar token:
# Utilizador > Configure > API Token > Add new Token

# Disparar build via API:
curl -X POST \
  -u "utilizador:TOKEN_API" \
  "http://jenkins:8080/job/MEU-JOB/build"

# Com parâmetros:
curl -X POST \
  -u "utilizador:TOKEN_API" \
  "http://jenkins:8080/job/MEU-JOB/buildWithParameters?BRANCH=main"

# Ver estado do build (JSON):
curl -u "utilizador:TOKEN_API" \
  "http://jenkins:8080/job/MEU-JOB/lastBuild/api/json"

Tokens de API substituem passwords em automação. Gera por utilizador em Configure. Dispara builds com POST /job/NOME/build. buildWithParameters aceita parâmetros. A API retorna JSON com o estado do build.