Skip to content

ci(ffi): publish prebuilt mobile binaries as Release assets (#4)#5

Merged
nandal merged 3 commits into
mainfrom
feat/mobile-binary-releases
Jun 23, 2026
Merged

ci(ffi): publish prebuilt mobile binaries as Release assets (#4)#5
nandal merged 3 commits into
mainfrom
feat/mobile-binary-releases

Conversation

@nandal

@nandal nandal commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Phase 1 of #4 — make the native Veil binaries downloadable so a consuming Flutter app (e.g. maktub-app) no longer needs a Rust + iOS/Android cross toolchain to do a device build.

Why

The warden_ffi Dart binding is on pub.dev, but the native libs it wraps are git-ignored and published nowhere. Today every build machine must check out warden and run build-mobile.sh itself. The binary is platform-specific but not machine-specific → build once, publish, consume.

What's in this PR

  • .github/workflows/mobile-release.yml — on a v* tag, cross-compile via the existing build-mobile.sh (iOS on macos-latest, Android on ubuntu-latest) and attach to the Release:

    • WardenFfi.xcframework.zip
    • warden-ffi-android-jniLibs.zip
    • SHA256SUMS

    Tag-triggered, not per-merge — keeps the binary version in lockstep with the warden_ffi pub.dev version (cut both from the same tag). workflow_dispatch runs the builds without releasing (the release job is tag-gated) for smoke-testing.

  • .github/workflows/mobile-ci.yml — path-filtered build-check (PR + push to main, scoped to core/**, ffi/**, Cargo/toolchain): cross-compiles both platforms + runs cargo test -p warden-ffi. Catches a broken mobile build without cutting a release.

  • Docs — top README.md, ffi/README.md, ffi/dart/README.md now point consumers at the Release assets (no toolchain), keeping build-from-source for warden devs.

Design notes

  • Why Releases, not GitHub Packages: Packages has no pub or CocoaPods/SwiftPM registry, and its Maven registry needs a token even for public reads. A Release asset downloads anonymously and is consumable from both a podspec and gradle — one store, all platforms, no auth.
  • Reuses build-mobile.sh unchanged (the already-verified static-xcframework + 4-ABI jniLibs path). No iOS linking changes here.

Reuse note

mobile-ci.yml and mobile-release.yml duplicate the build steps. Kept separate for clarity (check vs. publish, different triggers); a composite action could DRY them later if the steps grow.

Verification

  • actionlint clean on both workflows; YAML parses.
  • ⚠️ The workflows themselves run on GitHub's runners — they can't execute locally. First real run happens on merge (CI) and on the first v0.1.0-dev.1 tag (release). The cross-compiles they invoke are the same build-mobile.sh commands already used by hand.

Follow-up (Phase 2, tracked in #4)

warden_ffi_flutter plugin that downloads these assets at build time so consumers add one pub.dev dependency and nothing else. Separate PR because it needs an iOS static-vs-dynamic-framework decision + real-device verification.

🤖 Generated with Claude Code

nandal and others added 3 commits June 24, 2026 04:36
Consumers (e.g. maktub-app) currently must check out warden and cross-compile
the native Veil libs themselves — a full Rust + iOS/Android toolchain — because
the binary is git-ignored and distributed nowhere. The binary is platform- but
not machine-specific, so it should be built once and published.

- mobile-release.yml: on a `v*` tag, cross-compile via build-mobile.sh on
  macos/ubuntu runners and attach WardenFfi.xcframework.zip +
  warden-ffi-android-jniLibs.zip + SHA256SUMS to the Release. Tag-triggered so
  the binary version stays in lockstep with the warden_ffi pub.dev version
  (both cut from one tag); workflow_dispatch builds without releasing.
- mobile-ci.yml: path-filtered build-check (PR + main) that cross-compiles both
  platforms and runs the FFI host round-trip, so a mobile-build break surfaces
  early without cutting a release.
- docs: README, ffi/README, ffi/dart/README now point consumers at the Release
  assets (no toolchain) and keep build-from-source for warden devs.

Phase 1 of #4. The turn-key warden_ffi_flutter plugin (which downloads these
assets at build time) is the follow-up; it needs real-device verification.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cargo-ndk 4.x requires rustc 1.86; the toolchain is pinned at 1.83
(rust-toolchain.toml), so the unpinned install failed. 3.5.4 is the last
line that builds on 1.83, and pinning keeps the cross-compile reproducible.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
${{ env.ANDROID_NDK_LATEST_HOME }} resolved to empty — the env expression
context only holds workflow-defined vars, not runner-provided ones. The runner
exposes the NDK path as the shell var $ANDROID_NDK_LATEST_HOME, so set
ANDROID_NDK_HOME inline in the run command instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nandal
nandal merged commit dfa15bc into main Jun 23, 2026
3 checks passed
@nandal
nandal deleted the feat/mobile-binary-releases branch June 23, 2026 23:16
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