name: ci

on:
  pull_request:
    paths:
      - '**'
      - '!.gitignore'
      - '!LICENSE'
      - '!TODO'
      - '!doc/**'
      - '!examples/**'
      - '.github/workflows/ci.yml'
  push:
    branches:
      - master

jobs:
  linux:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        buildType: [Debug, Release]
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: true
      - name: build
        run: |
          make BUILD_TYPE=${{matrix.buildType}}
      - name: stats
        run: |
          make stats
      - name: test
        run: |
          make test
      - name: test 262
        if: ${{ matrix.buildType == 'Release' }}
        run: |
          time make test262
  linux-32bits:
    runs-on: ubuntu-latest
    defaults:
      run:
        shell: alpine.sh {0}
    steps:
      - uses: actions/checkout@v3
      - uses: jirutka/setup-alpine@v1
        with:
          arch: x86
          packages: "build-base make cmake"
      - name: build
        run: |
          make
      - name: stats
        run: |
          make stats
      - name: test
        run: |
          make test
  linux-gcc48:
    runs-on: ubuntu-latest
    container:
      image: ubuntu:14.04
    steps:
      - name: install dependencies
        run: |
          apt update && apt -y install make gcc-4.8 wget time software-properties-common
          # git in default ppa repository is too old to run submodule checkout
          add-apt-repository -y ppa:git-core/ppa
          apt update
          apt install -y git
          wget https://github.com/Kitware/CMake/releases/download/v3.28.0-rc5/cmake-3.28.0-rc5-linux-x86_64.sh
          sh cmake-3.28.0-rc5-linux-x86_64.sh --skip-license --prefix=/usr
      - name: checkout
        uses: actions/checkout@v3
        with:
          submodules: true
      - name: build
        run: |
          CC=gcc-4.8 make
      - name: stats
        run: |
          make stats
      - name: test
        run: |
          make test
      - name: test 262
        run: |
          time make test262
  linux-examples:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: build
        run: |
          make BUILD_EXAMPLES=ON
      - name: test
        run: |
          ldd build/hello
          ldd build/hello_module
          ldd build/test_fib
          ./build/hello
          ./build/hello_module
          ./build/test_fib
          cp build/fib.so examples/
          cp build/point.so examples/
          cp build/bjson.so tests/
          ./build/qjs examples/test_fib.js
          ./build/qjs examples/test_point.js
          ./build/qjs tests/test_bjson.js
          ./build/function_source
  linux-shared:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: build
        run: |
          make BUILD_SHARED_LIBS=ON
          ldd build/qjs
      - name: stats
        run: |
          make stats
  linux-asan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: true
      - name: build
        run: |
          make CONFIG_ASAN=ON
      - name: test
        env:
          ASAN_OPTIONS: halt_on_error=1
        run: |
          make test
      - name: test 262
        env:
          ASAN_OPTIONS: halt_on_error=1
        run: |
          time make test262
  linux-msan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: true
      - name: build
        env:
          CC: clang
        run: |
          make CONFIG_MSAN=ON
      - name: test
        env:
          MSAN_OPTIONS: halt_on_error=1
        run: |
          make test
  linux-ubsan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: true
      - name: build
        run: |
          make CONFIG_UBSAN=ON
      - name: test
        env:
          UBSAN_OPTIONS: halt_on_error=1
        run: |
          make test
      - name: test 262
        env:
          UBSAN_OPTIONS: halt_on_error=1
        run: |
          time make test262

  macos:
    runs-on: macos-latest
    strategy:
      fail-fast: false
      matrix:
        buildType: [Debug, Release]
    steps:
      - uses: actions/checkout@v3
      - name: build
        run: |
          make BUILD_TYPE=${{matrix.buildType}}
      - name: stats
        run: |
          make stats
      - name: test
        run: |
          make test
  macos-examples:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - name: build
        run: |
          make BUILD_EXAMPLES=ON
      - name: test
        run: |
          otool -L build/hello
          otool -L build/hello_module
          otool -L build/test_fib
          ./build/hello
          ./build/hello_module
          ./build/test_fib
          cp build/fib.so examples/
          cp build/point.so examples/
          cp build/bjson.so tests/
          ./build/qjs examples/test_fib.js
          ./build/qjs examples/test_point.js
          ./build/qjs tests/test_bjson.js
          ./build/function_source
  macos-shared:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - name: build
        run: |
          make BUILD_SHARED_LIBS=ON
          otool -L build/qjs
      - name: stats
        run: |
          make stats
  macos-asan:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - name: build
        run: |
          make CONFIG_ASAN=ON
      - name: test
        env:
          ASAN_OPTIONS: halt_on_error=1
        run: |
          make test
  macos-ubsan:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - name: build
        run: |
          make CONFIG_UBSAN=ON
      - name: test
        env:
          UBSAN_OPTIONS: halt_on_error=1
        run: |
          make test

  windows-clang:
    runs-on: windows-latest
    strategy:
      fail-fast: false
      matrix:
        buildType: [Debug, Release]
    steps:
      - uses: actions/checkout@v3
      - name: build
        run: |
          cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Visual Studio 17 2022" -T ClangCL
          cmake --build build --target qjs_exe
          cmake --build build --target function_source
      - name: stats
        run: |
          cmd /r build\Debug\qjs.exe -qd
      - name: test
        run: |
          cmd /r build\Debug\qjs.exe tests\test_bigint.js
          cmd /r build\Debug\qjs.exe tests\test_closure.js
          cmd /r build\Debug\qjs.exe tests\test_language.js
          cmd /r build\Debug\qjs.exe tests\test_builtin.js
          cmd /r build\Debug\qjs.exe tests\test_loop.js
          cmd /r build\Debug\qjs.exe tests\test_std.js
          cmd /r build\Debug\qjs.exe tests\test_worker.js
          cmd /r build\Debug\qjs.exe tests\test_queue_microtask.js
          cmd /r build\Debug\function_source.exe

  windows-mingw:
    runs-on: windows-latest
    strategy:
      fail-fast: false
      matrix:
        buildType: [Debug, Release]
        sys:
          - mingw32
          - mingw64
          - clang64
          - ucrt64
    defaults:
      run:
        shell: msys2 {0}
    steps:
    - uses: actions/checkout@v3
    - name: Setup MSYS2
      uses: msys2/setup-msys2@v2
      with:
        msystem: ${{matrix.sys}}
        install: >-
          git
          make
        pacboy: >-
          cmake:p
          ninja:p
          toolchain:p
    - name: build
      run: |
        make BUILD_TYPE=${{matrix.buildType}}
    - name: stats
      run: |
        make stats
        ldd build/qjs
    - name: test
      run: |
        make test
  windows-mingw-shared:
    runs-on: windows-latest
    defaults:
      run:
        shell: msys2 {0}
    steps:
      - uses: actions/checkout@v3
      - name: Setup MSYS2
        uses: msys2/setup-msys2@v2
        with:
          install: >-
            git
            make
          pacboy: >-
            cmake:p
            ninja:p
            toolchain:p
      - name: build
        run: |
          make BUILD_SHARED_LIBS=ON
          ldd build/qjs
      - name: stats
        run: |
          make stats

  emscripten:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: mymindstorm/setup-emsdk@v13
      - name: check emsdk
        run: emcc -v
      - name: build
        run: |
          emcmake cmake -B build
          emmake make -C build qjs_wasm -j$(getconf _NPROCESSORS_ONLN)
      - name: result
        run: ls -lh build

  cygwin:
    runs-on: windows-latest
    defaults:
      run:
        shell: C:\cygwin\bin\bash.exe --login --norc -eo pipefail -o igncr '{0}'
    env:
      CYGWIN_NOWINPATH: 1
      CHERE_INVOKING: 1
    steps:
      - name: Set up Cygwin
        uses: cygwin/cygwin-install-action@master
        with:
            packages: make cmake gcc-g++ bash

      - uses: actions/checkout@v3

      - name: build
        run: make

      - name: stats
        run: make stats

      - name: test
        run: make test

  openbsd:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: build + test
        uses: vmactions/openbsd-vm@v1
        with:
          usesh: true
          prepare: |
            pkg_add cmake gmake
          run: |
            gmake
            gmake stats

  freebsd:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: build + test
        uses: vmactions/freebsd-vm@v1
        with:
          usesh: true
          prepare: |
            pkg install -y cmake gmake
          run: |
            gmake
            gmake stats

  netbsd:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: build + test
        uses: vmactions/netbsd-vm@v1
        with:
          usesh: true
          prepare: |
            /usr/sbin/pkg_add cmake gmake
          run: |
            gmake
            gmake stats
            gmake test