React Native with Gitlab CI/CD

Introduction#

The aim of setting up CI/CD is to automatically build the app on every commit and send the APK. I looked into Gitlab CI/CD for this purpose since Sonzai is already hosted on Gitlab.

Build Stage#

To get started, I needed to choose a docker image in which the repo would be built. After looking around a bit, I found that the react-native-community has an official Docker image , the source of which can be found on GitHub .

Gitlab CI/CD is controlled by a versioned file in the repo: .gitlab-ci.yml. To start off, I added the build job in the file and set image to the docker image above.

stages:
    - build

build:
    image: reactnativecommunity/react-native-android
    stage: build

I needed to add the commands to be executed in order to build the app. Those commands are added under the script key as an array. In my case, I need to run yarn install to install all dependencies followed by ./gradlew assembleRelease in the android directory. The file now looks like.

stages:
    - build

build:
    image: reactnativecommunity/react-native-android
    stage: build
    script:
        - yarn install
        - cd android && chmod +x gradlew
        - ./gradlew assembleRelease

Next, once the build is done, I need to export the outputs generated in the build to be consumed by the deploy stage. This is done by adding an artifacts object which contains a path array for all the paths that need to be included in the artifacts. In this case, the outputs are in android/app/build/outputs/. The file now looks like:

stages:
    - build
    - deploy

build:
    image: reactnativecommunity/react-native-android
    stage: build
    script:
        - yarn install
        - cd android && chmod +x gradlew
        - ./gradlew assembleRelease
    artifacts:
        paths:
            - android/app/build/outputs/

The build stage is now done.

Deploy Stage#

Although I could use the same image, the image is fairly large and takes time to initialize. So, I used curlimages/curl which is an alpine image with curl added and thus is really light. I will be using curl to upload the file to Telegram. Check out the documentation for bots API. Adding the deploy stage, the file looks as:

stages:
    - build
    - deploy

build:
    image: reactnativecommunity/react-native-android
    stage: build
    script:
        - yarn install
        - cd android && chmod +x gradlew
        - ./gradlew assembleRelease
    artifacts:
        paths:
            - android/app/build/outputs/


deploy_tg:
    image: curlimages/curl
    stage: deploy

I created a bot via @BotFather and added it to a channel . Next, I got the channel’s chat ID. I stored the Bot Token and the channel’s chat ID as variables in Gitlab’s UI under Repository > Settings > CI / CD > Variables as TG_BOT_TOKEN and TG_CHAT_ID respectively.

Gitlab’s UI screenshot

Next, I added a curl request in the script array to make the actual request to Telegram Bot API which utilizes these variables. It also utilizes some predefined variables in Gitlab’s default environment . Here is the final .gitlab-ci.yml

stages:
    - build
    - deploy

build:
    image: reactnativecommunity/react-native-android
    stage: build
    script:
        - yarn install
        - cd android && chmod +x gradlew
        - ./gradlew assembleRelease
    artifacts:
        paths:
            - android/app/build/outputs/


deploy_tg:
    image: curlimages/curl
    stage: deploy
    script:
        - >-
            curl
            -F chat_id=$TG_CHAT_ID
            -F document=@android/app/build/outputs/apk/release/app-release.apk
            -F caption=" <b>Branch</b>: <code>$CI_COMMIT_BRANCH</code>

            <b>Commit</b>: <code>$CI_COMMIT_SHORT_SHA</code>

            <b>Tag(if any)</b>: <code>$CI_COMMIT_TAG</code>


            <code>$CI_COMMIT_MESSAGE</code>"
            -F parse_mode=html
            https://api.telegram.org/bot${TG_BOT_TOKEN}/sendDocument

Here is the first build using this.