Skip to content

DevOps for Mobile Apps Demo - November 8, 2021

Recording

https://youtu.be/3LnIuxI68BI

Mission

DevOps for Mobile Apps Single-Engineer Group

Our goal is to improve the experience for Developers targeting mobile platforms by providing CI/CD capabilities and workflows that improve the experience of provisioning and deploying mobile apps.

Demos like this one are published each week, you can find previous demos and see new ones when they are finished in the Weekly Demos issue.

Current Update - Code Signing and Beta Releases with Fastlane

  • iOS Pipeline
  • Android Pipeline

Screen_Shot_2021-11-08_at_2.19.37_PM

Android Pipeline

https://gitlab.com/gitlab-org/incubation-engineering/devops-for-mobile-apps/gitlab_unfiltered/-/merge_requests/7

https://gitlab.com/gitlab-org/incubation-engineering/devops-for-mobile-apps/gitlab_unfiltered/-/pipelines/403029886

Platform Signing Release
iOS Fastlane Match App Store Connect API
Android Keystore Service Account

Android App Signing

Generate an upload key and keystore

https://developer.android.com/studio/publish/app-signing#generate-key or https://flutter.dev/docs/deployment/android#signing-the-app

This process will generate a Java Keystore file (.jks) which will be uploaded to the Google Play store. The data in this keystore will be used to sign the application and validate the upload.

Set CI/CD Variables
  • ANDROID_KEYSTORE_PASSWORD
  • ANDROID_KEY_PASSWORD
  • ANDROID_KEY_ALIAS (i.e. upload)
  • ANDROID_KEY_STOREFILE (i.e. ../upload-keystore.jks)
Configure guild.gradle

https://gitlab.com/gitlab-org/incubation-engineering/devops-for-mobile-apps/gitlab_unfiltered/-/blob/master/android/app/build.gradle#L59-66

signingConfigs {
    release {
        keyAlias project.env.get("ANDROID_KEY_ALIAS")
        keyPassword project.env.get("ANDROID_KEY_PASSWORD")
        storeFile project.env.get("ANDROID_KEY_STOREFILE") ? file(project.env.get("ANDROID_KEY_STOREFILE")) : null
        storePassword project.env.get("ANDROID_KEYSTORE_PASSWORD")
    }
}
Binary CI/CD variable workaround

Open Issue: gitlab-org/gitlab#205379 (closed)

Base64 encode the contents of upload-keystore.jks

base64 -i upload-keystore.jks | pbcopy

Assign base64 encoded data to a CI/CD variable (i.e. APKSIGN_KEYSTORE_BASE64)

Base64 decode and write the output during the build

echo ${APKSIGN_KEYSTORE_BASE64} | base64 -d > upload-keystore.jks

Android App Release

Create a GCP Service Account & Credentials File

https://docs.fastlane.tools/getting-started/android/setup/ (See the Collect your Google credentials section)

Save the credentials file locally and configure the fastlane/Appfile to use it:

json_key_file("./json_key_file.json")

Fastlane offers a handy command to test the connection as well:

fastlane run validate_play_store_json_key json_key:json_key_file.json

Base64 encode the contents of json_key_file.json

base64 -i json_key_file.json | pbcopy

Assign base64 encoded data to a CI/CD variable (i.e. ANDROID_KEY_PROPERTIES_FILE_DATA)

Base64 decode and write the output during the build

echo ${ANDROID_JSON_KEY_FILE_DATA} | base64 -d > json_key_file.json

Fastlane beta deploy

.gitlab-ci.yml

beta_android:
  image: registry.gitlab.com/gitlab-org/incubation-engineering/devops-for-mobile-apps/gitlab_unfiltered/android-build
  stage: beta
  script:
    - bundle install
    - flutter pub get
    - cd android
    - echo ${ANDROID_JSON_KEY_FILE_DATA} | base64 -d > json_key_file.json
    - echo ${APKSIGN_KEYSTORE_BASE64} | base64 -d > upload-keystore.jks
    - flutter build appbundle
    - bundle exec fastlane android beta
  when: manual
  allow_failure: true
  only:
    refs:
      - master 

Fastfile

desc "Submit a new Beta Build to the Google Play store"
lane :beta do
  upload_to_play_store(
    track: 'internal',
    version_code: flutter_version()["version_code"],
    version_name: flutter_version()["version_name"],
    aab: '../build/app/outputs/bundle/release/app-release.aab'
  )
end

Command Reference:

  1. http://docs.fastlane.tools/actions/upload_to_play_store/
  2. https://github.com/tianhaoz95/fastlane-plugin-flutter_version

Additional Resources

Custom Docker Image

Failed to read key upload from store "/builds/gitlab-org/incubation-engineering/devops-for-mobile-apps/gitlab_unfiltered/android/upload-keystore.jks": Integrity check failed: java.security.NoSuchAlgorithmException: Algorithm HmacPBESHA256 not available

Android & Fastlane

Android + Fastlane

Android + Fastlane + GitLab

Nix

Up Next

  • Improve the build efficiency of the iOS builds by investigating the double compile problem and looking to contribute updates to the shared runner configuration.
  • Explore some ways in which we could simplify the process of app signing and releasing on GitLab using Fastlane.
Edited by Darby Frey