10 pontos por GN⁺ 2026-01-15 | 3 comentários | Compartilhar no WhatsApp
  • Compartilhamento da experiência frustrante de um desenvolvedor com o GitHub Actions, devido ao loop de feedback lento e ao processo complexo de depuração
  • No projeto tmplr, a documentação era gerada com CUE via build.rs, mas o problema começou quando o build de CI falhou
  • Entre 4 plataformas, apenas o Linux ARM falhava no build; a causa era o modo como o GitHub Actions esconde binários x86_64 em runners arm64 durante cross builds
  • Repetição de um loop de feedback ineficiente, levando 2–3 minutos para testar uma única alteração
  • Como solução, build.rs foi removido e houve migração para um GNU Makefile, resolvendo o problema ao controlar diretamente a lógica de CI

Contexto do problema

  • tmplr é uma ferramenta de scaffolding de arquivos/projetos que usa arquivos de template legíveis e editáveis por humanos
  • Em build.rs, o CUE era usado para gerar README.md, CHANGELOG.md e arquivos de versão/ajuda, garantindo consistência
  • O trabalho em si foi concluído em cerca de 1,5 hora, e o artigo relacionado também já havia sido escrito
  • Funcionava normalmente em ambiente local, mas no ambiente de CI do GitHub Actions o build falhou porque o binário do CUE não estava instalado

Causa da falha do build

  • Entre 4 plataformas (Linux ARM, macOS ARM, Linux x86_64, macOS x86_64), apenas o Linux ARM apresentava erro de “command not found”
  • Causa: o cross build com matrix é fortemente isolado, então o CUE era instalado apenas no host Linux x86_64 e no host macOS ARM
    • No macOS, não havia problema para executar binários x86_64
    • No Linux x86_64, também não havia problema para executar binários x86_64
    • Porém, no GitHub Actions, binários x86_64 são escondidos em runners arm64, tornando sua execução impossível

Loop de feedback ineficiente

  • Processo repetido para resolver o problema:
    1. Pesquisar formas possíveis de corrigir
    2. Alterar ci.yml
    3. Fazer commit e push (jj squash --ignore-immutable && jj git push)
    4. Abrir a aba "Actions"
    5. Abrir a execução mais recente
    6. Abrir a execução de Linux ARM
    7. Esperar alguns segundos
    8. Frustrar-se
    9. Repetir
  • 2–3 minutos gastos por alteração individual
  • Idealmente, o GitHub poderia oferecer um runner local completo, ou então uma forma de verificar rapidamente o andamento após o push
    • Algo como um recurso de "scratch commit": uma maneira de testar várias execuções sem poluir o histórico do Git nem o registro das execuções do Actions
  • Porém, atualmente esse tipo de recurso não existe

Solução

  • Após repetir o loop por 30 minutos, houve uma pausa
  • Foi aplicada uma abordagem já conhecida na internet: "não deixar o GitHub Actions gerenciar a lógica; controlar o script diretamente e fazer com que o Actions apenas o chame"
  • build.rs foi removido (foi uma pena, mas algum sacrifício era necessário)
  • Todo o trabalho de geração foi movido para um GNU Makefile
  • Os arquivos gerados foram commitados no repositório, e as mudanças de CI foram revertidas
  • Problema resolvido

Conclusão

  • O GitHub Actions é a razão pela qual algumas coisas boas deixam de ser possíveis
  • Muito tempo é desperdiçado depurando runners ou otimizando o processo de build
  • Ainda assim, há vantagens difíceis de obter por outros meios, como builds para macOS
  • E, claro, não se conhece outro sistema que seja mais fácil de configurar do que o GitHub Actions

We are all doomed to GitHub Actions. …but at least I dodged the bullet early.

3 comentários

 
iolothebard 2026-01-15

O GitHub Actions deveria fazer apenas setup de ambiente (SO, toolchain de build, …) e executar scripts (shell, Python, bat, ps1…). Mesmo que o GitHub caia, se o ambiente estiver pronto, deveria ser possível fazer o build em qualquer lugar. Quando vejo os workflows do GitHub Actions hoje em dia, fico pensando se realmente precisa ir atrás e usar até esse tipo de coisa. Há muito tempo atrás (?) o Ansible foi por esse caminho e acabou fracassando.

 
GN⁺ 2026-01-15
Comentários do Hacker News
  • O principal problema do GitHub Actions é que o loop de feedback é lento demais
    É realmente frustrante ter que dar push e esperar só para confirmar uma falha simples
    Acho melhor separar as tarefas de CI em scripts que possam ser executados localmente e usar os recursos do Actions apenas como melhoria incremental
    A combinação de workflow_dispatch e gh workflow run também é razoável, mas é inconveniente que o segundo não forneça diretamente a URL do workflow executado

    • Com nektos/act dá para executar Actions localmente
      Foi bastante bem-sucedido para obter feedback rápido
    • Eu padronizei o Actions para compilar e testar imagens Docker
      Se surgir algum problema, dá para depurar em um estado quase idêntico ao ambiente do GitHub Actions
    • Acho que não poder executar as etapas de CI localmente não faz sentido
      Isso deveria ser um requisito básico de qualquer sistema de CI
    • Já pensei em criar eu mesmo uma ferramenta de CI que pudesse ser executada localmente
      No fim, o que importa são recursos como enfileiramento, análise de saída e telemetria do histórico de builds
    • Ao usar gh workflow run, para obter a URL eu tinha que consultar de novo a lista de execuções do workflow pela API do GitHub
      Se houver várias execuções ao mesmo tempo, isso pode dar errado, mas por enquanto tem funcionado mais ou menos bem
  • Fiz um resumo de dicas de design para CI

    1. Usar uma linguagem de script amigável para CI, como pwsh, em vez de bash
    2. Não colocar lógica no workflow e mantê-lo simples
    3. Criar scripts independentes para que possam ser testados localmente
    4. Registrar saída de estado e informações de versão para facilitar a depuração
    5. Considerar runners de terceiros com bons recursos de depuração
    • Não concordo com o item (1). Se o processo de build ou teste ficar complexo demais, isso é um cheiro ruim
      Um shell simples deveria bastar
    • Não concordo com o item (1), mas acho o (2) correto
      É bom definir alvos de CI no Makefile e chamá-los de forma simples, como make ci-test
    • Já passei por um inferno de plugins do Jenkins no passado
      Desde então, gerencio todo o CI com wrappers simples como make build
    • Se você encapsular todos os builds em um único script, o sistema de CI perde a visibilidade das etapas detalhadas
      Seria bom poder separá-las com marcadores como BeginStep("Step Name")
    • No fim, com uma estrutura dessas, fico pensando se não seria necessário uma nova ferramenta de CI que execute os scripts diretamente
  • O problema não é tanto o GitHub Actions em si, mas a automação mal feita construída em cima dele
    A lógica deveria ser transformada em scripts numa linguagem como Python, para que também pudesse ser executada localmente

    • O que incomoda muita gente é não poder acessar por SSH e depurar diretamente na VM que falhou
      Você precisa modificar o workflow, dar push e esperar toda vez
    • Também houve quem brincasse que “esse trabalho de transformar tudo em scripts é coisa de algumas semanas faturáveis”
    • Recursos específicos de CI, como deploy, release e cache, são difíceis de reproduzir completamente em ambiente local
    • Essa abordagem lembra a época em que o systemd chamava scripts init.d, mas não é algo ruim
    • Alguém chegou a afirmar: “isso é 100% culpa do GitHub Actions”
  • Eu faço todo o CI dentro de contêineres
    A plataforma de CI só executa esse contêiner, então dá para rodar a mesma coisa localmente
    As plataformas não gostam dessa abordagem, porque ela quebra o vendor lock-in

    • Gosto do SourceHut CI
      Quando falha, dá para entrar por SSH imediatamente para depurar, e também é possível alterar o manifesto e reexecutar sem dar push em uma branch
      Mas ele exige self-hosting
    • No GitLab CI eu também usei algo parecido, com uma imagem Docker dedicada
      A padronização fica mais fácil, mas surge o trade-off de manter essa imagem
    • A desvantagem é que builds de macOS são difíceis de colocar em contêineres
    • Os webhooks do GitHub são muito detalhados
      Na prática, quase não existe lock-in, mas as pessoas caem em cargo cult de CI/CD
    • Teve até quem reagisse com “manda isso numa newsletter”
  • Eu gosto do GitHub Actions
    É melhor do que o Travis que eu usava antes e, para projetos OSS, é muito útil como recurso gratuito
    Depois que adotei Nix, a reprodutibilidade do ambiente melhorou bastante, e a combinação com o Actions ficou muito melhor

    • Eu também concordo com a abordagem usando Nix
      Dá para executar no Actions o mesmo contêiner criado com flake
      Projeto de exemplo
  • Acho que o GitHub Actions deveria ser apenas uma estrutura para chamar scripts bash ou python
    O bash tem muitas limitações, Python é mais flexível e também é fácil de executar localmente
    O ideal é algo como este artigo, que instala o uv automaticamente e gerencia dependências
    É mais complexo que bash, mas no ambiente do Actions isso não traz grande problema de desempenho

    • Na prática, YAML serve para definir o ambiente de execução, e a lógica de execução deve ficar em scripts externos
  • O maior problema do Actions é a forma como ele é vendido como algo para combinar workflows
    Depurar é quase impossível, e configurar cache é complicado, o que deixa os builds lentos
    Por isso, a ideia de executar diretamente em VMs persistentes parece atraente

  • Sou fundador da Depot
    Opero um serviço que oferece runners do GitHub Actions mais rápidos e baratos
    Muitas das reclamações que as pessoas sentem refletem de fato a opinião da maioria
    O sistema do Actions é estruturalmente ineficiente, e toda semana descobrimos um novo gargalo
    Tenho convicção de que existe uma forma melhor, e estamos experimentando isso
    Mais detalhes em depot.dev

  • No fim de semana passado, criei uma ferramenta chamada gg watch action
    Ela encontra a action mais recente ou em execução da branch atual
    Link no GitHub

    • A recepção foi boa, com comentários de que “isso deveria fazer parte da CLI gh
      Mas havia um bug em que o repositório não aparecia no comando gg tui
  • Fiquei me perguntando se uma ferramenta como act ajudaria
    nektos/act
    Por diferenças de arquitetura, a execução local e a online podem divergir, mas ainda assim parece útil

    • Quando vi isso no passado, não era um substituto completo
      Havia cerca de 80% de compatibilidade
    • Não é perfeitamente idêntico, mas é muito útil para criar um loop de feedback rápido
    • Na verdade, o mais necessário é um recurso que permita acessar por SSH e depurar após uma falha
      O SourceHut suporta isso, e é realmente muito conveniente
 
anyflow 2026-01-18

Parece ser um problema inevitável por causa da estrutura em que é preciso colocar a lógica dentro do YAML.

O texto acima parece ter dado mais ou menos a resposta abaixo, e fico pensando se substituir a parte dos scripts por Dagger não seria justamente a solução correta.

"Não deixe o GitHub Actions gerenciar a lógica; controle os scripts diretamente e faça com que o Actions apenas invoque esses scripts"