Skip to content

Standardize schema management: api_plugin_db_table_create() + db_update_table() - #86

Merged
cigamit merged 16 commits into
developfrom
feature/schema-api-db-update-table
Oct 1, 2026
Merged

cigamit merged 16 commits into
developfrom
feature/schema-api-db-update-table

Conversation

@TheWitness

@TheWitness TheWitness commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Standardize schema management (api_plugin_db_table_create + db_update_table) and add the fleet file manifest

Adds the fleet-wide manifest.json + upgrade-time file-pruning mechanism.

  • File manifest + upgrade pruning — new root manifest.json with tombstones (empty), expected (top-level files/directories shipping today, directories with a trailing /), and whitelist (empty). gexport_prune_files() (in setup.php, called from the version-change block of gexport_check_upgrade()) removes the dev-only tests/ tree on upgrade, refuses any path that resolves outside the plugin directory (a tampered manifest.json), warns on any file/directory it cannot remove, leaves whitelist/.git* alone, and logs — without removing — any top-level entry the manifest does not account for.
  • tests/bin/validate-manifest.php (wired into plugin-ci-workflow.yml) fails on drift between expected and the real top-level tree.
  • Tests — added PruneFilesTest; sandboxed base_path file-wide in GexportLifecycleTest (pre-loading the real includes/database.php) so its upgrade-path tests run the prune against a throwaway tree.

Validation

Full Pest suite green (63 passed) and patch-coverage passes at 100% (166/166 changed measured lines); manifest drift-check passes and the translation template is up to date.

Revision: hardening & fleet cleanup

Since the initial description, this PR also:

  • Prunes phpunit.xml on upgrade (alongside the dev-only tests/ tree) and leaves .md* lint configs in place — the drift check now ignores tests/, phpunit.xml, .git*, .md*, and whitelisted paths.
  • Hardens the prune against tampered manifests: refuses any tombstone whose normalized path contains a ./.. traversal segment or resolves outside the plugin directory (including via a symlinked directory), and protects a directory when a whitelisted entry lives beneath it — each with added unit coverage.
  • Renames the prune helpers to the documented naming convention: gexport_prune_files() / gexport_rmtree() (the plugin_gexport_ prefix is reserved for lifecycle/hook-registration functions).
  • Gives tests/Unit/PruneFilesTest.php the full standard GPL v2 header and aligns the Project Structure block in .github/copilot-instructions.md.

Replace the raw CREATE TABLE install and the version-gated ALTER TABLE upgrade migrations for graph_exports/graph_exports_tasks with the plugin schema API: a single *_table_data() definition per table, api_plugin_db_table_create() on install, and db_update_table() (else create) on upgrade. The one historical column rename is kept as a guarded pre-step since db_update_table() can not rename. Tests and copilot-instructions updated to the new pattern.
Copilot AI balanced review requested due to automatic review settings September 29, 2026 21:51

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

Existing-table upgrades can throw type errors, preserve an incorrect column default, and currently break a lifecycle test.

Review effort: Balanced
Findings: 2 High severity · 1 Medium severity

Open (3)
What changed in this PR

Standardizes gexport table installation and upgrades using Cacti’s schema APIs and shared definitions.

Changes:

  • Adds canonical definitions for both plugin tables.
  • Replaces raw schema migrations with create/update APIs.
  • Updates tests, guidance, and changelog documentation.
File Description
setup.php Implements shared schema definitions and upgrade refreshes.
tests/​bootstrap-unit.php Records schema API calls in test stubs.
tests/​Unit/​GexportSetupTableTest.php Verifies tracked table creation.
tests/​Integration/​GexportInstallHooksTest.php Verifies installation provisions both tables.
.github/​copilot-instructions.md Documents the standardized schema pattern.
CHANGELOG.md Records the schema-management refactor.

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

Comment thread setup.php
Comment thread setup.php Outdated
Comment thread setup.php Outdated
Copilot and others added 6 commits September 29, 2026 18:14
All table definitions and the create/upgrade/drop helpers now live in includes/database.php (with the Cacti copyright header); setup.php's install/uninstall/upgrade paths include it and delegate. Behavior is unchanged - api_plugin_db_table_create() on install, db_update_table()-else-create refresh on upgrade.
Switches every file inclusion from include/include_once to require/require_once for fail-fast consistency, and relocates the functions.php and gexport_security.php library files into includes/ (updating all references across setup.php, gexport.php, poller_export.php, and the tests). export_graph_monitor_tasks() now resolves poller_export.php via __DIR__/../ since functions.php moved down a directory.
The gettext location comments (--add-location=file) and entry ordering in
locales/po/cacti.pot are derived from the sorted list of scanned PHP files.
Moving functions.php and gexport_security.php into includes/ reordered those
references, so regenerate the template to match. No translatable strings were
added or removed (msgid set is unchanged); only source-location comments and
ordering differ.
…e gaps

The Enforce-coverage gate failed because pcov auto-scopes to the Composer
root (cacti/) and skips cacti/plugins/, so no plugin source was instrumented.
The coverage <source> set also still referenced the pre-move functions.php /
gexport_security.php paths and omitted the new includes/database.php.

- Switch the setup-php coverage driver from pcov to xdebug (matches the
  ci/coverage-xdebug rollout) so this plugin's own sources are measured.
- Point the coverage <source> set at includes/functions.php and
  includes/gexport_security.php and add includes/database.php.
- Update the stale GexportLifecycleTest assertion: the upgrade path now writes
  plugin_config via db_execute_prepared (not db_execute), and add a test that
  exercises gexport_upgrade_tables()'s legacy-column rename pre-step and the
  db_update_table() refresh branch (the previously-uncovered changed lines).
  Route the db_column_exists() test stub through the fixture layer so the
  rename branch can be driven.
- Allowlist the entry points gexport.php (web UI) and poller_export.php (CLI),
  which cannot load in the isolated unit process, in tests/bin/patch-coverage.php.
…-db-update-table

# Conflicts:
#	CHANGELOG.md
@TheWitness

Copy link
Copy Markdown
Member Author

This branch now also sets the plugin's INFO compat (minimum supported Cacti version) to 1.2.32, added in the latest commit as part of the fleet-wide compat standardization.

…pdate_table on 1.2.x does not reconcile column defaults)
browniebraun
browniebraun previously approved these changes Sep 30, 2026
Copilot added 5 commits September 30, 2026 19:48
phpunit.xml ships in the repo for CI but is a dev-only test artifact, so it
is removed from manifest.json 'expected', pruned from installs on upgrade
(like tests/), and excluded from the manifest drift check.

The retired markdown-lint configs (.mdlrc, .md_style.rb) are deleted, and
.md* is now ignored like .git*: protected from pruning and excluded from
drift if it reappears.
The upgrade-time prune now rejects any tombstone containing '.'/'..' segments
(which could escape the plugin directory or resolve to its root) and treats
ancestors of whitelist entries as protected, so a tombstone on a parent
directory can no longer delete a whitelisted file beneath it.
The trailing '# ...' comments in the Project Structure block drifted further
right down the tree; align them all to a single column.
- Use the full license header (from the plugin's own setup.php) in
  tests/Unit/PruneFilesTest.php instead of the abbreviated copyright banner.
- Document that the manifest drift check and the upgrade-time prune also
  handle phpunit.xml and .md* files, matching the implemented behavior.
The repository naming contract reserves the plugin_<name>_ prefix for plugin
lifecycle / hook-registration functions; all other functions use the plain
<name>_ prefix. Rename the internal upgrade helpers accordingly:

  plugin_<name>_prune_files() -> <name>_prune_files()
  plugin_<name>_rmtree()      -> <name>_rmtree()

The call site, unit tests, and the copilot-instructions.md references are
updated to match. No behavioral change.
@cigamit
cigamit merged commit aaaa9a7 into develop Oct 1, 2026
3 checks passed
@cigamit
cigamit deleted the feature/schema-api-db-update-table branch October 1, 2026 06:42
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.

4 participants