Automate publishing your android app to Google Play Store with Fastlane and Github Actions

tifanide

Tifani Dermendzhieva

Posted on April 20, 2023

Automate publishing your android app to Google Play Store with Fastlane and Github Actions

Developers need fast and efficient way to deliver apps to the users, ensuring continuous integration and clear versioning of their apps.
Manual publishing of an app can be time-consuming and involves a lot of repetitive steps that could easily be automated, such as building and signing a new app file, logging in to the Google Play Console and uploading the file.
Therefore, the most efficient way to achieve this is automating the process of publishing the app to Google Play Store.

In this tutorial, I will show you how you can use Fastlane and Gihtub Actions to automatically upload an android app bundle (.aab) to Google Play Store.

Prerequisites

Before we proceed with the tutorial, you will need to have done the following:

1. Create a Google Play Developer Account

2. Setup an app in your account

3. Enable Google Play Android Developer API

4. Enroll on Play App Signing: if you are not sure how to enroll, check out this super concise tutorial on jmango360

5. Configure your app to use the correct upload key for signing the app: it must be the one used to enroll for Play App Signing and for the purposes of this tutorial it will be called myKeystore.keystore

1. Create a service account and JSON key

To automate the process of publishing your app to Google Play Store you will have to provide a JSON key, which will be used for authentication against Google Play Developer API.
In order to obtain this key, you have to setup a service account first.

Create a new service account

Step 1: Login to Google Cloud Console

Step 2: Navigate to IAM & Admin and select Service Accounts

Step 3: Create a new service account and assign the role of Basic Editor to it.

Generate a new json key

Step 4: Navigate to the service account you have just created, click on create new key and select type JSON.

Download the key and store it securely. For the purposes of this tutorial rename the file to service-account.json.

Invite the service account user to the app project

Step 5: Login to Google Play Console and navigate to Setup -> API access

Step 6: Find the service account name (email) and grant admin access to it. If you want to keep the permissions to the minimum required, make sure that you have selected everything under the release section.

Note: Be aware that granting access to the service account can only be performed by the owner of the google developer account.

2. Setting up Fastlane

Step 1: Make sure that you have installed Ruby on your machine:

    ruby -v
Enter fullscreen mode Exit fullscreen mode

Step 2: Install fastlane:

    gem install fastlane -NV
Enter fullscreen mode Exit fullscreen mode

Step 3: At the root of the project (i.e. android/) run the following command to initialise fastlane:

    fastlane init
Enter fullscreen mode Exit fullscreen mode

This will prompt you to enter the name of the package, e.g. "io.appname.app".
You can press enter to skip the rest of the questions, as they can be configured later.
When asked "Download existing metadata and setup metadata management?" respond with no (i.e. n).

After the command has been executed you will notice that a new folder fastlane has been created.
Inside this folder there will be two files - Appfile and Fastfile.
Place the service-account.json in the fastlane/ folder, but do NOT commit it to github.

Step 4: In the fastlane/Appfile define the path to the service account json key (relative to where the fastlane actions will be called) and the package name.

Assuming that the fastlane actions will be called at the root of the project, the Appfile content looks like this:

    json_key_file("fastlane/service-account.json")
    package_name("io.appname.app")
Enter fullscreen mode Exit fullscreen mode

Important: When you use github actions make sure to restore the json key in the correct directory (i.e. fastlane/).

Step 5: The fastlane/Fastfile is where all methods (a.k.a lanes) must be defined.

Let's take a look at the following Fastfile.

There are two lanes (methods), the first of which is :internal. It uses the gradle action to build an app bundle (.aab) and the upload_to_play_store action to upload the bundle to the internal track on the play store (the other track options are 'alpha', 'beta' and 'production').
To find out more about the google play tracks click here.

The second lane is :production and uses the same actions to build and publish the bundle to the production track on Google Play.

    default_platform(:android)

        platform :android do

            # LANE 1
            desc "Publish a new version to the Google Play (INTERNAL)"
            lane :internal do

                # Generate AAB file
                gradle(
                task: "bundle",
                build_type: "Release"
                )

                # Upload the AAB to play store (internal track)
                upload_to_play_store(track: 'internal')
            end

            # LANE 2
            desc "Publish a new version to the Google Play (PROD)"
            lane :production do

                # Generate AAB file
                gradle(
                task: "bundle",
                build_type: "Release"
                )

                # Upload the AAB to play store (production track)
                upload_to_play_store(track: 'production')
            end
        end

Enter fullscreen mode Exit fullscreen mode

If you want to make sure everything works as expected before you publish your app, you could pass the validate_only: true argument to the upload_to_play_store action.
It will only verify that everything is correct without actually publishing the app on the selected track.

    # Validate upload the AAB to play store (production track)
    upload_to_play_store(track: 'production', validate_only: true)
Enter fullscreen mode Exit fullscreen mode

Note: You can find all available arguments for upload_to_play_store here

If you want to run the :production lane locally, execute the following command in your terminal (note: make sure you are working in the root dir):

    bundle exec fastlane production
Enter fullscreen mode Exit fullscreen mode

3. Create a workflow with Github Actions

Create new repository secrets for the JSON key and upload key (myKeystore.keystore)

Both the upload key and the service account json key contain sensitive information which should be stored securely and hence, should not be pushed to the github repository.
In order to be able to access them from within the workflow, you have to obtain them from the repository secrets. To achieve this, let's first ecrypt/encode them:

Step 1: Encrypt the .keystore file, in the terminal run the following command:

    gpg -c -armor myKeystore.keystore
Enter fullscreen mode Exit fullscreen mode

This command will prompt you to enter a passphrase. Important: Make note of the passphrase.

After successful exection you will be able to see a myKeystore.keystore.asc file in the current directory.

Step 2: Create a new repository secret (ENCRYPTED_KEYSTORE), containing the content of myKeystore.keystore.asc

Step 3: Create a new repository secret (ENCRYPTED_KEYSTORE_PASSPHRASE), containing the passphrase, used to encrypt the keystore (ref. Step 1)

Step 4: Encode the JSON key

    base64 -it service-account.json -o encoded.base64.txt
Enter fullscreen mode Exit fullscreen mode

Step 5: Create new repository secret (SERVICE_ACCOUNT_JSON) and place the content of the encoded.base64.txt

Create a new github workflow

Now, that Fastlane and the secrets have been setup, let's create the workflow .github/workflows/publish_play_store.yml, containing the following:

name: Publish to Play Store ( Internal track )

on:
  workflow_disptach:

jobs:
  upload-play-store-internal:
    name: Upload app to Play Store (Internal track)
    runs-on: ubuntu-latest

    steps:
      - name: Check out repository
        uses: actions/checkout@v3

      - name: Setup ruby
        uses: actions/setup-ruby@v1
        with:
          ruby-version: "3.x"

      - name: Setup fastlane
        run: |
          cd android
          bundle install
          cd ..

      - name: Restore json key # make sure that you restore the key in the correct directory (ref. fastlane/Appfile)
        run: |
          cd android/fastlane
          echo "${{ secrets.SERVICE_ACCOUNT_JSON }}" | base64 --decode > service-account.json
          cd ../..

      - name: Restore keystore # make sure that you restore the key in the correct directory (same as app/gradle.properties)
        run: |
          cd android/app
          echo "${{ secrets.ENCRYPTED_KEYSTORE }}" > myKeystore.keystore.asc
          gpg -d --passphrase ${{ secrets.ENCRYPTED_KEYSTORE_PASSPHRASE }} --batch myKeystore.keystore.asc > myKeystore.keystore
          cd ../..

      - name: Set up JDK environment
        uses: actions/setup-java@v3
        with:
          distribution: "zulu"
          java-version: 11

      - name: Install dependencies
        run: yarn install --frozen-lockfile

      - name: Make Gradlew Executable
        run: cd android && chmod +x ./gradlew

      - name: Upload app to Play Store (Internal track)
        run: |
          cd android
          bundle exec fastlane internal
Enter fullscreen mode Exit fullscreen mode

Congratulations, you have automated your app publishing process.
All you have to do is run the workflow and your app will be available to testers on the internal track. To publish the app on the production track instead, simply switch the lane in the final step to poduction and you are good to go.

Conclusion

Automating your app deployment can save you hours of building, testing, and releasing
your app on a regular basis. In this tutorial I have walked you through the steps
of automating the process of building and publishing an android app to Google Play
Store. If you are interested in reading other tutorials related to play store automation
with Gihtub Actions, I recommend these amazing articles by Tomer Ben Rachel on freecodecamp.org
and by Shreyas Patil on medium.com

💖 💪 🙅 🚩
tifanide
Tifani Dermendzhieva

Posted on April 20, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related