Documentation
Ship to the App Store
End-to-end path: Walnut app → App Store Connect → TestFlight → App Review → release.
Deep pages stay focused: signing (device.md), IPA upload (testflight.md), listing assets (screenshots.md). This page is the order of operations and the Apple-side steps Walnut does not click for you.
One-screen map
Apple Developer Program
│
├─► App ID (bundle id) Certificates, Identifiers & Profiles
├─► ASC app record App Store Connect → My Apps → (+)
└─► Team API key (.p8) Users and Access → Integrations
│
▼
walnut device login <app>
│
┌───────┴────────┐
▼ ▼
store/ metadata walnut.toml [ios]
+ screenshots versions + encryption flag
│ │
▼ ▼
walnut store upload walnut testflight
│ │
└───────┬────────┘
▼
ASC: attach build → Submit for Review → release
0. Prerequisites
| Need | Notes |
|---|---|
| Paid Apple Developer Program | Free teams cannot TestFlight or sell on the Store |
| macOS + Xcode | Archive / export |
Release walnut CLI | `` after toolchain changes |
App with App Store–ready ios/ | walnut new installs icons, orientations, encryption plist default |
1. Register the App ID
- developer.apple.com → Certificates, Identifiers & Profiles → Identifiers → (+)
- App IDs → App
- Description + Bundle ID = the
bundle_id/bundleIdin your Walnut manifest (walnut.toml/walnut.json) - Enable capabilities you actually use (HealthKit, Associated Domains, …). Today these often live under
ios/.
2. Create the app in App Store Connect
- App Store Connect → My Apps → (+) → New App
- Platforms: iOS
- Name, primary language, bundle ID (must match step 1), SKU (any stable string)
- User Access as you prefer
Walnut does not create this record yet (testflight assumes it exists).
3. Team API key (once per org)
Required for walnut testflight and walnut store upload.
- ASC → Users and Access → Integrations → App Store Connect API
- Team Keys (not Individual — Individual fails export with a fake password /
-20101) - Generate (Admin or App Manager) → download
AuthKey_<KEYID>.p8 - Issuer ID = UUID at the top of the Keys page (org-wide), not the Key ID
Then:
walnut device login .
# pick Apple ID + Team; paste key path / Key ID / Issuer ID
Or set WALNUT_ASC_KEY_PATH, WALNUT_ASC_KEY_ID, WALNUT_ASC_ISSUER_ID (and team via login / WALNUT_DEVELOPMENT_TEAM). Details: device.md, testflight.md.
4. Encryption / export compliance
Apple asks whether the app uses non-exempt encryption. Most Walnut demos (HTTPS only, no custom crypto) answer no.
In walnut.toml:
[ios]
marketing_version = "1.0"
build_number = "1"
# false (default) → Info.plist ITSAppUsesNonExemptEncryption = false
# ASC usually stops nagging “App Encryption Documentation” every upload.
uses_non_exempt_encryption = false
walnut testflight syncs that flag into ios/Info.plist (and project.yml when present) before archive.
| Set | When |
|---|---|
false (default) | Standard HTTPS / OS crypto only — typical Walnut apps |
true | You ship non-exempt crypto; then complete ASC encryption documentation |
Do not hand-edit the plist as the source of truth — keep the flag in the manifest.
5. Listing copy + screenshots
walnut screenshots init .
walnut screenshots slots
walnut simulator . --device "iPhone 16 Pro Max"
# Navigate to each screen, then:
walnut screenshots capture . --name 01-home --slot iphone-6-9
# …
walnut screenshots check .
Edit store/metadata/*.txt (subtitle, description, keywords, promotional text, what’s new). Full slot table and git rules: screenshots.md.
6. Upload a build (TestFlight)
walnut testflight --preflight .
walnut testflight .
Dry-run IPA only:
walnut testflight . --ipa-only
Wait for ASC processing (often a few minutes). The build appears under the app → TestFlight. Fix compliance / missing compliance there if ASC still blocks (usually the encryption flag above).
7. Push listing assets
walnut store upload .
# optional: --locale en-US --version 1.0 --dry-run
Creates the iOS version + locale if needed; patches metadata; uploads screenshots for slots under store/screenshots/raw/. Same Team API key as TestFlight.
8. App Review → release (App Store Connect UI)
Walnut stops before the legal/product buttons. In ASC:
- My Apps → your app → the iOS version you uploaded assets for
- Build — select the processed TestFlight build
- Complete required questionnaires (encryption already covered if the plist flag is correct; privacy nutrition labels, content rights, advertising, age rating as applicable)
- Pricing and Availability (if not set)
- Add for Review / Submit for Review
- After approval: Release This Version (or automatic release if you enabled it)
Internal / external TestFlight testing is optional but useful before step 5.
Happy-path command strip
walnut device login .
walnut screenshots init .
# capture + edit store/metadata/*
walnut screenshots check .
walnut testflight --preflight .
walnut testflight .
walnut store upload .
# → ASC: attach build, Submit for Review, release
What Walnut owns vs Apple owns
| Walnut CLI / manifest | You in Apple portals |
|---|---|
| Compile, archive, IPA, upload | Developer Program membership |
Sync uses_non_exempt_encryption → plist | Create App ID + ASC app record |
store/ metadata + screenshot upload | Privacy labels, age rating, review answers |
Version / build bump in walnut.toml | Submit for Review + release |
Related
- testflight.md — archive flags, troubleshooting (
-20101, icons, orientations) - screenshots.md — slots,
store upload - device.md — physical install + login
- licensing.md — Community splash vs Commercial