name: CI

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
  schedule:
    - cron: '11 1 * * 0'

jobs:
  build:
    runs-on: ubuntu-latest

    services:
      kafka:
        # Docker Hub image
        image: bitnami/kafka:3.0
        env:
          ALLOW_PLAINTEXT_LISTENER: 'yes'
          KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: 'true'
          KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper:2181
        # Set health checks to wait until Kafka has started
        options: >-
          --health-cmd "kafka-broker-api-versions.sh --version"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

      zookeeper:
        image: bitnami/zookeeper:3.8
        env:
          ALLOW_ANONYMOUS_LOGIN: 'yes'
        # Set health checks to wait until Zookeeper has started
        options: >-
          --health-cmd "echo mntr | nc -w 2 -q 2 localhost 2181"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    env:
      CI: true
      KAFKA_HOST: kafka

    strategy:
      matrix:
        compiler:
          - clang
          - gcc
        container:
          - almalinux:8
          - alpine:3.14
          - ubuntu:18.04

    container: ${{ matrix.container }}

    steps:
      - name: Checkout ProFTPD
        uses: actions/checkout@v2
        with:
          repository: proftpd/proftpd
          path: proftpd

      - name: Checkout module source code
        uses: actions/checkout@v2
        with:
          path: proftpd/contrib/mod_kafka

      - name: Whitespace check
        if: ${{ matrix.container == 'ubuntu:18.04' }}
        run: |
          apt-get update -qq
          apt-get install -y git
          cd proftpd/contrib/mod_kafka
          if [[ -n $(git diff --check HEAD^) ]]; then
            echo "You must remove whitespace before submitting a pull request"
            echo ""
            git diff --check HEAD^
            exit 1
          fi

      - name: Install Alpine packages
        if: ${{ matrix.container == 'alpine:3.14' }}
        run: |
          apk update
          # for builds
          apk add bash build-base clang compiler-rt-static gcc make zlib-dev
          # for unit tests
          apk add check check-dev subunit subunit-dev
          # for Kafka support
          apk add librdkafka-dev
          # for debugging
          clang --version
          gcc --version

      - name: Install RPM packages
        if: ${{ matrix.container == 'almalinux:8' }}
        run: |
          # Need to add other repos for e.g. libsodium
          yum install -y dnf-plugins-core epel-release yum-utils clang gcc make zlib-devel
          dnf config-manager --enable epel
          dnf config-manager --set-enabled powertools
          # for unit tests
          yum install -y check-devel https://cbs.centos.org/kojifiles/packages/subunit/1.4.0/1.el8/x86_64/subunit-1.4.0-1.el8.x86_64.rpm https://cbs.centos.org/kojifiles/packages/subunit/1.4.0/1.el8/x86_64/subunit-devel-1.4.0-1.el8.x86_64.rpm
          # for Kafka support
          yum install -y librdkafka-devel

          # for debugging
          clang --version
          gcc --version

      - name: Install Ubuntu packages
        if: ${{ matrix.container == 'ubuntu:18.04' }}
        run: |
          apt-get update -qq
          # for builds
          apt-get install -y clang gcc make
          # for unit tests
          apt-get install -y check libsubunit-dev

          # for Kafka support
          apt-get install -y librdkafka-dev

          # for zlib support
          apt-get install -y zlib1g-dev

          # for integration/regression test
          apt-get install -y \
            libcompress-raw-zlib-perl \
            libdata-dumper-simple-perl \
            libdatetime-perl \
            libfile-copy-recursive-perl \
            libfile-path-tiny-perl \
            libfile-spec-native-perl \
            libjson-perl \
            libnet-ssh2-perl \
            libnet-ssleay-perl \
            libnet-telnet-perl \
            libposix-2008-perl \
            libtest-unit-perl \
            libtime-hr-perl \
            libwww-perl
          PERL_MM_USE_DEFAULT=1 perl -MCPAN -e "CPAN::Shell->notest('install', 'Gzip::Faster')"
          PERL_MM_USE_DEFAULT=1 perl -MCPAN -e "CPAN::Shell->notest('install', 'Kafka')"

          # for test code coverage
          apt-get install -y lcov ruby
          gem install coveralls-lcov
          # for HTML validation
          apt-get install -y tidy
          # for debugging
          clang --version
          gcc --version

      - name: Prepare code coverage
        if: ${{ matrix.container == 'ubuntu:18.04' }}
        run: |
          lcov --directory proftpd --zerocounters

      - name: Build as shared module
        env:
          CC: ${{ matrix.compiler }}
        run: |
          cd proftpd
          ./configure LIBS="-lm -lsubunit -lrt -pthread" --enable-devel=coverage --enable-dso --enable-tests --with-shared=mod_kafka
          make

      - name: Build as static module
        env:
          CC: ${{ matrix.compiler }}
        run: |
          cd proftpd
          make clean
          ./configure LIBS="-lm -lsubunit -lrt -pthread" --enable-devel=coverage --enable-tests --with-modules=mod_kafka
          make

      - name: Run unit tests
        env:
          CC: ${{ matrix.compiler }}
        # Note: Skip the unit tests on Alpine
        if: ${{ matrix.container != 'alpine:3.14' }}
        run: |
          cd proftpd/contrib/mod_kafka
          make TEST_VERBOSE=1 check

      - name: Install with static modules
        run: |
          cd proftpd
          make install

      - name: Run integration tests
        if: ${{ matrix.compiler == 'gcc' && matrix.container == 'ubuntu:18.04' }}
        env:
          PROFTPD_TEST_BIN: /usr/local/sbin/proftpd
          PROFTPD_TEST_DIR: ${{ github.workspace }}/proftpd
        run: |
          cd proftpd/contrib/mod_kafka
          perl tests.pl

      - name: Build with shared modules
        env:
          CC: ${{ matrix.compiler }}
        run: |
          cd proftpd
          make clean
          ./configure LIBS="-lm -lsubunit -lrt -pthread" --enable-devel --enable-dso --with-shared=mod_kafka
          make

      - name: Install with shared modules
        run: |
          cd proftpd
          make install

      - name: Check HTML docs
        if: ${{ matrix.container == 'ubuntu:18.04' }}
        run: |
          cd proftpd/contrib/mod_kafka
          for f in $(/bin/ls *.html); do echo "Processing $f"; tidy -errors -omit -q $f; done || exit 0
