App Release
Setting Up a New Project
Use this checklist when adding @sil/app-release to a product repo such as Mazzi, Luys, or Tiko.
Goal
The product repo should own all app-specific configuration, content, screenshots, signing, Apple IDs, and launch hooks.
@sil/app-release should own only the reusable automation:
- validate apps
- generate screenshots
- generate promo videos
- archive and export iOS builds
- prepare App Store metadata for Fastlane Deliver
- upload builds, metadata, and screenshots
Required Project Files
Add one root manifest:
release.config.json
Example:
{
"apps": [
{ "slug": "chess", "releaseConfig": "apps/chess/release/ios.json" },
{ "slug": "reversi", "releaseConfig": "apps/reversi/release/ios.json" }
]
}
Add one release config per app:
apps/<app>/release/ios.json
Add metadata JSON per locale:
apps/<app>/release/app-store/en-US.json
Recommended metadata shape:
{
"name": "Mazzi Chess",
"subtitle": "Classic chess, offline",
"promotional_text": "Play focused chess games against Mazzi.",
"description": "A clean offline chess app with difficulty levels, undo, themes, and game history.",
"keywords": "chess,board game,offline,strategy,mazzi",
"release_notes": "Initial release.",
"support_url": "https://example.com/support",
"privacy_url": "https://example.com/privacy",
"marketing_url": "https://example.com",
"copyright": "2026 Sil van Diepen"
}
Required Local Tools
For local validation, screenshots, videos, and release automation, the machine usually needs:
- Xcode
- Xcode command line tools
- iOS simulator runtimes used by the config
- Node.js 22 or newer
- XcodeGen, if the app uses
project.yml - FFmpeg for promo videos
- ImageMagick for generated title/card/CTA promo segments
- Fastlane for metadata and screenshot upload
Install common tools with:
brew install xcodegen ffmpeg imagemagick fastlane
Required App Store Connect Setup
For build uploads, set these environment variables unless the app config overrides the names:
export APP_STORE_CONNECT_API_KEY_ID="..."
export APP_STORE_CONNECT_API_ISSUER_ID="..."
The current upload path uses xcrun altool. The private key must be configured in the normal App Store Connect API key location expected by Apple tooling.
Each app config also needs an App Store Connect Apple ID:
{
"appleId": "6785882144"
}
Required App Test Hooks
The app should support deterministic launch hooks for screenshots and videos.
The release config can pass launch arguments:
{
"launchArgs": ["--ui-testing", "--screenshot", "settings"]
}
Or environment variables:
{
"env": {
"MAZZI_SCREENSHOT": "1",
"MAZZI_SCREENSHOT_ROUTE": "settings",
"MAZZI_SCREENSHOT_LANGUAGE": "{appLanguage}"
}
}
Environment keys are automatically prefixed with SIMCTL_CHILD_ before launching the simulator app.
The app should use these hooks to:
- skip onboarding where needed
- select language
- select color mode
- open specific screens or sheets
- seed deterministic game state
- avoid network or account requirements
First Commands
From the product repo root, run:
npx @sil/app-release --config apps/chess/release/ios.json --mode preflight
For all apps:
npx -p @sil/app-release app-release-all --mode preflight
Fix every missing requirement reported for the module you want to run.
Then run one module at a time:
npx @sil/app-release --config apps/chess/release/ios.json --mode validate
npx @sil/app-release --config apps/chess/release/ios.json --mode screenshots
npx @sil/app-release --config apps/chess/release/ios.json --mode promo-video
npx @sil/app-release --config apps/chess/release/ios.json --mode archive
npx @sil/app-release --config apps/chess/release/ios.json --mode prepare-metadata
npx @sil/app-release --config apps/chess/release/ios.json --mode prepare-screenshots
After local output looks correct, upload explicitly:
npx @sil/app-release --config apps/chess/release/ios.json --mode upload-build
npx @sil/app-release --config apps/chess/release/ios.json --mode upload-metadata
npx @sil/app-release --config apps/chess/release/ios.json --mode upload-screenshots
Expected Output Layout
Screenshots default to:
artifacts/screenshots/<app>/screenshots/<version>/<device-slug>/*.png
Promo videos default to:
artifacts/videos/<app>/videos/<version>/*.mp4
Fastlane Deliver output defaults to:
artifacts/app-store/<app>/metadata/<locale>/*.txt
artifacts/app-store/<app>/screenshots/<locale>/*.png
Apps can override these paths in their config.
Agent Handoff Prompt
Use this prompt when pointing another agent at a product repo:
Set up @sil/app-release for this repo.
Read /Users/silvandiepen/Repositories/_projects/app-release/docs/setup-new-project.md and docs/config-reference.md first.
Add release.config.json at the repo root.
For each iOS app, add apps/<app>/release/ios.json and apps/<app>/release/app-store/en-US.json.
Use app-owned launch args or SIMCTL_CHILD env hooks for deterministic screenshots.
Run preflight for every app and fix missing module requirements.
Do not move release logic into this repo; keep only config/content here.