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

NeedNotes
Paid Apple Developer ProgramFree teams cannot TestFlight or sell on the Store
macOS + XcodeArchive / 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

  1. developer.apple.comCertificates, Identifiers & ProfilesIdentifiers(+)
  2. App IDs → App
  3. Description + Bundle ID = the bundle_id / bundleId in your Walnut manifest (walnut.toml / walnut.json)
  4. Enable capabilities you actually use (HealthKit, Associated Domains, …). Today these often live under ios/.

2. Create the app in App Store Connect

  1. App Store ConnectMy Apps(+)New App
  2. Platforms: iOS
  3. Name, primary language, bundle ID (must match step 1), SKU (any stable string)
  4. 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.

  1. ASC → Users and AccessIntegrationsApp Store Connect API
  2. Team Keys (not Individual — Individual fails export with a fake password / -20101)
  3. Generate (Admin or App Manager) → download AuthKey_<KEYID>.p8
  4. 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.

SetWhen
false (default)Standard HTTPS / OS crypto only — typical Walnut apps
trueYou 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:

  1. My Apps → your app → the iOS version you uploaded assets for
  2. Build — select the processed TestFlight build
  3. Complete required questionnaires (encryption already covered if the plist flag is correct; privacy nutrition labels, content rights, advertising, age rating as applicable)
  4. Pricing and Availability (if not set)
  5. Add for Review / Submit for Review
  6. 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 / manifestYou in Apple portals
Compile, archive, IPA, uploadDeveloper Program membership
Sync uses_non_exempt_encryption → plistCreate App ID + ASC app record
store/ metadata + screenshot uploadPrivacy labels, age rating, review answers
Version / build bump in walnut.tomlSubmit for Review + release