Skip to content

Tag builds fail Library Tests against the released iOS-only XCFramework #589

Description

@dcalhoun

Every release tag build fails :swift: Library Tests. Releases publish correctly — this is a false failure on a build that runs after the release is done — but it leaves every tag build red.

Latest: build 2574 (v0.20.0-alpha.0), 134 instances of:

ios/Sources/GutenbergKit/Sources/EditorViewController.swift:4:8: error: no such module 'GutenbergKitResources'

Cause

A release spans two builds:

  1. Trunk build (NEW_VERSION set) runs against resourcesMode = .local, so swift test compiles local sources and passes. It then publishes the XCFramework, rewrites Package.swift to .release(version:checksum:), and pushes the tag.
  2. Tag build, triggered by that push, now resolves GutenbergKitResources to the published XCFramework.

make test-swift-library is plain swift test, which builds for the host platform — arm64 macOS, since Package.swift declares platforms: [.iOS(.v17), .macOS(.v14)]. But build_xcframework.sh builds only iphoneos and iphonesimulator. Unpacking the published v0.20.0-alpha.0 artifact confirms it: ios-arm64 and ios-arm64_x86_64-simulator, both SupportedPlatform: ios. No macOS slice, so SwiftPM finds no match and the module doesn't exist. The zip and checksum are otherwise valid.

:swift: iOS Simulator Tests passes on the same build — it targets a simulator destination that does have a slice.

History

Introduced by #502, which made the release lane rewrite Package.swift to .release. Tag commits previously kept .local and passed. First affected release is v0.17.1; v0.16.0 (build 2312) is the last passing tag build.

Why the job matters

test-swift-library isn't redundant with iOS Simulator Tests. It was added in #476 specifically to build where canImport(UIKit) is false:

The existing swift test job runs xcodebuild -sdk iphonesimulator, where canImport(UIKit) is always true — so iOS-only conditional code is never exercised against macOS, and it's possible to break the host-platform build […] without CI noticing.

24+ files under ios/Sources/ sit behind #if canImport(UIKit) gates, and the macOS build is the only thing validating them. Any fix that stops building for the host gives up that coverage.

Suggested fix

Keep resourcesMode = .local for CI validation and flip to .release only in the published manifest.

The mismatch is that a manifest rewritten for consumers is handed to a test job that needs sources. Splitting the two resolves it directly: the tag build keeps compiling real source on macOS (preserving #476's coverage), while consumers still resolve the prebuilt binary from CDN. This would move the rewrite in update_swift_package / publish_release_to_github (fastlane/Fastfile) so the .release manifest lands only on the tagged commit, not on the tree CI tests.

Tradeoff: CI then never exercises the exact manifest consumers resolve, so this wants a separate lightweight resolve-check against the published tag.

Alternatives considered:

  • Add a macOS slice to build_xcframework.sh. Correct if macOS is genuinely supported, but the script is iOS-shaped throughout — resolve_slice_dir globs ios-*, link_dylib hardcodes -apple-ios targets, and verify_framework_plist asserts MinimumOSVersion, which isn't the right key for macOS. Adds build time and artifact size on every release for a slice nothing currently consumes.
  • Drop .macOS(.v14). Cheapest, and makes the manifest honest, but it removes the host-platform build entirely and so discards the #if canImport(UIKit) coverage test(ios): exercise the Swift package on macOS via swift test #476 added. Not recommended.

Related

build-xcframework has depends_on: swift-test-library — the job that builds the XCFramework waits on one that, on tag builds, can only pass if a valid XCFramework already exists. Never exercised (trunk's .local makes the test pass, and tag builds don't publish), but worth untangling alongside this.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    [Type] Automated TestingTesting infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions