DEV Community

Aashish Karki
Aashish Karki

Posted on

FastLane and github action for React Native app deployment .

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

gem install fastlane
Enter fullscreen mode Exit fullscreen mode

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

app_identifier "com.example.karkipy"
apple_id "aashish@karkipy.com"
team_id "1233343455"
Enter fullscreen mode Exit fullscreen mode

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

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

Enter fullscreen mode Exit fullscreen mode

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

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")


Enter fullscreen mode Exit fullscreen mode

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

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

Enter fullscreen mode Exit fullscreen mode

Now we move to Deploying our app using github actions.

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
Enter fullscreen mode Exit fullscreen mode

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.

Latest comments (2)

Collapse
 
ovsdrak profile image
Ovsdrak

Thanks!
Could you share the content of the action "increment-app-build"?

please

Collapse
 
karkipy profile image
Aashish Karki

hi sorry for the late reply, increment_build_number automatically increments by one but is only supported in ios, we had similar issue so to maintain the version through out both android and ios what we did was host the text file containing the version number, and incremented it each time we released and the version would be available in environment through out the project this will maintain the same version for both ios and android