Como criar um pipeline de entrega móvel sem servidor

Neste tutorial, descrevemos como criar um pipeline de entrega móvel sem servidor no Google Cloud:

  • Você receberá orientação sobre como configurar um aplicativo de teste para Android, criá-lo e distribuí-lo usando comandos do Gradle na máquina local. Esses comandos criam o pacote de aplicativos para Android (APK, na sigla em inglês) e fazem o upload para o Firebase App Distribution para distribuição aos testadores Beta.
  • Em seguida, para automatizar esse processo, instale o Android Builder (em inglês) para o Cloud Builde configure umgatilho de compilação para acionar automaticamente o build e a distribuição do Aplicativo Android com alterações no código-fonte.

Objetivos

  • Criar uma tarefa de build que crie um APK assinado.
  • Criar uma tarefa de build que use o Firebase App Distribution para distribuir novos builds.
  • Instalar o Android Builder com as dependências necessárias do SDK do Android.
  • Criar um gatilho de compilação no Google Cloud que use o Android Builder para criar o APK assinado e distribuí-lo usando o Firebase App Distribution.

Custos

Neste tutorial, há componentes faturáveis do Google Cloud, a saber:

A imagem base do Android Builder tem cerca de 1,9 GB. A calculadora de preços estima o custo de armazenamento de 2 GB de ambiente em cerca de US$ 0,05 por mês. A criação da imagem base do Android Builder leva aproximadamente 11 minutos, e custa US$ 0,03. Cada build adicional precisa levar cerca de 5 minutos e custa US$ 0,02. Consulte Preços do Cloud Build para mais informações.

Antes de começar

  1. Faça login na sua conta do Google.

    Se você ainda não tiver uma, inscreva-se.

  2. No Console do Cloud, na página do seletor de projetos, selecione ou crie um projeto do Cloud.

    Acessar a página do seletor de projetos

  3. Verifique se a cobrança está ativada para o seu projeto do Google Cloud. Saiba como confirmar se a cobrança está ativada para o seu projeto.

  4. Ative a API Compute Engine.

    Ative a API

  5. Instale e inicialize o SDK do Cloud..
  6. Verifique se o Gradle está instalado no computador.
  7. Verifique se o Android Studio está instalado no computador.
  8. Verifique se o Git está instalado no computador.

Neste tutorial, pressupomos que você:

  • esteja executando o macOS ou o Linux. Alguns procedimentos estão adaptados a um ambiente Windows, mas o tutorial não fornece instruções completas para esse caso de uso;
  • tenha alguma familiaridade com o desenvolvimento do Android, o Android Studio, o Gradle e o Git.

Conseguir que o build beta assinado do Android esteja em execução no local

Nesta seção, você fará a configuração de um aplicativo para Android de teste no Android Studio. O aplicativo é criado e distribuído usando as tarefas de criação do Gradle, executadas na janela do terminal do computador.

Desenvolver um aplicativo de teste para Android para o build

  1. No Android Studio, crie um novo projeto Android que use uma atividade vazia.

    Nas capturas de tela abaixo, veja as etapas no assistente para executar essa tarefa.

    Assistente do Android Studio, página 1

    Assistente do Android Studio, página 2

    Assistente do Android Studio, página 3

    Assistente do Android Studio, página 4

  2. Na janela do terminal do computador, mude para o diretório em que você criou o aplicativo de teste:

    cd ${HOME}/android-apps/TestAndroidBuild
  3. Nesse diretório, inicialize um repositório Git:

    git init && git checkout -b develop
  4. Edite o arquivo .gitignore e adicione os nomes dos arquivos e das extensões que o Git não enviará ao seu repositório de código-fonte:

    cat >> .gitignore <<EOF
    google-services.json
    app-distro.json
    keystore.properties
    EOF
  5. Confirme o aplicativo no repositório:

    git add -A
    git commit -m "empty application"
  6. Configure a ferramenta de linha de comando gcloud para usar seu projeto. Para o [PROJECT_NAME], use o nome do projeto selecionado ou criado.

    PROJECT=[PROJECT_NAME]
    gcloud config configurations create $PROJECT
    gcloud config config set project $PROJECT
  7. Crie um repositório de origem da nuvem para o aplicativo para Android:

    gcloud source repos create android-application
  8. Adicione o repositório de origem da nuvem como repositório remoto do aplicativo para Android:

    git remote add google \
        https://source.developers.google.com/p/${PROJECT}/r/android-application

Adicionar o Firebase ao seu aplicativo

  1. Acesse o Console do Firebase:

    Acessar o Console do Firebase

  2. Clique em Adicionar projeto.

  3. Em Insira o nome do projeto, selecione o projeto do Google Cloud criado anteriormente:

    Menu de projetos do Firebase Cloud

  4. Confirme o plano de faturamento do Firebase Blaze.

  5. Selecione se você quer ativar o Google Analytics. Neste tutorial, não é necessário usar o Analytics.

  6. Aguarde a criação do projeto do Firebase e clique em Continuar.

  7. Siga as instruções em Adicionar o Firebase ao seu projeto Android para adicionar o Firebase ao seu aplicativo Android.

  8. Verifique se o arquivo google-services.json foi movido para o seguinte diretório:

    {HOME}/android-apps/TestAndroidBuild

  9. Siga as instruções em Primeiros passos com o Firebase Crashlytics para adicionar o Firebase Crashlytics ao seu projeto Android.

  10. Altere os diretórios para o diretório no nível do aplicativo do seu projeto:

    cd {HOME}/android-apps/TestAndroidBuild/app

  11. Crie uma conta de serviço do Google Cloud com o papel de administrador do Firebase:

    gcloud iam service-accounts create app-distro --display-name=app-distro
    APP_DISTRO_SA=$(gcloud iam service-accounts list --filter="displayName:app-distro" --format='value(email)')
    gcloud projects add-iam-policy-binding $PROJECT --role roles/firebase.admin --member serviceAccount:$APP_DISTRO_SA
    gcloud iam service-accounts keys create app-distro.json $APP_DISTRO_SA
    

Criar a chave de assinatura e keystore

Para distribuir o aplicativo Android de pré-lançamento, assine o aplicativo usando um certificado armazenado em um arquivo Java keystore (.jks).

  1. Na janela de terminal, altere para o diretório pai do aplicativo:

    cd ${HOME}/AndroidStudioProjects/TestAndroidBuild
  2. Crie o keystore e a chave Java para assinar o aplicativo, bem como o arquivo keystore.properties que armazena o alias de chave, a senha e o caminho relativo para o arquivo keystore:

    JKS_PASSWORD=$(openssl rand -base64 12)
    keytool -genkey -noprompt -keystore ../signing/android.jks \
      -alias android-key \
      -dname "CN=example.com, OU=IT, O=Example, L=Sunnyvale, S=California, C=US" \
      -storepass ${JKS_PASSWORD} \
      -keypass ${JKS_PASSWORD}
    
    cat > ../signing/keystore.properties <<EOF
    storeFile=../signing/android.jks
    storePassword=${JKS_PASSWORD}
    keyPassword=${JKS_PASSWORD}
    keyAlias=android-key
    EOF

Criptografe os arquivos secretos do Android e adicione-os ao seu repositório de origem.

  1. Ative o serviço de gerenciamento de chaves:

    gcloud services enable cloudkms.googleapis.com
    
  2. Crie um keyring para armazenar suas chaves:

    gcloud kms keyrings create my-app --location=global
    
  3. Crie uma chave para armazenar seus secrets:

    gcloud kms keys create android-builder \
        --location=global \
        --keyring=my-app \
        --purpose=encryption
    
  4. Adicione o papel de criptografia/descriptografia à conta de serviço do Cloud Build:

    CLOUDBUILD_ACCOUNT=$(gcloud projects get-iam-policy $PROJECT \
        --filter="(bindings.role:roles/cloudbuild.builds.builder)" \
        --flatten="bindings[].members" \
        --format="value(bindings.members[])" | tail -1)
    
    gcloud kms keys add-iam-policy-binding android-builder --location=global \
        --keyring=my-app --member="${CLOUDBUILD_ACCOUNT} \
        --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
    
  5. Criptografe o arquivo keystore.properties:

    gcloud kms encrypt --plaintext-file=signing/keystore.properties \
        --ciphertext-file=signing/keystore.properties.enc --location=global \
        --keyring=my-app --key=android-builder
    
  6. Adicione os arquivos de assinatura ao seu repositório de origem:

    git add signing
    git commit -m "encrypted signing information"
    
  7. Criptografe o arquivo google-services.json:

    gcloud kms encrypt --plaintext-file=app/google-services.json \
        --ciphertext-file=app/google-services.json.enc --location=global \
        --keyring=my-app --key=android-builder
    
  8. Adicione o arquivo google-services.json.enc ao seu repositório de origem:

    git add app/google-services.json.enc
    git commit -m "encrypted application account"
    
  9. Criptografe o arquivo app-distro.json:

    gcloud kms encrypt --plaintext-file=app-distro.json \
        --ciphertext-file=app-distro.json.enc \
        --location=global \
        --keyring=my-app --key=android-builder
    
  10. Adicione o arquivo app-distro.json.enc ao seu repositório de origem:

    git add app-distro.json.enc
    git commit -m "encrypted service account"
    

Adicionar o Firebase App Distribution

Criar um grupo de distribuição do Firebase

  1. Acesse o Console do Firebase:

    Acessar o Console do Firebase

  2. Clique no aplicativo que você criou para o Firebase. O nome é semelhante ao do projeto do Cloud.

  3. Clique em Distribuição de aplicativos.

  4. Clique em Testadores.

  5. Clique em Adicionar testadores.

  6. Digite seu endereço de e-mail.

  7. Clique em Criar um grupo de testadores.

  8. Insira o nome beta-testers.

  9. Clique em Adicionar testadores.

  10. Adicione seu endereço de e-mail ao grupo beta-testers.

Atualizar o arquivo build.gradle para incluir as configurações de assinatura e de distribuição do Firebase

  1. Atualize o arquivo {HOME}/AndroidStudioProjects/TestAndroidBuild/build.gradle com linhas em negrito abaixo:

    buildscript {
        ext.kotlin_version = '1.3.41'
        repositories {
            google()
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.5.0'
            classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version'
            classpath 'com.google.firebase:firebase-appdistribution-gradle:2.0.0'
            classpath 'com.google.gms:google-services:4.3.1'
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
     }
    
  2. Adicione os seguintes snippets ao arquivo {HOME}/AndroidStudioProjects/TestAndroidBuild/app/build.gradle:

    android {
    // ...
    def debugKeystorePropertiesFile = rootProject.file("signing/keystore.properties")
    def keystoreProperties = new Properties()
    keystoreProperties.load(new FileInputStream(debugKeystorePropertiesFile))
    //...
    android {
      //...
        signingConfigs {
           debug {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile file(keystoreProperties['storeFile'].trim())
            storePassword keystoreProperties['storePassword']
          }
         }
          buildTypes {
            debug {
              firebaseAppDistribution {
                releaseNotesFile="release-notes.txt"
                groups="beta-testers"
              }
            }
          // ...
            packagingOptions {
              exclude "app-distro.json"
            }
          }
      }
    

Corrigir a dependência de teste no arquivo Gradle

  1. Verifique se a seguinte linha está em negrito no arquivo ${HOME}/AndroidStudioProjects/TestAndroidBuild/app/build.gradle:

    dependencies {
      //...
      androidTestImplementation 'androidx.test:runner:1.2.0'
      androidTestImplementation 'androidx.test.ext:junit:1.1.1'
      androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
     }
    

Criar e distribuir o aplicativo a partir do seu computador

  1. Na janela de terminal, verifique se você está no diretório pai do aplicativo de teste:

    {HOME}/AndroidStudioProjects/TestAndroidBuild

  2. Crie e distribua o aplicativo:

    gradle assembleDebug appDistributionUploadDebug
    

    Um e-mail é enviado para o grupo de distribuição com um link que permite ao usuário instalar o aplicativo.

Salvar as alterações do build no seu repositório de origem

  • Confirme as alterações no repositório de origem:

    git add app/build.gradle && git commit -m "Update build for distribution."
    

Criar seu build do Android no Cloud Build

A essa altura, você já tem tarefas de criação do Gradle em funcionamento. Elas são usadas para criar e distribuir seu aplicativo para Android. Nesta seção, você configura o Cloud Build para executar essas tarefas de build sempre que houver uma alteração na ramificação mestre do Cloud Source Repository.

  1. Defina a variável de ambiente PROJECT:

    export PROJECT=$(gcloud config get-value project)
    
  2. Crie o bucket de armazenamento a ser usado pelo Android Builder para salvar as dependências entre criações:

    gsutil mb gs://$PROJECT-cache-bucket
    
  3. Crie o bucket de armazenamento que o Android Builder usará para incrementar o número do Android Build:

    gsutil mb gs://$PROJECT-config-bucket
    
  4. Crie o bucket de armazenamento que o Android Builder usará para armazenar artefatos:

    gsutil mb gs://$PROJECT-artifact-bucket
    

Criar o Android Builder

  1. Em uma janela de terminal, clone o repositório de builders da comunidade para um diretório fora do diretório do aplicativo Android:

    git clone https://github.com/GoogleCloudPlatform/cloud-builders-community
    

    O repositório do GitHub contém os builders mantidos pela comunidade.

  2. Altere para o diretório que contém o builder tar:

    cd cloud-builders-community/tar
    
  3. Adicione o builder tar ao seu projeto:

    gcloud builds submit --config=cloudbuild.yaml
    
  4. Altere para o diretório em que está o Android Builder:

    cd ../android
    
  5. Crie o Android Builder, passando o build do SDK de destino como uma substituição:

    gcloud builds submit --config=cloudbuild.yaml \
        --substitutions=_ANDROID_VERSION=28 

Criar o gatilho de compilação do aplicativo para Android

Nesta seção, mostramos como criar o gatilho de compilação do aplicativo que usa o Android Builder da seção anterior para criar e distribuir o aplicativo para Android.

  1. Na janela do terminal, copie o arquivo cloudbuild.yaml de exemplo do diretório examples/ do Android Builder para o diretório do aplicativo Android de teste:

    cd ${HOME}/android-apps/TestAndroidBuild
    cp ${HOME}/cloud-builders-community/android/examples/build-test-deploy-firebase-distro.yaml \ ./cloudbuild.yaml
    
  2. Adicione o novo arquivo cloudbuild.yaml à ramificação develop do repositório de origem:

    git add cloudbuild.yaml && git commit -m "Add android builder to project."
    
  3. No Console do Cloud, acesse a página Gatilhos de compilação.

    Acessar a página "Gatilhos de compilação"

  4. Clique em Criar gatilho.

  5. Selecione o repositório android-application.

  6. Em Nome, insira android-application-build.

  7. Em Configuração do Build, selecione cloudbuild.yaml.

  8. Em cloudbuild.yaml location, insira /cloudbuild.yaml.

  9. Clique em Adicionar item. Isso permite configurar variáveis para o build.

  10. Para cada variável da tabela abaixo, digite o nome da variável (incluindo o sublinhado inicial) e o valor do seu projeto.

    Variável Valor Finalidade
    _CONFIG_BUCKET
    O bucket usado para armazenar o número do build.
    gs://[PROJECT_NAME]-config-bucket O URL do bucket que será usado para armazenar o número do build.
    _CACHE_BUCKET
    O bucket a ser usado para armazenar dependências de criação em cache.
    gs://[PROJECT_NAME]-cache-bucket Evita que o Gradle faça o download das mesmas dependências da internet em cada build.
    _ARTIFACT_BUCKET
    O bucket do Cloud Storage usado para armazenar artefatos de build.
    gs://[PROJECT_NAME]-artifact-bucket O Android Builder armazena artefatos intermediários e outros aqui durante o build.
  11. Clique em Criar gatilho.

Executar o gatilho de compilação do aplicativo

Agora é possível testar o funcionamento do gatilho de compilação do aplicativo e confirmar que o aplicativo foi distribuído para seu e-mail.

  1. Em uma janela do terminal, altere os diretórios para o diretório de nível superior do projeto de teste do aplicativo para Android:

    cd ${HOME}/android-apps/TestAndroidBuild
  2. Para acionar o build, envie à ramificação mestre do repositório do código-fonte:

    git push google develop
  3. No Console do Cloud, acesse a página do Cloud Build.

  4. Clique no último build em andamento para ver a saída dele para o build do aplicativo.

Como fazer a limpeza

Após concluir este tutorial, limpe os recursos que você criou no Google Cloud para não ser cobrado por eles no futuro. As próximas seções descrevem como excluir ou desativar esses recursos.

Excluir o projeto

O jeito mais fácil de evitar cobranças é excluir o projeto que você criou para o tutorial.

Para excluir o projeto:

  1. No Console do Cloud, acesse a página Gerenciar recursos:

    Acessar a página "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

Excluir registros de imagens

Exclua os registros de imagem da imagem do SDK do Android e do aplicativo para Android.

  1. No menu de navegação à esquerda do Console do Cloud, role até a seção Ferramentas e clique em Container Registry > Imagens.
  2. Selecione todas as imagens.

    Como selecionar todas as imagens

  3. Clique em Excluir.

Excluir buckets do Cloud Storage

Exclua os buckets do Cloud Storage que contenham as informações de assinatura do Android e as propriedades do Fabric. No Cloud Shell, use esses comandos, substituindo os valores pelos marcadores:

  1. Defina a variável de ambiente PROJECT.

    export PROJECT=$(gcloud config get-value project)
    
  2. Exclua os buckets de armazenamento criados para o build.

    gsutil rm gs://$PROJECT-cache-bucket
    gsutil rm gs://$PROJECT-config-bucket
    gsutil rm gs://$PROJECT-artifact-bucket
    

Excluir os gatilhos de compilação

  1. Exclua o gatilho de compilação de base do SDK do Android.
  2. Exclua o gatilho de compilação do Android.

Excluir o aplicativo do Firebase

  1. Navegue até o Console do Firebase.

  2. Selecione o projeto do Firebase que você criou para o tutorial. Ele precisa ter um nome semelhante a [PROJECT_NAME].

  3. No menu de configurações, selecione Configurações do projeto. Configurações do projeto do Firebase

  4. Role até a parte inferior da página e clique em Excluir projeto.

A seguir