Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'type:bug,status:needs-verification'
Comment thread
TheWitness marked this conversation as resolved.
assignees: ''

---
<!--
#
# Copyright (C) 2004-2026 The Cacti Group
#
-->
# Describe the bug

A clear and concise description of what the bug is.

## To Reproduce

Steps to reproduce the behavior:

1. Go to '...'

2. Click on '....'

3. Scroll down to '....'

4. See error

## Expected behavior

A clear and concise description of what you expected to happen.

## Screenshots

If applicable, add screenshots to help explain your problem.

## Desktop (please complete the following information)

- OS: [e.g. iOS]

- Browser [e.g. chrome, safari]

- Version [e.g. 22]

## Smartphone (please complete the following information)

- Device: [e.g. iPhone6]

- OS: [e.g. iOS8.1]

- Browser [e.g. stock browser, safari]

- Version [e.g. 22]

## Additional context

Add any other context about the problem here.
33 changes: 33 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'type:enhancement'
assignees: ''

---
<!--
#
# Copyright (C) 2004-2026 The Cacti Group
#
-->

# Feature Request

## Is your feature request related to a problem? Please describe

A clear and concise description of what the problem is. Ex. I'm always
frustrated when [...]

## Describe the solution you'd like

A clear and concise description of what you want to happen.

## Describe alternatives you've considered

A clear and concise description of any alternative solutions or features you've
considered.

## Additional context

Add any other context or screenshots about the feature request here.
40 changes: 40 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!--- Provide a general summary of your changes in the Title above -->

## Description
<!--- Describe your changes in detail -->

## Related Issue
<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->

## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->

## Screenshots (if appropriate):
<!--- GitHub allows you to paste images directly into textboxes -->

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [ ] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation repository accordingly.

<!--
#
# Copyright (C) 2004-2026 The Cacti Group
#
-->
11 changes: 11 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ print '<img alt="' . __esc($label, 'quicktree') . '">';

Document all changes in `CHANGELOG.md`; use descriptive commit messages referencing issue/PR numbers when applicable.

## CI & Dependency Baselines

- Do not commit a `composer.json` or `composer.lock` in this plugin's own repo root — the shared CI workflow installs Pest/dev dependencies into Cacti's own Composer-managed vendor tree (checked out alongside the plugin). Use Cacti's `composer.json`, not a plugin-local one.
- Do not add a plugin-local `.phpstan.neon`/`phpstan.neon` or `.php-cs-fixer.php`/`.php-cs-fixer.dist.php` — lint/static-analysis steps run against Cacti's own config from the Cacti core checkout, targeting this plugin's directory. Use the Cacti version, not a plugin-local config.
- Prefer Cacti's `cacti_count()`/`cacti_sizeof()` wrappers over the raw `count()`/`sizeof()` builtins in new or edited code.

## Internationalization (i18n)

- Translatable strings are managed with GNU gettext via `locales/build_gettext.sh`. `locales/po/cacti.pot` is the source template; Weblate owns syncing the per-language `.po`/`.mo` files from it.
- When a pull request adds or changes a string wrapped in `__()`/`__n()`/`__esc()`/`__x()`/`__xn()`/`__gettext()`, run `locales/build_gettext.sh` before pushing and add the resulting change to `locales/po/cacti.pot` only. Do not commit the regenerated per-language `.po`/`.mo` files in the same PR — Weblate takes care of the rest.

## References

- [Cacti main repo](https://github.com/Cacti/cacti/tree/1.2.x)
Expand Down
59 changes: 59 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# +-------------------------------------------------------------------------+
# | Copyright (C) 2004-2026 The Cacti Group |
# +-------------------------------------------------------------------------+
# | Cacti: The Complete RRDtool-based Graphing Solution |
# +-------------------------------------------------------------------------+
# | http://www.cacti.net/ |
# +-------------------------------------------------------------------------+
#
# CodeQL has no PHP analysis, so this covers the plugin JavaScript only. The PHP is
# covered by the syntax check and integration jobs in plugin-ci-workflow.yml.

name: "CodeQL"

on:
push:
branches: [main, develop]
paths-ignore:
- "**/*.md"
pull_request:
branches: [main, develop]
paths-ignore:
- "**/*.md"
schedule:
- cron: "30 1 * * 1"
workflow_dispatch:

concurrency:
group: codeql-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ["javascript-typescript"]
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Initialize CodeQL
uses: github/codeql-action/init@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
with:
category: "/language:${{ matrix.language }}"
84 changes: 42 additions & 42 deletions .github/workflows/plugin-ci-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:

services:
mariadb:
image: mariadb:10.6
image: mariadb:11.8
env:
MYSQL_ROOT_PASSWORD: cactiroot
MYSQL_DATABASE: cacti
Expand All @@ -55,7 +55,7 @@ jobs:
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping"
--health-cmd="mariadb-admin ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
Expand All @@ -64,22 +64,22 @@ jobs:

steps:
- name: Checkout Cacti
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: Cacti/cacti
ref: ${{ env.CACTI }}
path: cacti

- name: Checkout quicktree Plugin
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: cacti/plugins/quicktree

- name: Install PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2
with:
php-version: ${{ matrix.php }}
coverage: xdebug
coverage: pcov
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"

Expand All @@ -90,7 +90,7 @@ jobs:
run: sudo apt-get update

- name: Install System Dependencies
run: sudo apt-get install -y rrdtool fping
run: sudo apt-get install -y rrdtool fping gettext

- name: Setup Permissions
run: |
Expand All @@ -102,20 +102,23 @@ jobs:

- name: Create MySQL Config
run: |
echo "::add-mask::cactiroot"
echo -e "[client]\nuser = root\npassword = cactiroot\nhost = 127.0.0.1\n" > ~/.my.cnf
cat ~/.my.cnf
chmod 600 ~/.my.cnf

- name: Initialize Cacti Database
env:
MYSQL_AUTH_USR: '--defaults-file=~/.my.cnf'
run: |
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 "GRANT ALL PRIVILEGES ON cacti.* TO 'cactiuser'@'localhost';"
mysql $MYSQL_AUTH_USR -e "GRANT SELECT ON mysql.time_zone_name TO 'cactiuser'@'localhost';"
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
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: |
Expand All @@ -134,6 +137,13 @@ jobs:
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 | \
Expand All @@ -143,26 +153,6 @@ jobs:
sed -r "s/'cactiuser'/'cactiuser'/g" > ${{ github.workspace }}/cacti/include/config.php
sudo chmod 664 ${{ github.workspace }}/cacti/include/config.php

- name: Configure Apache
run: |
cat << 'EOF' | sed 's#GITHUB_WORKSPACE#${{ github.workspace }}#g' > /tmp/cacti.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot GITHUB_WORKSPACE/cacti

<Directory GITHUB_WORKSPACE/cacti>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
EOF
sudo cp /tmp/cacti.conf /etc/apache2/sites-available/000-default.conf
sudo systemctl restart apache2

- name: Install Cacti via CLI
run: |
cd ${{ github.workspace }}/cacti
Expand All @@ -176,8 +166,19 @@ jobs:
- name: Check PHP Syntax for Plugin
run: |
cd ${{ github.workspace }}/cacti/plugins/quicktree
if find . -name '*.php' -exec php -l {} 2>&1 \; | grep -iv 'no syntax errors detected'; then
echo "Syntax errors found!"
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

Expand All @@ -190,12 +191,11 @@ jobs:
run: |
cd ${{ github.workspace }}/cacti
include/vendor/bin/pest --configuration=plugins/quicktree/phpunit.xml \
--coverage-clover=plugins/quicktree/coverage/clover.xml \
plugins/quicktree/tests
--coverage-clover=plugins/quicktree/coverage/clover.xml

- name: Upload coverage report
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-php${{ matrix.php }}
path: ${{ github.workspace }}/cacti/plugins/quicktree/coverage/
Expand Down
2 changes: 1 addition & 1 deletion locales/build_gettext.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fi
echo "Updating Cacti language gettext language file..."
cd ${BASE_PATH}

${XGETTEXT_BIN} --no-wrap --copyright-holder="The Cacti Group" --package-name="Cacti" --package-version=`cat include/cacti_version` --msgid-bugs-address="developers@cacti.net" -F -k__gettext -k__ -k__n:1,2 -k__x:1c,2 -k__xn:1c,2,3 -k__esc -k__esc_n:1,2 -k__esc_x:1c,2 -k__esc_xn:1c,2,3 -k__date -o locales/po/cacti.pot `find . -maxdepth 2 -name \*.php`
${XGETTEXT_BIN} --no-wrap --copyright-holder="The Cacti Group" --package-name="Cacti" --package-version=`cat include/cacti_version` --msgid-bugs-address="developers@cacti.net" -F -k__gettext -k__ -k__n:1,2 -k__x:1c,2 -k__xn:1c,2,3 -k__esc -k__esc_n:1,2 -k__esc_x:1c,2 -k__esc_xn:1c,2,3 -k__date -o locales/po/cacti.pot `find . -maxdepth 2 -name \*.php | sort`

sed -i 's/FULL NAME <EMAIL@ADDRESS\>/Howard Jones <howie@thingy.com>/g' locales/po/cacti.pot
sed -i 's/LANGUAGE <LL@li.org>/Howard Jones <howie@thingy.com>/g' locales/po/cacti.pot
Expand Down
Loading
Loading