---
name: Test
on:  # yamllint disable-line rule:truthy
  pull_request:
  merge_group:
    branches:
      - main
    types:
      - checks_requested
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  contents: read
  # This is required for the ability to create/update the Pull request status
  statuses: write
jobs:
  scenario:
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        scenario:
          # QEMU
          - { image: "centos-9", env: "qemu-ansible-core-2.16" }
          - { image: "centos-10", env: "qemu-ansible-core-2.17" }
          # ansible/libdnf5 bug: https://issues.redhat.com/browse/RHELMISC-10110
          # - { image: "fedora-41", env: "qemu-ansible-core-2.17" }
          - { image: "fedora-42", env: "qemu-ansible-core-2.19" }

          # container
          - { image: "centos-9", env: "container-ansible-core-2.16" }
          - { image: "centos-9-bootc", env: "container-ansible-core-2.16" }
          # broken on non-running dbus
          # - { image: "centos-10", env: "container-ansible-core-2.17" }
          - { image: "centos-10-bootc", env: "container-ansible-core-2.17" }
          - { image: "fedora-41", env: "container-ansible-core-2.17" }
          - { image: "fedora-42", env: "container-ansible-core-2.17" }
          - { image: "fedora-41-bootc", env: "container-ansible-core-2.17" }
          - { image: "fedora-42-bootc", env: "container-ansible-core-2.17" }

    env:
      TOX_ARGS: "--skip-tags tests::infiniband,tests::nvme,tests::scsi"

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

      - name: Check if platform is supported
        id: check_platform
        run: |
          set -euxo pipefail
          image="${{ matrix.scenario.image }}"
          image="${image%-bootc}"

          # convert image to tag formats
          platform=
          platform_version=
          case "$image" in
          centos-*) platform=el; platform_version=el"${image#centos-}" ;;
          fedora-*) platform=fedora; platform_version="${image/-/}" ;;
          esac
          supported=
          if yq -e '.galaxy_info.galaxy_tags[] | select(. == "'${platform_version}'" or . == "'${platform}'")' meta/main.yml; then
            supported=true
          fi

          # bootc build support (in buildah) has a separate flag
          if [ "${{ matrix.scenario.image }}" != "$image" ]; then
          if ! yq -e '.galaxy_info.galaxy_tags[] | select(. == "containerbuild")' meta/main.yml; then
              supported=
            fi
          else
            # roles need to opt into support for running in a system container
            env="${{ matrix.scenario.env }}"
            if [ "${env#container}" != "$env" ] &&
              ! yq -e '.galaxy_info.galaxy_tags[] | select(. == "container")' meta/main.yml; then
              supported=
            fi
          fi

          echo "supported=$supported" >> "$GITHUB_OUTPUT"

      - name: Set up /dev/kvm
        if: steps.check_platform.outputs.supported
        run: |
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm --settle
          ls -l /dev/kvm

      - name: Disable man-db to speed up package install
        if: steps.check_platform.outputs.supported
        run: |
          echo "set man-db/auto-update false" | sudo debconf-communicate
          sudo dpkg-reconfigure man-db

      - name: Install test dependencies
        if: steps.check_platform.outputs.supported
        run: |
          set -euxo pipefail
          python3 -m pip install --upgrade pip
          sudo apt update
          sudo apt install -y --no-install-recommends git ansible-core genisoimage qemu-system-x86
          pip3 install "git+https://github.com/linux-system-roles/tox-lsr@3.11.0"

      # HACK: Drop this when moving this workflow to 26.04 LTS
      - name: Update podman to 5.x for compatibility with bootc-image-builder's podman 5
        if: steps.check_platform.outputs.supported && endsWith(matrix.scenario.image, '-bootc')
        run: |
          sed 's/noble/plucky/g' /etc/apt/sources.list.d/ubuntu.sources | sudo tee /etc/apt/sources.list.d/plucky.sources >/dev/null
          cat <<EOF | sudo tee /etc/apt/preferences.d/podman.pref >/dev/null
          Package: podman buildah golang-github-containers-common crun libgpgme11t64 libgpg-error0 golang-github-containers-image catatonit conmon containers-storage
          Pin: release n=plucky
          Pin-Priority: 991

          Package: libsubid4 netavark passt aardvark-dns containernetworking-plugins libslirp0 slirp4netns
          Pin: release n=plucky
          Pin-Priority: 991

          Package: *
          Pin: release n=plucky
          Pin-Priority: 400
          EOF

          sudo apt update
          sudo apt install -y podman crun conmon containers-storage

      - name: Configure tox-lsr
        if: steps.check_platform.outputs.supported
        run: >-
          curl -o ~/.config/linux-system-roles.json
          https://raw.githubusercontent.com/linux-system-roles/linux-system-roles.github.io/master/download/linux-system-roles.json

      - name: Run qemu integration tests
        if: steps.check_platform.outputs.supported && startsWith(matrix.scenario.env, 'qemu')
        run: >-
          tox -e ${{ matrix.scenario.env }} -- --image-name ${{ matrix.scenario.image }} --make-batch
          --log-level debug $TOX_ARGS --skip-tags tests::bootc-e2e
          --lsr-report-errors-url DEFAULT --

      - name: Qemu result summary
        if: steps.check_platform.outputs.supported && startsWith(matrix.scenario.env, 'qemu') && always()
        run: |
          set -euo pipefail
          # some platforms may have setup/cleanup playbooks - need to find the
          # actual test playbook that starts with tests_
          while read code start end test_files; do
              for f in $test_files; do
                  test_file="$f"
                  f="$(basename $test_file)"
                  if [[ "$f" =~ ^tests_ ]]; then
                      break
                  fi
              done
              if [ "$code" = "0" ]; then
                  echo -n "PASS: "
                  mv "$test_file.log" "${test_file}-SUCCESS.log"
              else
                  echo -n "FAIL: "
                  mv "$test_file.log" "${test_file}-FAIL.log"
              fi
              echo "$f"
          done < batch.report

      - name: Run container tox integration tests
        if: steps.check_platform.outputs.supported && startsWith(matrix.scenario.env, 'container')
        run: |
          set -euo pipefail
          # HACK: debug.py/profile.py setup is broken
          export LSR_CONTAINER_PROFILE=false
          export LSR_CONTAINER_PRETTY=false
          rc=0
          for t in tests/tests_*.yml; do
              if tox -e ${{ matrix.scenario.env }} -- --image-name ${{ matrix.scenario.image }} $t > ${t}.log 2>&1; then
                  echo "PASS: $(basename $t)"
                  mv "${t}.log" "${t}-SUCCESS.log"
              else
                  echo "FAIL: $(basename $t)"
                  mv "${t}.log" "${t}-FAIL.log"
                  rc=1
              fi
          done
          exit $rc

      - name: Run bootc validation tests in QEMU
        if: steps.check_platform.outputs.supported &&
            startsWith(matrix.scenario.env, 'container') &&
            endsWith(matrix.scenario.image, '-bootc')
        run: |
          set -euxo pipefail
          env=$(echo "${{ matrix.scenario.env }}" | sed 's/^container-/qemu-/')

          for image_file in $(ls tests/tmp/*/qcow2/disk.qcow2 2>/dev/null); do
              test="tests/$(basename $(dirname $(dirname $image_file))).yml"
              if tox -e "$env" -- --image-file "$(pwd)/$image_file" \
                     --log-level debug $TOX_ARGS \
                     --lsr-report-errors-url DEFAULT \
                     -e __bootc_validation=true \
                     -- "$test" >out 2>&1; then
                  mv out "${test}-PASS.log"
              else
                  mv out "${test}-FAIL.log"
                  exit 1
              fi
          done

      - name: Upload test logs on failure
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: "logs-${{ matrix.scenario.image }}-${{ matrix.scenario.env }}"
          path: |
            tests/*.log
            artifacts/default_provisioners.log
            artifacts/*.qcow2.*.log
            batch.txt
            batch.report
          retention-days: 30

      - name: Show test log failures
        if: steps.check_platform.outputs.supported && failure()
        run: |
          set -euo pipefail
          # grab check_logs.py script
          curl -s -L -o check_logs.py https://raw.githubusercontent.com/linux-system-roles/auto-maintenance/refs/heads/main/check_logs.py
          chmod +x check_logs.py
          declare -a cmdline=(./check_logs.py --github-action-format)
          for log in tests/*-FAIL.log; do
              cmdline+=(--lsr-error-log "$log")
          done
          "${cmdline[@]}"

      - name: Set commit status as success with a description that platform is skipped
        if: ${{ steps.check_platform.outputs.supported == '' }}
        uses: myrotvorets/set-commit-status-action@master
        with:
          status: success
          context: "${{ github.workflow }} / scenario (${{ matrix.scenario.image }}, ${{ matrix.scenario.env }}) (pull_request)"
          description: The role does not support this platform. Skipping.
          targetUrl: ""
