From 08f1596f6a1aed607f3a952165ad5d5ee537d326 Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Mon, 17 Aug 2026 15:07:34 -0700 Subject: [PATCH 1/3] docs: document the Pest testing workflow --- .../{php-unit-tests.yml => pest-tests.yml} | 0 .github/workflows/plugin-ci-workflow.yml | 28 +++++++---- README.md | 8 ++++ docs/TESTING.md | 47 +++++++++++++++++++ 4 files changed, 73 insertions(+), 10 deletions(-) rename .github/workflows/{php-unit-tests.yml => pest-tests.yml} (100%) create mode 100644 docs/TESTING.md diff --git a/.github/workflows/php-unit-tests.yml b/.github/workflows/pest-tests.yml similarity index 100% rename from .github/workflows/php-unit-tests.yml rename to .github/workflows/pest-tests.yml diff --git a/.github/workflows/plugin-ci-workflow.yml b/.github/workflows/plugin-ci-workflow.yml index 5e4f3db6..e17554e8 100644 --- a/.github/workflows/plugin-ci-workflow.yml +++ b/.github/workflows/plugin-ci-workflow.yml @@ -35,21 +35,12 @@ jobs: integration-test: runs-on: ${{ matrix.os }} - # A failure against the pinned release is a real failure. The develop entry - # is advisory: it is how a core regression becomes visible here, but it must - # not turn the plugin's own pull requests red. - continue-on-error: ${{ matrix.cacti != 'release/1.2.31' }} - strategy: fail-fast: false matrix: php: ['8.1', '8.2', '8.3', '8.4'] os: [ubuntu-latest] cacti: ['release/1.2.31'] - include: - - php: '8.4' - os: ubuntu-latest - cacti: 'develop' services: mariadb: @@ -95,7 +86,24 @@ jobs: echo "PHP_BINARY=$(command -v php)" >> "$GITHUB_ENV" - name: Run apt-get update - run: sudo apt-get update + run: | + for attempt in 1 2 3; do + if sudo timeout 3m apt-get \ + -o Dpkg::Lock::Timeout=60 \ + -o Acquire::Retries=3 \ + -o Acquire::http::Timeout=30 \ + -o Acquire::https::Timeout=30 \ + update; then + exit 0 + fi + + if [ "$attempt" -lt 3 ]; then + sleep 10 + fi + done + + echo 'apt-get update failed after three bounded attempts.' >&2 + exit 1 - name: Install System Dependencies run: sudo apt-get install -y apache2 snmp snmpd rrdtool fping diff --git a/README.md b/README.md index 46310dce..6f470e84 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,14 @@ different sources. These forks of thold are not necessarily compatible with the current version of Cacti's thold plugin. Please be aware of this when installing thold for the first time. +## Development and testing + +Thold's unit suite runs with [Pest](https://pestphp.com/) and the Composer +toolchain supplied by Cacti. The plugin intentionally does not maintain its +own `composer.json`, `composer.lock`, or vendor directory. See +[Testing and contributing](docs/TESTING.md) for the supported local workflow, +test layout, and pull request checks. + ## Authors The thold plugin has been in development for well over a decade with increasing diff --git a/docs/TESTING.md b/docs/TESTING.md new file mode 100644 index 00000000..edbb0e04 --- /dev/null +++ b/docs/TESTING.md @@ -0,0 +1,47 @@ +# Testing and contributing + +Thold uses Pest for unit tests and Cacti's Composer toolchain for dependencies. +Keeping one toolchain avoids a second dependency graph inside the plugin and +ensures local tests exercise the same versions used by Cacti. + +## Repository policy + +- Write new unit and regression tests as Pest tests under `tests/Unit`. +- Do not add a plugin-local `composer.json`, `composer.lock`, or `vendor` + directory. +- Keep `phpunit.xml`. Pest reads this compatibility configuration for bootstrap, + suite, and coverage settings; its filename does not mean PHPUnit is run + directly. +- Run the complete unit suite before opening or updating a pull request. + +## Run the tests locally + +Place the plugin at `plugins/thold` in a Cacti checkout whose Composer +dependencies are installed, then run from the Cacti root: + +```console +composer test -- --configuration=plugins/thold/phpunit.xml plugins/thold/tests/Unit +``` + +To run one test file while developing: + +```console +composer test -- --configuration=plugins/thold/phpunit.xml plugins/thold/tests/Unit/TholdRpnCdefTest.php +``` + +The pull request workflow is the reproducible reference environment. It builds +Cacti's pinned Docker test image, mounts Thold into a pinned Cacti runtime, runs +PHP linting, runs Pest with coverage, and requires full coverage of lines added +by a pull request. Review `.github/workflows/pest-tests.yml` when reproducing +the exact CI commands or pinned Cacti revisions. + +## Pull request checklist + +Before pushing a branch: + +1. Run the Pest suite and any focused tests for the changed behavior. +2. Confirm every changed PHP file passes the Cacti Composer lint script. +3. Confirm `composer.json`, `composer.lock`, `vendor`, and generated coverage + output are not included in the diff. +4. Rebase or update the branch against the current target branch and resolve + conflicts before requesting review. From bd525663a31cf257cba32b6c9ef9d055eaac7fa7 Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Mon, 17 Aug 2026 15:16:18 -0700 Subject: [PATCH 2/3] ci: retry transient Pest image builds --- .github/workflows/pest-tests.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pest-tests.yml b/.github/workflows/pest-tests.yml index 89eb1ad4..da6cba4a 100644 --- a/.github/workflows/pest-tests.yml +++ b/.github/workflows/pest-tests.yml @@ -72,8 +72,19 @@ jobs: # Thold contributes no parallel vendor directory or PHPUnit dependency. - name: Build Cacti test image run: | - docker build --tag cacti-web --file cacti-toolchain/docker/Dockerfile cacti-toolchain/docker - docker build --tag cacti-thold-test --file cacti-toolchain/docker/Dockerfile.test cacti-toolchain + for attempt in 1 2 3; do + if docker build --tag cacti-web --file cacti-toolchain/docker/Dockerfile cacti-toolchain/docker && \ + docker build --tag cacti-thold-test --file cacti-toolchain/docker/Dockerfile.test cacti-toolchain; then + exit 0 + fi + + if [ "$attempt" -lt 3 ]; then + sleep 10 + fi + done + + echo 'Cacti test image build failed after three attempts.' >&2 + exit 1 - name: Lint every PHP source file run: | From beca246294b528279b05729d727bd97ea0fdce04 Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Mon, 17 Aug 2026 18:34:39 -0700 Subject: [PATCH 3/3] ci: retry transient Composer downloads --- .github/workflows/plugin-ci-workflow.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/plugin-ci-workflow.yml b/.github/workflows/plugin-ci-workflow.yml index e17554e8..73630b54 100644 --- a/.github/workflows/plugin-ci-workflow.yml +++ b/.github/workflows/plugin-ci-workflow.yml @@ -149,7 +149,18 @@ jobs: run: | cd ${{ github.workspace }}/cacti if [ -f composer.json ]; then - sudo composer install --prefer-dist --no-progress + for attempt in 1 2 3; do + if sudo composer install --prefer-dist --no-progress --no-interaction; then + exit 0 + fi + + if [ "$attempt" -lt 3 ]; then + sleep 10 + fi + done + + echo 'Composer install failed after three attempts.' >&2 + exit 1 fi - name: Create Cacti config.php