name: Tests

on:
  push:
    branches: [ master ]
  pull_request:
    branches:
      - master
    types: [opened, synchronize]
    paths-ignore:
      - 'scripts/**'
      - '**/*.md'
  workflow_dispatch:

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest

    steps:
      - uses: actions/setup-go@v3
        with:
          go-version: 1.19
      - uses: actions/checkout@v3
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v3
        with:
          version: latest

  gomodcheck:
    name: Check internal dependencies
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Check dependencies
        run: |
          ./scripts/check_deps.sh

  codeql:
    name: CodeQL
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        language: [ 'go' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
        # Learn more:
        # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v2

    # ℹī¸ Command-line programs to run using the OS shell.
    # 📚 https://git.io/JvXDl

    # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines
    #    and modify them (or add more) to build your code if your project
    #    uses a compiled language

    #- run: |
    #   make bootstrap
    #   make release

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2

  test_cover:
    name: Coverage
    runs-on: ubuntu-20.04

    env:
      CGO_ENABLED: 0
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Sync VM submodule
        run: |
          git submodule sync
          git submodule update --init

      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: 1.19
          cache: true

      - name: Update Go modules
        run: go mod download -json

      - name: Write coverage profile
        run: go test -v ./... -coverprofile=./coverage.txt -covermode=atomic -coverpkg=./pkg...,./cli/...

      - name: Upload coverage results to Codecov
        uses: codecov/codecov-action@v2
        with:
          fail_ci_if_error: true # if something is wrong on uploading codecov results, then this job will fail
          files: ./coverage.txt
          verbose: true

  tests:
    name: Run tests
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-20.04, windows-2022, macos-12]
        go_versions: [ '1.17', '1.18', '1.19' ]
        exclude:
          # Only latest Go version for Windows and MacOS.
          - os: windows-2022
            go_versions: '1.17'
          - os: windows-2022
            go_versions: '1.18'
          - os: macos-12
            go_versions: '1.17'
          - os: macos-12
            go_versions: '1.18'
          # Exclude latest Go version for Ubuntu as Coverage uses it.
          - os: ubuntu-20.04
            go_versions: '1.19'
      fail-fast: false
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

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

      - name: Update Go modules
        run: go mod download -json

      - name: Sync VM submodule
        run: |
          git submodule sync
          git submodule update --init

      - name: Run tests
        run: go test -v -race ./...