name: CI
on: [push, pull_request]

permissions: read-all

jobs:
  linter-backend:
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Setup Go
        uses: actions/setup-go@v3
        with:
          go-version: 1.18
      - name: Run golangci-lint
        uses: golangci/golangci-lint-action@v3
        with:
          version: v1.45.2
          args: --timeout 5m

  linter-openapi:
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout Code
        uses: actions/checkout@v3
      - name: Lint OpenAPI specs
        uses: github/super-linter@v4
        env:
          VALIDATE_ALL_CODEBASE: true
          VALIDATE_OPENAPI: true
          FILTER_REGEX_INCLUDE: docs/api/openapi.yaml

  linter-artifacthub:
    runs-on: ubuntu-20.04
    container:
      image: artifacthub/ah
      options: --user root
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Run ah lint
        working-directory: ./charts/artifact-hub
        run: ah lint

  linter-clomonitor:
    runs-on: ubuntu-20.04
    env:
      GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
    container:
      image: public.ecr.aws/clomonitor/linter:latest
      options: --user root
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Run CloMonitor linter
        run: clomonitor-linter --pass-score 75 --url https://github.com/artifacthub/hub

  tests-database:
    runs-on: ubuntu-20.04
    container:
      image: artifacthub/db-tests
    services:
      postgres:
        image: artifacthub/postgres
        env:
          POSTGRES_USER: tests
          POSTGRES_PASSWORD: tests
          POSTGRES_DB: tests
        ports:
          - 5432:5432
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Apply database migrations
        working-directory: ./database/migrations
        run: TERN_CONF=../../../.github/workflows/tern.conf PGPORT=${{ job.services.postgres.ports[5432] }} ./migrate.sh
      - name: Install pgtap database extension
        run: PGPASSWORD=tests psql -h postgres -p ${{ job.services.postgres.ports[5432] }} -U tests tests -c 'create extension pgtap;'
      - name: Run database tests
        working-directory: ./database/tests
        run: PGPASSWORD=tests pg_prove --host postgres --dbname tests --username tests --verbose schema/*.sql functions/*/*.sql

  tests-backend:
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Setup Go
        uses: actions/setup-go@v3
        with:
          go-version: 1.18
      - name: Cache Go modules
        uses: actions/cache@v3
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
      - name: Run backend tests
        run: go test -cover -race -v -mod=readonly ./...

  tests-frontend:
    runs-on: ubuntu-20.04
    env:
      NODE_OPTIONS: --max_old_space_size=4096
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Cache node modules
        uses: actions/cache@v3
        with:
          path: ./web/node_modules
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-
      - name: Install dependencies
        working-directory: ./web
        run: yarn install
      - name: Run prettier
        working-directory: ./web
        run: yarn format:diff
      - name: Run eslint
        working-directory: ./web
        run: yarn lint
      - name: Run frontend tests
        working-directory: ./web
        run: yarn test --watchAll=false --passWithNoTests --verbose --maxWorkers=4

  tests-widget:
    runs-on: ubuntu-20.04
    env:
      NODE_OPTIONS: --max_old_space_size=4096
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Cache node modules
        uses: actions/cache@v3
        with:
          path: ./widget/node_modules
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-
      - name: Install dependencies
        working-directory: ./widget
        run: yarn install
      - name: Run prettier
        working-directory: ./widget
        run: yarn format:diff
      - name: Run eslint
        working-directory: ./widget
        run: yarn lint
      - name: Run widget tests
        working-directory: ./widget
        run: yarn test --watchAll=false --passWithNoTests --verbose

  build-backend:
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Setup Go
        uses: actions/setup-go@v3
        with:
          go-version: 1.18
      - name: Cache Go modules
        uses: actions/cache@v3
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
      - name: Build hub
        working-directory: ./cmd/hub
        run: go build -v
      - name: Build scanner
        working-directory: ./cmd/scanner
        run: go build -v
      - name: Build tracker
        working-directory: ./cmd/tracker
        run: go build -v

  build-frontend:
    runs-on: ubuntu-20.04
    env:
      NODE_OPTIONS: --max_old_space_size=4096
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Cache node modules
        uses: actions/cache@v3
        with:
          path: ./web/node_modules
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-
      - name: Install dependencies
        working-directory: ./web
        run: yarn install
      - name: Build frontend
        working-directory: ./web
        run: yarn build

  build-widget:
    runs-on: ubuntu-20.04
    env:
      NODE_OPTIONS: --max_old_space_size=4096
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Cache node modules
        uses: actions/cache@v3
        with:
          path: ./widget/node_modules
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-
      - name: Install dependencies
        working-directory: ./widget
        run: yarn install
      - name: Build widget
        working-directory: ./widget
        run: yarn build

  build-docker-images:
    if: github.ref == 'refs/heads/master'
    needs:
      - linter-backend
      - linter-openapi
      - linter-artifacthub
      - tests-database
      - tests-backend
      - tests-frontend
      - tests-widget
      - build-backend
      - build-frontend
      - build-widget
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-2
      - name: Login to AWS ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1
      - name: Build, tag and push hub image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        run: |
          docker build -f cmd/hub/Dockerfile -t $ECR_REGISTRY/hub:$GITHUB_SHA .
          docker push $ECR_REGISTRY/hub:$GITHUB_SHA
      - name: Build, tag and push db-migrator image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        run: |
          docker build -f database/migrations/Dockerfile -t $ECR_REGISTRY/db-migrator:$GITHUB_SHA .
          docker push $ECR_REGISTRY/db-migrator:$GITHUB_SHA
      - name: Build, tag and push scanner image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        run: |
          docker build -f cmd/scanner/Dockerfile -t $ECR_REGISTRY/scanner:$GITHUB_SHA .
          docker push $ECR_REGISTRY/scanner:$GITHUB_SHA
      - name: Build, tag and push tracker image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        run: |
          docker build -f cmd/tracker/Dockerfile -t $ECR_REGISTRY/tracker:$GITHUB_SHA .
          docker push $ECR_REGISTRY/tracker:$GITHUB_SHA
