name: Validate Fedora x86_64-v3 Copr SRPMs

on:
  workflow_dispatch:
    inputs:
      package_input:
        description: "Optional comma, space, or newline separated package list. Leave blank to use packages.txt."
        required: false
        default: ""
        type: string
      copr_project:
        description: "Optional Copr project in owner/project form for syncing SCM package definitions."
        required: false
        default: ""
        type: string
      submit_to_copr:
        description: "Sync package definitions to Copr after validation."
        required: false
        default: false
        type: boolean
      submit_package_builds:
        description: "Queue package builds after the x86_64-v3 macro package build succeeds."
        required: false
        default: false
        type: boolean
  push:
    paths:
      - '.copr/Makefile'
      - '.github/workflows/build-v3-rpms.yml'
      - 'ci/copr-distgit-make-srpm.py'
      - 'ci/prefetch-fedora-specs.py'
      - 'ci/sync-copr-packages.py'
      - 'packages.txt'
      - 'packaging/copr-rpm-macros-x86-64-v3.spec'
      - 'SPECS/**'

permissions:
  contents: read

jobs:
  prepare:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.select.outputs.matrix }}
      package_count: ${{ steps.select.outputs.package_count }}
    steps:
      - uses: actions/checkout@v4

      - id: select
        env:
          PACKAGE_INPUT: ${{ inputs.package_input }}
        run: |
          python3 <<'PY'
          import json
          import os
          import re
          from pathlib import Path

          packages_file = Path("packages.txt")
          package_input = os.environ.get("PACKAGE_INPUT", "")
          if not package_input.strip() and not packages_file.exists():
              print("::error::packages.txt not found")
              raise SystemExit(1)

          if package_input.strip():
              packages = [
                  entry
                  for entry in re.split(r"[\s,]+", package_input.strip())
                  if entry
              ]
          else:
              packages = [
                  line.strip()
                  for line in packages_file.read_text(encoding="utf-8").splitlines()
                  if line.strip() and not line.startswith("#")
              ]

          max_matrix = 128
          matrix = []
          if packages:
              shard_size = max(1, -(-len(packages) // max_matrix))
              shards = [
                  packages[index:index + shard_size]
                  for index in range(0, len(packages), shard_size)
              ]
              matrix = [
                  {
                      "shard": shard_index + 1,
                      "shard_label": f"{shard_index + 1:03d}",
                      "packages": shard,
                  }
                  for shard_index, shard in enumerate(shards)
              ]

          with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as handle:
              handle.write(f"matrix={json.dumps(matrix)}\n")
              handle.write(f"package_count={len(packages)}\n")
          PY

  validate-srpms:
    needs: prepare
    if: ${{ needs.prepare.outputs.package_count != '0' }}
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/funkemunky/kde-x86_64-v4-fedora-rpm-builder:latest
    strategy:
      fail-fast: false
      matrix:
        include: ${{ fromJSON(needs.prepare.outputs.matrix) }}
    steps:
      - uses: actions/checkout@v4

      - name: Install SRPM validation tools
        run: |
          dnf -y install git make python3 rpm-build ca-certificates curl

      - name: Generate shard SRPMs
        env:
          PACKAGES_JSON: ${{ toJSON(matrix.packages) }}
          SHARD_LABEL: ${{ matrix.shard_label }}
        run: |
          python3 <<'PY'
          import json
          import os
          import subprocess
          from pathlib import Path

          workspace = Path(os.environ["GITHUB_WORKSPACE"])
          shard_label = os.environ.get("SHARD_LABEL") or "000"
          packages = json.loads(os.environ.get("PACKAGES_JSON") or "[]")
          if packages is None:
              packages = []

          outdir = workspace / "artifacts" / f"srpm-shard-{shard_label}"
          outdir.mkdir(parents=True, exist_ok=True)

          subprocess.run(
              [
                  "make",
                  "-f",
                  ".copr/Makefile",
                  "srpm",
                  f"outdir={outdir}",
                  "spec=packaging/copr-rpm-macros-x86-64-v3.spec",
              ],
              check=True,
              cwd=workspace,
          )

          for package_name in packages:
              subprocess.run(
                  [
                      "make",
                      "-f",
                      ".copr/Makefile",
                      "srpm",
                      f"outdir={outdir}",
                      f"spec={package_name}",
                  ],
                  check=True,
                  cwd=workspace,
              )
          PY

      - name: Upload SRPM artifacts
        uses: actions/upload-artifact@v4
        with:
          name: srpm-shard-${{ matrix.shard_label }}
          path: artifacts/srpm-shard-${{ matrix.shard_label }}/
          if-no-files-found: error

  sync-copr:
    needs:
      - prepare
      - validate-srpms
    if: ${{ github.event_name == 'workflow_dispatch' && inputs.submit_to_copr && inputs.copr_project != '' }}
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/funkemunky/kde-x86_64-v4-fedora-rpm-builder:latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Copr sync tools
        run: |
          dnf -y install copr-cli git make python3 rpm-build ca-certificates curl

      - name: Configure copr-cli
        env:
          COPR_CONFIG: ${{ secrets.COPR_CONFIG }}
        run: |
          test -n "${COPR_CONFIG}"
          mkdir -p ~/.config
          printf '%s\n' "${COPR_CONFIG}" > ~/.config/copr
          chmod 0600 ~/.config/copr

      - name: Sync Copr SCM package definitions
        env:
          COPR_PROJECT: ${{ inputs.copr_project }}
          PACKAGE_INPUT: ${{ inputs.package_input }}
          SUBMIT_PACKAGE_BUILDS: ${{ inputs.submit_package_builds }}
        run: |
          set -euo pipefail
          ARGS=(
            --project "${COPR_PROJECT}"
            --clone-url "https://github.com/${GITHUB_REPOSITORY}.git"
            --commit "${GITHUB_SHA}"
            --package-input "${PACKAGE_INPUT}"
            --submit-macro-build
          )
          if [ "${SUBMIT_PACKAGE_BUILDS}" = "true" ]; then
            ARGS+=(--submit-package-builds --nowait-package-builds)
          fi
          python3 ci/sync-copr-packages.py "${ARGS[@]}"
