
CI/CD não é produto. É o hábito de integrar, testar e soltar software em ciclo curto, com o máximo de passos automáticos. O “dia do merge” de 2019 continua sendo o antipadrão. O que mudou é onde o YAML mora, quem roda o job e o que acontece depois que o pipeline fica verde.
CI, entrega e implantação — os três CDs
CI (integração contínua): cada push ou merge request vira build e teste automáticos sobre o tronco compartilhado. O conflito aparece hoje, não na sexta-feira da release.
Entrega contínua: o artefato aprovado (binário, imagem OCI, pacote) vai sozinho para um registro e fica pronto para produção. A subida ainda depende de um humano no botão — ou de um critério: tag, aprovação, janela de mudança.
Implantação contínua: o mesmo artefato sobe sozinho para produção se os testes passaram. O feedback do usuário chega em minutos. Exige testes em que você realmente confia, não um job verde oco.
Não vale brigar pelo acrônimo. Vale desenhar o pipeline: o que é automático, o que é porta e como se faz o rollback.

O pipeline em 2026: YAML no Git
Jenkins com plugins ainda roda muito legado. O ponto de partida no Linux hoje é um arquivo no repositório, um runner em container e o artefato em um registry.
GitHub Actions — o padrão de quem já está no GitHub. Fixe cada action pelo SHA do commit, não por tag flutuante: em março de 2025 as tags da action tj-actions/changed-files foram reapontadas para um commit malicioso que despejava secrets nos logs (CVE-2025-30066). Quem usava @v45 rodou o código do atacante; quem tinha fixado o SHA, não.
# .github/workflows/ci.yml
name: ci
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- run: make test
O bloco permissions reduz o token do job ao mínimo necessário — sem ele, o padrão pode ser mais amplo do que o teste precisa.
GitLab CI — o que o post irmão de 2019 já usava para Terraform. Um .gitlab-ci.yml e runners próprios, se você quiser soberania:
# .gitlab-ci.yml
stages: [test, image]
test:
stage: test
image: golang:1.27
script:
- go test ./...
image:
stage: image
image: docker:29
services: [docker:29-dind]
script:
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
As variáveis CI_REGISTRY* são preenchidas pelo próprio GitLab para o registry do projeto: nenhuma senha fica escrita no YAML.
Forgejo Actions / Gitea Actions — sintaxe compatível em boa parte com o GitHub Actions, rodando self-hosted, sem mandar o código para a nuvem alheia. O passo a passo com runner está no post sobre o Gitea com Actions e runner. O Woodpecker é a outra opção leve. No homelab Linux, isso compete com o GitLab CE.
O curso de Docker continua sendo pré-requisito: o job moderno é um container. Infraestrutura como código segue o mesmo espírito: Ansible e o pipeline de Terraform no GitLab.
CD virou GitOps
Implantar no Kubernetes em 2026 raramente é kubectl apply dentro do job de CI. O CI constrói a imagem, assina, envia ao registry e atualiza o Git (tag ou digest). O cluster puxa o estado desejado:
- Argo CD — aplicações declaradas no Git, detecção de drift e sincronização. A linha 3.5 (2026) trouxe mTLS no repo-server e uma verificação opcional, ainda em alpha, da integridade das fontes no hydrator.
- Flux — o outro projeto graduado da CNCF para GitOps, com controllers dentro do cluster.
O Git passa a ser a fonte da verdade. O runner deixa de ter credencial de produção eterna: OIDC para a nuvem, tokens de vida curta e admission no cluster verificando a assinatura (Cosign) antes do pod subir. Quem ainda faz docker compose up num VPS via SSH (como no Vaultwarden) está no degrau da entrega contínua — válido, só não é GitOps. Para o contexto de onde vieram as peças, veja a história do Docker e a do Kubernetes.
O pipeline como alvo
Em 2019 o medo era o merge quebrado. Em 2026 o medo é o job que passa e publica malware: action comprometida, pacote npm sequestrado, secret vazando no log.
- Fixe actions e imagens por SHA ou digest, nunca por
@v3solto. - Secrets no cofre (GitHub/GitLab, Vault, SOPS) — nunca no YAML.
- Token do job com o mínimo de permissões (
permissions:no Actions). - SBOM e assinatura com Cosign (Sigstore, keyless via OIDC) na imagem.
- Proveniência SLSA Build L2/L3 quando quem gera é a plataforma de build, não um script do repositório.
- PR vindo de fork: não rode o workflow do branch do atacante com secrets da organização (
pull_request_targetmal usado).
Depois do deploy, o Prometheus diz se o verde mentiu.
Por onde começar de verdade
- Tronco compartilhado, PRs pequenos, CI no PR (lint + teste). Sem isso, o resto é teatro.
- Imagem OCI versionada pelo SHA do commit, em registry próprio ou no GHCR/GitLab.
- Staging automático; produção com porta (tag ou aprovação) até os testes merecerem implantação contínua.
- Só então GitOps, assinatura e SLSA.
Muita empresa para no passo 2 e chama isso de DevOps. Não é pecado; é honesto. Pular para o Argo CD sem testes é pintar o avião.
Se o objetivo é formalizar o conhecimento, o post sobre a certificação LPI DevOps Tools Engineer cobre CI/CD, containers e automação.
Uma volta visual
O episódio do Dicionário do Programador, do canal Código Fonte TV, resume pipeline e CI/CD em poucos minutos:
Referências
- Pipelines Terraform no GitLab — o CD de infraestrutura no mesmo ano deste post
- Gitea: Git self-hosted com Actions, runner e tea CLI
- A história do GitLab
- Curso de Docker grátis
- Automatizando servidores Linux com Ansible
- Prometheus e Node Exporter
- GitLab CI/CD docs · GitHub Actions docs · Forgejo Actions
- SLSA · Sigstore · Argo CD · Flux
CI/CD continua sendo o mesmo pipeline de 2019: integrar cedo, testar sempre, soltar em pedaços pequenos. O YAML foi para o Git, o cluster passou a puxar o estado, e o job verde agora precisa provar de onde veio o binário. O resto é ferramenta.