From ae364054663ece83d33b42d366ce3d538ae1c6c0 Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 9 Oct 2025 12:51:07 +0200 Subject: [PATCH] CI and Runtime: Reorganize steps to run in parallel, and ARM runner --- .github/workflows/ci.yml | 537 +++++++++++++++++---------- .github/workflows/runtime.yml | 362 ++++++------------ Makefile.in | 5 +- rebar.config | 1 + test/ejabberd_SUITE_data/sql_sort.pl | 43 +++ 5 files changed, 491 insertions(+), 457 deletions(-) create mode 100644 test/ejabberd_SUITE_data/sql_sort.pl diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e97f99b5..3469a17d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,89 +18,42 @@ on: - 'priv/**' - '**.md' +env: + DEV: _build/dev/rel/ejabberd + jobs: - tests: - name: Tests + ############################################################### Compile ##### + + compile: + runs-on: ubuntu-24.04-arm strategy: - fail-fast: false matrix: - otp: ['25', '26', '27', '28'] - runs-on: ubuntu-24.04 - services: - redis: - image: public.ecr.aws/docker/library/redis - ports: - - 6379:6379 + otp: ['27'] steps: - uses: actions/checkout@v5 - - name: Test shell scripts - if: matrix.otp == '27' - run: | - shellcheck test/ejabberd_SUITE_data/gencerts.sh - shellcheck tools/captcha.sh - shellcheck ejabberd.init.template - shellcheck -x ejabberdctl.template - - - name: Get specific Erlang/OTP - uses: erlef/setup-beam@v1 + - uses: erlef/setup-beam@v1 with: otp-version: ${{ matrix.otp }} + hexpm-mirrors: | + https://cdn.jsdelivr.net/hex + https://builds.hex.pm - - name: Install MS SQL Server - run: | - docker run -d -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=ejabberd_Test1" \ - -v $(pwd)/test/docker/db/mssql/initdb/initdb_mssql.sql:/initdb_mssql.sql:ro \ - -v $(pwd)/sql/mssql.sql:/mssql.sql:ro \ - -v $(pwd)/sql/mssql.new.sql:/mssql.new.sql:ro \ - -p 1433:1433 --name ejabberd-mssql "mcr.microsoft.com/mssql/server:2019-latest" - sleep 10 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: libexpat1-dev libgd-dev libpam0g-dev + libsqlite3-dev libwebp-dev libyaml-dev - - name: Prepare databases - run: | - docker exec ejabberd-mssql /opt/mssql-tools18/bin/sqlcmd -C -U SA -P ejabberd_Test1 -S localhost -i /initdb_mssql.sql - docker exec ejabberd-mssql /opt/mssql-tools18/bin/sqlcmd -C -U SA -P ejabberd_Test1 -S localhost -d ejabberd_test -i /mssql.sql - sudo systemctl start mysql.service - sudo systemctl start postgresql.service - mysql -u root -proot -e "CREATE DATABASE ejabberd_test;" - mysql -u root -proot -e "CREATE USER 'ejabberd_test'@'localhost' - IDENTIFIED BY 'ejabberd_test';" - mysql -u root -proot -e "GRANT ALL ON ejabberd_test.* - TO 'ejabberd_test'@'localhost';" - pg_isready - sudo -u postgres psql -c "CREATE DATABASE ejabberd_test;" - sudo -u postgres psql -c "CREATE USER ejabberd_test - WITH PASSWORD 'ejabberd_test';" - sudo -u postgres psql -c "GRANT ALL PRIVILEGES - ON DATABASE ejabberd_test TO ejabberd_test;" - sudo -u postgres psql -c "GRANT ALL ON SCHEMA public TO ejabberd_test;" - sudo -u postgres psql -c "ALTER DATABASE ejabberd_test OWNER TO ejabberd_test;" - sudo -u postgres psql ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL - TABLES IN SCHEMA public - TO ejabberd_test;" - sudo -u postgres psql ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL - SEQUENCES IN SCHEMA public - TO ejabberd_test;" - - - name: Prepare libraries - run: | - sudo apt-get -qq update - sudo apt-get -y purge libgd3 nginx - sudo apt-get -qq install libexpat1-dev libgd-dev libpam0g-dev \ - libsqlite3-dev libwebp-dev libyaml-dev - - - name: Remove syntax_tools from release - run: sed -i 's|, syntax_tools||g' src/ejabberd.app.src.script - - - name: Cache Hex.pm + - name: Cache rebar3 uses: actions/cache@v4 with: path: | ~/.cache/rebar3/ - key: ${{matrix.otp}}-${{hashFiles('rebar.config')}} + _build/default/lib/ + key: ci-${{ matrix.otp }}-${{hashFiles('rebar.config')}} - name: Compile run: | @@ -108,63 +61,196 @@ jobs: ./configure --with-rebar=./rebar3 \ --prefix=/tmp/ejabberd \ --enable-all \ - --disable-elixir \ - --disable-mssql \ - --disable-odbc + --disable-elixir + sed -i 's|, syntax_tools||g' src/ejabberd.app.src.script make + tar -cvf /tmp/compiled.tar . + + - uses: actions/upload-artifact@v4 + with: + name: compiled-${{ matrix.otp }} + path: /tmp/compiled.tar + retention-days: 1 + + ########################################################## Static Tests ##### + + static: + needs: compile + runs-on: ubuntu-24.04-arm + strategy: + matrix: + otp: ['27'] + + steps: + + - uses: erlef/setup-beam@v1 + with: + otp-version: ${{ matrix.otp }} + hexpm-mirrors: | + https://cdn.jsdelivr.net/hex + https://builds.hex.pm + + - uses: actions/download-artifact@v5 + with: + name: compiled-${{ matrix.otp }} + - run: tar -xf compiled.tar + + - name: Test shell scripts + run: | + shellcheck ejabberd.init.template + shellcheck -x ejabberdctl.template + shellcheck .vscode/relive.sh + shellcheck rel/setup-dev.sh + shellcheck rel/setup-relive.sh + shellcheck test/ejabberd_SUITE_data/gencerts.sh + shellcheck tools/captcha.sh + shellcheck tools/emacs-indent.sh + shellcheck tools/generate-doap.sh + shellcheck tools/prepare-tr.sh + shellcheck tools/rebar3-format.sh - - run: make install -s - run: make hooks - run: make options - run: make xref - run: make dialyzer - run: make test-eunit - run: make elvis - if: matrix.otp >= '26' + if: matrix.otp > '25' - - name: Check Production Release - run: | - make rel - RE=_build/prod/rel/ejabberd - $RE/bin/ejabberdctl start - $RE/bin/ejabberdctl started - $RE/bin/ejabberdctl stop - $RE/bin/ejabberdctl stopped - cat $RE/logs/ejabberd.log - grep -q "is stopped in" $RE/logs/ejabberd.log + - run: make install -s - - name: Start Development Release - run: | - make dev - RE=_build/dev/rel/ejabberd - sed -i 's/starttls_required: true/starttls_required: false/g' $RE/conf/ejabberd.yml - $RE/bin/ejabberdctl start - $RE/bin/ejabberdctl started - $RE/bin/ejabberdctl register admin localhost admin - grep -q "is started in" $RE/logs/ejabberd.log + ######################################################### Dynamic Tests ##### - - name: Run XMPP Interoperability Tests against CI server. + dynamic: + needs: compile + runs-on: ubuntu-24.04-arm + strategy: + matrix: + otp: ['27'] + + steps: + + - uses: erlef/setup-beam@v1 + with: + otp-version: ${{ matrix.otp }} + hexpm-mirrors: | + https://cdn.jsdelivr.net/hex + https://builds.hex.pm + + - uses: awalsh128/cache-apt-pkgs-action@latest + if: matrix.otp < '27' + with: + packages: libexpat1-dev libgd-dev libpam0g-dev + libsqlite3-dev libwebp-dev libyaml-dev + + - uses: actions/download-artifact@v5 + with: + name: compiled-${{ matrix.otp }} + - run: tar -xf compiled.tar + + - name: Check production release + uses: ./.github/actions/manage-ejabberd + with: + for: prod + do: deploy, start, stop, check + + - name: Start development release + uses: ./.github/actions/manage-ejabberd + with: + for: dev + do: deploy, no_tls, start, register + username: user123 + + - name: Run XMPP Interoperability Tests against CI server if: matrix.otp == '27' continue-on-error: true uses: XMPP-Interop-Testing/xmpp-interop-tests-action@v1.7.1 with: domain: 'localhost' - adminAccountUsername: 'admin' - adminAccountPassword: 'admin' - disabledSpecifications: RFC6121,XEP-0030,XEP-0045,XEP-0054,XEP-0060,XEP-0080,XEP-0115,XEP-0118,XEP-0215,XEP-0347,XEP-0363,XEP-0384,XEP-0421 + adminAccountUsername: 'user123' + adminAccountPassword: 's0mePass' + disabledSpecifications: RFC6121,XEP-0030,XEP-0045,XEP-0054,XEP-0060, + XEP-0080,XEP-0115,XEP-0118,XEP-0215,XEP-0347, + XEP-0363,XEP-0384,XEP-0421 - - name: Stop Development Release + - name: Stop development release if: always() + uses: ./.github/actions/manage-ejabberd + with: + for: dev + do: stop, check + + - name: View production logs + if: always() + uses: ./.github/actions/manage-ejabberd + with: + for: prod + do: logs + + - name: View development logs + if: always() + uses: ./.github/actions/manage-ejabberd + with: + for: dev + do: logs + + ##################################################### Common Test Suite ##### + + ct: + needs: compile + runs-on: ubuntu-24.04-arm + strategy: + matrix: + otp: ['27'] + backend: [agnostic, extauth, ldap, mnesia, mysql, pgsql, redis, sqlite] + schema: [single, multi] + exclude: + - backend: agnostic + schema: single + - backend: extauth + schema: single + - backend: ldap + schema: single + - backend: mnesia + schema: single + - backend: redis + schema: single + + steps: + + - uses: erlef/setup-beam@v1 + with: + otp-version: ${{ matrix.otp }} + hexpm-mirrors: | + https://cdn.jsdelivr.net/hex + https://builds.hex.pm + + - uses: actions/download-artifact@v5 + with: + name: compiled-${{ matrix.otp }} + - run: tar -xf compiled.tar + + - name: Prepare database + uses: ./.github/actions/manage-database + with: + for: ${{ matrix.backend }} + do: install, start, user, create + + - name: Setup multihost SQL schema + if: matrix.schema == 'multi' run: | - RE=_build/dev/rel/ejabberd - $RE/bin/ejabberdctl stop - $RE/bin/ejabberdctl stopped - cat $RE/logs/ejabberd.log - grep -q "is stopped in" $RE/logs/ejabberd.log + sed -i 's|multihost_schema, false|multihost_schema, true|g' \ + test/suite.erl - name: Run tests id: ct - run: make test + run: CT_BACKENDS=${{ matrix.backend }} make test + + - name: Send to coveralls + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + DIAGNOSTIC=1 ./rebar3 as test coveralls send - name: Check results if: always() && (steps.ct.outcome != 'skipped') @@ -176,20 +262,45 @@ jobs: grep -q 'TEST COMPLETE,.* 0 failed' logs/suite.log test $(find logs/ -empty -name error.log) - - name: View logs failures - if: failure() && steps.ctresults.outcome == 'failure' + - name: View logs + if: always() run: | + echo "::group::ejabberd.log" + find logs/ -name ejabberd.log -exec cat '{}' ';' + echo "::endgroup::" + echo "::group::error.log" + find logs/ -name error.log -exec cat '{}' ';' + echo "::endgroup::" + echo "::group::exunit.log" + find logs/ -name exunit.log -exec cat '{}' ';' + echo "::endgroup::" + echo "::group::suite.log (only failures)" cat logs/suite.log | awk \ 'BEGIN{RS="\n=case";FS="\n"} /=result\s*failed/ {print "=case" $0}' - find logs/ -name error.log -exec cat '{}' ';' - find logs/ -name exunit.log -exec cat '{}' ';' + echo "::endgroup::" + echo "::group::suite.log (complete)" + cat logs/suite.log + echo "::endgroup::" - - name: Send to coveralls - if: matrix.otp == '27' + - name: Upload CT logs + if: failure() + uses: actions/upload-artifact@v4 + with: + name: ct-logs-${{ matrix.otp }}-${{ matrix.backend }}-${{ matrix.schema }} + path: _build/test/logs + retention-days: 14 + + ############################################################# Coveralls ##### + + cover: + needs: ct + if: always() + runs-on: ubuntu-24.04-arm + steps: + - name: Finish parallel upload to coveralls env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - DIAGNOSTIC=1 ./rebar3 as test coveralls send curl -v -k https://coveralls.io/webhook \ --header "Content-Type: application/json" \ --data '{"repo_name":"$GITHUB_REPOSITORY", @@ -197,96 +308,126 @@ jobs: "payload":{"build_num":$GITHUB_RUN_ID, "status":"done"}}' - - name: Check for changes to trigger schema upgrade test - uses: dorny/paths-filter@v3 - id: filter + ################################################################ Schema ##### + + schema: + needs: compile + runs-on: ubuntu-24.04-arm + strategy: + matrix: + otp: ['27'] + + steps: + + - uses: erlef/setup-beam@v1 with: - filters: | - sql: - - 'sql/**' - - 'src/mod_admin_update_sql.erl' + otp-version: ${{ matrix.otp }} + hexpm-mirrors: | + https://cdn.jsdelivr.net/hex + https://builds.hex.pm - - name: Prepare for schema upgrade test - id: prepupgradetest - if: ${{ steps.filter.outputs.sql == 'true' }} - run: | - [[ -d logs ]] && rm -rf logs - [[ -d _build/test/logs ]] && rm -rf _build/test/logs || true - sed -i 's|update_sql, false|update_sql, true|g' test/suite.erl - - name: Run DB tests on upgraded schema (mssql, mysql, pgsql) - run: CT_BACKENDS=mssql,mysql,pgsql make test - if: always() && steps.prepupgradetest.outcome != 'skipped' - id: ctupgradedschema - - name: Check results - if: always() && steps.ctupgradedschema.outcome != 'skipped' - run: | - [[ -d _build ]] && ln -s _build/test/logs/last/ logs || true - ln `find logs/ -name suite.log` logs/suite.log - grep 'TEST COMPLETE' logs/suite.log - grep -q 'TEST COMPLETE,.* 0 failed' logs/suite.log - test $(find logs/ -empty -name error.log) - - name: View logs failures - if: failure() && steps.ctupgradedschema.outcome != 'skipped' - run: | - cat logs/suite.log | awk \ - 'BEGIN{RS="\n=case";FS="\n"} /=result\s*failed/ {print "=case" $0}' - find logs/ -name error.log -exec cat '{}' ';' - find logs/ -name exunit.log -exec cat '{}' ';' - - - name: Prepare new schema - run: | - [[ -d logs ]] && rm -rf logs - [[ -d _build/test/logs ]] && rm -rf _build/test/logs || true - docker exec ejabberd-mssql /opt/mssql-tools18/bin/sqlcmd -C -U SA -P ejabberd_Test1 -S localhost -Q "drop database [ejabberd_test];" - docker exec ejabberd-mssql /opt/mssql-tools18/bin/sqlcmd -C -U SA -P ejabberd_Test1 -S localhost -Q "drop login [ejabberd_test];" - mysql -u root -proot -e "DROP DATABASE ejabberd_test;" - sudo -u postgres psql -c "DROP DATABASE ejabberd_test;" - docker exec ejabberd-mssql /opt/mssql-tools18/bin/sqlcmd -C -U SA -P ejabberd_Test1 -S localhost -i /initdb_mssql.sql - docker exec ejabberd-mssql /opt/mssql-tools18/bin/sqlcmd -C -U SA -P ejabberd_Test1 -S localhost -d ejabberd_test -i /mssql.new.sql - mysql -u root -proot -e "CREATE DATABASE ejabberd_test;" - mysql -u root -proot -e "GRANT ALL ON ejabberd_test.* - TO 'ejabberd_test'@'localhost';" - sudo -u postgres psql -c "CREATE DATABASE ejabberd_test;" - sudo -u postgres psql -c "GRANT ALL PRIVILEGES - ON DATABASE ejabberd_test TO ejabberd_test;" - sudo -u postgres psql -c "GRANT ALL ON SCHEMA public TO ejabberd_test;" - sudo -u postgres psql -c "ALTER DATABASE ejabberd_test OWNER TO ejabberd_test;" - sudo -u postgres psql ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL - TABLES IN SCHEMA public - TO ejabberd_test;" - sudo -u postgres psql ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL - SEQUENCES IN SCHEMA public - TO ejabberd_test;" - sed -i 's|multihost_schema, false|multihost_schema, true|g' test/suite.erl - - name: Run DB tests on new schema (mssql, mysql, pgsql) - run: CT_BACKENDS=mssql,mysql,pgsql make test - id: ctnewschema - - name: Check results - if: always() && steps.ctnewschema.outcome != 'skipped' - run: | - [[ -d _build ]] && ln -s _build/test/logs/last/ logs || true - ln `find logs/ -name suite.log` logs/suite.log - grep 'TEST COMPLETE' logs/suite.log - grep -q 'TEST COMPLETE,.* 0 failed' logs/suite.log - test $(find logs/ -empty -name error.log) - - name: View logs failures - if: failure() && steps.ctnewschema.outcome != 'skipped' - run: | - cat logs/suite.log | awk \ - 'BEGIN{RS="\n=case";FS="\n"} /=result\s*failed/ {print "=case" $0}' - find logs/ -name error.log -exec cat '{}' ';' - find logs/ -name exunit.log -exec cat '{}' ';' - - - name: Upload CT logs - if: failure() - uses: actions/upload-artifact@v4 + - uses: actions/download-artifact@v5 with: - name: ejabberd-ct-logs-${{matrix.otp}} - # - # Appending the wildcard character ("*") is a trick to make - # "ejabberd-packages" the root directory of the uploaded ZIP file: - # - # https://github.com/actions/upload-artifact#upload-using-multiple-paths-and-exclusions - # - path: _build/test/logs - retention-days: 14 + name: compiled-${{ matrix.otp }} + - run: tar -xf compiled.tar + + ###################################### multi-changed ## + + - name: Prepare databases + uses: ./.github/actions/manage-database + with: + for: mysql, pgsql + do: install, start, user, create + + - name: Prepare configuration + run: | + CT_BACKENDS=mysql,pgsql ./rebar3 ct \ + --suite=test/ejabberd_SUITE --group=configtest_single + make dev + cp test/ejabberd_SUITE_data/ejabberd.yml ${{ env.DEV }}/conf/ + cp _build/test/logs/last/*.yml ${{ env.DEV }}/database/ + echo "define_macro: [CONFIGTEST_CONFIG: {modules: {mod_muc: {}}}]" \ + > ${{ env.DEV }}/database/configtest.yml + cp _build/test/logs/last/*.pem ${{ env.DEV }}/conf/ + cp _build/test/logs/last/*.pem ${{ env.DEV }}/database/ + + - name: Run ejabberd + uses: ./.github/actions/manage-ejabberd + with: + for: dev + do: start, update_sql, stop, logs, check + username: user2 + + - name: Dump multihost databases + uses: ./.github/actions/manage-database + with: + for: mysql, pgsql + do: dump + dump-suffix: multi-changed + + ######################################### multi-auto ## + + - name: Prepare databases + uses: ./.github/actions/manage-database + with: + for: mysql, pgsql + do: drop, create + + - name: Configure multihost schema + run: | + sed -i 's|MULTIHOST_SCHEMA|true|g' ${{ env.DEV }}/conf/ejabberd.yml + + - name: Run ejabberd for multihost + uses: ./.github/actions/manage-ejabberd + with: + for: dev + do: start, stop, logs, check + username: user2 + + - name: Dump multihost databases + uses: ./.github/actions/manage-database + with: + for: mysql, pgsql + do: dump + dump-suffix: multi-auto + + ############################################ compare ## + + - name: View SQL schemas (mysql) + run: | + perl test/ejabberd_SUITE_data/sql_sort.pl \ + mysql-multi2.sql + perl test/ejabberd_SUITE_data/sql_sort.pl \ + mysql-changed2.sql + echo "::group::differences multi-auto > multi-changed" + diff -u mysql-multi2.sql mysql-changed2.sql || echo ok + echo "::endgroup::" + echo "::group::multi-auto.sql" + cat mysql-multi-auto.sql + echo "::endgroup::" + echo "::group::multi-changed.sql" + cat mysql-multi-changed.sql + echo "::endgroup::" + + - name: View SQL schemas (pgsql) + run: | + perl test/ejabberd_SUITE_data/sql_sort.pl \ + pgsql-multi2.sql + perl test/ejabberd_SUITE_data/sql_sort.pl \ + pgsql-changed2.sql + echo "::group::differences (multi-auto > multi-changed)" + diff -u pgsql-multi2.sql pgsql-changed2.sql || echo ok + echo "::endgroup::" + echo "::group::multi-auto.sql" + cat pgsql-multi-auto.sql + echo "::endgroup::" + echo "::group::multi-changed.sql" + cat pgsql-multi-changed.sql + echo "::endgroup::" + + - name: View ejabberd logs + if: always() + uses: ./.github/actions/manage-ejabberd + with: + for: dev + do: logs diff --git a/.github/workflows/runtime.yml b/.github/workflows/runtime.yml index 3bf4c03d1..013fe9d9d 100644 --- a/.github/workflows/runtime.yml +++ b/.github/workflows/runtime.yml @@ -26,10 +26,11 @@ on: jobs: + ################################################################ Rebars ##### + rebars: - name: Rebars + runs-on: ubuntu-24.04-arm strategy: - fail-fast: false matrix: otp: ['25', '26', '27', '28'] rebar: ['rebar', 'rebar3'] @@ -38,7 +39,6 @@ jobs: rebar: 'rebar' - otp: '28' rebar: 'rebar' - runs-on: ubuntu-24.04 container: image: public.ecr.aws/docker/library/erlang:${{ matrix.otp }} @@ -46,18 +46,8 @@ jobs: - uses: actions/checkout@v5 - - name: Get old 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: Get recent compatible Rebar binaries - if: matrix.otp > 23 && matrix.otp < 25 + if: matrix.otp < 25 run: | rm rebar rm rebar3 @@ -69,20 +59,17 @@ jobs: - 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 + apt-get -q -y install libexpat1-dev libgd-dev libpam0g-dev \ + libsqlite3-dev libwebp-dev libyaml-dev - - name: Cache Hex.pm + - name: Cache rebar3 + if: matrix.rebar == 'rebar3' uses: actions/cache@v4 with: path: | ~/.cache/rebar3/ - key: ${{matrix.otp}}-${{hashFiles('rebar.config')}} - - - name: Unlock eredis dependency - if: matrix.rebar == 'rebar3' && matrix.otp < 21 - run: rebar3 unlock eredis + _build/default/lib/ + key: runtime-${{ matrix.otp }}-${{matrix.rebar}}-${{hashFiles('rebar.config')}} - name: Compile run: | @@ -91,94 +78,47 @@ jobs: --prefix=/tmp/ejabberd \ --with-min-erlang=9.0.5 \ --enable-all \ - --disable-elixir \ - --disable-tools \ - --disable-odbc + --disable-elixir make + - run: make hooks + - run: make options - run: make xref - - run: make dialyzer + - run: make elvis + if: matrix.otp > '25' && matrix.rebar == 'rebar3' - - 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: Production + uses: ./.github/actions/manage-ejabberd + with: + for: prod + do: deploy, start, register, stop, logs, check + tool: ${{ matrix.rebar }} + username: user1 - - 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: Development + uses: ./.github/actions/manage-ejabberd + with: + for: dev + do: deploy, start, register, stop, logs, check + tool: ${{ matrix.rebar }} + username: user2 - - 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: Installed + uses: ./.github/actions/manage-ejabberd + with: + for: install + do: deploy, start, register, stop, logs, check + tool: ${{ matrix.rebar }} + username: user3 - - 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 ##### rebar3-elixir: - name: Rebar3+Elixir + runs-on: ubuntu-24.04-arm strategy: - fail-fast: false matrix: - elixir: ['1.14', '1.15', '1.16', '1.17', '1.18'] - runs-on: ubuntu-24.04 + elixir: ['1.14', '1.18'] container: image: public.ecr.aws/docker/library/elixir:${{ matrix.elixir }} @@ -189,26 +129,26 @@ jobs: - 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 + apt-get -q -y 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 + 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 + - name: Cache hex.pm uses: actions/cache@v4 with: path: | ~/.cache/rebar3/ - key: ${{matrix.elixir}}-${{hashFiles('rebar.config')}} + key: runtime-${{matrix.elixir}}-${{hashFiles('rebar.config')}} - name: Install Hex and Rebar3 manually on older Elixir - if: matrix.elixir <= '1.14' + if: matrix.elixir < '1.15' run: | mix local.hex --force mix local.rebar --force @@ -218,90 +158,45 @@ jobs: ./autogen.sh ./configure --with-rebar=./rebar3 \ --prefix=/tmp/ejabberd \ - --enable-all \ - --disable-odbc - make + --enable-all + make scripts deps + ./rebar3 eunit --verbose + - run: make hooks + - run: make options - run: make xref + #- run: make dialyzer + - run: make elvis + if: matrix.otp > '25' - - 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: Production + uses: ./.github/actions/manage-ejabberd + with: + for: prod + do: deploy, start, register, stop, logs, check + username: user1 - - 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: Release + uses: ./.github/actions/manage-ejabberd + with: + for: dev + do: deploy, start, register, stop, logs, check + username: user2 - - 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: Installed + uses: ./.github/actions/manage-ejabberd + with: + for: install + do: deploy, start, register, stop, logs, check + username: user3 - - 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 ##### mix: - name: Mix + runs-on: ubuntu-24.04-arm strategy: - fail-fast: false matrix: - elixir: ['1.14', '1.15', '1.16', '1.17', '1.18'] - runs-on: ubuntu-24.04 + elixir: ['1.14', '1.18'] container: image: public.ecr.aws/docker/library/elixir:${{ matrix.elixir }} @@ -312,11 +207,10 @@ jobs: - 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 + apt-get -q -y install libexpat1-dev libgd-dev libpam0g-dev \ + libsqlite3-dev libwebp-dev libyaml-dev - - name: Remove Elixir Matchers + - name: Remove Elixir matchers run: | echo "::remove-matcher owner=elixir-mixCompileWarning::" echo "::remove-matcher owner=elixir-credoOutputDefault::" @@ -326,20 +220,21 @@ jobs: - name: Enable Module.Example and an Elixir dependency run: | - sed -i "s|^modules:|modules:\n 'Ejabberd.Module.Example': {}|g" ejabberd.yml.example + 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 + - name: Cache hex.pm uses: actions/cache@v4 with: path: | ~/.hex/ - key: ${{matrix.elixir}}-${{hashFiles('mix.exs')}} + key: runtime-${{matrix.elixir}}-${{hashFiles('mix.exs')}} - name: Install Hex and Rebar3 manually on older Elixir - if: matrix.elixir <= '1.14' + if: matrix.elixir < '1.15' run: | mix local.hex --force mix local.rebar --force @@ -352,79 +247,32 @@ jobs: --enable-all make + - run: make hooks + - run: make options - run: make xref - - run: make dialyzer + - run: make elvis + if: matrix.otp > '25' - run: make edoc - - 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: Production + uses: ./.github/actions/manage-ejabberd + with: + for: prod + do: deploy, start, register, stop, logs, check + username: user1 - - 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: Development + uses: ./.github/actions/manage-ejabberd + with: + for: dev + do: deploy, start, register, stop, logs, check + username: user2 - - 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 + - name: Installed + uses: ./.github/actions/manage-ejabberd + with: + for: install + do: deploy, start, register, stop, logs, check + username: user3 diff --git a/Makefile.in b/Makefile.in index 0ab2ae943..2c44b11cc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -193,9 +193,10 @@ else XREFOPTIONS= CLEANARG= REBARREL=$(REBAR) generate - REBARDEV= + REBARDEV=@echo "Rebar2 detected... dev not supported.\ + \nTry: make prod, or: ./configure --with-rebar=rebar3 ; make dev" RELIVECMD=@echo "Rebar2 detected... relive not supported.\ - \nTry: ./configure --with-rebar=rebar3 ; make relive" + \nTry: ./configure --with-rebar=rebar3 ; make relive" REL_LIB_DIR = rel/ejabberd/lib COPY_REL_TARGET = rel endif diff --git a/rebar.config b/rebar.config index f7c7c3b94..349517e47 100644 --- a/rebar.config +++ b/rebar.config @@ -257,6 +257,7 @@ {cover_export_enabled, true}. {cover_excl_mods, [eldap_filter_yecc]}. {coveralls_coverdata, "_build/test/cover/ct.coverdata"}. +{coveralls_parallel, "true"}. {coveralls_service_name, "github"}. %%% diff --git a/test/ejabberd_SUITE_data/sql_sort.pl b/test/ejabberd_SUITE_data/sql_sort.pl new file mode 100644 index 000000000..a9eb8907f --- /dev/null +++ b/test/ejabberd_SUITE_data/sql_sort.pl @@ -0,0 +1,43 @@ +#!/usr/bin/perl -p0 + +use strict; + +sub sp{ + my $s=trim(shift); + my @r; + push @r, trim($1) while $s =~ m/ + ( + (?: + [^(),]+ | + (?: \( \) ) | + \( + ( [^()]+ | \( (?2) \) )+ + \) + )+ + ) + /gx; + return join(",\n",sort(@r)) + } + + sub trim { + my $s = shift; + $s =~ s/^\s+|\s+$//g; + return $s; + } + + s/--.*\n//gm; + + s/ + ( + [^()]+ | + (?: \( \) ) + ) | + \( + ( + (?: (?R) | [^()]+ )+ + ) + \)/ if ($2) { + "(\n".sp($2)."\n)" + } else { + $1 + }/gsxe;