← CI/CD: construir, validar e entregar
07 / 12 · 60 MIN

Validação estática e contratos entre jobs

Interpreta diagnósticos reais de actionlint e revê dependências, outputs e permissões sem confundir validação com execução.

Preparar exemplos positivos e negativos

O laboratório usa actionlint 1.7.11, compilado com Go 1.27.1 para Darwin arm64, para analisar oito workflows originais. Três são aceites e cinco rejeitados conforme as expectativas registadas. Guarda a versão, o hash do binário e os hashes dos ficheiros para poderes repetir a comparação. ShellCheck e pyflakes estão desligados explicitamente; o resultado não inclui essas análises. Nenhum workflow foi enviado ao GitHub, nenhum runner alojado foi iniciado e não foram solicitados tokens. Antes de executar, classifica cada ficheiro e escreve a razão. Depois compara o diagnóstico com a previsão. Uma rejeição esperada é um teste positivo do controlo, não uma falha do laboratório.

Corrigir o grafo sem perder a intenção

O exemplo missing-job declara que inspect precisa de compile, mas só existem build e inspect. Corrige a referência ao produtor realmente necessário. Não resolvas o erro apagando needs sem verificar se o consumidor pode começar antes de o dado existir. No exemplo cycle, build e inspect esperam um pelo outro. Mais runners não elimina a dependência circular. Decompõe as responsabilidades e identifica uma ordem executável. Numa revisão real, desenha também as verificações obrigatórias. Se publicação e testes dependerem apenas do mesmo build, podem não estar ligados entre si. Um grafo aceite pelo validador não demonstra que a publicação espera por todos os resultados exigidos pelo serviço.

Tratar outputs como um contrato

No ficheiro unknown-output, o produtor publica release_id e o consumidor pede relese_id. O diagnóstico expõe a gralha, mas a revisão deve ir além da ortografia: o valor precisa de ser produzido, publicado pelo job e consumido no contexto correto. O contexto needs refere os jobs de que o consumidor depende diretamente; não assumas que qualquer antecessor indireto fica automaticamente disponível. Se acrescentares uma dependência direta, conserva também o teste obrigatório. Um output vazio não deve ser substituído por qualquer rótulo só para avançar. Num serviço financeiro fictício, a identidade do candidato liga os resultados de teste ao conteúdo que será entregue e ao histórico necessário para recuperação.

Rever permissões com uma necessidade concreta

O exemplo invalid-permission usa contents: deploy, que não é um valor válido para esse âmbito. Corrigir a sintaxe para write-all seria uma resposta demasiado ampla a um job que apenas precisa de leitura. Declara a necessidade apropriada e revê a configuração efetiva. No exemplo unsafe-event-input, o título do pull request entra diretamente no código de run. A variante aceite passa-o por uma variável de ambiente e apresenta-o com quoting. A comparação ensina a separar dados de código, não a certificar a segurança de todo o workflow. Continua a ser necessário rever quem pode alterar a definição, que código é executado e quais os privilégios disponíveis em cada contexto.

Reconhecer um verde sem verificações

O ficheiro valid-without-tests é intencionalmente incompleto: o único comando imprime uma mensagem positiva. O actionlint aceita-o porque essa mensagem é sintaticamente válida. Nenhum teste funcional foi executado. Usa este exemplo para pedir a evidência certa durante uma reunião de entrega: comando de teste, casos selecionados, resultados, candidato avaliado e regra que impede promoção quando um requisito falha. Uma contagem zero de testes também merece investigação, mesmo com processo terminado em zero. Não transformes a observação numa regra de rejeitar qualquer printf; imprimir dados é legítimo. O problema é atribuir à apresentação do resultado a função de executar ou decidir a verificação.

Entregar uma revisão utilizável pela equipa

Termina a oficina revendo um desenho fictício com build, testes e publicação. Identifica o produtor de cada valor, as dependências e a condição que autoriza avançar. Para cada lacuna, regista uma alteração proposta e a evidência que confirmará a correção. Distingue o que o linter verificou do que precisa de execução na plataforma. Uma aprovação de pull request também não substitui automaticamente as checks de um recurso Azure DevOps; cada mecanismo tem âmbito próprio. O produto desta oficina é uma revisão argumentada e uma lista de verificações, não uma autorização de produção. O guião pode ser usado numa sessão de equipa, mas essa sessão humana ainda não foi executada.

python3 content/labs/cicd-evidence/run.py --actionlint /path/to/actionlint
# Requires actionlint 1.7.11; Bash path defaults to /bin/bash
# Eight original workflow fixtures: 3 accepted, 5 rejected
# ShellCheck and pyflakes integrations are disabled explicitly
# This command does not execute a hosted GitHub workflow.
NA PRÁTICA

Uma equipa fictícia separa build, teste e publicação. Uma gralha no output e um needs incompleto deixam o candidato sem identidade válida.

Armadilhas comuns

Eliminar dependências para silenciar erros, criar jobs vazios para satisfazer nomes ou tratar uma mensagem de sucesso como teste executado.

Tópicos relacionados: GitHub Actions · Gestão de releases · Git

Leva esta ideia contigo

Um workflow pode ser válido e continuar a não executar as verificações certas. Confirma o grafo, o contrato de dados e a decisão que utiliza os resultados.

Criar conta

Referência: actionlint v1.7.11 checks · CI/CD practices 2026-09; scoped GitHub Actions GitLab Jenkins and Azure DevOps Services documentation