[PM-9375] Build a debug-for-simulator version of the app for easier automated testing (#1151)

Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com>
This commit is contained in:
Katherine Bertelsen 2024-12-04 16:46:24 -06:00 committed by GitHub
parent e7b68a45bf
commit ec04d02405
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 135 additions and 59 deletions

View File

@ -123,3 +123,16 @@ jobs:
upload_version_info: false upload_version_info: false
compiler-flags: "DEBUG_MENU" compiler-flags: "DEBUG_MENU"
secrets: inherit secrets: inherit
build-simulator:
name: Build Simulator App
needs: resolve-values
uses: bitwarden/ios/.github/workflows/build.yml@main
with:
build-variant: Simulator
build-version: ${{ needs.resolve-values.outputs.version_name }}
build-number: ${{ needs.resolve-values.outputs.version_number }}
xcode-version: ${{ needs.resolve-values.outputs.xcode_version }}
distribute: false
upload_version_info: false
secrets: inherit

View File

@ -1,19 +0,0 @@
name: Build for Simulator
on:
workflow_dispatch:
inputs:
build-version:
description: "Unused"
jobs:
build:
name: Build
runs-on: macos-14
steps:
- name: Check out repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
fetch-depth: 0
filter: tree:0

View File

@ -11,6 +11,14 @@ on:
options: options:
- Beta - Beta
- Production - Production
build-mode:
description: "Build Mode"
required: true
default: "Device"
type: choice
options:
- Device
- Simulator
build-version: build-version:
description: "Version Name Override - e.g. '2024.8.1'" description: "Version Name Override - e.g. '2024.8.1'"
type: string type: string
@ -39,6 +47,9 @@ on:
build-variant: build-variant:
description: "Build Variant" description: "Build Variant"
type: string type: string
build-mode:
description: "Build Mode"
type: string
build-version: build-version:
description: "Version Name Override - e.g. '2024.8.1'" description: "Version Name Override - e.g. '2024.8.1'"
type: string type: string
@ -66,7 +77,9 @@ on:
type: boolean type: boolean
env: env:
_BUILD_VARIANT: ${{ inputs.build-variant || 'Beta' }} _BUILD_VARIANT: ${{ inputs.build-variant || 'Beta' }}
_BUILD_MODE: ${{ inputs.build-mode || 'Device' }}
_XCODE_VERSION: ${{ inputs.xcode-version }} _XCODE_VERSION: ${{ inputs.xcode-version }}
_COMPILER_FLAGS: ${{ inputs.compiler-flags }}
jobs: jobs:
build: build:
@ -134,12 +147,12 @@ jobs:
- name: Read default Xcode version - name: Read default Xcode version
run: | run: |
echo "DEFAULT_XCODE_VERSION=$(cat .xcode-version | tr -d '\n')" >> "$GITHUB_ENV" echo "_DEFAULT_XCODE_VERSION=$(cat .xcode-version | tr -d '\n')" >> "$GITHUB_ENV"
- name: Set Xcode version - name: Set Xcode version
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0 uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
with: with:
xcode-version: ${{ env._XCODE_VERSION || env.DEFAULT_XCODE_VERSION }} xcode-version: ${{ env._XCODE_VERSION || env._DEFAULT_XCODE_VERSION }}
- name: Cache Mint packages - name: Cache Mint packages
id: mint-cache id: mint-cache
@ -151,18 +164,20 @@ jobs:
${{ runner.os }}-mint- ${{ runner.os }}-mint-
- name: Log in to Azure - name: Log in to Azure
if: env._BUILD_MODE == 'Device'
uses: Azure/login@cb79c773a3cfa27f31f25eb3f677781210c9ce3d # v1.6.1 uses: Azure/login@cb79c773a3cfa27f31f25eb3f677781210c9ce3d # v1.6.1
with: with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets - name: Retrieve secrets
if: env._BUILD_MODE == 'Device'
uses: bitwarden/gh-actions/get-keyvault-secrets@main uses: bitwarden/gh-actions/get-keyvault-secrets@main
with: with:
keyvault: "bitwarden-ci" keyvault: "bitwarden-ci"
secrets: "appcenter-ios-token" secrets: "appcenter-ios-token"
- name: Retrieve production provisioning profiles - name: Retrieve production provisioning profiles
if: env._BUILD_VARIANT == 'Production' if: env._BUILD_VARIANT == 'Production' && env._BUILD_MODE == 'Device'
env: env:
ACCOUNT_NAME: bitwardenci ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: profiles CONTAINER_NAME: profiles
@ -185,7 +200,7 @@ jobs:
done done
- name: Retrieve beta provisioning profiles - name: Retrieve beta provisioning profiles
if: env._BUILD_VARIANT == 'Beta' if: env._BUILD_VARIANT == 'Beta' && env._BUILD_MODE == 'Device'
env: env:
ACCOUNT_NAME: bitwardenci ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: profiles CONTAINER_NAME: profiles
@ -208,7 +223,7 @@ jobs:
done done
- name: Retrieve production Google Services secret - name: Retrieve production Google Services secret
if: env._BUILD_VARIANT == 'Production' if: env._BUILD_VARIANT == 'Production' && env._BUILD_MODE == 'Device'
env: env:
ACCOUNT_NAME: bitwardenci ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile CONTAINER_NAME: mobile
@ -220,7 +235,7 @@ jobs:
--file Bitwarden/Application/Support/$TARGET_FILE --output none --file Bitwarden/Application/Support/$TARGET_FILE --output none
- name: Retrieve watch production Google Services secret - name: Retrieve watch production Google Services secret
if: env._BUILD_VARIANT == 'Production' if: env._BUILD_VARIANT == 'Production' && env._BUILD_MODE == 'Device'
env: env:
ACCOUNT_NAME: bitwardenci ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile CONTAINER_NAME: mobile
@ -233,7 +248,7 @@ jobs:
plutil -replace BUNDLE_ID -string com.8bit.bitwarden.watchkitapp BitwardenWatchApp/$TARGET_FILE plutil -replace BUNDLE_ID -string com.8bit.bitwarden.watchkitapp BitwardenWatchApp/$TARGET_FILE
- name: Retrieve beta Google Services secret - name: Retrieve beta Google Services secret
if: env._BUILD_VARIANT == 'Beta' if: env._BUILD_VARIANT == 'Beta' && env._BUILD_MODE == 'Device'
env: env:
ACCOUNT_NAME: bitwardenci ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile CONTAINER_NAME: mobile
@ -245,7 +260,7 @@ jobs:
--file Bitwarden/Application/Support/$TARGET_FILE --output none --file Bitwarden/Application/Support/$TARGET_FILE --output none
- name: Retrieve watch beta Google Services secret - name: Retrieve watch beta Google Services secret
if: env._BUILD_VARIANT == 'Beta' if: env._BUILD_VARIANT == 'Beta' && env._BUILD_MODE == 'Device'
env: env:
ACCOUNT_NAME: bitwardenci ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile CONTAINER_NAME: mobile
@ -258,12 +273,14 @@ jobs:
plutil -replace BUNDLE_ID -string com.8bit.bitwarden.beta.watchkitapp BitwardenWatchApp/$TARGET_FILE plutil -replace BUNDLE_ID -string com.8bit.bitwarden.beta.watchkitapp BitwardenWatchApp/$TARGET_FILE
- name: Retrieve certificates - name: Retrieve certificates
if: env._BUILD_MODE == 'Device'
run: | run: |
mkdir -p $HOME/certificates mkdir -p $HOME/certificates
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/ios-distribution | az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/ios-distribution |
jq -r .value | base64 -d > $HOME/certificates/ios-distribution.p12 jq -r .value | base64 -d > $HOME/certificates/ios-distribution.p12
- name: Download Fastlane credentials - name: Download Fastlane credentials
if: env._BUILD_MODE == 'Device'
env: env:
ACCOUNT_NAME: bitwardenci ACCOUNT_NAME: bitwardenci
CONTAINER_NAME: mobile CONTAINER_NAME: mobile
@ -274,6 +291,7 @@ jobs:
--file $HOME/secrets/$FILE --output none --file $HOME/secrets/$FILE --output none
- name: Configure Keychain Access - name: Configure Keychain Access
if: env._BUILD_MODE == 'Device'
env: env:
KEYCHAIN_PASSWORD: ${{ secrets.IOS_KEYCHAIN_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.IOS_KEYCHAIN_PASSWORD }}
run: | run: |
@ -287,6 +305,7 @@ jobs:
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain
- name: Configure provisioning profiles - name: Configure provisioning profiles
if: env._BUILD_MODE == 'Device'
run: | run: |
./Scripts/configure_provisioning_profiles.sh ${{ env._BUILD_VARIANT }} ./Scripts/configure_provisioning_profiles.sh ${{ env._BUILD_VARIANT }}
@ -301,18 +320,28 @@ jobs:
echo 'app_identifier "com.8bit.bitwarden.beta"' > fastlane/Appfile echo 'app_identifier "com.8bit.bitwarden.beta"' > fastlane/Appfile
- name: Update APNS entitlements - name: Update APNS entitlements
if: env._BUILD_MODE == 'Device'
run: | run: |
plutil -replace aps-environment -string production Bitwarden/Application/Support/Bitwarden.entitlements plutil -replace aps-environment -string production Bitwarden/Application/Support/Bitwarden.entitlements
- name: Configure Ruby - name: Configure Ruby
if: env._BUILD_MODE == 'Device'
uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0 uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc # v1.202.0
with: with:
bundler-cache: true bundler-cache: true
- name: Install Fastlane, Mint - name: Update homebrew
run: | run: |
brew update brew update
brew install fastlane mint
- name: Install Fastlane
if: env._BUILD_MODE == 'Device'
run: |
brew install fastlane
- name: Install Mint
run: |
brew install mint
- name: Install Mint packages - name: Install Mint packages
if: steps.mint-cache.outputs.cache-hit != 'true' if: steps.mint-cache.outputs.cache-hit != 'true'
@ -321,7 +350,7 @@ jobs:
- name: Select variant - name: Select variant
run: | run: |
./Scripts/select_variant.sh ${{ env._BUILD_VARIANT }} "${{ inputs.compiler-flags }}" ./Scripts/select_variant.sh ${{ env._BUILD_VARIANT }} "${{ env._COMPILER_FLAGS }}"
- name: Update build version and number - name: Update build version and number
run: | run: |
@ -330,26 +359,39 @@ jobs:
- name: Update CI build info - name: Update CI build info
run: | run: |
./Scripts/update_app_ci_build_info.sh ${{ github.run_id }} ${{ github.run_number }} ${{ github.run_attempt }} "${{ inputs.compiler-flags }}" ./Scripts/update_app_ci_build_info.sh ${{ github.run_id }} ${{ github.run_number }} ${{ github.run_attempt }} "${{ env._COMPILER_FLAGS }}"
- name: Build iOS app - name: Build iOS app
run: | run: |
./Scripts/build.sh ./Scripts/build.sh ${{ env._BUILD_MODE }}
- name: Prepare IPA & dSYM files for upload to GitHub - name: Prepare artifacts for upload to GitHub
run: | run: |
mkdir -p export
case "$_BUILD_MODE" in
"Simulator")
cp -r build/DerivedData/Build/Products/Debug-iphonesimulator/Bitwarden.app export
;;
"Device")
mkdir -p export/dSYMs mkdir -p export/dSYMs
cp build/Bitwarden/Bitwarden.ipa export cp build/Bitwarden/Bitwarden.ipa export
cp -rv build/Bitwarden.xcarchive/dSYMs/*.dSYM export/dSYMs cp -rv build/Bitwarden.xcarchive/dSYMs/*.dSYM export/dSYMs
;;
*)
echo "Error: Invalid BUILD_MODE '$_BUILD_MODE'"
exit 1
;;
esac
- name: Upload IPA & dSYM files - name: Upload artifacts to GitHub
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with: with:
name: Bitwarden iOS ${{ steps.version_info.outputs.version_name }} (${{ steps.version_info.outputs.version_number }}) ${{ env._BUILD_VARIANT }} ${{ env._XCODE_VERSION || env.DEFAULT_XCODE_VERSION }} name: Bitwarden iOS ${{ steps.version_info.outputs.version_name }} (${{ steps.version_info.outputs.version_number }}) ${{ env._BUILD_VARIANT }} ${{ env._XCODE_VERSION || env.DEFAULT_XCODE_VERSION }} ${{ env._BUILD_MODE }} ${{ env._COMPILER_FLAGS }}
path: export path: export
if-no-files-found: error if-no-files-found: error
- name: Set up private auth key - name: Set up private auth key
if: env._BUILD_MODE == 'Device'
run: | run: |
mkdir ~/private_keys mkdir ~/private_keys
cat << EOF > ~/private_keys/AuthKey_J46C83CB96.p8 cat << EOF > ~/private_keys/AuthKey_J46C83CB96.p8
@ -357,6 +399,7 @@ jobs:
EOF EOF
- name: Validate app with App Store Connect - name: Validate app with App Store Connect
if: env._BUILD_MODE == 'Device'
run: | run: |
xcrun altool --validate-app \ xcrun altool --validate-app \
--type ios \ --type ios \
@ -365,7 +408,7 @@ jobs:
--apiIssuer "${{ secrets.APP_STORE_CONNECT_TEAM_ISSUER }}" --apiIssuer "${{ secrets.APP_STORE_CONNECT_TEAM_ISSUER }}"
- name: Upload app to TestFlight with Fastlane - name: Upload app to TestFlight with Fastlane
if: ${{ inputs.distribute }} if: ${{ inputs.distribute && env._BUILD_MODE == 'Device' }}
run: | run: |
CHANGELOG="$(git show -s --format=%s) CHANGELOG="$(git show -s --format=%s)
$GITHUB_REPOSITORY/$GITHUB_REF_NAME @ $GITHUB_SHA $GITHUB_REPOSITORY/$GITHUB_REF_NAME @ $GITHUB_SHA

View File

@ -1,43 +1,82 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# #
# Builds the beta Bitwarden iOS app, and outputs an IPA file that can be uploaded to TestFlight. # Builds the Bitwarden iOS app.
# If run in Simulator mode, produces an APP file for the iOS Simulator for ease of automated testing.
# If run in Device mode, produces an IPA file that can be uploaded to TestFlight.
# #
# Usage: # Usage:
# #
# $ ./build.sh # $ ./build.sh <build_mode>
#
# Where mode is one of:
# - Device: Build for physical iOS devices
# - Simulator: Build for iOS Simulator
set -euo pipefail set -euo pipefail
bold=$(tput -T ansi bold) bold=$(tput -T ansi bold)
normal=$(tput -T ansi sgr0) normal=$(tput -T ansi sgr0)
BUILD_DIR="build" if [ $# -lt 1 ]; then
echo >&2 "Called without necessary arguments: ${bold}mode${normal}"
echo >&2 "For example: \`Scripts/build.sh Simulator"
exit 1
fi
MODE=$1
BUILD_DIR="build"
DERIVED_DATA_PATH="${BUILD_DIR}/DerivedData"
ARCHIVE_PATH="${BUILD_DIR}/Bitwarden.xcarchive" ARCHIVE_PATH="${BUILD_DIR}/Bitwarden.xcarchive"
EXPORT_PATH="${BUILD_DIR}/Bitwarden" EXPORT_PATH="${BUILD_DIR}/Bitwarden"
echo "🧱 Building in $(pwd)" echo "🧱 Building in ${bold}$(pwd)${normal}"
echo "🧱 Using build mode of ${bold}${MODE}${normal}."
echo "🧱 Derived Data path ${bold}${DERIVED_DATA_PATH}${normal}"
echo "🧱 Archive path ${bold}${ARCHIVE_PATH}${normal}"
echo "🧱 Export path ${bold}${EXPORT_PATH}${normal}"
echo "" echo ""
echo "🌱 Generating xcode project" echo "🌱 Generating Xcode project"
mint run xcodegen mint run xcodegen
echo ""
mkdir -p "${BUILD_DIR}" mkdir -p "${BUILD_DIR}"
echo "🔨 Performing Xcode archive" case "$MODE" in
"Simulator")
echo "🔨 Performing Xcode build"
xcrun xcodebuild \
-project Bitwarden.xcodeproj \
-scheme Bitwarden \
-configuration Debug \
-destination "generic/platform=iOS Simulator" \
-derivedDataPath "${DERIVED_DATA_PATH}" \
| xcbeautify --renderer github-actions
;;
"Device")
echo "📦 Performing Xcode archive"
xcrun xcodebuild archive \ xcrun xcodebuild archive \
-project Bitwarden.xcodeproj \ -project Bitwarden.xcodeproj \
-scheme Bitwarden \ -scheme Bitwarden \
-configuration Release \ -configuration Release \
-archivePath "${ARCHIVE_PATH}" \ -archivePath "${ARCHIVE_PATH}" \
-derivedDataPath "${DERIVED_DATA_PATH}" \
| xcbeautify --renderer github-actions | xcbeautify --renderer github-actions
echo ""
echo "📦 Performing Xcode archive export" echo "🚚 Performing Xcode archive export"
xcrun xcodebuild -exportArchive \ xcrun xcodebuild -exportArchive \
-archivePath "${ARCHIVE_PATH}" \ -archivePath "${ARCHIVE_PATH}" \
-exportPath "${EXPORT_PATH}" \ -exportPath "${EXPORT_PATH}" \
-exportOptionsPlist "Configs/export_options.plist" \ -exportOptionsPlist "Configs/export_options.plist" \
| xcbeautify --renderer github-actions | xcbeautify --renderer github-actions
;;
*)
echo >&2 "Invalid build mode: ${bold}${MODE}${normal}"
echo >&2 "Must be one of: Simulator, Device"
exit 1
;;
esac
echo ""
echo "🎉 Build complete" echo "🎉 Build complete"