12k
All articles

5 alternativas ao GitHub Actions para equipes de frontend

Compare cinco alternativas ao GitHub Actions para equipes frontend: CircleCI, Buildkite, Jenkins, Woodpecker CI e Dagger, com exemplos e orientações.

OpenReplay Team
OpenReplay Team
5 alternativas ao GitHub Actions para equipes de frontend

As melhores alternativas ao GitHub Actions para equipes de frontend são: o CircleCI, para CI totalmente hospedado; o Buildkite, para um plano de controle hospedado que roda em agentes hospedados ou auto-hospedados; o Jenkins e o Woodpecker CI, para CI totalmente auto-hospedado; e o Dagger, para pipelines como código que rodam da mesma forma no notebook e em qualquer CI.

O gatilho costuma ser uma fatura cheia de minutos de runner, um pull request parado na fila ou um workflow que só falha nos runners do GitHub e nunca na sua máquina. Este artigo parte do princípio de que você já conhece o modelo de workflows do GitHub Actions. Ele compara cinco opções nos mesmos três pontos: para quem cada uma é indicada, onde seus jobs são executados e como fica um job de instalação, lint, testes e build para um frontend em Node.

Principais conclusões

  • Se cada job de CI apenas chama npm ci, npm run lint, npm test e npm run build, trocar de ferramenta de CI significa reescrever algumas linhas de YAML, e não a lógica do pipeline.
  • O Buildkite hospeda a orquestração, enquanto os jobs rodam em agentes: Linux hospedado pelo Buildkite, macOS hospedado pelo Buildkite nos planos pagos ou máquinas operadas pela sua equipe.
  • O CircleCI é um CI hospedado configurado em .circleci/config.yml e oferece suporte a runners auto-hospedados em todos os planos, inclusive no Free.
  • O Jenkins e o Woodpecker são auto-hospedados. Você deixa de pagar por minuto e passa a pagar por servidores e manutenção.
  • O Dagger não é um serviço de CI. É código de pipeline que roda localmente e dentro de qualquer CI que você já usa.

Por que equipes de frontend procuram alternativas ao GitHub Actions?

Equipes de frontend costumam abandonar o GitHub Actions por um destes quatro motivos: os minutos dos runners hospedados custam caro demais, os runners hospedados ficam presos em fila, é preciso rodar agentes em hardware próprio ou não é possível reproduzir um pipeline de CI/CD localmente. Analise o segundo motivo antes de migrar. Se o seu único problema são os runners hospedados na fila, os runners auto-hospedados do GitHub Actions podem resolver a questão sem trocar de ferramenta. O GitLab CI/CD vale a pena principalmente se você também for migrar seus repositórios; a configuração dele é abordada em Pipelines de GitLab CI/CD.

Para manter a comparação justa, coloque a lógica de build no package.json, de modo que todas as ferramentas de CI chamem os mesmos scripts:

{
  "scripts": {
    "lint": "eslint .",
    "test": "vitest run",
    "build": "vite build"
  }
}

Substitua pelos comandos do seu framework. Em cada exemplo abaixo, a configuração de CI faz uma única coisa: executa npm ci e, em seguida, esses três scripts.

Buildkite

O Buildkite é indicado para equipes que querem orquestração hospedada, mas precisam de controle sobre as máquinas que executam seus jobs. O Buildkite suporta os dois modelos: agentes que você mesmo opera e agentes que o Buildkite hospeda para você. Os agentes Linux hospedados pelo Buildkite estão disponíveis em todos os planos, inclusive no Free, que é limitado ao tamanho de máquina pequeno. Os agentes macOS hospedados pelo Buildkite exigem um plano Pro ou Enterprise. Os agentes auto-hospedados consultam o Buildkite em busca de trabalho (polling), então você não precisa abrir nenhuma porta de entrada. O Buildkite oferece uma conta gratuita para começar.

# .buildkite/pipeline.yml
steps:
  - label: "Install, lint, test, build"
    commands:
      - npm ci
      - npm run lint
      - npm test
      - npm run build
    plugins:
      - docker#v5.14.0:
          image: "node:<your-node-version>"

O plugin do Docker executa os comandos dentro de uma imagem Node, então o agente só precisa ter o Docker. Se o Node já estiver instalado no agente, você pode remover o bloco plugins.

Veredito: o Buildkite é a melhor opção quando você quer ter controle da sua infraestrutura de computação sem operar um servidor de CI. A contrapartida é que você gerencia a frota de agentes, a menos que use agentes hospedados.

CircleCI

O CircleCI é indicado para equipes que querem um serviço totalmente hospedado, com o mínimo de infraestrutura. O CircleCI é hospedado em primeiro lugar, mas também oferece runners auto-hospedados em todos os planos, inclusive no Free. Por padrão, seu código roda na infraestrutura do CircleCI. A introdução à configuração do CircleCI indica a 2.1 como a versão mais recente.

# .circleci/config.yml
version: 2.1

jobs:
  build:
    docker:
      - image: cimg/node:<full.node.version>
    steps:
      - checkout
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build

workflows:
  ci:
    jobs:
      - build

Fixe a imagem cimg/node na versão completa do Node do seu projeto. O CircleCI também oferece cache de dependências, mas ele foi deixado de fora aqui para manter o exemplo curto. Erros de YAML são um motivo comum para o primeiro push no CircleCI falhar, então vale a pena passar o arquivo pelo validador de YAML da OpenReplay para identificar erros de sintaxe antes de fazer o commit.

Veredito: o CircleCI é o substituto mais equivalente ao GitHub Actions. Faz sentido se os minutos e as filas são o problema, mas você ainda não quer operar servidores.

Jenkins

O Jenkins é indicado para equipes com requisitos rígidos de infraestrutura on-premises e alguém com tempo para mantê-lo. O Jenkins é exclusivamente auto-hospedado. O software é gratuito e open source, mas o custo deixa de ser a cobrança por minuto e passa a ser os servidores, plugins e atualizações que sua equipe mantém. Os pipelines ficam em um Jenkinsfile escrito em sintaxe declarativa de Pipeline:

pipeline {
    agent any
    stages {
        stage('Install') { steps { sh 'npm ci' } }
        stage('Lint')    { steps { sh 'npm run lint' } }
        stage('Test')    { steps { sh 'npm test' } }
        stage('Build')   { steps { sh 'npm run build' } }
    }
}

agent any pressupõe que o Node esteja instalado em qualquer agente que pegar o job.

Veredito: escolha o Jenkins apenas quando auto-hospedar for um requisito obrigatório. Para a maioria das equipes de frontend, a manutenção custa mais do que os minutos economizados.

Woodpecker CI

O Woodpecker CI é indicado para equipes pequenas que querem um CI leve, auto-hospedado e com um YAML familiar. O Woodpecker CI é auto-hospedado, e cada step executa seus comandos dentro do contêiner especificado no próprio step, conforme descrito na sintaxe de workflows. Os workflows podem ficar em um diretório .woodpecker/, com um workflow por arquivo.

# .woodpecker/ci.yaml
steps:
  - name: install
    image: node:<your-node-version>
    commands:
      - npm ci
  - name: lint
    image: node:<your-node-version>
    commands:
      - npm run lint
  - name: test
    image: node:<your-node-version>
    commands:
      - npm test
  - name: build
    image: node:<your-node-version>
    commands:
      - npm run build

Dividir o trabalho em quatro steps não significa instalar quatro vezes. Por padrão, os steps rodam em sequência, e o workspace com o checkout é montado em todos eles, então a pasta node_modules gerada em install continua disponível em build. Com o woodpecker-cli e um backend compatível instalados, você pode executar um workflow localmente com woodpecker-cli exec antes de fazer o push.

Veredito: para auto-hospedagem, o Woodpecker CI é uma opção mais simples que o Jenkins. A desvantagem é que você mesmo opera o servidor e os agentes.

Dagger: pipelines como código, não um serviço de CI

O Dagger não é um serviço de CI hospedado e não substitui um. Você escreve o pipeline como código com um SDK do Dagger, e o mesmo código roda no notebook e dentro de qualquer sistema de CI, inclusive o GitHub Actions. A documentação dos SDKs abrange Go, Python, TypeScript, Java, PHP e Elixir, além do Dang, a linguagem de script própria do Dagger. Veja o mesmo job em TypeScript, usando um módulo criado com dagger init --sdk=typescript --name=frontend-ci:

import { dag, Directory, object, func } from "@dagger.io/dagger"

@object()
class FrontendCi {
  @func()
  async check(source: Directory, nodeVersion: string): Promise<string> {
    return await dag
      .container()
      .from(`node:${nodeVersion}`)
      .withMountedDirectory("/src", source)
      .withWorkdir("/src")
      .withExec(["npm", "ci"])
      .withExec(["npm", "run", "lint"])
      .withExec(["npm", "test"])
      .withExec(["npm", "run", "build"])
      .stdout()
  }
}

Execute localmente com dagger call check --source=. --node-version=<your-node-version>. Seu job de CI existente passa a executar esse mesmo comando e nada mais. Se a execução local passar, a execução no CI roda exatamente os mesmos steps de contêiner. O custo é mais um SDK e uma engine para a equipe aprender.

Esses comandos são do Dagger 0.x. O Dagger 1.0, anunciado em beta em outubro de 2026, renomeia esses comandos: dagger module init cria um módulo, e dagger call passa a ser dagger api call. O código TypeScript em si permanece o mesmo.

Como escolher uma alternativa ao GitHub Actions?

A alternativa certa ao GitHub Actions depende de onde você quer que os jobs sejam executados:

  • Se você quer um CI totalmente hospedado, sem nada para operar, use o CircleCI. A configuração dele é bem parecida com a que você já tem.
  • Se você quer orquestração hospedada em máquinas próprias ou hospedadas pelo fornecedor, use o Buildkite, principalmente se precisar de builds para macOS.
  • Se auto-hospedar é obrigatório e você tem pessoas para fazer a manutenção, use o Jenkins.
  • Se auto-hospedar é obrigatório e você quer algo enxuto, use o Woodpecker CI.
  • Se o problema real é o “funciona localmente, falha no CI”, adicione o Dagger e mantenha qualquer uma das ferramentas acima, ou o próprio GitHub Actions, como executor.
  • Se o único problema é o tempo de fila, experimente primeiro os runners auto-hospedados do GitHub Actions.

O backend Docker do Woodpecker e o Dagger precisam de um runtime de contêineres. Se o Docker Desktop não for adequado para suas máquinas, o Dagger também roda em Podman e nerdctl, e o Woodpecker pode rodar no Kubernetes ou diretamente no host com seu backend local.

Seja qual for a ferramenta escolhida, comece movendo toda a lógica de build para scripts npm. Depois, teste a substituta em um único branch, rodando em paralelo com o GitHub Actions, e compare os resultados por uma semana antes de fazer a migração.

Perguntas frequentes

O GitHub cobra por minuto pelos runners auto-hospedados no GitHub Actions?

Não. O GitHub não cobra tarifas por minuto pelo uso de runners auto-hospedados, então o custo são as máquinas em que você os executa. Em dezembro de 2025, o GitHub anunciou uma taxa de plataforma de 0,002 dólar americano por minuto para runners auto-hospedados a partir de 1º de março de 2026, mas depois adiou a cobrança para reavaliar sua abordagem. Consulte a documentação de cobrança do GitHub Actions antes de montar uma comparação de custos com base em qualquer um desses valores.

Posso executar um job do CircleCI localmente antes de fazer o push?

Sim, um job por vez. A CLI do CircleCI executa um único job dentro do Docker na sua máquina com circleci local execute. Workflows não rodam localmente, e o executor machine não é suportado. Para uma configuração na versão 2.1, primeiro exporte a configuração processada com circleci config process e, em seguida, passe esse arquivo para o circleci local execute usando a flag -c e o nome do job.

O Woodpecker CI funciona com repositórios hospedados no GitHub?

Sim. O Woodpecker suporta o GitHub, inclusive o GitHub Enterprise, além de GitLab, Gitea, Forgejo e Bitbucket Cloud. Você registra uma aplicação OAuth na forja e passa o client ID e o secret dela para o servidor do Woodpecker por meio de variáveis de ambiente como WOODPECKER_GITHUB_CLIENT e WOODPECKER_GITHUB_SECRET. Os repositórios continuam no GitHub, o Woodpecker reporta o status do pipeline de volta para ele, e apenas o servidor e os agentes rodam na sua infraestrutura.

Como executo uma função do Dagger a partir de um workflow existente do GitHub Actions?

Adicione um step que use a action oficial dagger/dagger-for-github após o actions/checkout. A action instala a CLI do Dagger, inicia uma Dagger Engine no runner e chama sua função. Defina verb como call e passe os mesmos argumentos que você usa localmente, como check com o diretório do código-fonte e a versão do Node. A lógica do pipeline permanece no módulo, então, se você deixar o GitHub Actions no futuro, só precisará alterar esse wrapper simples.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.