Skip to content

Build iOS

Build iOS #19

Workflow file for this run

name: Build iOS
# Controls when the workflow will run
on:
workflow_call:
inputs:
build_environment:
description: "Build Environment"
type: string
required: true
upload_to_app_store:
description: "Upload to App Store"
type: boolean
required: true
workflow_dispatch:
inputs:
build_environment:
description: "Build Environment"
type: choice
options:
- DEV
- TEST
- PROD
default: "development"
upload_to_app_store:
description: "Upload to App Store"
type: boolean
default: false
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
env:
ANGULAR_DIRECTORY: ./client/wfnews-war/src/main/angular
APP_CONFIG_FILE: ./client/wfnews-war/src/main/angular/src/assets/data/appConfig.mobile.json
runs-on: macos-latest
environment:
name: ${{ inputs.build_environment }}
steps:
- uses: actions/checkout@v3
- name: Set short git commit SHA
id: vars
if: always()
run: |
calculatedSha=$(git rev-parse --short ${{ github.sha }})
echo "::set-output name=short_sha::$calculatedSha"
- name: Add .npmrc file
working-directory: ${{ env.ANGULAR_DIRECTORY }}
env:
NPMRC: ${{ secrets.NPMRC }}
run: echo -e -n "$NPMRC" > .npmrc
- name: Get XML Info
id: version
uses: mavrosxristoforos/get-xml-info@1.1.1
with:
xml-file: "client/pom.xml"
xpath: "/*[local-name()='project']/*[local-name()='version']"
- name: Replace tokens
uses: cschleiden/replace-tokens@v1.2
with:
files: ${{ env.APP_CONFIG_FILE }}
env:
# From config.jsp
AGOL_ACTIVE_FIRES: ${{ vars.AGOL_ACTIVE_FIRES }}
AGOL_AREA_RESTRICTIONS: ${{ vars.AGOL_AREA_RESTRICTIONS }}
AGOL_BANS_AND_PROHIBITIONS: ${{ vars.AGOL_BANS_AND_PROHIBITIONS }}
AGOL_EVAC_ORDERS: ${{ vars.AGOL_EVAC_ORDERS }}
AGOL_FIRE_CENTRES: ${{ vars.AGOL_FIRE_CENTRES }}
AGOL_PERIMETRES: ${{ vars.AGOL_PERIMETRES }}
AGOL_URL: ${{ vars.AGOL_URL }}
APP_STORE_URL: ${{ vars.APP_STORE_URL }}
APPLICATION_ACRONYM: ${{ vars.APPLICATION_ACRONYM }}
APPLICATION_ENVIRONMENT: ${{ vars.DEFAULT_APPLICATION_ENVIRONMENT }}
BASE_URL: ${{ vars.BASE_URL }}
BC_WILDFIRE_SUPPORT_PAGE: ${{ vars.BC_WILDFIRE_SUPPORT_PAGE }}
BUILD_NUMBER: ${{ github.run_number }}
BURN_REGISTRATION_LINE: ${{ vars.BURN_REGISTRATION_LINE }}
# CONFIG_IM_URL: ${{ vars.CONFIG_IM_URL }}
DRIVEBC_BASE_URL: ${{ vars.DRIVEBC_BASE_URL }}
FACEBOOK_URL: ${{ vars.FACEBOOK_URL }}
GOOGLE_PLAY_URL: ${{ vars.GOOGLE_PLAY_URL }}
LAZY_AUTHENTICATE: ${{ vars.LAZY_AUTHENTICATE }}
# MAP_ICONS_ICON_ANCHOR: ${{ vars.MAP_ICONS_ICON_ANCHOR }}
# MAP_ICONS_ICON_SIZE: ${{ vars.MAP_ICONS_ICON_SIZE }}
# MAP_ICONS_SHADOW_SIZE: ${{ vars.MAP_ICONS_SHADOW_SIZE }}
# MAP_ICONS_TOOLTIP_OFFSET: ${{ vars.MAP_ICONS_TOOLTIP_OFFSET }}
MORE_INFORMATION_LINK: ${{ vars.MORE_INFORMATION_LINK }}
OPENMAPS_BASE_URL: ${{ vars.OPENMAPS_BASE_URL }}
POINT_ID_URL: ${{ vars.POINT_ID_URL }}
PROJECT_VERSION: ${{ steps.version.outputs.info }}
REPORT_A_WILDFIRE_PHONE_LINE: ${{ vars.REPORT_A_WILDFIRE_PHONE_LINE }}
SITEMINDER_URL_PREFIX: ${{ vars.SITEMINDER_URL_PREFIX }}
TWITTER_URL: ${{ vars.TWITTER_URL }}
WEBADE_OAUTH2_AUTH_SCOPES: ${{ vars.WEBADE_OAUTH2_AUTH_SCOPES }}
WEBADE_OAUTH2_AUTHORIZE_URL: ${{ vars.WEBADE_OAUTH2_AUTHORIZE_URL }}
WEBADE_OAUTH2_CHECK_TOKEN_V2_URL: ${{ vars.WEBADE_OAUTH2_CHECK_TOKEN_URL }}
WEBADE_OAUTH2_CLIENT_ID: ${{ vars.WEBADE_OAUTH2_UI_CLIENT_ID }}
WEBADE_OAUTH2_ENABLE_CHECK_TOKEN: ${{ vars.WEBADE_OAUTH2_ENABLE_CHECK_TOKEN }}
WEBADE_OAUTH2_WFNEWS_REST_CLIENT_SECRET: ${{secrets.WEBADE_OAUTH2_WFNEWS_UI_CLIENT_SECRET}}
WFDM_API_URL: ${{ vars.WFDM_REST_URL }}
# WFDM_PROXY: ${{ vars.WFDM_PROXY }}
WFIM_API_URL: ${{ vars.WFIM_CLIENT_URL }}
WFNEWS_API_KEY: ${{ env.API_KEY }}
WFNEWS_API_URL: ${{ vars.WFNEWS_API_URL }}
WILDFIRE_INFORMATION_LINE: ${{ vars.WILDFIRE_INFORMATION_LINE }}
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'npm'
cache-dependency-path: '**/package.json'
- name: Configure ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7
bundler-cache: true
- name: Check Xcode version
run: /usr/bin/xcodebuild -version
- name: Install Ionic
run: npm install -g @ionic/cli
- name: Install app dependencies
working-directory: ${{ env.ANGULAR_DIRECTORY }}
run: |
export NODE_OPTIONS="--max_old_space_size=4096"
npm install --legacy-peer-deps
- name: Prepare app for build
working-directory: ${{ env.ANGULAR_DIRECTORY }}
run: ionic capacitor sync ios --configuration=mobile
- name: Add Google Services file
working-directory: "${{ env.ANGULAR_DIRECTORY }}/ios/App/App"
env:
GOOGLE_FILE: ${{ secrets.GOOGLE_SERVICE_INFO_PLIST_BASE64 }}
run: |
echo -n "$GOOGLE_FILE" | base64 --decode -o GoogleService-Info.plist
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
IOS_BUILD_CERTIFICATE_PASSWORD: ${{ secrets.IOS_BUILD_CERTIFICATE_PASSWD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_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 "$IOS_BUILD_CERTIFICATE_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 archive
working-directory: ${{ env.ANGULAR_DIRECTORY }}
run: |
xcodebuild -scheme "App" \
-workspace ./ios/App/App.xcworkspace \
-archivePath $RUNNER_TEMP/App.xcarchive \
-sdk iphoneos \
-configuration Release \
-destination generic/platform=iOS \
clean archive
- name: Export IPA
env:
EXPORT_OPTIONS_PLIST: ${{ secrets.EXPORT_OPTIONS_PLIST }}
run: |
EXPORT_OPTS_PATH=$RUNNER_TEMP/ExportOptions.plist
echo -n "$EXPORT_OPTIONS_PLIST" | base64 --decode -o $EXPORT_OPTS_PATH
xcodebuild -exportArchive -archivePath $RUNNER_TEMP/App.xcarchive -exportOptionsPlist $EXPORT_OPTS_PATH -exportPath $RUNNER_TEMP/build
- name: Upload IPA
uses: actions/upload-artifact@v3
with:
name: app
path: ${{ runner.temp }}/build/App.ipa
retention-days: 3
- name: "Upload app to TestFlight"
uses: apple-actions/upload-testflight-build@v1
if: ${{ inputs.upload_to_app_store == true }}
with:
app-path: ${{ runner.temp }}/build/App.ipa
issuer-id: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
api-key-id: ${{ secrets.APP_STORE_CONNECT_KEY_IDENTIFIER_95 }}
api-private-key: ${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY_95 }}
- name: Post to a Slack channel
id: slack
if: always()
uses: slackapi/slack-github-action@v1.24.0
env:
STATUS_EMOJI: ${{ job.status == 'success' && ':white_check_mark:' || ':x:' }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
with:
# Slack channel id, channel name, or user id to post message.
# See also: https://api.slack.com/methods/chat.postMessage#channels
# You can pass in multiple channels to post to by providing a comma-delimited list of channel IDs.
channel-id: "wildfire-build-notifier"
slack-message: ":apple_mac: - ${{ steps.vars.outputs.short_sha }} : ${{ env.STATUS_EMOJI }} ${{ job.status }} \n Environment: ${{ inputs.build_environment }} \n Upload to App Store: ${{ inputs.upload_to_app_store }}"