name: Validation

# If a pull-request is pushed then cancel all previously running jobs related
# to that pull-request
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  cancel-in-progress: true

on:
  push:
    branches:
      - python-3
  pull_request:

jobs:
  validate-docs:
    runs-on: ubuntu-latest
    container:
      image: centos:7
      volumes:
        - /node20217:/node20217:rw,rshared
        - /node20217:/__e/node20:ro,rshared
    steps:
    - name: Fetch Node 20
      run: |
        curl -LO https://unofficial-builds.nodejs.org/download/release/v20.9.0/node-v20.9.0-linux-x64-glibc-217.tar.xz
        tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217
    - name: Fixup CentOS repo files
      run: |
        sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo
        sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo
        sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo

    - name: Install utils
      run: |
        yum install -y git wget ca-certificates
    - name: Fetch Beaker repository
      run: |
        wget https://beaker-project.org/yum/beaker-server-RedHatEnterpriseLinux.repo -P /etc/yum.repos.d/
    - uses: actions/checkout@v4
    - name: Install Beaker dependency from specfile
      run: |
        yum-builddep *.spec -y
    - name: Build documentation
      run: |
        make -C documentation html SPHINXOPTS="-W"
        mv documentation/_build/html /__w
    - uses: actions/upload-artifact@v4
      with:
        name: beaker-docs
        path: /home/runner/work/html

  integration-tests:
    runs-on: ubuntu-latest
    env:
      MYSQL_USER: beaker
      MYSQL_PASSWORD: beaker
      MYSQL_ROOT_PASSWORD: toor
    strategy:
      fail-fast: false
      matrix:
        test-target: ["bkr.inttest.client", "bkr.inttest.labcontroller", "bkr.inttest.server"]
    container:
      image: centos:7
      options: --init
      volumes:
        - /node20217:/node20217:rw,rshared
        - /node20217:/__e/node20:ro,rshared
    services:
      database:
        image: mariadb:10-ubi
        env:
          MYSQL_USER: ${{ env.MYSQL_USER }}
          MYSQL_PASSWORD: ${{ env.MYSQL_PASSWORD }}
          MYSQL_ROOT_PASSWORD: ${{ env.MYSQL_ROOT_PASSWORD }}
        ports:
          - 3306
    steps:
      - name: Fetch Node 20
        run: |
          curl -LO https://unofficial-builds.nodejs.org/download/release/v20.9.0/node-v20.9.0-linux-x64-glibc-217.tar.xz
          tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217
      - name: Fixup CentOS repo files
        run: |
          sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo
          sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo
          sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo

      # We have to install git 2.18+ to perform checkout via git
      # IUS is no longer maintained, use vault.ius.io for archived packages
      # EPEL 7 is also archived, fix repos to point to archive
      - name: Install git to allow checkout
        run: |
          yum install epel-release -y
          # Fix EPEL repos to use archive (EL7 is EOL)
          sed -i 's|^metalink=|#metalink=|g' /etc/yum.repos.d/epel*.repo
          sed -i 's|^#\?baseurl=.*|baseurl=https://archives.fedoraproject.org/pub/archive/epel/7/$basearch|g' /etc/yum.repos.d/epel*.repo
          cat > /etc/yum.repos.d/ius-vault.repo << 'EOF'
          [ius-vault]
          name=IUS Vault for Enterprise Linux 7 - $basearch
          baseurl=https://vault.ius.io/el7/$basearch/
          enabled=1
          gpgcheck=1
          gpgkey=https://vault.ius.io/RPM-GPG-KEY-IUS-7
          EOF
          yum install git236-core -y

      # Do not upgrade to @v4 as node 20 is incompatible with CentOS 7
      - name: Checkout
        uses: actions/checkout@v3

      # Remove custom git from the IUS repository - git will be reinstalled later as it is needed by beaker itself.
      - name: Remove git236 and YUM repositories
        run: |
          yum remove git236-core epel-release -y
          rm -f /etc/yum.repos.d/ius-vault.repo

      - name: Add Beaker Server YUM repository
        run: |
          curl -o /etc/yum.repos.d/beaker-server.repo https://beaker-project.org/yum/beaker-server-RedHatEnterpriseLinux.repo

      - name: Install Beaker dependencies
        run: |
          yum install epel-release -y
          # Fix EPEL repos to use archive (EL7 is EOL)
          sed -i 's|^metalink=|#metalink=|g' /etc/yum.repos.d/epel*.repo
          sed -i 's|^#\?baseurl=.*|baseurl=https://archives.fedoraproject.org/pub/archive/epel/7/$basearch|g' /etc/yum.repos.d/epel*.repo
          yum install mariadb beaker-integration-tests -y
          yum-builddep beaker.spec -y
          yum remove beaker-common \
              beaker-client \
              beaker-lab-controller \
              beaker-server \
              beaker-integration-tests -y

      - name: Checkout submodules
        run: |
          git submodule update --init --recursive

      - name: Configure database for testing
        run: |
          cat <<EOT > init.sql
          CREATE DATABASE beaker_test;
          CREATE DATABASE beaker_migration_test;
          GRANT ALL PRIVILEGES ON beaker_test.* TO 'beaker'@'%';
          GRANT ALL PRIVILEGES ON beaker_migration_test.* TO 'beaker'@'%';
          SET GLOBAL max_allowed_packet=1073741824;
          SET GLOBAL character_set_server=utf8;
          EOT

          mysql -uroot -p${{ env.MYSQL_ROOT_PASSWORD }} -h database < init.sql
          sed -i 's/@localhost/@database/g' IntegrationTests/server-test.cfg

      - name: Update version
        run: |
          # Update the version in common/__init__.py, as this file is used in the application and tests to determine the version
          current_version=$(grep -oE "__version__ = '[^']+'" Common/bkr/common/__init__.py | cut -d "'" -f 2)
          new_version="$current_version.git.$(git rev-parse --short HEAD)"
          sed -i "s/__version__ = '$current_version'/__version__ = '$new_version'/" Common/bkr/common/__init__.py

      - name: Run integration tests for ${{ matrix.test-target }}
        run: |
          pushd IntegrationTests
          # Disable Selenium tests until we have plan for selenium driver + firefox
          rm -rf src/bkr/inttest/server/selenium
          ./run-tests.sh -v ${{ matrix.test-target }}

  unit-tests:
    runs-on: ubuntu-latest
    container:
      image: ${{ matrix.os-target.name }}
      options: --init
      volumes:
        - /node20217:/node20217:rw,rshared
        - /node20217:/__e/node20:ro,rshared
    strategy:
      fail-fast: false
      matrix:
        test-target:
          - Common
          - Client
          - LabController
          - Server
        os-target:
          - name: centos:7
          - name: quay.io/fedora/fedora:rawhide
          - name: quay.io/fedora/fedora:44
          - name: quay.io/fedora/fedora:43
          - name: quay.io/fedora/fedora:42
          - name: quay.io/centos/centos:stream9
            additional_repos: "crb"
            additional_packages: "epel-release"
          - name: quay.io/centos/centos:stream10
            additional_repos: "crb"
            additional_packages: "epel-release"
        exclude:
          - test-target: Server
            os-target:
              name: quay.io/fedora/fedora:rawhide
          - test-target: Server
            os-target:
              name: quay.io/fedora/fedora:44
          - test-target: Server
            os-target:
              name: quay.io/fedora/fedora:43
          - test-target: Server
            os-target:
              name: quay.io/fedora/fedora:42
          - test-target: Server
            os-target:
              name: quay.io/centos/centos:stream9
          - test-target: Server
            os-target:
              name: quay.io/centos/centos:stream10
          - test-target: LabController
            os-target:
              name: quay.io/fedora/fedora:rawhide
          - test-target: LabController
            os-target:
              name: quay.io/fedora/fedora:44
          - test-target: LabController
            os-target:
              name: quay.io/fedora/fedora:43
          - test-target: LabController
            os-target:
              name: quay.io/fedora/fedora:42
          - test-target: LabController
            os-target:
              name: quay.io/centos/centos:stream9
          - test-target: LabController
            os-target:
              name: quay.io/centos/centos:stream10
    steps:
      - name: Fixup CentOS repo files
        if: matrix.os-target.name == 'centos:7'
        run: |
          sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo
          sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo
          sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo
      - name: Fetch Node 20
        run: |
          yum install xz -y
          curl -LO https://unofficial-builds.nodejs.org/download/release/v20.9.0/node-v20.9.0-linux-x64-glibc-217.tar.xz
          tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217
      - name: Set BKR_PY3 environment variable
        run: echo "BKR_PY3=1" >> $GITHUB_ENV
        if: matrix.os-target.name != 'centos:7'

      - name: Install DNF and plugins
        run: yum install -y dnf 'dnf-command(builddep)' 'dnf-command(config-manager)'

      - name: Enable additional repositories
        run: |
          IFS=', ' read -r -a repos <<< "${{ matrix.os-target.additional_repos }}"
          for repo in "${repos[@]}"; do
            dnf config-manager --set-enabled $repo
          done
      - name: Install additional packages
        run: |
          IFS=', ' read -r -a packages <<< "${{ matrix.os-target.additional_packages }}"
          for package in "${packages[@]}"; do
            dnf install -y $package
          done

      # Do not upgrade to @v4 as node 20 is incompatible with CentOS 7
      - name: Checkout
        uses: actions/checkout@v3

      - name: Add Beaker Server YUM repository
        if: matrix.os-target.name == 'centos:7'
        run: |
          curl -o /etc/yum.repos.d/beaker-server.repo https://beaker-project.org/yum/beaker-server-RedHatEnterpriseLinux.repo
      # Build dependencies must be sufficient, the same is done during RPM build
      - name: Install Beaker dependency from specfile
        run: |
          dnf builddep -y *.spec
      - name: Run unit tests
        run: |
          pushd ${{ matrix.test-target }}
          ./run-tests.sh
