Bitrise vs Github Actions

Mustafa Ürgüplüoğlu
inventiv
Published in
8 min readAug 19, 2021

In mobile development CI/CD processes became essential. In order to achieve that there are so many tools out there. Bitrise and Github Actions are one of the most popular solutions for CI/CD processes. In this article we are going to compare these tools on android development perspective.

Firstly we will talk about pros and cons for each tool’s free versions and then we are going to compare implementation details for release workflow.

If you want to see paid versions, you can check Bitrise Pricing-Github Actions Pricing

Pros and Cons

In order to automatize build process, we will follow the steps below :

  • Define Variables
  • Create Workflow
  • Define Trigger (When specified tag received)
  • Define Environment (Choose OS)
  • Clone Repository
  • Cache Packages (Optional)
  • Install Required Components
  • Android Lint & Unit Test (Optional)
  • Android Build
  • Publish To Google Play

Step 1 — Define Variables

You can keep your sensitive data (such as credentials, private keys, passwords etc.) in CI/CD tool’s secret configuration. Secret variables can not be seen by anyone. In our sample we are going to store our keystore file, keystore alias, keystore password values in secrets. You can keep common insensitive variables in environment variables.

Bitrise

You have two options for keys, Environment Variables and Secrets. Env Vars are fully exposed in builds triggered by pull requests so you should not add any sensitive information to Env Vars. Secrets are special type of Env Vars as they hide information in an encrypted format so that your private input is not exposed in the build logs/bitrise.yml.

Text values can be stored in Secrets in key-value format. Sensitive Files can be stored in “Code Signing” tab. Later on, in workflows we can access these values and files.

Github Actions

You can set custom environment variables in your workflow file. Environment variables are case-sensitive. Commands run in actions or steps can create, read, and modify environment variables.

To set environment variables, you need to specify the variables in the workflow file. You can define environment variables for a step, job, or entire workflow.

Sample usage of environment variables in .yml file

Encrypted secrets allow you to store sensitive information in your organization, repository, or repository environments. The secrets that you create are available to use in Github Actions workflows. GitHub automatically redacts secrets printed to the logs. Secrets are defined in Your Github Repository -> Settings -> Secrets

We will create four Github Secrets for sign application. They are TEST_KEYSTORE(File), TEST_KEY_ALIAS(String), TEST_KEY_PASSWORD(String), TEST_STORE_PASSWORD(String). As you know keystore is in file format. But in Github Secrets we can only store strings. So we need to convert it to string. For convert file to string, we will use base64 to convert it string format. In terminal use below code to convert your keystore file to base64 string format. In Fastlane we will read this string and convert back to it file format again.

base64 -i <in-file> -o <outfile>base64 -i test.keystore -o test.txt

In Fastlane

sudo bash -c "echo '${{ secrets.TEST_KEYSTORE }}' | base64 -d > test.keystore"

Step 2— Create Workflow

A workflow is a configurable automated process made up of one or more jobs. You can separate your development and deploy workflows.

Bitrise

You can use Web UI or bitrise.yml configuration file for define workflows.

Web UI Workflows and bitrise.yml tab in screenshot

Github Actions

You have to create a YAML file to define your workflow configuration. You must store workflow files in the .github/workflows directory of your repository.

Step 3— Define Triggers

Bitrise

Go to the Triggers tab and define your rules. There is 3 options to trigger your workflows. Push (When commit pushed to your repository), Pull Request (When a new pull request created on your repository), Tag (When a commit received with a defined tag name).

For example if you want to deploy your .apk or .aab to Google Play, you can define a Tag Trigger rule like “*-googleplay”. When your repository receive a tag (ex: “v1.7.2-googleplay” your “deploy” workflow will be triggered.

Github Actions

Create your workflow file like .github/workflows/build.yml Below “on:” you can use pull_request, push and many others. In order to trigger action on receiving a tag, which value contains “googleplay”, you should use the code snippet below:

Define Trigger

Step 4— Define Environment

These workflows runs over a machine. These machines can be run Linux, Windows or Mac.

Bitrise

Go to the Stack tab for choose your OS Environment. Ubuntu and Mac available in Bitrise.

Bitrise Stack Tab

Github Actions

In your build.yml file you have to define os which demonstrated in code snippet below.

Define OS Environment

Virtual Environments support Ubuntu, Windows and Mac. And if you want you can use self-hosted machine.

Step 5— Clone Repository

Before build your .apk or .aab file, first you have to clone repository into machine.

Bitrise

For this there is a step called “Git Clone Repository”. But before you must use “Activate SSH key” step to authenticate with your repository. You can clone a repository from Github, Bitbucket, Gitlab or any source.

Github Actions

Your repository and workflow already in same place so you don’t need to be authenticate for access repo. And we will use actions/checkout step. This action checks-out your repository under $GITHUB_WORKSPACE, so your workflow can access it.

Clone Repository

Step 6— Cache Packages (Optional)

Every single build runs on a clean virtual machine. This means that normally, without caching, everything must be done from scratch on the virtual machine, including, for example, installing your dependencies. To make your workflows faster and more efficient, you can create and use caches for dependencies and other commonly reused files.

Bitrise

Every branch of your repository on which you run a build will have its own cache archive. For use them you have to set two steps. “Bitrise.io Cache:Pull” is pulling pre cached values from cache archive. And then “Bitrise.io Cache:Push” is pushing cached values to the archive.

Github Actions

We use “cache@v2” action to cache required gradle dependencies for build. There is sample below:

Step 7— Install Required Components

In virtual machine you must install required Android components before build your application.

Bitrise

“Install missing Android SDK components” This step analyze your root settings.gradle file, to collect the active build.gradle files.Based on the files it will install required Android SDK components.

Install Required Components Step

Github Actions

We are going to use Fastlane to run Android related tasks. Fastlane helps managing these tasks. First of all we need to init fastlane under project root folder. And we are going to use “Fastfile” to write our scripts. Basically the idea is that: Github action workflow is going to run that Fastlane methods from terminal.

Step 8— Android Lint & Unit Test

Before taking build you must control your code health with Android Lint & Unit Test your code.

Bitrise

After “Install missing Android SDK components” you can add “Android Lint” and “Android Unit Test” steps like below. Lint & Unit Test results will be uploaded “Apps & Artifacts” section in your build result.

Android Lint & Unit Test Step

Github Actions

We defined “run_lint” and “run_unit_tests” fucntions in Fastfile. In action we are going to call these functions.

Step 9— Android Build

In this step you must build .apk or .aab file to send it to your testers or upload to Google Play Store.

Bitrise

After “Android Lint” and “Android Unit Test” you must add “Android Build” step. You can configure Variants, Build types etc. for your build in UI.

Android Build Step

Github Actions

We defined “generate_signed_apk” function in Fastfile. In action we are going to call this function.

Step 10— Publish To Google Play

We created our .apk file so we can send it to Google Play. But first you need service_account.json file. You can create this file with follow this guide.

Bitrise

Upload your keystore file into “ANDROID KEYSTORE FILE” and fill the password and alias fields.

Upload Keystore File To Bitrise Code Signing

Now we can add “Android Sign” step in Workflows. And select your already defined parameters for “Keystore url”, “Keystore password”, “Key alias” and “Key password”.

Upload your service_account.json file to “Code Signing” -> “GENERIC FILE STORAGE” place in Bitrise.

Upload service_account.json File To Bitrise Code Signing

Now we can add “Google Play Deploy” step in Workflows. And select your uploaded file id for “Service Account JSON key file path”.

Upload To Google Play Bitrise Step

If everything works fine, when “Google Play Deploy” step finished after your .apk will be uploaded in Google Play Alpha.

Github Actions

We will use Fastlane for complete this step. Like in Step 1 — TEST_KEYSTORE file we will upload our service_account.json file to Github Secrets.

  • First “secrets.SERVICE_ACCOUNT_JSON” string will be converted to service_account.json file.
  • Second fastlane deploy_apk_to_play_store function will be triggered.
  • Finally Fastfile deploy_apk_to_play_store function will upload our apk to Google Play Store.

If everything works fine, your .apk will be uploaded Google Play Internal track.

Google Play Publish Step

Conclusion

As a result; both platforms have their pros and cons. Bitrise can be preferred for an easier integration and source control independent usage option, while Github Actions can be preferred for using single place for both source control and CI/CD processes.

You can check all the codes from sample repository.

Resources

--

--