build(ios): Codemagic pipeline + runbook for App Store (no Mac needed)

The iOS app is a Capacitor shell over the live web UI — the web/server side is already fully
Capacitor-ready (nativePlatform() detects Capacitor; setupNativePush registers APNs tokens via
/api/v1/devices; the APNs sender is built into server/push.js, config-gated). So this adds only
the build/sign/upload path:

- codemagic.yaml: macOS-cloud workflow that generates the iOS project, patches Info.plist,
  generates icons/splash, signs via an App Store Connect API key (automatic signing), archives,
  and uploads to TestFlight. No Mac required.
- mobile/scripts/ios-patch.sh: adds the App-Review privacy usage strings (camera/mic/photos) +
  display name to the generated Info.plist.
- mobile/IOS_SETUP.md: click-by-click runbook — ASC app record, API key, Codemagic integration,
  first build, APNs key → server .env, and the public-submission checklist.

Bundle id com.bizgaze.connect. No secrets committed — Apple keys live in Codemagic + server .env.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 16:45:10 +05:30
parent c8f383cbcb
commit bc909cb0c0
3 changed files with 173 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
# Codemagic CI/CD — builds the Biz Connect iOS app (Capacitor shell over the live web UI) and uploads it
# to TestFlight / App Store Connect. No Mac needed: this runs on Codemagic's macOS cloud instances.
#
# The app is a thin Capacitor wrapper that loads https://remote.bizgaze.com, so there's no bundled web
# code to build here — we generate the iOS project, patch its privacy strings, sign, archive and upload.
#
# ── One-time setup (see mobile/IOS_SETUP.md for the click-by-click) ────────────────────────────────
# 1. App Store Connect: create the app with bundle id com.bizgaze.connect
# 2. Codemagic → Teams/Integrations → App Store Connect: add your ASC API key (issuer id, key id, .p8).
# Name the integration exactly: BizGaze App Store Connect
# 3. That's it — automatic code signing fetches/creates the distribution cert + profile from that key.
workflows:
ios-testflight:
name: Biz Connect iOS → TestFlight
max_build_duration: 60
instance_type: mac_mini_m2
integrations:
app_store_connect: BizGaze App Store Connect # ← must match the integration name you create
environment:
ios_signing:
distribution_type: app_store
bundle_identifier: com.bizgaze.connect
vars:
BUNDLE_ID: "com.bizgaze.connect"
XCODE_WORKSPACE: "mobile/ios/App/App.xcworkspace"
XCODE_SCHEME: "App"
node: 20
xcode: latest
cocoapods: default
scripts:
- name: Install JS dependencies
script: |
cd mobile
npm ci
- name: Generate the iOS project (Capacitor)
script: |
cd mobile
# `cap add ios` scaffolds ios/App; safe to re-run — it no-ops if it already exists.
if [ ! -d "ios" ]; then npx cap add ios; fi
npx cap sync ios
# App icon + splash from resources/icon.png & resources/splash*.png (1024x1024 icon, 2732² splash).
npx capacitor-assets generate --ios || echo "asset generation skipped"
- name: Patch Info.plist (App-Review privacy strings) + bundle id
script: |
bash mobile/scripts/ios-patch.sh
- name: Set up code signing
script: |
# Automatic signing via the App Store Connect API key configured in the integration above.
keychain initialize
app-store-connect fetch-signing-files "$BUNDLE_ID" \
--type IOS_APP_STORE --create
keychain add-certificates
xcode-project use-profiles
- name: Install CocoaPods
script: |
cd mobile/ios/App
pod install
- name: Build the signed IPA
script: |
xcode-project build-ipa \
--workspace "$XCODE_WORKSPACE" \
--scheme "$XCODE_SCHEME"
artifacts:
- build/ios/ipa/*.ipa
- /tmp/xcodebuild_logs/*.log
publishing:
app_store_connect:
auth: integration
submit_to_testflight: true
# Flip this to true (and add a `submit_to_app_store` group with reviewer notes) once you're ready
# to push a build to public App Store review instead of only TestFlight.
# submit_to_app_store: false
email:
recipients:
- sriramphanib@gmail.com
notify:
success: true
failure: true