FASTLANE: FROM ZERO TO AUTO
--
Have you ever felt bored doing repetitive work or were insecure about data leaks?
An android developer, for example, does things like building AAB to upload to the Playstore. And, always remember to store passwords, alias names, and key passwords that absolutely must not be forgotten for life if you don’t want to deal with all the complications that will occur.
We might think to write it down in a document. But can it guarantee that the document will always be there? Will the document not fall into the hands of irresponsible people? Will we always remember where we put the document? If you’re in a team, would you be willing to give your app’s keystore file and password to someone else? Of course, it’s risky.
Some developers may be okay with all that stuff, but it won’t solve the first problem: doing tedious things like building AABs and then uploading them via the Play Console. Wait, did you guys upgrade the version code earlier? We sometimes forget about it, then repeat it. So dull, isn’t it?
Have you ever heard of Fastlane?
Fastlane is an open-source platform that aims to simplify the distribution of mobile applications. Fastlane automates our workflows quickly and inexpensively. We combine automation in Fastlane with automation in our repositories like Gitlab CI, Github Actions, etc. For more details, read about CI/CD.
I will share how to apply the automation to an android application project that has not implemented any automation, either Fastlane or CI/CD in the repository.
Here I have an application that only displays the version of the application:
https://play.google.com/store/apps/details?id=id.sydev.justversion
We need to have an app already deployed in the Playstore to do this. Our next step will be to add automation to our repository. In this case, I use GitLab, so I will use GitLab CI. Read how to make a GitLab CI/CD here.
Here are a few sections, let’s go one by one.
image: jangrewe/gitlab-ci-android
The image
here shows that the Docker image
that we use is of jangrewe/gitlab-ci-android.
cache:
key: ${CI_PROJECT_ID}
paths:
- .gradle/
The cache
is used to store pipeline results from jobs so they don’t need to be worked on again, they can be reused.
before_script:
- chmod +x ./gradlew
before_script
contains commands to be executed each time jobs are running.
stages:
- build
- inspection
stages
contain jobs to be executed in order from top to bottom. If you want to run jobs simultaneously, it can be done by matching the stage name on the job as in the script above, stage inspection is found in 3 jobs, namely linter
, linterFormat
, and unitTest
.
build:
stage: build
script:
- ./gradlew assembleDebug
artifacts:
paths:
- app/build/outputs/
only:
- merge_requests
- dev
The above script shows one job
named build. The stage contains the name of the stage
to be executed in the stages section. The script has the commands to be executed. artifacts
indicate that the script will save the results at the specified path. Only, is used to specify where the job will be performed. The example above will only run on the dev
branch and when making a merge request
.
In addition to the commands above, we can learn more at the link here.
After adding the above code to our project. We will do a push to GitLab, after that we can look in the CI/CD tab -> pipeline
to see if the automation is running or not. When it is successful, we can download the APK build available on the job artifact. The build problem to be shared with the QA team is also resolved.
By implementing Gitlab CI, we don’t need to do a manual build for distribution; just download the artifact. But not everyone has access rights to the repository, so we will implement Fastlane so that people can download our application on the Playstore.
The way to implement Fastlane already exists here. First, we will create a service account as an identity to run an API from Google. In this case, it is deploying through a third party (Fastlane) in the form of the JSON
format.
Once we get it (we call it service_account.json
), we are trying to deploy it through our local machines first then place it in our project’s root directory. After that, it’s time for us to install Fastlane.
sudo gem install fastlane
This command is used to install Fastlane on our device.
fastlane init
This command is used to initialize Fastlane in our project. Here we will be asked to enter the package name of our application, then enter the service_account
path JSON, which we have placed in our project’s root directory before.
After that, we will be asked to confirm whether to import metadata
from Google Play. Choose y
if we feel it’s safe. But don’t worry, we can change it next time. After completion, it will generate several files as shown in the image below.
We can confirm whether our service_account.json
is valid or not with the command:
bundle exec fastlane run validate_play_store_json_key json_key:service_account.json
If it is confirmed to be valid, we will modify the Fastfile
and Appfile
files. The result generated from the previous Fastlane in command is depicted here:
After that, we are going to make changes in our application, such as adding a changelog feature like this:
The change already exists. the QA team needs to get this change. We can try Fastlane on our local machine first to execute the internal deployment with the Fastlane command that we have set up in our Fastfile
.
fastlane internal
A message will have been sent to Slack via Fastlane with the APK internal URL address. we don’t need to open the artifact on GitLab to give it to the QA team.
They can get it directly on the Slack channel!
We have successfully deployed internal applications without needing to open the Play Console. It’s time we combine the two automation that we have made to be more automated.
Imagine that we have finished developing a sprint. We only need to make an MR to our GitLab. After merging, the application will be built automatically by GitLab using Fastlane, and then distributed to the Playstore. We need to modify ourgitlab-ci
file so that we can execute the existing Fastlane commands like this:
Enter the environment we need to deploy to the GitLab variable as above, we can also include our .jks
file if needed, otherwise, put the .jks
file in the app directory. Uncheck FlagProtect variable
if we work in an unprotected branch.
Before pushing to GitLab, let’s prepare the metadata
for deployment with the command:
fastlane supply init
Then we will get our previous metadata
file on Playstore in the Fastlane directory:
In the changelogs directory, there is a .txt
file with a name based on the version code. Because we will be deploying version 1.2
with version code 2
, we need to create a new file with the name 2.tx
t and fill in the changes we made.
After that, we can delete the service_account.json
file because it’s for security reasons and it’s not needed because we already save it in GitLab variables. If so, do commit and push.
When we push to the dev branch, the uploadPlayStoreInternal
job of the deploy
stage will be executed and will run the internal Fastlane as we did before on our local machine.
Upon success, a success message along with the URL internal app sharing will be sent to the Slack channel, after safe we can make a merge request to the branch master.
Once the pipeline is completed, perform merge and then see the process on the tab CI / CD -> pipeline
An incoming message in Slack, it’s time to take a look at the Play Console. The app is being reviewed! We’ve done the automation, no more manual work for our app distribution!
Conclusion
By using CI/CD and Fastlane, we can implement automation to make it faster, cheaper, and hassle-free. We also don’t need to memorize all the sensitive stuff to avoid data leakage.
References: