Deploy automático com GitHub Actions

Com o GitHub Actions, um arquivo YAML em .github/workflows roda a cada push e faz o deploy por você. Você guarda as credenciais em secrets e escolhe quais branches disparam o fluxo.

Atualizado em 7 min de leitura

Objetivos de aprendizado

Depois de ler este artigo, você vai conseguir:

  • Criar um workflow que faz deploy a cada push na branch principal
  • Guardar tokens e chaves de API em secrets sem expô-los no código
  • Rodar testes antes do deploy e verificar se ele funcionou
Nesta página

Fazer deploy à mão funciona nas primeiras vezes: você compacta a pasta, envia, reinicia. Com o tempo, o passo manual vira o ponto onde alguém esquece de rodar os testes, sobe a pasta errada ou deixa o servidor numa versão antiga.

O GitHub Actions resolve isso levando o deploy para dentro do repositório. Um arquivo de texto descreve o que acontece a cada push, e o GitHub executa os passos numa máquina temporária. Se o conceito de deploy ainda é novo para você, comece por o que é deploy.

DEPLOY_TOKENpushbranchmaintestjob detestesdeployneeds: testServidornova versãono arTestes falhamo job de deploy é pulado
O push na main roda os testes; só se eles passam o job de deploy usa o secret e coloca a nova versão no ar.

Como funciona o deploy automático com GitHub Actions?#

Um workflow é um arquivo YAML guardado em .github/workflows/ no repositório. Ele declara:

  • Gatilhos (on): o que dispara a execução, como um push, a publicação de uma release ou um clique manual.
  • Jobs: blocos de trabalho. Cada job roda numa máquina virtual própria, chamada de runner.
  • Steps: os passos de cada job. Um passo executa um comando (run) ou usa uma ação pronta (uses).

No deploy automático, o gatilho é o push na branch principal e o último job envia o código para o servidor. Tudo que o job precisa (token, chave de API) vem de secrets, nunca do código.

O que você precisa antes de começar?#

  • Um repositório no GitHub com o projeto.
  • Uma aplicação já criada no seu servidor ou plataforma de hospedagem, para ter para onde enviar.
  • Uma credencial que permita enviar código a esse destino (chave de API, token ou chave SSH).
  • Um script ou comando que faça o deploy a partir do terminal. Se você consegue fazer o deploy rodando um comando na sua máquina, consegue automatizá-lo.

Teste o comando de deploy localmente antes de colocá-lo no workflow. Depurar o YAML e o deploy ao mesmo tempo é bem mais lento.

Como criar o primeiro workflow, passo a passo?#

1. Crie o arquivo. No repositório, crie .github/workflows/deploy.yml. O nome do arquivo é livre, mas a pasta não.

2. Cadastre a credencial como secret. No GitHub, abra Settings > Secrets and variables > Actions, aba Secrets, e clique em New repository secret. Dê um nome, como DEPLOY_TOKEN, e cole o valor. Pela linha de comando, gh secret set DEPLOY_TOKEN pede o valor e o salva.

3. Escreva o workflow. Este exemplo roda os testes de um projeto Node.js e só então faz o deploy:

yaml
name: Deploy

on:
  push:
    branches: [main]
  workflow_dispatch:

concurrency:
  group: deploy-${{ github.ref }}
  cancel-in-progress: false

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: lts/*
      - run: npm ci
      - run: npm test

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - name: Enviar para o servidor
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
        run: ./scripts/deploy.sh

4. Faça commit e push na main. O workflow aparece na aba Actions do repositório e começa a rodar.

O script scripts/deploy.sh é o comando que você já testou localmente. Troque-o pelo que o seu destino exige; cada plataforma tem o seu caminho: um rsync por SSH, uma CLI própria ou uma ação oficial, como a da seção final.

Como funciona cada parte do arquivo?#

Qual branch dispara o deploy?#

branches: [main] limita o gatilho de push à main. Push em outras branches não dispara o deploy. Você pode listar mais de uma branch ou usar padrões como release/**. Não dá para combinar branches e branches-ignore no mesmo evento.

Por que usar workflow_dispatch?#

Ele adiciona o botão Run workflow na aba Actions. É útil para refazer um deploy sem criar um commit novo, por exemplo depois de corrigir uma variável de ambiente. O gatilho só funciona quando o arquivo existe na branch padrão do repositório.

Para que serve o concurrency?#

Sem ele, dois pushes seguidos podem iniciar dois deploys ao mesmo tempo, e o que terminar por último ganha, mesmo sendo o mais antigo. Com group, só uma execução do grupo roda por vez e, por padrão, se várias esperarem, só a mais recente fica pendente. Mantenha cancel-in-progress: false em deploys: cancelar um envio no meio pode deixar a aplicação num estado incompleto.

O que o needs faz?#

needs: test faz o job de deploy esperar o job de testes e só rodar se ele passar. É a forma mais simples de garantir que código quebrado não vai para produção.

Qual versão de cada ação usar?#

Fixe a versão principal, como actions/checkout@v7. Evite apontar para @main: uma mudança do autor da ação pode alterar o seu deploy sem aviso.

Como guardar tokens e chaves com segurança?#

Regras que evitam a maior parte dos incidentes:

  • Nunca escreva a credencial no YAML nem no código. O arquivo vai para o histórico do Git. Se uma chave chegar lá, considere-a comprometida e veja o que fazer se vazar uma chave de API no GitHub.
  • Use ${{ secrets.NOME }}. O GitHub oculta o valor nos logs e substitui por asteriscos.
  • Valores que não são segredo (como o ID de uma aplicação) podem ir em Variables, na mesma tela, e entram como ${{ vars.NOME }}.
  • Secrets não chegam a workflows disparados por forks. O GitHub não os passa ao runner, o que protege contra pull requests maliciosos.
  • Dê o mínimo de permissão. Adicione permissions: contents: read ao workflow quando ele não precisar escrever no repositório.

Para a configuração da aplicação em si (banco, tokens do bot), siga a mesma lógica das variáveis de ambiente: o valor fica no ambiente, não no repositório.

Como saber se o deploy funcionou?#

  1. Abra a aba Actions e entre na execução. Cada step tem seu log. Um check verde em todos os jobs significa que o comando terminou sem erro.
  2. Confirme no destino: a aplicação reiniciou? A mudança aparece? Um check verde só diz que o comando saiu com código 0, não que a aplicação subiu.
  3. Leia os logs da aplicação logo depois do deploy (veja como ler logs de aplicação). Erro de variável faltando ou dependência não instalada aparece ali.

Quais erros são mais comuns?#

  • Secret vazio. Um nome digitado errado em secrets.NOME não gera erro: a expressão devolve uma string vazia, e o comando falha depois com um erro de autenticação. Confira o nome no cadastro do secret.
  • Esquecer o checkout. O runner começa vazio. Sem actions/checkout, não há arquivos para enviar.
  • Arquivo na pasta errada. O workflow precisa estar em .github/workflows/ na raiz, com extensão .yml ou .yaml.
  • Indentação do YAML. Dois espaços por nível, sem tabs. Um espaço errado muda o significado ou invalida o arquivo.
  • Workflow não dispara. Verifique se o push foi na branch listada em branches e se o arquivo está na branch que você enviou.
  • Comando que pede confirmação. O runner não tem terminal interativo. Comandos que perguntam "tem certeza?" travam ou saem com erro, então use a opção de confirmação automática do comando.
  • Deploy de fork não roda. Sem secrets, o job de deploy falha em pull requests de forks. Faça o deploy só em push, não em pull_request.

Como fazer isso na Square Cloud#

Se o destino for a Square Cloud, a GitHub Action oficial substitui o scripts/deploy.sh: ela executa um comando da CLI a cada push, release ou execução manual. Mantenha o job de testes e troque só o job de deploy:

yaml
  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: squarecloudofc/github-action@v2
        with:
          token: ${{ secrets.SQUARECLOUD_API_KEY }}
          command: commit ${{ vars.APP_ID }} --restart

A entrada token recebe a API key da sua conta, guardada em Secrets como neste guia, e o ID da aplicação pode ficar em Variables, porque não é segredo. O commit envia os arquivos da pasta de trabalho (a entrada opcional workdir muda qual) e sobrescreve só os que vão no envio; o resto do disco da aplicação continua lá. O --restart reinicia a aplicação para a nova versão entrar no ar. A plataforma não tem etapa de build: se o projeto compila, rode o build num step antes do commit.

Depois do push, confira os logs da aplicação no painel, como na seção sobre verificar o deploy. O arquivo squarecloud.app é opcional: o painel o gera no deploy, ou você o escreve na raiz do projeto. Veja as entradas da ação em GitHub Action e os comandos da CLI.

Deploy

Envie pelo GitHub, pela CLI ou em ZIP e publique em segundos

Saiba mais

Perguntas frequentes

O GitHub Actions é gratuito?

Depende do plano e do tipo de repositório. O GitHub inclui uma cota de minutos e cobra o excedente em alguns casos, então confira a página de cobrança do GitHub Actions para o seu caso.

Posso usar secrets em pull requests de forks?

Não. O GitHub não passa secrets ao runner quando o workflow é disparado por um repositório fork. Isso impede que um pull request de terceiros leia suas credenciais.

Como disparar o deploy manualmente?

Adicione o gatilho workflow_dispatch ao bloco on. O GitHub passa a mostrar o botão Run workflow na aba Actions, e o gatilho só funciona se o arquivo estiver na branch padrão.

O deploy roda se os testes falharem?

Não, se o job de deploy declarar needs apontando para o job de testes. Quando um job do qual outro depende falha, o job dependente é pulado.

Próximo artigoQuanto custa hospedar uma aplicação Node.jsHospedar Node.js custa de zero, com limites, a poucas dezenas de reais por mês. Veja o que define o preço, quanta RAM o app usa e como cada opção cobra.