FastLane and github action for React Native app deployment .
Published: 2020-12-14 15:04:43

fastlane provides a simple implementation for deployment of android and ios app. Github action provides pipelines to simplify the release process.

fastlane can be installed via command 

```bash
gem install fastlane
```

as we will be using github action so we presume the runner image will have the tools and software installed for us. 

Specification are listed in https://docs.github.com/en/free-pro-team@latest/actions/reference/specifications-for-github-hosted-runners.

For iOS setup the faslane file for ios. Inside the ios folder create a folder named fastlane with files AppFile and FastFile. But first setup a github repo to host credentials for code sign. Setup : https://docs.fastlane.tools/actions/match/

AppFile: provide app identifier and app id and team id to it 

```bash
app_identifier "com.example.karkipy"
apple_id "aashish@karkipy.com"
team_id "1233343455"
```

FastFile: is where we write script to build and deploy our app. Be sure to host your credentials in a private repo in git.

```bash
default_platform(:ios)

platform :ios do
  desc "Build for ios"
  lane :build do |options|
    # Create a custom keychain for code signing
    create_keychain(
      name: 'keychain',
      password: 'password',
      default_keychain: true,
      unlock: true,
      timeout: 3600,
      add_to_search_list: true
    )

    match(
      storage_mode: 'git',
      type: "appstore",
      keychain_name: 'keychain',
      keychain_password: 'password',
      readonly: true,
      git_url: 'https/github/url' ## where secrets is hosted.
    )

    # Building the iOS app
    gym(
      workspace: "./Example.xcworkspace",
      include_bitcode: true,
      include_symbols: true,
      silent: true,
      clean: true,
      scheme: "Example",
      export_method: "app-store"
    )
  end


  desc "Upload to testflight"
  lane :testflight_release_to_app_store do |options|
    build
    upload_to_testflight(
      skip_submission: true,
      skip_waiting_for_build_processing: true
    )
  end

  desc "Upload to production"
  lane :production_release_to_app_store do |options|
    build
    upload_to_app_store(
      skip_screenshots: true,
      skip_metadata: true
    )
  end
end

```


For Android, create folder named fastlane inside android with similar setup of ios, uses AppFile and FastFile

AppFile: contains package name and path to secret json key that provided by Google. Steps : https://docs.fastlane.tools/actions/supply/#setup


```bash
json_key_file("app/api.json") # path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
package_name("com.example.karkipy")


```

FastFile: contains steps for fastlane to build and deploy android app

```bash
default_platform(:android)

platform :android do
  desc "Build aab file"
  lane :build do
    gradle(
      task: 'bundle',
      build_type: 'Release'
    )
  end

  desc "Release for alpha testing"
  lane :alpha_release_to_play_store do
    build
    upload_to_play_store(
      package_name: 'com.example.karkipy',
      track: "alpha",
      skip_upload_apk: true,
      aab: "app/build/outputs/bundle/release/app-release.aab"
    )
  end

  desc "Release for production"
  lane :production_release_to_play_store do
    build
    upload_to_play_store(
      package_name: 'com.example.karkipy',
      track: "production",
      skip_upload_apk: true,
      aab: "app/build/outputs/bundle/release/app-release.aab"
    )
  end
end

```

Now we move to Deploying our app using github actions.

```bash
name: Publish Staging App to App Store and Play Store

on:
  release:
    types: [published]
jobs:
  release-ios:
    name: Build Staging app and release  to testflight app
    needs: [increment-app-build]
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v1
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: '10.x'
      - name: Login Github User
        run: echo -e "machine github.com\n  login $PERSONAL_ACCESS_TOKEN" >> ~/.netrc
        env:
          PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
      - name: Install packages
        run: |
          yarn install
      - name: Bundle and Upload to AppStore
        run: |
          cd ios && pod install
          fastlane ios testflight_release_to_app_store
        env:
          FASTLANE_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
          MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}

  release-android:
    name: Build staging app and release to alpha track android
    needs: [increment-app-build]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - 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 install
          yarn react-native link
      - name: Install Fastlane
        run:  gem install fastlane
      - name: Bundle and Upload to PlayStore
        run: |
          cd android
          fastlane android alpha_release_to_play_store
```

Note: FASTLANE_PASSWORD and MATCH_PASSWORD are values need to be provided from environment so we pass it to the env for ios deployment, MATCH_PASSWORD is created during our credential creation and FASTLANE_PASSWORD is our apple id password. Also we are loginng into github using personal access token which gives us access to the repository which has our credentials hosted.