name: CI

on:
  # If we run CI on all branches then we end up doing duplicate work for
  # branches which are also PRs.
  push:
    branches:
      - main
      - kripken/*
  pull_request:

jobs:

  lint:
    name: lint
    if: ${{ github.event_name == 'pull_request' }}
    runs-on: ubuntu-latest
    steps:
    - uses: actions/setup-python@v1
      with:
        python-version: '3.x'
    - uses: actions/checkout@v1
      with:
        submodules: true
    - name: install tools
      run: |
        sudo pip3 install -r requirements-dev.txt
        sudo apt-get install clang-format clang-tidy
    - name: update path
      run:  echo "PATH=$PATH:/usr/lib/llvm-8/bin" >> $GITHUB_ENV
    - run: flake8
    - run: ./scripts/clang-format-diff.sh
    - name: clang-tidy
      run: |
        # clang-tidy requires compile_commands.json generated by cmake
        cmake . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
        ./scripts/clang-tidy-diff.sh

  build:
    name: build
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    steps:
    - uses: actions/setup-python@v1
      with:
        python-version: '3.x'
    - uses: actions/checkout@v1
      with:
        submodules: true

    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt

    - name: gen-s-parser
      run: ./scripts/gen-s-parser.py | diff src/gen-s-parser.inc -
      if: matrix.os == 'ubuntu-latest'

    - name: install ninja (linux)
      run: sudo apt-get install ninja-build
      if: matrix.os == 'ubuntu-latest'

    - name: install ninja (macos)
      run: brew install ninja
      if: matrix.os == 'macos-latest'

    - name: install ninja (win)
      run: choco install ninja
      if: matrix.os == 'windows-latest'

    - name: mkdir
      run: mkdir -p out

    - name: cmake (linux)
      run: cmake -S . -B out -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=out/install
      if: matrix.os == 'ubuntu-latest'

    - name: cmake (macos)
      run: cmake -S . -B out -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_OSX_ARCHITECTURES=x86_64
      if: matrix.os == 'macos-latest'

    - name: cmake (win)
      # -G "Visual Studio 15 2017"
      run: cmake -S . -B out -DCMAKE_INSTALL_PREFIX=out/install
      if: matrix.os == 'windows-latest'

    - name: build
      run: cmake --build out --config Release -v

    - name: install
      run: cmake --install out --config Release

    - name: strip
      run: find out/install/ -type f -perm -u=x -exec strip -x {} +
      if: matrix.os != 'windows-latest'

    - name: Upload artifacts
      uses: actions/upload-artifact@v1
      with:
        name: build-${{ matrix.os }}
        path: out/install

    - name: test binaryen-lit
      run: python out/bin/binaryen-lit -vv test/lit/parse-error.wast

    - name: test
      run: python check.py --binaryen-bin=out/bin

  build-clang:
    name: clang (LTO)
    runs-on: ubuntu-latest
    steps:
    - uses: actions/setup-python@v1
      with:
        python-version: '3.x'
    - uses: actions/checkout@v1
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DBYN_ENABLE_LTO=ON
    - name: build
      run: cmake --build out -v
    - name: test binaryen-lit
      run: python out/bin/binaryen-lit -vv test/lit/parse-error.wast
    - name: test
      run: python check.py --binaryen-bin=out/bin

  # TODO(sbc): Find a way to reduce the duplicate between these sanitizer jobs
  build-asan:
    name: asan
    runs-on: ubuntu-latest
    env:
      ASAN_OPTIONS: "symbolize=1"
      COMPILER_FLAGS: "-fsanitize=address"
    steps:
    - uses: actions/setup-python@v1
      with:
        python-version: '3.x'
    - uses: actions/checkout@v1
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_FLAGS="$COMPILER_FLAGS" -DCMAKE_CXX_FLAGS="$COMPILER_FLAGS"
    - name: build
      run: cmake --build out
    - name: test
      run: python check.py --binaryen-bin=out/bin

  # Build with gcc 6.3 and run tests on Alpine Linux (inside chroot).
  # Note: Alpine uses musl libc.
  # Keep in sync with build_release.yml
  build-alpine:
    name: alpine
    runs-on: ubuntu-latest
    steps:
    - uses: actions/setup-python@v1
      with:
        python-version: '3.x'
    - uses: actions/checkout@v1
      with:
        submodules: true
    - name: start docker
      run: |
        docker run -w /src -dit --name alpine -v $PWD:/src node:lts-alpine
        echo 'docker exec alpine "$@";' > ./alpine.sh
        chmod +x ./alpine.sh

    - name: install packages
      run: |
        ./alpine.sh apk update
        ./alpine.sh apk add build-base cmake git python3 py3-pip clang ninja

    - name: install python dev dependencies
      run: ./alpine.sh pip3 install -r requirements-dev.txt

    - name: cmake
      run: |
        ./alpine.sh cmake . -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_CXX_FLAGS="-static" -DCMAKE_C_FLAGS="-static" -DCMAKE_BUILD_TYPE=Release -DBUILD_STATIC_LIB=ON -DCMAKE_INSTALL_PREFIX=install

    - name: build
      run: |
        ./alpine.sh ninja install

    - name: test
      run: ./alpine.sh python3 ./check.py

  # Duplicates build-asan.  Please keep in sync
  build-ubsan:
    name: ubsan
    runs-on: ubuntu-latest
    env:
      COMPILER_FLAGS: "-fsanitize=undefined -fno-sanitize-recover=all"
      CC: "clang"
      CXX: "clang++"
    steps:
    - uses: actions/setup-python@v1
      with:
        python-version: '3.x'
    - uses: actions/checkout@v1
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_FLAGS="$COMPILER_FLAGS" -DCMAKE_CXX_FLAGS="$COMPILER_FLAGS -fsanitize-blacklist=$PWD/ubsan.blacklist"
    - name: build
      run: cmake --build out
    - name: test
      run: python check.py --binaryen-bin=out/bin

  # Duplicates build-asan.  Please keep in sync
  build-tsan:
    name: tsan
    runs-on: ubuntu-latest
    env:
      COMPILER_FLAGS: "-fsanitize=thread"
      LINKER_FLAGS: "-fsanitize=thread"
    steps:
    - uses: actions/setup-python@v1
      with:
        python-version: '3.x'
    - uses: actions/checkout@v1
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: install Python dev dependencies
      run: pip3 install -r requirements-dev.txt
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G Ninja -DCMAKE_INSTALL_PREFIX=out/install -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_FLAGS="$COMPILER_FLAGS" -DCMAKE_CXX_FLAGS="$COMPILER_FLAGS" -DCMAKE_EXE_LINKER_FLAGS="$LINKER_FLAGS"
    - name: build
      run: cmake --build out
    - name: test
      run: python check.py --binaryen-bin=out/bin

  # Build the .js outputs using emcc
  build-emscripten:
    name: emscripten
    runs-on: ubuntu-latest
    steps:
    - uses: actions/setup-python@v1
      with:
        python-version: '3.x'
    - uses: actions/checkout@v1
      with:
        submodules: true
    - name: install ninja
      run: sudo apt-get install ninja-build
    - name: emsdk install
      run: |
        mkdir $HOME/emsdk
        git clone --depth 1 https://github.com/emscripten-core/emsdk.git $HOME/emsdk
        $HOME/emsdk/emsdk update-tags
        $HOME/emsdk/emsdk install tot
        $HOME/emsdk/emsdk activate tot
    - name: update path
      run:  echo "PATH=$PATH:$HOME/emsdk" >> $GITHUB_ENV
    - name: emcc-tests
      run: |
        source $HOME/emsdk/emsdk_env.sh
        ./scripts/emcc-tests.sh

  # Windows + gcc needs work before the tests will run, so just test the compile
  build-mingw:
    name: mingw
    runs-on: windows-latest
    steps:
    - uses: actions/setup-python@v1
      with:
        python-version: '3.x'
    - uses: actions/checkout@v1
      with:
        submodules: true
    - name: cmake
      run: |
        mkdir -p out
        cmake -S . -B out -G "MSYS Makefiles"
    - name: build
      run: cmake --build out
