#
# Copyright 2021 The Dapr Authors
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#     http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# Required secrets:
# - AZURE_CREDENTIALS: JSON object containing the Azure service principal credentials. Docs: https://github.com/Azure/login#configure-a-service-principal-with-a-secret
# - DAPR_BOT_TOKEN: Token for the Dapr bot
#
# Optional secrets:
# - AZURE_DIAG_LOG_ANALYTICS_WORKSPACE_ID: Resource ID of the Log Analytics Workspace where to store certain diagnostic logs (e.g. `/subscriptions/<subscription>/resourcegroups/<resource group>/providers/Microsoft.OperationalInsights/workspaces/<workspace name>`)
# - AZURE_DIAG_STORAGE_ID: Resource ID of the Azure Storage account where to store certain diagnostic logs (e.g. `/subscriptions/<subscription>/resourcegroups/<resource group>/providers/Microsoft.Storage/storageAccounts/<storage account name>`)
# - AZURE_ARM_DIAG_LOG_ANALYTICS_WORKSPACE_ID: Resource ID of the Log Analytics Workspace where to store certain diagnostic logs for Arm64 (e.g. `/subscriptions/<subscription>/resourcegroups/<resource group>/providers/Microsoft.OperationalInsights/workspaces/<workspace name>`)
# - AZURE_ARM_DIAG_STORAGE_ID: Resource ID of the Azure Storage account where to store certain diagnostic logs for Arm64 (e.g. `/subscriptions/<subscription>/resourcegroups/<resource group>/providers/Microsoft.Storage/storageAccounts/<storage account name>`)

name: dapr-test

on:
  # Run every 4 hours on weekdays, and every 12 hours on weekends
  schedule:
    - cron: "11 3,7,11,15,19,23 * * 1-5"
    - cron: "11 11,23 * * 0,6"
  # Manual trigger
  workflow_dispatch:
  # Dispatch on external events
  repository_dispatch:
    types: [e2e-test]
env:
  # Configure proxy for Go modules
  GOPROXY: https://proxy.golang.org
  # Version of kubectl
  KUBECTLVER: "v1.27.6"
  # If not empty, uses cloud resources for testing
  TEST_CLOUD_ENV: "azure"
  # Version of Helm
  HELMVER: "v3.10.0"
  # Kubernetes namespace to use
  DAPR_NAMESPACE: "dapr-tests"
  # Timeout for tests
  MAX_TEST_TIMEOUT: 5400
  # Enable HA mode for tests
  HA_MODE: true
  # Enable tests on ARM64
  ENABLE_ARM: "false"
  # Space-separated of supported Azure regions: one will be picked randomly for each cluster
  AZURE_REGIONS: "westus3"
  AZURE_ARM_REGIONS: "eastus"
  # Container registry where to cache e2e test images
  DAPR_CACHE_REGISTRY: "dapre2eacr.azurecr.io"
  # Name of the Azure Key Vault resource used in tests
  # The credentials defined in AZURE_CREDENTIALS must have permissions to perform operations in this vault
  AZURE_KEY_VAULT_NAME: "dapre2ekv"
  # Whether to collect TCP dumps
  TCP_DUMPS: "false"
  # Additional build tags for Dapr
  DAPR_GO_BUILD_TAGS: "subtlecrypto,wfbackendsqlite"
  # Useful for upgrade/downgrade/compatibility tests
  # TODO: Make this auto-populated based on GitHub's releases.
  DAPR_TEST_N_MINUS_1_IMAGE: "ghcr.io/dapr/daprd:1.13.0"
  DAPR_TEST_N_MINUS_2_IMAGE: "ghcr.io/dapr/daprd:1.12.5"

jobs:
  deploy-infrastructure:
    name: Deploy test infrastructure
    runs-on: ubuntu-22.04
    steps:
      - name: Set up for manual runs
        if: github.event_name == 'workflow_dispatch'
        run: |
          echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV
          echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV
        shell: bash
      - name: Set up for scheduled test
        if: github.event_name == 'schedule'
        run: |
          echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV
          echo "CHECKOUT_REF=refs/heads/master" >> $GITHUB_ENV
        shell: bash
      - name: Set up for dispatched events
        if: github.event_name == 'repository_dispatch'
        uses: actions/github-script@v6.2.0
        with:
          github-token: ${{secrets.DAPR_BOT_TOKEN}}
          script: |
            const testPayload = context.payload.client_payload;
            if (testPayload && testPayload.command == "ok-to-test") {
              var fs = require('fs');
              // Set environment variables
              fs.appendFileSync(process.env.GITHUB_ENV,
                `CHECKOUT_REPO=${testPayload.pull_head_repo}\n`+
                `CHECKOUT_REF=${testPayload.pull_head_ref}\n`+
                `PR_NUMBER=${testPayload.issue.number}`
              );
            }
      - name: Create PR comment
        if: env.PR_NUMBER != ''
        uses: artursouza/sticky-pull-request-comment@v2.2.0
        with:
          header: ${{ github.run_id }}
          number: ${{ env.PR_NUMBER }}
          hide: true
          hide_classify: OUTDATED
          GITHUB_TOKEN: ${{ secrets.DAPR_BOT_TOKEN }}
          message: |
            # Dapr E2E test

            🔗 **[Link to Action run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})**

            Commit ref: ${{ env.CHECKOUT_REF }}
      - name: Check out code
        if: env.CHECKOUT_REPO != ''
        uses: actions/checkout@v4
        with:
          repository: ${{ env.CHECKOUT_REPO }}
          ref: ${{ env.CHECKOUT_REF }}
      - name: Login to Azure
        if: env.CHECKOUT_REPO != ''
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
      - name: Build test prefix
        if: env.CHECKOUT_REPO != ''
        run: |
          BASE_STR="E2E|${GITHUB_SHA}|${GITHUB_SERVER_URL}|${GITHUB_REPOSITORY}|${GITHUB_RUN_ID}|${GITHUB_RUN_ATTEMPT}"
          SUFFIX=$(echo $BASE_STR | sha1sum | head -c 10)
          TEST_PREFIX="dapre2e${SUFFIX}"
          echo "Test prefix is ${TEST_PREFIX}"
          echo "TEST_PREFIX=${TEST_PREFIX}" >> $GITHUB_ENV
        shell: bash
      - name: Deploy the test cluster
        if: env.TEST_PREFIX != ''
        run: |
          # Select one random Azure region
          REGIONS=(${{ env.AZURE_REGIONS }})
          REGIONS_SIZE=${#REGIONS[@]}
          REGIONS_IDX=$(($RANDOM % $REGIONS_SIZE))
          REGION1=${REGIONS[$REGIONS_IDX]}
          echo "REGION1=${REGION1}" >> $GITHUB_ENV
          REGION2=${REGIONS[$REGIONS_IDX]}
          echo "REGION2=${REGION2}" >> $GITHUB_ENV
          REGION3=${{ env.AZURE_ARM_REGIONS }}
          echo "REGION3=${REGION3}" >> $GITHUB_ENV
          echo "Deploying to Azure regions: Linux_amd64=${REGION1} Windows=${REGION2} Linux_arm64=${REGION3}"
          # Tags
          DATE_TAG=$(date --iso-8601=seconds)
          echo "Tags: date=${DATE_TAG}"

          # Deploy Linux arm64/amd64 and Windows clusters
          # Retry the deployment twice in case of transient failures (such as capacity constraints)
          success=false
          for i in 1 2 3; do 
            az deployment sub create \
              --name "${{ env.TEST_PREFIX }}" \
              --location ${REGION1} \
              --template-file ./tests/test-infra/azure-all.bicep \
              --parameters \
                namePrefix="${{ env.TEST_PREFIX }}" \
                enableArm="${{ env.ENABLE_ARM }}" \
                location1=${REGION1} \
                location2=${REGION2} \
                location3=${REGION3} \
                dateTag="${DATE_TAG}" \
                diagLogAnalyticsWorkspaceResourceId="${{ secrets.AZURE_DIAG_LOG_ANALYTICS_WORKSPACE_ID }}" \
                diagStorageResourceId="${{ secrets.AZURE_DIAG_STORAGE_ID }}" \
                armDiagLogAnalyticsWorkspaceResourceId="${{ secrets.AZURE_ARM_DIAG_LOG_ANALYTICS_WORKSPACE_ID }}" \
                armDiagStorageResourceId="${{ secrets.AZURE_ARM_DIAG_STORAGE_ID }}" \
              && success=true \
              && break \
              || sleep 120
          done
          # Exit with error if failed
          $success || exit 1
        shell: bash
      - name: Update PR comment for success
        if: success() && env.PR_NUMBER != ''
        uses: artursouza/sticky-pull-request-comment@v2.2.0
        with:
          header: ${{ github.run_id }}
          number: ${{ env.PR_NUMBER }}
          append: true
          GITHUB_TOKEN: ${{ secrets.DAPR_BOT_TOKEN }}
          message: |
            ## ✅ Infrastructure deployed

            | Cluster | Resource group name | Azure region |
            | --- | --- | --- |
            | Linux | `Dapr-E2E-${{ env.TEST_PREFIX }}l` | ${{ env.REGION1 }} |
            | Windows | `Dapr-E2E-${{ env.TEST_PREFIX }}w` | ${{ env.REGION2 }} |
            | Linux/arm64 | `Dapr-E2E-${{ env.TEST_PREFIX }}la` | ${{ env.REGION3 }} |
      - name: Update PR comment for failure
        if: failure() && env.PR_NUMBER != ''
        uses: artursouza/sticky-pull-request-comment@v2.2.0
        with:
          header: ${{ github.run_id }}
          number: ${{ env.PR_NUMBER }}
          append: true
          GITHUB_TOKEN: ${{ secrets.DAPR_BOT_TOKEN }}
          message: |
            ## ❌ Infrastructure deployment failed

            | Cluster | Resource group name | Azure region |
            | --- | --- | --- |
            | Linux | `Dapr-E2E-${{ env.TEST_PREFIX }}l` | ${{ env.REGION1 }} |
            | Windows | `Dapr-E2E-${{ env.TEST_PREFIX }}w` | ${{ env.REGION2 }} |
            | Linux/arm64 | `Dapr-E2E-${{ env.TEST_PREFIX }}la` | ${{ env.REGION3 }} |

            Please check the logs for details on the failure.

  build:
    name: Build for  ${{ matrix.target_os }} on ${{ matrix.target_arch }}
    runs-on: ${{ matrix.os }}
    env:
      GOOS: ${{ matrix.target_os }}
      GOARCH: ${{ matrix.target_arch }}
      TARGET_OS: ${{ matrix.target_os }}
      TARGET_ARCH: ${{ matrix.target_arch }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-22.04
            target_os: linux
            target_arch: amd64
          - os: windows-2022
            target_os: windows
            target_arch: amd64
            windows_version: ltsc2022
    steps:
      - name: Set up for manual runs
        if: github.event_name == 'workflow_dispatch'
        run: |
          echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV
          echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV
        shell: bash
      - name: Set up for scheduled test
        if: github.event_name == 'schedule'
        run: |
          echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV
          echo "CHECKOUT_REF=refs/heads/master" >> $GITHUB_ENV
        shell: bash
      - name: Set up for dispatched events
        if: github.event_name == 'repository_dispatch'
        uses: actions/github-script@v6.2.0
        with:
          github-token: ${{secrets.DAPR_BOT_TOKEN}}
          script: |
            const testPayload = context.payload.client_payload;
            if (testPayload && testPayload.command == "ok-to-test") {
              var fs = require('fs');
              // Set environment variables
              fs.appendFileSync(process.env.GITHUB_ENV,
                `CHECKOUT_REPO=${testPayload.pull_head_repo}\n`+
                `CHECKOUT_REF=${testPayload.pull_head_ref}\n`+
                `PR_NUMBER=${testPayload.issue.number}`
              );
            }
      # In windows-2019 images, WSL comes with bash.exe (but no distribution) and that causes issues
      # See: https://github.community/t/wsl-not-available-for-hosted-windows-machine/124389
      - name: Remove bash.exe from WSL
        if: runner.os == 'Windows'
        run: |
          rm.exe "C:/WINDOWS/system32/bash.EXE"
      - name: Check out code
        if: env.CHECKOUT_REPO != ''
        uses: actions/checkout@v4
        with:
          repository: ${{ env.CHECKOUT_REPO }}
          ref: ${{ env.CHECKOUT_REF }}
      - name: Set up Go
        id: setup-go
        uses: actions/setup-go@v5
        with:
          go-version-file: "go.mod"
      - name: Login to Azure
        if: env.CHECKOUT_REPO != ''
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
      - name: Login to cache registry for Windows
        if: runner.os == 'Windows' && env.CHECKOUT_REPO != '' && env.DAPR_CACHE_REGISTRY != ''
        run: |
          $accessToken = (az acr login  -n ${{ env.DAPR_CACHE_REGISTRY }} --expose-token --query accessToken --output tsv)
          docker login ${{ env.DAPR_CACHE_REGISTRY }} -u 00000000-0000-0000-0000-000000000000 -p $accessToken
      - name: Login to cache registry for Linux or Mac
        if: runner.os != 'Windows' && env.CHECKOUT_REPO != '' && env.DAPR_CACHE_REGISTRY != ''
        run: |
          az acr login --name ${{ env.DAPR_CACHE_REGISTRY }}
        shell: bash
      - name: Build test prefix and set env vars
        if: env.CHECKOUT_REPO != ''
        run: |
          BASE_STR="E2E|${GITHUB_SHA}|${GITHUB_SERVER_URL}|${GITHUB_REPOSITORY}|${GITHUB_RUN_ID}|${GITHUB_RUN_ATTEMPT}"
          SUFFIX=$(echo $BASE_STR | sha1sum | head -c 10)
          TEST_PREFIX=""
          if [ "${{ env.TARGET_OS }}" == "windows" ] ; then
            TEST_PREFIX="dapre2e${SUFFIX}w"
          elif [ "${{ env.TARGET_ARCH }}" == "arm64" ] ; then  
            TEST_PREFIX="dapre2e${SUFFIX}la"
          else
            TEST_PREFIX="dapre2e${SUFFIX}l"
          fi
          echo "Test prefix is ${TEST_PREFIX}"
          echo "TEST_PREFIX=${TEST_PREFIX}" >> $GITHUB_ENV
          echo "DAPR_REGISTRY=${TEST_PREFIX}acr.azurecr.io" >> $GITHUB_ENV
          echo "TEST_CLUSTER=${TEST_PREFIX}-aks" >> $GITHUB_ENV
          echo "DAPR_TAG=${TEST_PREFIX}" >> $GITHUB_ENV
          echo "DAPR_TEST_TAG=${TEST_PREFIX}" >> $GITHUB_ENV
          echo "TEST_RESOURCE_GROUP=Dapr-E2E-${TEST_PREFIX}" >> $GITHUB_ENV
          echo "WINDOWS_VERSION=${{ matrix.windows_version }}" >> $GITHUB_ENV
        shell: bash
      - name: Build Dapr and its Docker images
        if: env.TEST_PREFIX != ''
        run: |
          make build
          if [ "${{ env.TARGET_OS }}" = "linux" ] && [ "${{ env.TARGET_ARCH }}" != "arm" ]; then
            # For Linux, we use images based on Mariner
            DOCKERFILE=Dockerfile-mariner make docker-build
          else
            make docker-build
          fi
        shell: bash
      - name: Wait for Azure Container Registry deployment
        timeout-minutes: 30
        if: env.TEST_PREFIX != ''
        run: ./tests/test-infra/wait_${{ env.TEST_CLOUD_ENV }}_registry.sh ${{ env.TEST_PREFIX }}acr
        shell: bash
      - name: Login to Azure Container Registry for Windows
        if: runner.os == 'Windows' && env.TEST_PREFIX != ''
        run: |
          $accessToken = (az acr login  -n ${{ env.DAPR_REGISTRY }} --expose-token --query accessToken --output tsv)
          docker login ${{ env.DAPR_REGISTRY }} -u 00000000-0000-0000-0000-000000000000 -p $accessToken
      - name: Login to Azure Container Registry for Linux or Mac
        if: runner.os != 'Windows' && env.TEST_PREFIX != ''
        run: |
          az acr login --name ${{ env.TEST_PREFIX }}acr
        shell: bash
      - name: Push Dapr container images
        if: env.TEST_PREFIX != ''
        run: |
          if [ "${{ env.TARGET_OS }}" = "linux" ] && [ "${{ env.TARGET_ARCH }}" != "arm" ]; then
            # For Linux, we use images based on Mariner
            DOCKERFILE=Dockerfile-mariner make docker-push
          else
            make docker-push
          fi
        shell: bash
      - name: Build and push E2E test apps
        if: env.TEST_PREFIX != ''
        run: |
          make build-push-e2e-app-all
        shell: bash
      - name: Update PR comment for success
        if: success() && env.PR_NUMBER != ''
        uses: artursouza/sticky-pull-request-comment@v2.2.0
        with:
          header: ${{ github.run_id }}
          number: ${{ env.PR_NUMBER }}
          append: true
          GITHUB_TOKEN: ${{ secrets.DAPR_BOT_TOKEN }}
          message: |
            ## ✅ Build succeeded for ${{ matrix.target_os }}/${{ matrix.target_arch }}

            - Image tag: `${{ env.DAPR_TAG }}`
            - Test image tag: `${{ env.DAPR_TEST_TAG }}`
      - name: Update PR comment for failure
        if: failure() && env.PR_NUMBER != ''
        uses: artursouza/sticky-pull-request-comment@v2.2.0
        with:
          header: ${{ github.run_id }}
          number: ${{ env.PR_NUMBER }}
          append: true
          GITHUB_TOKEN: ${{ secrets.DAPR_BOT_TOKEN }}
          message: |
            ## ❌ Build failed for ${{ matrix.target_os }}/${{ matrix.target_arch }}

            Please check the logs for details on the error.

  test-e2e:
    name: End-to-end ${{ matrix.target_os }} on ${{ matrix.target_arch }} tests
    needs:
      - build
      - deploy-infrastructure
    # Always run on Linux as the local OS is irrelevant and this is faster
    runs-on: ubuntu-22.04
    env:
      TARGET_OS: ${{ matrix.target_os }}
      TARGET_ARCH: ${{ matrix.target_arch }}
      TEST_OUTPUT_FILE_PREFIX: "test_report"
      PULL_POLICY: IfNotPresent
    strategy:
      fail-fast: false
      matrix:
        include:
          - target_os: linux
            target_arch: amd64
          - target_os: windows
            target_arch: amd64
            windows_version: ltsc2022
    steps:
      - name: Set up log paths
        run: |
          echo "DAPR_CONTAINER_LOG_PATH=$GITHUB_WORKSPACE/container_logs/${{ matrix.target_os }}_${{ matrix.target_arch }}" | sed 's/\\/\//g' >> $GITHUB_ENV
          echo "DAPR_TEST_LOG_PATH=$GITHUB_WORKSPACE/test_logs/${{ matrix.target_os }}_${{ matrix.target_arch }}" | sed 's/\\/\//g' >> $GITHUB_ENV
        shell: bash
      - name: Set up for manual runs
        if: github.event_name == 'workflow_dispatch'
        run: |
          echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV
          echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV
        shell: bash
      - name: Set up for scheduled test
        if: github.event_name == 'schedule'
        run: |
          echo "CHECKOUT_REPO=${{ github.repository }}" >> $GITHUB_ENV
          echo "CHECKOUT_REF=refs/heads/master" >> $GITHUB_ENV
        shell: bash
      - name: Set up for dispatched events
        if: github.event_name == 'repository_dispatch'
        uses: actions/github-script@v6.2.0
        with:
          github-token: ${{secrets.DAPR_BOT_TOKEN}}
          script: |
            const testPayload = context.payload.client_payload;
            if (testPayload && testPayload.command == "ok-to-test") {
              var fs = require('fs');
              // Set environment variables
              fs.appendFileSync(process.env.GITHUB_ENV,
                `CHECKOUT_REPO=${testPayload.pull_head_repo}\n`+
                `CHECKOUT_REF=${testPayload.pull_head_ref}\n`+
                `PR_NUMBER=${testPayload.issue.number}`
              );
            }
      - name: Check out code
        if: env.CHECKOUT_REPO != ''
        uses: actions/checkout@v4
        with:
          repository: ${{ env.CHECKOUT_REPO }}
          ref: ${{ env.CHECKOUT_REF }}
      - name: Set up Go
        id: setup-go
        uses: actions/setup-go@v5
        with:
          go-version-file: "go.mod"
      - uses: azure/setup-kubectl@v3
        with:
          version: ${{ env.KUBECTLVER }}
        id: install
      - name: Set up Helm ${{ env.HELMVER }}
        uses: azure/setup-helm@v3
        with:
          version: ${{ env.HELMVER }}
      - name: Login to Azure
        if: env.CHECKOUT_REPO != ''
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
      - name: Build test prefix and set env vars
        if: env.CHECKOUT_REPO != ''
        run: |
          BASE_STR="E2E|${GITHUB_SHA}|${GITHUB_SERVER_URL}|${GITHUB_REPOSITORY}|${GITHUB_RUN_ID}|${GITHUB_RUN_ATTEMPT}"
          SUFFIX=$(echo $BASE_STR | sha1sum | head -c 10)
          TEST_PREFIX=""
          if [ "${{ env.TARGET_OS }}" == "windows" ] ; then
            TEST_PREFIX="dapre2e${SUFFIX}w"
          elif [ "${{ env.TARGET_ARCH }}" == "arm64" ] ; then  
            TEST_PREFIX="dapre2e${SUFFIX}la"
          else
            TEST_PREFIX="dapre2e${SUFFIX}l"
          fi
          echo "Test prefix is ${TEST_PREFIX}"
          echo "TEST_PREFIX=${TEST_PREFIX}" >> $GITHUB_ENV
          echo "DAPR_REGISTRY=${TEST_PREFIX}acr.azurecr.io" >> $GITHUB_ENV
          echo "TEST_CLUSTER=${TEST_PREFIX}-aks" >> $GITHUB_ENV
          echo "DAPR_TAG=${TEST_PREFIX}" >> $GITHUB_ENV
          echo "DAPR_TEST_TAG=${TEST_PREFIX}" >> $GITHUB_ENV
          echo "TEST_RESOURCE_GROUP=Dapr-E2E-${TEST_PREFIX}" >> $GITHUB_ENV
          echo "WINDOWS_VERSION=${{ matrix.windows_version }}" >> $GITHUB_ENV
        shell: bash
      - name: Enable tcpdump
        if: env.TCP_DUMPS == 'true'
        run: |
          sudo tcpdump -nn -i any -w sntp.cap &
          sleep 1
        shell: bash
      - name: Connect to Kubernetes
        if: env.TEST_PREFIX != ''
        run: |
          az aks get-credentials -n "${{ env.TEST_CLUSTER }}" -g "${{ env.TEST_RESOURCE_GROUP }}"
          kubectl create namespace ${{ env.DAPR_NAMESPACE }}
        shell: bash
      - name: Setup for cloud resources
        if: env.TEST_PREFIX != '' && env.TEST_CLOUD_ENV != ''
        env:
          AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}
        run: ./tests/test-infra/setup_${{ env.TEST_CLOUD_ENV }}.sh
        shell: bash
      - name: Preparing AKS cluster for test
        if: env.TEST_PREFIX != ''
        run: |
          make setup-helm-init
          make setup-test-env-redis
          make setup-test-env-kafka
          make setup-test-env-zipkin
          make setup-test-env-postgres
          kubectl get pods -n ${{ env.DAPR_NAMESPACE }}
        shell: bash
      - name: Deploy dapr to AKS cluster
        if: env.TEST_PREFIX != ''
        env:
          ADDITIONAL_HELM_SET: "dapr_operator.logLevel=debug,dapr_operator.watchInterval=20s,dapr_dashboard.enabled=false"
        run: make docker-deploy-k8s
      - name: Deploy test components
        if: env.TEST_PREFIX != ''
        run: make setup-test-components
      - name: Show dapr configurations
        if: env.TEST_PREFIX != ''
        run: kubectl get configurations daprsystem -n ${{ env.DAPR_NAMESPACE }} -o yaml
      - name: Determine if E2E tests should run
        if: env.TEST_PREFIX != '' && env.TEST_CLOUD_ENV != ''
        run: ./tests/test-infra/skip_${{ env.TEST_CLOUD_ENV }}.sh
        shell: bash
      - name: Run E2E tests
        if: env.TEST_PREFIX != '' && env.SKIP_E2E != 'true'
        run: make test-e2e-all
      - name: Add job test summary
        if: always()
        uses: test-summary/action@v2
        with:
          paths: ${{ env.TEST_OUTPUT_FILE_PREFIX }}_e2e*.xml
      - name: Add job test outputs
        if: always()
        uses: actions/github-script@v6
        with:
          script: |
            const script = require('./.github/scripts/dapr_tests_summary.js')
            await script({core, glob})
      - name: Save control plane K8s resources
        if: always() && env.TEST_PREFIX != ''
        run: |
          make save-dapr-control-plane-k8s-resources || true
      - name: Save control plane logs
        if: always() && env.TEST_PREFIX != ''
        run: |
          make save-dapr-control-plane-k8s-logs
      - name: Stop tcpdump
        if: always() && env.TCP_DUMPS == 'true'
        run: |
          sleep 1
          sudo kill -2 $(pgrep tcpdump)
          sleep 1
      # Container log files can be bigger than the maximum file size allowed by GitHub
      - name: Compress logs
        if: always()
        run: |
          test ${{ env.DAPR_CONTAINER_LOG_PATH }} \
            && gzip --fast -r ${{ env.DAPR_CONTAINER_LOG_PATH }} \
            || true
          test ${{ env.DAPR_TEST_LOG_PATH }} \
            && gzip --fast -r ${{ env.DAPR_TEST_LOG_PATH }} \
            || true
          test -f sntp.cap \
            && gzip --fast sntp.cap \
            || true
        shell: bash
      - name: Upload tcpdump
        if: always() && env.TCP_DUMPS == 'true'
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.target_os }}_${{ matrix.target_arch }}_tcpdump
          path: sntp.cap.gz
          compression-level: 0 # File is already compressed
      - name: Upload container logs
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.target_os }}_${{ matrix.target_arch }}_container_logs
          path: ${{ env.DAPR_CONTAINER_LOG_PATH }}
          compression-level: 0 # Content is already compressed
      - name: Upload test logs
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.target_os }}_${{ matrix.target_arch }}_test_logs
          path: ${{ env.DAPR_TEST_LOG_PATH }}
          compression-level: 0 # Content is already compressed
      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          #TODO: .json suffix can be removed from artifact name after test analytics scripts are updated
          name: ${{ matrix.target_os }}_${{ matrix.target_arch }}_e2e.json
          path: ${{ env.TEST_OUTPUT_FILE_PREFIX }}_e2e.*
      - name: Update PR comment for success
        if: success() && env.PR_NUMBER != '' && env.SKIP_E2E != 'true'
        uses: artursouza/sticky-pull-request-comment@v2.2.0
        with:
          header: ${{ github.run_id }}
          number: ${{ env.PR_NUMBER }}
          append: true
          GITHUB_TOKEN: ${{ secrets.DAPR_BOT_TOKEN }}
          message: |
            ## ✅ Tests succeeded on ${{ matrix.target_os }}/${{ matrix.target_arch }}

            - Image tag: `${{ env.DAPR_TAG }}`
            - Test image tag: `${{ env.DAPR_TEST_TAG }}`
      - name: Update PR comment for skipped test run
        if: success() && env.PR_NUMBER != '' && env.SKIP_E2E == 'true'
        uses: artursouza/sticky-pull-request-comment@v2.2.0
        with:
          header: ${{ github.run_id }}
          number: ${{ env.PR_NUMBER }}
          append: true
          GITHUB_TOKEN: ${{ secrets.DAPR_BOT_TOKEN }}
          message: |
            ## ⚠️ Tests skipped on ${{ matrix.target_os }}/${{ matrix.target_arch }}

            - Image tag: `${{ env.DAPR_TAG }}`
            - Test image tag: `${{ env.DAPR_TEST_TAG }}`
      - name: Update PR comment for failure
        if: failure() && env.PR_NUMBER != ''
        uses: artursouza/sticky-pull-request-comment@v2.2.0
        with:
          header: ${{ github.run_id }}
          number: ${{ env.PR_NUMBER }}
          append: true
          GITHUB_TOKEN: ${{ secrets.DAPR_BOT_TOKEN }}
          message: |
            ## ❌ Tests failed on ${{ matrix.target_os }}/${{ matrix.target_arch }}

            Please check the logs for details on the error.
      - name: Update PR comment for cancellation
        if: cancelled() && env.PR_NUMBER != ''
        uses: artursouza/sticky-pull-request-comment@v2.2.0
        with:
          header: ${{ github.run_id }}
          number: ${{ env.PR_NUMBER }}
          append: true
          GITHUB_TOKEN: ${{ secrets.DAPR_BOT_TOKEN }}
          message: |
            ## ⚠️ Tests cancelled for ${{ matrix.target_os }}/${{ matrix.target_arch }}

            The Action has been canceled

  cleanup:
    name: Clean up Azure resources
    runs-on: ubuntu-22.04
    needs:
      - test-e2e
    if: always()
    steps:
      - name: Login to Azure
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}
      - name: Build test prefix
        run: |
          BASE_STR="E2E|${GITHUB_SHA}|${GITHUB_SERVER_URL}|${GITHUB_REPOSITORY}|${GITHUB_RUN_ID}|${GITHUB_RUN_ATTEMPT}"
          SUFFIX=$(echo $BASE_STR | sha1sum | head -c 10)
          TEST_PREFIX="dapre2e${SUFFIX}"
          echo "Test prefix is ${TEST_PREFIX}"
          echo "TEST_PREFIX=${TEST_PREFIX}" >> $GITHUB_ENV
        shell: bash
      - name: Delete Linux cluster
        run: |
          # We are not waiting for these commands to complete, and we're ignoring errors
          echo "Starting removal of resource group Dapr-E2E-${{ env.TEST_PREFIX }}l"
          az group delete --no-wait --yes --name "Dapr-E2E-${{ env.TEST_PREFIX }}l" || true
        shell: bash
      - name: Delete Windows cluster
        run: |
          # We are not waiting for these commands to complete, and we're ignoring errors
          echo "Starting removal of resource group Dapr-E2E-${{ env.TEST_PREFIX }}w"
          az group delete --no-wait --yes --name "Dapr-E2E-${{ env.TEST_PREFIX }}w" || true
        shell: bash
      - name: Delete Arm64 cluster
        if: env.ENABLE_ARM == 'true'
        run: |
          # We are not waiting for these commands to complete, and we're ignoring errors
          echo "Starting removal of resource group Dapr-E2E-${{ env.TEST_PREFIX }}la"
          az group delete --no-wait --yes --name "Dapr-E2E-${{ env.TEST_PREFIX }}la" || true
        shell: bash
