name: "Validations"

# we should cancel any in-progress runs for the same workflow + PR/ref
# so that we can avoid redundant work / save on CI minutes
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

on:
  workflow_dispatch:
  pull_request:
  push:
    branches:
      - main

permissions: {}

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.com: memory & general purpose instances for testing
    #   spot enabled: ok to interrupt non-production workloads
    #   tmpfs: faster io-intensive workflows
    #   note: s3-cache intentionally omitted -- PR runs are untrusted and must not write to the
    #   shared cache backend that the trusted release workflow reads from (cache poisoning).
    runs-on: &test-runner "runs-on=${{ github.run_id }}/cpu=4+8/ram=32+128/family=r5+r6+r7+r8+m4+m5+m6+m7+m8/spot=price-capacity-optimized/extras=tmpfs"
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          # the self-consistency tests for the output of the capabilities code generation depends on unit test
          # output from  ./syft/pkg/... packages. Therefore we need to download the test fixture cache here
          # so that running the few unit tests as part of static analysis works correctly.
          download-test-fixture-cache: true

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

  Unit-Test:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Unit tests"
    runs-on: *test-runner
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          download-test-fixture-cache: true

      - name: Run unit tests
        run: make unit

      - name: Check for capability drift
        run: make check-capability-drift

  Integration-Test:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Integration tests"
    runs-on: *test-runner
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          download-test-fixture-cache: true

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

      - name: Run integration tests
        run: make integration

  Build-Snapshot-Artifacts:
    name: "Build snapshot artifacts"
    # runs-on.com: compute instances for parallel builds
    #   spot disabled: reliability for build workflows (used for releases too)
    #   goreleaser uses parallelism of 12, so we need more CPUs
    #   tmpfs: faster io-intensive workflows
    #   note: s3-cache intentionally omitted -- PR runs are untrusted and must not write to the
    #   shared cache backend that the trusted release workflow reads from (cache poisoning).
    runs-on: "runs-on=${{ github.run_id }}/cpu=16+32/ram=32+128/family=c5+c6+c7+c8/spot=false/extras=tmpfs"
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          bootstrap-apt-packages: ""

      - name: Build snapshot artifacts
        run: make snapshot

      - name: Smoke test snapshot build
        run: make snapshot-smoke-test

      - name: Upload snapshot artifacts
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
        with:
          name: snapshot
          path: snapshot/
          retention-days: 30

  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: *test-runner
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          download-test-fixture-cache: true

      - name: Download snapshot artifacts
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c #v8.0.1
        with:
          name: snapshot
          path: snapshot

      - name: Restore binary permissions
        run: chmod +x snapshot/*/syft snapshot/*/*.exe 2>/dev/null || true

      - name: Run comparison tests (Linux)
        run: make compare-linux

      - 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]
    # note: macos runners aren't supported yet for runs-on managed runners.
    runs-on: macos-latest
    permissions:
      contents: read
    steps:
      - name: Install Cosign
        uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2

      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          bootstrap-apt-packages: ""
          go-dependencies: false
          download-test-fixture-cache: true

      - name: Download snapshot artifacts
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c #v8.0.1
        with:
          name: snapshot
          path: snapshot

      - name: Restore binary permissions
        run: chmod +x snapshot/*/syft 2>/dev/null || true

      - name: Run comparison tests (Mac)
        run: make compare-mac

      - 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: *test-runner
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          download-test-fixture-cache: true

      - name: Download snapshot artifacts
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c #v8.0.1
        with:
          name: snapshot
          path: snapshot

      - name: Restore binary permissions
        run: chmod +x snapshot/*/syft snapshot/*/*.exe 2>/dev/null || true

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