Skip to content

Add an Android workflow, for Swift packages to build the Android SDK and test against #83

Closed

Description

@finagolfin

I've had requests for an Android workflow, both using my unofficial SDK, finagolfin/swift-android-sdk#127, and for whenever an official Android SDK is available. Rather than waiting for an official Android SDK first, I thought I could put together an Android workflow here that builds the Android SDK from source on first use, then uses it to cross-compile that Swift package that invoked this workflow on its CI and run its tests in the Android emulator, before finally caching the freshly-built Android SDK on that Swift package's CI for subsequent test runs.

Here are some further details:

  • I'd start off with Swift 6.1 only, building from the latest snapshot tag, then add other release branches later.
  • linux-only for build host initially, add macOS later
  • I currently download some pre-compiled libraries for Android from another OSS project for my SDK bundle supporting Android API 24: a backported posix_spawn() wrapper to Android API 24 and libcurl/libxml2 for Foundation. I'd simply require Android API 28, when posix_spawn() was added to Android, and remove FoundationNetworking and FoundationXML support for this workflow, looking into ways to add those back later, so no such external libraries would be required for this workflow.
  • I'd simply use an existing external Android emulator workflow, as I do on my Android CI. We could look into removing that external dependency later, if wanted.
  • Once an official Android SDK is available, we could make that the default, and make this fresh build an alternate option for those who want it.

@FranzBusch or @shahmishal, let me know if you'd be okay with adding such an Android workflow here, will put together a pull if so.

Activity

  1. marcprux commented on Jan 14, 2025

    @marcprux
    Contributor

    We might want to base this on https://github.com/marketplace/actions/swift-android-action, which supports building and testing on both Linux and macOS (Intel) hosts, as well as caching the SDK, host toolchain, and emulator.

    The SDK is currently downloaded from a mirror of https://github.com/finagolfin/swift-android-sdk/releases, but adding a step to optionally build it from source would be a possibility, at least for Linux.

  2. finagolfin commented on Jan 14, 2025

    @finagolfin
    MemberAuthor

    Fine by me, if you've done the work already and want to submit it here.

  3. marcprux commented on Jan 14, 2025

    @marcprux
    Contributor

    if you've done the work already [...]

    Well, I wouldn't quite say that, yet :). Getting this working would essentially require mashing your SDK build step (sdks.yml#L109) into a pre-build step of swift-android-action's action.yml#L154. This could be optimized somewhat, since the SDK bundle that is produced could just contain the host architecture (rather than each of aarch64, x86_64, and armv7, as your general SDK release includes).

    I'm wondering a few things:

    1. Where do we get the patches that you apply? Or do we envision that this will only work with a Swift source checkout that doesn't need any Android patches?
    2. Why do you propose excluding the external libraries that get-packages-and-swift-source.swift fetches? We might be able to do without FoundationXML and FoundationNetworking, but could we have a useful SDK without ICU?
    3. Would the caller of the workflow be expected to specify a specific tag parameter (like swift-DEVELOPMENT-SNAPSHOT-2025-01-10-a), or would it be swift-DEVELOPMENT-SNAPSHOT-latest, and the script would dynamically fetch the most recent tag?
    4. None of this would work on macOS until the build-script is capable of cross-compiling the Android SDK. But I think we can live with that.
  4. finagolfin commented on Jan 14, 2025

    @finagolfin
    MemberAuthor

    This could be optimized somewhat, since the SDK bundle that is produced could just contain the host architecture (rather than each of aarch64, x86_64, and armv7, as your general SDK release includes).

    More than that, it wouldn't have to be a bundle, but just an Android SDK with a destination config file for this workflow.

    Where do we get the patches that you apply?

    In this repo? Or directly in the workflow script if external patch files won't work somehow. I just checked and my current SDK build only has to patch 8-9 lines in 6.1/6.2 for Android, and I'm about to upstream those too.

    Why do you propose excluding the external libraries that get-packages-and-swift-source.swift fetches?

    Cutting down the dependency tree further, that's all.

    We might be able to do without FoundationXML and FoundationNetworking, but could we have a useful SDK without ICU?

    Um, libicu's already been removed as an external dependency, 😃 so I'd just use the swift-foundation-icu package instead.

    Would the caller of the workflow be expected to specify a specific tag parameter (like swift-DEVELOPMENT-SNAPSHOT-2025-01-10-a), or would it be swift-DEVELOPMENT-SNAPSHOT-latest, and the script would dynamically fetch the most recent tag?

    Both shouldn't be hard.

    None of this would work on macOS until the build-script is capable of cross-compiling the Android SDK.

    That's been working for awhile: I think you had it working through llbuild too, which is more than the SDK needs. Of course, there may have been regressions since, but I expect to look into and figure that out soon.

  5. finagolfin commented on Sep 13, 2025

    @finagolfin
    MemberAuthor

    After further discussion, I don't think the approach in #106 will be accepted, as I don't think this repo accepts pulls that simply pull in external public workflows, I believe for security concerns. Now that there is an official Docker build for Android and plans for official Android SDKs built using that, we should instead put together a workflow using those SDKs.

    Then the question becomes how to test for Android: whether we can invoke a popular Android emulator action here or if we need to set the emulator up ourselves too.

  6. marcprux commented on Sep 13, 2025

    @marcprux
    Contributor

    Agreed. Once the Android snapshot is published, I was planning on filing a new PR (or else updating #106) to follow the pattern of the WASM and Static Linux SDKs to install the Android SDK like:

    install_sdks() {
    if [[ "$INSTALL_STATIC_LINUX" == true ]]; then
    log "Starting install of Swift ${SWIFT_VERSION_INPUT} Static Linux Swift SDK"
    install_static_linux_sdk
    fi

    That will at least allow us to build packages against the SDK.

    As for testing, using the android-emulator-runner would obviously be the most expedient; we could even fork it (or snarf it into this repo) if security is the main concern against re-using it (@shahmishal?). Alternatively, we could just pin the version to a commit hash, which is a common way to protect against workflow supply-chain attacks.

    Ultimately, though, the android-emulator-runner workflow isn't doing anything especially magical that we couldn't re-implement ourselves: it is just installing and configuring an Android emulator and launching it. But it would be a shame to discard their years of fixes and tweaks and optimizations that make it the go-to for Android testing.

  7. finagolfin commented on Dec 19, 2025

    @finagolfin
    MemberAuthor

    @ahoppen, would you add this to the Android project board? It would be good to have this listed there, but I don't seem to have the permissions in this repo to add it.

  8. ahoppen commented on Dec 21, 2025

    @ahoppen
    Member

    would you add this to Swift on Android? It would be good to have this listed there, but I don't seem to have the permissions in this repo to add it.

    Done. Added it to the Todo section. Let me know if I should move it.

  9. moved this from Todo to In Progress in Swift on Androidon Dec 21, 2025
  10. finagolfin commented on Dec 21, 2025

    @finagolfin
    MemberAuthor

    No problem, I can do that myself: I just don't have the permissions to add projects on this repo, thanks. 👍

  11. finagolfin commented on Jan 6, 2026

    @finagolfin
    MemberAuthor

    With Marc's work in #172 and #215, this has been set up in a different way with the official SDK snapshots.

  12. moved this from In Progress to Done in Swift on Androidon Jan 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions