From e122904c9a5d46b8b92ba72d07fdfc37ba61b6ac Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Mon, 12 Oct 2026 21:48:02 -0700 Subject: [PATCH 1/4] ci: pin fixtures and install locked shared test dependencies Signed-off-by: Thomas Vincent --- .github/workflows/codeql.yml | 2 + .github/workflows/plugin-ci-workflow.yml | 65 +++++++++++++----------- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 334d181..49b2ece 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -47,6 +47,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Initialize CodeQL uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3 with: diff --git a/.github/workflows/plugin-ci-workflow.yml b/.github/workflows/plugin-ci-workflow.yml index 1ced549..157b03a 100644 --- a/.github/workflows/plugin-ci-workflow.yml +++ b/.github/workflows/plugin-ci-workflow.yml @@ -31,6 +31,9 @@ on: - main - develop +permissions: + contents: read + env: # Branch or tag of Cacti/cacti to check out for both jobs below. 1.2.x is # the stable release line and has no Composer dev-dependencies or lint @@ -38,10 +41,15 @@ env: # `if: env.CACTI != '1.2.x'` or install what they need explicitly. Set # this to 'develop' to test against Cacti's Composer-managed tree instead. CACTI: 1.2.x - COMPOSER_ALLOW_SUPERUSER: 1 + CACTI_REF: d6d230f712c0af1a0391646f65364950ebf131af # 1.2.x fixture + +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: integration-test: + timeout-minutes: 45 runs-on: ${{ matrix.os }} strategy: @@ -52,7 +60,7 @@ jobs: services: mariadb: - image: mariadb:11.8 + image: mariadb:11.8@sha256:6422478cb8e159f080fb1d8ccf65101e26fe51385787fde7d16c3b165a331f15 env: MYSQL_ROOT_PASSWORD: cactiroot MYSQL_DATABASE: cacti @@ -72,13 +80,15 @@ jobs: - name: Checkout Cacti uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + persist-credentials: false repository: Cacti/cacti - ref: ${{ env.CACTI }} + ref: ${{ env.CACTI_REF }} path: cacti - name: Checkout Weathermap Plugin uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + persist-credentials: false path: cacti/plugins/weathermap # patch-coverage.php diffs against the base branch below. fetch-depth: 0 @@ -87,6 +97,7 @@ jobs: uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 # 2.40.0 with: php-version: ${{ matrix.php }} + tools: composer:2.10.3 extensions: intl, mysql, gd, ldap, gmp, xml, curl, json, mbstring ini-values: "post_max_size=256M, max_execution_time=60, date.timezone=America/New_York" coverage: xdebug @@ -137,33 +148,25 @@ jobs: 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: | - cd ${{ github.workspace }}/cacti - if [ -f composer.json ]; then - composer validate --strict || true - fi - - # 1.2.x declares no dev dependencies of its own, so require Pest - # explicitly rather than assuming Cacti's composer.json provides it. - # Not run with sudo so the vendor tree stays owned by the runner user, - # which Pest itself needs later to write its result cache. - - name: Install Composer Dependencies - run: | - cd ${{ github.workspace }}/cacti - if [ -f composer.json ]; then - sudo composer config --no-plugins allow-plugins.pestphp/pest-plugin true - sudo composer require --no-progress --no-interaction "pestphp/pest:^3" "pestphp/pest-plugin-drift:^3.0" - sudo rm -f composer.lock - sudo composer install --dev --no-progress - fi - - - name: Restore vendor ownership for Pest - run: | - if [ -d ${{ github.workspace }}/cacti/include/vendor ]; then - sudo chown -R runner:runner ${{ github.workspace }}/cacti/include/vendor ${{ github.workspace }}/cacti/composer.lock - fi - + # Core's release archives exclude .github and tests. Fetch these paths + # through Git at the immutable helper revision instead of an Action archive. + - name: Checkout shared CI tooling + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: Cacti/cacti + ref: f3ff777992875740e4665fedfe2eff8335f5b894 + persist-credentials: false + path: ci-tools + sparse-checkout: | + .github/actions/setup-plugin-dependencies + tests/tools/plugin-harness + + - name: Install locked Cacti and plugin test dependencies + uses: ./ci-tools/.github/actions/setup-plugin-dependencies + with: + cacti-directory: cacti + install-core-dev: 'false' + - name: Create Cacti config.php run: | cat ${{ github.workspace }}/cacti/include/config.php.dist | \ @@ -203,7 +206,7 @@ jobs: - name: Run Pest Unit Tests run: | cd ${{ github.workspace }}/cacti - include/vendor/bin/pest --configuration=plugins/weathermap/phpunit.xml \ + "$CACTI_PEST_BIN" --configuration=plugins/weathermap/phpunit.xml \ --coverage-clover=plugins/weathermap/coverage/clover.xml # Whole-file coverage is meaningless here: most of the plugin only runs From 936ff4e1427fc8ee6cfdc7cf5a95fdcadf950c6e Mon Sep 17 00:00:00 2001 From: Thomas Vincent Date: Sat, 17 Oct 2026 14:17:44 -0700 Subject: [PATCH 2/4] docs(changelog): keep CI hardening outside released 2.0 notes Signed-off-by: Thomas Vincent --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cbcc8b..7d808e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ IMPORTANT NOTE: This version only works on CACTI 1.x++! ## Changes +--- develop --- + +* security: Pin CI fixtures and shared test dependencies, disable persisted checkout credentials, and limit workflow permissions and runtime + --- 2.0 --- * security: Add a version-safe CSP nonce (`plugin_weathermap_csp_nonce()`) to every inline `