Skip to content

Add XCFramework build infrastructure and CI#401

Open
mokagio wants to merge 5 commits intotrunkfrom
xcframework-build-infra
Open

Add XCFramework build infrastructure and CI#401
mokagio wants to merge 5 commits intotrunkfrom
xcframework-build-infra

Conversation

@mokagio
Copy link
Copy Markdown
Contributor

@mokagio mokagio commented Mar 25, 2026

Summary

Adds the automation for building, signing, and uploading the resources XCFramework build. This will allow having a smaller follow up PR focused only on updating the release automation to handle version bumping, Package.swift update, and GitHub release.

This lands the build and upload pipeline without wiring into Package.swift — consumers still use the local source target.

I pushed a one-off Package.swift update branch to use the latest artifact built here and tested it in WordPress iOS via CI-made Prototype Build.

  • Add build_xcframework.sh script that archives GutenbergKitResources for device + simulator, links .o into a dylib, assembles an XCFramework with resource bundles and dSYMs, and outputs a zip with SPM checksum
  • Add make build-resources-xcframework target
  • Add Fastlane setup scoped to publish_to_s3 and xcframework_sign lanes (release orchestration lanes deferred)
  • Add Buildkite steps: XCFramework build on every push, S3 publish gated on NEW_VERSION env var

Test plan

  • Verify make build-resources-xcframework produces a valid zip + checksum locally
  • Verify Buildkite build step succeeds and uploads artifacts
  • Verify S3 publish step is skipped when NEW_VERSION is not set

🤖 Generated with Claude Code


Posted by Claude Code (Opus 4.6) on behalf of @mokagio with approval.

mokagio and others added 4 commits March 24, 2026 18:11
Archives `GutenbergKitResources` for device and simulator,
assembles an XCFramework with resource bundles and dSYMs,
then outputs a zip with SPM checksum.

The `.o` → dylib linking step is necessary because SPM
produces a static object file; without it, `BundleFinder`
gets statically linked into the consuming app and
`Bundle(for:)` resolves to the wrong bundle at runtime.

---

Generated with the help of Claude Code, https://claude.ai/code

Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
Scoped to `publish_to_s3` and `xcframework_sign` lanes.
Release orchestration lanes (`release`, `validate`,
`update_swift_package`, `publish_release_to_github`) are
deferred to a follow-up once the full CI release flow
is designed.

---

Generated with the help of Claude Code, https://claude.ai/code

Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
The build step runs on every push, uploading the zip
and checksum as Buildkite artifacts.
The S3 publish step is gated on `NEW_VERSION` env var,
matching the pattern Android already uses for on-demand
release builds.

---

Generated with the help of Claude Code, https://claude.ai/code

Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
Split zip+checksum out of `build_xcframework.sh` into
`package_xcframework.sh` so codesigning can happen on the
unzipped `.xcframework` directory between build and package.

The CI build step now runs:
1. `fastlane set_up_signing_release` — installs certs
2. `make build-resources-xcframework` — builds xcframework
3. `fastlane xcframework_sign` — codesigns xcframework
4. `./package_xcframework.sh` — zips + checksums

---

Generated with the help of Claude Code, https://claude.ai/code

Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
@mokagio mokagio force-pushed the xcframework-build-infra branch from 99a89e0 to 919f5fd Compare March 25, 2026 09:27
Comment on lines +74 to +80
buildkite-agent artifact download dist.tar.gz .
tar -xzf dist.tar.gz
install_gems
bundle exec fastlane set_up_signing_release
make build-resources-xcframework
bundle exec fastlane xcframework_sign
./package_xcframework.sh
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admit this is quite confusing with a mash of Fastlane, make, and scripts. I'll tidy up in a follow up, my preference being to use make as the single entry point.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buildkite-agent artifact download '*.xcframework.zip' .
buildkite-agent artifact download '*.xcframework.zip.checksum.txt' .
install_gems
bundle exec fastlane publish_to_s3 version:${NEW_VERSION:-$BUILDKITE_COMMIT}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Android publishes every version but does not have the issue of having to update Package.swift to match the checksum generated by the build.

Given storage is cheap, it might be okay for us to publish the XCFramework on every build, too, just to continue exercising the infra and avoid surprises at release time.

Or, we could be frugal and only publish when we need. I'm leaning toward publishing one every build, though. Faster feedback. And we could add additional automation to easily push a commit with updated Package.swift so that any XCFramework in S3 can be tested in WordPress iOS in a few clicks.

@mokagio mokagio requested a review from dcalhoun March 26, 2026 05:05
@mokagio mokagio marked this pull request as ready for review March 26, 2026 05:05
@dcalhoun dcalhoun added the [Type] Build Tooling Issues or PRs related to build tooling label Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Type] Build Tooling Issues or PRs related to build tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants