Fastlane
Automate iOS and macOS builds, code signing, TestFlight distribution, and App Store submissions — all from one-off CLI commands. No Fastfile required.
Verify Installation
fastlane --version
If not installed:
brew install fastlane
Or via RubyGems:
sudo gem install fastlane -NV
After install, add to your shell profile:
export PATH="$HOME/.fastlane/bin:$PATH"
Authentication
App Store Connect API Key (Preferred)
API keys avoid 2FA prompts and are the recommended approach for automation and CI.
- Generate a key at App Store Connect → Users and Access → Keys.
- Download the
.p8file. - Set environment variables:
export APP_STORE_CONNECT_API_KEY_KEY_ID="XXXXXXXXXX"
export APP_STORE_CONNECT_API_KEY_ISSUER_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export APP_STORE_CONNECT_API_KEY_KEY_FILEPATH="/path/to/AuthKey_XXXXXXXXXX.p8"
Or pass the key inline as JSON:
export APP_STORE_CONNECT_API_KEY_KEY='{"key_id":"XXXXXXXXXX","issuer_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","key_filepath":"/path/to/AuthKey.p8"}'
Agent guidance: Always prefer API key authentication. Only fall back to Apple ID when the user explicitly does not have API key access.
Apple ID Fallback
export FASTLANE_USER="user@example.com"
export FASTLANE_PASSWORD="app-specific-password"
Generate an app-specific password at appleid.apple.com. If 2FA is enabled, you may also need:
export FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx"
export SPACESHIP_2FA_SMS_DEFAULT_PHONE_NUMBER="+1 (xxx) xxx-xxxx"
Environment Variables — Authentication Reference
| Variable | Purpose |
|---|---|
APP_STORE_CONNECT_API_KEY_KEY_ID | API key ID from App Store Connect |
APP_STORE_CONNECT_API_KEY_ISSUER_ID | Issuer ID from App Store Connect |
APP_STORE_CONNECT_API_KEY_KEY_FILEPATH | Path to the .p8 private key file |
APP_STORE_CONNECT_API_KEY_KEY | Inline JSON containing all key fields |
FASTLANE_USER | Apple ID email |
FASTLANE_PASSWORD | Apple ID password or app-specific password |
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD | App-specific password for 2FA accounts |
MATCH_PASSWORD | Encryption password for match certificates repo |
MATCH_GIT_URL | Git URL for match certificates repository |
One-Off Action Execution
Fastlane actions can be run directly from the CLI without a Fastfile:
fastlane run <action_name> key:value key2:value2
Discover available actions:
fastlane actions # List all actions
fastlane action <action_name> # Show details for one action
fastlane search_actions <query> # Search by keyword
Agent guidance: Use
fastlane run <action>for one-off tasks. This is the core pattern — every section below shows both the shorthand tool command and thefastlane runequivalent.
pilot (TestFlight)
Upload a Build to TestFlight
fastlane pilot upload --ipa "/path/to/App.ipa"
Equivalent:
fastlane run upload_to_testflight ipa:"/path/to/App.ipa"
With API key:
fastlane pilot upload \
--ipa "/path/to/App.ipa" \
--api_key_path "/path/to/api_key.json"
List Builds
fastlane pilot builds
Manage Testers
# Add a tester
fastlane pilot add email:"tester@example.com" group_name:"Beta Testers"
# Remove a tester
fastlane pilot remove email:"tester@example.com"
# List testers
fastlane pilot list
Distribute to External Testers
fastlane pilot distribute \
--build_number "42" \
--groups "External Beta" \
--changelog "Bug fixes and performance improvements"
Common pilot Flags
| Flag | Purpose |
|---|---|
--ipa | Path to IPA file |
--app_identifier | Bundle ID (e.g., com.example.app) |
--skip_waiting_for_build_processing | Don't wait for Apple's processing |
--distribute_external | Send to external testers |
--groups | Tester group names (comma-separated) |
--changelog | What to Test text |
--beta_app_review_info | JSON with review info |
deliver (App Store)
Submit to App Store
fastlane deliver --ipa "/path/to/App.ipa" --submit_for_review
Equivalent:
fastlane run upload_to_app_store ipa:"/path/to/App.ipa" submit_for_review:true
Upload Metadata Only
fastlane deliver --skip_binary_upload --skip_screenshots
Upload Screenshots Only
fastlane deliver --skip_binary_upload --skip_metadata
Download Existing Metadata
fastlane deliver download_metadata --app_identifier "com.example.app"
Download Existing Screenshots
fastlane deliver download_screenshots --app_identifier "com.example.app"
Common deliver Flags
| Flag | Purpose |
|---|---|
--ipa | Path to IPA file |
--pkg | Path to PKG file (macOS) |
--app_identifier | Bundle ID |
--submit_for_review | Auto-submit after upload |
--automatic_release | Release automatically after approval |
--force | Skip HTML preview verification |
--skip_binary_upload | Metadata/screenshots only |
--skip_metadata | Binary/screenshots only |
--skip_screenshots | Binary/metadata only |
--metadata_path | Custom metadata folder path |
--screenshots_path | Custom screenshots folder path |
--phased_release | Enable phased release |
--reject_if_possible | Reject current version before uploading |
gym / build_app (Build)
Build an IPA
fastlane gym \
--workspace "App.xcworkspace" \
--scheme "App" \
--export_method "app-store" \
--output_directory "./build"
Equivalent:
fastlane run build_app \
workspace:"App.xcworkspace" \
scheme:"App" \
export_method:"app-store" \
output_directory:"./build"
Build with Xcode Project (no workspace)
fastlane gym \
--project "App.xcodeproj" \
--scheme "App" \
--export_method "app-store"
Export Methods
| Method | Use Case |
|---|---|
app-store | App Store and TestFlight submission |
ad-hoc | Direct device installation via profile |
development | Debug builds for registered devices |
enterprise | In-house enterprise distribution |
developer-id | macOS distribution outside App Store |
mac-application | macOS App Store |
validation | Validate without exporting |
Common gym Flags
| Flag | Purpose |
|---|---|
--workspace | Path to .xcworkspace |
--project | Path to .xcodeproj |
--scheme | Build scheme |
--configuration | Build config (Debug/Release) |
--export_method | See export methods table |
--output_directory | Where to save the IPA |
--output_name | Custom IPA filename |
--clean | Clean before building |
--include_bitcode | Include bitcode |
--include_symbols | Include dSYM symbols |
--xcargs | Extra xcodebuild arguments |
--derived_data_path | Custom DerivedData path |
--catalyst_platform | macos or ios for Catalyst apps |
Agent guidance: If the project has a
.xcworkspace(e.g., uses CocoaPods or SPM), always use--workspace. Only use--projectwhen there is no workspace.
match (Code Signing)
Sync certificates and provisioning profiles from a shared Git repo or cloud storage.
Sync for App Store
fastlane match appstore --app_identifier "com.example.app"
Equivalent:
fastlane run sync_code_signing type:"appstore" app_identifier:"com.example.app"
Sync for Development
fastlane match development --app_identifier "com.example.app"
Sync for Ad Hoc
fastlane match adhoc --app_identifier "com.example.app"
Read-Only Mode (CI)
fastlane match appstore --readonly --app_identifier "com.example.app"
Agent guidance: Always use
--readonlyon CI servers. This prevents accidentally creating new certificates and disrupting the team.
Nuke (Reset All Certificates)
# Remove all certificates and profiles for a type
fastlane match nuke appstore
fastlane match nuke development
Warning: Nuke is destructive and irreversible. Always confirm with the user before running nuke commands.
Common match Flags
| Flag | Purpose |
|---|---|
--type | appstore, development, adhoc, enterprise |
--app_identifier | Bundle ID(s), comma-separated for multiple |
--git_url | Git repo URL for certificates |
--readonly | Don't create new certs/profiles |
--force | Renew existing profile |
--team_id | Apple Developer team ID |
--storage_mode | git, google_cloud, s3 |
--verbose | Detailed output |
Agent guidance: Prefer
matchovercert + sighfor teams. It centralizes signing and avoids the "works on my machine" problem.
scan / run_tests (Testing)
Run Tests
fastlane scan \
--workspace "App.xcworkspace" \
--scheme "AppTests" \
--device "iPhone 16 Pro"
Equivalent:
fastlane run run_tests \
workspace:"App.xcworkspace" \
scheme:"AppTests" \
device:"iPhone 16 Pro"
Run on Multiple Devices
fastlane scan \
--workspace "App.xcworkspace" \
--scheme "AppTests" \
--devices "iPhone 16 Pro,iPad Pro (13-inch) (M4)"
Output Formats
fastlane scan \
--scheme "AppTests" \
--output_types "html,junit" \
--output_directory "./test_results"
Common scan Flags
| Flag | Purpose |
|---|---|
--workspace | Path to .xcworkspace |
--project | Path to .xcodeproj |
--scheme | Test scheme |
--device | Simulator device name |
--devices | Multiple simulators (comma-separated) |
--output_types | html, junit, json |
--output_directory | Where to save results |
--code_coverage | Enable code coverage |
--clean | Clean before testing |
--fail_build | Fail on test failures (default: true) |
--xcargs | Extra xcodebuild arguments |
--result_bundle | Generate Xcode result bundle |
snapshot (Screenshots)
Capture App Store screenshots across devices and languages automatically.
Capture Screenshots
fastlane snapshot \
--workspace "App.xcworkspace" \
--scheme "AppUITests" \
--devices "iPhone 16 Pro Max,iPhone SE (3rd generation),iPad Pro (13-inch) (M4)" \
--languages "en-US,es-ES,fr-FR" \
--output_directory "./screenshots"
Equivalent:
fastlane run capture_screenshots \
workspace:"App.xcworkspace" \
scheme:"AppUITests" \
devices:"iPhone 16 Pro Max,iPhone SE (3rd generation),iPad Pro (13-inch) (M4)" \
languages:"en-US,es-ES,fr-FR" \
output_directory:"./screenshots"
Common snapshot Flags
| Flag | Purpose |
|---|---|
--workspace | Path to .xcworkspace |
--scheme | UI test scheme with snapshot calls |
--devices | Simulator names (comma-separated) |
--languages | Locale codes (comma-separated) |
--output_directory | Where to save screenshots |
--clear_previous_screenshots | Clean output folder first |
--stop_after_first_error | Abort on first failure |
--override_status_bar | Clean status bar (9:41, full battery) |
cert + sigh (Certificates & Profiles)
Standalone certificate and provisioning profile management.
Create/Fetch a Certificate
fastlane cert --development
fastlane cert # Distribution certificate by default
Equivalent:
fastlane run get_certificates development:true
Create/Fetch a Provisioning Profile
# App Store profile
fastlane sigh --app_identifier "com.example.app"
# Development profile
fastlane sigh --development --app_identifier "com.example.app"
# Ad hoc profile
fastlane sigh --adhoc --app_identifier "com.example.app"
Equivalent:
fastlane run get_provisioning_profile app_identifier:"com.example.app"
Repair Profiles
fastlane sigh repair
Common Flags
| Flag | Purpose |
|---|---|
--development | Development cert/profile |
--adhoc | Ad hoc profile |
--app_identifier | Bundle ID |
--team_id | Developer team ID |
--output_path | Where to save profile |
--force | Renew even if current is valid |
--readonly | Don't create, only fetch |
Agent guidance: For individual developers,
cert + sighworks fine. For teams, recommendmatchinstead — it prevents certificate conflicts.
precheck (Validation)
Validate app metadata before submitting to avoid App Store Review rejections.
fastlane precheck --app_identifier "com.example.app"
Equivalent:
fastlane run check_app_store_metadata app_identifier:"com.example.app"
What precheck Validates
- Unreachable URLs in metadata
- Mentions of other platforms (Android, etc.)
- Profanity or inappropriate content
- Placeholder text
- Copyright date accuracy
pem (Push Notification Certificates)
Generate push notification certificates for APNs.
fastlane pem --app_identifier "com.example.app" --output_path "./certs"
Equivalent:
fastlane run get_push_certificate app_identifier:"com.example.app" output_path:"./certs"
Common pem Flags
| Flag | Purpose |
|---|---|
--app_identifier | Bundle ID |
--output_path | Where to save certs |
--development | Development push cert |
--generate_p12 | Also generate .p12 file |
--p12_password | Password for .p12 |
--force | Create new even if existing is valid |
--team_id | Developer team ID |
Agent guidance: For modern projects using token-based APNs (
.p8key), push certs are unnecessary. Only usepemif the project specifically uses certificate-based APNs.
frameit (Screenshot Frames)
Add device bezels and titles to screenshots for App Store presentation.
fastlane frameit --path "./screenshots"
With titles:
fastlane frameit silver --path "./screenshots"
Equivalent:
fastlane run frame_screenshots path:"./screenshots"
A Framefile.json in the screenshots directory controls titles, fonts, and colors.
Common Workflows
Build + Upload to TestFlight
fastlane gym \
--workspace "App.xcworkspace" \
--scheme "App" \
--export_method "app-store" \
--output_directory "./build" && \
fastlane pilot upload \
--ipa "./build/App.ipa" \
--changelog "Latest build from CI"
Build + Submit to App Store
fastlane gym \
--workspace "App.xcworkspace" \
--scheme "App" \
--export_method "app-store" \
--output_directory "./build" && \
fastlane deliver \
--ipa "./build/App.ipa" \
--submit_for_review \
--automatic_release \
--force
Sync Signing + Build + Upload
fastlane match appstore \
--app_identifier "com.example.app" \
--readonly && \
fastlane gym \
--workspace "App.xcworkspace" \
--scheme "App" \
--export_method "app-store" \
--output_directory "./build" && \
fastlane pilot upload \
--ipa "./build/App.ipa"
Test + Build + Upload
fastlane scan \
--workspace "App.xcworkspace" \
--scheme "AppTests" && \
fastlane gym \
--workspace "App.xcworkspace" \
--scheme "App" \
--export_method "app-store" \
--output_directory "./build" && \
fastlane pilot upload \
--ipa "./build/App.ipa"
Screenshots + Frames + Upload
fastlane snapshot \
--workspace "App.xcworkspace" \
--scheme "AppUITests" \
--output_directory "./screenshots" && \
fastlane frameit silver --path "./screenshots" && \
fastlane deliver --skip_binary_upload --skip_metadata
Environment Variables
General
| Variable | Purpose |
|---|---|
FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT | Timeout for xcodebuild settings (seconds) |
FASTLANE_XCODEBUILD_SETTINGS_RETRIES | Retry count for xcodebuild |
FASTLANE_OPT_OUT_USAGE | Set to YES to disable analytics |
FL_OUTPUT_DIR | Default output directory |
FASTLANE_SKIP_UPDATE_CHECK | Skip update prompts |
FASTLANE_HIDE_TIMESTAMP | Hide log timestamps |
FASTLANE_DISABLE_COLORS | Disable colored output |
CI-Specific
| Variable | Purpose |
|---|---|
CI | Set to true on CI environments |
FASTLANE_DONT_STORE_PASSWORD | Don't save passwords to keychain |
MATCH_KEYCHAIN_NAME | Keychain name for CI |
MATCH_KEYCHAIN_PASSWORD | Keychain password for CI |
Xcode
| Variable | Purpose |
|---|---|
GYM_WORKSPACE | Default workspace path |
GYM_SCHEME | Default scheme |
GYM_OUTPUT_DIRECTORY | Default output directory |
GYM_EXPORT_METHOD | Default export method |
SCAN_WORKSPACE | Default workspace for tests |
SCAN_SCHEME | Default test scheme |
SCAN_DEVICE | Default test device |
Notes
CLI Syntax Rules
- All
fastlane runparameters usekey:valuesyntax (no dashes, no equals signs). - Tool shorthand commands (
fastlane gym,fastlane pilot) use--key valueor--key "value"syntax. - Boolean parameters:
true/falseforfastlane run,--flag/no flag for shorthand. - Array parameters: comma-separated strings (e.g.,
devices:"iPhone 16,iPad Pro"). - Paths with spaces must be quoted.
Error Handling
- Session expired: Re-authenticate with
fastlane spaceauth -u user@example.comor refresh API key. - Code signing errors: Run
fastlane matchto sync, orsecurity find-identity -v -p codesigningto verify local certs. - "Could not find App": Verify
app_identifiermatches the bundle ID registered in App Store Connect. - Timeout on upload: Set
FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT=120and retry. - Profile mismatch: Run
fastlane sigh repairorfastlane matchwith--force.
Agent Tips
When a user asks to "deploy" or "release" an iOS app, the typical flow is: match (sign) → gym (build) → pilot (TestFlight) or deliver (App Store).
If the user has a
Fastfile, respect it. But for one-off commands, always use the CLI syntax shown in this skill.
Always check for an existing
.xcworkspacebefore defaulting to.xcodeproj. Runls *.xcworkspaceto verify.
For CI environments, always use
--readonlywith match and set theCI=trueenvironment variable.
When in doubt about which action to use, run
fastlane actionsorfastlane search_actions <keyword>to discover the right one.