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: Setup and run tsc
      run: yarn setup
    - name: Esbuild
      run: yarn esbuild
    - name: Zip artifacts
      run: |
        zip -r compressed-build \
          ./lib/* \
          ./out/* \
          ./out-*/* \
          ./addons/addon-attach/lib/* \
          ./addons/addon-attach/out/* \
          ./addons/addon-attach/out-*/* \
          ./addons/addon-clipboard/lib/* \
          ./addons/addon-clipboard/out/* \
          ./addons/addon-clipboard/out-*/* \
          ./addons/addon-fit/lib/* \
          ./addons/addon-fit/out/* \
          ./addons/addon-fit/out-*/* \
          ./addons/addon-image/lib/* \
          ./addons/addon-image/out/* \
          ./addons/addon-image/out-*/* \
          ./addons/addon-ligatures/lib/* \
          ./addons/addon-ligatures/out/* \
          ./addons/addon-ligatures/out-*/* \
          ./addons/addon-search/lib/* \
          ./addons/addon-search/out/* \
          ./addons/addon-search/out-*/* \
          ./addons/addon-serialize/lib/* \
          ./addons/addon-serialize/out/* \
          ./addons/addon-serialize/out-*/* \
          ./addons/addon-unicode11/lib/* \
          ./addons/addon-unicode11/out/* \
          ./addons/addon-unicode11/out-*/* \
          ./addons/addon-unicode-graphemes/lib/* \
          ./addons/addon-unicode-graphemes/out/* \
          ./addons/addon-unicode-graphemes/out-*/* \
          ./addons/addon-web-links/lib/* \
          ./addons/addon-web-links/out/* \
          ./addons/addon-web-links/out-*/* \
          ./addons/addon-webgl/lib/* \
          ./addons/addon-webgl/out/* \
          ./addons/addon-webgl/out-*st/*
    - 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:
    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-integration:
    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 esbuild-demo
    - name: Integration tests (core) # Tests use 50% workers to reduce flakiness
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=core
    - name: Integration tests (addon-attach)
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-attach
    - name: Integration tests (addon-clipboard)
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-clipboard
    - name: Integration tests (addon-fit)
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-fit
    - name: Integration tests (addon-image)
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-image
    - name: Integration tests (addon-search)
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-search
    - name: Integration tests (addon-serialize)
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-serialize
    - name: Integration tests (addon-unicode-graphemes)
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-unicode-graphemes
    - name: Integration tests (addon-unicode11)
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-unicode11
    - name: Integration tests (addon-web-links)
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-web-links
    - name: Integration tests (addon-webgl)
      run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-webgl

  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
