8 pontos por GN⁺ 2026-02-07 | 3 comentários | Compartilhar no WhatsApp
  • Embora seja amplamente usado por ser um CI incluído por padrão no repositório, sua ineficiência estrutural e experiência de usuário instável reduzem a produtividade dos desenvolvedores
  • O carregamento lento do visualizador de logs e os travamentos do navegador, além da sintaxe complexa de YAML e erros de expressões, levam a depuração repetitiva
  • Por conta de uma arquitetura em que você não possui os recursos de computação, a ferramenta expõe limitações em desempenho, escalabilidade e controle do ambiente
  • Ao tentar contornar vários problemas, repete-se a situação de recriar o próprio CI com YAML complexo ou scripts Bash gigantescos
  • Em comparação, o Buildkite oferece uma alternativa de CI sustentável no longo prazo com estrutura YAML simples, agentes com possibilidade de self-hosting e uma experiência prática de logs

Problemas do GitHub Actions

  • O visualizador de logs do GitHub Actions é ineficiente: até para verificar um erro simples são necessários vários cliques e carregamentos de página
    • Quando um build falha, é preciso passar pela página de resumo dos checks → página de execução do workflow → página do job → clique na etapa recolhida, exigindo 3 a 4 transições de página, cada uma com seu próprio carregamento
    • Em logs de builds grandes, o navegador trava repetidamente, e o congelamento do Chrome ao usar a busca é reproduzível
    • Em logs longos, a rolagem simplesmente deixa de funcionar, e no fim você precisa baixar o artefato do log bruto e abrir em um editor de texto
    • O botão de voltar leva não para a página original do PR, mas para páginas imprevisíveis da UI do GitHub Actions, enchendo o histórico do navegador com URLs do Actions
  • A improdutividade do processo de depuração
    • Para verificar variáveis de ambiente, você adiciona uma etapa run: env, faz push de novo e entra em um ciclo de feedback de 20 minutos, repetindo esse processo dezenas de vezes por causa de uma mudança de uma linha
    • Com ciclos de feedback de 20 minutos se repetindo, o dia inteiro é consumido esperando o CI
  • As limitações estruturais do YAML
    • O YAML do GitHub Actions é uma forma especial que combina sua própria linguagem de expressões, modelo de objetos de contexto e regras de interpolação de strings
    • Se você errar uma única aspas em uma expressão ${{ }}, só vai descobrir que a string se perdeu depois de esperar 4 minutos até o runner subir
    • A sintaxe das expressões existe em um espaço liminar: complexa demais para ser apenas configuração, limitada demais para ser usada como linguagem de programação de verdade
    • A estrutura faz com que a sintaxe seja aprendida pela experiência de falha, e não pela documentação
  • Os riscos de segurança do Marketplace
    • Ao carregar uma action externa com a sintaxe uses:, você concede a terceiros não verificados acesso ao repositório, aos segredos e ao ambiente de build
    • É possível fixar por SHA, mas quase ninguém faz isso e, mesmo fixando, o modelo continua sendo executar código opaco que você não leu com acesso ao GITHUB_TOKEN
    • O Marketplace mistura actions mantidas pela comunidade com níveis variados de qualidade, em sua maioria compostas por scripts shell e Dockerfiles
    • O gerenciamento de dependências é opaco, e existe a possibilidade de executar código inseguro
  • As restrições do ambiente de computação
    • Os runners padrão do GitHub Actions são runners compartilhados da Microsoft: lentos, com recursos limitados e sem possibilidade de customização significativa
    • O custo de runners maiores já é suficiente para fazer o time financeiro mandar um "precisamos conversar" em forma de reunião, e mesmo assim o ambiente continua fora do seu controle
    • Existem pelo menos seis startups — como Namespace, Blacksmith, Actuated, Runs-on e BuildJet — especializadas apenas em resolver a lentidão dos runners do GitHub Actions, o que por si só prova a deficiência do ambiente de computação padrão
    • Configurar um self-hosted runner resolve o problema de computação, mas todos os outros — expressões YAML, modelo de permissões, Marketplace, visualizador de logs — continuam iguais

Problemas menores, mas cumulativos

  • actions/cache: as chaves de cache são confusas, cache miss acontece em silêncio e a remoção de cache (eviction) é opaca, fazendo você gastar mais tempo depurando cache do que economiza com ele
  • Workflows reutilizáveis: não podem ser aninhados além de certa profundidade, não acessam de forma limpa o contexto do workflow chamador e não permitem testes isolados
  • Modelo de permissões do GITHUB_TOKEN: permissions: write-all é amplo demais, e permissões granulares viram um labirinto por causa da interação entre configurações em nível de repositório, workflow e job
  • Controle de concorrência (concurrency): cancelar execuções em andamento no mesmo branch dá para fazer com uma linha, mas controles mais finos do que isso não são suportados
  • Impossibilidade de usar secrets em condições if: uma execução condicional como if: secrets.DEPLOY_KEY != '' não funciona e, embora isso seja razoável do ponto de vista de segurança, ainda exige soluções alternativas ao escrever workflows que funcionem tanto em forks quanto no repositório principal

A armadilha do "vamos só usar script Bash"

  • Engenheiros cansados do YAML de CI sentem a tentação de substituir tudo por scripts bash em run:, mas com o tempo vão sendo adicionados condicionais, funções, parsing de argumentos e paralelismo
  • Três meses depois, surgem 800 linhas de bash reimplementando paralelismo de jobs com wait e arquivos PID, além de lógica própria de retry e parsing de saída
  • No fim, você não escapou do sistema de CI: apenas construiu manualmente em bash um sistema de CI pior, sem framework de testes e que ninguém consegue acompanhar
  • Bash é adequado como cola (glue), mas usá-lo como sistema de build ou harness de testes apenas move a complexidade de um lugar com guardrails para outro sem nenhum

A abordagem alternativa do Buildkite

  • Visualizador de logs confiável

    • O visualizador de logs do Buildkite mostra logs corretamente sem travar o navegador, renderizando cores ANSI e a formatação dos frameworks de teste como deveriam aparecer
    • Com o recurso de Annotation, uma etapa de build pode exibir diretamente na página do build, em Markdown, resumos de falhas de teste, relatórios de cobertura e links de deploy
    • Como os agentes rodam na sua própria infraestrutura, é possível acessar a máquina de build por SSH e depurar diretamente
  • Estrutura YAML simples

    • O YAML do Buildkite é uma estrutura de dados pura que descreve o pipeline, declarando apenas etapas, comandos e plugins
    • Quando lógica de verdade é necessária, ela é escrita em uma linguagem de programação real que pode ser executada localmente
    • Isso mantém clara a fronteira de "orquestração na configuração, lógica no código", exatamente a fronteira que o GitHub Actions embaralha
  • Controle total sobre o ambiente de computação

    • O agente do Buildkite é um binário único, capaz de rodar na sua própria nuvem, on-premises ou hardware customizado
    • Você pode controlar completamente tipo de instância, cache, armazenamento local e rede, desde grandes instâncias EC2 com discos NVMe e 20 GB de cache de camadas Docker até um Raspberry Pi
    • Não existe uma indústria de terceiros do tipo "Buildkite, só que mais rápido"; basta rodar uma máquina maior
    • Para o mantenedor individual de uma pequena biblioteca open source, o tier gratuito do GitHub Actions para repositórios públicos continua valendo a pena
    • O foco principal deste texto são equipes que operam sistemas de produção, onde o tempo de CI é medido como perda semanal de horas de engenharia e builds de 45 minutos geram custo tanto em computação quanto em mão de obra
    • Nesses ambientes, o overhead de operar agentes do Buildkite se paga rapidamente
  • Suporte a pipelines dinâmicos

    • No Buildkite, as etapas do pipeline são dados, e scripts podem gerar (emit) e enviar novas etapas dinamicamente em tempo de execução
    • Em monorepos, isso permite gerar exatamente as etapas de build e teste necessárias com base nos arquivos alterados, sem matrizes hardcoded nem espaguete de if: contains(...)
    • matrix, condições if e workflows reutilizáveis do GitHub Actions tentam aproximar isso, mas acabam fazendo você montar uma máquina de Rube Goldberg em uma linguagem declarativa com pouca expressividade
  • Simplicidade da estrutura de plugins

    • Estruturalmente, ela é parecida com o Marketplace do GitHub Actions por também buscar código em repositórios de terceiros
    • A diferença é que os plugins do Buildkite costumam ser thin shell hooks, e não imagens Docker, o que reduz a superfície e permite ler tudo em poucos minutos
    • Como tudo roda na sua própria infraestrutura, o usuário pode controlar o blast radius
  • Detalhes voltados para a experiência do usuário

    • O Buildkite permite mostrar emojis personalizados (:parrot:, :docker: etc.) ao lado das etapas do pipeline; pode parecer algo pequeno, mas mostra um cuidado minucioso com a experiência de uso do produto
    • O GitHub Actions parece um produto desenhado por comitê que nunca perguntou: "isso é prazeroso de usar?"

Conclusão: critérios para escolher um sistema de CI

  • O GitHub Actions dominou o mercado pela vantagem de ser o default, com repositórios públicos gratuitos, integração na plataforma que todo mundo já usa e um nível "bom o suficiente"
    • É o Internet Explorer do CI: continua sendo usado porque o custo de migração é real e o tempo é finito
  • O Buildkite é superior em usabilidade contínua e experiência do desenvolvedor
  • Para projetos open source simples, o GitHub Actions basta, mas em ambientes grandes de produção o Buildkite é mais adequado
  • Na história dos sistemas de CI, quem ganha participação de mercado não é o melhor sistema, e sim o sistema mais fácil de começar a usar
  • O GitHub Actions é o CI mais fácil de começar, e o Buildkite é o CI melhor para continuar usando; no longo prazo, isso importa mais
  • Se a estrutura da ferramenta de CI está consumindo o tempo dos desenvolvedores, o problema não são os desenvolvedores, e sim a própria ferramenta

3 comentários

 
kimjoin2 2026-02-07

Parece que o problema é a própria complexidade crescente do CI.

 
tujuc 2026-02-07

Parece que o mesmo texto foi publicado duas vezes. Ainda assim, hoje em dia isso até parece uma boa combinação para a IA montar..

 
GN⁺ 2026-02-07
Comentários no Hacker News
  • Já usei vários sistemas de CI. Usei bastante CircleCI e GitHub Actions, mas cheguei a uma conclusão diferente da do autor
    Antigamente, Jenkins era voltado para Java e Travis para Rails, mas esse tipo de CI especializada acabou sendo um beco sem saída. Hoje, CI evoluiu para ser simplesmente um orquestrador de workflows
    O motivo de eu ter migrado do CircleCI 2 para o GitHub Actions também foi porque o CircleCI não conseguiu fazer bem essa transição. O GHA tinha expressividade suficiente
    Coisas como navegador de logs ou sintaxe YAML são problemas menores. O importante é ter controle sobre os recursos de computação e pipelines dinâmicos; o primeiro é possível em qualquer CI, e o segundo é um ponto forte do Buildkite
    Minha conclusão é que o Actions é, na prática, bem decente, e se eu começasse uma empresa nova usaria Buildkite; para open source, usaria Actions

    • Discordo. Em desenvolvimento de jogos, o sistema de build é central, e uma abordagem genérica de CI é lenta demais
      Se você não entende o grafo de build, precisa manter estado de build incremental, e isso provoca bugs intermitentes. Por isso são necessários sistemas como UnrealEngine Horde ou UBA, que entendem profundamente a estrutura de build
      Com uma CI generalista, um build pode levar mais de um dia
    • O Actions é um despachante de eventos e orquestrador, motor de execução, sistema de cache, marketplace, gerenciador de secrets e uma plataforma multifuncional
      Eu costumo usar só as partes boas do GHA. Por exemplo, o GitHub é excelente como despachante de eventos, mas ruim como orquestrador de workflows, então delego essa parte a outro sistema
    • Não concordo com tratar o navegador de logs como algo sem importância. A experiência de ler logs com cores ANSI e formatação preservadas é importante
      Se os logs que você vê dezenas de vezes por dia são ruins, a produtividade cai. Ler logs brutos ignorando códigos de escape é realmente doloroso
    • Foi dito que “ter controle sobre os recursos de computação” é importante, mas o GitHub cobra mesmo quando você executa a CI no seu próprio hardware
    • Fui cliente inicial do Buildkite e fiquei muito satisfeito com o sistema, que é ergonômico e oferece muito controle
  • Eu mantenho a simplicidade. Coloco toda a orquestração no script deploy.sh e executo localmente no Mac ou no AWS CodeBuild
    O YAML é só uma linha: bash deploy.sh. Se houver um contêiner Docker, ele funciona igual em qualquer lugar, como Azure ou GitHub Actions

  • A estratégia central em qualquer ambiente de CI é ter um sistema de build idêntico ao local
    Eu sempre começo com um Makefile. Docker, builds de CI, linting, tudo é acionado pelo Makefile. Quando o projeto cresce, às vezes migro para outras ferramentas, mas a base é uma única ferramenta de disparo

    • Foi com essa ideia que criei o mkincl. Ele permite modularizar e reutilizar Makefiles. Uso na empresa há anos, e é intuitivo e flexível
    • Em vez de depender de plugins do provedor de CI, é melhor migrar para uma linguagem de mais alto nível
      Eu uso muito Fastlane em mobile, e ele reduz boilerplate e fornece estrutura. No fim, continua sendo Ruby, então dá para escapar quando necessário
    • Make é realmente um sistema estranho. Uma das regras padrão é extrair arquivos de um sistema de controle de versão
      (link para a documentação do GNU Make)
      No fim, isso equivale a dizer “é só usar um script Bash”, mas com complexidade desnecessária adicionada
    • Essa abordagem é ideal, mas irrealista em projetos médios e grandes
      Na empresa atual, como já não é possível rodar o pipeline inteiro localmente, surgiu uma infraestrutura gigantesca de CI em que se roda build 10 vezes para testar um único MR
  • Achei que este texto parecia publicidade de Nix/Buildkite
    A CI deveria só executar scripts ou alvos de build. A CI deve fornecer ambiente e configuração, e a lógica deve ficar no código
    Isso traz independência da CI, facilitando a migração entre sistemas

    • “Manter a CI simples” é algo realisticamente impossível. Em escala, a complexidade com gatilhos condicionais, estratégia de branches, permissões e balanceamento de carga é inevitável
      O GitLab CI lida relativamente bem com essa complexidade. Seus templates e recursos de composição de jobs são excelentes, mas é difícil depurar, e a lógica condicional às vezes falha de forma inesperada
    • Isso não é publicidade. Até para a equipe do Buildkite foi uma surpresa agradável
    • Também concordo. Quando migrei um sistema de CI no passado, as equipes que colocavam toda a lógica em arquivos .sh tiveram uma migração muito fácil
      Já as equipes que fragmentaram tudo na UI sofreram bastante
    • Pelo menos fico feliz que não tenha havido reação do tipo “isso foi escrito por IA”
  • O problema não é CI/CD em si, e sim a cultura de programar em arquivos de configuração
    O ciclo de git commit -m "try fix" e depois esperar 10 minutos é comum demais. Ainda faltam ambientes de CI reproduzíveis localmente

    • Isso não é problema de ferramenta, e sim resultado de falha de política. É preciso distinguir claramente build, release e build de debug
      Se o isolamento de ambientes for definido por política, qualquer ferramenta funciona bem. No fim, o essencial é a harmonia entre ferramenta e metodologia
    • Exato, acho que esse ponto representa 80% da ideia central do texto
    • Ferramentas como act ajudam bastante a reproduzir CI localmente
  • O título dizendo que “está matando equipes de engenharia” é exagerado. GitHub Actions é bom o suficiente
    Eu prefiro a Bitbucket ou GitLab

    • Eu também cliquei achando “A Microsoft está matando pessoas?”, e saí decepcionado
    • Eu também achei que seria sobre GitLab. Especialmente o problema de loop de feedback lento também se aplica exatamente ao GitLab
  • A queda de confiabilidade do GitHub tem sido séria recentemente
    O actions/checkout falha sem motivo, jobs de release rodam duas vezes, e às vezes fica 40 minutos só esperando
    Uso há anos, mas a estabilidade básica está piorando. Pena que deixei passar o Buildkite

    • Exato, os jobs de cron do GHA são instáveis. A própria documentação menciona que não são confiáveis
  • GitHub Actions é uma das piores ferramentas de CI que já usei (no nível do Jenkins)
    Em contrapartida, o Buildkite é o melhor. Graças aos pipelines dinâmicos, ele pode criar etapas de retry automaticamente quando um teste falha, ou ajustar testes paralelos com base nas mudanças no código
    Também é uma grande vantagem poder usar uma configuração de máquina diferente para cada job de CI. Recomendo fortemente

    • Jenkins tinha muitos problemas, mas a definição de pipeline baseada em Groovy era boa. Acho muito melhor que YAML
    • Jenkins é um sistema estável testado em batalha. Lida com milhares de jobs sem problema e funciona logo após a instalação. Acho que é um dos melhores open source dos últimos 25 anos
  • As pessoas que defendem uma “CI simples baseada em scripts” parecem não ter experiência com projetos reais em grande escala