Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 53 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ jobs:
id: cache-ndk
uses: actions/cache@v5
with:
path: ~/android-ndk-${{ matrix.ndk_version }}
key: android-ndk-${{ runner.os }}-${{ runner.arch }}-${{ matrix.ndk_version }}
path: ~/android-ndk-${{ matrix.ndk_version }}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid downloading the NDKs altogether, since the Github runners already have several NDKs installed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pre-installed NDKs change over time, and they don't have 30-beta-1 (see https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md#android and https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md#android). Best to just download and cache, methinks — plus it is closer to what an end-user will need to be doing as part of the Swift SDK for Android setup.


- name: Install Android NDK
if: steps.cache-ndk.outputs.cache-hit != 'true'
Expand All @@ -89,9 +89,10 @@ jobs:
- name: Set ANDROID_NDK_HOME
run: echo "ANDROID_NDK_HOME=$HOME/android-ndk-${NDK_VERSION}" >> "$GITHUB_ENV"

- name: Install Android Swift SDK and matching host toolchain
# Looks up the Android Swift SDK URL and checksum from the swift.org
# install API and installs it via `swift sdk install`.
- name: Resolve Android Swift SDK download URL
id: resolve-sdk
# Look up the Android Swift SDK URL and checksum from the swift.org
# install API.
run: |
set -euxo pipefail
case "$SWIFT_VERSION" in
Expand Down Expand Up @@ -132,13 +133,13 @@ jobs:
swift_install=${swift_install#swift-}
swift_install=${swift_install/-RELEASE/}

echo "Installing Android Swift SDK and host toolchain"
echo " tag: $swift_install"
echo " url: $sdk_url"
echo " checksum: $sdk_checksum"
swiftly install "${swift_install}"
swift sdk install "$sdk_url" --checksum "$sdk_checksum"
swift sdk list
sdk_filename="${snapshot_tag}_android.artifactbundle.tar.gz"

echo "snapshot_tag=${snapshot_tag}" >> "$GITHUB_OUTPUT"
echo "sdk_url=${sdk_url}" >> "$GITHUB_OUTPUT"
echo "sdk_checksum=${sdk_checksum}" >> "$GITHUB_OUTPUT"
echo "swift_install=${swift_install}" >> "$GITHUB_OUTPUT"
echo "sdk_filename=${sdk_filename}" >> "$GITHUB_OUTPUT"

# Override the matrix-supplied SWIFT_VERSION (e.g. "6.3") with the
# resolved patch version (e.g. "6.3.1") so the gradle scripts pick up
Expand All @@ -148,6 +149,45 @@ jobs:
echo "SWIFT_VERSION=${swift_install}" >> "$GITHUB_ENV"
echo "SWIFT_ANDROID_SDK_VERSION=${snapshot_tag#swift-}_android" >> "$GITHUB_ENV"

- name: Cache Android Swift SDK artifact
id: cache-swift-sdk
uses: actions/cache@v5
with:
key: ${{ steps.resolve-sdk.outputs.sdk_filename }}
path: ~/swift-sdk-cache/${{ steps.resolve-sdk.outputs.sdk_filename }}

- name: Download Android Swift SDK artifact
if: steps.cache-swift-sdk.outputs.cache-hit != 'true'
run: |
set -euxo pipefail
mkdir -p "$HOME/swift-sdk-cache"
curl -L -o "$HOME/swift-sdk-cache/${{ steps.resolve-sdk.outputs.sdk_filename }}" --retry 3 "${{ steps.resolve-sdk.outputs.sdk_url }}"
echo "${{ steps.resolve-sdk.outputs.sdk_checksum }} $HOME/swift-sdk-cache/${{ steps.resolve-sdk.outputs.sdk_filename }}" | shasum -a 256 -c -

- name: Cache Host Toolchain
# Disabled because we are overflowing the 10GB GitHub cache limit with this
# https://github.com/swiftlang/swift-android-examples/pull/44#discussion_r3236006987
if: false
id: cache-swiftly-toolchain
uses: actions/cache@v5
with:
key: swiftly-${{ runner.os }}-${{ runner.arch }}-${{ steps.resolve-sdk.outputs.swift_install }}
path: |
~/Library/Developer/Toolchains
~/.local/share/swiftly
~/.local/bin/swiftly
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, this is going to overload the runner cache for this repo quickly, since it only holds 10 GBs, which is almost how much the six toolchains we download use.

Since the runners normally have the release toolchains installed, can we just check that version and skip downloading it for the installed one, if it already is the latest?

For the snapshot swiftly cache, is there some way to evict the cache of older toolchains on every run? Otherwise, this will balloon up quickly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, we are overflowing the cache (https://github.com/swiftlang/swift-android-examples/actions/caches) with just the 3 host toolchains (6.3, nightly-6.3, and nightly-main) for the two platforms (Ubuntu + macOS).

Since the runners normally have the release toolchains installed, can we just check that version and skip downloading it for the installed one, if it already is the latest?

Even if we could rely on the right host toolchain being installed (which would require us to re-work how we use swiftly, since swiftly won't know about the pre-installed toolchain), the runners won't ever have nightly-main or nightly-6.3 pre-installed, so that won't leave enough room for NDK + Swift SDK for Android.

So either we pare down the matrix (e.g., drop nightly-6.3, or drop macOS or Ubuntu), or I guess we can't cache either the host toolchain or the Swift SDK for Android. How annoying.

Any suggestions for what to drop?

Copy link
Copy Markdown
Member

@finagolfin finagolfin May 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The already installed NDKs and the release Swift toolchain is my suggestion. I know it's more logic in the workflow, but it will avoid unnecessary rebuildsdownloads from random cache eviction, which I've seen in my old Android CI too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For macOS, it looks like they only include the Xcode swift toolchain, not the OSS. And in any case, the release Swift toolchain lags behind the latest, sometimes significantly. For example, Swift 6.3.2 was just released, so Ubuntu's 6.3.1 wouldn't match and so we'd need to download and install it anyway.

I'm just going to disable the swiftly caching for now and look at it again in a future PR. At least we will still get the benefit of caching the NDKs and the Swift SDKs for now.


- name: Install host toolchain and Android Swift SDK
run: |
set -euxo pipefail
echo "Installing Android Swift SDK and host toolchain"
echo " tag: ${{ steps.resolve-sdk.outputs.swift_install }}"
echo " file: $HOME/swift-sdk-cache/${{ steps.resolve-sdk.outputs.sdk_filename }}"
echo " checksum: ${{ steps.resolve-sdk.outputs.sdk_checksum }}"
swiftly install "${{ steps.resolve-sdk.outputs.swift_install }}"
swift sdk install "$HOME/swift-sdk-cache/${{ steps.resolve-sdk.outputs.sdk_filename }}"
swift sdk list

- name: Configure Swift Android SDK
run: |
set -euo pipefail
Expand Down Expand Up @@ -214,7 +254,7 @@ jobs:
- name: Summarize APK artifacts
if: always()
run: |
echo "## APK Artifacts (os:${{ matrix.os }} / swift:${{ matrix.swift_version }} / ndk:${{ matrix.ndk_version }}) / configuration:${{ matrix.configuration }}" >> "$GITHUB_STEP_SUMMARY"
echo "## APK Artifacts (os:${{ matrix.os }} / swift:${{ steps.resolve-sdk.outputs.swift_install }} / ndk:${{ matrix.ndk_version }} / configuration:${{ matrix.configuration }})" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "| Project | APK | Size |" >> "$GITHUB_STEP_SUMMARY"
echo "|---------|-----|------|" >> "$GITHUB_STEP_SUMMARY"
Expand All @@ -236,6 +276,6 @@ jobs:
if: always()
uses: actions/upload-artifact@v7
with:
name: apks-${{ matrix.os }}-${{ matrix.swift_version }}-${{ matrix.ndk_version }}
name: apks-${{ matrix.os }}-${{ steps.resolve-sdk.outputs.swift_install }}-${{ matrix.ndk_version }}-${{ matrix.configuration }}
path: '**/build/outputs/apk/**/*.apk'
if-no-files-found: warn
Loading