name: zfs-qemu

on:
  push:
  pull_request:
  workflow_dispatch:
    inputs:
      fedora_kernel_ver:
        type: string
        required: false
        default: ""
        description: "(optional) Experimental kernel version to install on Fedora (like '6.14' or '6.13.3-0.rc3')"
      specific_os:
        type: string
        required: false
        default: ""
        description: "(optional) Only run on this specific OS (like 'fedora42' or 'alpine3-23')"

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

jobs:
  test-config:
    name: Setup
    runs-on: ubuntu-24.04
    outputs:
      test_os: ${{ steps.os.outputs.os }}
      ci_type: ${{ steps.os.outputs.ci_type }}
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - name: Generate OS config and CI type
        id: os
        run: |
          ci_type="default"
          ci_source="auto"

          # determine CI type when running on PR
          if ${{ github.event_name == 'pull_request' }}; then
            head=${{ github.event.pull_request.head.sha }}
            base=${{ github.event.pull_request.base.sha }}
            read ci_type ci_source <<< "$(python3 .github/workflows/scripts/generate-ci-type.py $head $base)"
          fi

          case "$ci_type" in
          quick)
            os_selection='["almalinux8", "almalinux9", "almalinux10", "debian12", "fedora42", "freebsd15-1s", "ubuntu24"]'
            ;;
          linux)
            os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian11", "debian12", "debian13", "fedora42", "fedora43", "fedora44", "ubuntu22", "ubuntu24"]'
            ;;
          freebsd)
            os_selection='["freebsd13-5r", "freebsd14-4r", "freebsd13-5s", "freebsd14-4s", "freebsd15-1s", "freebsd16-0c"]'
            ;;
          *)
            # default list
            os_selection='["almalinux8", "almalinux9", "almalinux10", "centos-stream9", "centos-stream10", "debian12", "debian13", "fedora42", "fedora43", "fedora44", "freebsd14-4r", "freebsd15-1s", "freebsd16-0c", "ubuntu22", "ubuntu24"]'
            ;;
          esac

          # Repository-level override for OS selection.
          # Set vars.ZTS_OS_OVERRIDE in repo settings to restrict targets
          # (e.g. '["debian13"]' or '["debian13", "fedora42"]').
          # Manual ZFS-CI-Type in commit messages bypasses the override.
          if [ -n "${{ vars.ZTS_OS_OVERRIDE }}" ] && [ "$ci_source" != "manual" ]; then
            override='${{ vars.ZTS_OS_OVERRIDE }}'
            if echo "$override" | jq -e 'type == "array"' >/dev/null 2>&1; then
              os_selection="$override"
            else
              echo "::warning::Invalid ZTS_OS_OVERRIDE, using default"
            fi
          fi

          if ${{ github.event.inputs.fedora_kernel_ver != '' }}; then
              # They specified a custom kernel version for Fedora.
              # Use only Fedora runners.
              os_json=$(echo ${os_selection} | jq -c '[.[] | select(startswith("fedora"))]')
          elif ${{ github.event.inputs.specific_os != '' }}; then
              # Use only the specified runner.
              os_json=$(jq -cn --arg os "${{ github.event.inputs.specific_os }}" '[ $os ]')
          else
              # Normal case
              os_json=$(echo ${os_selection} | jq -c)
          fi

          echo "os=$os_json" | tee -a $GITHUB_OUTPUT
          echo "ci_type=$ci_type" | tee -a $GITHUB_OUTPUT

  qemu-vm:
    name: qemu-x86
    needs: [ test-config ]
    strategy:
      fail-fast: false
      matrix:
        # rhl:     almalinux8, almalinux9, centos-streamX, fedora4x
        # debian:  debian12, debian13, ubuntu22, ubuntu24
        # misc:    archlinux, tumbleweed
        # FreeBSD variants of november 2025:
        # FreeBSD Release: freebsd13-5r, freebsd14-4r, freebsd15-0r
        # FreeBSD Stable:  freebsd13-5s, freebsd14-4s, freebsd15-1s
        # FreeBSD Current: freebsd16-0c
        os: ${{ fromJson(needs.test-config.outputs.test_os) }}
    runs-on: ubuntu-24.04
    steps:
    - uses: actions/checkout@v6
      with:
        ref: ${{ github.event.pull_request.head.sha }}

    - name: Setup QEMU
      timeout-minutes: 60
      run: .github/workflows/scripts/qemu-1-setup.sh

    - name: Start build machine
      timeout-minutes: 10
      run: .github/workflows/scripts/qemu-2-start.sh ${{ matrix.os }}

    - name: Install dependencies
      timeout-minutes: 60
      run: .github/workflows/scripts/qemu-3-deps.sh --poweroff ${{ matrix.os }} ${{ github.event.inputs.fedora_kernel_ver }}

    - name: Build modules
      timeout-minutes: 30
      run: .github/workflows/scripts/qemu-4-build.sh --poweroff --enable-debug ${{ matrix.os }}

    - name: Setup testing machines
      timeout-minutes: 5
      run: .github/workflows/scripts/qemu-5-setup.sh

    - name: Run tests
      timeout-minutes: 270
      run: .github/workflows/scripts/qemu-6-tests.sh
      env:
        CI_TYPE: ${{ needs.test-config.outputs.ci_type }}

    - name: Prepare artifacts
      if: always()
      timeout-minutes: 10
      run: .github/workflows/scripts/qemu-7-prepare.sh

    - uses: actions/upload-artifact@v7
      id: artifact-upload
      if: always()
      with:
        name: Logs-functional-${{ matrix.os }}
        path: /tmp/qemu-${{ matrix.os }}.tar.bz2
        archive: false
        if-no-files-found: ignore

    - name: Test Summary
      if: always()
      run: .github/workflows/scripts/qemu-8-summary.sh '${{ steps.artifact-upload.outputs.artifact-url }}'

  cleanup:
    if: always()
    name: Cleanup
    runs-on: ubuntu-latest
    needs: [ qemu-vm ]

    steps:
    - uses: actions/checkout@v6
      with:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: actions/download-artifact@v8
    - name: Generating summary
      run: .github/workflows/scripts/qemu-9-summary-page.sh
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 2
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 3
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 4
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 5
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 6
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 7
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 8
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 9
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 10
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 11
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 12
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 13
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 14
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 15
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 16
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 17
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 18
    - name: Generating summary...
      run: .github/workflows/scripts/qemu-9-summary-page.sh 19
    - uses: actions/upload-artifact@v7
      with:
        name: Summary Files
        path: out-*
        archive: true
