Skip to content

iOS TestFlight Deployment

Bartendie ships to TestFlight and the App Store through the R26D release toolchain: autopen (code signing from the team vault) and pigeon (build numbers, release records, store uploads). There is no Fastlane and no Ruby in the release path — Ruby remains only as a build dependency for CocoaPods.

  • Mac with Xcode (including the iOS platform: xcodebuild -downloadPlatform iOS after Xcode updates)
  • autopen and pigeon CLIs on your PATH
  • GPG key authorized for the signing vault (r26d_signing_secrets) — autopen clones and decrypts it per session
  • Node (asdf) and CocoaPods via bundler (bundle install — handled automatically by task ios:pods)

No Apple ID password or 2FA is needed: store uploads authenticate with the App Store Connect API key served from the vault by autopen ios release-env.

All tasks run from shaker/:

Terminal window
# 1. Update release notes (becomes TestFlight "What to Test")
$EDITOR release_notes/ios.txt
# 2. Bump the version in app.json (expo.version) if this is a new version
# 3. Build a signed IPA (pulls the next build number from pigeon)
task ios:build
# 4. Optional: smoke test the Release build in the simulator
task ios:sim
# 5. Optional: validate the IPA with Apple without uploading
task ios:validate
# 6. Publish that exact IPA to TestFlight
task ios:publish

task ios:beta runs build + publish in one shot. When the TestFlight build is verified and you want to submit it for App Store review:

Terminal window
task ios:release
TaskWhat it does
ios:podsEnsures node_modules, Ruby gems, and CocoaPods are installed and in sync (runs automatically before builds)
ios:preflightVerifies the Xcode environment (first-launch state, iOS platform installed)
ios:version-syncSyncs app.json version → MARKETING_VERSION / CFBundleShortVersionString
ios:buildautopen signing setup → pigeon build number → xcodebuild archive + export → build/ios/Bartendie.ipa
ios:simBuilds Release for the iOS simulator and launches it (smoke test)
ios:validateValidates the IPA against App Store Connect without uploading
ios:publishpigeon release create + artifact publish (R2) + channel promote beta (TestFlight upload)
ios:betaios:build + ios:publish
ios:releasepigeon channel promote stable — submits the processed beta build for App Store review
  • Signingautopen ios prepare clones the vault, decrypts the team distribution certificate and the app’s provisioning profile with your GPG key, and installs them into a temporary keychain. autopen ios cleanup removes everything afterwards (the build task does this automatically, even on failure).
  • Build numbers — pigeon is the authority: pigeon build-number next bartendie --platform ios. If it ever drifts from App Store Connect (upload rejected as duplicate), re-seed with pigeon build-number set bartendie --platform ios --number <latest-in-TestFlight>.
  • Store credentialsautopen ios release-env exports ASC_API_KEY_ID / ASC_API_KEY_ISSUER_ID / ASC_API_PRIVATE_KEY_PATH from the vault. Pre-set ASC_* env vars win (useful for CI).
  • Artifacts — every published IPA is recorded as a pigeon release and stored in R2, so release history is queryable after the fact.
  • xcodebuild plugin/framework errors after an Xcode updatesudo xcodebuild -runFirstLaunch
  • “iOS x.y is not installed”xcodebuild -downloadPlatform iOS (both are caught up front by ios:preflight)
  • “The bundle version must be higher than the previously uploaded version” → re-seed the pigeon build number (see above), then rebuild — never re-publish the rejected IPA
  • Vault decryption failures → your GPG key must be listed in the vault’s .sops.yaml; check autopen vault status