diff --git a/.github/workflows/php-unit-tests.yml b/.github/workflows/pest-tests.yml similarity index 90% rename from .github/workflows/php-unit-tests.yml rename to .github/workflows/pest-tests.yml index 89eb1ad4..da6cba4a 100644 --- a/.github/workflows/php-unit-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: | diff --git a/.github/workflows/plugin-ci-workflow.yml b/.github/workflows/plugin-ci-workflow.yml index 5e4f3db6..73630b54 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 @@ -141,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 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.