# @format

name: Workflow

on:
  pull_request:
    branches:
      - master
  push:
    branches:
      - master

# This ensures that previous jobs for the PR are canceled when the PR is
# updated.
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref }}
  cancel-in-progress: true

jobs:
  lint-job:
    name: Checking Lint
    runs-on: [ubuntu-latest]
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go

      - name: Build on ${{ matrix.os }}
        env:
          GO111MODULE: on
          GOOS: linux
        run: |
          make verifiers

  semgrep-static-code-analysis:
    name: "semgrep checks"
    runs-on: ubuntu-latest
    strategy:
      matrix:
        os: [ubuntu-latest]
    steps:
      - name: Check out source code
        uses: actions/checkout@v3
      - name: Scanning code on ${{ matrix.os }}
        continue-on-error: false
        run: |
          # Install semgrep rather than using a container due to:
          # https://github.com/actions/checkout/issues/334
          sudo apt install -y python3-pip || apt install -y python3-pip
          pip3 install semgrep
          semgrep --config semgrep.yaml $(pwd)/portal-ui --error

  ui-assets:
    name: "React Code Has No Warnings & Prettified"
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Read .nvmrc
        id: node_version
        run: echo "$(cat .nvmrc)" && echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_ENV
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
          cache: "yarn"
          cache-dependency-path: portal-ui/yarn.lock
      - uses: actions/cache@v3
        id: assets-cache
        name: Assets Cache
        with:
          path: |
            ./portal-ui/build/
          key: ${{ runner.os }}-assets-${{ github.run_id }}
      - name: Install Dependencies
        working-directory: ./portal-ui
        continue-on-error: false
        run: |
          yarn install --frozen-lockfile --immutable
      - name: Check for Warnings in build output
        working-directory: ./portal-ui
        continue-on-error: false
        run: |
          ./check-warnings.sh
      - name: Check if Files are Prettified
        working-directory: ./portal-ui
        continue-on-error: false
        run: |
          ./check-prettier.sh
      - name: Check for dead code
        working-directory: ./portal-ui
        continue-on-error: false
        run: |
          ./check-deadcode.sh
  reuse-golang-dependencies:
    name: reuse golang dependencies
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go
      - name: Build on ${{ matrix.os }}
        env:
          GO111MODULE: on
          GOOS: linux
        run: |
          go mod download

  latest-minio:
    name: Build latest MinIO
    runs-on: [ubuntu-latest]
    strategy:
      matrix:
        go-version: [1.21.x]
    steps:
      # To build minio image, we need to clone the repository first
      - name: Clone github.com/minio/minio
        uses: actions/checkout@v3
        with:
          repository: minio/minio
      - uses: actions/cache@v3
        id: minio-latest-cache
        name: MinIO Latest Cache
        with:
          path: |
            ./minio
          key: ${{ runner.os }}-minio-latest-${{ hashFiles('./go.sum') }}
      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go-minio
      - name: Build on ${{ matrix.os }}
        if: steps.minio-latest-cache.outputs.cache-hit != 'true'
        run: |
          echo "Create minio binary";
          make build;
  compile-binary:
    name: Compiles on Go ${{ matrix.go-version }} and ${{ matrix.os }}
    needs:
      - lint-job
      - ui-assets
      - reuse-golang-dependencies
      - semgrep-static-code-analysis
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}
      - uses: actions/cache@v3
        id: assets-cache
        name: Assets Cache
        with:
          path: |
            ./portal-ui/build/
          key: ${{ runner.os }}-assets-${{ github.run_id }}
      - name: Build on ${{ matrix.os }}
        env:
          GO111MODULE: on
          GOOS: linux
        run: |
          make console

  all-permissions-1:
    name: Permissions Tests Part 1
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    timeout-minutes: 10
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio

      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-1/ -q --skip-js-errors -c 3

      - name: Clean up users & policies
        run: |
          make cleanup-permissions

  all-permissions-2:
    name: Permissions Tests Part 2
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    timeout-minutes: 10
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-2/ -q --skip-js-errors -c 3

      - name: Clean up users & policies
        run: |
          make cleanup-permissions

  all-permissions-3:
    name: Permissions Tests Part 3
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    timeout-minutes: 10
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-3/ -q --skip-js-errors -c 3

      - name: Clean up users & policies
        run: |
          make cleanup-permissions

  all-permissions-4:
    name: Permissions Tests Part 4
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    timeout-minutes: 15
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        timeout-minutes: 10
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-4/ --skip-js-errors

  all-permissions-5:
    name: Permissions Tests Part 5
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        timeout-minutes: 5
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-5/ --skip-js-errors

  all-permissions-6:
    name: Permissions Tests Part 6
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        timeout-minutes: 5
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-6/ --skip-js-errors

  all-permissions-7:
    name: Permissions Tests Part 7
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)
      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        timeout-minutes: 5
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-7/ --skip-js-errors

  all-permissions-8:
    name: Permissions Tests Part 8
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        timeout-minutes: 5
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-8/ --skip-js-errors

  all-permissions-9:
    name: Permissions Tests Part 9
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-9/ --skip-js-errors -c 3

      - name: Clean up users & policies
        run: |
          make cleanup-permissions

  all-permissions-A:
    name: Permissions Tests Part A
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-A/ --skip-js-errors -c 3

      - name: Clean up users & policies
        run: |
          make cleanup-permissions

  all-permissions-B:
    name: Permissions Tests Part B
    needs:
      - compile-binary
    runs-on: [ubuntu-latest]
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
      - name: Install MinIO JS
        working-directory: ./
        continue-on-error: false
        run: |
          yarn add minio
      - uses: actions/cache@v3
        name: Console Binary Cache
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-${{ github.run_id }}

      - name: clean-previous-containers-if-any
        run: |
          docker stop minio || true;
          docker container prune -f || true;

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Install TestCafe
        run: npm install testcafe@3.0.0

      - name: Run TestCafe Tests
        run: npx testcafe "chrome:headless" portal-ui/tests/permissions-B/ --skip-js-errors -c 3

      - name: Clean up users & policies
        run: |
          make cleanup-permissions

  test-pkg-on-go:
    name: Test Pkg on Go ${{ matrix.go-version }} and ${{ matrix.os }}
    needs:
      - lint-job
      - ui-assets
      - reuse-golang-dependencies
      - semgrep-static-code-analysis
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go

      - name: Build on ${{ matrix.os }}
        env:
          GO111MODULE: on
          GOOS: linux
        run: |
          make test-pkg

      - uses: actions/cache@v3
        id: coverage-cache-pkg
        name: Coverage Cache Pkg
        with:
          path: |
            ./pkg/coverage/
          key: ${{ runner.os }}-coverage-pkg-2-${{ github.run_id }}
  test-restapi-on-go:
    name: Test Restapi on Go ${{ matrix.go-version }} and ${{ matrix.os }}
    needs:
      - lint-job
      - ui-assets
      - reuse-golang-dependencies
      - semgrep-static-code-analysis
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go

      - name: Build on ${{ matrix.os }}
        env:
          GO111MODULE: on
          GOOS: linux
        run: |
          make test

      - uses: actions/cache@v3
        id: coverage-cache-restapi
        name: Coverage Cache RestAPI
        with:
          path: |
            ./restapi/coverage/
          key: ${{ runner.os }}-coverage-restapi-2-${{ github.run_id }}
  b-integration-tests:
    name: Integration Tests with Latest Distributed MinIO
    needs:
      - lint-job
      - ui-assets
      - reuse-golang-dependencies
      - semgrep-static-code-analysis
      - latest-minio
    runs-on: ubuntu-latest

    strategy:
      matrix:
        go-version: [1.21.x]

    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Clone github.com/minio/minio
        uses: actions/checkout@master
        with:
          repository: minio/minio
          path: "minio_repository"
      - uses: actions/cache@v3
        id: minio-latest-cache
        name: MinIO Latest Cache
        with:
          path: |
            ./minio
          key: ${{ runner.os }}-minio-latest-${{ hashFiles('./minio_repository/go.sum') }}
      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go

      - name: Build on ${{ matrix.os }}
        run: |
          echo "The idea is to build minio image from downloaded repository";
          cd $GITHUB_WORKSPACE/minio_repository;
          echo "Get git version to build MinIO Image";
          VERSION=`git rev-parse HEAD`;
          echo $VERSION;
          echo "Create MinIO image";
          if [ ! -f ../minio ]; then
              echo "minio binary not found!, so compiling..."
              make docker VERSION=$VERSION;
          else
              echo "Using binary from cache"
              cp ../minio .
          fi
          docker build -q --no-cache -t minio/minio:$VERSION . -f Dockerfile
          echo "Jumping back to console repository to run the integration test"
          cd $GITHUB_WORKSPACE;
          echo "We are going to use the built image on test-integration";
          VERSION="minio/minio:$VERSION";
          echo $VERSION;

          echo "Create bucket for replication with versioning"
          echo "Download mc for Ubuntu"
          wget -q https://dl.min.io/client/mc/release/linux-amd64/mc
          echo "Change the permissions to execute mc command"
          chmod +x mc
          echo "Create the folder to put the all.out file"
          make test-integration MINIO_VERSION=$VERSION;

      - uses: actions/cache@v3
        id: coverage-cache
        name: Coverage Cache
        with:
          path: |
            ./integration/coverage/
          key: ${{ runner.os }}-coverage-2-${{ github.run_id }}
  react-tests:
    name: React Tests
    needs:
      - lint-job
      - ui-assets
      - reuse-golang-dependencies
      - semgrep-static-code-analysis
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install modules
        working-directory: ./portal-ui
        run: yarn
      - name: Run tests
        working-directory: ./portal-ui
        run: yarn test
  replication:
    name: Site Replication Test
    needs:
      - lint-job
      - ui-assets
      - reuse-golang-dependencies
      - semgrep-static-code-analysis
      - latest-minio
    runs-on: [ubuntu-latest]

    strategy:
      matrix:
        go-version: [1.21.x]

    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go

      - name: Clone github.com/minio/minio
        uses: actions/checkout@master
        with:
          repository: minio/minio
          path: "minio_repository"
      - uses: actions/cache@v3
        id: minio-latest-cache
        name: MinIO Latest Cache
        with:
          path: |
            ./minio
          key: ${{ runner.os }}-minio-latest-${{ hashFiles('./minio_repository/go.sum') }}

      - name: Build on ${{ matrix.os }}
        run: |
          echo "The idea is to build minio image from downloaded repository";
          cd $GITHUB_WORKSPACE/minio_repository;
          echo "Get git version to build MinIO Image";
          VERSION=`git rev-parse HEAD`;
          echo $VERSION;
          echo "Create MinIO image";
          if [ ! -f ../minio ]; then
              echo "minio binary not found!, so compiling..."
              make docker VERSION=$VERSION;
          else
              echo "Using binary from cache"
              cp ../minio .
          fi
          docker build -q --no-cache -t minio/minio:$VERSION . -f Dockerfile
          echo "Jumping back to console repository to run the integration test"
          cd $GITHUB_WORKSPACE;
          echo "We are going to use the built image on test-integration";
          VERSION="minio/minio:$VERSION";
          echo $VERSION;
          make test-replication MINIO_VERSION=$VERSION;
      - uses: actions/cache@v3
        id: coverage-cache-replication
        name: Coverage Cache Replication
        with:
          path: |
            ./replication/coverage/
          key: ${{ runner.os }}-replication-coverage-2-${{ github.run_id }}

      # To save our replication.out file into an artifact.
      # By default, GitHub stores build logs and artifacts for 90 days.
      - uses: actions/upload-artifact@v3
        with:
          name: replication-artifact
          path: ./replication/coverage/replication.out
          if-no-files-found: error
  sso-integration:
    name: SSO Integration Test
    needs:
      - lint-job
      - ui-assets
      - reuse-golang-dependencies
      - semgrep-static-code-analysis
      - latest-minio
    runs-on: ubuntu-latest

    strategy:
      matrix:
        go-version: [1.21.x]

    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go

      - name: Clone github.com/minio/minio
        uses: actions/checkout@master
        with:
          repository: minio/minio
          path: "minio_repository"
      - uses: actions/cache@v3
        id: minio-latest-cache
        name: MinIO Latest Cache
        with:
          path: |
            ./minio
          key: ${{ runner.os }}-minio-latest-${{ hashFiles('./minio_repository/go.sum') }}

      - name: Build on ${{ matrix.os }}
        run: |
          echo "The idea is to build minio image from downloaded repository";
          cd $GITHUB_WORKSPACE/minio_repository;
          echo "replace github.com/minio/console => ../" >> go.mod

          echo "updates to go.mod needed; to update it: go mod tidy"
          go mod tidy -compat=1.19

          echo "Get git version to build MinIO Image";
          VERSION=`git rev-parse HEAD`;
          echo $VERSION;
          echo "Create MinIO image";
          if [ ! -f ../minio ]; then
              echo "minio binary not found!, so compiling..."
              make docker VERSION=$VERSION;
          else
              echo "Using binary from cache"
              cp ../minio .
          fi
          docker build -q --no-cache -t minio/minio:$VERSION . -f Dockerfile
          echo "Jumping back to console repository to run the integration test"
          cd $GITHUB_WORKSPACE;
          echo "We are going to use the built image on test-integration";
          VERSION="minio/minio:$VERSION";
          echo $VERSION;
          make test-sso-integration MINIO_VERSION=$VERSION;
      - uses: actions/cache@v3
        id: coverage-cache-sso
        name: Coverage Cache SSO
        with:
          path: |
            ./sso-integration/coverage/
          key: ${{ runner.os }}-sso-coverage-2-${{ github.run_id }}
  coverage:
    name: "Coverage Limit Check"
    needs:
      - b-integration-tests
      - test-restapi-on-go
      - test-pkg-on-go
      - sso-integration
      - replication
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go
      - name: Check out gocovmerge as a nested repository
        uses: actions/checkout@v3
        with:
          repository: wadey/gocovmerge
          path: gocovmerge

      - uses: actions/cache@v3
        id: coverage-cache
        name: Coverage Cache
        with:
          path: |
            ./integration/coverage/
          key: ${{ runner.os }}-coverage-2-${{ github.run_id }}

      - uses: actions/cache@v3
        id: coverage-cache-sso
        name: Coverage Cache SSO
        with:
          path: |
            ./sso-integration/coverage/
          key: ${{ runner.os }}-sso-coverage-2-${{ github.run_id }}

      - uses: actions/cache@v3
        id: coverage-cache-replication
        name: Coverage Cache Replication
        with:
          path: |
            ./replication/coverage/
          key: ${{ runner.os }}-replication-coverage-2-${{ github.run_id }}

      - uses: actions/cache@v3
        id: coverage-cache-restapi
        name: Coverage Cache RestAPI
        with:
          path: |
            ./restapi/coverage/
          key: ${{ runner.os }}-coverage-restapi-2-${{ github.run_id }}

      - uses: actions/cache@v3
        id: coverage-cache-pkg
        name: Coverage Cache Pkg
        with:
          path: |
            ./pkg/coverage/
          key: ${{ runner.os }}-coverage-pkg-2-${{ github.run_id }}

      # Get the replication.out file from the artifact since this is working for self host runner.
      - uses: actions/download-artifact@v3
        with:
          name: replication-artifact
          path: replication/coverage

      - name: Get coverage
        run: |
          echo "change directory to gocovmerge"
          cd gocovmerge
          echo "download golang x tools"
          go mod download golang.org/x/tools
          echo "go mod tidy compat mode"
          go mod tidy -compat=1.19
          echo "go build gocoverage.go"
          go build gocovmerge.go
          echo "put together the outs for final coverage resolution"
          ./gocovmerge ../integration/coverage/system.out ../replication/coverage/replication.out ../sso-integration/coverage/sso-system.out ../restapi/coverage/coverage.out ../pkg/coverage/coverage-pkg.out > all.out
          echo "Download mc for Ubuntu"
          wget -q https://dl.min.io/client/mc/release/linux-amd64/mc
          echo "Change the permissions to execute mc command"
          chmod +x mc
          echo "Only run our test if play is up and running since we require it for replication tests here."
          PLAY_IS_ON=`wget --spider --server-response https://play.min.io:9443/login 2>&1 | grep '200\ OK' | wc -l`
          if [ $PLAY_IS_ON == 1 ]
          then
            echo "Play is up and running, we will proceed with the play part for coverage"
            echo "Create the folder to put the all.out file"
            ./mc mb --ignore-existing play/builds/
            echo "Copy the all.out file to play bucket"
            echo ${{ github.repository }}
            echo ${{ github.event.number }}
            echo ${{ github.run_id }}
            # mc cp can fail due to lack of space: mc: <ERROR> Failed to copy `all.out`.
            # Storage backend has reached its minimum free disk threshold. Please delete a few objects to proceed.
            ./mc cp all.out play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
            ./mc cp all.out play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
            go tool cover -html=all.out -o coverage.html
            ./mc cp coverage.html play/builds/${{ github.repository }}/${{ github.event.number }}/${{ github.run_id }}/ || true
            ./mc cp coverage.html play/builds/${{ github.repository }}/${{ github.event.number }}/latest/ || true
          else
            echo "Play is down, please report it on hack channel, no coverage is going to be uploaded!!!"
          fi
          echo "grep to obtain the result"
          go tool cover -func=all.out | grep total > tmp2
          result=`cat tmp2 | awk 'END {print $3}'`
          result=${result%\%}
          threshold=71.4
          echo "Result:"
          echo "$result%"
          if (( $(echo "$result >= $threshold" |bc -l) )); then
            echo "It is equal or greater than threshold ($threshold%), passed!"
          else
            echo "It is smaller than threshold ($threshold%) value, failed!"
            exit 1
          fi

  ui-assets-istanbul-coverage:
    name: "Assets with Istanbul Plugin for coverage"
    runs-on: ubuntu-latest
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Read .nvmrc
        id: node_version
        run: echo "$(cat .nvmrc)" && echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_ENV
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.NVMRC }}
          cache: "yarn"
          cache-dependency-path: portal-ui/yarn.lock
      - uses: actions/cache@v3
        id: assets-cache-istanbul-coverage
        name: Assets Cache Istanbul Coverage
        with:
          path: |
            ./portal-ui/build/
          key: ${{ runner.os }}-assets-istanbul-coverage-${{ github.run_id }}
      - name: Install Dependencies
        working-directory: ./portal-ui
        continue-on-error: false
        run: |
          yarn install --frozen-lockfile --immutable
      - name: Check for Warnings in build output
        working-directory: ./portal-ui
        continue-on-error: false
        run: |
          ./check-warnings-istanbul-coverage.sh

  compile-binary-istanbul-coverage:
    name: "Compile Console Binary with Istanbul Plugin for Coverage"
    needs:
      - lint-job
      - ui-assets-istanbul-coverage
      - reuse-golang-dependencies
      - semgrep-static-code-analysis
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        go-version: [1.21.x]
        os: [ubuntu-latest]
    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.go-version }}
          cache: true
        id: go
      - uses: actions/cache@v3
        name: Console Binary Cache Istanbul Coverage
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-istanbul-coverage-${{ github.run_id }}
      - uses: actions/cache@v3
        id: assets-cache-istanbul-coverage
        name: Assets Cache Istanbul Coverage
        with:
          path: |
            ./portal-ui/build/
          key: ${{ runner.os }}-assets-istanbul-coverage-${{ github.run_id }}
      - name: Build on ${{ matrix.os }}
        env:
          GO111MODULE: on
          GOOS: linux
        run: |
          make console

  playwright:
    needs:
      - compile-binary-istanbul-coverage
    timeout-minutes: 60
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16

      - name: Install dependencies
        run: |
          echo "Install dependencies"
          cd $GITHUB_WORKSPACE/portal-ui
          yarn add -D playwright
          yarn add -D babel-plugin-istanbul
          yarn add -D nyc
          yarn add -D react-app-rewired
          yarn add -D create-react-app
          yarn add -D @playwright/test
          yarn init -y
          echo "yarn install"
          yarn install

      - name: Install Playwright Browsers
        run: npx playwright install --with-deps

      - uses: actions/cache@v3
        name: Console Binary Cache Istanbul Coverage
        with:
          path: |
            ./console
          key: ${{ runner.os }}-binary-istanbul-coverage-${{ github.run_id }}

      - name: Start Console, front-end app and initialize users/policies
        run: |
          (./console server) & (make initialize-permissions)

      - name: Run Playwright tests
        run: |
          echo "Run tests under playwright folder only"
          cd $GITHUB_WORKSPACE/portal-ui
          yarn remove playwright
          yarn add --dev @playwright/test
          echo "npx playwright test"
          npx playwright test # To run the tests
          echo "npx nyc report"
          npx nyc report # To see report printed in logs as text
          echo "npx nyc report --reporter=html"
          npx nyc report --reporter=html # to see report in ./coverage/index.html
      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30
      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: coverage
          path: coverage/
          retention-days: 30
