Deploy a mobile application on the stores with Gitlab + Fastlane !

P-A
7 min readApr 10, 2020

--

First of all, I would like to introduce this post like a good basic approche for beginner in devOps mobile. You can use this post like a sandbox to understand the steps for an automatic deployment and to have a good structure for your futur development.

What you’re going to get from this tutorial :

  • Setup Fastlane on Android and IOS project.
  • Create specific lanes with Fastlane and understand them.
  • Setup Gitlab CI/CD and .gitlab-ci.yml.
  • Deploy your app on the Stores (AppStore & PlayStore).

Prerequisite:

  • Mac OS X (Fastlane run only on OSX).
  • Gitlab account.
  • Google playStore developer account (25$ for life).
  • Apple developper account (99$ per year).

For this post, I will use a react-native project, but you can use this post for your native application. This post is compatible with React-Native, Java (Android) and Swift/Objective-C (IOS) projects.

The project that I will use is available ON THIS GITHUB. It’s a basic application which have a slider designed. Feel free to use it.

default App

Ready ? Let’s start …

#1 — Fastlane

1.1) Installation

Firstly, you will need to install Fastlane :

  • Open a terminal anywhere.
  • Install the latest Xcode command line tools:
xcode-select — install
  • Install fastlane using:
# Using RubyGems
sudo gem install fastlane -NV
# Alternatively using Homebrew
brew install fastlane

I am providing just the installation but get the full documentation here.

1.2) Initialisation

Once Fastlane installed on your machine. We can now initialise it. Doesn’t matter if your project is in React-Native or native because Fastlane works identically for these three cases java / swift or objective-c / React-native.

For android :

Go in your android project folder and initialise Fastlane.

cd androidfastlane init

Fastlane will detect your android project. The first information to give is the package name of your application.

You can find the package name atdefaultConfig.applicationId of your app in app/build.gradle file.

Fastlane init Step 1 — Android — Package Name

Then Fastlane will ask you the secret JSON to Google Play to download the existing metadata. We didn’t configured it yet. Just press Enter and n for the second input.

Fastlane init Step 2 — Android — Secret JSON Google Play

Next step, Fastlane will generate it configuration. Press Enter until the end.

Fastlane Step 3 — Android — Generate fastlane configuration

Fastlane is now configured. You can see in your android project a folder android/fastlane with two files:

Fastlane init final step — Android project

Appfile : which has the package name and the path to your secret JSON to Google Play (not set yet).

Fastfile : which contains default lanes.

For IOS:

Go in your ios project folder and initialise fastlane.

cd iosfastlane init

Fastlane will detect the IOS project and start the initialisation. For IOS fastlane will provide you four choices. Let’s choose the manual setup.

Fastlane init Step 1— IOS — Manual Setup

The manual setup will let you free to setup your tasks as you want. To finish the configuration of fastlane press Enter until the end.

Fastlane init — IOS — Final Step

Faster than Android Fastlane in IOS is now configured. As you can see on your IOS project the folder fastlane with two files:

Fastlane init final step — IOS project

Appfile : which has your application informations (not set yet).

Fastfile : which contains default lanes.

#2 — Fastlane Lanes

Fastlane is the easiest way to automate beta deployments and releases for your iOS and Android apps. 🚀 It handles all tedious tasks, like generating screenshots, dealing with code signing, and releasing your application.

One of the most interesting part with fasltane, is the plugin system. I will show you some useful lanes.

Let’s create them.

For Android :

In the file android/fastlane/Fastfile you can see default lanes :

lane :test
lane :beta
lane :deploy

We will create our custom lane which will compile the application and increment the build number. We will call it upload_interna :

lane: upload_internal

Past this lane on your android/fastlane/Fastfile :

Android lane upload_internal

This lane executing tasks in this order:

  • Clean the project thanks to the command ./gradlew clean
  • Increment the the version code of your project. You can find the version code of your app on the app/build.gradle in the structure android.defaultConfig.versionCode . As you can see on this line ENV["BUILD_NUMBER_ANDROID].to_i is getting the environnement variable BUILD_NUMBER_ANDROID and convert into INT.
  • Build the application app.aab.

Why .aab and not .apk ? check this documentation to know more about Android App Bundle.

Before to launch this lane localy. Make sure to have the required plugins. So run in your android/ project :

fastlane add_plugin increment_version_code

Answer (y) to let fastlane modify the Gemfile for you. Now You should have this output:

fastlane add_plugin — output

Before to compile a bundle make sure you have signed your application. If you didn’t check this documentation.

Everything is set let’s run your first lane. Go in your android project and run :

export BUILD_NUMBER_ANDROID=1 && fastlane upload_internal
fastlane upload_internal end ouput

You can find you app-release.aab in android/build/outputs/bundle/release folder.

For IOS :

In the file ios/fastlane/Fastfile you can see custom_lane . Replace content of the file by this :

Fastfile IOS — beta lane

This lane executing tasks in this order:

  • Increment the the version code of your project. As you can see on this line ENV["BUILD_NUMBER_IOS].to_i is getting the environnement variable BUILD_NUMBER_IOS and convert into INT.
  • Build the application.

#3 — Gitlab CI/CD with Gitlab Runner

First of all, you MUST set up a gitlab-runner on a OSX machine. The problem is there are not shared runner OSX on Gitlab. So you can start by create a runner on your Mac. Go on you gitlab repository, on the settings > CI/CD.

Settings > CI/CD

Expand the Runners section. And follow the instruction “Set up a specific Runner manually’’ .

gitlab-runner register

Do not forget to add tags of your runner, it will be useful for launch your CI. Once register start the runner.

gitlab-runner start

On the Runner tab of your Gitlab project you should see your runner active.

Your Runner is now set up. Before to create our .gitlab-ci.yml. We have to create personal access token from Gitlab. Why ? Pretty simple, when a CI is launched. It run inside a container. It means, if you increment a variable inside. At the end this variable will be not saved to the project. The problem is when you upload your App on the Apple Store or Google PlayStore we have to provide for each build a unique version code. So we need a counter. The goal is to access to these variables outside from the container, to saved it.

Go to Settings of your account, then go in the Access Tokens and setup a Personal Access Token.

Setup Personal Access Token

Once created you will get a new personal access tokens, save it. Be careful you will not be able to retrieve it again.

Next step, add 2 environnements variables:

  • BUILD_NUMBER_ANDROID
  • BUILD_NUMBER_IOS

Next step write your .gitlab-ci.yml

.gitlab-ci.yml

Commit and Push. On Gitlab you can now trigger 2 tasks manually.

#4 — Upload your App on the Stores

Final step is now to upload the applications on the stores.

For Google PlayStore (Android) :

First of all, if you didn’t do it yet, for the first time you have to upload manually your application on Google Play Console. After your first .aad/.apk uploaded, you can continue this step.

Provide your secret JSON Google (google credentials). If you haven’t got yet, follow the instructions of fastlane here. Once your credentials downloaded add it to your android project. And fill the json_key_file in the Appfile android/fastlane/Appfile .

Example: json_key_file("../playstore-service.json")

Now go in your android/fastlane/Fastfile and add this at the end of your lane upload_internal .

upload_to_play_store(
track: 'internal',
skip_upload_metadata: true,
skip_upload_images: true,
skip_upload_screenshots: true,
)

Don’t worry you will upload an internal version. It’s a close version that only your list of testeurs can have access.

Commit and push. Now your lane will upload your application as internal version on Google Play Console.

For AppleStore (IOS) :

First of all, if you didn’t do it yet, for the first time you have to upload manually your application on AppStore. After your first .ipa uploaded, you can continue this step.

Fill the ios/fastlane/Appfile by uncommenting and completing app_identifie and apple_id.

Now go in your ios/fastlane/Fastfile and add this at the end of your lane beta .

upload_to_testflight(skip_waiting_for_build_processing: true);

Don’t worry you will upload on testflight. It’s a close version that only your list of testeurs can have access.

Commit and push. Now your lane will upload your application as testflight version on iTunes connect.

Conclusion

Fastlane is a great tools for devops and developers. It has many features really interesting. It deserve it to pass some time to read their documentation.

--

--

P-A

CTO of Lanslot — Auto-Entrepreneur — Full-Stack Mobile