Using Gitlab CI to Build Android Project

Back to Blog Home

Using Gitlab CI to Build Android Project

Since last year Gitlab has a CI feature that is really useful for deployment. Android developers can also use this free feature to automate APK builds, which is a big plus compared to other premium build or setup CI system on the server. The limit to Gitlab CI for a private project is 2000 minutes per month and unlimited for a public project. In this post, we’ll be learning how to use Gitlab CI to build an unsigned APK.

Setup

Setup git inside your existing project / new project. Then, create a new project in Gitlab and point the remote to this new Gitlab project. Next, we create a new file inside our root Android project with .gitlab-ci.yml as the filename.

This file contains configuration for Gitlab CI. For the documentation of what to put inside this file, you can refer from here. Next, for our Android project, we can create a configuration to install and set up everything to run the Android SDK, but this is not the best practice. Instead, we will use a docker image from Jangrewe GitHub which has everything set up & configured inside. So paste this lines inside .gitlab-ci.yml :

image: jangrewe/gitlab-ci-android

stages:
- build

before_script:
- export GRADLE_USER_HOME=$(pwd)/.gradle
- chmod +x ./gradlew

cache:
  key: ${CI_PROJECT_ID}
  paths:
  - .gradle/

build:
  stage: build
  script:
  - ./gradlew assembleDebug
  artifacts:
    paths:
    - app/build/outputs/

Even though by default a pipeline in Gitlab CI runs with 3 stages: build, test & deploy. We only use build stage here, other stages will be omitted if they weren’t defined in the config.

Next, we activate a Shared Runner by opening Gitlab Setting → CI/CD and click Enable shared runner if it wasn’t enabled by default. A runner is a Gitlab process that runs the CI, and Shared Runner is a type of runner that’s provided by Gitlab, so we don’t need to set up anything inside our computer or server.

Activate CI

Next, we commit and push our project to Gitlab. Now open Gitlab and click on CI/CD → Pipelines, it will show a pipeline that’s currently running and past pipelines.

On Jobs submenu, it will display current job details, so if you have 3 stages, it will show the progress of each stage.

By pressing running on status, the page will switch to terminal display to show what is happening behind the scene.

After the build has done, a passed status will be shown, and when you click on passed status, there will be 2 new buttons on the right, Download & Browse, to download your build (zip) and browse what’s inside your build. To download this build, you can also use the button on the right on the pipelines/jobs menu.

Our example above can be accessed in this repository. You can download the final build from that repository here.

Note :

Please remember that this is an unsigned apk. It is highly not recommended to upload your keystore to the repository so you can make a signed apk. To signed apk locally please run these commands locally :

  • zipalign the unsigned apk.
zipalign -v -p 4 input-unsigned.apk input-aligned.apk
  • Sign apk using apksigner.
apksigner sign --ks keystore.jks --out output-release.apk input-aligned.apk
  • Verify that output-release.apk has been appropriately signed.
apksigner verify my-app-release.apk

Upload APK to TestFairy

If you already have a TestFairy account, uploading the APK to TestFairy is very simple. First, find your TestFairy API Key inside Account Preferences. Copy the key and paste the key into Gitlab CI Secret Variable.

Then, add a new job inside the .gitlab-ci.yml configuration above.

image: jangrewe/gitlab-ci-android

stages:
- build
- deploy

before_script:
  ...

cache:
  ...

build:
  ...

deploy:
  stage: deploy
  only:
    - master
  script:
    - |
      curl \
        -A "GitLab CI" \
        -F api_key="${TESTFAIRY_API_KEY}" \
        -F comment="GitLab Pipeline build ${CI_COMMIT_SHA}" \
        -F file=@android.apk \
        https://upload.testfairy.com/api/upload/

Replace -F file=@android.apk argument with a path to your apk.

*If you want to upload the debug apk from the build step, change the value in deploy into:

deploy:
  stage: deploy
  only:
    - master
  script:
    - |
      curl \
        -A "GitLab CI" \
        -F api_key="${TESTFAIRY_API_KEY}" \
        -F comment="GitLab Pipeline build ${CI_COMMIT_SHA}" \
        -F file=app/build/outputs/apk/debug/app-debug.apk \
        https://upload.testfairy.com/api/upload/
  dependencies:
    - build

The dependencies keyword means the deploy step requires the artifact from the build stage. This command will pass the artifact and auto extract the content. Then we change the file argument path into app-debug.apk path from the extracted artifact.