Skip to content

Harden local-notifications iOS patching for Capacitor 8 API drift in release builds#482

Merged
BunsDev merged 3 commits intomainfrom
copilot/fix-github-actions-ios-build
Apr 20, 2026
Merged

Harden local-notifications iOS patching for Capacitor 8 API drift in release builds#482
BunsDev merged 3 commits intomainfrom
copilot/fix-github-actions-ios-build

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 20, 2026

What Changed

The iOS release job was failing because the post-cap sync patch no longer fully normalized @capacitor/local-notifications Swift sources for the Capacitor APIs present in CI. This PR makes patching deterministic, version-aware, and fail-fast so CI does not proceed with partially patched plugin code.

  • Patch script hardening (scripts/patch-capacitor-local-notifications.ts)

    • Added strict preconditions: required files must exist; plugin version must parse and be major 8.
    • Switched to global replacement semantics (all occurrences), not first-hit replacement.
    • Expanded replacements to handle both upstream and previously patched variants:
      • getArray(..., JSObject.self) / optional-chain forms → getArray(..., []).compactMap(...)
      • incompatible call.reject(...) paths → compatible call.unimplemented(...) paths used in this environment.
    • Added post-patch verification gates:
      • required patched patterns must exist,
      • forbidden legacy patterns must be absent,
      • script exits with clear errors when expectations are not met.
  • Idempotency + maintainability

    • Script now cleanly no-ops on already patched sources.
    • Extracted legacy/required/forbidden pattern sets as constants to keep replacement and verification logic aligned.
  • Capacitor/workflow scope

    • Confirmed Capacitor packages are already aligned on major 8 in repo/lockfile; no dependency bump needed.
    • Existing iOS workflow order (patch after cap sync ios) remains unchanged.
const pluginLooksPatched = isPluginSwiftPatched(pluginUpdated);
assert(
  pluginHadKnownLegacyPattern || pluginLooksPatched,
  "Unsupported LocalNotificationsPlugin.swift layout; patch script needs to be updated for the installed plugin version.",
);
assert(pluginLooksPatched, "LocalNotificationsPlugin.swift patch verification failed.");

Why

The failure mode was “patch appears to run, Xcode still compiles incompatible Swift.” The right fix is to make patching explicit and verifiable against the installed plugin version so mismatches fail immediately with actionable errors instead of surfacing later as Swift compile failures in the iOS job.

UI Changes

None.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes
Original prompt

Implement the optimal and recommended fix for the failing GitHub Actions job in OpenKnots/okcode (run 24683396897, job 72187038780).

Context:

  • The failing job is from workflow .github/workflows/release.yml at commit 033947daf1cfe7756cc574512944e9bde7c71752.
  • Failure occurs during iOS build with Xcode 15.4 compiling Capacitor Local Notifications plugin.
  • Logs show Swift compile errors in node_modules/@capacitor/local-notifications/ios/Sources/LocalNotificationsPlugin/LocalNotificationsPlugin.swift including:
    • call.getArray("notifications") now requires a second parameter default value (getArray(_ key: String, _ defaultValue: Capacitor.JSArray) -> Capacitor.JSArray).
    • Optional chaining ?. used on non-optional return.
    • CAPPluginCall has no member reject.
    • Another call: call.getArray("notifications", JSObject.self) type mismatch.
  • Workflow already runs bun run patch:capacitor-local-notifications (script scripts/patch-capacitor-local-notifications.ts) before and after bunx cap sync ios --deployment, but patch is not effective or out of date.

Goal:

  • Apply an optimal, robust fix so the iOS build no longer fails.

Recommended approach:

  1. Determine installed Capacitor major versions in this repo and align @capacitor/local-notifications with @capacitor/core/@capacitor/ios (pin compatible versions in the appropriate package.json within apps/mobile and/or workspace root as needed). Update lockfile accordingly.
  2. Update scripts/patch-capacitor-local-notifications.ts to patch the current plugin source in a version-aware, idempotent way, and add verification so CI fails early if the expected patterns are not found or the patch didn’t apply.
  3. Ensure the iOS workflow step order remains correct (patch after cap sync ios, and remove redundant patch step if unnecessary) while keeping behavior stable.

Deliverables:

  • Code changes in the repository to:
    • Align Capacitor packages and/or adjust dependency versions.
    • Fix/update the patch script so it actually patches the plugin code for the installed versions.
    • Add clear errors/logging and verification.
  • Ensure bun install --frozen-lockfile still works in CI.
  • Provide concise explanation in PR description.

Reference:

  • Workflow file: .github/workflows/release.yml (commit 033947d).
  • Job logs show compile errors in LocalNotificationsPlugin.swift around lines 60, 61, 126, 164, 165, 204, 292, 605, 606.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: Please find a solution for this failing job. Use the logs, job definition, and any referenced files where the failure occurred. Keep your response focused on the solution and include code suggestions when appropriate.

Assistant: The job is failing during the iOS build because the Swift sources inside node_modules/@capacitor/local-notifications no longer compile with the Capacitor API your build is using (Xcode 15.4 is just where it gets surfaced). The errors show an API mismatch:

  • call.getArray("notifications") now requires a default value (getArray(_ key: String, _ defaultValue: JSArray) -> JSArray)
  • call.getArray(...) returns a non-optional JSArray, so ?.compactMap(...) is invalid
  • CAPPluginCall has no member reject (your Capacitor version expects call.reject(...) to be replaced with call.reject(<message>, <code?>, <error?>, <data?>) or call.reject(...) is no longer available and you should be using the newer error APIs (varies by Capacitor major)

The fix: stop compiling incompatible plugin code

You have already anticipated this in your workflow: the iOS job runs “Patch Capacitor local-notifications for Xcode 15”:

  • .github/workflows/release.yml lines 361-370 run:
    • bun run patch:capacitor-local-notifications
    • then bunx cap sync ios --deployment
    • then patch again

But the compilation errors prove the patch either:

  1. isn’t being applied correctly, or
  2. is applying a patch for a different Capacitor major than what is installed, or
  3. the plugin version drifted and your patch script no longer matches.

Recommended solution (robust): pin compatible versions + regenerate the patch

  1. Align Capacitor core and local-notifications to the same major version

    • In your repo, ensure these are the same major:
      • @capacitor/core
      • @capacitor/ios
      • @capacitor/local-notifications
    • Then update lockfile and reinstall.

    Concretely, pick one track:

    • Option A (fastest): downgrade local-notifications to match your current Capacitor
      • If you’re on Capacitor 6, pin @capacitor/local-notifications@6.x
      • If you’re on Capacitor 7, pin @capacitor/local-notifications@7.x
    • Option B: upgrade Capacitor core/ios to match the plugin version you’re getting
      • Upgrade all @capacitor/* packages together.
  2. **Fix the patch script so it patches the *curre...

This pull request was created from Copilot chat.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
okcode-marketing Ready Ready Preview Apr 20, 2026 7:17pm
v0-compute-the-platform-to-build Ready Ready Preview, Open in v0 Apr 20, 2026 7:17pm

Copilot AI changed the title [WIP] Fix GitHub Actions job failure during iOS build Harden local-notifications iOS patching for Capacitor 8 API drift in release builds Apr 20, 2026
Copilot AI requested a review from BunsDev April 20, 2026 19:18
@BunsDev BunsDev marked this pull request as ready for review April 20, 2026 19:18
@BunsDev BunsDev merged commit d5848ba into main Apr 20, 2026
4 checks passed
@github-actions github-actions Bot added size:L vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants