name: 'Tests'

on:
  push:
    branches:
      - main
  pull_request:
    paths-ignore:
      - 'docs/**'
      - '**.mdx?'

concurrency:
  group: ${{ github.workflow }}-${{ github.ref_name }}
  cancel-in-progress: true

permissions:
  contents: read  #  to fetch code (actions/checkout)

jobs:
  lint:
    name: 'lint (node: ${{ matrix.node }})'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [14, 16, 18]
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}

      - run: yarn install --frozen-lockfile
      - name: Run lint
        run: yarn run -s lint

  unit_back:
    name: 'unit_back (node: ${{ matrix.node }})'
    needs: [lint]
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [14, 16, 18]
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}

      - run: yarn install --frozen-lockfile
      - name: Run tests
        run: yarn run -s test:unit --coverage
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          directory: ./coverage
          flags: back,unit_back

  unit_front:
    name: 'unit_front (node: ${{ matrix.node }})'
    needs: [lint]
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [14, 16, 18]
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}

      - run: yarn install --frozen-lockfile
      - name: Build
        run: yarn build
      - name: Run test
        run: yarn run -s test:front --coverage
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          directory: ./coverage
          flags: front,unit_front

  api_ce_pg:
    runs-on: ubuntu-latest
    needs: [lint, unit_back, unit_front]
    name: '[CE] API Integration (postgres, node: ${{ matrix.node }})'
    strategy:
      matrix:
        node: [14, 16, 18]
    services:
      postgres:
        # Docker Hub image
        image: postgres
        # Provide the password for postgres
        env:
          POSTGRES_USER: strapi
          POSTGRES_PASSWORD: strapi
          POSTGRES_DB: strapi_test
        # Set health checks to wait until postgres has started
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
          -v /__w/.github/workflows/db/postgres:/docker-entrypoint-initdb.d
        ports:
          # Maps tcp port 5432 on service container to the host
          - 5432:5432
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
      - run: yarn install --frozen-lockfile
      - uses: ./.github/actions/run-api-tests
        with:
          dbOptions: '--dbclient=postgres --dbhost=localhost --dbport=5432 --dbname=strapi_test --dbusername=strapi --dbpassword=strapi'

  api_ce_mysql:
    runs-on: ubuntu-latest
    needs: [lint, unit_back, unit_front]
    name: '[CE] API Integration (mysql, node: ${{ matrix.node }})'
    strategy:
      matrix:
        node: [14, 16, 18]
    services:
      mysql:
        image: mysql
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3
          -e MYSQL_ROOT_PASSWORD=strapi
          -e MYSQL_ROOT_HOST="%"
          -e MYSQL_USER=strapi
          -e MYSQL_PASSWORD=strapi
          -e MYSQL_DATABASE=strapi_test
          --entrypoint sh mysql -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password"
        ports:
          # Maps tcp port 5432 on service container to the host
          - 3306:3306
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
      - run: yarn install --frozen-lockfile
      - uses: ./.github/actions/run-api-tests
        with:
          dbOptions: '--dbclient=mysql --dbhost=localhost --dbport=3306 --dbname=strapi_test --dbusername=strapi --dbpassword=strapi'

  api_ce_mysql_5:
    runs-on: ubuntu-latest
    needs: [lint, unit_back, unit_front]
    name: '[CE] API Integration (mysql:5 , node: ${{ matrix.node }})'
    strategy:
      matrix:
        node: [14, 16, 18]
    services:
      mysql:
        image: mysql:5
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3
          -e MYSQL_ROOT_PASSWORD=strapi
          -e MYSQL_ROOT_HOST="%"
          -e MYSQL_USER=strapi
          -e MYSQL_PASSWORD=strapi
          -e MYSQL_DATABASE=strapi_test
          --entrypoint sh mysql -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password"
        ports:
          # Maps tcp port 5432 on service container to the host
          - 3306:3306
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
      - run: yarn install --frozen-lockfile
      - uses: ./.github/actions/run-api-tests
        with:
          dbOptions: '--dbclient=mysql --dbhost=localhost --dbport=3306 --dbname=strapi_test --dbusername=strapi --dbpassword=strapi'

  api_ce_sqlite:
    runs-on: ubuntu-latest
    needs: [lint, unit_back, unit_front]
    name: '[CE] API Integration (sqlite: ${{ matrix.sqlite_pkg }}, node: ${{ matrix.node }})'
    strategy:
      matrix:
        node: [14, 16, 18]
        sqlite_pkg: ['better-sqlite3', 'sqlite3', '@vscode/sqlite3']
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
      - run: yarn install --frozen-lockfile
      - uses: ./.github/actions/run-api-tests
        env:
          SQLITE_PKG: ${{ matrix.sqlite_pkg }}
        with:
          dbOptions: '--dbclient=sqlite-legacy --dbfile=./tmp/data.db'
  # EE
  api_ee_pg:
    runs-on: ubuntu-latest
    needs: [lint, unit_back, unit_front]
    name: '[EE] API Integration (postgres, node: ${{ matrix.node }})'
    if: github.event.pull_request.head.repo.full_name == github.repository && !(github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]')
    env:
      STRAPI_LICENSE: ${{ secrets.strapiLicense }}
    strategy:
      matrix:
        node: [14, 16, 18]
    services:
      postgres:
        # Docker Hub image
        image: postgres
        # Provide the password for postgres
        env:
          POSTGRES_USER: strapi
          POSTGRES_PASSWORD: strapi
          POSTGRES_DB: strapi_test
        # Set health checks to wait until postgres has started
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
          -v /__w/.github/workflows/db/postgres:/docker-entrypoint-initdb.d
        ports:
          # Maps tcp port 5432 on service container to the host
          - 5432:5432
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
      - run: yarn install --frozen-lockfile
      - uses: ./.github/actions/run-api-tests
        with:
          dbOptions: '--dbclient=postgres --dbhost=localhost --dbport=5432 --dbname=strapi_test --dbusername=strapi --dbpassword=strapi'
          runEE: true
  api_ee_mysql:
    runs-on: ubuntu-latest
    needs: [lint, unit_back, unit_front]
    name: '[EE] API Integration (mysql, node: ${{ matrix.node }})'
    if: github.event.pull_request.head.repo.full_name == github.repository && !(github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]')
    env:
      STRAPI_LICENSE: ${{ secrets.strapiLicense }}
    strategy:
      matrix:
        node: [14, 16, 18]
    services:
      mysql:
        image: mysql
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3
          -e MYSQL_ROOT_PASSWORD=strapi
          -e MYSQL_ROOT_HOST="%"
          -e MYSQL_USER=strapi
          -e MYSQL_PASSWORD=strapi
          -e MYSQL_DATABASE=strapi_test
          --entrypoint sh mysql -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password"
        ports:
          # Maps tcp port 5432 on service container to the host
          - 3306:3306
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
      - run: yarn install --frozen-lockfile
      - uses: ./.github/actions/run-api-tests
        with:
          dbOptions: '--dbclient=mysql --dbhost=localhost --dbport=3306 --dbname=strapi_test --dbusername=strapi --dbpassword=strapi'
          runEE: true

  api_ee_sqlite:
    runs-on: ubuntu-latest
    needs: [lint, unit_back, unit_front]
    name: '[EE] API Integration (sqlite: ${{ matrix.sqlite_pkg }}, node: ${{ matrix.node }})'
    if: github.event.pull_request.head.repo.full_name == github.repository && !(github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]')
    env:
      STRAPI_LICENSE: ${{ secrets.strapiLicense }}
    strategy:
      matrix:
        node: [14, 16, 18]
        sqlite_pkg: ['better-sqlite3', 'sqlite3', '@vscode/sqlite3']
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - uses: actions/cache@v3
        with:
          path: '**/node_modules'
          key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/yarn.lock') }}
      - run: yarn install --frozen-lockfile
      - uses: ./.github/actions/run-api-tests
        env:
          SQLITE_PKG: ${{ matrix.sqlite_pkg }}
        with:
          dbOptions: '--dbclient=sqlite --dbfile=./tmp/data.db'
          runEE: true