fix: stamp required version keys into GutenbergKitResources framework Info.plist#551
Open
jkmassel wants to merge 2 commits into
Open
fix: stamp required version keys into GutenbergKitResources framework Info.plist#551jkmassel wants to merge 2 commits into
jkmassel wants to merge 2 commits into
Conversation
XCFramework BuildThis PR's XCFramework is available for testing. Add the following to your .package(url: "https://github.com/wordpress-mobile/GutenbergKit", branch: "pr-build/551")Built from 352520d |
… Info.plist build_xcframework.sh hand-wrote the framework Info.plist with only four keys, omitting CFBundleShortVersionString and MinimumOSVersion. App Store Connect requires both on any embedded framework, so consuming apps failed to upload to TestFlight (altool 90057 / 90360) even though GutenbergKit's own CI was green: codesign doesn't validate version keys, so the deficient framework sailed through signing and publishing. Stamp the version keys from package.json and MinimumOSVersion from Package.swift (swift package dump-package), both fail-closed, and verify every shipped slice's plist before it leaves the build step so this can't silently recur.
26a4c2b to
4783614
Compare
crazytonyli
requested changes
Jul 15, 2026
| # The `|| ''` collapses a missing/empty/undefined `version` to the empty | ||
| # string so the guard below catches it — `node -p` would otherwise print the | ||
| # literal "undefined" and stamp it as the version, the exact drift we prevent. | ||
| MARKETING_VERSION="$(node -p "require('./package.json').version || ''" 2>/dev/null || true)" |
Contributor
There was a problem hiding this comment.
Use jq instead of node?
The MINIMUM_IOS_VERSION lookup already requires jq (swift package dump-package | jq), so reading MARKETING_VERSION with jq too drops the node dependency from this script and keeps both version reads consistent. `.version // empty` preserves the fail-closed behavior: a missing, null, or empty version yields empty output so the guard fires, rather than stamping a literal "null" (the jq analogue of the node "undefined" case the previous comment guarded against). Addresses review feedback on #551.
crazytonyli
approved these changes
Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
GutenbergKitResources.framework'sInfo.plistwas missingCFBundleShortVersionStringandMinimumOSVersion, which App Store Connect requires on every embedded framework. This adds those keys (plusCFBundleVersion), sources every value from a single manifest, and adds a post-build check so the plist can't silently drift again.Why?
build_xcframework.shhand-writes the frameworkInfo.plistwith only four keys —CFBundleExecutable,CFBundleIdentifier,CFBundleName,CFBundlePackageType.codesign(fastlane xcframework_sign) doesn't validate version keys, so the deficient framework passes signing, zips, and publishes to the CDN unnoticed. altool is the first tool in the chain that validates embedded-framework plists — so the failure only surfaces at a consuming app's TestFlight upload, three hops downstream:CFBundleShortVersionString→ altool 90057MinimumOSVersion→ altool 90360This blocked a wordpress-ios TestFlight upload: build 33156.
Note: this fix is forward-only — the XCFramework already on the CDN still carries the bad plist, so it won't unblock a consumer on its own. It needs a new GutenbergKit release carrying this change, then a consumer bump to pick it up.
How?
1. Stamp the required keys
The heredoc now also emits
CFBundleShortVersionString,CFBundleVersion,MinimumOSVersion, andCFBundleInfoDictionaryVersion.CFBundleVersionwasn't in altool's error list, but a framework carryingCFBundleShortVersionStringwithout it is malformed by convention — cheaper to include now than to eat a second upload round-trip.2. Single source of truth, fail-closed
CFBundleShortVersionString/CFBundleVersion←package.jsonversionMinimumOSVersion←Package.swift's declared iOS platform, viaswift package dump-package | jq(SwiftPM normalizes.v17→"17.0", the exact format the key wants)Both abort the build if the value can't be read, rather than stamping a silently-wrong placeholder — a wrong-but-present version is exactly the drift we want to prevent.
MINIMUM_IOS_VERSIONis no longer hardcoded, so the dylib link target (-target arch-apple-ios${MINIMUM_IOS_VERSION}) tracksPackage.swifttoo.3. Verify before the artifact leaves the step
After
create-xcframework,verify_framework_plistruns against every shipped slice andexit 1s unless:plutil -lintpasses,CFBundleShortVersionStringmatchespackage.json,CFBundleVersionis present, andMinimumOSVersionmatches. A dropped or stale key now reddens GutenbergKit's ownbuild-xcframeworkjob instead of a downstream App Store upload.Testing Instructions
make build-resources-xcframework(or./build_xcframework.sh).--- Verifying framework Info.pliststep printsOK:for each slice and the script exits0.CFBundleShortVersionString= thepackage.jsonversion andMinimumOSVersion=17.0.package.json'sversion, rebuild, and confirm the verification step fails the build with aCFBundleShortVersionString ... does not matcherror.Accessibility Testing Instructions
N/A — build tooling only, no UI change.