Files
Sauci/.agents/learnings/promoted/2026-08-30-ios-extension-version-verification.md
T

1.8 KiB

id, date, status, scope, evidence, destination, review_after
id date status scope evidence destination review_after
2026-08-30-ios-extension-version-verification 2026-08-30 promoted iOS release artifact verification v1.0.6 exported IPA inspection and reproduced v1.0.7 Xcode build-setting mismatch apps/mobile/scripts/release-preflight.mjs and .codex/skills/release-mobile/SKILL.md 2027-02-28

Symptom

The signed iOS build logged that the widget extension build number 44 did not match the containing app build number 45, even though export completed.

Reproduction

Build iOS version 1.0.6 with EAS auto-increment from build 44 to 45 and retain the archive log. Extract the resulting IPA with ditto, then read the containing app and every packaged extension Info.plist with PlistBuddy.

Cause

The v1.0.6 archive warning described an intermediate state and was not authoritative for that exported package. The later v1.0.7 reproduction found a separate real hazard: CURRENT_PROJECT_VERSION in both LiveDrawWidget configurations can override the widget plist and package an older build number.

Remediation

Before every iOS release, require public-version parity across app config, both plists, and Xcode marketing settings. Require the widget Debug and Release CURRENT_PROJECT_VERSION values to equal both plists. Then inspect the exported app and all packaged extensions. Reject or rebuild only when the final IPA values differ; do not accept or reject a release from archive warnings alone.

Evidence

PlistBuddy read CFBundleShortVersionString 1.0.6 and CFBundleVersion 45 from both v1.0.6 packaged plists. The v1.0.7 build later proved a stale widget Xcode setting can survive plist-only review. release-preflight.mjs and its node test now reject that mismatch before EAS allocation; exported IPA inspection remains the final authority.