name: CI/CD

on:
  push:
    branches:
      - release/*
      - develop
  pull_request:
    types:
      - opened
      - ready_for_review
      - reopened
      - edited
      - synchronize
jobs:
  node-modules:
    # All jobs depend on node_modules, so none should run if the PR is in draft
    if: github.event.pull_request.draft == false
    runs-on: ubuntu-22.04
    name: 'Cache yarn modules'
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }}
      - name: Cache node modules
        id: cache
        uses: actions/cache@v3
        with:
          path: node_modules
          key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
          # comment out "restore-keys" if you need to rebuild yarn from 0
          restore-keys: |
            ${{ runner.os }}-cache-node-modules-

      - name: Setup node
        uses: actions/setup-node@v3
        if: steps.cache.outputs.cache-hit != 'true'
        with:
          node-version-file: '.nvmrc'
          # https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
          cache: yarn
      - name: yarn install
        if: steps.cache.outputs.cache-hit != 'true'
        run: yarn install --pure-lockfile

  lint-pr-title:
    needs: node-modules
    if: ${{ github.event_name == 'pull_request' }}
    name: Verify PR title
    uses: ./.github/workflows/lint-pr.yml
    secrets: inherit

  lint-format:
    timeout-minutes: 20
    needs: node-modules
    runs-on: ubuntu-22.04
    name: '(CI) lint + format check'
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version-file: '.nvmrc'
          # https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
          cache: yarn

      - name: Cache node modules
        uses: actions/cache@v3
        with:
          path: node_modules
          key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}

      - name: Derive appropriate SHAs for base and head for `nx affected` commands
        uses: nrwl/nx-set-shas@v3
        with:
          main-branch-name: develop

      - name: Check formatting
        run: yarn nx format:check

      - name: Lint affected
        run: yarn nx affected:lint --max-warnings=0

      - name: Build affected spec
        run: yarn nx affected --target=build-spec

  test-affected:
    timeout-minutes: 30
    needs: build-sources
    runs-on: ubuntu-22.04
    name: 'run unit test of affected apps'
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version-file: '.nvmrc'
          cache: yarn

      - name: Cache node modules
        uses: actions/cache@v3
        with:
          path: node_modules
          key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}

      - name: Derive appropriate SHAs for base and head for `nx affected` commands
        uses: nrwl/nx-set-shas@v3
        with:
          main-branch-name: develop

      - name: Test affected
        run: yarn nx affected:test

  build-sources:
    timeout-minutes: 30
    needs: lint-format
    runs-on: ubuntu-22.04
    name: 'Build sources of affected apps'
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version-file: '.nvmrc'
          cache: yarn

      - name: Cache node modules
        uses: actions/cache@v3
        with:
          path: node_modules
          key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}

      - name: Derive appropriate SHAs for base and head for `nx affected` commands
        uses: nrwl/nx-set-shas@v3
        with:
          main-branch-name: develop

      # See affected apps
      - name: See affected apps
        run: |
          branch_slug="$(echo '${{ github.head_ref || github.ref_name }}' | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | cut -c 1-50 )"
          python3 tools/ci/check-affected.py --github-ref="${{ github.ref }}" --branch-slug="$branch_slug" --event-name="${{ github.event_name }}"

      - name: Verify script result
        run: |
          echo "Check outputs from script"
          echo "projects: ${{ env.PROJECTS }}"
          echo "projects-e2e: ${{ env.PROJECTS_E2E }}"
          echo "preview_governance: ${{ env.PREVIEW_GOVERNANCE }}"
          echo "preview_trading: ${{ env.PREVIEW_TRADING }}"
          echo "preview_explorer: ${{ env.PREVIEW_EXPLORER }}"
          echo "preview_tools: ${{ env.PREVIEW_TOOLS }}"

      - name: Build affected
        run: yarn nx affected:build || (yarn install && yarn nx affected:build)
    outputs:
      projects: ${{ env.PROJECTS }}
      projects-e2e: ${{ env.PROJECTS_E2E }}
      preview_governance: ${{ env.PREVIEW_GOVERNANCE }}
      preview_trading: ${{ env.PREVIEW_TRADING }}
      preview_explorer: ${{ env.PREVIEW_EXPLORER }}
      preview_tools: ${{ env.PREVIEW_TOOLS }}

  # console-e2e:
  #   needs: build-sources
  #   name: '(CI) console python'
  #   uses: ./.github/workflows/console-test-run.yml
  #   secrets: inherit
  #   if: ${{ contains(fromJSON(needs.build-sources.outputs.projects), 'trading') && github.event_name == 'pull_request' }}
  #   with:
  #     github-sha: ${{ github.event.pull_request.head.sha || github.sha }}

  cypress:
    needs: build-sources
    name: '(CI) cypress'
    # if: ${{ needs.build-sources.outputs.projects-e2e != '[]' }}
    uses: ./.github/workflows/cypress-run.yml
    secrets: inherit
    with:
      projects: ${{ needs.build-sources.outputs.projects-e2e }}
      tags: '@smoke'

  publish-dist:
    needs: build-sources
    name: '(CD) publish dist'
    if: ${{ (github.event_name == 'pull_request' &&  github.event.pull_request.head.repo.full_name == 'vegaprotocol/frontend-monorepo') || github.event_name == 'push' }}
    uses: ./.github/workflows/publish-dist.yml
    secrets: inherit
    with:
      projects: ${{ needs.build-sources.outputs.projects }}

  dist-check:
    runs-on: ubuntu-latest
    needs:
      - publish-dist
      - build-sources
    if: ${{ github.event_name == 'pull_request' &&  github.event.pull_request.head.repo.full_name == 'vegaprotocol/frontend-monorepo' }}
    timeout-minutes: 60
    name: '(CD) comment preview links'
    steps:
      - name: Find Comment
        uses: peter-evans/find-comment@v2
        id: fc
        with:
          issue-number: ${{ github.event.pull_request.number }}
          body-includes: Previews

      - name: Wait for deployments
        run: |
          # https://stackoverflow.com/questions/3183444/check-for-valid-link-url
          regex='(https?|ftp|file)://[-[:alnum:]\+&@#/%?=~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|]'
          if [[ "${{ needs.build-sources.outputs.preview_governance }}" =~ $regex ]]; then
            until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_governance }}"; do
              echo "waiting for governance preview: ${{ needs.build-sources.outputs.preview_governance }}"
              sleep 5
            done
          fi
          if [[ "${{ needs.build-sources.outputs.preview_explorer }}" =~ $regex ]]; then
            until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_explorer }}"; do
              echo "waiting for explorer preview: ${{ needs.build-sources.outputs.preview_explorer }}"
              sleep 5
            done
          fi
          if [[ "${{ needs.build-sources.outputs.preview_trading }}" =~ $regex ]]; then
            until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_trading }}"; do
              echo "waiting for trading preview: ${{ needs.build-sources.outputs.preview_trading }}"
              sleep 5
            done
          fi
          if [[ "${{ needs.build-sources.outputs.preview_tools }}" =~ $regex ]]; then
            until curl --insecure --location --fail "${{ needs.build-sources.outputs.preview_tools }}"; do
              echo "waiting for tools preview: ${{ needs.build-sources.outputs.preview_tools }}"
              sleep 5
            done
          fi

      - name: Create comment
        uses: peter-evans/create-or-update-comment@v3
        if: ${{ steps.fc.outputs.comment-id == 0 }}
        with:
          issue-number: ${{ github.event.pull_request.number }}
          body: |
            Previews
            * governance: ${{ needs.build-sources.outputs.preview_governance }}
            * explorer: ${{ needs.build-sources.outputs.preview_explorer  }}
            * trading: ${{ needs.build-sources.outputs.preview_trading }}
            * tools: ${{ needs.build-sources.outputs.preview_tools }}

  # Report single result at the end, to avoid mess with required checks in PR
  cypress-check:
    name: '(CI) cypress - check'
    if: ${{ always() }}
    needs: cypress
    runs-on: ubuntu-22.04
    steps:
      - run: |
          result="${{ needs.cypress.result }}"
          if [[ $result == "success" || $result == "skipped" ]]; then
            exit 0
          else
            exit 1
          fi
