name: Test
on:
  pull_request:
      paths-ignore:
      - '**.md'
      - 'docs/**'
      - 'mkdocs.yml'
      - 'LICENSE'
      - '.release-please-manifest.json' ## don't run tests for release-please PRs
      - 'helm/trivy/Chart.yaml'
  merge_group:
  workflow_dispatch:

jobs:
  test:
    name: Test
    runs-on: ${{ matrix.operating-system }}
    strategy:
      matrix:
        operating-system: [ubuntu-latest, windows-latest, macos-latest]
    steps:
      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

      - name: Set up Go
        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
        with:
          go-version-file: go.mod
          cache: false
          check-latest: true # Ensure we use the latest Go patch version

      - name: go mod tidy
        run: |
          go mod tidy
          if [ -n "$(git status --porcelain)" ]; then
            echo "Run 'go mod tidy' and push it"
            exit 1
          fi
        if: matrix.operating-system == 'ubuntu-latest'

      - name: Lint
        id: lint
        uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
        with:
          version: v2.4
          args: --verbose
          skip-save-cache: true  # Restore cache from main branch but don't save new cache
        env:
          GOEXPERIMENT: jsonv2
        if: matrix.operating-system == 'ubuntu-latest'

      - name: Check if linter failed
        run: |
          echo "Linter failed, running 'mage lint:fix' might help to correct some errors"
          exit 1
        if: ${{ failure() && steps.lint.conclusion == 'failure' }}

      - name: Install tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Check if CLI references are up-to-date
        run: |
          mage docs:generate
          if [ -n "$(git status --porcelain)" ]; then
            echo "Run 'mage docs:generate' and push it"
            exit 1
          fi
        if: matrix.operating-system == 'ubuntu-latest'

      - name: Run unit tests
        run: mage test:unit

  integration:
    name: Integration Test
    runs-on: ubuntu-latest
    steps:
      - name: Check out code into the Go module directory
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

      - name: Set up Go
        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
        with:
          go-version-file: go.mod
          cache: false
          check-latest: true # Ensure we use the latest Go patch version

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Generate image list digest
        id: image-digest
        run: |
          source integration/testimages.ini
          IMAGE_LIST=$(skopeo list-tags docker://$TEST_IMAGES)
          DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags += ["containerd"] | .Tags |= sort' | sha256sum | cut -d' ' -f1)
          echo "digest=$DIGEST" >> $GITHUB_OUTPUT

      - name: Restore test images from cache
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          path: integration/testdata/fixtures/images
          key: cache-test-images-${{ steps.image-digest.outputs.digest }}

      - name: Run integration tests
        run: mage test:integration

  k8s-integration:
    name: K8s Integration Test
    runs-on: ubuntu-latest
    steps:
      - name: Check out code into the Go module directory
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

      - name: Set up Go
        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
        with:
          go-version-file: go.mod
          cache: false
          check-latest: true # Ensure we use the latest Go patch version

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Run k8s integration tests
        run: mage test:k8s

  module-test:
    name: Module Integration Test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

      - name: Set up Go
        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
        with:
          go-version-file: go.mod
          cache: false
          check-latest: true # Ensure we use the latest Go patch version

      - name: Install tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Generate image list digest
        id: image-digest
        run: |
          source integration/testimages.ini
          IMAGE_LIST=$(skopeo list-tags docker://$TEST_IMAGES)
          DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags += ["containerd"] | .Tags |= sort' | sha256sum | cut -d' ' -f1)
          echo "digest=$DIGEST" >> $GITHUB_OUTPUT

      - name: Restore test images from cache
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          path: integration/testdata/fixtures/images
          key: cache-test-images-${{ steps.image-digest.outputs.digest }}

      - name: Run module integration tests
        shell: bash
        run: |
          mage test:module

  vm-test:
    name: VM Integration Test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

      - name: Set up Go
        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
        with:
          go-version-file: go.mod
          cache: false
          check-latest: true # Ensure we use the latest Go patch version

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Generate image list digest
        id: image-digest
        run: |
          source integration/testimages.ini
          IMAGE_LIST=$(skopeo list-tags docker://$TEST_VM_IMAGES)
          DIGEST=$(echo "$IMAGE_LIST" | jq '.Tags |= sort' | sha256sum | cut -d' ' -f1)
          echo "digest=$DIGEST" >> $GITHUB_OUTPUT

      - name: Restore test VM images from cache
        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
        with:
          path: integration/testdata/fixtures/vm-images
          key: cache-test-vm-images-${{ steps.image-digest.outputs.digest }}

      - name: Run vm integration tests
        run: |
          mage test:vm

  e2e-test:
    name: E2E Test
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

      - name: Set up Go
        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
        with:
          go-version-file: go.mod
          cache: false
          check-latest: true # Ensure we use the latest Go patch version

      - name: Install Go tools
        run: go install tool # GOBIN is added to the PATH by the setup-go action

      - name: Run E2E tests
        run: mage test:e2e

  build-test:
    name: Build Test
    runs-on: ${{ matrix.operating-system }}
    strategy:
      matrix:
        operating-system: [ubuntu-latest, windows-latest, macos-latest]
    env:
      DOCKER_CLI_EXPERIMENTAL: "enabled"
    steps:
    # The go-build (GOCACHE env) directory requires a large amount of free disk space.
    - name: Free up disk space
      if: matrix.operating-system == 'ubuntu-latest'
      run: |
        sudo rm -rf /usr/local/lib/android
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf /opt/hostedtoolcache/CodeQL
        sudo docker image prune --all --force
        df -h

    - name: Checkout
      uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

    - name: Set up Go
      uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
      with:
        go-version-file: go.mod
        cache: false
        check-latest: true # Ensure we use the latest Go patch version

    - name: Determine GoReleaser ID
      id: goreleaser_id
      shell: bash
      run: |
        if [ "${{ matrix.operating-system }}" == "windows-latest" ]; then
          echo "id=--id build-windows" >> $GITHUB_OUTPUT
        elif [ "${{ matrix.operating-system }}" == "macos-latest" ]; then
          echo "id=--id build-macos --id build-bsd" >> $GITHUB_OUTPUT
        else
          echo "id=--id build-linux" >> $GITHUB_OUTPUT
        fi

    - name: Run GoReleaser
      uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
      with:
        version: v2.1.0
        args: build --snapshot --clean --timeout 90m ${{ steps.goreleaser_id.outputs.id }}
