Attempt to re-use existing Android emulator configuration #340
Workflow file for this run
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
| name: sdk-install-demo ci | |
| on: | |
| push: | |
| branches: [ main ] | |
| workflow_dispatch: | |
| pull_request: | |
| schedule: | |
| - cron: '0 13 * * *' | |
| jobs: | |
| install-sdk: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: 'macOS 15 X64 API 28' | |
| os: 'macos-15-intel' | |
| ANDROID_API: 28 | |
| NDK_VERSION: 'r27d' | |
| EMULATOR_ARCH: 'x86_64' | |
| EMULATOR_ARCH_TRIPLE: 'x86_64' | |
| - name: 'Ubuntu X64 API 28' | |
| os: 'ubuntu-latest' | |
| ANDROID_API: 28 | |
| NDK_VERSION: 'r28c' | |
| EMULATOR_ARCH: 'x86_64' | |
| EMULATOR_ARCH_TRIPLE: 'x86_64' | |
| - name: 'macOS 15 X64 API 30' | |
| os: 'macos-15-intel' | |
| ANDROID_API: 30 | |
| NDK_VERSION: 'r27d' | |
| EMULATOR_ARCH: 'x86_64' | |
| EMULATOR_ARCH_TRIPLE: 'x86_64' | |
| - name: 'Ubuntu X64 API 35' | |
| os: 'ubuntu-latest' | |
| ANDROID_API: 35 | |
| NDK_VERSION: 'r29' | |
| EMULATOR_ARCH: 'x86_64' | |
| EMULATOR_ARCH_TRIPLE: 'x86_64' | |
| # Android SDK for Linux is only x86_64 | |
| #- name: 'Ubuntu ARM API 28' | |
| # os: 'ubuntu-24.04-arm' | |
| # ANDROID_API: 28 | |
| # EMULATOR_ARCH: 'arm64-v8a' | |
| # EMULATOR_ARCH_TRIPLE: 'aarch64' | |
| # Cannot test on ARM macOS because Android emulator required nested | |
| # virtualization | |
| #- name: 'macOS 15 ARM' | |
| # os: 'macos-15' | |
| # ANDROID_API: 28 | |
| # EMULATOR_ARCH: 'arm64-v8a' | |
| # EMULATOR_ARCH_TRIPLE: 'aarch64' | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Free Disk Space | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo rm -rf /usr/share/dotnet | |
| sudo rm -rf /opt/ghc | |
| sudo rm -rf "/usr/local/share/boost" | |
| sudo rm -rf "$AGENT_TOOLSDIRECTORY" | |
| - name: Setup Android Environment | |
| run: | | |
| echo "$ANDROID_HOME/cmdline-tools/latest/bin" >> $GITHUB_PATH | |
| echo "$ANDROID_HOME/platform-tools" >> $GITHUB_PATH | |
| echo "$ANDROID_HOME/build-tools/latest" >> $GITHUB_PATH | |
| echo "$ANDROID_HOME/tools" >> $GITHUB_PATH | |
| echo "$ANDROID_HOME/emulator" >> $GITHUB_PATH | |
| echo "ANDROID_API=${{ matrix.ANDROID_API }}" >> $GITHUB_ENV | |
| echo "ANDROID_EMULATOR_ARCH=${{ matrix.EMULATOR_ARCH }}" >> $GITHUB_ENV | |
| echo "ANDROID_EMULATOR_ARCH_TRIPLE=${{ matrix.EMULATOR_ARCH_TRIPLE }}" >> $GITHUB_ENV | |
| echo "ANDROID_TARGET=default" >> $GITHUB_ENV | |
| #echo "ANDROID_PROFILE=Pixel 6" >> $GITHUB_ENV | |
| echo "ANDROID_PROFILE=Nexus 10" >> $GITHUB_ENV | |
| echo "ANDROID_CHANNEL=3" >> $GITHUB_ENV | |
| echo "ANDROID_NDK_VERSION=${{ matrix.NDK_VERSION }}" >> $GITHUB_ENV | |
| if [[ "${RUNNER_OS}" == "Linux" ]]; then | |
| # needed for Linux or else the emulator will be created in | |
| # ~/.android/avd but it will be sought in ~/.config/.android/avd | |
| echo "ANDROID_AVD_HOME=${XDG_CONFIG_HOME:-$HOME}/.android/avd" >> $GITHUB_ENV | |
| # enable KVM on Linux, else error on emulator launch: | |
| # CPU acceleration status: This user doesn't have permissions to use KVM (/dev/kvm). | |
| echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules | |
| sudo udevadm control --reload-rules | |
| sudo udevadm trigger --name-match=kvm | |
| fi | |
| - name: Create and Launch Android Emulator | |
| run: | | |
| EMULATOR_SPEC="system-images;android-${ANDROID_API};default;${ANDROID_EMULATOR_ARCH}" | |
| EMULATOR_NAME="swiftemu" | |
| sdkmanager --list_installed | |
| yes | sdkmanager --licenses > /dev/null | |
| sdkmanager --install "${EMULATOR_SPEC}" "emulator" "platform-tools" "platforms;android-${ANDROID_API}" | |
| avdmanager create avd -n "${EMULATOR_NAME}" -k "${EMULATOR_SPEC}" --device "${ANDROID_PROFILE}" | |
| emulator -list-avds | |
| # launch the emulator in the background; we will cat the logs at the end | |
| nohup emulator -memory 4096 -avd "${EMULATOR_NAME}" -wipe-data -no-window -no-snapshot -noaudio -no-boot-anim 2>&1 > emulator.log & | |
| adb logcat 2>&1 > logcat.log & | |
| - name: Install Prerequisites | |
| run: | | |
| if [[ "${RUNNER_OS}" == "Linux" ]]; then | |
| # libcurl4-openssl-dev needed for host toolchain | |
| sudo apt-get -y install libcurl4-openssl-dev | |
| fi | |
| # swiftly install instructions from https://www.swift.org/install/linux/ | |
| - name: Install Swiftly | |
| run: | | |
| if [[ "${RUNNER_OS}" == "macOS" ]]; then | |
| curl -fsSL -O https://download.swift.org/swiftly/darwin/swiftly.pkg | |
| installer -pkg swiftly.pkg -target CurrentUserHomeDirectory | |
| ~/.swiftly/bin/swiftly init --quiet-shell-followup --skip-install | |
| . "${SWIFTLY_HOME_DIR:-$HOME/.swiftly}/env.sh" | |
| elif [[ "${RUNNER_OS}" == "Linux" ]]; then | |
| curl -fsSL -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz | |
| tar zxf swiftly-$(uname -m).tar.gz | |
| ./swiftly init --quiet-shell-followup --skip-install | |
| . "${SWIFTLY_HOME_DIR:-$HOME/.local/share/swiftly}/env.sh" | |
| else | |
| echo "Error: unsupported OS: ${RUNNER_OS}" | |
| exit 1 | |
| fi | |
| hash -r | |
| echo "${SWIFTLY_BIN_DIR}" >> "${GITHUB_PATH}" | |
| - name: Get Latest Toolchain Info | |
| run: | | |
| sdk_json=$(curl -fsSL "https://www.swift.org/api/v1/install/dev/main/android-sdk.json") || fatal "Failed to fetch android-sdk development snapshots" | |
| download=$(echo "$sdk_json" | jq -r '.[0].download') | |
| snapshot_tag=$(echo "$sdk_json" | jq -r '.[0].dir') | |
| checksum=$(echo "$sdk_json" | jq -r '.[0].checksum') | |
| echo "SWIFT_TOOLCHAIN_VERSION=${snapshot_tag}" >> ${GITHUB_ENV} | |
| echo "SWIFT_ANDROID_SDK_VERSION=${snapshot_tag}" >> ${GITHUB_ENV} | |
| echo "SWIFT_ANDROID_SDK_DOWNLOAD=${download}" >> ${GITHUB_ENV} | |
| echo "SWIFT_ANDROID_SDK_CHECKSUM=${checksum}" >> ${GITHUB_ENV} | |
| - name: Install Swift Host Toolchain | |
| run: swiftly install --use "${SWIFT_TOOLCHAIN_VERSION}" | |
| - name: Install Swift SDK for Android | |
| run: swiftly run swift sdk install https://download.swift.org/development/android-sdk/${SWIFT_ANDROID_SDK_VERSION}/${SWIFT_ANDROID_SDK_DOWNLOAD} --checksum ${SWIFT_ANDROID_SDK_CHECKSUM} | |
| - name: List Swift SDKs | |
| run: | | |
| swiftly run swift sdk list | |
| swiftly run swift --version | |
| swiftly run swift --version +"${SWIFT_TOOLCHAIN_VERSION}" | |
| - name: Setup Android NDK | |
| run: | | |
| # Only install the NDK if it is overridden | |
| # Otherwise use the runner-installed NDK | |
| if [[ ! -z "${ANDROID_NDK_VERSION}" ]]; then | |
| mkdir ~/android-ndk | |
| cd ~/android-ndk | |
| curl -fsSLO https://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-$(uname -s).zip | |
| unzip -q android-ndk-${ANDROID_NDK_VERSION}-*.zip | |
| echo "ANDROID_NDK_HOME=${PWD}/android-ndk-${ANDROID_NDK_VERSION}" >> $GITHUB_ENV | |
| fi | |
| # note that we must *not* have ANDROID_NDK_ROOT set! | |
| # https://github.com/swiftlang/swift-driver/pull/1879 | |
| echo "ANDROID_NDK_ROOT=" >> $GITHUB_ENV | |
| - name: Setup Swift SDK for Android | |
| run: | | |
| cd ~/Library/org.swift.swiftpm || cd ${XDG_CONFIG_HOME}/swiftpm || cd ~/.local/swiftpm || cd ~/.swiftpm | |
| ./swift-sdks/${SWIFT_ANDROID_SDK_VERSION}*.artifactbundle/swift-android/scripts/setup-android-sdk.sh | |
| cd ./swift-sdks/${SWIFT_ANDROID_SDK_VERSION}*.artifactbundle | |
| echo "SWIFT_ANDROID_SDK_HOME=${PWD}" >> $GITHUB_ENV | |
| - name: Build Swift Executable for Android | |
| run: | | |
| mkdir hello | |
| cd hello | |
| swiftly run swift package init --type executable | |
| swiftly run swift build --swift-sdk "${ANDROID_EMULATOR_ARCH_TRIPLE}-unknown-linux-android${ANDROID_API}" --static-swift-stdlib | |
| file .build/debug/hello | |
| - name: Wait for Android Emulator | |
| run: adb wait-for-any-device | |
| timeout-minutes: 5 | |
| - name: Check Android Emulator | |
| run: adb shell 'echo Hello Android!' | |
| - name: Run Swift Executable on Android Emulator | |
| run: | | |
| cd hello | |
| adb push .build/debug/hello /data/local/tmp | |
| adb push $ANDROID_NDK_HOME/toolchains/llvm/prebuilt/*/sysroot/usr/lib/${ANDROID_EMULATOR_ARCH_TRIPLE}-linux-android/libc++_shared.so /data/local/tmp/ | |
| adb shell /data/local/tmp/hello | |
| - name: Create run-tests script | |
| run: | | |
| cat > run-tests.sh << "EOF" | |
| #!/bin/bash -ex | |
| ORG=$(echo "${1}" | cut -d '/' -f 1) | |
| PACKAGE=$(echo "${1}" | cut -d '/' -f 2) | |
| git clone https://github.com/${ORG}/${PACKAGE} | |
| cd ${PACKAGE} | |
| TRIPLE="${ANDROID_EMULATOR_ARCH_TRIPLE}-unknown-linux-android${ANDROID_API}" | |
| swiftly run swift build --swift-sdk "${TRIPLE}" --build-tests +"${SWIFT_TOOLCHAIN_VERSION}" | |
| STAGING=".build/android-test-${PACKAGE}/" | |
| rm -rf "${STAGING}" | |
| mkdir "${STAGING}" | |
| cp -a .build/"${TRIPLE}"/"${PACKAGE}"PackageTests.xctest "${STAGING}" | |
| cp -a .build/"${TRIPLE}"/*.resources "${STAGING}" | |
| # for the common case of tests referencing their own resources | |
| cp -a Tests "${STAGING}" | |
| cp -a $ANDROID_NDK_HOME/toolchains/llvm/prebuilt/*/sysroot/usr/lib/${ANDROID_EMULATOR_ARCH_TRIPLE}-linux-android/libc++_shared.so "${STAGING}" | |
| cp -a "${SWIFT_ANDROID_SDK_HOME}"/swift-android/swift-resources/usr/lib/swift-${ANDROID_EMULATOR_ARCH_TRIPLE}/android/*.so /data/local/tmp/ | |
| cd .build/ | |
| STAGING_BASE=$(basename "${STAGING}") | |
| zip -r "${STAGING_BASE}.zip" "${STAGING_BASE}" | |
| adb push "${STAGING_BASE}.zip" /data/local/tmp/ | |
| adb shell unzip -d /data/local/tmp/ /data/local/tmp/"${STAGING_BASE}.zip" | |
| adb shell /data/local/tmp/"${STAGING_BASE}"/"${PACKAGE}"PackageTests.xctest | |
| EOF | |
| chmod +x run-tests.sh | |
| cat run-tests.sh | |
| - name: Run swift-collections tests | |
| # too slow | |
| if: false | |
| run: ./run-tests.sh apple/swift-collections | |
| - name: Run swift-numerics tests | |
| run: ./run-tests.sh apple/swift-numerics | |
| - name: Run swift-algorithms tests | |
| run: ./run-tests.sh apple/swift-algorithms | |
| - name: Run swift-atomics tests | |
| run: ./run-tests.sh apple/swift-atomics | |
| - name: Run swift-system tests | |
| run: ./run-tests.sh apple/swift-system | |
| - name: Run swift-crypto tests | |
| run: ./run-tests.sh apple/swift-crypto | |
| - name: Run swift-nio tests | |
| if: false | |
| run: ./run-tests.sh apple/swift-nio | |
| - name: Run swift-argument-parser tests | |
| # needs local files: | |
| # error: MathExampleTests.testMath_AddHelp : failed - No executable at '/data/local/tmp/math'. | |
| if: false | |
| run: ./run-tests.sh apple/swift-argument-parser | |
| - name: Show Android Emulator Log | |
| if: always() | |
| run: cat emulator.log | |
| - name: Show Android Logcat Output | |
| if: always() | |
| run: cat logcat.log | |