diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 4a0f0046..eede1be9 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -25,3 +25,156 @@ jobs: name: docker-logs path: | *.log + + android-build: + name: Android ${{ matrix.build-type }} ${{ matrix.swift-version }} ${{ matrix.arch }} ${{ matrix.runner }} (compiler=${{ matrix.build-compiler }}) + strategy: + fail-fast: false + matrix: + include: + - swift-version: 'tag:swift-DEVELOPMENT-SNAPSHOT-2026-02-06-a' + build-type: 'docker' + build-compiler: '1' + runner: 'ubuntu-24.04' + - swift-version: 'tag:swift-6.3-DEVELOPMENT-SNAPSHOT-2026-01-29-a' + build-type: 'local' + build-compiler: '1' + runner: 'ubuntu-24.04' + runs-on: ${{ matrix.runner }} + # 16 hour timeout + timeout-minutes: 1080 + steps: + - name: Free Disk Space + run: | + df -h + # brings available space from 25G to 32G + # otherwise we sometimes run out of space during the build + sudo rm -rf /usr/share/miniconda /usr/share/az* /usr/share/glade* /usr/local/share/chromium /usr/local/share/powershell /usr/share/dotnet /opt/ghc /opt/hostedtoolcache /usr/local/graalvm/ /usr/local/.ghcup/ /usr/local/lib/node_modules /usr/local/share/boost + sudo docker image prune --all --force + sudo docker builder prune -a + df -h + - name: Setup + id: config + run: | + # these variabes are used by build-docker and build-local + # to determine which Swift version to build for + echo "SWIFT_VERSION=${{ matrix.swift-version }}" >> $GITHUB_ENV + # pass the build-compiler matrix through to the build script + echo "BUILD_COMPILER=${{ matrix.build-compiler }}" >> $GITHUB_ENV + echo "TARGET_ARCHS=${{ matrix.arch }}" >> $GITHUB_ENV + echo "WORKDIR=${{ runner.temp }}/swift-android-sdk" >> $GITHUB_ENV + - name: Checkout repository + uses: actions/checkout@v4 + - name: Build Android SDK (Local) + if: ${{ matrix.build-type == 'local' }} + working-directory: swift-ci/sdks/android + run: | + sudo apt install -q patchelf build-essential cmake ninja-build python3 golang git gnupg2 libcurl4-openssl-dev libedit-dev libicu-dev libncurses5-dev libpython3-dev libsqlite3-dev libxml2-dev rsync uuid-dev uuid-runtime tzdata curl unzip + ./build-local ${SWIFT_VERSION} ${WORKDIR} + - name: Build Android SDK (Docker) + if: ${{ matrix.build-type == 'docker' }} + working-directory: swift-ci/sdks/android + run: | + ./build-docker ${SWIFT_VERSION} ${WORKDIR} + - name: Install Host Toolchain + if: ${{ matrix.build-type == 'docker' }} + working-directory: swift-ci/sdks/android + run: | + # when building in a Docker container, we don't have a local host toolchain, + # but we need one in order to run the SDK validation tests, so we install it now + HOST_OS=ubuntu$(lsb_release -sr) + source ./scripts/toolchain-vars.sh + mkdir -p ${WORKDIR}/host-toolchain + ./scripts/install-swift.sh ${WORKDIR}/host-toolchain/$SWIFT_BASE/usr + ls ${WORKDIR}/host-toolchain + ${WORKDIR}/host-toolchain/*/usr/bin/swift --version + - name: Get artifact info + id: info + shell: bash + run: | + set -ex + SWIFT_ROOT=$(dirname ${WORKDIR}/host-toolchain/*/usr) + echo "swift-root=${SWIFT_ROOT}" >> $GITHUB_OUTPUT + echo "swift-path=${SWIFT_ROOT}/usr/bin/swift" >> $GITHUB_OUTPUT + + ARTIFACT_PATH=$(realpath ${WORKDIR}/products/*.artifactbundle.tar.gz) + echo "artifact-path=${ARTIFACT_PATH}" >> $GITHUB_OUTPUT + echo "sdk-id=x86_64-unknown-linux-android28" >> $GITHUB_OUTPUT + + ARTIFACT_EXT=".artifactbundle.tar.gz" + ARTIFACT_NAME="$(basename ${ARTIFACT_PATH} ${ARTIFACT_EXT})" + # depending on whether we are building locally or in a container, add a maker to the name + if [[ "${{ matrix.build-type }}" == 'local' ]]; then + ARTIFACT_NAME="${ARTIFACT_NAME}-local" + fi + if [[ "${{ matrix.build-compiler }}" == '1' ]]; then + ARTIFACT_NAME="${ARTIFACT_NAME}-hostbuild" + fi + # artifacts need a unique name so we suffix with the matrix arch(s) + if [[ ! -z "${{ matrix.arch }}" ]]; then + ARTIFACT_NAME="${ARTIFACT_NAME}-$(echo ${{ matrix.arch }} | tr ',' '-')" + fi + ARTIFACT_NAME="${ARTIFACT_NAME}${ARTIFACT_EXT}" + + # There is no way to prevent even a single-file artifact from being zipped: + # https://github.com/actions/upload-artifact?tab=readme-ov-file#zip-archives + # so the actual artifact download will look like: + # swift-6.1-RELEASE_android-0.1-x86_64.artifactbundle.tar.gz.zip + echo "artifact-name=${ARTIFACT_NAME}" >> $GITHUB_OUTPUT + - name: Upload SDK artifactbundle + uses: actions/upload-artifact@v4 + with: + compression-level: 0 + name: ${{ steps.info.outputs.artifact-name }} + path: ${{ steps.info.outputs.artifact-path }} + - name: Cleanup + run: | + # need to free up some space or else when installing we get: No space left on device + df -h + rm -rf ${WORKDIR}/{build,source} + sudo docker image prune --all --force + sudo docker builder prune -a + df -h + - name: Install artifactbundle + shell: bash + run: | + set -ex + ${{ steps.info.outputs.swift-path }} sdk install ${{ steps.info.outputs.artifact-path }} + ${{ steps.info.outputs.swift-path }} sdk configure --show-configuration $(${{ steps.info.outputs.swift-path }} sdk list | head -n 1) ${{ steps.info.outputs.sdk-id }} + # recent releases require that ANDROID_NDK_ROOT *not* be set + # see https://github.com/swiftlang/swift-driver/pull/1879 + echo "ANDROID_NDK_ROOT=" >> $GITHUB_ENV + + - name: Create Demo Project + run: | + cd ${{ runner.temp }} + mkdir DemoProject + cd DemoProject + ${{ steps.info.outputs.swift-path }} --version + ${{ steps.info.outputs.swift-path }} package init + echo 'import Foundation' >> Sources/DemoProject/DemoProject.swift + echo 'import FoundationEssentials' >> Sources/DemoProject/DemoProject.swift + echo 'import FoundationXML' >> Sources/DemoProject/DemoProject.swift + echo 'import FoundationNetworking' >> Sources/DemoProject/DemoProject.swift + echo 'import Dispatch' >> Sources/DemoProject/DemoProject.swift + echo 'import Android' >> Sources/DemoProject/DemoProject.swift + - name: Test Demo Project on Android + uses: skiptools/swift-android-action@main + with: + # only test for the complete arch SDK build to speed up CI + #run-tests: ${{ matrix.arch == '' }} + package-path: ${{ runner.temp }}/DemoProject + installed-sdk: ${{ steps.info.outputs.sdk-id }} + installed-swift: ${{ steps.info.outputs.swift-root }} + + - name: Checkout swift-algorithms + uses: actions/checkout@v4 + with: + repository: apple/swift-algorithms + path: swift-algorithms + - name: Test swift-algorithms + uses: skiptools/swift-android-action@main + with: + package-path: swift-algorithms + installed-sdk: ${{ steps.info.outputs.sdk-id }} + installed-swift: ${{ steps.info.outputs.swift-root }} diff --git a/swift-ci/sdks/android/build-docker b/swift-ci/sdks/android/build-docker index 3b88952c..ba177336 100755 --- a/swift-ci/sdks/android/build-docker +++ b/swift-ci/sdks/android/build-docker @@ -17,8 +17,8 @@ # default architectures to build for TARGET_ARCHS=${TARGET_ARCHS:-aarch64,x86_64,armv7} -ANDROID_NDK_VERSION=android-ndk-r27d -ANDROID_API=28 +ANDROID_NDK_VERSION=android-ndk-r28c +ANDROID_API=24 BASEPATH=$(dirname $(realpath $0)) cd ${BASEPATH} diff --git a/swift-ci/sdks/android/build-local b/swift-ci/sdks/android/build-local index b5f078c5..3e84ff7d 100755 --- a/swift-ci/sdks/android/build-local +++ b/swift-ci/sdks/android/build-local @@ -17,8 +17,8 @@ # default architectures to build for TARGET_ARCHS=${TARGET_ARCHS:-aarch64,x86_64,armv7} -ANDROID_NDK_VERSION=android-ndk-r27d -ANDROID_API=28 +ANDROID_NDK_VERSION=android-ndk-r28c +ANDROID_API=24 BASEPATH=$(dirname $(realpath $0)) cd ${BASEPATH} diff --git a/swift-ci/sdks/android/scripts/build.sh b/swift-ci/sdks/android/scripts/build.sh index b36f08ba..92418ccc 100755 --- a/swift-ci/sdks/android/scripts/build.sh +++ b/swift-ci/sdks/android/scripts/build.sh @@ -244,7 +244,7 @@ libxml2_version=$(versionFromTag ${swift_source_dir}/libxml2) curl_desc=$(describe ${swift_source_dir}/curl | tr '_' '.') curl_version=${curl_desc#curl-} -boringssl_version=$(describe ${source_dir}/boringssl) +boringssl_version=$(describe ${swift_source_dir}/boringssl) function quiet_pushd { pushd "$1" >/dev/null 2>&1 @@ -351,6 +351,7 @@ for arch in $archs; do -DLIBXML2_WITH_ICU=NO \ -DLIBXML2_WITH_ICONV=NO \ -DLIBXML2_WITH_LZMA=NO \ + -DLIBXML2_WITH_TESTS=OFF \ -DBUILD_SHARED_LIBS=OFF \ -DBUILD_STATIC_LIBS=ON @@ -366,7 +367,7 @@ for arch in $archs; do groupend groupstart "Building boringssl for ${compiler_target_host}" - quiet_pushd ${source_dir}/boringssl + quiet_pushd ${swift_source_dir}/boringssl run cmake \ -GNinja \ -B ${build_dir}/$arch/boringssl \ @@ -484,7 +485,7 @@ for arch in $archs; do ${build_cmark} \ ${local_build} \ --host-test \ - --skip-test-linux \ + --skip-test-linux --skip-clean-libdispatch --skip-clean-foundation --skip-clean-xctest \ --skip-test-xctest --skip-test-foundation \ --build-swift-static-stdlib \ --swift-install-components='compiler;clang-resource-dir-symlink;license;stdlib;sdk-overlay' \ diff --git a/swift-ci/sdks/android/scripts/fetch-source.sh b/swift-ci/sdks/android/scripts/fetch-source.sh index 7a5ead9f..1fe08807 100755 --- a/swift-ci/sdks/android/scripts/fetch-source.sh +++ b/swift-ci/sdks/android/scripts/fetch-source.sh @@ -154,10 +154,14 @@ fi popd >/dev/null groupend -# Fetch BoringSSL -groupstart "Fetching BoringSSL" -[[ -d boringssl ]] || git clone https://boringssl.googlesource.com/boringssl -pushd boringssl >/dev/null 2>&1 -git checkout ${BORINGSSL_VERSION} +groupstart "Fetching XML" +pushd swift-project/libxml2 >/dev/null 2>&1 +git checkout v2.14.5 +popd >/dev/null 2>&1 +groupend + +groupstart "Fetching Curl" +pushd swift-project/curl >/dev/null 2>&1 +git checkout curl-8_15_0 popd >/dev/null 2>&1 groupend