Usando Github Actions para publicar seu Flutter APP no Firebase App Distribution

Tempo de leitura: 6 minutes

1. Por que estou escrevendo este artigo?

Há alguns meses comecei a desenvolver um side-project de aplicativo Flutter, que ainda não está disponível, mas pretendo publicá-lo nas lojas de aplicativos quando sentir que está pronto para o lançamento do MVP.
Neste projeto, estou usando o banco de dados Firebase para armazenar os dados do aplicativo, autenticação, armazenamento de arquivos e alguns outros recursos. MAS temos um que é o tema principal deste artigo: Firebase App Distribution.

2. Distribuição de aplicativos do Firebase

O Firebase possui uma funcionalidade própria cujo trabalho é literalmente distribuir seu aplicativo para um usuário (ou um grupo de usuários).
Quando falamos de aplicativos Flutter, também estamos falando sobre o download desses aplicativos em nossos dispositivos móveis (no caso de aplicativos móveis, não vou falar sobre Flutter Web neste artigo). Talvez você ou sua equipe queiram testá-lo ou mostrá-lo para o gerente ou líder da equipe, seja o que for.

Esta é a maneira “legal”, mas difícil de fazer isso. Fazendo o upload do arquivo do seu app para o Firebase App Distribution.

3. A maneira manual

Antes de tudo, é claro, você precisará gerar uma compilação do seu aplicativo Flutter.

flutter build apk

ou

flutter build aab

Ao entrar no console do projeto Firebase, você terá uma lista de atalhos no lado esquerdo e provavelmente verá uma opção chamada ‘App Distribution’. Clique nisso.

Você verá uma grande caixa azul tracejada solicitando que você carregue o APK do aplicativo ou o arquivo AAB.

Em seguida, aparecerá um cartão com um campo de texto para colocar o e-mail do testador ou o nome de um grupo de testadores (que você pode criar clicando na terceira barra de navegação superior).

Então, você só precisa pressionar ‘Próxima’ e ‘Enviar para testadores’.

Bom trabalho! Agora, seu aplicativo está nos dispositivos de todos os testadores que você o enviou.
Mas… Fazer isso TODAS as vezes parece perda de tempo. Não é? Talvez. Talvez não.

 

4. A maneira GitHub Actions

Agora, no tópico principal deste artigo, mostrarei como automatizar esse processo de upload do seu aplicativo para o Firebase App Distribution e enviá-lo aos testadores.
No final deste tópico, você saberá como fazer esse processo apenas fazendo push ou abrindo uma pull request em um branch Git específico do seu projeto.

Em seu projeto, crie um caminho chamado .github/workflows, assim:

Dentro dele, crie um arquivo .yaml com o nome do seu fluxo de trabalho. Eu nomeei o meu como ‘firebase_workflow.yaml’.

Vamos começar dando um nome ao fluxo de trabalho.

name: Firebase APP Workflow

Em seguida, precisaremos determinar quando esse fluxo de trabalho será acionado. Empurrando para um ramo? Criando uma solicitação pull para uma ramificação?

Exemplo de como deve ficar o arquivo yaml até aqui:

name: Firebase APP workflow

on:
  push:
    branches:
      - main

  pull_request:
    branches:
      - main

Precisamos colocar trabalhos em nosso arquivo de fluxo de trabalho. Acima temos um exemplo de configuração que é muito importante para toda a operação do fluxo de trabalho.

Criei uma chave chamada firebase_distribution e dei a ela o nome “Firebase App Distribution”. Em seguida, configurei a máquina virtual na qual ele será executado.

Você pode ler mais sobre isso aqui

jobs:
  firebase_distribution:
    name: Firebase App Distribution
    runs-on: ubuntu-latest ## virtual machine
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-java@v1
        with:
          java-version: "12.x"

Então, temos dois passos iniciais importantes para definir. A primeira é uma ação oficial do GitHub usada para fazer check-out de um repositório para que um fluxo de trabalho possa acessá-lo. O segundo é bem mais complexo, mas, resumidamente, baixa e configura uma versão solicitada do Java.

- name: Decode google-services.json
        env: 
            GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
        run: echo "$GOOGLE_SERVICES_JSON" > android/app/google-services.json

Dentro da chave env colocamos outra chave chamada GOOGLE_SERVICES_JSON. Mas, por enquanto, precisarei explicar o que é esse “secrets.GOOGLE_SERVICES_JSON” aqui.

Para isso, abra o repositório do projeto Github e entre na página de configurações.

Nas opções do lado esquerdo, procure a sessão de segurança e clique em “Secrets” > “Actions”.

Precisamos criar 3 chaves secretas. Cada um para:

  • Firebase App ID
  • Firebase Token
  • Google Services Json

Nomeie-os de acordo com sua preferência.

O Firebase App ID pode ser encontrado seguindo estas etapas curtas de clique no console do projeto Firebase:

Só precisamos copiá-lo e colá-lo em nossa chave secreta.

O token Firebase pode ser obtido executando alguns comandos em sua máquina.

Inicialmente, precisaremos instalar o npm e executar o seguinte comando:

npm install -g firebase-tools

Em seguida, execute este segundo comando:

firebase login:ci

Depois disso, o token será mostrado pela sua CLI.

Para a última chave, basta abrir o google-services.json em nosso projeto no caminho “android/app/google-services.json”, copiar todo o conteúdo dentro e colar na respectiva chave secreta em seu projeto Github repositório.

Agora, podemos voltar ao nosso fluxo de trabalho e entender o que acontecerá a partir de agora:

- name: Decode google-services.json
  env: 
      GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
  run: echo "$GOOGLE_SERVICES_JSON" > android/app/google-services.json

Basicamente, usar secrets.KEY_NAME nos permite acessar as chaves secretas do nosso projeto.

Estamos acessando a chave secreta chamada GOOGLE_SERVICES_JSON e executando um comando nela.

Agora, podemos continuar escrevendo nosso fluxo de trabalho:

- uses: subosito/flutter-action@v1
       with:
         channel: "stable"

subosito/flutter-actions@v1 é apenas um ambiente Flutter em execução em nosso fluxo de trabalho. Então, agora que temos ‘acesso’ ao ambiente Flutter, podemos escolher um canal Flutter para usar. Leia sobre esta ação aqui.

A partir de agora, executaremos comandos do Flutter dentro do nosso fluxo de trabalho:

- run: flutter pub get
     - run: flutter build apk
     - uses: actions/upload-artifact@v1
       with:
         name: release-apk
         path: build/app/outputs/apk/release/app-release.apk

Observe que comandos já conhecidos como flutter pub get e flutter build apk agora aparecem em nosso fluxo de trabalho. Porém, para fazer upload do arquivo app gerado (artefato), precisaremos usar a ação upload-artifact@v1 e analisar o caminho de construção que armazenará o arquivo app.

Para finalizar (eu juro), completamos nosso fluxo de trabalho com uma ação do Firebase que terá a responsabilidade de fazer o upload do aplicativo para o Firebase App Distribution. Leia sobre wzieba/Firebase-Distribution-Github-Action. Esta ação carrega seus artefatos com extensões .apk, .aab e .ipa (este último para iOS) para Firebase App Distribution.

- name: upload artifact to Firebase App Distribution
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
            appId: ${{secrets.FIREBASE_APP_ID}}
            token: ${{secrets.FIREBASE_TOKEN}}
            groups: testers
            file: build/app/outputs/flutter-apk/app.apk

Precisamos analisar as chaves secretas de novo significado, o nome do grupo de testadores (que você criou no console do projeto Firebase) e o caminho do arquivo. No Flutter, por padrão, ele é armazenado em build/app/outputs/apk/release/app-release.apk.

É isso! Nosso arquivo de processo de fluxo de trabalho está pronto!

 

5. Resultado final do arquivo yaml do fluxo de trabalho

É assim que seu arquivo de fluxo de trabalho deve ficar:

name: Firebase APP workflow

on:
  push:
    branches:
      - main

  pull_request:
    branches:
      - main

jobs:
  firebase_app:
    name: Run Firebase Workflow
    runs-on: ubuntu-latest ## virtual machine
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-java@v1
        with:
          java-version: "12.x"

      - name: Decode google-services.json
        env: 
            GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
        run: echo "$GOOGLE_SERVICES_JSON" > android/app/google-services.json

      - uses: subosito/flutter-action@v1
        with:
          channel: "stable"
      - run: flutter pub get
      - run: flutter build apk
      - uses: actions/upload-artifact@v1
        with:
          name: release-apk
          path: build/app/outputs/apk/release/app-release.apk
      - name: Upload to Firebase App Distribution
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
            appId: ${{secrets.FIREBASE_APP_ID}}
            token: ${{secrets.FIREBASE_TOKEN}}
            groups: testers
            file: build/app/outputs/flutter-apk/app.apk

 

6. Testando!

Agora, só precisamos enviar nosso projeto para a ramificação do projeto do github que escolhemos ou mesclar a solicitação pull (depende do que você escolheu fazer) para acionar o fluxo de trabalho.

Depois disso, você pode ver o processo funcionando clicando na guia “Ações” no repositório do seu projeto.

É assim que seu alerta de fluxo de trabalho deve se parecer:

 

É isso!

MUITO obrigado por ler até aqui! Espero que este artigo possa ajudá-lo a criar fluxos de trabalho de ações do github para carregar seu aplicativo no Firebase APP Distribution.