name: Test WasmEdge extensions

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
  cancel-in-progress: true

on:
  push:
    branches:
      - master
    paths:
      - ".github/workflows/build-extensions.yml"
      - "plugins/**"
      - "test/**"
      - "thirdparty/**"
      - "tools/**"
      - "CMakeLists.txt"
      - "cmake/**"
      - "utils/wasi-nn/**"
      - "utils/wasi-crypto/**"
  pull_request:
    branches:
      - master
      - "proposal/**"
    paths:
      - ".github/workflows/build-extensions.yml"
      - "plugins/**"
      - "test/**"
      - "thirdparty/**"
      - "tools/**"
      - "CMakeLists.txt"
      - "cmake/**"
      - "utils/wasi-nn/**"
      - "utils/wasi-crypto/**"

jobs:
  # TODO: Refactor `lint` with `on.workflow_run`
  # https://docs.github.com/en/actions/using-workflows/triggering-a-workflow
  lint:
    uses: ./.github/workflows/reusable-call-linter.yml

  get_version:
    name: Retrieve version information
    needs: lint
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.prep.outputs.version }}
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Ensure git safe directory
        run: |
          git config --global --add safe.directory $(pwd)
      - name: Get version
        id: prep
        run: |
          # Retrieve annotated tags. Details: https://github.com/actions/checkout/issues/290
          git fetch --tags --force
          echo "Set version: $(git describe --match "[0-9].[0-9]*" --tag)"
          echo "version=$(git describe --match '[0-9].[0-9]*' --tag)" >> $GITHUB_OUTPUT

  # Due to the dependencies and exclusions of WASI-NN, build them saperately.
  build_ubuntu_wasi_nn:
    strategy:
      matrix:
        include:
          - name: Plugins_g++
            compiler: g++
            docker_tag: ubuntu-build-gcc
            build_type: Release
          - name: Plugins_clang++
            compiler: clang++
            docker_tag: ubuntu-build-clang
            build_type: Release
    name: WASI-NN (Ubuntu, ${{ matrix.compiler }}, ${{ matrix.build_type }})
    runs-on: ubuntu-latest
    env:
      output_dir: build/plugins/wasi_nn
      test_dir: build/test/plugins/wasi_nn
      build_options: -DWASMEDGE_PLUGIN_WASI_NN_BACKEND=PyTorch -DWASMEDGE_PLUGIN_WASI_NN_BACKEND=OpenVINO -DWASMEDGE_PLUGIN_WASI_NN_BACKEND=TensorFlowLite -DWASMEDGE_PLUGIN_WASI_NN_BACKEND=GGML
      tar_names: wasi_nn-pytorch wasi_nn-openvino wasi_nn-tensorflowlite wasi_nn-ggml
      test_bin: wasiNNTests
      output_bin: libwasmedgePluginWasiNN.so
      OPENVINO_VERSION: "2023.0.2"
      OPENVINO_YEAR: "2023"
      PYTORCH_VERSION: "1.8.2"
      PYTORCH_INSTALL_TO: "."
    needs: [get_version]
    container:
      image: wasmedge/wasmedge:${{ matrix.docker_tag }}
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Ensure git safe directory
        run: |
          git config --global --add safe.directory $(pwd)
      - name: Install dependencies
        shell: bash
        run: |
          apt update
          apt install -y unzip libopenblas-dev pkg-config
          bash utils/wasi-nn/install-openvino.sh
          bash utils/wasi-nn/install-pytorch.sh
      - name: Build and test WASI-NN using ${{ matrix.compiler }} with ${{ matrix.build_type }} mode
        shell: bash
        run: |
          export Torch_DIR=$(pwd)/${PYTORCH_INSTALL_TO}/libtorch
          ldconfig
          plugin_array=(${tar_names})
          option_array=(${build_options})
          cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DWASMEDGE_BUILD_TESTS=ON -DWASMEDGE_BUILD_AOT_RUNTIME=OFF -DWASMEDGE_BUILD_TOOLS=OFF
          for (( i=0; i<${#plugin_array[@]}; i++ ));
          do
            echo "Building ${plugin_array[$i]} backend:"
            cmake -Bbuild -GNinja ${option_array[$i]}
            cmake --build build --target ${test_bin}

            echo "Testing ${plugin_array[$i]} backend:"
            cd ${test_dir}
            ./${test_bin}
            cd -

            echo "Copying ${plugin_array[$i]} backend:"
            cp -f ${output_dir}/${output_bin} ${output_bin}
            tar -zcvf plugin_${plugin_array[$i]}.tar.gz ${output_bin}
          done
      - name: Upload artifact - wasi_nn-pytorch
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_nn-pytorch-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasi_nn-pytorch.tar.gz
      - name: Upload artifact - wasi_nn-openvino
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_nn-openvino-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasi_nn-openvino.tar.gz
      - name: Upload artifact - wasi_nn-tensorflowlite
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_nn-tensorflowlite-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasi_nn-tensorflowlite.tar.gz
      - name: Upload artifact - wasi_nn-ggml
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_nn-ggml-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasi_nn-ggml.tar.gz

  build_ubuntu:
    strategy:
      matrix:
        include:
          - name: Plugins_g++
            compiler: g++
            docker_tag: ubuntu-build-gcc-plugins-deps
            build_type: Release
          - name: Plugins_clang++
            compiler: clang++
            docker_tag: ubuntu-build-clang-plugins-deps
            build_type: Release
    name: Plugins (Ubuntu, ${{ matrix.compiler }}, ${{ matrix.build_type }})
    runs-on: ubuntu-latest
    env:
      output_prefix: build/plugins
      test_prefix: build/test/plugins
      build_options: -DWASMEDGE_PLUGIN_WASI_CRYPTO=ON -DWASMEDGE_PLUGIN_WASI_LOGGING=ON -DWASMEDGE_PLUGIN_PROCESS=ON -DWASMEDGE_PLUGIN_TENSORFLOW=ON -DWASMEDGE_PLUGIN_TENSORFLOWLITE=ON -DWASMEDGE_PLUGIN_IMAGE=ON -DWASMEDGE_PLUGIN_WASM_BPF=ON -DWASMEDGE_PLUGIN_RUSTLS=ON -DWASMEDGE_PLUGIN_OPENCVMINI=ON -DWASMEDGE_PLUGIN_ZLIB=ON
      tar_names: wasi_crypto wasi_logging wasmedge_process wasmedge_tensorflow wasmedge_tensorflowlite wasmedge_image wasm_bpf wasmedge_rustls wasmedge_opencvmini wasmedge_zlib
      test_bins: wasiCryptoTests wasiLoggingTests wasmedgeProcessTests wasmedgeTensorflowTests wasmedgeTensorflowLiteTests wasmedgeImageTests wasmBpfTests wasmEdgeRUSTLSTests wasmedgeOpencvminiTests wasmedgeZlibTests
      output_bins: libwasmedgePluginWasiCrypto.so libwasmedgePluginWasiLogging.so libwasmedgePluginWasmEdgeProcess.so libwasmedgePluginWasmEdgeTensorflow.so libwasmedgePluginWasmEdgeTensorflowLite.so libwasmedgePluginWasmEdgeImage.so libwasmedgePluginWasmBpf.so libwasmedge_rustls.so libwasmedgePluginWasmEdgeOpenCVMini.so libwasmedgePluginWasmEdgeZlib.so
    needs: [get_version]
    container:
      image: wasmedge/wasmedge:${{ matrix.docker_tag }}
      # Required for mounting debugfs
      # Tests of wasm_bpf also require privileges
      options: --privileged
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Install dependencies
        run: |
          apt update
          apt install -y libssl-dev
          apt install -y libelf-dev zlib1g-dev pkg-config
          apt install -y clang llvm
          apt install -y cargo
          # Running tests of wasm_bpf requires proper ebpf running environment
          mount -t debugfs none /sys/kernel/debug
      - name: Build plugins using ${{ matrix.compiler }} with ${{ matrix.build_type }} mode
        shell: bash
        run: |
          testbin_array=(${test_bins})
          cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DWASMEDGE_BUILD_TESTS=ON -DWASMEDGE_BUILD_AOT_RUNTIME=OFF -DWASMEDGE_BUILD_TOOLS=OFF ${build_options}
          for (( i=0; i<${#testbin_array[@]}; i++ ));
          do
            echo "Building ${testbin_array[$i]} :"
            cmake --build build --target ${testbin_array[$i]}
          done
      - name: Test plugins
        shell: bash
        run: |
          plugin_array=(${tar_names})
          testbin_array=(${test_bins})
          for (( i=0; i<${#plugin_array[@]}; i++ ));
          do
            echo "Testing ${plugin_array[$i]} :"
            cd ${test_prefix}/${plugin_array[$i]}
            ./${testbin_array[$i]}
            cd -
          done
      - name: Prepare the plugins tar.gz package
        shell: bash
        run: |
          plugin_array=(${tar_names})
          outbin_array=(${output_bins})
          for (( i=0; i<${#plugin_array[@]}; i++ ));
          do
            echo "Copying ${plugin_array[$i]} :"
            cp ${output_prefix}/${plugin_array[$i]}/${outbin_array[$i]} ${outbin_array[$i]}
            tar -zcvf plugin_${plugin_array[$i]}.tar.gz ${outbin_array[$i]}
          done
      - name: Upload artifact - wasi_crypto
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_crypto-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasi_crypto.tar.gz
      - name: Upload artifact - wasi_logging
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_logging-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasi_logging.tar.gz
      - name: Upload artifact - wasmedge_process
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_process-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasmedge_process.tar.gz
      - name: Upload artifact - wasmedge_tensorflow
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_tensorflow-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasmedge_tensorflow.tar.gz
      - name: Upload artifact - wasmedge_tensorflowlite
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_tensorflowlite-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasmedge_tensorflowlite.tar.gz
      - name: Upload artifact - wasmedge_image
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_image-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasmedge_image.tar.gz
      - name: Upload artifact - wasm_bpf
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasm_bpf-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasm_bpf.tar.gz
      - name: Upload artifact - wasmedge_rustls
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_rustls-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasmedge_rustls.tar.gz
      - name: Upload artifact - wasmedge_opencvmini
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_opencvmini-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasmedge_opencvmini.tar.gz
      - name: Upload artifact - wasmedge_zlib
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_zlib-${{ needs.get_version.outputs.version }}-ubuntu22.04-${{ matrix.compiler }}.tar.gz
          path: plugin_wasmedge_zlib.tar.gz

  # Due to the dependencies and exclusions of WASI-NN, build them saperately.
  build_manylinux_wasi_nn:
    strategy:
      matrix:
        include:
          - name: Plugins_x86_64
            host_runner: ubuntu-latest
            docker_tag: manylinux2014_x86_64
            build_type: Release
          - name: Plugins_aarch64
            host_runner: linux-arm64
            docker_tag: manylinux2014_aarch64
            build_type: Release
    name: WASI-NN (${{ matrix.docker_tag }}, g++, ${{ matrix.build_type }})
    runs-on: ${{ matrix.host_runner }}
    env:
      output_dir: build/plugins/wasi_nn
      test_dir: build/test/plugins/wasi_nn
      build_options_all_platforms: -DWASMEDGE_PLUGIN_WASI_NN_BACKEND=TensorFlowLite -DWASMEDGE_PLUGIN_WASI_NN_BACKEND=GGML
      build_options_manylinux2014_x86_64: -DWASMEDGE_PLUGIN_WASI_NN_BACKEND=PyTorch
      build_options_manylinux2014_aarch64:
      tar_names_all_platforms: wasi_nn-tensorflowlite wasi_nn-ggml
      tar_names_manylinux2014_x86_64: wasi_nn-pytorch
      tar_names_manylinux2014_aarch64:
      test_bin: wasiNNTests
      output_bin: libwasmedgePluginWasiNN.so
      PYTORCH_VERSION: "1.8.2"
      PYTORCH_INSTALL_TO: "."
    needs: [get_version]
    container:
      image: wasmedge/wasmedge:${{ matrix.docker_tag }}
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Install dependencies
        shell: bash
        run: |
          bash ./utils/wasi-nn/install-pytorch.sh --disable-cxx11-abi
      - name: Build and test WASI-NN using g++ with ${{ matrix.build_type }} mode
        shell: bash
        run: |
          export Torch_DIR=$(pwd)/${PYTORCH_INSTALL_TO}/libtorch
          plugin_array=(${tar_names_all_platforms} ${tar_names_${{ matrix.docker_tag }}})
          option_array=(${build_options_all_platforms} ${build_options_${{ matrix.docker_tag }}})
          cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DWASMEDGE_BUILD_TESTS=ON -DWASMEDGE_BUILD_AOT_RUNTIME=OFF -DWASMEDGE_BUILD_TOOLS=OFF -DWASMEDGE_PLUGIN_WASI_NN_GGML_LLAMA_BLAS=OFF
          for (( i=0; i<${#plugin_array[@]}; i++ ));
          do
            echo "Building ${plugin_array[$i]} backend:"
            cmake -Bbuild -GNinja ${option_array[$i]} -DWASMEDGE_PLUGIN_WASI_NN_GGML_LLAMA_BLAS=OFF
            cmake --build build --target ${test_bin}

            echo "Testing ${plugin_array[$i]} backend:"
            cd ${test_dir}
            echo "Testing ${plugin_array[$i]} backend:"
            ./${test_bin}
            cd -

            echo "Copying ${plugin_array[$i]} backend:"
            cp -f ${output_dir}/${output_bin} ${output_bin}
            tar -zcvf plugin_${plugin_array[$i]}.tar.gz ${output_bin}
          done
      - name: Upload artifact - wasi_nn-pytorch
        if: contains(matrix.docker_tag, 'manylinux2014_x86_64')
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_nn-pytorch-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasi_nn-pytorch.tar.gz
      - name: Upload artifact - wasi_nn-tensorflowlite
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_nn-tensorflowlite-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasi_nn-tensorflowlite.tar.gz
      - name: Upload artifact - wasi_nn-ggml
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_nn-ggml-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasi_nn-ggml.tar.gz

  build_manylinux:
    strategy:
      matrix:
        include:
          - name: Plugins_x86_64
            host_runner: ubuntu-latest
            docker_tag: manylinux2014_x86_64-plugins-deps
            build_type: Release
          - name: Plugins_aarch64
            host_runner: linux-arm64
            docker_tag: manylinux2014_aarch64-plugins-deps
            build_type: Release
    name: Plugins (${{ matrix.docker_tag }}, g++, ${{ matrix.build_type }})
    runs-on: ${{ matrix.host_runner }}
    env:
      output_prefix: build/plugins
      test_prefix: build/test/plugins
      build_options_all_platforms: -DWASMEDGE_PLUGIN_WASI_CRYPTO=ON -DWASMEDGE_PLUGIN_WASI_LOGGING=ON -DWASMEDGE_PLUGIN_PROCESS=ON -DWASMEDGE_PLUGIN_TENSORFLOW=ON -DWASMEDGE_PLUGIN_TENSORFLOWLITE=ON -DWASMEDGE_PLUGIN_IMAGE=ON -DWASMEDGE_PLUGIN_OPENCVMINI=ON -DWASMEDGE_PLUGIN_ZLIB=ON
      build_options_manylinux2014_x86_64: -DWASMEDGE_PLUGIN_WASM_BPF=ON -DWASMEDGE_PLUGIN_RUSTLS=ON -DWASMEDGE_PLUGIN_WASM_BPF_BUILD_LIBBPF_WITH_PKG_CONF=OFF
      build_options_manylinux2014_aarch64:
      tar_names_all_platforms: wasi_crypto wasi_logging wasmedge_process wasmedge_tensorflow wasmedge_tensorflowlite wasmedge_image wasmedge_opencvmini wasmedge_zlib
      tar_names_manylinux2014_x86_64: wasm_bpf wasmedge_rustls
      tar_names_manylinux2014_aarch64:
      test_bins_all_platforms: wasiCryptoTests wasiLoggingTests wasmedgeProcessTests wasmedgeTensorflowTests wasmedgeTensorflowLiteTests wasmedgeImageTests wasmedgeOpencvminiTests wasmedgeZlibTests
      test_bins_manylinux2014_x86_64: wasmBpfTests wasmEdgeRUSTLSTests
      test_bins_manylinux2014_aarch64:
      output_bins_all_platforms: libwasmedgePluginWasiCrypto.so libwasmedgePluginWasiLogging.so libwasmedgePluginWasmEdgeProcess.so libwasmedgePluginWasmEdgeTensorflow.so libwasmedgePluginWasmEdgeTensorflowLite.so libwasmedgePluginWasmEdgeImage.so libwasmedgePluginWasmEdgeOpenCVMini.so libwasmedgePluginWasmEdgeZlib.so
      output_bins_manylinux2014_x86_64: libwasmedgePluginWasmBpf.so libwasmedge_rustls.so
      output_bins_manylinux2014_aarch64:
    needs: [get_version]
    container:
      image: wasmedge/wasmedge:${{ matrix.docker_tag }}
      # Required for mounting debugfs
      # Tests of wasm_bpf also require privileges
      options: --privileged
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Build and install dependencies
        run: |
          yum update -y
          yum install -y zlib-devel zlib-static cmake curl
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y
          bash ./utils/wasi-crypto/build-openssl.sh
          # Running tests of wasm_bpf requires proper ebpf running environment
          mount -t debugfs none /sys/kernel/debug
      - name: Build and test plugins using g++ with ${{ matrix.build_type }} mode
        shell: bash
        run: |
          source "$HOME/.cargo/env"
          testbin_array=(${test_bins_all_platforms} ${test_bins_${{ matrix.docker_tag }}})
          cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DWASMEDGE_BUILD_TESTS=ON -DWASMEDGE_BUILD_AOT_RUNTIME=OFF -DWASMEDGE_BUILD_TOOLS=OFF ${build_options_all_platforms} ${build_options_${{ matrix.docker_tag }}} -DOPENSSL_ROOT_DIR=$(pwd)/openssl-1.1.1n/openssl
          for (( i=0; i<${#testbin_array[@]}; i++ ));
          do
            echo "Building ${testbin_array[$i]} :"
            cmake --build build --target ${testbin_array[$i]}
          done
      - name: Test plugins
        shell: bash
        run: |
          plugin_array=(${tar_names_all_platforms} ${tar_names_${{ matrix.docker_tag }}})
          testbin_array=(${test_bins_all_platforms} ${test_bins_${{ matrix.docker_tag }}})
          for (( i=0; i<${#plugin_array[@]}; i++ ));
          do
            echo "Testing ${plugin_array[$i]} :"
            cd ${test_prefix}/${plugin_array[$i]}
            ./${testbin_array[$i]}
            cd -
          done
      - name: Prepare the WasmEdge plugins tar.gz package
        shell: bash
        run: |
          plugin_array=(${tar_names_all_platforms} ${tar_names_${{ matrix.docker_tag }}})
          outbin_array=(${output_bins_all_platforms} ${output_bins_${{ matrix.docker_tag }}})
          for (( i=0; i<${#plugin_array[@]}; i++ ));
          do
            echo "Copying ${plugin_array[$i]} :"
            cp ${output_prefix}/${plugin_array[$i]}/${outbin_array[$i]} ${outbin_array[$i]}
            tar -zcvf plugin_${plugin_array[$i]}.tar.gz ${outbin_array[$i]}
          done
      - name: Upload artifact - wasi_crypto
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_crypto-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasi_crypto.tar.gz
      - name: Upload artifact - wasi_logging
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_logging-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasi_logging.tar.gz
      - name: Upload artifact - wasmedge_process
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_process-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasmedge_process.tar.gz
      - name: Upload artifact - wasmedge_tensorflow
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_tensorflow-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasmedge_tensorflow.tar.gz
      - name: Upload artifact - wasmedge_tensorflowlite
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_tensorflowlite-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasmedge_tensorflowlite.tar.gz
      - name: Upload artifact - wasmedge_image
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_image-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasmedge_image.tar.gz
      - name: Upload artifact - wasm_bpf
        if: contains(matrix.docker_tag, 'manylinux2014_x86_64')
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasm_bpf-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasm_bpf.tar.gz
      - name: Upload artifact - wasmedge_rustls
        if: contains(matrix.docker_tag, 'manylinux2014_x86_64')
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_rustls-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasmedge_rustls.tar.gz
      - name: Upload artifact - wasmedge_opencvmini
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_opencvmini-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasmedge_opencvmini.tar.gz
      - name: Upload artifact - wasmedge_zlib
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_zlib-${{ needs.get_version.outputs.version }}-${{ matrix.docker_tag }}.tar.gz
          path: plugin_wasmedge_zlib.tar.gz

  build_macos:
    strategy:
      matrix:
        include:
          - name: Plugins_MacOS_11
            system: MacOS 11
            host_runner: macos-11
            darwin_version: darwin_20
            build_type: Release
            arch: x86_64
          - name: Plugins_MacOS_12
            system: MacOS 12
            host_runner: macos-12
            darwin_version: darwin_21
            build_type: Release
            arch: x86_64
          - name: Plugins_MacOS_arm64
            system: MacOS 13 (arm64)
            host_runner: mac-arm64
            darwin_version: darwin_22
            build_type: Release
            arch: arm64
    name: Plugins (${{ matrix.system }}, clang++,  ${{ matrix.build_type }})
    runs-on: ${{ matrix.host_runner }}
    env:
      output_prefix: build/plugins
      test_prefix: build/test/plugins
      build_options: -DWASMEDGE_PLUGIN_WASI_CRYPTO=ON -DWASMEDGE_PLUGIN_RUSTLS=ON -DWASMEDGE_PLUGIN_WASI_LOGGING=ON -DWASMEDGE_PLUGIN_TENSORFLOW=ON -DWASMEDGE_PLUGIN_TENSORFLOWLITE=ON -DWASMEDGE_PLUGIN_IMAGE=ON -DWASMEDGE_PLUGIN_OPENCVMINI=ON
      tar_names: wasi_crypto wasi_logging wasmedge_rustls wasmedge_tensorflow wasmedge_tensorflowlite wasmedge_image wasmedge_opencvmini
      test_bins: wasiCryptoTests wasiLoggingTests wasmEdgeRUSTLSTests wasmedgeTensorflowTests wasmedgeTensorflowLiteTests wasmedgeImageTests wasmedgeOpencvminiTests
      output_bins: libwasmedgePluginWasiCrypto.dylib libwasmedgePluginWasiLogging.dylib libwasmedge_rustls.dylib libwasmedgePluginWasmEdgeTensorflow.dylib libwasmedgePluginWasmEdgeTensorflowLite.dylib libwasmedgePluginWasmEdgeImage.dylib libwasmedgePluginWasmEdgeOpenCVMini.dylib
    needs: [get_version]
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Build and install dependencies
        run: |
          eval $(/opt/homebrew/bin/brew shellenv)
          brew install llvm@16 ninja cmake openssl opencv rust
      - name: Build WasmEdge plugins using clang++ with ${{ matrix.build_type }} mode
        shell: bash
        run: |
          eval $(/opt/homebrew/bin/brew shellenv)
          testbin_array=(${test_bins})
          export LLVM_DIR="$(brew --prefix)/opt/llvm@16/lib/cmake"
          export CC=clang
          export CXX=clang++
          cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DWASMEDGE_BUILD_TESTS=ON -DWASMEDGE_BUILD_AOT_RUNTIME=OFF -DWASMEDGE_BUILD_TOOLS=OFF ${build_options} -DOPENSSL_ROOT_DIR=$(brew --prefix)/opt/openssl
          for (( i=0; i<${#testbin_array[@]}; i++ ));
          do
            echo "Building ${testbin_array[$i]} :"
            cmake --build build --target ${testbin_array[$i]}
          done
      - name: Test WasmEdge plugins
        shell: bash
        run: |
          eval $(/opt/homebrew/bin/brew shellenv)
          plugin_array=(${tar_names})
          testbin_array=(${test_bins})
          for (( i=0; i<${#plugin_array[@]}; i++ ));
          do
            if [[ ${plugin_array[$i]} == "wasmedge_opencvmini" ]]; then
              echo "Temporary disable ${plugin_array[$i]} testing"
              continue
            fi
            echo "Testing ${plugin_array[$i]} :"
            cd ${test_prefix}/${plugin_array[$i]}
            ./${testbin_array[$i]}
            cd -
          done
      - name: Prepare the WasmEdge plugins tar.gz package
        shell: bash
        run: |
          eval $(/opt/homebrew/bin/brew shellenv)
          plugin_array=(${tar_names})
          outbin_array=(${output_bins})
          for (( i=0; i<${#plugin_array[@]}; i++ ));
          do
            echo "Copying ${plugin_array[$i]} :"
            cp ${output_prefix}/${plugin_array[$i]}/${outbin_array[$i]} ${outbin_array[$i]}
            tar -zcvf plugin_${plugin_array[$i]}.tar.gz ${outbin_array[$i]}
          done
      - name: Upload artifact - wasi_crypto
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_crypto-${{ needs.get_version.outputs.version }}-${{ matrix.darwin_version }}_${{ matrix.arch }}.tar.gz
          path: plugin_wasi_crypto.tar.gz
      - name: Upload artifact - wasi_logging
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasi_logging-${{ needs.get_version.outputs.version }}-${{ matrix.darwin_version }}_${{ matrix.arch }}.tar.gz
          path: plugin_wasi_logging.tar.gz
      - name: Upload artifact - wasmedge_rustls
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_rustls-${{ needs.get_version.outputs.version }}-${{ matrix.darwin_version }}_${{ matrix.arch }}.tar.gz
          path: plugin_wasmedge_rustls.tar.gz
      - name: Upload artifact - wasmedge_tensorflow
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_tensorflow-${{ needs.get_version.outputs.version }}-${{ matrix.darwin_version }}_${{ matrix.arch }}.tar.gz
          path: plugin_wasmedge_tensorflow.tar.gz
      - name: Upload artifact - wasmedge_tensorflowlite
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_tensorflowlite-${{ needs.get_version.outputs.version }}-${{ matrix.darwin_version }}_${{ matrix.arch }}.tar.gz
          path: plugin_wasmedge_tensorflowlite.tar.gz
      - name: Upload artifact - wasmedge_image
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_image-${{ needs.get_version.outputs.version }}-${{ matrix.darwin_version }}_${{ matrix.arch }}.tar.gz
          path: plugin_wasmedge_image.tar.gz
      - name: Upload artifact - wasmedge_opencvmini
        uses: actions/upload-artifact@v3
        with:
          name: WasmEdge-plugin-wasmedge_opencvmini-${{ needs.get_version.outputs.version }}-${{ matrix.darwin_version }}_${{ matrix.arch }}.tar.gz
          path: plugin_wasmedge_opencvmini.tar.gz
