Skip to content

fix(godot): embed ios frameworks on export#148

Merged
hyochan merged 5 commits into
mainfrom
codex/fix-godot-ios-export
May 10, 2026
Merged

fix(godot): embed ios frameworks on export#148
hyochan merged 5 commits into
mainfrom
codex/fix-godot-ios-export

Conversation

@hyochan

@hyochan hyochan commented May 10, 2026

Copy link
Copy Markdown
Member

Summary

  • Register GodotIap iOS frameworks during Godot export so Xcode embeds and signs them automatically.
  • Ship and harden the post-export iOS fixer in the Godot release artifact for older or already-exported projects.
  • Update Godot setup docs to describe the automatic export path and fallback workflow.

Related: #146

Changes

Godot iOS export

  • Add iOS support to the Godot export plugin and register GodotIap.framework plus SwiftGodotRuntime.framework as embedded frameworks.
  • Keep compatibility with older Godot 4.x export APIs.
  • Add a parser-satisfying return path in the async product fetch helper.

Post-export fallback

  • Include scripts/fix_ios_embed.sh in the Godot release zip.
  • Let the script find any exported .xcodeproj, copy missing framework Info.plist files, normalize framework bundle references, and avoid duplicate framework link entries.

Docs

  • Update Godot iOS setup docs to make automatic embedding the primary path.
  • Keep manual Xcode and Info.plist workarounds as fallback guidance.

Test plan

  • bash -n libraries/godot-iap/scripts/fix_ios_embed.sh
  • git diff --check
  • make test in libraries/godot-iap (92 passed)
  • bun run typecheck in packages/docs
  • bun run lint in packages/docs
  • Godot iOS export to /tmp/openiap-godot-ios-export succeeded and produced archive/IPA
  • fix_ios_embed.sh applied to exported Xcode project
  • xcodebuild -project /tmp/openiap-godot-ios-export/Martie.xcodeproj -scheme Martie -sdk iphoneos -configuration Debug -destination 'generic/platform=iOS' build
  • pre-commit docs typecheck/audit/prettier hook passed

Summary by CodeRabbit

  • New Features

    • iOS export support added alongside Android
    • Export now automatically embeds required iOS frameworks
    • Packaged addon includes a post-export fixer script to correct Xcode framework embedding
  • Documentation

    • iOS setup guide updated with automatic embedding workflow and preferred post-export fixer
    • Manual Xcode fallback and Info.plist guidance clarified

Review Change Stack

Register GodotIap iOS frameworks during export and keep the post-export fixer available in release artifacts. Update the fixer to restore framework Info.plist files, normalize framework bundle references, and avoid duplicate Xcode framework links.

Document the automatic export path and fallback workflow for Godot iOS setup.
@coderabbitai

coderabbitai Bot commented May 10, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8cc9c506-0780-47c5-ab58-441006a0b7be

📥 Commits

Reviewing files that changed from the base of the PR and between afbbbbd and c8bdfb2.

📒 Files selected for processing (5)
  • knowledge/internal/05-docs-patterns.md
  • libraries/godot-iap/addons/godot-iap/godot_iap_plugin.gd
  • libraries/godot-iap/scripts/fix_ios_embed.sh
  • packages/docs/src/pages/docs/setup/godot.tsx
  • packages/docs/src/pages/docs/updates/releases.tsx
✅ Files skipped from review due to trivial changes (1)
  • packages/docs/src/pages/docs/setup/godot.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • libraries/godot-iap/addons/godot-iap/godot_iap_plugin.gd
  • libraries/godot-iap/scripts/fix_ios_embed.sh

📝 Walkthrough

Walkthrough

This PR adds iOS framework embedding support to the GodotIap plugin by enhancing the export plugin to detect iOS exports and register framework embedding, providing a comprehensive post-export Xcode fixup script, packaging the script in releases, and documenting the complete setup workflow.

Changes

iOS Framework Embedding Implementation

Layer / File(s) Summary
Export Plugin iOS Support
libraries/godot-iap/addons/godot-iap/godot_iap_plugin.gd
Export plugin now declares IOS_FRAMEWORKS constant, reports iOS platform support, detects iOS exports via feature flags, and integrates framework embedding into _export_begin with adaptive embedding API calls.
Runtime Fallback Safety
libraries/godot-iap/addons/godot-iap/godot_iap.gd
Add explicit empty dictionary return at end of _await_products_fetched_for(...) to ensure the function always returns a value.
Framework Embedding Script: Bash wrapper & path discovery
libraries/godot-iap/scripts/fix_ios_embed.sh
Bash wrapper adds strict settings, computes addon/export roots, auto-detects .xcodeproj, validates pbxproj, and supports env overrides.
Framework Embedding Script: Copy Info.plist
libraries/godot-iap/scripts/fix_ios_embed.sh
Copies Info.plist for GodotIap and SwiftGodotRuntime into exported framework bundles and backs up the pbxproj before Python modifications.
Framework Embedding Script: Normalize PBXFileReference
libraries/godot-iap/scripts/fix_ios_embed.sh
Python step normalizes framework PBXFileReference entries and locates their IDs; exits with warnings if references are missing after normalization.
Framework Embedding Script: Embed Phase Update
libraries/godot-iap/scripts/fix_ios_embed.sh
Ensures PBXBuildFile entries exist (reuse or hashed fallback) and appends missing entries to the Embed Frameworks PBXCopyFilesBuildPhase.
Framework Embedding Script: Duplicate Cleanup
libraries/godot-iap/scripts/fix_ios_embed.sh
Removes duplicate PBXBuildFile/PBXFileReference relationships and cleans PBXGroup entries to preserve canonical framework references.
Framework Embedding Script: Write & Finalize
libraries/godot-iap/scripts/fix_ios_embed.sh
Writes the updated project.pbxproj and prints completion messages.
Release Packaging
.github/workflows/release-godot.yml
Deploy job now creates dist/addons/godot-iap/scripts and copies executable fix_ios_embed.sh into the packaged addon distribution.
Documentation and Release Notes
packages/docs/src/pages/docs/setup/godot.tsx, packages/docs/src/pages/docs/updates/releases.tsx, knowledge/internal/05-docs-patterns.md
Updated Godot setup docs to describe automatic framework embedding, post-export fixer usage, manual Xcode fallback, Info.plist fallback; added release note for May 10, 2026 patch; refined internal release-note verification guidance.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped through Xcode night and day,

Copied plists and fixed the way,
Frameworks snug in export's cart,
GodotIap now plays its part,
Hooray — builds leap, bugs at bay!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding iOS framework embedding during Godot export. It is concise, specific, and directly reflects the primary objective of the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-godot-ios-export

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@hyochan hyochan added godot-iap godot-iap library 📱 iOS Related to iOS 📖 documentation Improvements or additions to documentation 💨 ci Cloud integration 🛠 bugfix All kinds of bug fixes ⌚ ux User Experience labels May 10, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request automates iOS framework embedding for the Godot IAP plugin by updating the export plugin and significantly improving the post-export fix script. The documentation has also been updated to reflect these changes. Key feedback includes correcting a typo in the Godot 4.3/4.4 API method name, tightening regex patterns in the fix script to avoid over-matching sub-files, and addressing fragility in the project file formatting logic.

Comment thread libraries/godot-iap/addons/godot-iap/godot_iap_plugin.gd
Comment thread libraries/godot-iap/scripts/fix_ios_embed.sh Outdated
Comment thread libraries/godot-iap/scripts/fix_ios_embed.sh Outdated
Comment thread libraries/godot-iap/scripts/fix_ios_embed.sh Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/docs/src/pages/docs/setup/godot.tsx (1)

209-226: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reading flow: "Then confirm the runpath" follows collapsed <details> content.

After the rewrite, the "Manual Xcode fallback" steps live inside a collapsible <details>, but the "The frameworks are located at" code block and the "Then confirm the runpath" instructions remain outside. With the disclosure collapsed (default), readers using the automatic export path will see "Then confirm the runpath" without any antecedent — and runpath setup is something Godot's export already wires up, so it is really part of the manual fallback flow.

Consider moving the framework paths and runpath steps into the <details> block, or rewording so they don't appear conditional on the collapsed steps.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/docs/src/pages/docs/setup/godot.tsx` around lines 209 - 226, The
"The frameworks are located at:" CodeBlock and the "Then confirm the runpath" ol
are currently outside the collapsible Manual Xcode fallback <details>, causing
them to appear when the details are collapsed and misleading readers; either
move the CodeBlock and the entire runpath instructions (the <ol> starting with
"Go to the Build Settings tab") into the same <details> block that contains the
"Manual Xcode fallback" content, or reword the heading/text to make it explicit
these steps apply only to the manual fallback flow (reference the existing
CodeBlock, the <ol> with "Runpath Search Paths" and the Manual Xcode fallback
<details> disclosure).
🧹 Nitpick comments (2)
libraries/godot-iap/addons/godot-iap/godot_iap_plugin.gd (1)

32-35: 💤 Low value

Add a typed array annotation for IOS_FRAMEWORKS.

Minor type-safety nit: Array[String] makes the contract explicit and lets the parser/editor catch accidental non-string entries.

♻️ Proposed change
-	const IOS_FRAMEWORKS = [
+	const IOS_FRAMEWORKS: Array[String] = [
 		"res://addons/godot-iap/bin/ios/GodotIap.framework",
 		"res://addons/godot-iap/bin/ios/SwiftGodotRuntime.framework",
 	]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libraries/godot-iap/addons/godot-iap/godot_iap_plugin.gd` around lines 32 -
35, The constant IOS_FRAMEWORKS should be declared with an explicit typed array
to ensure all entries are strings; update the declaration of IOS_FRAMEWORKS to
include the GDScript type annotation Array[String] (e.g. const IOS_FRAMEWORKS:
Array[String] = [...]) so the parser/editor enforces string-only entries for the
array.
libraries/godot-iap/scripts/fix_ios_embed.sh (1)

24-32: ⚡ Quick win

Silently picks first .xcodeproj when multiple exist.

find ... | sort | head -n 1 returns a single project without telling the user there were multiple. If a Godot iOS export ever places more than one .xcodeproj at the top level (or a user runs this against the wrong directory), the script will quietly fix the wrong one. A small guard makes the failure mode explicit while keeping the existing single-project happy path.

♻️ Proposed change
 if [ -z "$XCODEPROJ" ]; then
-    XCODEPROJ="$(find "$IOS_EXPORT_DIR" -maxdepth 1 -name "*.xcodeproj" -type d | sort | head -n 1)"
+    mapfile -t _xcodeprojs < <(find "$IOS_EXPORT_DIR" -maxdepth 1 -name "*.xcodeproj" -type d | sort)
+    if [ "${`#_xcodeprojs`[@]}" -gt 1 ]; then
+        echo "Error: multiple .xcodeproj found in $IOS_EXPORT_DIR:" >&2
+        printf '  %s\n' "${_xcodeprojs[@]}" >&2
+        echo "Set XCODEPROJ=/path/to/App.xcodeproj to disambiguate." >&2
+        exit 1
+    fi
+    XCODEPROJ="${_xcodeprojs[0]:-}"
 fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libraries/godot-iap/scripts/fix_ios_embed.sh` around lines 24 - 32, The
script silently chooses the first .xcodeproj when multiple exist by assigning
XCODEPROJ="$(find "$IOS_EXPORT_DIR" -maxdepth 1 -name "*.xcodeproj" -type d |
sort | head -n 1)"; change this logic to detect if more than one .xcodeproj is
present and fail fast: use the same find pipeline but capture all matches, count
them, and if count > 1 print an error listing the found projects and instruct
the user to set XCODEPROJ or correct IOS_EXPORT_DIR, then exit 1; if count == 1
continue and assign XCODEPROJ to that single path so the existing single-project
path remains unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/docs/src/pages/docs/setup/godot.tsx`:
- Around line 209-226: The "The frameworks are located at:" CodeBlock and the
"Then confirm the runpath" ol are currently outside the collapsible Manual Xcode
fallback <details>, causing them to appear when the details are collapsed and
misleading readers; either move the CodeBlock and the entire runpath
instructions (the <ol> starting with "Go to the Build Settings tab") into the
same <details> block that contains the "Manual Xcode fallback" content, or
reword the heading/text to make it explicit these steps apply only to the manual
fallback flow (reference the existing CodeBlock, the <ol> with "Runpath Search
Paths" and the Manual Xcode fallback <details> disclosure).

---

Nitpick comments:
In `@libraries/godot-iap/addons/godot-iap/godot_iap_plugin.gd`:
- Around line 32-35: The constant IOS_FRAMEWORKS should be declared with an
explicit typed array to ensure all entries are strings; update the declaration
of IOS_FRAMEWORKS to include the GDScript type annotation Array[String] (e.g.
const IOS_FRAMEWORKS: Array[String] = [...]) so the parser/editor enforces
string-only entries for the array.

In `@libraries/godot-iap/scripts/fix_ios_embed.sh`:
- Around line 24-32: The script silently chooses the first .xcodeproj when
multiple exist by assigning XCODEPROJ="$(find "$IOS_EXPORT_DIR" -maxdepth 1
-name "*.xcodeproj" -type d | sort | head -n 1)"; change this logic to detect if
more than one .xcodeproj is present and fail fast: use the same find pipeline
but capture all matches, count them, and if count > 1 print an error listing the
found projects and instruct the user to set XCODEPROJ or correct IOS_EXPORT_DIR,
then exit 1; if count == 1 continue and assign XCODEPROJ to that single path so
the existing single-project path remains unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6e166ce0-69e7-4d3a-8d9d-50acce231242

📥 Commits

Reviewing files that changed from the base of the PR and between 8612fd5 and afbbbbd.

📒 Files selected for processing (5)
  • .github/workflows/release-godot.yml
  • libraries/godot-iap/addons/godot-iap/godot_iap.gd
  • libraries/godot-iap/addons/godot-iap/godot_iap_plugin.gd
  • libraries/godot-iap/scripts/fix_ios_embed.sh
  • packages/docs/src/pages/docs/setup/godot.tsx

Tighten the iOS export fallback script, add an extra Apple framework API fallback, and move manual runpath guidance into the manual docs section.
@hyochan

hyochan commented May 10, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@hyochan

hyochan commented May 10, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@coderabbitai

coderabbitai Bot commented May 10, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request automates iOS framework embedding in Godot exports and enhances the robustness of the fix_ios_embed.sh script. Key changes include updating the Godot export plugin to register frameworks automatically, rewriting the post-export script to handle complex Xcode project structures and duplicate links, and updating documentation to reflect the improved workflow. Review feedback identifies an incorrect method name in the export plugin and suggests a more robust regex for parsing Xcode project files to accommodate varying indentation.

Comment on lines +66 to +71
if has_method("add_apple_embedded_platform_embedded_framework"):
call("add_apple_embedded_platform_embedded_framework", path)
return
if has_method("add_apple_embedded_framework"):
call("add_apple_embedded_framework", path)
return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The method name add_apple_embedded_platform_embedded_framework appears to be incorrect and does not exist in the Godot Engine source. The standard modern method for Godot 4.2+ is add_apple_embedded_framework. I recommend removing the redundant and incorrect check to simplify the logic while maintaining compatibility with older versions via the existing fallback.

		if has_method("add_apple_embedded_framework"):
			call("add_apple_embedded_framework", path)
			return

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No code change for this one. I checked the local Godot 4.6.2 binary and it exposes add_apple_embedded_platform_embedded_framework, add_apple_embedded_platform_framework, add_ios_embedded_framework, and add_ios_framework, but not add_apple_embedded_framework. Keeping add_apple_embedded_platform_embedded_framework preserves the modern Godot 4.6 path; add_apple_embedded_framework remains as an extra compatibility fallback before add_ios_embedded_framework.

Comment thread libraries/godot-iap/scripts/fix_ios_embed.sh Outdated
@hyochan hyochan merged commit 914fe74 into main May 10, 2026
9 checks passed
@hyochan hyochan deleted the codex/fix-godot-ios-export branch May 10, 2026 18:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🛠 bugfix All kinds of bug fixes 💨 ci Cloud integration 📖 documentation Improvements or additions to documentation godot-iap godot-iap library 📱 iOS Related to iOS ⌚ ux User Experience

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant