Skip to content

Instantly share code, notes, and snippets.

@enzo-santos
Last active April 28, 2024 03:44
Show Gist options
  • Save enzo-santos/7f3b957ff50ea7c17be4c1335836da0e to your computer and use it in GitHub Desktop.
Save enzo-santos/7f3b957ff50ea7c17be4c1335836da0e to your computer and use it in GitHub Desktop.
Play Store + GitLab CI tutorial

Play Store + GitLab CI tutorial

This tutorial will teach you how to deploy a Flutter-based app to Play Store using GitLab CI.

Glossary

If you encounter a variable you don't recognize while reading, take a look here.

Variable name Description
... Sensitive value.
GIST_PACKAGE_NAME The Android package name, such as com.example.demo.

Tutorial

Requirements

  • An app bundle must have been sent at least once via Google Play Console. This assumes that you have a Google Play developer account and an Android signing key.
  • A service account associated with your developer account, as described here.

Local setup

This setup assumes that the current working directory is the root of your Flutter project.

  • Create a file inside android named Gemfile, with contents
source "https://rubygems.org"

gem "fastlane"
  • Create a file inside android/fastlane named Fastfile, with contents
default_platform(:android)

platform :android do
  desc "Deploy a new version to the Google Play"
  lane :deploy do
    upload_to_play_store(
      package_name: GIST_PACKAGE_NAME,
      release_status: 'draft',
      track: 'internal',
      json_key: './play-console-key.json',
      aab: '../build/app/outputs/bundle/release/app-release.aab',
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
    )
  end
end

You can customize the release status, the release track and add or modify any parameters described by upload_to_play_store. You can also rename the play-console-key.json file used in json_key, we'll define it later.

  • Open the file android/app/build.gradle and modify the following contents:
android {
    // ...
    signingConfigs {
        release {
            storeFile file("android_signing_store_file.jks")
            storePassword System.getenv("ANDROID_SIGNING_STORE_PASSWORD")
            keyAlias System.getenv("ANDROID_SIGNING_KEY_ALIAS")
            keyPassword System.getenv("ANDROID_SIGNING_KEY_PASSWORD")
       }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
    // ...
}

You can rename the android_signing_store_file.jks file used in storeFile, we'll define it later.

  • Create a file inside the root directory named .gitlab-ci.yml, with contents
variables:
  # If you renamed any of the paths previously, you need to rename them again here
  ANDROID_SIGNING_STORE_FILE_FILENAME: android_signing_store_file.jks
  PLAYSTORE_SERVICE_ACCOUNT_FILENAME: play-console-key.json

stages:
  - build
  - deploy

before_script:
  - git config --global url."https://github.com/".insteadOf "[email protected]:"
  - git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/".insteadOf "[email protected]:"

build-job:
  image: cirrusci/flutter:2.10.5
  stage: build
  before_script:
    - echo $ANDROID_SIGNING_STORE_FILE_BASE64 | base64 --decode > android/app/$ANDROID_SIGNING_STORE_FILE_FILENAME
  script:
    - flutter doctor
    - flutter pub get
    - flutter build appbundle
  after_script:
    - rm android/app/$ANDROID_SIGNING_STORE_FILE_FILENAME
  artifacts:
    paths:
      - build/app/outputs/bundle/release/app-release.aab
    expire_in: 1 hour

deploy-job:
  image: fastlanetools/fastlane:latest
  stage: deploy
  before_script:
    - echo $PLAYSTORE_SERVICE_ACCOUNT_DATA > android/$PLAYSTORE_SERVICE_ACCOUNT_FILENAME
    - cd android
  script:
    - bundle install
    - bundle exec fastlane deploy
  after_script:
    - cd ..
    - rm android/$PLAYSTORE_SERVICE_ACCOUNT_FILENAME

CI setup

You need to add five secret variables:

  • ANDROID_SIGNING_KEY_ALIAS, ANDROID_SIGNING_KEY_PASSWORD, ANDROID_SIGNING_STORE_PASSWORD: their respective values you defined in the signing step, as plain text
  • ANDROID_SIGNING_STORE_FILE_BASE64: the contents of the store file generated for your Android signing, as base64
  • PLAYSTORE_SERVICE_ACCOUNT_DATA: the contents of your Play Store service account JSON file, as plain text

Your service account file should have the following format

{
  "type": "service_account",
  "project_id": "...",
  "private_key_id": "...",
  "private_key": "...",
  "client_email": "...",
  "client_id": "...",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "..."
}

Commit and let the pipeline run! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment