Distribution of Android build with fastlane

Introduction

Hi, I am Shiam Shabbir working as an Android engineer at GA technologies Co., Ltd. under PDD division Renosy team. I have been working here from September 2018 till now. As a foreigner, communicating with Japanese language seems pretty hard to me. I have to rely on Google translator tools, and announce something like android version release to all seems hard to me every time. So I was trying to find some solutions to overcome these problems.

While I was working in android, creation and distribution of builds to QA team and publishing the app to app store was done manually. However, it is good to do for learning but if you need to do it on a regular basis then it becomes a tedious job. Moreover, I don't know Japanese very well. So it was also difficult for me to distribute and post distribution message to Slack among my team members. Thus I came up with the idea about automation of distribution process. As for iOS we have fastlane tools to do this kind of job. So I choose fastlane to do the same for Android.

What is fastlane?

fastlane - App automation done right

A ruby based build tools to automate mobile app's tedious build and release procedure. Fastlane is an open source platform aimed at simplifying Android and iOS deployment. Fastlane lets you automate every aspect of your development and release workflow.

How to Use?

docs.fastlane.tools

Official document is pretty much understandable about how to install and integrate fastlane with your project. Although, for a new project you must consider following steps: (Assuming already fastlane is installed properly)

Step 1: initialize fastlane into project

Navigate to project root folder, and run the following command in a terminal:

$ fastlane init

Step 2: Provide application package

Provide application package name when asked like following

$ To not re-enter your package name and issuer every time you run one of the Fastlane tools or fastlane, 
these will be stored in a so-called Appfile. Package Name (com.krausefx.app):<your_application_package_name>
(can be found in AndroidManifest.xml file ->package="jp.co.companyname.xyz")
  • Other steps like adding json can be skipped for now. This json is useful for uploading metaData to google. Although I haven’t checked this one till now.

That's all for initial setup. Fastlane will automatically generate a configuration for you based on the information provided on project root ~/.fastlane folder.

f:id:s_shabbir:20191010172811p:plain
Fastlane folder structure in Android project

((Appfile which defines configuration information that is global to your app)) ((Fastfile which defines the "lanes" that drive the behavior of fastlane. This is a Ruby file. ))

Fastfile for fastlane

Fastfile is a Ruby based file to describe all jobs and task to execute. Let’s take a look inside Fastfile.

default_platform(:android)

changelog = prompt(
    text: "Release notes: ",
    multi_line_end_keyword: "END"
)

platform :android do

  desc "Runs all the tests"
  lane :test do
    gradle(task: "test")
  end

  # desc "Submit a new Beta Build to Crashlytics Beta"
  desc "Build a beta staging Apk"
  lane :beta do

    gradle(
        task: 'assemble',
        build_type: '{your_build_variants}'
    )
    @apk_output_info = load_json(json_path: "./app/build/outputs/apk/prod/{build_variants}/output.json")

    # crashlytics uploading
    crashlytics(
        api_token: '<crashlytics_api_token>',
        build_secret: '<crashlytics_build_secret>',
        groups: '<selected-dist-group>',
        notes: changelog
    )

    slack(
        # channel webhook url
        slack_url: "<your_slack_channel_webhook_url>",
        # message to display
        message: "Androidアプリのベータ版を配信しました!チケットを更新したのでQAお願いします!",
        payload: {
            "Build_date" => Time.new.to_s,
            "release_notes": changelog,
            "distributed_version": "" + @apk_output_info[0]['apkData']['versionName']
        },
        default_payloads: [:git_branch],
        success: true
    )
  end
end

Minimal requirements for an automation task through fastlane is creating lane :xyzTask. Inside that lane you need to define your tasks. In the above image, we have two lanes lane :test and lane :beta.

To execute any tasks, from project root folder type the following command in a terminal:

$ rbenv exec bundle exec fastlane beta
($ rbenv exec bundle exec fastlane <action_name>) 

This will execute android beta build and distribute it to Crashlytics for QA testing. *1

Useful methods of fastlane

Fastlane has many convenient methods to ease your life. Here I will describe only what I have used to set up minimal distribution of android.

Breaking down Fastfile :

  • default_platform(:android) - Automatically created from fastlane init command. Usually indicates for which platform it should build the tasks.
  • prompt(text:”xyz” , multi_line_end_keyword: “end”) - This will trigger every time when you execute any lane. Basically as the name suggests, this command wait for user input. When user input is completed, an END string need to set to finish prompt action. I used it to write release notes.
  • lane: test- Only for android gradle test tasks to execute.
  • lane: beta - This lane is for creating and distributing android build file .apk. Here build_type can be your build variant(‘release’, ‘beta’ etc.).

I used crashlytics to upload build for QA. If anyone wants to upload to play store use following instead of crashlytics.

upload_to_play_store(track: 'beta')
upload_to_play_store(track: '{ play store track name }')

Post to Slack Channel

Now if you want to post to slack after successful upload complete you can use

slack(message: '<your message>')

If you want particular slack channel to announce distribution you should:

  1. Create app if not present already. https://api.slack.com/slack-apps
  2. Add your channel name to integrate and get webhook url for posting.[ Incoming Webhooks | Slack]
  3. Copy webhook url and paste it to Fastfile as:
 slack(
        # channel webhook url
        slack_url: "<your_slack_channel_webhook_url>",
        # message to display
        message: "Androidアプリのベータ版を配信しました!チケットを更新したのでQAお願いします!",
        payload: {
            "Build_date" => Time.new.to_s,
            "release_notes": changelog,
            "distributed_version": "" + @apk_output_info[0]['apkData']['versionName']
        },
        default_payloads: [:git_branch],
        success: true
    )

slack message composed by one of my teammate not by me 😉

Fastlane will post on behalf of you into slack channel. Now I do not need to translate and copy paste slack message all the time. Also create and distribute build seems much easier than manual way and saves a lot of time as promised by fastlane.

やった

And that's it. I hope now you can automate your android projects distribution using fastlane tools. For further Information about fastlane android setup and documentation: fastlane docs

*1:Tips: I used rbenv, bundle and gemFile to separate fastlane installation from system default. You can install rbenv and bundler using brew.