Skip to content

Android Release

Android Release #4

Workflow file for this run

---
name: Android Release
on:
workflow_dispatch:
inputs:
ref_name:
description: A git commit/hash/tag (optional)
type: string
default: ""
flavor:
description: The Android flavor that will be built (optional)
type: choice
default: ""
options:
- ""
- dev
- prod
upload_to_google_play:
description: Upload app to Google Play
type: choice
default: "yes"
options:
- "yes"
- "no"
concurrency:
group:
${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: "20"
RUBY_VERSION: 3.1.4
JAVA_VERSION: "17"
SKIP_COCOAPODS: "yes"
# Google Play Console API (for upload_to_play_store)
GOOGLE_JSON_SECRET_CONTENT: ${{ secrets.GOOGLE_JSON_SECRET_CONTENT }}
# Android Keystores (for create_keystore_file)
ANDROID_DEV_KEYSTORE_CONTENT: ${{ secrets.ANDROID_DEV_KEYSTORE_CONTENT }}
ANDROID_PROD_KEYSTORE_CONTENT: ${{ secrets.ANDROID_PROD_KEYSTORE_CONTENT }}
# Android Keystore Passwords and Aliases (for build.gradle)
ANDROID_DEV_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_DEV_KEYSTORE_PASSWORD }}
ANDROID_DEV_KEYSTORE_ALIAS: ${{ secrets.ANDROID_DEV_KEYSTORE_ALIAS }}
ANDROID_PROD_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_PROD_KEYSTORE_PASSWORD }}
ANDROID_PROD_KEYSTORE_ALIAS: ${{ secrets.ANDROID_PROD_KEYSTORE_ALIAS }}
# Sentry configuration
SENTRY_PROPERTIES_CONTENT: ${{ secrets.SENTRY_PROPERTIES_CONTENT }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
# Amplitude Analytics
AMPLITUDE_API_KEY: ${{ secrets.AMPLITUDE_API_KEY }}
AMPLITUDE_EXPERIMENT_DEPLOYMENT_KEY:
${{ secrets.AMPLITUDE_EXPERIMENT_DEPLOYMENT_KEY }}
# Backend URLs
FREIGHTER_BACKEND_V1_PROD_URL: ${{ secrets.FREIGHTER_BACKEND_V1_PROD_URL }}
FREIGHTER_BACKEND_V1_STG_URL: ${{ secrets.FREIGHTER_BACKEND_V1_STG_URL }}
FREIGHTER_BACKEND_V1_DEV_URL: ${{ secrets.FREIGHTER_BACKEND_V1_DEV_URL }}
FREIGHTER_BACKEND_V2_PROD_URL: ${{ secrets.FREIGHTER_BACKEND_V2_PROD_URL }}
FREIGHTER_BACKEND_V2_STG_URL: ${{ secrets.FREIGHTER_BACKEND_V2_STG_URL }}
FREIGHTER_BACKEND_V2_DEV_URL: ${{ secrets.FREIGHTER_BACKEND_V2_DEV_URL }}
# Wallet Kit Configuration (Production)
WALLET_KIT_PROJECT_ID_PROD: ${{ secrets.WALLET_KIT_PROJECT_ID_PROD }}
WALLET_KIT_MT_NAME_PROD: ${{ secrets.WALLET_KIT_MT_NAME_PROD }}
WALLET_KIT_MT_DESCRIPTION_PROD: ${{ secrets.WALLET_KIT_MT_DESCRIPTION_PROD }}
WALLET_KIT_MT_URL_PROD: ${{ secrets.WALLET_KIT_MT_URL_PROD }}
WALLET_KIT_MT_ICON_PROD: ${{ secrets.WALLET_KIT_MT_ICON_PROD }}
WALLET_KIT_MT_REDIRECT_NATIVE_PROD:
${{ secrets.WALLET_KIT_MT_REDIRECT_NATIVE_PROD }}
# Wallet Kit Configuration (Development)
WALLET_KIT_PROJECT_ID_DEV: ${{ secrets.WALLET_KIT_PROJECT_ID_DEV }}
WALLET_KIT_MT_NAME_DEV: ${{ secrets.WALLET_KIT_MT_NAME_DEV }}
WALLET_KIT_MT_DESCRIPTION_DEV: ${{ secrets.WALLET_KIT_MT_DESCRIPTION_DEV }}
WALLET_KIT_MT_URL_DEV: ${{ secrets.WALLET_KIT_MT_URL_DEV }}
WALLET_KIT_MT_ICON_DEV: ${{ secrets.WALLET_KIT_MT_ICON_DEV }}
WALLET_KIT_MT_REDIRECT_NATIVE_DEV:
${{ secrets.WALLET_KIT_MT_REDIRECT_NATIVE_DEV }}
jobs:
build:
name: Build Android
runs-on: "ubuntu-latest-16-cores"
timeout-minutes: 30
steps:
- name: Set ref
run: |
if [[ "${{ github.event.inputs.ref_name }}" != "" ]]; then
echo "REF_NAME=${{ github.event.inputs.ref_name }}" >> $GITHUB_ENV
else
echo "REF_NAME=${{ github.ref_name }}" >> $GITHUB_ENV
fi
- uses: actions/checkout@v5
with:
ref: ${{ env.REF_NAME }}
- name: Make scripts executable
run: find scripts -type f -exec chmod +x {} \;
- name: Set env
run: |
echo "UPLOAD_TO_GOOGLE_PLAY=${{ github.event.inputs.upload_to_google_play }}" >> $GITHUB_ENV
export ANDROID_FLAVOR="${{ github.event.inputs.flavor }}"
./scripts/gh-android-env >> $GITHUB_ENV
- name: Decode and save sentry.properties
run: |
echo ${{ env.SENTRY_PROPERTIES_CONTENT }} | base64 --decode > ./android/sentry.properties
# Most of the vars below are set on the ./scripts/gh-android-env script.
- name: Debug info
run: |
echo "UPLOAD_TO_GOOGLE_PLAY=${{ github.event.inputs.upload_to_google_play }}"
echo "BUILD_VERSION=${BUILD_VERSION}"
echo "REF_NAME=${REF_NAME}"
echo "APP_VERSION=${APP_VERSION}"
echo "APP_ID=${APP_ID}"
echo "APP_NAME=${APP_NAME}"
echo "ANDROID_FLAVOR=${ANDROID_FLAVOR}"
echo "FASTLANE_LANE=${FASTLANE_LANE}"
echo "SENTRY_PROPERTIES_CONTENT=$(echo -n $SENTRY_PROPERTIES_CONTENT | md5sum)"
echo "GOOGLE_JSON_SECRET_CONTENT=$(echo -n $GOOGLE_JSON_SECRET_CONTENT | md5sum)"
echo "ANDROID_DEV_KEYSTORE_CONTENT=$(echo -n $ANDROID_DEV_KEYSTORE_CONTENT | md5sum)"
echo "ANDROID_PROD_KEYSTORE_CONTENT=$(echo -n $ANDROID_PROD_KEYSTORE_CONTENT | md5sum)"
echo "ANDROID_DEV_KEYSTORE_PASSWORD=$(echo -n $ANDROID_DEV_KEYSTORE_PASSWORD | md5sum)"
echo "ANDROID_PROD_KEYSTORE_PASSWORD=$(echo -n $ANDROID_PROD_KEYSTORE_PASSWORD | md5sum)"
- name: Enable Corepack
run: corepack enable
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: "yarn"
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.RUBY_VERSION }}
bundler-cache: true
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: zulu
cache: gradle
- name: Run Yarn Install
run: |
yarn install --frozen-lockfile --immutable
- name: Run Post Install
run: |
yarn postinstall
- name: Build and Distribute Application
id: fastlane
run: |
bundle exec fastlane --version
bundle exec fastlane android ${{ env.FASTLANE_LANE }}
# Dev builds: Short retention for rapid iteration
- name: Upload dev build artifacts
uses: actions/upload-artifact@v4
if: always() && env.ANDROID_FLAVOR == 'dev'
with:
name: android-build-dev-${{ env.BUILD_VERSION }}
path: android/app/build/outputs/bundle/devRelease/
retention-days: 7
# Production builds: Extended retention given less frequent uploads
- name: Upload prod build artifacts
uses: actions/upload-artifact@v4
if: always() && env.ANDROID_FLAVOR == 'prod'
with:
name: android-build-prod-${{ env.BUILD_VERSION }}
path: android/app/build/outputs/bundle/prodRelease/
retention-days: 30