Skip to content

Build Mobile App

Build Mobile App #68

name: Build Mobile App
on:
workflow_dispatch:
push:
branches: [ main ]
paths:
- "DevExMobileTestApp/**"
env:
# The build number is based on github.run_number. However, the build number used by the app
# is already higher than that number. It throws an error because the number has already been used
# So, the number has too be offset past that value
VERSION_NUM_OFFSET: 10
jobs:
build-android:
name: Build and sign android bundle
runs-on: ubuntu-latest
defaults:
run:
working-directory: DevExMobileTestApp
env:
KEYSTORE_FILE: android/app/release.keystore
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
cache: 'yarn'
node-version: 19
cache-dependency-path: DevExMobileTestApp/yarn.lock
- name: Install node modules
run: |
yarn install --frozen-lockfile
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
build-root-directory: DevExMobileTestApp
- name: Decode keystore file
env:
UPLOAD_KEYSTORE: ${{ secrets.ANDROID_UPLOAD_KEYSTORE_BASE64 }}
run: |
echo "${UPLOAD_KEYSTORE}" | base64 -d > ${KEYSTORE_FILE}
- name: run number with offset
env:
NUM: ${{ github.run_number }}
run: |
echo "GITHUB_RUN_NUMBER_WITH_OFFSET=$(($NUM + $VERSION_NUM_OFFSET))" >> $GITHUB_ENV
- name: Sign app
env:
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_SIGNING_KEY_PASSWORD: ${{ secrets.ANDROID_SIGNING_KEY_PASSWORD }}
ANDROID_SIGNING_STORE_PASSWORD: ${{ secrets.ANDROID_SIGNING_STORE_PASSWORD }}
VERSION_CODE: ${{ env.GITHUB_RUN_NUMBER_WITH_OFFSET }}
run: |
npx react-native build-android --mode=release
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: android-release
path: DevExMobileTestApp/android/app/build/outputs/bundle/release/app-release.aab
if-no-files-found: error
retention-days: 1
# - name: Setup JFrog CLI
# uses: jfrog/setup-jfrog-cli@v4
# with:
# disable-job-summary: true
# env:
# JF_PROJECT: ${{ vars.ARTIFACTORY_PROJECT }}
# JF_URL: ${{ vars.ARTIFACTORY_URL }}
# JF_USER: ${{ secrets.ARTIFACTORY_SERVICE_ACCOUNT_USER }}
# JF_PASSWORD: ${{ secrets.ARTIFACTORY_SERVICE_ACCOUNT_PWD }}
# - name: Push Build to Artifactory
# run: |
# export JFROG_CLI_LOG_LEVEL=DEBUG
# jf rt upload android/app/build/outputs/bundle/release/app-release.aab ${{ vars.ARTIFACTORY_REPO_NAME }}
build-ios:
name: Build and sign ios
runs-on: macos-latest
defaults:
run:
working-directory: DevExMobileTestApp/ios
env:
PROJECT: ${{ 'DevExMobileTestApp.xcworkspace' }}
SCHEME: ${{ 'DevExMobileTestApp' }}
DATA_DIR: ${{ 'xcbuild' }}
ARCHIVE_NAME: ${{ 'DevExMobileTestApp.xcarchive' }}
EXPORT_DIR: ${{ 'export' }}
IPA_NAME: ${{ 'DevExMobileTestApp.ipa' }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Xcode version
uses: maxim-lobanov/[email protected]
with:
xcode-version: '15.2'
- name: Display XCode Path for debug
run: |
xcode-select -p
- name: Cache Pods
uses: actions/cache@v4
with:
path: DevExMobileTestApp/ios/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: Setup Node.js environment
uses: actions/setup-node@v4
with:
cache: 'yarn'
node-version: 19
cache-dependency-path: DevExMobileTestApp/yarn.lock
- name: Install node modules
working-directory: DevExMobileTestApp
run: |
yarn install --frozen-lockfile
- name: CocoaPod Install
run: pod install
# from https://docs.github.com/en/enterprise-cloud@latest/actions/deployment/deploying-xcode-applications/installing-an-apple-certificate-on-macos-runners-for-xcode-development
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_APP_STORE_BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.APPLE_APP_STORE_BUILD_CERTIFICATE_PASSWD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.IOS_PROVISION_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
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: run number with offset
env:
NUM: ${{ github.run_number }}
run: |
echo "GITHUB_RUN_NUMBER_WITH_OFFSET=$(($NUM + $VERSION_NUM_OFFSET))" >> $GITHUB_ENV
- name: Increment Build No.
env:
BUILD_NO: ${{ env.GITHUB_RUN_NUMBER_WITH_OFFSET }}
run: |
# Set Build Number. Not worrying about storing to repo.
agvtool new-version -all ${BUILD_NO}
- name: Build For Release
run: |
xcodebuild \
-workspace $PROJECT \
-scheme $SCHEME \
-configuration Release \
-sdk iphoneos \
-derivedDataPath $DATA_DIR \
-archivePath ${DATA_DIR}/${ARCHIVE_NAME} \
archive
- name: Export Archive
run: |
xcodebuild \
-exportArchive \
-archivePath ${DATA_DIR}/${ARCHIVE_NAME} \
-exportPath $EXPORT_DIR \
-exportOptionsPlist exportOptions.plist \
-verbose
- name: Upload a Build Artifact
uses: actions/upload-artifact@v3
with:
name: ios-release
path: DevExMobileTestApp/ios/${{ env.EXPORT_DIR }}
if-no-files-found: error
retention-days: 1
# - name: Setup JFrog CLI
# uses: jfrog/setup-jfrog-cli@v4
# with:
# disable-job-summary: true
# env:
# JF_PROJECT: ${{ vars.ARTIFACTORY_PROJECT }}
# JF_URL: ${{ vars.ARTIFACTORY_URL }}
# JF_USER: ${{ secrets.ARTIFACTORY_SERVICE_ACCOUNT_USER }}
# JF_PASSWORD: ${{ secrets.ARTIFACTORY_SERVICE_ACCOUNT_PWD }}
# - name: Push Build to Artifactory
# run: |
# export JFROG_CLI_LOG_LEVEL=DEBUG
# jf rt upload "$EXPORT_DIR/*" ${{ vars.ARTIFACTORY_REPO_NAME }}