apps/ios/fastlane/SETUP.md
Install:
brew install fastlane
Create an App Store Connect API key:
.p8, note the Issuer ID and Key IDRecommended (macOS): store the private key in Keychain and write non-secret vars:
scripts/ios-asc-keychain-setup.sh \
--key-path /absolute/path/to/AuthKey_XXXXXXXXXX.p8 \
--issuer-id YOUR_ISSUER_ID \
--write-env
This writes these auth variables in apps/ios/fastlane/.env:
ASC_KEY_ID=YOUR_KEY_ID
ASC_ISSUER_ID=YOUR_ISSUER_ID
ASC_KEYCHAIN_SERVICE=openclaw-asc-key
ASC_KEYCHAIN_ACCOUNT=YOUR_MAC_USERNAME
Important: apps/ios/fastlane/.env is only for Fastlane/App Store Connect auth and optional beta-archive settings. It does not configure gateway-side direct APNs push delivery for local iOS builds.
Optional app targeting variables (helpful if Fastlane cannot auto-resolve app by bundle):
ASC_APP_IDENTIFIER=ai.openclaw.client
# or
ASC_APP_ID=YOUR_APP_STORE_CONNECT_APP_ID
File-based fallback (CI/non-macOS):
ASC_KEY_ID=YOUR_KEY_ID
ASC_ISSUER_ID=YOUR_ISSUER_ID
ASC_KEY_PATH=/absolute/path/to/AuthKey_XXXXXXXXXX.p8
Code signing variable (optional in .env):
IOS_DEVELOPMENT_TEAM=YOUR_TEAM_ID
Tip: run scripts/ios-team-id.sh from repo root to print a Team ID for .env. The helper prefers the canonical OpenClaw team (Y5PE65HELJ) when present locally; otherwise it prefers the first non-personal team from your Xcode account (then personal team if needed). Fastlane uses this helper automatically if IOS_DEVELOPMENT_TEAM is missing.
For local/manual iOS builds that stay on direct APNs, configure the gateway host separately with OPENCLAW_APNS_TEAM_ID, OPENCLAW_APNS_KEY_ID, and either OPENCLAW_APNS_PRIVATE_KEY_P8 or OPENCLAW_APNS_PRIVATE_KEY_PATH. Those gateway runtime env vars are separate from Fastlane's .env.
Validate auth:
cd apps/ios
fastlane ios auth_check
ASC auth is only required when:
If you pass --build-number to pnpm ios:beta:archive, the local archive path does not need ASC auth.
Archive locally without upload:
pnpm ios:beta:archive
Upload to TestFlight:
pnpm ios:beta
Direct Fastlane entry point:
cd apps/ios
fastlane ios beta
Maintainer recovery path for a fresh clone on the same Mac:
apps/ios/fastlane/.env so it contains the non-secret variables:ASC_KEY_ID=YOUR_KEY_ID
ASC_ISSUER_ID=YOUR_ISSUER_ID
ASC_KEYCHAIN_SERVICE=openclaw-asc-key
ASC_KEYCHAIN_ACCOUNT=YOUR_MAC_USERNAME
cd apps/ios
fastlane ios auth_check
pnpm ios:version:pin -- --from-gateway
export OPENCLAW_PUSH_RELAY_BASE_URL=https://relay.example.com
pnpm ios:beta
Quick verification after upload:
apps/ios/build/beta/OpenClaw-<version>.ipa existsUploaded iOS beta: version=<version> short=<short> build=<build>Versioning rules:
apps/ios/version.json is the pinned iOS release version sourceapps/ios/CHANGELOG.md is the iOS-only changelog and release-note sourceYYYY.M.Dpnpm ios:version:pin -- --from-gateway promotes the current root gateway version into the pinned iOS release versionpackage.json.version alone does not change the iOS app versionCFBundleShortVersionString to the pinned iOS version, for example 2026.4.10CFBundleVersion as the next integer TestFlight build number for that short versionpnpm ios:version:sync after changing apps/ios/version.json or apps/ios/CHANGELOG.mdpnpm ios:version:check validates that checked-in iOS version artifacts are in syncapps/ios/OpenClaw.xcodeproj from apps/ios/project.yml before archivingapps/ios/VERSIONING.md for the detailed workflow