Skip to content

chore: harmonize CI workflow, templates, and test structure - #29

Merged
TheWitness merged 8 commits into
developfrom
chore/ci-and-template-harmonization
Sep 21, 2026
Merged

TheWitness merged 8 commits into
developfrom
chore/ci-and-template-harmonization

Conversation

@TheWitness

Copy link
Copy Markdown
Member

Description

Second repo in the fleet-wide plugin_* CI/template/test-structure
harmonization effort (see plugin_analytics#8 for the first). This repo was
actually used as the reference template for the composer-install/poller
pattern, so most of it was already compliant — the diff here is smaller.

Changes

  • MySQL password logging fix: same fix just applied to
    plugin_analytics after Copilot review flagged it there — cat ~/.my.cnf
    printed the root password into the Actions log; replaced with chmod 600.
  • MySQL bootstrap hardening: quoted --defaults-file, grants added for
    both 'cactiuser'@'localhost' and 'cactiuser'@'127.0.0.1' (previously
    localhost-only).
  • PHP syntax check: switched to the vendor-excluding, null-delimited
    find/xargs pattern from plugin_audit.
  • No CodeQL workflow added: this repo has no JavaScript/Python/Ruby
    content (PHP + Shell only), so there's nothing for CodeQL to scan.
  • PHP compatibility tests consolidated: this repo uniquely had both
    tests/Security/Php74CompatibilityTest.php and
    tests/Security/Php82CompatibilityTest.php side by side. Merged into a
    single tests/Security/PhpCompatibilityTest.php checking only for PHP
    8.3/8.4-only syntax (this plugin's floor is PHP 8.2 per the CI matrix).
  • Removed dead tests/TestCase.php: not referenced by any
    uses(TestCase::class) call in this plugin's actual tests. Removed the
    now-dead require_once for it in tests/bootstrap-unit.php too.
  • Issue/PR templates added: this repo had none before. Added
    .github/ISSUE_TEMPLATE/bug_report.md, feature_request.md, and
    .github/PULL_REQUEST_TEMPLATE.md, styled after Cacti/cacti's own templates.
  • copilot-instructions.md: documented the CI/dependency baselines (no
    plugin-local composer.json/composer.lock/phpstan/php-cs-fixer config;
    prefer cacti_count()/cacti_sizeof()).

Everything else (pinned Actions, the "Restore vendor ownership for Pest"
step, no Configure Apache step, the bespoke "Wait for background apcupsd
poller" step, the log-failure gate) was already in place here and used as
the template for the rest of the fleet.

Related Issue

N/A — internal fleet harmonization, not tracked against a specific issue.

How Has This Been Tested?

  • The modified workflow YAML was parsed and validated locally
    (powershell-yaml) before pushing.
  • Full CI (Plugin Integration Tests) will run automatically on this PR.

Types of changes

  • Non-breaking maintenance/CI change

Checklist

  • My change follows the fleet-wide harmonization conventions being rolled
    out across plugin_* repos.

Part of the fleet-wide plugin_* harmonization effort (2nd repo after
plugin_analytics).

- Stop logging the MySQL root password in CI output (cat ~/.my.cnf ->
  chmod 600), same fix just applied to plugin_analytics per Copilot review.
- Harden MySQL bootstrap: quoted --defaults-file, grants added for both
  'cactiuser'@'localhost' and 'cactiuser'@'127.0.0.1'.
- Switch the PHP syntax-check step to the vendor-excluding, null-delimited
  find/xargs pattern used in plugin_audit.
- No CodeQL workflow added: this repo has no JavaScript/Python/Ruby content
  (PHP + Shell only per repo language stats), so there is nothing for
  CodeQL to scan.
- Consolidate tests/Security/Php74CompatibilityTest.php AND
  tests/Security/Php82CompatibilityTest.php (this repo had both) into a
  single tests/Security/PhpCompatibilityTest.php, now checking for PHP
  8.3/8.4-only syntax only (this plugin's floor is PHP 8.2 per the CI
  matrix), replacing the now-moot PHP 7.4-vs-8.0 checks.
- Remove tests/TestCase.php and its require in tests/bootstrap-unit.php: no
  test in this plugin actually uses `uses(TestCase::class)` (verified via an
  org-wide code search); it was unused boilerplate.
- Add .github/ISSUE_TEMPLATE/{bug_report,feature_request}.md and
  .github/PULL_REQUEST_TEMPLATE.md, styled after Cacti/cacti's own templates
  (this repo previously had none).
- Document CI/dependency baselines in copilot-instructions.md: no plugin-local
  composer.json/composer.lock or phpstan/php-cs-fixer config (use Cacti's),
  and prefer cacti_count()/cacti_sizeof() over count()/sizeof().

Everything else (pinned Actions, "Restore vendor ownership for Pest" step,
no Configure Apache step, the bespoke "Wait for background apcupsd poller"
step, the log-failure gate) was already in place in this repo and used as
the template for the rest of the fleet.
Copilot AI lite review requested due to automatic review settings September 21, 2026 14:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The consolidated PhpCompatibilityTest currently has gaps/bugs in its guards (missing checks and attribute matching) that weaken the stated PHP 8.2-compatibility guarantee.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 4 Medium severity · 1 Low severity

Open (5)
What changed in this PR

This PR continues the fleet-wide harmonization of plugin_* repositories by aligning CI workflow behavior, test structure, and GitHub templates with the shared conventions used across the Cacti plugin ecosystem.

Changes:

  • Hardened GitHub Actions MySQL bootstrap (avoid logging credentials, safer --defaults-file usage, grants for both localhost and 127.0.0.1).
  • Consolidated PHP compatibility/security tests by replacing per-version compatibility test files with a single recursive PhpCompatibilityTest.
  • Added standard GitHub issue/PR templates and updated repo Copilot guidance to document CI/dependency baselines.
File Description
.github/​workflows/​plugin-ci-workflow.yml CI hardening: avoids password logging, improves MySQL bootstrap, and updates PHP syntax checking to a vendor-excluding `find
tests/​Security/​PhpCompatibilityTest.php New consolidated compatibility test scanning all production PHP files for PHP 8.3/8.4-only constructs.
tests/​Security/​Php82CompatibilityTest.php Removed in favor of the consolidated compatibility test.
tests/​Security/​Php74CompatibilityTest.php Removed (plugin floor is PHP 8.2 per CI matrix).
tests/​bootstrap-unit.php Removes dead TestCase.php bootstrap include.
tests/​TestCase.php Deleted unused PHPUnit base class.
.github/​PULL_REQUEST_TEMPLATE.md Adds a standard PR template.
.github/​ISSUE_TEMPLATE/​bug_report.md Adds a standard bug report template.
.github/​ISSUE_TEMPLATE/​feature_request.md Adds a standard feature request template.
.github/​copilot-instructions.md Documents CI/dependency baselines and preferred conventions for generated changes.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/Security/PhpCompatibilityTest.php Outdated
Comment thread tests/Security/PhpCompatibilityTest.php Outdated
Comment thread tests/Security/PhpCompatibilityTest.php Outdated
Comment thread tests/Security/PhpCompatibilityTest.php
Comment thread tests/Security/PhpCompatibilityTest.php Outdated
- Document the locales/build_gettext.sh + cacti.pot workflow in
  copilot-instructions.md (Weblate owns per-language .po/.mo sync).
- Add a CI step that regenerates cacti.pot and fails if it is stale,
  ignoring the POT-Creation-Date timestamp.
- Mark locales/build_gettext.sh executable.
- Bump the CI MariaDB service image floor to 11.8 (from mariadb:10.6 /
  mysql:8.0).
- mariadb:11.8 no longer ships mysqladmin; use mariadb-admin for the
  service container healthcheck.
- Run chmod/build_gettext.sh with sudo in the i18n verification step,
  since locales/ is owned by www-data by the time it runs.
Ran the real locales/build_gettext.sh (xgettext/msgmerge/msgfmt) to
refresh the translation template against current source. Per the i18n
workflow documented in copilot-instructions.md, only the regenerated
cacti.pot is committed here; Weblate owns syncing the per-language
.po/.mo files from it.
…ibilityTest

Matches the project's PSR coding standard (short array syntax, single
quotes for non-interpolated strings) that php-cs-fixer enforces in CI.
`find` without `sort` returns filesystem/readdir-order results, which
can differ between machines (e.g. a local regen vs. a GitHub Actions
runner), producing a spurious reordering diff in cacti.pot even when
no strings actually changed. Pipe through `sort` and regenerate
cacti.pot with the now-deterministic order.
- tests/Security/PhpCompatibilityTest.php: fixed the #[Override]/#[Deprecated]
  attribute regexes to also match the fully qualified (`#[\Override]`,
  `#[\Deprecated]`) form, added a realpath() false-guard for the plugin root,
  included the relative file path in both RuntimeException messages, added
  typed-class-constant and dynamic-class-constant-fetch checks (PHP 8.3), and
  restored each()/create_function() removed-in-PHP-8.0 guards that the
  consolidation had dropped. Also excludes include/vendor/ (not just vendor/)
  from the recursive source scan.
- .github/workflows/plugin-ci-workflow.yml: the "Create MySQL Config" step's
  root password is now masked via `::add-mask::` before it's echoed into
  ~/.my.cnf, so it no longer appears in plaintext in the Actions log (chmod
  600 alone only protected the file after creation, not the command's own
  echoed source in the log).
@TheWitness

Copy link
Copy Markdown
Member Author

This PR's tests/Security/PhpCompatibilityTest.php #[Override]/#[Deprecated] regexes now also match the fully qualified form (#[\Override], #[\Deprecated]), a realpath() false-guard was added for the plugin root, both exception messages now include the relative file path, typed-class-constant and dynamic-class-constant-fetch checks (PHP 8.3) were added, and each()/create_function() (removed in PHP 8.0) guards were restored. The CI workflow's MySQL root password is now masked via ::add-mask:: before being written to ~/.my.cnf, so it no longer appears in plaintext in the Actions log. Resolving the corresponding review threads.

The each()-removed-in-PHP-8.0 check matched jQuery's $.each(/.each(
calls too, which have nothing to do with the removed PHP global
function. Exclude any each( preceded by . or > via a negative
lookbehind.
@TheWitness
TheWitness merged commit befdcd8 into develop Sep 21, 2026
3 checks passed
@TheWitness
TheWitness deleted the chore/ci-and-template-harmonization branch September 21, 2026 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants