name: Runtime

on:
  push:
    paths:
    - '*'
    - '!*.md'
    - '.github/workflows/runtime.yml'
    - 'checkouts/**'
    - 'config/**'
    - 'lib/**'
    - 'm4/**'
    - 'plugins/**'
    - 'rel/**'
  pull_request:
    paths:
    - '*'
    - '!*.md'
    - '.github/workflows/runtime.yml'
    - 'checkouts/**'
    - 'config/**'
    - 'lib/**'
    - 'm4/**'
    - 'plugins/**'
    - 'rel/**'

jobs:

  rebars:
    name: Rebars
    strategy:
      fail-fast: false
      matrix:
        otp: ['20', '25', '26', '27']
        rebar: ['rebar', 'rebar3']
        exclude:
        - otp: '27'
          rebar: 'rebar'
    runs-on: ubuntu-24.04
    container:
      image: erlang:${{ matrix.otp }}

    steps:

    - uses: actions/checkout@v4

    - name: Get compatible Rebar binaries
      if: matrix.otp < 24
      run: |
        rm rebar
        rm rebar3
        wget https://github.com/processone/ejabberd/raw/21.12/rebar
        wget https://github.com/processone/ejabberd/raw/21.12/rebar3
        chmod +x rebar
        chmod +x rebar3

    - name: Prepare libraries
      run: |
        apt-get -qq update
        apt-get purge -y libgd3 nginx
        apt-get -qq install libexpat1-dev libgd-dev libpam0g-dev \
                            libsqlite3-dev libwebp-dev libyaml-dev

    - name: Cache Hex.pm
      uses: actions/cache@v4
      with:
        path: |
          ~/.cache/rebar3/
        key: ${{matrix.otp}}-${{hashFiles('rebar.config')}}

    - name: Get compatible Rebar binaries
      if: matrix.rebar == 'rebar3' && matrix.otp < 21
      run: rebar3 unlock eredis

    - name: Compile
      run: |
        ./autogen.sh
        ./configure --with-rebar=./${{ matrix.rebar }} \
                    --prefix=/tmp/ejabberd \
                    --enable-all \
                    --disable-elixir \
                    --disable-tools \
                    --disable-odbc
        make

    - run: make xref

    - run: make dialyzer

    - name: Prepare rel (rebar2)
      if: matrix.rebar == 'rebar'
      run: |
        mkdir -p _build/prod && ln -s `pwd`/rel/ _build/prod/rel
        mkdir -p _build/dev  && ln -s `pwd`/rel/ _build/dev/rel

    - name: Run rel
      run: |
        make rel
        _build/prod/rel/ejabberd/bin/ejabberdctl start \
          && _build/prod/rel/ejabberd/bin/ejabberdctl started
        _build/prod/rel/ejabberd/bin/ejabberdctl register user1 localhost s0mePass
        _build/prod/rel/ejabberd/bin/ejabberdctl registered_users localhost > registered.log
        _build/prod/rel/ejabberd/bin/ejabberdctl stop \
          && _build/prod/rel/ejabberd/bin/ejabberdctl stopped

    - name: Run dev
      run: |
        make dev
        _build/dev/rel/ejabberd/bin/ejabberdctl start \
          && _build/dev/rel/ejabberd/bin/ejabberdctl started
        _build/dev/rel/ejabberd/bin/ejabberdctl register user2 localhost s0mePass
        _build/dev/rel/ejabberd/bin/ejabberdctl registered_users localhost >> registered.log
        _build/dev/rel/ejabberd/bin/ejabberdctl stop \
          && _build/dev/rel/ejabberd/bin/ejabberdctl stopped

    - name: Run install
      run: |
        make install
        /tmp/ejabberd/sbin/ejabberdctl start \
          && /tmp/ejabberd/sbin/ejabberdctl started
        /tmp/ejabberd/sbin/ejabberdctl register user3 localhost s0mePass
        /tmp/ejabberd/sbin/ejabberdctl registered_users localhost >> registered.log
        /tmp/ejabberd/sbin/ejabberdctl stop \
          && /tmp/ejabberd/sbin/ejabberdctl stopped

    - name: View logs
      run: |
        echo "===> Registered:"
        cat registered.log
        echo "===> Prod:"
        cat _build/prod/rel/ejabberd/logs/*
        echo "===> Dev:"
        cat _build/dev/rel/ejabberd/logs/*
        echo "===> Install:"
        cat /tmp/ejabberd/var/log/ejabberd/*

    - name: Check logs
      run: |
        grep -q '^user1$' registered.log
        grep -q '^user2$' registered.log
        grep -q '^user3$' registered.log
        grep -q 'is started' _build/prod/rel/ejabberd/logs/ejabberd.log
        grep -q 'is stopped' _build/prod/rel/ejabberd/logs/ejabberd.log
        test $(find _build/prod/rel/ -empty -name error.log)
        grep -q 'is started' _build/dev/rel/ejabberd/logs/ejabberd.log
        grep -q 'is stopped' _build/dev/rel/ejabberd/logs/ejabberd.log
        test $(find _build/dev/rel/ -empty -name error.log)
        grep -q 'is started' /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        grep -q 'is stopped' /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        test $(find /tmp/ejabberd/var/log/ejabberd/ -empty -name error.log)

    - name: View logs failures
      if: always()
      run: |
        cat _build/prod/rel/ejabberd/logs/ejabberd.log
        cat _build/prod/rel/ejabberd/logs/error.log
        cat _build/dev/rel/ejabberd/logs/ejabberd.log
        cat _build/dev/rel/ejabberd/logs/error.log
        cat /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        cat /tmp/ejabberd/var/log/ejabberd/error.log

  rebar3-elixir:
    name: Rebar3+Elixir
    strategy:
      fail-fast: false
      matrix:
        elixir: ['1.13', '1.14', '1.15', '1.16', '1.17']
    runs-on: ubuntu-24.04
    container:
      image: elixir:${{ matrix.elixir }}

    steps:

    - uses: actions/checkout@v4

    - name: Prepare libraries
      run: |
        apt-get -qq update
        apt-get -y purge libgd3 nginx
        apt-get -qq install libexpat1-dev libgd-dev libpam0g-dev \
                            libsqlite3-dev libwebp-dev libyaml-dev

    - name: Enable Module.Example and an Elixir dependency
      run: |
        sed -i "s|^modules:|modules:\n  'Ejabberd.Module.Example': {}|g" ejabberd.yml.example
        cat ejabberd.yml.example
        sed -i 's|^{deps, \[\(.*\)|{deps, [{decimal, ".*", {git, "https://github.com/ericmj/decimal", {branch, "main"}}},\n \1|g' rebar.config
        cat rebar.config

    - name: Cache Hex.pm
      uses: actions/cache@v4
      with:
        path: |
          ~/.cache/rebar3/
        key: ${{matrix.elixir}}-${{hashFiles('rebar.config')}}

    - name: Install Hex and Rebar3 manually on older Elixir
      if: matrix.elixir <= '1.14'
      run: |
        mix local.hex --force
        mix local.rebar --force

    - name: Compile
      run: |
        ./autogen.sh
        ./configure --with-rebar=./rebar3 \
                    --prefix=/tmp/ejabberd \
                    --enable-all \
                    --disable-odbc
        make

    - run: make xref

    - name: Run rel
      run: |
        make rel
        _build/prod/rel/ejabberd/bin/ejabberdctl start \
          && _build/prod/rel/ejabberd/bin/ejabberdctl started
        _build/prod/rel/ejabberd/bin/ejabberdctl register user1 localhost s0mePass
        _build/prod/rel/ejabberd/bin/ejabberdctl registered_users localhost > registered.log
        _build/prod/rel/ejabberd/bin/ejabberdctl stop \
          && _build/prod/rel/ejabberd/bin/ejabberdctl stopped

    - name: Run dev
      run: |
        make dev
        _build/dev/rel/ejabberd/bin/ejabberdctl start \
          && _build/dev/rel/ejabberd/bin/ejabberdctl started
        _build/dev/rel/ejabberd/bin/ejabberdctl register user2 localhost s0mePass
        _build/dev/rel/ejabberd/bin/ejabberdctl registered_users localhost >> registered.log
        _build/dev/rel/ejabberd/bin/ejabberdctl stop \
          && _build/dev/rel/ejabberd/bin/ejabberdctl stopped

    - name: Run install
      run: |
        make install
        /tmp/ejabberd/sbin/ejabberdctl start \
          && /tmp/ejabberd/sbin/ejabberdctl started
        /tmp/ejabberd/sbin/ejabberdctl register user3 localhost s0mePass
        /tmp/ejabberd/sbin/ejabberdctl registered_users localhost >> registered.log
        /tmp/ejabberd/sbin/ejabberdctl stop \
          && /tmp/ejabberd/sbin/ejabberdctl stopped

    - name: View logs
      if: always()
      run: |
        echo "===> Registered:"
        cat registered.log
        echo "===> Prod:"
        cat _build/prod/rel/ejabberd/logs/*
        echo "===> Dev:"
        cat _build/dev/rel/ejabberd/logs/*
        echo "===> Install:"
        cat /tmp/ejabberd/var/log/ejabberd/*

    - name: Check logs
      if: always()
      run: |
        grep -q '^user1$' registered.log
        grep -q '^user2$' registered.log
        grep -q '^user3$' registered.log
        grep -q 'is started' _build/prod/rel/ejabberd/logs/ejabberd.log
        grep -q 'is stopped' _build/prod/rel/ejabberd/logs/ejabberd.log
        grep -q 'Stopping Ejabberd.Module.Example' _build/prod/rel/ejabberd/logs/ejabberd.log
        test $(find _build/prod/ -empty -name error.log)
        grep -q 'is started' _build/dev/rel/ejabberd/logs/ejabberd.log
        grep -q 'is stopped' _build/dev/rel/ejabberd/logs/ejabberd.log
        grep -q 'Stopping Ejabberd.Module.Example' _build/dev/rel/ejabberd/logs/ejabberd.log
        test $(find _build/dev/ -empty -name error.log)
        grep -q 'is started' /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        grep -q 'is stopped' /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        grep -q 'Stopping Ejabberd.Module.Example' /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        test $(find /tmp/ejabberd/var/log/ejabberd/ -empty -name error.log)

    - name: View logs failures
      if: failure()
      run: |
        cat _build/prod/rel/ejabberd/logs/ejabberd.log
        cat _build/prod/rel/ejabberd/logs/error.log
        cat _build/dev/rel/ejabberd/logs/ejabberd.log
        cat _build/dev/rel/ejabberd/logs/error.log
        cat /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        cat /tmp/ejabberd/var/log/ejabberd/error.log

  mix:
    name: Mix
    strategy:
      fail-fast: false
      matrix:
        elixir: ['1.13', '1.14', '1.15', '1.16', '1.17']
    runs-on: ubuntu-24.04
    container:
      image: elixir:${{ matrix.elixir }}

    steps:

    - uses: actions/checkout@v4

    - name: Prepare libraries
      run: |
        apt-get -qq update
        apt-get -y purge libgd3 nginx
        apt-get -qq install libexpat1-dev libgd-dev libpam0g-dev \
                            libsqlite3-dev libwebp-dev libyaml-dev

    - name: Remove Elixir Matchers
      run: |
        echo "::remove-matcher owner=elixir-mixCompileWarning::"
        echo "::remove-matcher owner=elixir-credoOutputDefault::"
        echo "::remove-matcher owner=elixir-mixCompileError::"
        echo "::remove-matcher owner=elixir-mixTestFailure::"
        echo "::remove-matcher owner=elixir-dialyzerOutputDefault::"

    - name: Enable Module.Example and an Elixir dependency
      run: |
        sed -i "s|^modules:|modules:\n  'Ejabberd.Module.Example': {}|g" ejabberd.yml.example
        cat ejabberd.yml.example
        sed -i 's|^{deps, \(.*\)|{deps, \1\n  {decimal, ".*", {git, "https://github.com/ericmj/decimal", {branch, "main"}}}, |g' rebar.config
        cat rebar.config

    - name: Cache Hex.pm
      uses: actions/cache@v4
      with:
        path: |
          ~/.hex/
        key: ${{matrix.elixir}}-${{hashFiles('mix.exs')}}

    - name: Install Hex and Rebar3 manually on older Elixir
      if: matrix.elixir <= '1.14'
      run: |
        mix local.hex --force
        mix local.rebar --force

    - name: Compile
      run: |
        ./autogen.sh
        ./configure --with-rebar=mix \
                    --prefix=/tmp/ejabberd \
                    --enable-all
        make

    - run: make xref

    - run: make dialyzer

    - run: make edoc
      if: matrix.elixir >= '1.14'

    - name: Run rel
      run: |
        make rel
        _build/prod/rel/ejabberd/bin/ejabberdctl start \
          && _build/prod/rel/ejabberd/bin/ejabberdctl started
        _build/prod/rel/ejabberd/bin/ejabberdctl register user1 localhost s0mePass
        _build/prod/rel/ejabberd/bin/ejabberdctl registered_users localhost > registered.log
        _build/prod/rel/ejabberd/bin/ejabberdctl stop \
          && _build/prod/rel/ejabberd/bin/ejabberdctl stopped

    - name: Run dev
      run: |
        make dev
        _build/dev/rel/ejabberd/bin/ejabberdctl start \
          && _build/dev/rel/ejabberd/bin/ejabberdctl started
        _build/dev/rel/ejabberd/bin/ejabberdctl register user2 localhost s0mePass
        _build/dev/rel/ejabberd/bin/ejabberdctl registered_users localhost >> registered.log
        _build/dev/rel/ejabberd/bin/ejabberdctl stop \
          && _build/dev/rel/ejabberd/bin/ejabberdctl stopped

    - name: Run install
      run: |
        make install
        /tmp/ejabberd/sbin/ejabberdctl start \
          && /tmp/ejabberd/sbin/ejabberdctl started
        /tmp/ejabberd/sbin/ejabberdctl register user3 localhost s0mePass
        /tmp/ejabberd/sbin/ejabberdctl registered_users localhost >> registered.log
        /tmp/ejabberd/sbin/ejabberdctl stop \
          && /tmp/ejabberd/sbin/ejabberdctl stopped

    - name: View logs
      if: always()
      run: |
        echo "===> Registered:"
        cat registered.log
        echo "===> Prod:"
        cat _build/prod/rel/ejabberd/logs/*
        echo "===> Dev:"
        cat _build/dev/rel/ejabberd/logs/*
        echo "===> Install:"
        cat /tmp/ejabberd/var/log/ejabberd/*

    - name: Check logs
      if: always()
      run: |
        grep -q '^user1$' registered.log
        grep -q '^user2$' registered.log
        grep -q '^user3$' registered.log
        grep -q 'is started' _build/prod/rel/ejabberd/logs/ejabberd.log
        grep -q 'is stopped' _build/prod/rel/ejabberd/logs/ejabberd.log
        grep -q 'Stopping Ejabberd.Module.Example' _build/prod/rel/ejabberd/logs/ejabberd.log
        test $(find _build/prod/ -empty -name error.log)
        grep -q 'is started' _build/dev/rel/ejabberd/logs/ejabberd.log
        grep -q 'is stopped' _build/dev/rel/ejabberd/logs/ejabberd.log
        grep -q 'Stopping Ejabberd.Module.Example' _build/dev/rel/ejabberd/logs/ejabberd.log
        test $(find _build/dev/ -empty -name error.log)
        grep -q 'is started' /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        grep -q 'is stopped' /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        grep -q 'Stopping Ejabberd.Module.Example' /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        test $(find /tmp/ejabberd/var/log/ejabberd/ -empty -name error.log)

    - name: View logs failures
      if: failure()
      run: |
        cat _build/prod/rel/ejabberd/logs/ejabberd.log
        cat _build/prod/rel/ejabberd/logs/error.log
        cat _build/dev/rel/ejabberd/logs/ejabberd.log
        cat _build/dev/rel/ejabberd/logs/error.log
        cat /tmp/ejabberd/var/log/ejabberd/ejabberd.log
        cat /tmp/ejabberd/var/log/ejabberd/error.log
