Skip to content

Split library files into includes/, add the file manifest + upgrade p… #51

Split library files into includes/, add the file manifest + upgrade p…

Split library files into includes/, add the file manifest + upgrade p… #51

# +-------------------------------------------------------------------------+
# | Copyright (C) 2004-2026 The Cacti Group |
# | |
# | This program is free software; you can redistribute it and/or |
# | modify it under the terms of the GNU General Public License |
# | as published by the Free Software Foundation; either version 2 |
# | of the License, or (at your option) any later version. |
# | |
# | This program is distributed in the hope that it will be useful, |
# | but WITHOUT ANY WARRANTY; without even the implied warranty of |
# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# | GNU General Public License for more details. |
# +-------------------------------------------------------------------------+
# | Cacti: The Complete RRDtool-based Graphing Solution |
# +-------------------------------------------------------------------------+
# | This code is designed, written, and maintained by the Cacti Group. See |
# | about.php and/or the AUTHORS file for specific developer information. |
# +-------------------------------------------------------------------------+
# | http://www.cacti.net/ |
# +-------------------------------------------------------------------------+
name: Plugin Integration Tests
on:
push:
branches:
- main
- develop
pull_request:
branches:
- main
- develop
env:
CACTI: 1.2.x
jobs:
integration-test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
php: ['8.2', '8.3', '8.4']
os: [ubuntu-latest]
services:
mariadb:
image: mariadb:11.8
env:
MYSQL_ROOT_PASSWORD: cactiroot
MYSQL_DATABASE: cacti
MYSQL_USER: cactiuser
MYSQL_PASSWORD: cactiuser
ports:
- 3306:3306
options: >-
--health-cmd="mariadb-admin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
name: PHP ${{ matrix.php }} Integration Test on ${{ matrix.os }}
steps:
- name: Checkout Cacti
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: Cacti/cacti
ref: ${{ env.CACTI }}
path: cacti
- name: Checkout quicktree Plugin
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: cacti/plugins/quicktree
# patch-coverage.php diffs against the base branch below.
fetch-depth: 0
- name: Install PHP ${{ matrix.php }}
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2
with:
php-version: ${{ matrix.php }}
coverage: xdebug
extensions: intl, mysql, gd, ldap, gmp, xml, curl, json, mbstring, snmp
ini-values: "post_max_size=256M, max_execution_time=60, date.timezone=America/New_York"
- name: Check PHP version
run: php -v
- name: Validate plugin manifest (expected-file drift)
run: php cacti/plugins/quicktree/tests/bin/validate-manifest.php
- name: Run apt-get update
run: sudo apt-get update
- name: Install System Dependencies
run: sudo apt-get install -y rrdtool fping gettext
- name: Setup Permissions
run: |
sudo chown -R www-data:runner ${{ github.workspace }}/cacti
sudo find ${{ github.workspace }}/cacti -type d -exec chmod 775 {} \;
sudo find ${{ github.workspace }}/cacti -type f -exec chmod 664 {} \;
sudo chmod +x ${{ github.workspace }}/cacti/cmd.php
sudo chmod +x ${{ github.workspace }}/cacti/poller.php
- name: Create MySQL Config
run: |
echo "::add-mask::cactiroot"
echo -e "[client]\nuser = root\npassword = cactiroot\nhost = 127.0.0.1\n" > ~/.my.cnf
chmod 600 ~/.my.cnf
- name: Initialize Cacti Database
run: |
MYSQL_AUTH_USR="--defaults-file=$HOME/.my.cnf"
mysql "$MYSQL_AUTH_USR" -e 'CREATE DATABASE IF NOT EXISTS cacti;'
mysql "$MYSQL_AUTH_USR" -e "CREATE USER IF NOT EXISTS 'cactiuser'@'localhost' IDENTIFIED BY 'cactiuser';"
mysql "$MYSQL_AUTH_USR" -e "CREATE USER IF NOT EXISTS 'cactiuser'@'127.0.0.1' IDENTIFIED BY 'cactiuser';"
mysql "$MYSQL_AUTH_USR" -e "GRANT ALL PRIVILEGES ON cacti.* TO 'cactiuser'@'localhost';"
mysql "$MYSQL_AUTH_USR" -e "GRANT ALL PRIVILEGES ON cacti.* TO 'cactiuser'@'127.0.0.1';"
mysql "$MYSQL_AUTH_USR" -e "GRANT SELECT ON mysql.time_zone_name TO 'cactiuser'@'localhost';"
mysql "$MYSQL_AUTH_USR" -e "GRANT SELECT ON mysql.time_zone_name TO 'cactiuser'@'127.0.0.1';"
mysql "$MYSQL_AUTH_USR" -e "FLUSH PRIVILEGES;"
mysql "$MYSQL_AUTH_USR" cacti < ${{ github.workspace }}/cacti/cacti.sql
mysql "$MYSQL_AUTH_USR" -e "INSERT INTO settings (name, value) VALUES ('path_php_binary', '/usr/bin/php')" cacti
- name: Validate composer files
run: |
cd ${{ github.workspace }}/cacti
if [ -f composer.json ]; then
composer validate --strict || true
fi
- name: Install Composer Dependencies
run: |
cd ${{ github.workspace }}/cacti
if [ -f composer.json ]; then
sudo composer config --no-plugins allow-plugins.pestphp/pest-plugin true
sudo composer require --no-progress --no-interaction "pestphp/pest: ^3" "pestphp/pest-plugin-drift: ^3.0"
sudo rm -f composer.lock
sudo composer install --dev --no-progress
fi
- name: Restore vendor ownership for Pest
run: |
cd ${{ github.workspace }}/cacti
if [ -d include/vendor ]; then
sudo chown -R runner:runner include/vendor composer.lock
fi
- name: Create Cacti config.php
run: |
cat ${{ github.workspace }}/cacti/include/config.php.dist | \
sed -r "s/localhost/127.0.0.1/g" | \
sed -r "s/'cacti'/'cacti'/g" | \
sed -r "s/'cactiuser'/'cactiuser'/g" | \
sed -r "s/'cactiuser'/'cactiuser'/g" > ${{ github.workspace }}/cacti/include/config.php
sudo chmod 664 ${{ github.workspace }}/cacti/include/config.php
- name: Install Cacti via CLI
run: |
cd ${{ github.workspace }}/cacti
sudo php cli/install_cacti.php --accept-eula --install --force
- name: Install quicktree Plugin
run: |
cd ${{ github.workspace }}/cacti
sudo php cli/plugin_manage.php --plugin=quicktree --install --enable
- name: Check PHP Syntax for Plugin
run: |
cd ${{ github.workspace }}/cacti/plugins/quicktree
find . -path './vendor' -prune -o -type f -name '*.php' -print0 | xargs -0 -r -n1 php -l
- name: Verify translation template is up to date
run: |
cd ${{ github.workspace }}/cacti/plugins/quicktree
sudo chmod +x locales/build_gettext.sh
sudo ./locales/build_gettext.sh
grep -v '^"POT-Creation-Date:' locales/po/cacti.pot > /tmp/cacti.pot.new
git checkout -- locales/
grep -v '^"POT-Creation-Date:' locales/po/cacti.pot > /tmp/cacti.pot.old
if ! cmp -s /tmp/cacti.pot.old /tmp/cacti.pot.new; then
echo "locales/po/cacti.pot is out of date. Run locales/build_gettext.sh and commit the updated locales/po/cacti.pot."
diff -u /tmp/cacti.pot.old /tmp/cacti.pot.new || true
exit 1
fi
- name: Set expected Cacti version for unit tests
run: echo -n "${{ env.CACTI }}" | sudo tee ${{ github.workspace }}/cacti/plugins/quicktree/tests/.cacti-version > /dev/null
- name: Run Pest Unit Tests
run: |
cd ${{ github.workspace }}/cacti
include/vendor/bin/pest --configuration=plugins/quicktree/phpunit.xml \
--coverage-clover=plugins/quicktree/coverage/clover.xml
# Whole-file coverage is meaningless here: most of the plugin only runs
# inside a live Cacti. What is enforceable is that a change covers the
# lines it adds.
- name: Enforce coverage of changed lines
if: github.event_name == 'pull_request'
env:
BASE_REF: ${{ github.event.pull_request.base.sha }}
run: |
cd ${{ github.workspace }}/cacti/plugins/quicktree
git config --global --add safe.directory ${{ github.workspace }}/cacti/plugins/quicktree
php tests/bin/patch-coverage.php coverage/clover.xml "$BASE_REF" 100
- name: Upload coverage report
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-php${{ matrix.php }}
path: ${{ github.workspace }}/cacti/plugins/quicktree/coverage/
if-no-files-found: warn
- name: Remove the plugins directory exclusion from the .phpstan.neon
if: ${{ env.CACTI != '1.2.x' }}
run: sed '/plugins/d' -i .phpstan.neon
working-directory: ${{ github.workspace }}/cacti
- name: Mark composer scripts executable
if: ${{ env.CACTI != '1.2.x' }}
run: sudo chmod +x ${{ github.workspace }}/cacti/include/vendor/bin/*
- name: Run Linter on base code
if: ${{ env.CACTI != '1.2.x' }}
run: composer run-script lint ${{ github.workspace }}/cacti/plugins/quicktree
working-directory: ${{ github.workspace }}/cacti
- name: Checking coding standards on base code
if: ${{ env.CACTI != '1.2.x' }}
run: composer run-script phpcsfixer ${{ github.workspace }}/cacti/plugins/quicktree
working-directory: ${{ github.workspace }}/cacti
- name: Run PHPStan at Level 6 on base code outside of Composer due to technical issues
if: ${{ env.CACTI != '1.2.x' }}
run: ./include/vendor/bin/phpstan analyze --level 6 ${{ github.workspace }}/cacti/plugins/quicktree
working-directory: ${{ github.workspace }}/cacti
- name: Re-apply web user ownership before polling
run: |
# Ancestor directories above the checkout (e.g. /home/runner, .../work)
# are typically 750 owned by the runner user, which blocks a non-root
# www-data process from traversing down to the checkout at all.
p="${{ github.workspace }}"
while [ "$p" != "/" ]; do
sudo chmod o+x "$p" || true
p=$(dirname "$p")
done
sudo chown -R www-data:runner ${{ github.workspace }}/cacti
sudo find ${{ github.workspace }}/cacti -type d -exec chmod 775 {} \;
sudo find ${{ github.workspace }}/cacti -type f -exec chmod 664 {} \;
sudo chmod +x ${{ github.workspace }}/cacti/cmd.php
sudo chmod +x ${{ github.workspace }}/cacti/poller.php
- name: Run Cacti Poller
run: |
cd ${{ github.workspace }}/cacti
sudo -u www-data php poller.php --poller=1 --force --debug
if ! grep -q "SYSTEM STATS" log/cacti.log; then
echo "Cacti poller did not finish successfully"
cat log/cacti.log
exit 1
fi
- name: View Cacti Logs
if: always()
run: |
if [ -f ${{ github.workspace }}/cacti/log/cacti.log ]; then
echo "=== Cacti Log ==="
sudo cat ${{ github.workspace }}/cacti/log/cacti.log
fi
- name: Check Cacti Logs for Errors
if: always()
run: |
if [ -f ${{ github.workspace }}/cacti/log/cacti.log ]; then
if grep -E "FATAL:|ERROR:|WARNING:" ${{ github.workspace }}/cacti/log/cacti.log; then
echo "Found FATAL/ERROR/WARNING entries in Cacti log"
exit 1
fi
fi