Skip to content

feat(mobile): Capacitor app (iOS + Android) + mobile-responsive fixes #3

feat(mobile): Capacitor app (iOS + Android) + mobile-responsive fixes

feat(mobile): Capacitor app (iOS + Android) + mobile-responsive fixes #3

Workflow file for this run

name: Build iOS App
concurrency:
group: Build-iOS-App-${{ github.workflow }}-${{ github.head_ref || github.event.workflow_run.head_branch || github.run_id }}
cancel-in-progress: true
on:
merge_group:
pull_request:
branches:
- main
- "release/**"
paths:
- "mobile/**"
- ".github/workflows/pr-ios-build.yml"
push:
tags:
- "v*.*.*"
permissions:
contents: read
jobs:
# PR / merge-group / tag: verify the app compiles for the simulator (no signing).
build-ios:
name: Build iOS (simulator)
runs-on: macos-15
timeout-minutes: 45
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
- name: Install XcodeGen
run: brew install xcodegen
- name: Generate Xcode project
working-directory: ./mobile
run: xcodegen generate
- name: Build (iphonesimulator, unsigned)
working-directory: ./mobile
run: |
xcodebuild \
-project Onyx.xcodeproj \
-scheme Onyx \
-sdk iphonesimulator \
-configuration Debug \
-derivedDataPath build \
-destination 'generic/platform=iOS Simulator' \
CODE_SIGNING_ALLOWED=NO \
build
- name: Upload build artifacts
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: ios-build-${{ github.run_id }}
path: |
mobile/build/Build/Products/Debug-iphonesimulator/Onyx.app
retention-days: 7
if-no-files-found: ignore
# Release: on a semver tag (excluding beta), build a signed archive and upload to
# TestFlight. Reuses the desktop signing setup (deployment.yml): Apple secrets pulled
# from AWS Secrets Manager via OIDC, certificate imported into a keychain. iOS App
# Store distribution also needs a provisioning profile, stored alongside the existing
# deploy/apple-* secrets as deploy/apple-ios-provisioning-profile.
release-ios:
name: Release iOS (TestFlight)
needs: build-ios
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'beta')
runs-on: macos-15
timeout-minutes: 60
permissions:
contents: read
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37
with:
role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }}
aws-region: us-east-2
- name: Get AWS Secrets
uses: aws-actions/aws-secretsmanager-get-secrets@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802
with:
secret-ids: |
APPLE_ID, deploy/apple-id
APPLE_PASSWORD, deploy/apple-password
APPLE_CERTIFICATE, deploy/apple-certificate
APPLE_CERTIFICATE_PASSWORD, deploy/apple-certificate-password
KEYCHAIN_PASSWORD, deploy/keychain-password
APPLE_TEAM_ID, deploy/apple-team-id
APPLE_IOS_PROVISIONING_PROFILE, deploy/apple-ios-provisioning-profile
parse-json-secrets: true
- name: Install XcodeGen
run: brew install xcodegen
- name: Generate Xcode project
working-directory: ./mobile
run: xcodegen generate
- name: Import Apple Developer Certificate
run: |
echo "$APPLE_CERTIFICATE" | base64 --decode > certificate.p12
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
security set-keychain-settings -t 3600 -u build.keychain
security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
security find-identity -v -p codesigning build.keychain
- name: Resolve signing identity
run: |
CERT_INFO=$(security find-identity -v -p codesigning build.keychain | grep -E "(Apple Distribution|iPhone Distribution)" | head -n 1)
CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}')
echo "CERT_ID=$CERT_ID" >> "$GITHUB_ENV"
- name: Install provisioning profile
run: |
mkdir -p "$HOME/Library/MobileDevice/Provisioning Profiles"
echo "$APPLE_IOS_PROVISIONING_PROFILE" | base64 --decode > profile.mobileprovision
PLIST=$(security cms -D -i profile.mobileprovision)
UUID=$(/usr/libexec/PlistBuddy -c "Print :UUID" /dev/stdin <<< "$PLIST")
NAME=$(/usr/libexec/PlistBuddy -c "Print :Name" /dev/stdin <<< "$PLIST")
cp profile.mobileprovision "$HOME/Library/MobileDevice/Provisioning Profiles/$UUID.mobileprovision"
echo "PROFILE_NAME=$NAME" >> "$GITHUB_ENV"
- name: Generate ExportOptions.plist
working-directory: ./mobile
run: |
cat > ExportOptions.plist <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key><string>app-store</string>
<key>destination</key><string>export</string>
<key>teamID</key><string>${APPLE_TEAM_ID}</string>
<key>signingStyle</key><string>manual</string>
<key>signingCertificate</key><string>${CERT_ID}</string>
<key>provisioningProfiles</key>
<dict>
<key>app.onyx.ios</key><string>${PROFILE_NAME}</string>
</dict>
<key>uploadSymbols</key><true/>
</dict>
</plist>
PLIST
- name: Archive (device, signed)
working-directory: ./mobile
run: |
xcodebuild \
-project Onyx.xcodeproj \
-scheme Onyx \
-sdk iphoneos \
-configuration Release \
-archivePath build/Onyx.xcarchive \
CODE_SIGN_STYLE=Manual \
CODE_SIGN_IDENTITY="$CERT_ID" \
DEVELOPMENT_TEAM="$APPLE_TEAM_ID" \
PROVISIONING_PROFILE_SPECIFIER="$PROFILE_NAME" \
MARKETING_VERSION="${GITHUB_REF_NAME#v}" \
CURRENT_PROJECT_VERSION="$GITHUB_RUN_NUMBER" \
archive
- name: Export .ipa
working-directory: ./mobile
run: |
xcodebuild -exportArchive \
-archivePath build/Onyx.xcarchive \
-exportOptionsPlist ExportOptions.plist \
-exportPath build/export
- name: Upload to TestFlight
working-directory: ./mobile
run: |
IPA=$(find build/export -name "*.ipa" | head -1)
xcrun altool --upload-app --type ios \
--file "$IPA" \
--username "$APPLE_ID" \
--password "$APPLE_PASSWORD"