Integração contínua e entrega contínua existem para resolver um problema simples: código que fica na máquina do desenvolvedor não tem valor. O valor está no software rodando em produção. CI/CD é o conjunto de práticas e ferramentas que encurta o caminho entre esses dois pontos — e GitHub Actions é hoje uma das formas mais acessíveis de colocar isso em prática.
Neste post vamos construir um pipeline real: do push no repositório até o deploy automatizado, entendendo cada etapa pelo caminho.
O que é CI e o que é CD
Integração contínua (CI) é a prática de integrar código com frequência — idealmente várias vezes por dia — e verificar automaticamente que cada integração não quebrou nada. Isso inclui compilar o projeto, rodar os testes e checar formatação ou lint.
Entrega contínua (CD) vai além: cada mudança que passa pela CI está pronta para ser enviada para produção. Em alguns times isso é manual — um clique aprova o deploy. Em outros é totalmente automatizado, e qualquer push na branch principal vai direto para produção.
GitHub Actions oferece infraestrutura para os dois. Você escreve um arquivo YAML descrevendo o que deve acontecer em resposta a eventos — um push, um pull request, um merge — e o GitHub executa em máquinas gerenciadas por eles.
Como GitHub Actions funciona
Tudo parte de um arquivo dentro de .github/workflows/
no seu repositório. Cada arquivo define um workflow.
Um workflow tem gatilhos (on), e quando o gatilho dispara,
ele executa um ou mais jobs. Cada job roda em uma
máquina virtual e é composto de steps — comandos
shell ou actions reutilizáveis publicadas por terceiros.
Jobs diferentes rodam em paralelo por padrão. Se um job depende de
outro, você declara essa dependência com needs, e o
segundo só começa quando o primeiro terminar com sucesso.
Um pipeline de CI básico
Para uma aplicação Node.js, um pipeline de CI mínimo faz três coisas: instala as dependências, roda o lint e executa os testes. Isso deve acontecer em todo pull request, para que o time saiba se uma mudança quebra algo antes de fazer o merge.
O gatilho pull_request faz o workflow rodar sempre que
um PR é aberto ou atualizado. O runner ubuntu-latest
é a máquina virtual onde tudo vai rodar — é gratuita para repositórios
públicos e tem uma cota mensal para repositórios privados.
actions/checkout é uma action oficial que faz o clone
do repositório na máquina virtual. actions/setup-node
instala a versão do Node que você especificar. Depois disso, são
comandos shell normais.
Adicionando o deploy
O deploy entra como um job que depende do job de CI. Ele só roda
se o CI passou, e somente na branch main — não faz
sentido fazer deploy de todo branch de feature.
Credenciais nunca devem aparecer no YAML. GitHub Actions tem um
sistema de Secrets: você adiciona um segredo nas configurações do
repositório e acessa via secrets.NOME_DO_SEGREDO no
workflow. Eles aparecem mascarados nos logs.
Cache de dependências
Instalar dependências a cada execução é lento e desnecessário quando
o package-lock.json não mudou. A action
actions/cache salva o diretório node_modules
entre execuções usando um hash do arquivo de lock como chave. Quando
o hash é o mesmo, o cache é restaurado e o npm install
termina em segundos.
Essa otimização muda o tempo de um pipeline de 3–4 minutos para menos de 1 minuto em repositórios com dependências pesadas.
Estratégia de matrix
Se você precisa garantir que sua aplicação funciona em múltiplas
versões do Node ou em múltiplos sistemas operacionais, a estratégia
matrix do GitHub Actions faz isso sem duplicar código.
Você declara as combinações e o Actions cria um job para cada uma,
rodando em paralelo.
Isso é especialmente útil para bibliotecas que precisam suportar múltiplos ambientes. Para aplicações com um ambiente de produção definido, geralmente não é necessário.
O que não fazer
Alguns erros comuns em pipelines GitHub Actions valem mencionar.
Não use @latest em actions de terceiros — use sempre
uma versão fixa com o hash do commit para evitar que uma mudança
remota quebre seu pipeline silenciosamente. Não coloque segredos
em variáveis de ambiente globais quando só um step precisa deles —
reduza o escopo. E não ignore falhas de lint: se o pipeline deixa
o lint passar sem falhar o job, ele não tem utilidade.
Conclusão
Um pipeline de CI/CD bem configurado transforma o processo de desenvolvimento. Code review fica mais objetivo quando o pipeline já verificou que os testes passam. Deploy vira um evento rotineiro e não estressante. E o time ganha confiança para fazer mudanças com frequência, porque sabe que qualquer regressão vai aparecer rapidamente — não em produção às três da manhã.
GitHub Actions tem uma curva de aprendizado pequena comparada ao valor que entrega. O investimento de algumas horas configurando um pipeline decente retorna muitas vezes em produtividade e confiabilidade.