Deploy React Native app on  Playstore with Fastlane and Github Actions ( 2 / 2 )
Tags: reactnative, fastlane, github, android
Published: 2021-03-15 09:40:59

This is the second part of my post “Deploy React Native app on  Playstore with Fastlane and Github Actions”. 
All the sources of the application used here are available in this Github repository: https://github.com/antoinecellier/rn-fastlane-githubactions

In this part, we are going to set up Github Actions to build and upload an Android App Bundle on Playstore for each pre-release.

![Workflow Fastlane + Github Actions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5t6q0m756pjbpv1tazo.png)

###Setting up Github secrets
First, we will see how to store sensitive datas in Github secrets in order to use it easily with Github actions.

####Encrypt `release.keystore` file and `service_account.json` file with GPG.
Github documentation suggests using GPG to encrypt your credentials and store them as Github secrets: 
https://docs.github.com/en/actions/reference/encrypted-secrets#limits-for-secrets 

You must install GPG on your machine ( https://gnupg.org ), then encrypt these two files:
```shell
$ gpg -c --armor release.keystore 
> Enter Passphrase 
$ gpg -c --armor service_account.json 
> Enter Passphrase
```
![Enter passphrase prompt for GPG](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67y0ppz5k46cf4verpmv.png)

Each file encrypted with GPG must have a passphrase associated with it. The passphrase is used for decryption. Once you have done this, two `.asc` files have been generated. The idea is to store the contents of the `.asc` files and its passphrase in the secrets of Github.

###Store Github secrets
According to the Fastlane configuration and files encrypted, you need to have these data in Github secrets:
- For `.keystore` file:
  - Content of `.keystore.asc` (`cat .keystore.asc`).
  - Passphrase of `.keystore.asc` for decrypt the file.
  - Password of `.keystore` file.
  - Alias of `.keystore` file.
  - Key password of `.keystore` file.
- For `service_account.json` ( Playstore service account file ):
  - Content of `service_account.json.asc` (`cat service_account.json.asc`).
  - Passphrase of `service_account.json.asc` for decrypt the file.

On your repository Github page go to `Settings > Secrets` , and create new secrets for each value above.

![Example of secret form in Github](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nuexdr1l85y3hviiw09r.png)

Overview of Github secrets needed:

![List of Github secrets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qiuimk1il7iyirzz8hm.png)


###Setting up Github actions
At the root of the application, create a `.github/` folder with inside two folders:
- `workflows/` folder with inside a file named `pre-release.yml`.
- `scripts/` folder with inside a file named `decrypt_android_keys.sh`.

`.github/` folder with files are available here: 
https://github.com/antoinecellier/rn-fastlane-githubactions/tree/main/.github

Let's now take a look at the file `.github/scripts/scripts/decrypt_android_keys.sh`:


```shell
echo "$RELEASE_KEYSTORE" > release.keystore.asc 
gpg -d --passphrase="$RELEASE_KEYSTORE_PASSPHRASE" --batch release.keystore.asc > android/fastlane/release.keystore 

echo "$SERVICE_ACCOUNT" > service_account.json.asc 
gpg -d --passphrase="$SERVICE_ACCOUNT_PASSPHRASE" --batch service_account.json.asc > android/fastlane/service_account.json 

rm release.keystore.asc service_account.json.asc

```

The role of this file is to decrypt the `.keystore.asc` and `service_account.json.asc` files thanks to passphrase.


In `.github/workflows/pre-release.yml`, you will define your Github actions which trigger the lane for build and upload the Android App Bundle on Playstore. Here is its content:

```yaml
name: Pre Release 

on: 
 release: 
  types: [prereleased] 

 workflow_dispatch: 

jobs: 
 Build-and-Deploy: 
  runs-on: ubuntu-latest 

  steps: 
   - uses: actions/checkout@v2 
   - name: Decrypt Android keys 
     run: sh ./.github/scripts/decrypt_android_keys.sh 
     env: 
      RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }}              RELEASE_KEYSTORE_PASSPHRASE: ${{ secrets.RELEASE_KEYSTORE_PASSPHRASE }} SERVICE_ACCOUNT: ${{ secrets.SERVICE_ACCOUNT }} 
SERVICE_ACCOUNT_PASSPHRASE: ${{ secrets.SERVICE_ACCOUNT_PASSPHRASE }} 

   - uses: actions/setup-node@v1 
     with: 
      node-version: '10.x' 

   - uses: actions/setup-ruby@v1 
     with: 
      ruby-version: '2.x' 

   - name: Install packages 
     run: | 
         yarn

   - name: Install Fastlane 
      run: gem install fastlane
   - name: Upload to PlayStore 
      run: | 
         cd android 
         fastlane android playstoreInternal RELEASE_KEYSTORE_PASSWORD:${{secrets.RELEASE_KEYSTORE_PASSWORD}} 
 RELEASE_KEYSTORE_KEY_PASSWORD:${{secrets.RELEASE_KEYSTORE_KEY_PASSWORD}} RELEASE_KEYSTORE_ALIAS:${{secrets.RELEASE_KEYSTORE_ALIAS}}

```

Let's dig in this file. We first define the action’s trigger, in this case on each `pre-release`.

```yaml
name: Pre Release 
 on: 
  release: 
   types: [prereleased]
```

Then, we declare a job named `Build-and-Deploy` which runs on Ubuntu environment.
The job will execute `decrypt_android_keys.sh` thanks to Github secrets.
```yaml
jobs: Build-and-Deploy: 
 runs-on: ubuntu-latest 

 steps: 
  - uses: actions/checkout@v2 
  - name: Decrypt Android keys 
    run: sh ./.github/scripts/decrypt_android_keys.sh 
    env: 
     RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }}               RELEASE_KEYSTORE_PASSPHRASE: ${{ secrets.RELEASE_KEYSTORE_PASSPHRASE }} 
     SERVICE_ACCOUNT: ${{ secrets.SERVICE_ACCOUNT }} 
     SERVICE_ACCOUNT_PASSPHRASE: ${{ secrets.SERVICE_ACCOUNT_PASSPHRASE }}
```

Once the content of `release.keystore.asc` and `service_account.json.asc` decrypted and retrieved, we setup and install Fastlane. To finish, the action run `playstoreInternal` lane with each parameters needed:
```yaml

- uses: actions/setup-node@v1
        with:
          node-version: '10.x'

      - uses: actions/setup-ruby@v1
        with:
          ruby-version: '2.x'

      - name: Install packages
        run: |
          yarn

      - name: Install Fastlane
        run: gem install fastlane

      - name: Upload to PlayStore
        run: |
          cd android
          fastlane playstoreInternal   RELEASE_KEYSTORE_PASSWORD:${{secrets.RELEASE_KEYSTORE_PASSWORD}} RELEASE_KEYSTORE_KEY_PASSWORD:${{secrets.RELEASE_KEYSTORE_KEY_PASSWORD}} RELEASE_KEYSTORE_ALIAS:${{secrets.RELEASE_KEYSTORE_ALIAS}}
```

Push the `.github/` folder on your Github repository, and create a` pre-release` to trigger this awesome Github action!

![Form to create pre-release](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hysj5jwrlraylj2do2ox.png)

And here's the result 🎉 🚀

![Github action success](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/brbh8n5sjb58dyr4efzz.png)


If you have any other way to use Fastlane with Github actions or if you see a way to improve what I propose to you, please share it with us.

A big thank you to [@eric_briand](https://twitter.com/eric_briand), [@bpetetot](https://twitter.com/bpetetot) and [@tbetous](https://twitter.com/tbetous) for their proofreading.

Sources:
- https://medium.com/@StefMa/how-to-store-a-android-keystore-safely-on-github-actions-f0cef9413784
- https://github.com/features/actions