# SPDX-License-Identifier: LGPL-2.1-only
#
# Continuous Integration Workflow for libcgroup
#
# Copyright (c) 2020-2021 Oracle and/or its affiliates.
# Author: Tom Hromatka <tom.hromatka@oracle.com>
#

name: Continuous Integration
on: ["push", "pull_request"]

jobs:
  # Doc: https://github.com/redhat-plumbers-in-action/differential-shellcheck#usage
  differential-shellcheck:
    name: Differential ShellCheck
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest

    permissions:
      contents: read
      security-events: write
      pull-requests: write

    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Differential ShellCheck
        uses: redhat-plumbers-in-action/differential-shellcheck@v4
        with:
          severity: warning
          token: ${{ secrets.GITHUB_TOKEN }}

  flake8-lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - name: Check out source repository
        uses: actions/checkout@v3
      - name: Set up Python environment
        uses: actions/setup-python@v4
        with:
          python-version: "3.8"
      - name: flake8 Lint
        uses: reviewdog/action-flake8@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}

  doxygen:
    name: Doxygen
    # Only run Doxygen against the main branch
    if: github.ref_name == 'main'
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: false
    - uses: mattnotmitt/doxygen-action@v1
      with:
        working-directory: "./"
        doxyfile-path: "./doc/Doxygen"
    - name: Move the Doxygen Files
      run: sudo mv ./html doc/
    - name: Deploy Doxygen
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./doc/html
        publish_branch: doxygen/${{ github.ref_name }}

  unittests:
    name: Unit Tests
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: false
    - name: Initialize the directory
      uses: ./.github/actions/setup-libcgroup
    - name: Run unit tests
      run: |
        pushd tests/gunit
        make check
        popd
    - name: Display test logs
      if: ${{ always() }}
      run: cat tests/gunit/test-suite.log
    - name: Collate code coverage results
      uses: ./.github/actions/code-coverage
    - name: Upload code coverage results
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        path-to-lcov: ./lcov.total
        flag-name: "Unit Tests"
        parallel: True
    - name: Archive code coverage results
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Unit Test Code Coverage
        path: lcov.*

  distcheckv1:
    name: Cgroup v1 Dist Check
    runs-on: ubuntu-20.04

    steps:
    - name: Install container dependencies
      run: |
        sudo apt-get update
        sudo apt-get install lxc lxd-installer
    - uses: actions/checkout@v3
      with:
        submodules: false
    - name: Initialize the directory
      uses: ./.github/actions/setup-libcgroup
    - name: Run make distcheck
      run: make distcheck
    - name: Display test logs
      if: ${{ failure() }}
      run: |
        cat libcgroup-*/_build/sub/tests/ftests/ftests-wrapper.sh.log

  buildtests:
    name: Build tests
    runs-on: ubuntu-20.04

    steps:
    - name: Install dependencies
      run: |
        sudo apt-get update
    - uses: actions/checkout@v3
      with:
        submodules: false
    - name: Initialize the directory
      uses: ./.github/actions/setup-libcgroup
    - name: Reconfigure libcgroup with systemd disabled
      run: CFLAGS="$CFLAGS -Werror" ./configure --sysconfdir=/etc --localstatedir=/var --enable-code-coverage --enable-opaque-hierarchy="name=systemd" --enable-python --enable-systemd=no
    - name: Build the library
      run: make
    - name: Reconfigure libcgroup with samples enabled
      run: CFLAGS="$CFLAGS -Werror" ./configure --sysconfdir=/etc --localstatedir=/var --enable-code-coverage --enable-opaque-hierarchy="name=systemd" --enable-python --enable-samples
    - name: Build the library
      run: make
    - name: Reconfigure libcgroup with systemd disabled and samples enabled
      run: CFLAGS="$CFLAGS -Werror" ./configure --sysconfdir=/etc --localstatedir=/var --enable-code-coverage --enable-opaque-hierarchy="name=systemd" --enable-python --enable-systemd=no --enable-samples
    - name: Build the library
      run: make

  functionaltestsv1:
    name: Cgroup v1 Functional Tests
    runs-on: ubuntu-20.04

    steps:
    - name: Install container dependencies
      run: |
        sudo apt-get update
        sudo apt-get install lxc lxd-installer
    - uses: actions/checkout@v3
      with:
        submodules: false
    - name: Initialize the directory
      uses: ./.github/actions/setup-libcgroup
    - name: Run functional tests
      run: |
        # The cgroup v1 runner hosted by Github Actions doesn't allow
        # for exclusive cpusets.  Thus, skip the cpuset automated test
        pushd src/python/build/lib.*
        export PYTHONPATH=$PYTHONPATH:$(pwd)
        popd
        pushd tests/ftests
        ./ftests.py -l 10 -L ftests.log
        ./ftests.py -l 10 -L ftests-nocontainer.log --skip 38 --no-container
        popd
    - name: Archive test logs
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Cgroup v1 test logs
        path: ./*.log
    - name: Collate code coverage results
      uses: ./.github/actions/code-coverage
    - name: Upload code coverage results
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        path-to-lcov: ./lcov.total
        flag-name: "Cgroup v1 Functional Tests"
        parallel: True
    - name: Archive code coverage results
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Cgroup v1 Code Coverage
        path: lcov.*

  functionaltestsv1v2:
    name: Cgroup v1/v2 Functional Tests
    runs-on: ubuntu-20.04

    steps:
    - name: Mount cpuset cgroup v2 controller
      run: |
        # unmount the cpuset v1 controller.  This should make it available
        # in the v2 hierarchy after all references have been freed
        sudo umount /sys/fs/cgroup/cpuset
        # wait for the references to the cpuset controller to go away
        sleep 30
        cat /sys/fs/cgroup/unified/cgroup.controllers
        sudo su -c "echo +cpuset > /sys/fs/cgroup/unified/cgroup.subtree_control"
        cat /sys/fs/cgroup/unified/cgroup.subtree_control
    - name: Install container dependencies
      run: |
        sudo apt-get update
        sudo apt-get install lxc lxd-installer
    - uses: actions/checkout@v3
      with:
        submodules: false
    - name: Initialize the directory
      uses: ./.github/actions/setup-libcgroup
    - name: Run functional tests
      run: |
        pushd src/python/build/lib.*
        export PYTHONPATH=$PYTHONPATH:$(pwd)
        popd
        pushd tests/ftests
        make check
        popd
    - name: Display test logs
      if: ${{ always() }}
      run: |
        cat tests/ftests/ftests-wrapper.sh.log
    - name: Archive test logs
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Cgroup v1v2 test logs
        path: tests/ftests/*.log
    - name: Collate code coverage results
      uses: ./.github/actions/code-coverage
    - name: Upload code coverage results
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        path-to-lcov: ./lcov.total
        flag-name: "Cgroup v1/v2 Functional Tests"
        parallel: True
    - name: Archive code coverage results
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Cgroup v1v2 Code Coverage
        path: lcov.*

  functionaltestsv2_legacy:
    name: Cgroup v2 Functional Tests - legacy
    runs-on: cgroup-legacy

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: false
    - name: Initialize the directory
      uses: ./.github/actions/setup-libcgroup
    - name: Run functional tests
      run: |
        pushd src/python/build/lib.*
        export PYTHONPATH=$PYTHONPATH:$(pwd)
        popd
        pushd tests/ftests
        make check
        popd
    - name: Display test logs
      if: ${{ always() }}
      run: |
        cat tests/ftests/ftests-wrapper.sh.log
    - name: Archive test logs
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Cgroup v2 test logs - legacy
        path: tests/ftests/*.log
    - name: Collate code coverage results
      uses: ./.github/actions/code-coverage
    - name: Upload code coverage results
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        path-to-lcov: ./lcov.total
        flag-name: "Cgroup v2 Functional Tests - legacy"
        parallel: True
    - name: Archive code coverage results
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Cgroup v2 Code Coverage - legacy
        path: lcov.*

  functionaltestsv2_hybrid:
    name: Cgroup v2 Functional Tests - hybrid
    runs-on: cgroup-hybrid

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: false
    - name: Initialize the directory
      uses: ./.github/actions/setup-libcgroup
    - name: Run functional tests
      run: |
        pushd src/python/build/lib.*
        export PYTHONPATH=$PYTHONPATH:$(pwd)
        popd
        pushd tests/ftests
        make check
        popd
    - name: Display test logs
      if: ${{ always() }}
      run: |
        cat tests/ftests/ftests-wrapper.sh.log
    - name: Archive test logs
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Cgroup v2 test logs - hybrid
        path: tests/ftests/*.log
    - name: Collate code coverage results
      uses: ./.github/actions/code-coverage
    - name: Upload code coverage results
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        path-to-lcov: ./lcov.total
        flag-name: "Cgroup v2 Functional Tests - hybrid"
        parallel: True
    - name: Archive code coverage results
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Cgroup v2 Code Coverage - hybrid
        path: lcov.*

  functionaltestsv2_unified:
    name: Cgroup v2 Functional Tests - unified
    runs-on: cgroup-unified

    steps:
    - uses: actions/checkout@v3
      with:
        submodules: false
    - name: Initialize the directory
      uses: ./.github/actions/setup-libcgroup
    - name: Run functional tests
      run: |
        pushd src/python/build/lib.*
        export PYTHONPATH=$PYTHONPATH:$(pwd)
        popd
        pushd tests/ftests
        make check
        popd
    - name: Display test logs
      if: ${{ always() }}
      run: |
        cat tests/ftests/ftests-wrapper.sh.log
    - name: Archive test logs
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Cgroup v2 test logs - unified
        path: tests/ftests/*.log
    - name: Collate code coverage results
      uses: ./.github/actions/code-coverage
    - name: Upload code coverage results
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        path-to-lcov: ./lcov.total
        flag-name: "Cgroup v2 Functional Tests - unified"
        parallel: True
    - name: Archive code coverage results
      if: ${{ always() }}
      uses: actions/upload-artifact@v3
      with:
        name: Cgroup v2 Code Coverage - unified
        path: lcov.*

  finalize:
    name: Finalize the test run
    if: ${{ always() }}
    needs: [unittests, functionaltestsv1, functionaltestsv1v2, functionaltestsv2_legacy,
            functionaltestsv2_hybrid, functionaltestsv2_unified]
    runs-on: ubuntu-latest
    steps:
    - name: Finalize code coverage results
      uses: coverallsapp/github-action@master
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        parallel-finished: True
