name: CI

on:
  push:
    branches:
      - '*'
    tags:
      - '*'
    paths-ignore:
      - "**.md"
      - "benchmark/**"
      - ".github/workflows/benchmark.yml"
      - ".github/workflows/docker-*.yml"
      - ".github/*.yml"
  pull_request:
    branches:
      - '*'

jobs:
  build:
    if: "!contains(github.event.head_commit.message, 'skip ci')"

    runs-on: ubuntu-latest

    strategy:
      fail-fast: false

      matrix:
        node:
          - 16.x
        adapter:
          - local
          - redis
          - cluster
          - nats
        app_manager:
          - array
          - mysql
          - postgres
          - dynamodb

        include:
          - adapter: local
            rate_limiter: local
            queue_driver: sync
            cache_driver: memory
          - adapter: local
            rate_limiter: local
            queue_driver: sqs
            cache_driver: memory
          - adapter: cluster
            rate_limiter: cluster
            queue_driver: sync
            cache_driver: redis
          - adapter: redis
            rate_limiter: redis
            queue_driver: redis
            cache_driver: redis
          - adapter: nats
            rate_limiter: redis
            queue_driver: sync
            cache_driver: redis

    name: Node.js ${{ matrix.node }} (adapter:${{ matrix.adapter }} manager:${{ matrix.app_manager }} ratelimiter:${{ matrix.rate_limiter }} queue:${{ matrix.queue_driver }})

    steps:
      - uses: actions/checkout@v3.0.2

      - uses: actions/setup-node@v3.4.1
        name: Setup Node.js v${{ matrix.node }}
        with:
          node-version: ${{ matrix.node }}

      - name: Install dependencies
        run: npm install

      - name: Execute lint & build
        run: |
          npm run lint
          npm run build

      - name: Setup Redis
        if: "matrix.adapter == 'redis' || matrix.adapter == 'cluster' || matrix.adapter == 'nats'"
        run: docker run -p 6379:6379 redis:6-alpine &

      # Setup MySQL with user `root`, password `root` and database `testing`
      - name: Setup MySQL
        if: "matrix.app_manager == 'mysql'"
        run: |
          sudo systemctl start mysql.service
          mysql -e 'CREATE DATABASE testing;' -u root -proot
          mysql -u root -proot --database=testing < tests/fixtures/mysql_schema.sql

      # Setup PostgreSQL with user `testing`, password `testing` and database `testing`
      - name: Setup PostgreSQL
        if: "matrix.app_manager == 'postgres'"
        run: |
          sudo systemctl start postgresql.service
          pg_isready
          sudo -u postgres psql --command="CREATE USER testing PASSWORD 'testing'"
          sudo -u postgres createdb --owner=postgres testing
          psql --host=127.0.0.1 --username=testing testing < tests/fixtures/postgres_schema.sql
        env:
          PGPASSWORD: testing

      - name: Setup DynamoDB
        if: "matrix.app_manager == 'dynamodb'"
        run: |
          docker run -p 8000:8000 amazon/dynamodb-local &
          node tests/fixtures/dynamodb_schema.js
        env:
          AWS_ACCESS_KEY_ID: fake-id
          AWS_SECRET_ACCESS_KEY: fake-secret

      - name: Setup Localstack
        if: "matrix.queue_driver == 'sqs'"
        run: |
          pip install localstack awscli-local[ver1]
          docker pull localstack/localstack
          localstack start -d
          localstack wait -t 30
          echo "Startup complete"
          awslocal s3 mb s3://test
          awslocal s3 ls
          awslocal sqs create-queue --queue-name test.fifo \
            --attributes='{
              "FifoQueue": "true",
              "ContentBasedDeduplication": "true",
              "DeduplicationScope": "messageGroup",
              "FifoThroughputLimit": "perMessageGroupId",
              "MessageRetentionPeriod": "3600",
              "ReceiveMessageWaitTimeSeconds": "1",
              "VisibilityTimeout": "5"
            }' \
            --region us-east-1
          awslocal sqs list-queues

      - name: Setup NATS
        if: "matrix.adapter == 'nats'"
        run: |
          docker run -d \
            -p 4222:4222 \
            -p 6222:6222 \
            -p 8222:8222 \
            nats --jetstream --user="" --pass=""

      - name: Execute tests
        run: npm run test
        env:
          RETRY_TIMES: 2
          TEST_ADAPTER: ${{ matrix.adapter }}
          TEST_APP_MANAGER: ${{ matrix.app_manager }}
          TEST_CACHE_DRIVER: ${{ matrix.cache_driver }}
          TEST_QUEUE_DRIVER: ${{ matrix.queue_driver }}
          TEST_RATE_LIMITER: ${{ matrix.rate_limiter }}
          TEST_MYSQL_USER: root
          TEST_MYSQL_PASSWORD: root
          TEST_SQS_URL: http://localhost:4566/000000000000/test.fifo
          AWS_ACCESS_KEY_ID: fake-id
          AWS_SECRET_ACCESS_KEY: fake-secret

      - uses: codecov/codecov-action@v3.1.0
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: false
