name: e2e test daily

on:
  workflow_dispatch:
  schedule:
    - cron: "0 3 * * 2-5" # At 03:00 on every day-of-week from Tuesday through Friday.

jobs:
  find-latest-image:
    strategy:
      fail-fast: false
      matrix:
        refStream: ["ref/main/stream/debug/?", "ref/release/stream/stable/?"]
    name: Find latest image
    runs-on: ubuntu-22.04
    permissions:
      id-token: write
      contents: read
    outputs:
      image-main-debug: ${{ steps.relabel-output.outputs.image-main-debug }}
      image-release-stable: ${{ steps.relabel-output.outputs.image-release-stable }}
    steps:
      - name: Checkout
        uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
        with:
          ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }}

      - name: Select relevant image
        id: select-image-action
        uses: ./.github/actions/select_image
        with:
          osImage: ${{ matrix.refStream }}

      - name: Relabel output
        id: relabel-output
        shell: bash
        run: |
          ref=$(echo ${{ matrix.refStream }} | cut -d/ -f2)
          stream=$(echo ${{ matrix.refStream }} | cut -d/ -f4)

          echo "image-$ref-$stream=${{ steps.select-image-action.outputs.osImage }}" | tee -a "$GITHUB_OUTPUT"

  e2e-daily:
    strategy:
      fail-fast: false
      max-parallel: 5
      matrix:
        kubernetesVersion: ["1.28"] # should be default
        attestationVariant: ["gcp-sev-es", "gcp-sev-snp", "azure-sev-snp", "azure-tdx", "aws-sev-snp"]
        refStream: ["ref/main/stream/debug/?", "ref/release/stream/stable/?"]
        test: ["sonobuoy quick"]
        exclude:
          # TODO(v2.18 msanft): Remove exclude rule for GCP SEV-SNP stable once images exist.
          - kubernetesVersion: "1.28"
            attestationVariant: "gcp-sev-snp"
            refStream: "ref/release/stream/stable/?"
            test: "sonobuoy quick"
    runs-on: ubuntu-22.04
    permissions:
      id-token: write
      checks: write
      contents: read
      packages: write
      actions: write
    needs: [find-latest-image]
    steps:
      - name: Check out repository
        uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
        with:
          fetch-depth: 0
          ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }}

      - name: Split attestationVariant
        id: split-attestationVariant
        shell: bash
        run: |
          attestationVariant="${{ matrix.attestationVariant }}"
          cloudProvider="${attestationVariant%%-*}"

          echo "cloudProvider=${cloudProvider}" | tee -a "$GITHUB_OUTPUT"

      - name: Run E2E test
        id: e2e_test
        uses: ./.github/actions/e2e_test
        with:
          workerNodesCount: "2"
          controlNodesCount: "3"
          cloudProvider: ${{ steps.split-attestationVariant.outputs.cloudProvider }}
          attestationVariant: ${{ matrix.attestationVariant }}
          osImage: ${{ matrix.refStream == 'ref/release/stream/stable/?' && needs.find-latest-image.outputs.image-release-stable || needs.find-latest-image.outputs.image-main-debug }}
          isDebugImage: ${{ matrix.refStream == 'ref/main/stream/debug/?' }}
          cliVersion: ${{ matrix.refStream == 'ref/release/stream/stable/?' && needs.find-latest-image.outputs.image-release-stable || '' }}
          refStream: ${{ matrix.refStream }}
          gcpProject: constellation-e2e
          gcpClusterCreateServiceAccount: "infrastructure-e2e@constellation-e2e.iam.gserviceaccount.com"
          gcpIAMCreateServiceAccount: "iam-e2e@constellation-e2e.iam.gserviceaccount.com"
          kubernetesVersion: ${{ matrix.kubernetesVersion }}
          test: ${{ matrix.test }}
          azureClusterCreateCredentials: ${{ secrets.AZURE_E2E_CLUSTER_CREDENTIALS }}
          azureIAMCreateCredentials: ${{ secrets.AZURE_E2E_IAM_CREDENTIALS }}
          registry: ghcr.io
          githubToken: ${{ secrets.GITHUB_TOKEN }}
          cosignPassword: ${{ secrets.COSIGN_PASSWORD }}
          cosignPrivateKey: ${{ secrets.COSIGN_PRIVATE_KEY }}
          fetchMeasurements: ${{ matrix.refStream != 'ref/release/stream/stable/?' }}
          awsOpenSearchDomain: ${{ secrets.AWS_OPENSEARCH_DOMAIN }}
          awsOpenSearchUsers: ${{ secrets.AWS_OPENSEARCH_USER }}
          awsOpenSearchPwd: ${{ secrets.AWS_OPENSEARCH_PWD }}
          clusterCreation: "cli"
          encryptionSecret: ${{ secrets.ARTIFACT_ENCRYPT_PASSWD }}

      - name: Always terminate cluster
        if: always()
        uses: ./.github/actions/constellation_destroy
        with:
          kubeconfig: ${{ steps.e2e_test.outputs.kubeconfig }}
          clusterCreation: "cli"
          cloudProvider: ${{ steps.split-attestationVariant.outputs.cloudProvider }}
          azureClusterDeleteCredentials: ${{ secrets.AZURE_E2E_CLUSTER_CREDENTIALS }}
          gcpClusterDeleteServiceAccount: "infrastructure-e2e@constellation-e2e.iam.gserviceaccount.com"

      - name: Always delete IAM configuration
        if: always()
        uses: ./.github/actions/constellation_iam_destroy
        with:
          cloudProvider: ${{ steps.split-attestationVariant.outputs.cloudProvider }}
          azureCredentials: ${{ secrets.AZURE_E2E_IAM_CREDENTIALS }}
          gcpServiceAccount: "iam-e2e@constellation-e2e.iam.gserviceaccount.com"

      - name: Update tfstate
        if: always()
        env:
          GH_TOKEN: ${{ github.token }}
        uses: ./.github/actions/update_tfstate
        with:
          name: terraform-state-${{ steps.e2e_test.outputs.namePrefix }}
          runID: ${{ github.run_id }}
          encryptionSecret: ${{ secrets.ARTIFACT_ENCRYPT_PASSWD }}

      - name: Notify about failure
        if: |
          failure() &&
          github.ref == 'refs/heads/main' &&
          github.event_name == 'schedule'
        continue-on-error: true
        uses: ./.github/actions/notify_e2e_failure
        with:
          projectWriteToken: ${{ secrets.PROJECT_WRITE_TOKEN }}
          refStream: ${{ matrix.refStream }}
          test: ${{ matrix.test }}
          kubernetesVersion: ${{ matrix.kubernetesVersion }}
          provider: ${{ steps.split-attestationVariant.outputs.cloudProvider }}
          attestationVariant: ${{ matrix.attestationVariant }}
          clusterCreation: "cli"

  e2e-mini:
    name: Run miniconstellation E2E test
    runs-on: ubuntu-22.04
    environment: e2e
    permissions:
      id-token: write
      contents: read
      packages: write
    steps:
      - name: Checkout
        id: checkout
        uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
        with:
          ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }}

      - name: Azure login OIDC
        uses: azure/login@cb79c773a3cfa27f31f25eb3f677781210c9ce3d # v1.6.1
        with:
          client-id: ${{ secrets.AZURE_E2E_MINI_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      - name: Run e2e MiniConstellation
        uses: ./.github/actions/e2e_mini
        with:
          azureClientID: ${{ secrets.AZURE_E2E_MINI_CLIENT_ID }}
          azureSubscriptionID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
          azureTenantID: ${{ secrets.AZURE_TENANT_ID }}
          registry: ghcr.io
          githubToken: ${{ secrets.GITHUB_TOKEN }}

      - name: Notify about failure
        if: |
          failure() &&
          github.ref == 'refs/heads/main' &&
          github.event_name == 'schedule'
        continue-on-error: true
        uses: ./.github/actions/notify_e2e_failure
        with:
          projectWriteToken: ${{ secrets.PROJECT_WRITE_TOKEN }}
          attestationVariant: "qemu-vtpm"
          test: "MiniConstellation"
          provider: "QEMU"