name: CI
on:
  workflow_call:
    secrets:
      codecov_token:
        required: true
jobs:
  lint:
    name: Lint source files
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
        with:
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          cache: npm
          node-version-file: '.node-version'

      - name: Install Dependencies
        run: npm ci --ignore-scripts

      - name: Lint ESLint
        run: npm run lint

      - name: Check Types
        run: npm run check

      - name: Lint Prettier
        run: npm run prettier:check

      - name: Spellcheck
        run: npm run check:spelling

  checkForCommonlyIgnoredFiles:
    name: Check for commonly ignored files
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
        with:
          persist-credentials: false

      - name: Check if commit contains files that should be ignored
        run: |
          git clone --depth 1 https://github.com/github/gitignore.git &&
          cat gitignore/Node.gitignore $(find gitignore/Global -name "*.gitignore" | grep -v ModelSim) > all.gitignore &&
          if  [[ "$(git ls-files -iX all.gitignore)" != "" ]]; then
            echo "::error::Please remove these files:"
            git ls-files -iX all.gitignore
            exit 1
          fi

  checkPackageLock:
    name: Check health of package-lock.json file
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
        with:
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          cache: npm
          node-version-file: '.node-version'

      - name: Install Dependencies
        run: npm ci --ignore-scripts

      - name: Run npm install
        run: npm install --ignore-scripts --force --package-lock-only --engine-strict --strict-peer-deps

      - name: Check that package-lock.json is in sync with package.json
        run: git diff --exit-code package-lock.json

  integrationTests:
    name: Run integration tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
        with:
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version-file: '.node-version'
          # We install bunch of packages during integration tests without locking them
          # so we skip cache action to not pollute cache for other jobs.

      - name: Install Dependencies
        run: npm ci --ignore-scripts

      - name: Run Integration Tests
        run: npm run check:integrations

  fuzz:
    name: Run fuzzing tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
        with:
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          cache: npm
          node-version-file: '.node-version'

      - name: Install Dependencies
        run: npm ci --ignore-scripts

      - name: Run Tests
        run: npm run fuzzonly

  coverage:
    name: Measure test coverage
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
        with:
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          cache: npm
          node-version-file: '.node-version'

      - name: Install Dependencies
        run: npm ci --ignore-scripts

      - name: Run tests and measure code coverage
        run: npm run testonly:cover

      - name: Upload coverage to Codecov
        if: ${{ always() }}
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage/coverage-final.json
          fail_ci_if_error: true
          token: ${{ secrets.codecov_token }}

  test:
    name: Run tests on Node v${{ matrix.node_version_to_setup }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node_version_to_setup: [12, 14, 16, 17]
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
        with:
          persist-credentials: false

      - name: Setup Node.js v${{ matrix.node_version_to_setup }}
        uses: actions/setup-node@v2
        with:
          cache: npm
          node-version: ${{ matrix.node_version_to_setup }}

      - name: Install Dependencies
        run: npm ci --ignore-scripts

      - name: Run Tests
        run: npm run testonly

  build-npm-dist:
    name: Build 'npmDist' artifact
    runs-on: ubuntu-latest
    needs: [test, fuzz, lint, integrationTests]
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
        with:
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          cache: npm
          node-version-file: '.node-version'

      - name: Install Dependencies
        run: npm ci --ignore-scripts

      - name: Build NPM package
        run: npm run build:npm

      - name: Upload npmDist package
        uses: actions/upload-artifact@v4
        with:
          name: npmDist
          path: ./npmDist

  build-deno-dist:
    name: Build 'denoDist' artifact
    runs-on: ubuntu-latest
    needs: [test, fuzz, lint, integrationTests]
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
        with:
          persist-credentials: false

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version-file: '.node-version'

      - name: Install Dependencies
        run: npm ci --ignore-scripts

      - name: Build Deno package
        run: npm run build:deno

      - name: Upload denoDist package
        uses: actions/upload-artifact@v4
        with:
          name: denoDist
          path: ./denoDist