Skip to content

Instantly share code, notes, and snippets.

@PrimeTimeTran
Created October 16, 2023 00:29
Show Gist options
  • Save PrimeTimeTran/393334d499ceaec80543f3b342703607 to your computer and use it in GitHub Desktop.
Save PrimeTimeTran/393334d499ceaec80543f3b342703607 to your computer and use it in GitHub Desktop.
name: Build & distribute apps
on:
push:
branches: [main]
tags:
- '*'
workflow_dispatch:
jobs:
# Note: Conditional jobs
# Needed because we don't have access to matrix.platform in the
# if conditional of jobs(to run or not run, that is the question πŸ€”)
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter
setup:
name: Setup 🏁
runs-on: ubuntu-latest
if: ${{ github.ref_type == 'tag' }}
strategy:
fail-fast: false
outputs:
tag: ${{ steps.set_tagged.outputs.tag }}
platform: ${{ steps.set_platform.outputs.platform }}
steps:
- uses: actions/checkout@v3
- name: Check & set tagged 🏷️ release
if: startsWith(github.ref, 'refs/tags/')
id: set_tagged
run: |
echo "Tag name: ${{ github.ref_name }}"
echo "tag='${{ github.ref_name }}'" >> "$GITHUB_OUTPUT"
- name: Set platform πŸš‰ for subsequent jobs
id: set_platform
run: |
echo "platform='${{ matrix.platform }}'" >> "$GITHUB_OUTPUT"
# Pass to new job.
echo "value_one=value_one" >> $GITHUB_OUTPUT
# Pass to next step.
echo "value_two=value_two" >> $GITHUB_ENV
# Differing techniques to pass vars between steps, jobs, actions
# Leaving because documentation on the internet is fragmented across older/newer versions of Git.
# Might as well see it as an example so next time we need to update we don't have to find & set to view again.
- name: View env variables
run: |
echo value_one: ${{ env.value_one }}
echo value_two: ${{ env.value_two }}
android-build:
name: Android πŸ€– build
needs: setup
runs-on: ubuntu-latest
if: ${{ needs.setup.outputs.platform }} == 'android'
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v3
- name: Install Java
uses: actions/setup-java@v2
with:
java-version: 11
distribution: zulu
- name: Install Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: 3.13.2
- name: Bump Android πŸ€– version name & code
uses: Devofure/[email protected]
with:
versionName: ${{ vars.APP_VERSION }}
versionCode: ${{ github.run_number }}
gradlePath: ./android/app/build.gradle
- name: Build Android πŸ€– keystore
run: |
echo "${{ secrets.KEYSTORE_PROPERTIES }}" > keystore.properties.asc
gpg -d --passphrase "${{ secrets.RELEASE_KEYSTORE_PASSWORD }}" --batch keystore.properties.asc > android/keystore.properties
echo "${{ secrets.RELEASE_KEYSTORE }}" > release.keystore.asc
gpg -d --passphrase "${{ secrets.RELEASE_KEYSTORE_PASSWORD }}" --batch release.keystore.asc > android/app/release.keystore
- name: Build Android πŸ€– APK
run: |
flutter --version
flutter pub get
export FLUTTER_SDK=/path/to/flutter/sdk
export FLUTTER_VERSION_CODE="${{vars.APP_VERSION}}"
export FLUTTER_VERSION_NAME="${{ vars.APP_VERSION }}"
flutter build apk --flavor=preview
mkdir -p dist
mv ./build/app/outputs/flutter-apk/app-preview-release.apk dist/rse.apk
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: built-apk
path: dist/rse.apk
android-distribute:
name: Android πŸ€– distribute
needs: android-build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Download artifact
uses: actions/download-artifact@v2
with:
name: built-apk
path: dist/
- name: Upload to Android πŸ€– .apk to Firebase App Distribution
uses: w9jds/[email protected]
with:
args: appdistribution:distribute dist/rse.apk --app ${{ secrets.FIREBASE_APP_ID_ANDROID }} --groups ${{ vars.FIREBASE_TEST_GROUPS }}
env:
GCP_SA_KEY: ${{ secrets.FIREBASE_TOKEN }}
# A macOS machine needed to build IPA.
# We'd have reused several of the steps from above otherwise.
ios-build:
name: iOS 🍎 build
needs: setup
runs-on: macOS-latest
if: ${{ needs.setup.outputs.platform }} == 'ios'
steps:
- uses: actions/checkout@v3
- name: Install Java
uses: actions/setup-java@v2
with:
java-version: 11
distribution: zulu
- name: Install Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: 3.13.2
- name: Bump iOS 🍎 version name & code
uses: yanamura/ios-bump-version@v1
with:
version: 1.0.0
project-path: ios
build-number: ${{ github.run_number }}
- name: Install the Apple 🍎 certificate and provisioning profile
env:
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: Build iOS 🍎 IPA
run: |
flutter --version
flutter pub get
xcrun xcodebuild -showBuildSettings -workspace ./ios/Runner.xcworkspace -scheme Runner -configuration Release
flutter build ipa --export-options-plist ./ios/ExportOptions.plist
mkdir -p dist
mv ./build/ios/ipa/rse.ipa dist/rse.ipa
- name: Upload dSYMs to Crashlytics πŸ’₯
run: |
cd ios
Pods/FirebaseCrashlytics/upload-symbols -gsp ../ios/Runner/GoogleService-Info.plist -p ios ../build/ios/archive/Runner.xcarchive/dSYMs
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: built-ipa
path: dist
# A linux machine is needed for firebase app distribution action.
# Also helps for rerunning failing jobs due to misconfigured environment.
ios-distribute:
name: iOS 🍎 distribute
needs: ios-build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Download artifact
uses: actions/download-artifact@v2
with:
name: built-ipa
path: dist
- name: Upload to iOS 🍎 .ipa to Firebase App Distribution
uses: w9jds/[email protected]
with:
args: appdistribution:distribute dist/rse.ipa --app ${{ secrets.FIREBASE_APP_ID_IOS }} --groups ${{ vars.FIREBASE_TEST_GROUPS }}
env:
GCP_SA_KEY: ${{ secrets.FIREBASE_TOKEN }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment