on:
  push:
    branches: [master, release]
  pull_request:

name: CI

env:
  CARGO_ARGS: --features "ssl jit"
  NON_WASM_PACKAGES: >
    -p rustpython-bytecode
    -p rustpython-common
    -p rustpython-compiler
    -p rustpython-parser
    -p rustpython-vm
    -p rustpython-jit
    -p rustpython-derive
    -p rustpython

jobs:
  rust_tests:
    name: Run rust tests
    runs-on:  ${{ matrix.os }}
    strategy:
      matrix:
        os: [macos-latest, ubuntu-latest, windows-latest]
      fail-fast: false
    steps:
      - uses: actions/checkout@master
      - uses: actions-rs/toolchain@v1
      - name: Set up the Windows environment
        run: |
          choco install llvm
          powershell.exe scripts/symlinks-to-hardlinks.ps1
        if: runner.os == 'Windows'
      - name: Set up the Mac environment
        run: brew install autoconf automake libtool
        if: runner.os == 'macOS'
      - name: Cache cargo dependencies
        uses: actions/cache@v2
        with:
          path: |
              ~/.cargo/registry
              ~/.cargo/git
              target
          key: ${{ runner.os }}-debug_opt3-${{ hashFiles('**/Cargo.lock') }}
      - name: run rust tests
        uses: actions-rs/cargo@v1
        with:
          command: test
          args: --verbose ${{ env.CARGO_ARGS }} ${{ env.NON_WASM_PACKAGES }}
      - name: check compilation without threading
        uses: actions-rs/cargo@v1
        with:
          command: check
          args: ${{ env.CARGO_ARGS }} --no-default-features

  snippets_cpython:
    name: Run snippets and cpython tests
    runs-on:  ${{ matrix.os }}
    strategy:
      matrix:
        os: [macos-latest, ubuntu-latest, windows-latest]
      fail-fast: false
    steps:
      - uses: actions/checkout@master
      - uses: actions-rs/toolchain@v1
      - uses: actions/setup-python@v2
        with:
          python-version: 3.8
      - name: Set up the Windows environment
        run: |
          choco install llvm
          powershell.exe scripts/symlinks-to-hardlinks.ps1
        if: runner.os == 'Windows'
      - name: Set up the Mac environment
        run: brew install autoconf automake libtool
        if: runner.os == 'macOS'
      - name: Cache cargo dependencies
        uses: actions/cache@v2
        # cache gets corrupted for some reason on mac
        if: runner.os != 'macOS'
        with:
          path: |
              ~/.cargo/registry
              ~/.cargo/git
              target
          key: ${{ runner.os }}-release-${{ hashFiles('**/Cargo.lock') }}
      - name: build rustpython
        uses: actions-rs/cargo@v1
        with:
          command: build
          args: --release --verbose ${{ env.CARGO_ARGS }}
      - uses: actions/setup-python@v1
        with:
          python-version: 3.8
      - name: Install pipenv
        run: |
          python -V
          python -m pip install --upgrade pip
          python -m pip install pipenv
      - run: pipenv install --python 3.8
        working-directory: ./extra_tests
      - name: run snippets
        run: pipenv run pytest -v
        working-directory: ./extra_tests
      - name: run cpython tests
        run: target/release/rustpython -m test -v
        env:
          RUSTPYTHONPATH: ${{ github.workspace }}/Lib
        if: runner.os == 'Linux'
      - name: run cpython tests (macOS lightweight)
        run:
          target/release/rustpython -m test -v -x
            test_argparse test_json test_bytes test_bytearray test_long test_unicode test_array
            test_asyncgen test_list test_complex test_json test_set test_dis test_calendar
        env:
          RUSTPYTHONPATH: ${{ github.workspace }}/Lib
        if: runner.os == 'macOS'
      - name: run cpython tests (windows partial - fixme)
        run:
          target/release/rustpython -m test -v -x
            test_argparse test_json test_bytes test_long test_pwd test_bool test_cgi test_complex
            test_exception_hierarchy test_glob test_iter test_list test_os test_pathlib
            test_py_compile test_set test_shutil test_sys test_unicode test_unittest test_venv
            test_zipimport test_importlib test_io
        env:
          RUSTPYTHONPATH: ${{ github.workspace }}/Lib
        if: runner.os == 'Windows'

  lint:
    name: Check Rust code with rustfmt and clippy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - uses: actions-rs/toolchain@v1
        with:
            profile: minimal
            toolchain: stable
            components: rustfmt
            override: true
      - name: run rustfmt
        uses: actions-rs/cargo@v1
        with:
          command: fmt
          args: --all -- --check
      - name: run clippy
        uses: actions-rs/cargo@v1
        with:
          command: clippy
          args: ${{ env.CARGO_ARGS }} ${{ env.NON_WASM_PACKAGES }} -- -Dwarnings
      - name: run clippy on wasm
        uses: actions-rs/cargo@v1
        with:
          command: clippy
          args: --manifest-path=wasm/lib/Cargo.toml -- -Dwarnings
      - uses: actions/setup-python@v1
        with:
          python-version: 3.8
      - name: install flake8
        run: python -m pip install flake8
      - name: run lint
        run: flake8 . --count --exclude=./.*,./Lib,./vm/Lib,./benches/  --select=E9,F63,F7,F82 --show-source --statistics
  miri:
    name: Run tests under miri
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - uses: actions-rs/toolchain@v1
        with:
            profile: minimal
            toolchain: nightly
            components: miri
            override: true
      - name: Run tests under miri
        # miri-ignore-leaks because the type-object circular reference means that there will always be
        # a memory leak, at least until we have proper cyclic gc
        run: MIRIFLAGS='-Zmiri-ignore-leaks' cargo +nightly miri test -p rustpython-vm -- miri_test

  wasm:
    name: Check the WASM package and demo
    needs: rust_tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - name: Cache cargo dependencies
        uses: actions/cache@v2
        with:
          path: |
              ~/.cargo/registry
              ~/.cargo/git
              target
          key: ${{ runner.os }}-wasm_opt3-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
               ${{ runner.os }}-debug_opt3-${{ hashFiles('**/Cargo.lock') }}
      - name: install wasm-pack
        run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
      - name: install geckodriver
        run: |
          wget https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-linux32.tar.gz
          mkdir geckodriver
          tar -xzf geckodriver-v0.24.0-linux32.tar.gz -C geckodriver
      - uses: actions/setup-python@v1
        with:
          python-version: 3.8
      - name: Install pipenv
        run: |
          python -V
          python -m pip install --upgrade pip
          python -m pip install pipenv
      - run: pipenv install
        working-directory: ./wasm/tests
      - uses: actions/setup-node@v1
      - name: run test
        run: |
          export PATH=$PATH:`pwd`/../../geckodriver
          npm install
          npm run test
        working-directory: ./wasm/demo
      - name: build notebook demo
        if: github.ref == 'refs/heads/release'
        run: |
          npm install
          npm run dist
          mv dist ../demo/dist/notebook
        working-directory: ./wasm/notebook
      - name: Deploy demo to Github Pages
        if: success() && github.ref == 'refs/heads/release'
        uses: peaceiris/actions-gh-pages@v2
        env:
          ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEMO_DEPLOY_KEY }}
          PUBLISH_DIR: ./wasm/demo/dist
          EXTERNAL_REPOSITORY: RustPython/demo
          PUBLISH_BRANCH: master

