name: CI-unix

on:
  pull_request:
    paths:
      - '**'
      - '!docs/**'
      - '!src/win/**'
      - '!.**'
      - '.github/workflows/CI-unix.yml'
  push:
    branches:
      - v[0-9].*
      - master

jobs:
  build-linux:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: configure
        run: |
          ./autogen.sh
          mkdir build
          (cd build && ../configure)
      - name: distcheck
        run: |
          make -C build distcheck

  build-android:
    runs-on: ubuntu-latest
    container: reactnativecommunity/react-native-android:2020-5-20
    # Work around an issue where the node from actions/checkout is too new
    # to run inside the long-in-the-tooth react-nactive-android container
    # image.
    env:
      ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
      ANDROID_AVD_HOME: /root/.android/avd
    steps:
      - uses: actions/checkout@v3
      - name: Envinfo
        run: npx envinfo
      - name: Configure android arm64
        # see build options you can use in https://developer.android.com/ndk/guides/cmake
        run: |
          mkdir build
          cd build
          $ANDROID_HOME/cmake/3.10.2.4988404/bin/cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/20.0.5594570/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-24 ..
      - name: Build android arm64
        run: |
          $ANDROID_HOME/cmake/3.10.2.4988404/bin/cmake --build build
          ls -lh build
      - name: Install Android ABI arm64-v8a
        run: |
          # TODO: This can be in a pre-built docker image
          sdkmanager "build-tools;24.0.3" "platforms;android-24" "system-images;android-24;google_apis;arm64-v8a"

      - name: Start emulator
        run: |
          echo no | avdmanager create avd -n test -k "system-images;android-24;google_apis;arm64-v8a"

          adb start-server

          emulator @test -memory 2048 -no-audio -no-window -gpu off -no-snapshot -no-boot-anim -netdelay none -netspeed full -no-snapshot-save -no-snapshot-load -writable-system  &

          adb wait-for-device

          adb shell "su 0 setenforce 0" # to allow some syscalls like link, chmod, etc.

          # Push the build and test fixtures to the device
          adb push build /data/local/tmp
          adb shell mkdir /data/local/tmp/build/test
          adb push test/fixtures /data/local/tmp/build/test

      - name: Test
        run: |
          adb shell "cd /data/local/tmp/build ; env UV_TEST_TIMEOUT_MULTIPLIER=5 ./uv_run_tests_a"

  build-macos:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [macos-13, macos-14]
    steps:
      - uses: actions/checkout@v4
      - name: Envinfo
        run: npx envinfo
      - name: Disable Firewall
        run: |
          /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
          sudo defaults write /Library/Preferences/com.apple.alf globalstate -int 0
          /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
      - name: Setup
        run: |
          brew install ninja automake libtool
      - name: Configure
        run: |
          mkdir build
          cd build
          cmake .. -DBUILD_TESTING=ON -G Ninja
      - name: Build
        run: |
          cmake --build build
          ls -lh
      - name: platform_output
        run: |
          ./build/uv_run_tests platform_output
      - name: platform_output_a
        run: |
          ./build/uv_run_tests_a platform_output
      - name: Test
        run: |
          cd build && ctest -V
      - name: Autotools configure
        if: always()
        run: |
          ./autogen.sh
          mkdir build-auto
          (cd build-auto && ../configure)
          make -C build-auto -j4

  build-ios:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [macos-13, macos-14]
    steps:
      - uses: actions/checkout@v4
      - name: Configure
        run: |
          mkdir build-ios
          cd build-ios
          cmake .. -GXcode -DCMAKE_SYSTEM_NAME:STRING=iOS -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED:BOOL=NO -DCMAKE_CONFIGURATION_TYPES:STRING=Release
      - name: Build
        run: |
          cmake --build build-ios
          ls -lh build-ios

  build-cross-qemu:
    runs-on: ubuntu-latest
    name: build-cross-qemu-${{ matrix.config.target }}

    strategy:
      fail-fast: false
      matrix:
        config:
          - {target: arm,     toolchain: gcc-arm-linux-gnueabi,     cc: arm-linux-gnueabi-gcc,      qemu: qemu-arm-static     }
          - {target: armhf,   toolchain: gcc-arm-linux-gnueabihf,   cc: arm-linux-gnueabihf-gcc,    qemu: qemu-arm-static     }
          - {target: aarch64, toolchain: gcc-aarch64-linux-gnu,     cc: aarch64-linux-gnu-gcc,      qemu: qemu-aarch64-static }
          - {target: riscv64, toolchain: gcc-riscv64-linux-gnu,     cc: riscv64-linux-gnu-gcc,      qemu: qemu-riscv64-static }
          - {target: ppc,     toolchain: gcc-powerpc-linux-gnu,     cc: powerpc-linux-gnu-gcc,      qemu: qemu-ppc-static     }
          - {target: ppc64,   toolchain: gcc-powerpc64-linux-gnu,   cc: powerpc64-linux-gnu-gcc,    qemu: qemu-ppc64-static   }
          - {target: ppc64le, toolchain: gcc-powerpc64le-linux-gnu, cc: powerpc64le-linux-gnu-gcc,  qemu: qemu-ppc64le-static }
          - {target: s390x,   toolchain: gcc-s390x-linux-gnu,       cc: s390x-linux-gnu-gcc,        qemu: qemu-s390x-static   }
          - {target: mips,    toolchain: gcc-mips-linux-gnu,          cc: mips-linux-gnu-gcc,         qemu: qemu-mips-static     }
          - {target: mips64,  toolchain: gcc-mips64-linux-gnuabi64,   cc: mips64-linux-gnuabi64-gcc,  qemu: qemu-mips64-static   }
          - {target: mipsel,  toolchain: gcc-mipsel-linux-gnu,        cc: mipsel-linux-gnu-gcc,       qemu: qemu-mipsel-static   }
          - {target: mips64el,toolchain: gcc-mips64el-linux-gnuabi64, cc: mips64el-linux-gnuabi64-gcc,qemu: qemu-mips64el-static }
          - {target: arm (u64 slots),     toolchain: gcc-arm-linux-gnueabi,     cc: arm-linux-gnueabi-gcc,      qemu: qemu-arm-static}
          - {target: aarch64 (u64 slots), toolchain: gcc-aarch64-linux-gnu,     cc: aarch64-linux-gnu-gcc,      qemu: qemu-aarch64-static}
          - {target: ppc (u64 slots),     toolchain: gcc-powerpc-linux-gnu,     cc: powerpc-linux-gnu-gcc,      qemu: qemu-ppc-static}
          - {target: ppc64 (u64 slots),   toolchain: gcc-powerpc64-linux-gnu,   cc: powerpc64-linux-gnu-gcc,    qemu: qemu-ppc64-static}

    steps:
      - uses: actions/checkout@v4
      - name: Install QEMU
        # this ensure install latest qemu on ubuntu, apt get version is old
        env:
          QEMU_SRC: "http://archive.ubuntu.com/ubuntu/pool/universe/q/qemu"
          QEMU_VER: "qemu-user-static_7\\.2+dfsg-.*_amd64.deb$"
        run: |
          DEB=`curl -s $QEMU_SRC/ | grep -o -E 'href="([^"#]+)"' | cut -d'"' -f2 | grep $QEMU_VER | tail -1`
          wget $QEMU_SRC/$DEB
          sudo dpkg -i $DEB
      - name: Install ${{ matrix.config.toolchain }}
        run: |
          sudo apt update
          sudo apt install ${{ matrix.config.toolchain }} -y
      - name: Configure with ${{ matrix.config.cc }}
        run: |
          mkdir build
          cd build
          cmake .. -DBUILD_TESTING=ON -DQEMU=ON -DCMAKE_C_COMPILER=${{ matrix.config.cc }}
      - name: Build
        run: |
          cmake --build build
          ls -lh build
      - name: Test
        run: |
          ${{ matrix.config.qemu }} build/uv_run_tests_a
