name: "Validations"

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

permissions:
  contents: read

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/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap

      - 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: ubuntu-20.04
    steps:
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
      
      - name: Run unit tests
        run: make unit

  Quality-Test:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Quality tests"
    runs-on: ubuntu-22.04-4core-16gb
    steps:
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
        with:
          submodules: true

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap

      - name: Run quality tests
        run: make quality
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Archive the provider state
        if: ${{ failure() }}
        run: tar -czvf qg-capture-state.tar.gz -C test/quality --exclude tools --exclude labels .yardstick.yaml .yardstick

      - name: Upload the provider state archive
        if: ${{ failure() }}
        uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
        with:
          name: qg-capture-state
          path: qg-capture-state.tar.gz

      - name: Show instructions to debug
        if: ${{ failure() }}
        run: |
          ARCHIVE_BASENAME=qg-capture-state
          ARCHIVE_NAME=$ARCHIVE_BASENAME.zip

          cat << EOF >> $GITHUB_STEP_SUMMARY
          ## Troubleshooting failed run

          Download the artifact from this workflow run: \`$ARCHIVE_NAME\`

          Then run the following commands to debug:
          \`\`\`bash
          # copy the archive to the tests/quality directory
          cd test/quality
          unzip $ARCHIVE_NAME && tar -xzf $ARCHIVE_BASENAME.tar.gz
          \`\`\`

          Now you can debug the with yardstick:
          \`\`\`bash
          poetry shell
          yardstick result list
          yardstick label explore
          \`\`\`
          EOF


  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/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap

      - name: Restore integration test cache
        uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
        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/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          # why have another build cache key? We don't want unit/integration/etc test build caches to replace
          # the snapshot build cache, which includes builds for all OSs and architectures. As long as this key is
          # unique from the build-cache-key-prefix in other CI jobs, we should be fine.
          #
          # note: ideally this value should match what is used in release (just to help with build times).
          build-cache-key-prefix: "snapshot"
          bootstrap-apt-packages: ""

      - name: Build snapshot artifacts
        run: make snapshot

      # why not use actions/upload-artifact? It is very slow (3 minutes to upload ~600MB of data, vs 10 seconds with this approach).
      # see https://github.com/actions/upload-artifact/issues/199 for more info
      - name: Upload snapshot artifacts
        uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
        with:
          path: snapshot
          key: snapshot-build-${{ github.run_id }}

  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@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7

      - name: Download snapshot build
        uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
        with:
          path: snapshot
          key: snapshot-build-${{ github.run_id }}

      - name: Restore install.sh test image cache
        id: install-test-image-cache
        uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
        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:
      - name: Install Cosign
        uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 #v3.5.0

      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7

      - name: Download snapshot build
        uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
        with:
          path: snapshot
          key: snapshot-build-${{ github.run_id }}

      - name: Restore docker image cache for compare testing
        id: mac-compare-testing-cache
        uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
        with:
          path: image.tar
          key: ${{ runner.os }}-${{ hashFiles('test/compare/mac.sh') }}

      - 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/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap

      - name: Restore CLI test-fixture cache
        uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
        with:
          path: ${{ github.workspace }}/test/cli/test-fixtures/cache
          key: ${{ runner.os }}-cli-test-cache-${{ hashFiles('test/cli/test-fixtures/cache.fingerprint') }}

      - name: Download snapshot build
        uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
        with:
          path: snapshot
          key: snapshot-build-${{ github.run_id }}

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