Resolvendo Rapidamente Falhas de Build Usando a CLI do Jenkins

Use a CLI do Jenkins para inspecionar builds com falha, transmitir logs, verificar parâmetros e reexecutar jobs sem navegar pela interface gráfica.

Resolvendo Rapidamente Falhas de Build Usando a CLI do Jenkins

A interface web do Jenkins é útil quando você está explorando. A CLI do Jenkins é melhor quando você já sabe o nome do job, precisa do log agora ou quer repetir as mesmas verificações sem clicar em páginas.

Um build com falha geralmente precisa de três informações: o que foi executado, onde falhou e o que mudou desde a última execução bem-sucedida. A CLI pode obter todas as três rapidamente se você configurá-la uma vez.

Configure um comando CLI reutilizável

Baixe o jar da CLI do seu próprio controlador Jenkins:

curl -O "$JENKINS_URL/jnlpJars/jenkins-cli.jar"

Use um token de API, não sua senha de conta:

export JENKINS_URL="https://jenkins.example.com"
export JENKINS_USER="seu-usuario"
export JENKINS_API_TOKEN="seu-token-api"

alias jcli='java -jar jenkins-cli.jar -s "$JENKINS_URL" -auth "$JENKINS_USER:$JENKINS_API_TOKEN"'

Teste a autenticação antes de solucionar uma falha real:

jcli who-am-i
jcli help

Se isso falhar, corrija o acesso à CLI primeiro. Causas comuns são URL errada, token copiado com espaço extra, permissões ausentes ou uma configuração de segurança do Jenkins que desabilita o transporte da CLI que você está tentando usar.

Para scripts compartilhados, evite aliases de shell. Encapsule o comando em um pequeno script ou use variáveis de ambiente no cofre de segredos do seu CI para que tokens não apareçam no histórico do shell.

Encontre o build com falha

Se você sabe o nome do job e o número do build, vá direto para o log do console. Se você só sabe que algo falhou recentemente, comece com Groovy através da CLI:

jcli groovy = <<'EOF'
Jenkins.instance.getAllItems(hudson.model.Job.class).each { job ->
  def b = job.getLastBuild()
  if (b != null && b.result == hudson.model.Result.FAILURE) {
    println "${job.fullName} #${b.number} ${b.getTime()}"
  }
}
EOF

Para pastas e pipelines multibranch, use o nome completo do job exatamente como o Jenkins o conhece. Um job de branch pode parecer:

time-service/main
time-service/PR-42
pasta-a/pasta-b/deploy-prod

Se um nome contiver espaços, coloque-o entre aspas no seu shell:

jcli console "Pasta Com Espaços/Meu Pipeline" 128

Obtenha o log do console primeiro

O log do console ainda é a fonte de verdade mais rápida para a maioria das falhas:

jcli console MeuJobPipeline 123

Para logs longos, salve uma cópia e pesquise com contexto:

jcli console MeuJobPipeline 123 > build-123.log
grep -niE "error|failed|exception|traceback|permission denied|timeout" build-123.log | head -40
grep -niC 3 "permission denied" build-123.log

Não confie apenas na primeira linha que contém "error". Ferramentas de build geralmente imprimem avisos, nomes de teste ou texto de falha esperado. Procure pela primeira falha significativa após o início do estágio e leia as linhas anteriores. A causa geralmente está acima do stack trace.

Para um build em execução, acompanhe o log:

jcli console MeuJobPipeline 123 -f

Algumas versões do Jenkins e modos da CLI aceitam --follow; outros usam -f. Verifique jcli help console no seu controlador.

Identifique o estágio que falhou

Logs de pipeline incluem marcadores de estágio. Pesquise por eles perto da falha:

grep -n "\[Pipeline\] stage" build-123.log

Em seguida, inspecione a seção após o último marcador de estágio antes do erro. Se o log for ruidoso, abra-o com less:

less build-123.log

Dentro do less, pesquise por /ERROR, /Exception ou /[Pipeline] stage.

Um bom Jenkinsfile facilita isso imprimindo nomes de etapas claros antes de operações arriscadas:

echo 'Instalando dependências npm'
sh 'npm ci'
echo 'Executando testes unitários'
sh 'npm test'

Se cada etapa for apenas sh './ci.sh', a CLI ainda pode buscar o log, mas o log pode não fornecer informações suficientes. Nesse caso, melhore o pipeline após o incidente.

Verifique parâmetros e causas

Um build pode falhar porque foi executado com o branch errado, ambiente errado ou parâmetro desatualizado. Obtenha os metadados do build com Groovy:

jcli groovy = <<'EOF'
def job = Jenkins.instance.getItemByFullName('MeuJobPipeline')
def build = job?.getBuildByNumber(123)
if (build == null) {
  println 'Build não encontrado'
  return
}
println "Job: ${job.fullName}"
println "Build: #${build.number}"
println "Resultado: ${build.result}"
println "Duração: ${build.durationString}"
println 'Causas:'
build.getCauses().each { println "- ${it.shortDescription}" }
println 'Parâmetros:'
build.getAction(hudson.model.ParametersAction)?.parameters?.each {
  println "- ${it.name}=${it.value}"
}
EOF

Isso é especialmente útil para jobs de deploy. Uma implantação de produção com falha com BRANCH=feature/test é um problema muito diferente de uma implantação com falha da tag de versão esperada.

Tenha cuidado ao imprimir variáveis de ambiente. Elas podem incluir segredos. Se você precisar de detalhes do ambiente, imprima chaves seguras específicas em vez de despejar tudo:

jcli groovy = <<'EOF'
def job = Jenkins.instance.getItemByFullName('MeuJobPipeline')
def build = job?.getBuildByNumber(123)
def env = build?.getEnvironment(TaskListener.NULL)
['JOB_NAME', 'BUILD_NUMBER', 'BRANCH_NAME', 'GIT_COMMIT', 'NODE_NAME'].each { key ->
  println "${key}=${env?.get(key)}"
}
EOF

Se seu script não tiver permissão ou um plugin alterar os metadados disponíveis, recorra ao log do console e à configuração do job.

Compare com o último build bem-sucedido

Um único log de falha é útil. Um log de falha ao lado do último log bem-sucedido é melhor.

Encontre o número do último build bem-sucedido:

jcli groovy = <<'EOF'
def job = Jenkins.instance.getItemByFullName('MeuJobPipeline')
def b = job?.getLastSuccessfulBuild()
println b == null ? 'Nenhum build bem-sucedido encontrado' : b.number
EOF

Em seguida, obtenha ambos os logs:

jcli console MeuJobPipeline 122 > build-122-sucesso.log
jcli console MeuJobPipeline 123 > build-123-falha.log

Compare os comandos, versões de dependências, rótulos de agentes, branches e SHAs de checkout. Muitas falhas vêm de uma imagem base alterada, uma dependência movida, um agente diferente ou uma credencial que expirou entre builds.

Para pipelines baseados em Git, esses valores geralmente são suficientes para começar:

grep -nE "Checking out|GIT_COMMIT|BRANCH_NAME|git rev-parse|Docker|image:" build-123-falha.log

Reexecute um build com cuidado

Depois de entender a falha ou aplicar uma correção, acione um novo build:

jcli build MeuJobPipeline

Para jobs parametrizados:

jcli build MeuJobPipeline -p BRANCH=main -p ENVIRONMENT=staging

Para aguardar e transmitir a saída, verifique as opções suportadas pelo seu controlador:

jcli help build

Opções comuns incluem aguardar a conclusão e imprimir a saída do console, mas os nomes podem variar conforme a versão do Jenkins e plugins.

Não reexecute jobs de deploy de produção apenas para ver o que acontece. Confirme parâmetros, credenciais e ambiente de destino primeiro. Se o job não for idempotente, uma reexecução pode piorar o incidente.

Use a saída da CLI em notas de incidente

A CLI é boa para deixar um rastro. Salve o log exato e os metadados que você usou:

mkdir -p incidente-jenkins-123
jcli console MeuJobPipeline 123 > incidente-jenkins-123/console.log
jcli get-job MeuJobPipeline > incidente-jenkins-123/job-config.xml

Trate job-config.xml como sensível se contiver referências a credenciais, URLs ou nomes internos. Não cole em tickets públicos.

Uma nota de incidente compacta pode incluir:

Job: MeuJobPipeline #123
Estágio com falha: Testes unitários
Primeiro comando com falha: npm test
Commit: abc1234
Agente: linux-build-07
Causa provável: instalação de dependência usou Node 22 em vez do Node 20 esperado
Ação: versão da ferramenta fixada e reexecutado #124 com sucesso

Isso é muito mais útil do que "Jenkins falhou."

Um fluxo prático de solução de problemas

Use esta ordem quando um build falhar e você precisar de sinal rapidamente:

jcli who-am-i
jcli console MeuJobPipeline 123 > build-123.log
grep -niE "error|failed|exception|permission denied|timeout" build-123.log | head -40
grep -n "\[Pipeline\] stage" build-123.log

Em seguida, inspecione parâmetros e causas com Groovy, compare com o último build bem-sucedido e reexecute apenas depois de saber se a falha foi de código, infraestrutura, credenciais ou parâmetros de entrada.

A CLI do Jenkins não vai diagnosticar magicamente todos os builds com falha. O que ela faz bem é remover atritos. Ela traz o log, metadados e comando de reexecução para o seu terminal rapidamente, onde você pode pesquisar, comparar, salvar e repetir as mesmas verificações na próxima vez que um pipeline quebrar.