5.4 KiB
OpenClaw iOS Versioning
OpenClaw iOS uses a pinned CalVer release version instead of reading the current gateway version automatically on every build.
Goals
- keep TestFlight submissions on one stable app version while iterating
- change only
CFBundleVersionduring normal TestFlight iteration - promote the iOS release version to the current gateway version only when a maintainer chooses to do that
- keep Apple bundle fields valid for App Store Connect
- generate App Store release notes from an iOS-owned changelog
Version model
The pinned iOS release version lives in apps/ios/version.json.
Supported pinned format:
YYYY.M.D
Examples:
2026.4.62026.4.10
The root gateway version in package.json may still be one of:
YYYY.M.DYYYY.M.D-beta.NYYYY.M.D-N
When you pin iOS from the gateway version, the iOS tooling strips the gateway suffix and keeps only the base CalVer.
Examples:
- gateway
2026.4.10-> iOS2026.4.10 - gateway
2026.4.10-beta.3-> iOS2026.4.10 - gateway
2026.4.10-2-> iOS2026.4.10
Apple bundle mapping
Pinned iOS version 2026.4.10 maps to:
CFBundleShortVersionString = 2026.4.10CFBundleVersion = numeric build number only
CFBundleShortVersionString stays fixed for a TestFlight train until you intentionally pin a newer iOS release version.
Source of truth and generated files
Source files
apps/ios/version.json- pinned iOS release version
apps/ios/CHANGELOG.md- iOS-only changelog and release-note source
apps/ios/VERSIONING.md- workflow and constraints
Generated or derived files
apps/ios/Config/Version.xcconfig- checked-in defaults derived from
apps/ios/version.json
- checked-in defaults derived from
apps/ios/fastlane/metadata/en-US/release_notes.txt- generated from
apps/ios/CHANGELOG.md
- generated from
apps/ios/build/Version.xcconfig- local gitignored build override generated per build or release prep
Tooling surfaces
Version parsing and sync tooling
scripts/lib/ios-version.ts- validates pinned iOS CalVer
- normalizes gateway version -> pinned iOS CalVer
- renders checked-in xcconfig and release notes
scripts/ios-version.ts- CLI for JSON, shell, or single-field version reads
scripts/ios-sync-versioning.ts- syncs checked-in derived files from the pinned iOS version
scripts/ios-pin-version.ts- explicitly pins iOS to a chosen release version or the current gateway version
Build and App Store release flow
scripts/ios-write-version-xcconfig.sh- reads the pinned iOS version
- writes the local numeric build override file in
apps/ios/build/Version.xcconfig
scripts/ios-release-prepare.sh- prepares App Store distribution signing and bundle settings against the pinned iOS version
scripts/ios-release-signing.mjs- validates the checked-in App Store signing manifest
- renders the temporary release xcconfig profile pins
apps/ios/fastlane/Fastfile- resolves version metadata from the pinned iOS helper
- creates or verifies Developer Portal bundle IDs/services through Fastlane
produce - syncs encrypted App Store signing assets with Fastlane
match - increments App Store Connect build numbers for the pinned short version
- uploads screenshots and release notes before archiving a release build
Release-note resolution order
When generating apps/ios/fastlane/metadata/en-US/release_notes.txt, the tooling reads the first available changelog section in this order:
- exact pinned version, for example
## 2026.4.10 ## Unreleased
Recommended workflow:
- while iterating on a TestFlight train, keep pending notes under
## Unreleased - before the production release, move or copy the final notes under
## <pinned version>and run sync again
Common commands
pnpm ios:version
pnpm ios:version:check
pnpm ios:version:sync
pnpm ios:version:pin -- --from-gateway
pnpm ios:version:pin -- --version 2026.4.10
Normal TestFlight iteration workflow
- keep
apps/ios/version.jsonpinned to the current TestFlight train version - update
apps/ios/CHANGELOG.mdunder## Unreleasedwhile iterating - upload more App Store Connect builds with
pnpm ios:release:upload - let Fastlane increment only
CFBundleVersion
This keeps the TestFlight version stable while review is in flight.
New release promotion workflow
When you want the next production iOS release to align with the current gateway release:
- pin iOS from the root gateway version:
pnpm ios:version:pin -- --from-gateway
- review the generated changes in:
apps/ios/version.jsonapps/ios/Config/Version.xcconfigapps/ios/fastlane/metadata/en-US/release_notes.txt
- update
apps/ios/CHANGELOG.mdfor the new release if needed - run
pnpm ios:version:syncagain if the changelog changed - upload the first App Store Connect build for that newly pinned version
- keep iterating only by build number until the release candidate is ready
- manually submit the reviewed build for App Review in App Store Connect
- release the approved build to production
Important invariant
Fastlane and Xcode should consume only the pinned iOS version from apps/ios/version.json.
Changing package.json.version alone must not change the iOS app version until a maintainer explicitly runs the pin step.
App Review submission must remain manual. Automation may create/update the editable App Store version, upload screenshots, upload release notes, and upload builds, but it should not submit a build for review.