Implement GutenbergKitResources binary dependency build#318
Implement GutenbergKitResources binary dependency build#318
Conversation
d39e34e to
e53dfea
Compare
| /// - ``always``: Always returns `true` - cached responses are always used. | ||
| /// | ||
| package func allowsResponseWith(date: Date, currentDate: Date = .now) -> Bool { | ||
| func allowsResponseWith(date: Date, currentDate: Date = .now) -> Bool { |
There was a problem hiding this comment.
SwiftPM required packageAccess: false on the GutenbergKit target for binary target compatibility.
With that flag off, the compiler no longer passes -package-name, so the package access modifier silently degrades to fileprivate breaking visibility across files within the module.
| let gutenbergCSS = Self.loadGutenbergCSS() ?? "" | ||
| let gutenbergCSS = GutenbergKitResources.loadGutenbergCSS() ?? "" | ||
| assert(!gutenbergCSS.isEmpty, "Failed to load Gutenberg CSS from bundle. Previews will not render correctly.") |
There was a problem hiding this comment.
There might be more robust ways to handle a path error internally, but I consider them out of scope for the moment.
| /ios/Sources/GutenbergKit/Gutenberg/assets | ||
| /ios/Sources/GutenbergKit/Gutenberg/index.html |
There was a problem hiding this comment.
These should not actually be generated anymore. We can keep them here for a while to avoid issues while local copies update, or get rid of them already to avoid carrying dead weight. What do you think?
| /ios/Sources/GutenbergKit/Gutenberg/assets | |
| /ios/Sources/GutenbergKit/Gutenberg/index.html |
| @@ -0,0 +1,152 @@ | |||
| #!/usr/bin/env bash | |||
There was a problem hiding this comment.
It took me a while to get this to run in #315 and it's based on a setup that had it in the root and I wasn't game to move it just yet.
There was a problem hiding this comment.
https://linear.app/a8c/issue/AINFRA-1983/followup-gutenbergkitresources-setup-move-script-away-from-root tracks moving it in a better location
9e7a477 to
76639c8
Compare
d1deddd to
60a14ac
Compare
|
@dcalhoun I can't tell if the E2E tests are due to my changes or not. I noticed you recently worked on an E2E fix, which I rebased this on top of. Maybe with your extra context you can let me know? Thanks! |
Thanks for the continued efforts on this, @mokagio! 🙇🏻♂️ It seems the CI failures are likely related to the changes in this pull request. When running the iOS UI tests locally in Xcode, I see errors related to the Dev server error
I was able to circumvent the error with the following diff. diff --git a/ios/Sources/GutenbergKit/Sources/EditorViewController.swift b/ios/Sources/GutenbergKit/Sources/EditorViewController.swift
index 1993d818..828d2519 100644
--- a/ios/Sources/GutenbergKit/Sources/EditorViewController.swift
+++ b/ios/Sources/GutenbergKit/Sources/EditorViewController.swift
@@ -465,7 +465,7 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro
onSelection: { [weak self] in self?.didSelectBlockInserterItem($0) },
onClose: { [weak self] in self?.notifyInserterClosed() }
)
- .environmentObject(htmlPreviewManager)
+// .environmentObject(htmlPreviewManager)
})
context.viewController = host
|
|
Thanks for the hints @dcalhoun . I'll see where they lead. |
Introduces a new `GutenbergKitResources` target to host the built Gutenberg web assets as a separate module. `Package.swift` uses `GUTENBERGKIT_SWIFT_USE_LOCAL_RESOURCES` env var to switch between a local source target (development) and a pre-built XCFramework binary target (releases). Sets `packageAccess: false` on `GutenbergKit` — required for binary target compatibility within the same package. --- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Required by `packageAccess: false` on the GutenbergKit target, which enables binary target compatibility for GutenbergKitResources within the same package. --- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace `Bundle.module` lookups in `EditorViewController` and `HTMLPreviewManager` with the new module's API. --- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resources are now served by GutenbergKitResources. The `Gutenberg/` directory is excluded from the target and both build output directories are gitignored. --- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The script archives GutenbergKitResources for device and simulator, creates an XCFramework, and outputs a zip with checksum for SPM consumption. Makefile changes: - Set GUTENBERGKIT_SWIFT_USE_LOCAL_RESOURCES for all targets - Copy dist output to GutenbergKitResources/Resources/ - Add build-resources-xcframework target --- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Swift tests now build resources locally first - Add XCFramework build step with artifact upload --- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Modeled on wordpress-rs. The `release` lane: 1. Validates the version doesn't already exist 2. Updates Package.swift version and checksum 3. Tags, pushes, and creates a GitHub release 4. Uploads XCFramework zip to S3 --- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
These ~58 files are now generated during the build and distributed via the GutenbergKitResources XCFramework. --- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The XCFramework build failed because xcodebuild only auto-creates schemes for products, not bare targets. Test signing failed because CI lacks a code identity for the new resource bundle. --- Generated with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
xcodebuild requires -destination for SPM packages. --- Generated with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The auto-generated GutenbergKit product scheme no longer includes a test action now that there are multiple products in the package. --- Generated with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Avoids breakage when CI and local have different Xcode point releases. --- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
--- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
--- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The macro now takes the scheme as a parameter, removing the duplicated xcodebuild invocation. --- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
--- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
--- Generate with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Buildkite's interpolator doesn't support shell parameter
expansion (`${VAR#pattern}`).
`$$` passes through as a literal `$` to the shell.
---
Generated with the help of Claude Code, https://claude.ai/code
Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
--- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
A directory named `Resources` inside a flat `.bundle` confuses `codesign`: it can't distinguish the iOS flat layout from the macOS deep layout, failing with "bundle format unrecognized, invalid, or unsuitable". Renaming to `Gutenberg` avoids the reserved name. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
The build script names the zip with the git SHA
(`GutenbergKitResources-{sha}.xcframework.zip`), but
`Package.swift` expects the stable name
`GutenbergKitResources.xcframework.zip`.
Use the stable name as the S3 key so SPM can resolve it.
---
Generated with the help of Claude Code, https://claude.ai/code
Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
Ruby's `||` doesn't catch empty strings, so `version:` with no value silently passes through, producing S3 keys without a version segment. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
--- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
Inline `$$` escaping in pipeline YAML failed to pass `BUILDKITE_TAG` through to the shell. A standalone script with `set -euo pipefail` avoids the double-interpolation issue entirely. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
Without it, iOS refuses to install the app: "missing or invalid CFBundleExecutable in its Info.plist". --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
SPM produces a `.o` object file for library targets. Copying it directly as the framework binary caused Xcode to statically link the code into the consuming app. This put the auto-generated `BundleFinder` class in the app binary, so `Bundle(for: BundleFinder.self)` resolved to the main bundle instead of the framework bundle—missing the resource bundle nested inside the framework directory. Linking the `.o` into a proper dylib keeps `BundleFinder` in the framework at runtime, fixing the crash: `unable to find bundle named GutenbergKit_GutenbergKitResources` --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
39a064c to
74af0b9
Compare
The `test-ios-e2e` target copied build output into `GutenbergKit/Gutenberg/` but not into the new `GutenbergKitResources/Gutenberg/` directory, which is where the editor now loads resources from. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
The `GutenbergKit` target now excludes `Gutenberg/` in `Package.swift`—all web assets are served from the `GutenbergKitResources` target instead. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>
Separate the iOS and Android dist copy steps into dedicated Makefile targets so they can be run or debugged independently. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 <noreply@anthropic.com>


What?
Adds infrastructure to build and distribute
GutenbergKitResourcesas a pre-built XCFramework, decoupling the JS build from Swift consumers.Based on the research work done on #315 .
Why?
Currently, every Swift consumer must run the full JS build to get Gutenberg editor assets.
With a binary XCFramework for resources, consumers can pull a pre-built artifact from CDN instead, significantly reducing build times and simplifying integration.
How?
GutenbergKitResourcesSPM target wrapping bundled editor assets (HTML, CSS, JS)Package.swiftusesContext.environmentto switch between local source and CDN binary targetbuild_xcframework.shassembles a proper.frameworkfrom SPM archive DerivedData (binary, swiftmodule, modulemap, headers, resource bundles) since SPM archives don't produce installable frameworksreleaselane handles versioning, GitHub release, and S3 uploadGutenbergKittarget depends onGutenbergKitResourcesinstead of bundling assets directlypackageaccess modifiers migrated tointernal(required bypackageAccess: false)Testing Instructions
make build— builds web assets and copies to all platform directoriesmake build-swift-package— builds the Swift package with local resourcesmake build-resources-xcframework— producesGutenbergKitResources-<sha>.xcframework.zipios-arm64andios-arm64_x86_64-simulatorslices with the binary, Modules, Headers, and resource bundleGenerated with the help of Claude Opus 4.6