name: CI

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js 18.x
      uses: actions/setup-node@v3
      with:
        node-version: 18.x
        cache: 'yarn'
    - name: Install dependencies
      run: yarn --frozen-lockfile
    - name: Build
      run: yarn setup
    - name: Zip artifacts
      run: |
        zip -r compressed-build \
          ./out/* \
          ./out-test/* \
          ./addons/addon-attach/out/* \
          ./addons/addon-attach/out-test/* \
          ./addons/addon-canvas/out/* \
          ./addons/addon-canvas/out-test/* \
          ./addons/addon-fit/out/* \
          ./addons/addon-fit/out-test/* \
          ./addons/addon-image/out/* \
          ./addons/addon-image/out-test/* \
          ./addons/addon-ligatures/out/* \
          ./addons/addon-ligatures/out-test/* \
          ./addons/addon-search/out/* \
          ./addons/addon-search/out-test/* \
          ./addons/addon-serialize/out/* \
          ./addons/addon-serialize/out-test/* \
          ./addons/addon-unicode11/out/* \
          ./addons/addon-unicode11/out-test/* \
          ./addons/addon-unicode-graphemes/out/* \
          ./addons/addon-unicode-graphemes/out-test/* \
          ./addons/addon-web-links/out/* \
          ./addons/addon-web-links/out-test/* \
          ./addons/addon-webgl/out/* \
          ./addons/addon-webgl/out-test/*
    - name: Upload artifacts
      uses: actions/upload-artifact@v3
      with:
        name: build-artifacts
        path: compressed-build.zip
        if-no-files-found: error

  lint:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js 18.x
      uses: actions/setup-node@v3
      with:
        node-version: 18.x
        cache: 'yarn'
    - name: Install dependencies
      run: |
        yarn --frozen-lockfile
        yarn install-addons
    - name: Lint code
      env:
        NODE_OPTIONS: --max_old_space_size=4096
      run: yarn lint
    - name: Lint API
      run: yarn lint-api

  test-unit-coverage:
    needs: build
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js 18.x
      uses: actions/setup-node@v3
      with:
        node-version: 18.x
        cache: 'yarn'
    - name: Install dependencies
      run: |
        yarn --frozen-lockfile
        yarn install-addons
    - uses: actions/download-artifact@v3
      with:
        name: build-artifacts
    - name: Unzip artifacts
      shell: bash
      run: |
        if [ "$RUNNER_OS" == "Windows" ]; then
          pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
        else
          unzip -o compressed-build.zip
        fi
        ls -R
    - name: Unit test coverage
      run: |
        yarn test-unit-coverage --forbid-only
        EXIT_CODE=$?
        ./node_modules/.bin/nyc report --reporter=cobertura
        exit $EXIT_CODE

  test-unit-parallel:
    timeout-minutes: 20
    strategy:
      matrix:
        node-version: [18]
        runs-on: [ubuntu, macos, windows]
    runs-on: ${{ matrix.runs-on }}-latest
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js ${{ matrix.node-version }}.x
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}.x
        cache: 'yarn'
    - name: Install dependencies
      run: |
        yarn --frozen-lockfile
        yarn install-addons
    - name: Wait for build job
      uses: NathanFirmo/wait-for-other-job@v1.1.1
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
        job: build
    - uses: actions/download-artifact@v3
      with:
        name: build-artifacts
    - name: Unzip artifacts
      shell: bash
      run: |
        if [ "$RUNNER_OS" == "Windows" ]; then
          pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
        else
          unzip -o compressed-build.zip
        fi
        ls -R
    - name: Unit tests
      run: yarn test-unit --forbid-only

  test-api-parallel:
    timeout-minutes: 20
    strategy:
      matrix:
        node-version: [18] # just one as integration tests are about testing in browser
        runs-on: [ubuntu] # macos is flaky
        browser: [chromium, firefox]
    runs-on: ${{ matrix.runs-on }}-latest
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js ${{ matrix.node-version }}.x
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}.x
        cache: 'yarn'
    - name: Install dependencies
      run: |
        yarn --frozen-lockfile
        yarn install-addons
    - name: Install playwright
      run: npx playwright install
    - name: Wait for build job
      uses: NathanFirmo/wait-for-other-job@v1.1.1
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
        job: build
    - uses: actions/download-artifact@v3
      with:
        name: build-artifacts
    - name: Unzip artifacts
      shell: bash
      run: |
        if [ "$RUNNER_OS" == "Windows" ]; then
          pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
        else
          unzip -o compressed-build.zip
        fi
        ls -R
    - name: Integration tests (${{ matrix.browser }})
      run: yarn test-api-${{ matrix.browser }} --headless --forbid-only

  test-playwright-parallel:
    timeout-minutes: 20
    strategy:
      matrix:
        node-version: [18] # just one as integration tests are about testing in browser
        runs-on: [ubuntu] # macos is flaky
        browser: [chromium, firefox, webkit]
    runs-on: ${{ matrix.runs-on }}-latest
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js ${{ matrix.node-version }}.x
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}.x
        cache: 'yarn'
    - name: Install dependencies
      run: |
        yarn --frozen-lockfile
        yarn install-addons
    - name: Install playwright
      run: npx playwright install --with-deps ${{ matrix.browser }}
    - name: Wait for build job
      uses: NathanFirmo/wait-for-other-job@v1.1.1
      with:
        token: ${{ secrets.GITHUB_TOKEN }}
        job: build
    - uses: actions/download-artifact@v3
      with:
        name: build-artifacts
    - name: Unzip artifacts
      shell: bash
      run: |
        if [ "$RUNNER_OS" == "Windows" ]; then
          pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
        else
          unzip -o compressed-build.zip
        fi
        ls -R
    - name: Build demo
      run: yarn build-demo
    - name: Integration tests (core) # Tests use 50% workers to reduce flakiness
      run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=core
    - name: Integration tests (addon-canvas)
      run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-canvas
    - name: Integration tests (addon-webgl)
      run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-webgl

  test-api:
    needs: build
    timeout-minutes: 20
    strategy:
      matrix:
        node-version: [18] # just one as integration tests are about testing in browser
        runs-on: [windows] # macos is flaky
        browser: [chromium, firefox]
    runs-on: ${{ matrix.runs-on }}-latest
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js ${{ matrix.node-version }}.x
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}.x
        cache: 'yarn'
    - name: Install dependencies
      run: |
        yarn --frozen-lockfile
        yarn install-addons
    - name: Install playwright
      run: npx playwright install
    - uses: actions/download-artifact@v3
      with:
        name: build-artifacts
    - name: Unzip artifacts
      shell: bash
      run: |
        if [ "$RUNNER_OS" == "Windows" ]; then
          pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
        else
          unzip -o compressed-build.zip
        fi
        ls -R
    - name: Integration tests (${{ matrix.browser }})
      run: yarn test-api-${{ matrix.browser }} --headless --forbid-only

  release-dry-run:
    needs: build
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18]
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js ${{ matrix.node-version }}.x
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}.x
        cache: 'yarn'
    - name: Install dependencies
      run: |
        yarn --frozen-lockfile
        yarn install-addons
    - name: Install playwright
      run: npx playwright install
    - uses: actions/download-artifact@v3
      with:
        name: build-artifacts
    - name: Unzip artifacts
      shell: bash
      run: |
        if [ "$RUNNER_OS" == "Windows" ]; then
          pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
        else
          unzip -o compressed-build.zip
        fi
        ls -R
    - name: Package headless
      run: |
        yarn package-headless
        node ./bin/package_headless.js
    - name: Publish to npm (dry run)
      run: node ./bin/publish.js --dry
