home / skills / willsigmon / sigstack / testflight-expert

This skill streamlines beta distribution and tester management with TestFlight integrations and CI/CD, accelerating feedback collection and release cycles.

npx playbooks add skill willsigmon/sigstack --skill testflight-expert

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.9 KB
---
name: TestFlight Expert
description: TestFlight - beta testing, internal/external testers, build distribution
allowed-tools: Read, Edit, Bash, WebFetch
model: sonnet
---

# TestFlight Expert

Distribute beta builds and collect feedback through Apple's TestFlight.

## TestFlight Overview

- **Internal Testing**: Up to 100 testers (no review)
- **External Testing**: Up to 10,000 testers (requires review)
- **Build Expiry**: 90 days
- **Feedback**: Screenshots and crash reports

## Fastlane Upload

### Basic Upload
```ruby
# Fastfile
lane :beta do
  build_app(scheme: "App")
  upload_to_testflight(
    skip_waiting_for_build_processing: true
  )
end
```

### With Changelog
```ruby
lane :beta do
  build_app(scheme: "App")
  upload_to_testflight(
    changelog: "Bug fixes and improvements",
    distribute_external: true,
    groups: ["Beta Testers"]
  )
end
```

## App Store Connect API

### Setup
```bash
# Create API key in App Store Connect
# Users and Access → Keys → App Store Connect API

# Store credentials
export APP_STORE_CONNECT_API_KEY_ID="XXXXXXXXXX"
export APP_STORE_CONNECT_ISSUER_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export APP_STORE_CONNECT_API_KEY_PATH="~/.appstore/AuthKey.p8"
```

### Fastlane Config
```ruby
# Appfile
app_store_connect_api_key(
  key_id: ENV["APP_STORE_CONNECT_API_KEY_ID"],
  issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"],
  key_filepath: ENV["APP_STORE_CONNECT_API_KEY_PATH"]
)
```

## Managing Testers

### Add Internal Tester
```ruby
# Must be App Store Connect user
# Add manually in App Store Connect
```

### Add External Group
```ruby
lane :add_testers do
  upload_to_testflight(
    groups: ["Beta Testers", "VIP Testers"],
    distribute_external: true
  )
end
```

### CLI Tester Management
```bash
# Using app-store-connect-cli
asc testflight add-tester \
  --email "[email protected]" \
  --group "Beta Testers" \
  --app-id 123456789
```

## CI/CD Integration

### GitHub Actions
```yaml
name: TestFlight
on:
  push:
    branches: [main]

jobs:
  testflight:
    runs-on: macos-14
    steps:
      - uses: actions/checkout@v4

      - name: Setup Signing
        uses: apple-actions/import-codesign-certs@v2
        with:
          p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
          p12-password: ${{ secrets.CERTIFICATES_PASSWORD }}

      - name: Build & Upload
        run: |
          bundle exec fastlane beta
        env:
          APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.ASC_KEY_ID }}
          APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
          APP_STORE_CONNECT_API_KEY: ${{ secrets.ASC_KEY }}
```

## Build Processing

### Wait for Processing
```ruby
lane :beta do
  build_app(scheme: "App")
  upload_to_testflight(
    skip_waiting_for_build_processing: false,
    wait_processing_timeout_duration: 3600
  )
  # Build is ready for testing
end
```

### Skip Waiting
```ruby
lane :beta do
  build_app(scheme: "App")
  upload_to_testflight(
    skip_waiting_for_build_processing: true
  )
  # Continue without waiting (faster CI)
end
```

## Beta Review Tips

### What Gets Reviewed
- First build of new app
- Major version changes
- Significant feature additions

### Speed Up Review
- Complete app description
- Add test account credentials
- Clear beta release notes
- No placeholder content

### Typical Review Time
- 24-48 hours for external builds
- Internal builds: No review needed

## Collecting Feedback

### In-App Feedback
```swift
import StoreKit

// Prompt for beta feedback
SKStoreReviewController.requestReview()
```

### TestFlight Feedback
- Users shake device to send feedback
- Includes screenshot + notes
- Crash reports auto-collected

## Version Management

```ruby
lane :beta do
  # Auto-increment build number
  increment_build_number(
    build_number: latest_testflight_build_number + 1
  )

  build_app(scheme: "App")
  upload_to_testflight
end
```

Use when: Beta distribution, tester management, CI upload automation

Overview

This skill helps teams distribute iOS beta builds via Apple TestFlight, manage internal and external testers, and automate uploads from CI. It bundles Fastlane patterns, App Store Connect API setup, and tester management commands to streamline beta distribution. The goal is reliable build delivery, predictable review times, and structured feedback collection.

How this skill works

It automates build signing, increments build numbers, and uploads artifacts to TestFlight using Fastlane and the App Store Connect API. The skill manages tester groups (internal and external), toggles waiting for Apple processing, and provides CI/CD examples for GitHub Actions. It also surfaces best practices for speeding external beta review and collecting in-app feedback.

When to use it

  • Distributing pre-release iOS builds to internal or external testers
  • Automating TestFlight uploads from CI (GitHub Actions, other runners)
  • Managing tester groups and inviting testers at scale
  • Collecting crash reports and tester feedback during beta
  • Handling build numbering and processing wait/skip options

Best practices

  • Use App Store Connect API keys stored in CI secrets to avoid interactive auth
  • Auto-increment build numbers based on latest TestFlight build to prevent collisions
  • Group external testers and provide clear release notes and test account credentials to speed review
  • Use skip_waiting_for_build_processing=true for faster CI pipelines when immediate availability isn’t required
  • Keep beta metadata complete and avoid placeholder content to reduce external review delays

Example use cases

  • Run a Fastlane lane to build and upload beta builds on push to main using macOS runners
  • Add or update external tester groups and distribute a release with changelog and group assignment
  • Use CLI tooling to add single testers during outreach or QA cycles
  • Configure App Store Connect API keys and pipeline secrets to enable unattended uploads
  • Prompt users for in-app feedback and rely on TestFlight screenshots and crash reports to triage issues

FAQ

How many testers can I add?

Internal testers: up to 100 (no review). External testers: up to 10,000 (requires App Review for the build).

How long are TestFlight builds available?

Each uploaded build expires after 90 days from the upload date.

Should I wait for build processing in CI?

If you need the build available to external testers immediately after upload, wait for processing. For faster CI and downstream steps that don’t depend on TestFlight availability, skip waiting.