---
name: Run integration tests in Testing Farm
on:
  issue_comment:
    types:
      - created
permissions:
  contents: read
  # This is required for the ability to create/update the Pull request status
  statuses: write
jobs:
  prepare_vars:
    name: Get info from role and PR to determine if and how to test
    # The concurrency key is used to prevent multiple workflows from running at the same time
    concurrency:
      # group name contains reponame-pr_num to allow simualteneous runs in different PRs
      group: testing-farm-${{ github.event.repository.name }}-${{ github.event.issue.number }}
      cancel-in-progress: true
    # Let's schedule tests only on user request. NOT automatically.
    # Only repository owner or member can schedule tests
    if: |
      github.event.issue.pull_request
      && contains(github.event.comment.body, '[citest]')
      && (contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)
      || contains('systemroller', github.event.comment.user.login))
    runs-on: ubuntu-latest
    outputs:
      supported_platforms: ${{ steps.supported_platforms.outputs.supported_platforms }}
      head_sha: ${{ steps.head_sha.outputs.head_sha }}
      memory: ${{ steps.memory.outputs.memory }}
    steps:
      - name: Dump github context
        run:   echo "$GITHUB_CONTEXT"
        shell: bash
        env:
          GITHUB_CONTEXT: ${{ toJson(github) }}

      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Get head sha of the PR
        id: head_sha
        run: |
          head_sha=$(gh api "repos/$REPO/pulls/$PR_NO" --jq '.head.sha')
          echo "head_sha=$head_sha" >> $GITHUB_OUTPUT
        env:
          REPO: ${{ github.repository }}
          PR_NO: ${{ github.event.issue.number }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Checkout PR
        uses: actions/checkout@v4
        with:
          ref: ${{ steps.head_sha.outputs.head_sha }}

      - name: Get memory
        id: memory
        run: |
          if [ -d tests/provision.fmf ]; then
            memory=$(grep -rPo '    m: \K(.*)' tests/provision.fmf)
          fi
          if [ -n "$memory" ]; then
            echo "memory=$memory" >> $GITHUB_OUTPUT
          else
            echo "memory=2048" >> $GITHUB_OUTPUT
          fi

      - name: Get supported platforms
        id: supported_platforms
        run: |
          supported_platforms=""
          meta_main=meta/main.yml
          # All Fedora are supported, add latest Fedora versions to supported_platforms
          if yq '.galaxy_info.galaxy_tags[]' "$meta_main" | grep -qi fedora$; then
            supported_platforms+=" Fedora-41"
            supported_platforms+=" Fedora-42"
          fi
          # Specific Fedora versions supported
          if yq '.galaxy_info.galaxy_tags[]' "$meta_main" | grep -qiP 'fedora\d+$'; then
            for fedora_ver in $(yq '.galaxy_info.galaxy_tags[]' "$meta_main" | grep -iPo 'fedora\K(\d+$)'); do
              supported_platforms+=" Fedora-$fedora_ver"
            done
          fi
          if yq '.galaxy_info.galaxy_tags[]' "$meta_main" | grep -qi el7; then
            supported_platforms+=" CentOS-7-latest"
          fi
          for ver in 8 9 10; do
            if yq '.galaxy_info.galaxy_tags[]' "$meta_main" | grep -qi el"$ver"; then
              supported_platforms+=" CentOS-Stream-$ver"
            fi
          done
          echo "supported_platforms=$supported_platforms" >> $GITHUB_OUTPUT

  testing-farm:
    name: ${{ matrix.platform }}/ansible-${{ matrix.ansible_version }}
    needs: prepare_vars
    strategy:
      fail-fast: false
      matrix:
        include:
          - platform: Fedora-41
            ansible_version: 2.17
          - platform: Fedora-42
            ansible_version: 2.19
          - platform: CentOS-7-latest
            ansible_version: 2.9
          - platform: CentOS-Stream-8
            ansible_version: 2.9
          # On CentOS-Stream-8, latest supported Ansible is 2.16
          - platform: CentOS-Stream-8
            ansible_version: 2.16
          - platform: CentOS-Stream-9
            ansible_version: 2.17
          - platform: CentOS-Stream-10
            ansible_version: 2.17
    runs-on: ubuntu-latest
    env:
      ARTIFACTS_DIR_NAME: "tf_${{ github.event.repository.name }}-${{ github.event.issue.number }}_\
        ${{ matrix.platform }}-${{ matrix.ansible_version }}_\
        ${{ needs.prepare_vars.outputs.datetime }}/artifacts"
      ARTIFACT_TARGET_DIR: /srv/pub/alt/${{ vars.SR_LSR_USER }}/logs
    steps:
      - name: Set variables with DATETIME and artifact location
        id: set_vars
        run: |
          printf -v DATETIME '%(%Y%m%d-%H%M%S)T' -1
          ARTIFACTS_DIR_NAME="tf_${{ github.event.repository.name }}-${{ github.event.issue.number }}_\
          ${{ matrix.platform }}-${{ matrix.ansible_version }}_$DATETIME/artifacts"
          ARTIFACTS_TARGET_DIR=/srv/pub/alt/${{ vars.SR_LSR_USER }}/logs
          ARTIFACTS_DIR=$ARTIFACTS_TARGET_DIR/$ARTIFACTS_DIR_NAME
          ARTIFACTS_URL=https://dl.fedoraproject.org/pub/alt/${{ vars.SR_LSR_USER }}/logs/$ARTIFACTS_DIR_NAME
          echo "DATETIME=$DATETIME" >> $GITHUB_OUTPUT
          echo "ARTIFACTS_DIR=$ARTIFACTS_DIR" >> $GITHUB_OUTPUT
          echo "ARTIFACTS_URL=$ARTIFACTS_URL" >> $GITHUB_OUTPUT

      - name: Set commit status as pending
        if: contains(needs.prepare_vars.outputs.supported_platforms, matrix.platform)
        uses: myrotvorets/set-commit-status-action@master
        with:
          sha: ${{ needs.prepare_vars.outputs.head_sha }}
          status: pending
          context: ${{ matrix.platform }}|ansible-${{ matrix.ansible_version }}
          description: Test started
          targetUrl: ""

      - name: Set commit status as success with a description that platform is skipped
        if: "!contains(needs.prepare_vars.outputs.supported_platforms, matrix.platform)"
        uses: myrotvorets/set-commit-status-action@master
        with:
          sha: ${{ needs.prepare_vars.outputs.head_sha }}
          status: success
          context: ${{ matrix.platform }}|ansible-${{ matrix.ansible_version }}
          description: The role does not support this platform. Skipping.
          targetUrl: ""

      - name: Run test in testing farm
        uses: sclorg/testing-farm-as-github-action@v4
        if: contains(needs.prepare_vars.outputs.supported_platforms, matrix.platform)
        with:
          git_ref: main
          pipeline_settings: '{ "type": "tmt-multihost" }'
          environment_settings: '{ "provisioning": { "tags": { "BusinessUnit": "system_roles" } } }'
          # Keeping SR_ARTIFACTS_URL at the bottom makes the link in logs clickable
          variables: "SR_ANSIBLE_VER=${{ matrix.ansible_version }};\
            SR_REPO_NAME=${{ github.event.repository.name }};\
            SR_GITHUB_ORG=${{ github.repository_owner }};\
            SR_PR_NUM=${{ github.event.issue.number }};\
            SR_ARTIFACTS_DIR=${{ steps.set_vars.outputs.ARTIFACTS_DIR }};\
            SR_TEST_LOCAL_CHANGES=false;\
            SR_LSR_USER=${{ vars.SR_LSR_USER }};\
            SR_ARTIFACTS_URL=${{ steps.set_vars.outputs.ARTIFACTS_URL }}"
          # Note that LINUXSYSTEMROLES_SSH_KEY must be single-line, TF doesn't read multi-line variables fine.
          secrets: "SR_LSR_DOMAIN=${{ secrets.SR_LSR_DOMAIN }};\
            SR_LSR_SSH_KEY=${{ secrets.SR_LSR_SSH_KEY }}"
          compose: ${{ matrix.platform }}
          # There are two blockers for using public ranch:
          # 1. multihost is not supported in public https://github.com/teemtee/tmt/issues/2620
          # 2. Security issue that leaks long secrets - Jira TFT-2698
          tf_scope: private
          api_key: ${{ secrets.TF_API_KEY_RH }}
          update_pull_request_status: false
          tmt_plan_filter: "tag:playbooks_parallel,ha_cluster"

      - name: Set final commit status
        uses: myrotvorets/set-commit-status-action@master
        if: always() && contains(needs.prepare_vars.outputs.supported_platforms, matrix.platform)
        with:
          sha: ${{ needs.prepare_vars.outputs.head_sha }}
          status: ${{ job.status }}
          context: ${{ matrix.platform }}|ansible-${{ matrix.ansible_version }}
          description: Test finished
          targetUrl: ${{ steps.set_vars.outputs.ARTIFACTS_URL }}
