Repository navigation
fix: publish SwiftPM binary in pub package, Android bindgen/exit codes, CI startup - #25
Merged
Merged
Conversation
The precompile workflow never declared PRECOMPILE_BINARIES_PRIVATE_KEY under workflow_call, so callers that pass it explicitly were rejected at startup with 'Invalid secret, PRECOMPILE_BINARIES_PRIVATE_KEY is not defined in the referenced workflow.' Every build-all-platforms run since the secret passthrough landed has been a startup_failure. Also read the publish token from github.token, which stays available to called workflows under explicit secret maps.
The tag publish job checked out the tag, which never contains darwin/fjs/Binaries/fjs.xcframework.zip, so published packages shipped an empty Binaries directory and Swift Package Manager resolution failed with a missing FjsBinary archive (#24). Add a fetch-precompiled-artifacts build tool command that downloads the signed composite through the existing asset store (verifying the generation manifest, signatures, digests, and checksum bindings) and materialize the zip before flutter pub publish, with a hard existence gate so a regression cannot publish silently.
…ailures Bindgen resolves libclang from CLANG_PATH, so pin it to the NDK clang; a host LLVM installation has mismatched resource headers and cannot find stdbool.h when compiling against the NDK sysroot on Windows (#23). The armv7 include directory also has to use the NDK LLVM triple (arm-linux-androideabi), which drops the v7 suffix. run_build_tool.cmd now captures the Dart exit code and returns it with exit /b (including after the snapshot-rebuild retry path). Previously a failed Rust build could leave Gradle reporting success with no libfjs.so in the APK (#23).
Bump the synchronized version fields and record the fixes for the missing SwiftPM binary in published packages, Android bindgen/exit-code handling on Windows, and the CI workflow startup regression.
iota9star
force-pushed
the
fix/pub-and-android-issues
branch
from
September 29, 2026 14:00
26fd761 to
8034583
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Expected asset inventory omits valid non-checksum composite outputs, causing verification and fetching to reject supported manifests.
Review effort: Balanced
Findings: 1
What changed in this PR
Fixes SwiftPM publishing, Android bindgen configuration, Windows exit-code propagation, and reusable workflow startup.
Changes:
- Fetches and verifies SwiftPM binaries before pub.dev publishing.
- Corrects Android NDK clang settings and Windows build failures.
- Updates release metadata to 3.3.1.
| File | Description |
|---|---|
.github/workflows/precompile-binaries.yml |
Declares the signing secret and uses github.token. |
.github/workflows/publish-pub.yml |
Fetches and validates the SwiftPM archive before publishing. |
CHANGELOG.md |
Documents 3.3.1 fixes. |
cargokit/build_tool/lib/src/android_environment.dart |
Configures NDK clang and armv7 includes. |
cargokit/build_tool/lib/src/build_tool.dart |
Registers the artifact-fetch command. |
cargokit/build_tool/lib/src/fetch_precompiled_artifacts.dart |
Implements verified composite artifact retrieval. |
cargokit/build_tool/lib/src/verify_binaries.dart |
Shares expected-generation inventory logic. |
cargokit/build_tool/test/android_environment_test.dart |
Tests Android environment changes. |
cargokit/run_build_tool.cmd |
Propagates Dart exit codes. |
darwin/fjs.podspec |
Updates version to 3.3.1. |
example/pubspec.lock |
Refreshes package versions. |
ios/fjs.podspec |
Updates version to 3.3.1. |
libfjs/Cargo.lock |
Updates the crate version. |
libfjs/Cargo.toml |
Updates the crate version. |
macos/fjs.podspec |
Updates version to 3.3.1. |
pubspec.yaml |
Updates package version to 3.3.1. |
tool/check_darwin_package_support.sh |
Updates release invariants and workflow checks. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+40
to
+49
| for (final group in precompiled.compositeGroups) { | ||
| for (final checksum | ||
| in group.outputs.where((output) => output.endsWith('.checksum'))) { | ||
| final archive = checksum.substring(0, checksum.length - '.checksum'.length); | ||
| if (group.outputs.contains(archive)) { | ||
| result.add(archive); | ||
| result.add(checksum); | ||
| } | ||
| } | ||
| } |
h2 0.4.13 -> 0.4.19 (RUSTSEC-2026-0258) and rustls 0.23.38 -> 0.23.45 (RUSTSEC-2026-0285). The advisories were published after CI stopped starting workflows, so the audit gate never saw them until now.
rquickjs moves from the 0.12.1 pin to master 3d5ecfc9 (0.14.0) and the llrt crates move from 952fd20 to main 89941ae1. rquickjs 0.14 makes ArrayBuffer/TypedArray::as_bytes unsafe because the slice aliases engine memory; the three call sites copy the bytes before any JavaScript can run, which the new SAFETY comments record.
The FRB reproducibility check regenerates the bindings and compares bytes against the committed files, so an unpinned nightly rustfmt makes the gate hostage to whatever nightly the runner installs that day. Pin the toolchain in both the check script and the workflow so regeneration stays deterministic.
The proxy-methods-while-initializing test released the blocked init before close() had necessarily transitioned the engine state, so the resumed init could win the race to finish_init and succeed. Wait for close()'s state transition (which happens on its first poll) before releasing the block; observed as a Linux CI failure after the rquickjs 0.14 upgrade shifted the scheduling.
dlopen2 0.9.0 (pulled in by rquickjs 0.14 dyn-load) dropped its once_cell dependency while raw/unix.rs still imports it on every non-linux/non-macos target, so android builds failed with E0433. Vendor the crate with a std::sync::LazyLock swap until upstream releases a fix. FRB regeneration drifted on CI because cargo-expand auto-installs the latest release, whose expansion output differs from the one the committed files were generated with. Pin cargo-expand 1.0.126, regenerate, and enforce the pin in the codegen check.
A caret constraint let CI's lock-free root resolution pick newer FRB runtimes (2.13.0 just published), and the generator's auto-upgrade then rewrote pubspec.yaml to the exact codegen version, failing the clean-tree gate. FRB enforces runtime == codegen at run time anyway, so the exact cap encodes the real constraint.
The gate scans build-log paragraphs, and the runner sdk manager's mid-build CMake install now logs an analytics.settings lock warning inside the same paragraph as the cargokit env dump; the Flutter tool also nags about this leg's intentionally old Gradle/AGP/Kotlin pins. Neither is a cargokit deprecation, so skip records containing them.
Replace the vendored third_party/dlopen2 with a [patch.crates-io] git reference to iota9star/dlopen2 (upstream PR OpenByteDev/dlopen2#29) so no third-party source lives in this repository; drop it once upstream releases the android fix. Cap the root flutter_rust_bridge constraint to >=2.12.0 <2.13.0: an exact pin made pub's dry-run warn about overly tight constraints, while a caret let CI resolve 2.13.0 and trip the generator's auto-upgrade rewrite. The range keeps resolution on the pinned codegen minor line without the warning. Use floating nightly for the FRB toolchain instead of a pinned nightly date.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Fixes the broken CI pipeline (every
Build All Platformsrun has failed to start or complete since August 13) and the two open packaging issues, upgrades the Rust engine dependencies, and prepares release 3.3.1.Issues fixed
darwin/fjs/Binaries/fjs.xcframework.zip, so Swift Package Manager resolution failed with a missingFjsBinaryarchive. The tag-triggered publish workflow now materializes the signed SwiftPM composite from the verified precompiled generation beforeflutter pub publishand hard-fails when the binary is absent. SwiftPM and CocoaPods remain supported: SPM consumes the package-local zip, CocoaPods keeps building from source through the unchangedcargokit/build_pod.shscript phase.CLANG_PATHto the NDK clang and uses the NDK LLVM triple directory (arm-linux-androideabi) for armv7 include paths.CI startup and stability
PRECOMPILE_BINARIES_PRIVATE_KEYon the reusable precompile workflow; CI had rejected every workflow startup since the secret passthrough was introduced.cargokit/run_build_tool.cmdnow propagates the build tool exit code (including after the snapshot-rebuild retry), so Windows Gradle builds fail instead of silently producing an APK withoutlibfjs.so.cargo-expand1.0.126 for FRB regeneration (release drift re-prints expanded code and shifted generated trait-ignore headers) and capped the rootflutter_rust_bridgeconstraint to>=2.12.0 <2.13.0(fresh CI resolutions picked 2.13.0 and tripped the generator auto-upgrade into rewritingpubspec.yaml). The Rust toolchain uses floating nightly, as before.test_engine_runtime_proxy_methods_fail_while_initializingby waiting forclose()to transition the state before releasing the blocked init.h2(RUSTSEC-2026-0258) andrustls(RUSTSEC-2026-0285) to clear the RustSec audit gate.Dependency upgrades
rquickjs0.12.1 → 0.14.0 (DelSkayn/rquickjs@3d5efc9);ArrayBuffer/TypedArraybyte reads now copy before JavaScript can run, as the newas_bytescontract requires.llrtcrates moved to main89941ae1.dlopen2(pulled in by rquickjsdyn-load) 0.9.0 is broken on Android — upstream removed itsonce_celldependency while still importing it on non-linux/non-macos targets (E0433). Patched via[patch.crates-io]to a one-line fix in iota9star/dlopen2, proposed upstream as Fix android build: replace once_cell Lazy with std LazyLock OpenByteDev/dlopen2#29; drop the patch line once upstream releases.Release
Version bumped to 3.3.1 everywhere (pubspec, Cargo.toml/lock, podspecs, self-check invariants) with a CHANGELOG section. Full CI matrix green on the final commit (quality gates, Darwin package, Android x3 + Gradle 8.9/9.1 legs, Linux, Windows).