Criando um fluxo de CI/CD completo para apps Flutter com GitHub Actions e Firebase App Distribution
A cada semana surgem novas ferramentas, mas a dor de distribuir versões de teste continua a mesma: alguém envia um .apk no grupo do WhatsApp, outra pessoa instala a versão errada e, quando o bug é reportado, ninguém sabe exatamente qual commit ele está usando.
A boa notícia é que o Flutter, o GitHub Actions e o Firebase App Distribution formam uma tríade que resolve esse problema de forma gratuita e automatizada. A receita abaixo leva menos de 30 minutos para rodar e, depois de configurada, publica um .apk novo no grupo de teste toda vez que você der git push.
Por que Flutter + GitHub Actions + Firebase?
- Flutter: um único código, builds para Android e iOS.
- GitHub Actions: funciona dentro do seu repositório, não precisa de servidor extra.
- Firebase App Distribution: disponibiliza builds internas para testadores com um link simples — sem Google Play ou TestFlight.
Essa combinação é tão eficaz que muitas empresas deixaram de usar o Fastlane para casos mais simples. A configuração é direta e, mantendo-se no plano Spark (gratuito) do Firebase, não gera custos.
Passo a passo em 5 etapas
1. Preparando o app e o Firebase
- No Firebase Console crie um projeto novo ou selecione um já existente.
- Adicione os aplicativos Android e iOS com os pacotes corretos (
com.suaempresa.nomeapp). - Baixe os arquivos
google-services.json(Android) eGoogleService-Info.plist(iOS) e deixe-os na raiz dos respectivos módulos dentro do projeto Flutter.
Dica de segurança: em vez de commitar os arquivos de configuração, use as secrets do GitHub para armazenar o conteúdo dos arquivos como variáveis de ambiente. Assim você evita expor IDs privados no histórico do git.
2. Gerando uma chave de upload para Android
O Firebase App Distribution aceita .apk ou .aab. Para equipes pequenas, o .apk costuma ser suficiente.
# Dentro do diretório android
keytool -genkey -v -keystore upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
Coloque o arquivo upload-keystore.jks na pasta android/app e crie um arquivo key.properties:
storePassword=SENHA
keyPassword=SENHA
keyAlias=upload
storeFile=upload-keystore.jks
Adicione essas senhas como secrets também (KEYSTORE_PASSWORD, KEY_PASSWORD, KEY_ALIAS).
3. Workflow básico no GitHub Actions
Crie .github/workflows/deploy.yml:
name: Deploy to Firebase App Distribution
on:
push:
branches: [ develop ] # ou outra branch de teste
jobs:
build-android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.19.6' # ou a versão que seu projeto usa
channel: 'stable'
- name: Flutter pub get
run: flutter pub get
- name: Build APK
run: flutter build apk --release
- name: Upload to Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{ secrets.FIREBASE_ANDROID_APP_ID }}
token: ${{ secrets.FIREBASE_TOKEN }}
groups: testers
file: build/app/outputs/flutter-apk/app-release.apk
Como gerar FIREBASE_TOKEN? No terminal:
npm install -g firebase-tools
firebase login:ci
Copie o token e guarde como FIREBASE_TOKEN nas secrets do repositório.
4. Agrupando testadores
No Firebase Console, clique em App Distribution → Testers & Groups → New Group. Crie um grupo chamado testers e adicione os e-mails. Toda vez que o workflow rodar, cada pessoa receberá um e-mail ou notificação no aplicativo Firebase com link direto para instalar.
5. Evoluindo: separando builds de homologação e produção
Após validar o fluxo básico, crie dois workflows:
deploy-dev.yml: dispara em pushes paradevelop, gera.apkcom sufixo-devno nome.deploy-release.yml: dispara ao criar uma tag que comece comv, gera.aabe sobe para a Google Play internamente (usando o mesmo token do Firebase).
Exemplo de condição no YAML:
on:
push:
tags:
- 'v*'
Dessa forma, ninguém manda build de release sem querer.
Dicas para evitar surpresas na semana de lançamento
-
Cache de dependências
Adicione o seguinte no workflow para economizar 3-4 minutos por execução:- name: Cache Flutter uses: actions/cache@v4 with: path: | ~/.pub-cache build/ key: ${{ runner.os }}-flutter-${{ hashFiles('**/pubspec.lock') }} -
Notificações no Slack
Configure um step final para postar no canal avisando que um novo build está disponível.- name: Notify Slack run: | curl -X POST \ -H 'Content-type: application/json' \ --data '{"text":"📦 APK novo enviado para teste: ${{ github.sha }}"}' \ ${{ secrets.SLACK_WEBHOOK }} -
Teste de regressão automática
Antes do upload, executeflutter test integration_testpara garantir que a build não quebrou funcionalidades críticas.
Resultado prático no dia a dia
Depois de implementar esse fluxo, o seu time:
- Nunca mais precisa abrir o Android Studio para gerar APK.
- Sabe exatamente qual commit está em cada build disponibilizada.
- Recebe feedback por meio de crashlytics e performance monitoring automaticamente atrelados ao número da versão.
- Consegue entregar hotfixes em minutos, basta fazer
git cherry-picke dar push.
Mesmo que Google ou Apple lancem novos requisitos de loja amanhã, a infra que você construiu hoje continuará funcional: basta ajustar o step de build ou adicionar mais secrets. Em outras palavras, o ganho é atemporal — e, para quem ainda envia .apk no WhatsApp, representa um salto de qualidade imediato.