name: "Validations"
on:
  workflow_dispatch:
  push:
    branches:
      - main
  pull_request:

env:
  GO_VERSION: "1.18.x"
  GO_STABLE_VERSION: true

jobs:
  Static-Analysis:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Static analysis"
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/setup-go@v2
        with:
          go-version: ${{ env.GO_VERSION }}
          stable: ${{ env.GO_STABLE_VERSION }}

      - uses: actions/checkout@v2

      - name: Restore tool cache
        id: tool-cache
        uses: actions/cache@v2.1.3
        with:
          path: ${{ github.workspace }}/.tmp
          key: ${{ runner.os }}-tool-${{ hashFiles('Makefile') }}

      - name: Restore go cache
        id: go-cache
        uses: actions/cache@v2.1.3
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-${{ env.GO_VERSION }}-

      - name: (cache-miss) Bootstrap all project dependencies
        if: steps.tool-cache.outputs.cache-hit != 'true' || steps.go-cache.outputs.cache-hit != 'true'
        run: make bootstrap

      - name: Bootstrap CI environment dependencies
        run: make ci-bootstrap

      - name: Run static analysis
        run: make static-analysis

      # allow for PRs to skip validating the syft version to allow for incremental updates of syft before release.
      # In this way checks against the main branch (which are required for release) will fail, but PR checks will not
      - name: Ensure syft version is a release version
        run: |
          echo "GitHub reference: ${GITHUB_REF##*/}"
          git fetch origin main
          git merge-base --is-ancestor ${GITHUB_REF##*/} origin/main && make validate-syft-release-version || echo "skipping syft version check"

  Unit-Test:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Unit tests"
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/setup-go@v2
        with:
          go-version: ${{ env.GO_VERSION }}
          stable: ${{ env.GO_STABLE_VERSION }}

      - uses: actions/checkout@v2

      - name: Restore tool cache
        id: tool-cache
        uses: actions/cache@v2.1.3
        with:
          path: ${{ github.workspace }}/.tmp
          key: ${{ runner.os }}-tool-${{ hashFiles('Makefile') }}

      - name: Restore go cache
        id: go-cache
        uses: actions/cache@v2.1.3
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-${{ env.GO_VERSION }}-

      - name: (cache-miss) Bootstrap all project dependencies
        if: steps.tool-cache.outputs.cache-hit != 'true' || steps.go-cache.outputs.cache-hit != 'true'
        run: make bootstrap

      - name: Bootstrap CI environment dependencies
        run: make ci-bootstrap

      - name: Run unit tests
        run: make unit

      - uses: actions/upload-artifact@v2
        with:
          name: unit-test-results
          path: test/results/**/*

  Integration-Test:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Integration tests"
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/setup-go@v2
        with:
          go-version: ${{ env.GO_VERSION }}
          stable: ${{ env.GO_STABLE_VERSION }}

      - uses: actions/checkout@v2

      - name: Restore tool cache
        id: tool-cache
        uses: actions/cache@v2.1.3
        with:
          path: ${{ github.workspace }}/.tmp
          key: ${{ runner.os }}-tool-${{ hashFiles('Makefile') }}

      - name: Restore go cache
        id: go-cache
        uses: actions/cache@v2.1.3
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-${{ env.GO_VERSION }}-

      - name: (cache-miss) Bootstrap all project dependencies
        if: steps.tool-cache.outputs.cache-hit != 'true' || steps.go-cache.outputs.cache-hit != 'true'
        run: make bootstrap

      - name: Bootstrap CI environment dependencies
        run: make ci-bootstrap

      - name: Validate syft output against the CycloneDX schema
        run: make validate-cyclonedx-schema

      - name: Build key for tar cache
        run: make integration-fingerprint

      - name: Restore integration test cache
        uses: actions/cache@v2.1.3
        with:
          path: ${{ github.workspace }}/test/integration/test-fixtures/cache
          key: ${{ runner.os }}-integration-test-cache-${{ hashFiles('test/integration/test-fixtures/cache.fingerprint') }}

      - name: Run integration tests
        run: make integration

  Build-Snapshot-Artifacts:
    name: "Build snapshot artifacts"
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/setup-go@v2
        with:
          go-version: ${{ env.GO_VERSION }}
          stable: ${{ env.GO_STABLE_VERSION }}

      - uses: actions/checkout@v2

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1

      - name: Restore tool cache
        id: tool-cache
        uses: actions/cache@v2.1.3
        with:
          path: ${{ github.workspace }}/.tmp
          key: ${{ runner.os }}-tool-${{ hashFiles('Makefile') }}

      - name: Restore go cache
        id: go-cache
        uses: actions/cache@v2.1.3
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-${{ env.GO_VERSION }}-

      - name: (cache-miss) Bootstrap all project dependencies
        if: steps.tool-cache.outputs.cache-hit != 'true' || steps.go-cache.outputs.cache-hit != 'true'
        run: make bootstrap

      - name: Build snapshot artifacts
        run: make snapshot

      - uses: actions/upload-artifact@v2
        with:
          name: artifacts
          path: snapshot/**/*

  Acceptance-Linux:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Acceptance tests (Linux)"
    needs: [Build-Snapshot-Artifacts]
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v2

      - uses: actions/download-artifact@v2
        with:
          name: artifacts
          path: snapshot

      - name: Build key for image cache
        run: make install-fingerprint

      - name: Restore install.sh test image cache
        id: install-test-image-cache
        uses: actions/cache@v2.1.3
        with:
          path: ${{ github.workspace }}/test/install/cache
          key: ${{ runner.os }}-install-test-image-cache-${{ hashFiles('test/install/cache.fingerprint') }}

      - name: Load test image cache
        if: steps.install-test-image-cache.outputs.cache-hit == 'true'
        run: make install-test-cache-load

      - name: Run install.sh tests (Linux)
        run: make install-test

      - name: (cache-miss) Create test image cache
        if: steps.install-test-image-cache.outputs.cache-hit != 'true'
        run: make install-test-cache-save

  Acceptance-Mac:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Acceptance tests (Mac)"
    needs: [Build-Snapshot-Artifacts]
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v2

      - uses: actions/download-artifact@v2
        with:
          name: artifacts
          path: snapshot

      - name: Run install.sh tests (Mac)
        run: make install-test-ci-mac


  Cli-Linux:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "CLI tests (Linux)"
    needs: [Build-Snapshot-Artifacts]
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/setup-go@v2
        with:
          go-version: ${{ env.GO_VERSION }}
          stable: ${{ env.GO_STABLE_VERSION }}

      - uses: actions/checkout@v2

      - name: Restore go cache
        id: go-cache
        uses: actions/cache@v2.1.3
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-${{ env.GO_VERSION }}-

      - name: (cache-miss) Bootstrap go dependencies
        if: steps.go-cache.outputs.cache-hit != 'true'
        run: make bootstrap-go

      - name: Build key for tar cache
        run: make cli-fingerprint

      - name: Restore CLI test cache
        uses: actions/cache@v2.1.3
        with:
          path: ${{ github.workspace }}/test/cli/test-fixtures/cache
          key: ${{ runner.os }}-cli-test-cache-${{ hashFiles('test/cli/test-fixtures/cache.fingerprint') }}

      - uses: actions/download-artifact@v2
        with:
          name: artifacts
          path: snapshot

      - name: Run CLI Tests (Linux)
        run: make cli
