Skip to content

ci: assert the plugin actually linked into the iOS build - #152

Merged
hpoul merged 1 commit into
mainfrom
ci-assert-plugin-linked
Aug 25, 2026
Merged

ci: assert the plugin actually linked into the iOS build#152
hpoul merged 1 commit into
mainfrom
ci-assert-plugin-linked

Conversation

@hpoul

@hpoul hpoul commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

The iOS job asserts two things today: the build exited 0, and no Podfile came back. Neither says this package ended up inside the binary.

A plugin that fails to link produces a perfectly successful build. The failure surfaces on a user's device as MissingPluginException: No implementation found for method init on channel biometric_storage — the shape of #136. A wrong product name in Package.swift, a source_files glob that stops matching after a file move, or a typo in the pubspec plugin: block would all ship green.

So the job now asks the artifact rather than the exit code:

biometric_storage symbols in the binary: 179

This is the check I ran by hand during the SwiftPM migration in #150 — it is how I knew the migration worked rather than merely compiled. It just never became a CI step.

Why it is worth having even though a silent drop is unlikely. The generated registrant does import biometric_storage and calls BiometricStoragePlugin.register(...), so a missing module fails to compile. But the module can exist while the product links nothing, and that is precisely the case this catches.

Verified all three arms locally, because a check that cannot fail is worthless:

against symbols result
Runner.app/Runner 179 passes
Flutter.framework/Flutter (no plugin) 0 fails
a path that does not exist fails, rather than passing vacuously

That last arm matters: without it, a rename of the build output would turn the assertion into a no-op that stays green forever.

Costs one step and no build time.

🤖 Generated with Claude Code

The iOS job proved the example compiled and that no Podfile came back. Neither
says this package ended up inside the binary — a plugin that fails to link
builds perfectly and fails on a user's device with MissingPluginException,
which is the shape of #136. A wrong product name in Package.swift, a
source_files glob that stops matching after a file move, or a typo in the
pubspec plugin block would all ship green.

So ask the artifact rather than the exit code: nm the built Runner for the
package's symbols. On the current build there are 179.

The registrant importing the module makes a fully silent drop unlikely — it
would fail to compile — but the module can exist while the product links
nothing, and that is the case this catches.

Verified all three arms locally against real binaries: 179 symbols in Runner
(passes), 0 in Flutter.framework (fails), and a missing path fails rather than
passing vacuously.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@hpoul
hpoul merged commit d9d4641 into main Aug 25, 2026
15 checks passed
@hpoul
hpoul deleted the ci-assert-plugin-linked branch August 25, 2026 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant