From f1d4a00d1fb4a4967906fdfae10e7a11158e8ac7 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Tue, 4 Aug 2026 14:18:22 +1200 Subject: [PATCH 1/9] Add reusable PHPCS and AI-checklist workflows for plugin repos, PG-4897 matomo-tests.yml is deliberately excluded: it is produced by core's generate:test-action and varies per plugin, so its centralization path is through that generator. --- .github/workflows/plugin-ai-checklist.yml | 25 +++++++++++ .github/workflows/plugin-phpcs.yml | 54 +++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 .github/workflows/plugin-ai-checklist.yml create mode 100644 .github/workflows/plugin-phpcs.yml diff --git a/.github/workflows/plugin-ai-checklist.yml b/.github/workflows/plugin-ai-checklist.yml new file mode 100644 index 0000000..36eefba --- /dev/null +++ b/.github/workflows/plugin-ai-checklist.yml @@ -0,0 +1,25 @@ +name: AI Checklist + +on: + workflow_call: {} + +permissions: + actions: read + checks: none + contents: none + deployments: none + issues: none + packages: none + pull-requests: read + repository-projects: none + security-events: none + statuses: none + +jobs: + AiChecklist: + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + steps: + - name: Run tests + uses: matomo-org/github-action-checklist-gate@main diff --git a/.github/workflows/plugin-phpcs.yml b/.github/workflows/plugin-phpcs.yml new file mode 100644 index 0000000..4ddb7cc --- /dev/null +++ b/.github/workflows/plugin-phpcs.yml @@ -0,0 +1,54 @@ +name: PHPCS check + +on: + workflow_call: + inputs: + plugin-name: + description: "Name of the plugin, e.g. LoginLdap" + required: true + type: string + php-version: + description: "PHP version the job runs on" + required: false + type: string + default: '7.4' + +permissions: + actions: read + checks: read + contents: read + deployments: none + issues: read + packages: none + pull-requests: read + repository-projects: none + security-events: none + statuses: read + +jobs: + phpcs: + name: PHPCS + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + with: + lfs: false + persist-credentials: false + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 + with: + php-version: ${{ inputs.php-version }} + tools: cs2pr + - name: Install dependencies + run: + composer init --name=matomo/$(echo '${{ inputs.plugin-name }}' | tr '[:upper:]' '[:lower:]') --quiet; + composer --no-plugins config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true -n; + composer config repositories.matomo-coding-standards vcs https://github.com/matomo-org/matomo-coding-standards -n; + composer require matomo-org/matomo-coding-standards:dev-master; + composer install --dev --prefer-dist --no-progress --no-suggest + - name: Check PHP code styles + id: phpcs + run: ./vendor/bin/phpcs --report-full --standard=phpcs.xml --report-checkstyle=./phpcs-report.xml + - name: Show PHPCS results in PR + if: ${{ always() && steps.phpcs.outcome == 'failure' }} + run: cs2pr ./phpcs-report.xml --prepend-filename From 399573d612ca7b3c4ee0c8779d97f54631464597 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Tue, 4 Aug 2026 14:21:01 +1200 Subject: [PATCH 2/9] Pass the plugin name to the shell via env rather than template interpolation --- .github/workflows/plugin-phpcs.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/plugin-phpcs.yml b/.github/workflows/plugin-phpcs.yml index 4ddb7cc..fa35739 100644 --- a/.github/workflows/plugin-phpcs.yml +++ b/.github/workflows/plugin-phpcs.yml @@ -40,8 +40,10 @@ jobs: php-version: ${{ inputs.php-version }} tools: cs2pr - name: Install dependencies + env: + PLUGIN_NAME: ${{ inputs.plugin-name }} run: - composer init --name=matomo/$(echo '${{ inputs.plugin-name }}' | tr '[:upper:]' '[:lower:]') --quiet; + composer init --name=matomo/$(echo "$PLUGIN_NAME" | tr '[:upper:]' '[:lower:]') --quiet; composer --no-plugins config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true -n; composer config repositories.matomo-coding-standards vcs https://github.com/matomo-org/matomo-coding-standards -n; composer require matomo-org/matomo-coding-standards:dev-master; From ea97f2e11a2561b49cf35c3aaa8232fc6fd8c9fe Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Tue, 4 Aug 2026 14:35:49 +1200 Subject: [PATCH 3/9] Validate the plugin name up front --- .github/workflows/plugin-phpcs.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/plugin-phpcs.yml b/.github/workflows/plugin-phpcs.yml index fa35739..4e5e4df 100644 --- a/.github/workflows/plugin-phpcs.yml +++ b/.github/workflows/plugin-phpcs.yml @@ -30,6 +30,15 @@ jobs: name: PHPCS runs-on: ubuntu-24.04 steps: + - name: Validate inputs + env: + PLUGIN_NAME: ${{ inputs.plugin-name }} + run: | + if [[ ! "$PLUGIN_NAME" =~ ^[A-Za-z0-9_]+$ ]]; then + echo "Invalid plugin-name: $PLUGIN_NAME" + exit 1 + fi + - uses: actions/checkout@v4 with: lfs: false From 8add14af249428c70b703273b7720b7010d3be07 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Tue, 4 Aug 2026 14:52:05 +1200 Subject: [PATCH 4/9] Pin all actions to commit SHAs --- .github/workflows/plugin-phpcs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/plugin-phpcs.yml b/.github/workflows/plugin-phpcs.yml index 4e5e4df..d4d4f2e 100644 --- a/.github/workflows/plugin-phpcs.yml +++ b/.github/workflows/plugin-phpcs.yml @@ -39,7 +39,7 @@ jobs: exit 1 fi - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 with: lfs: false persist-credentials: false From b17ac7bcca95f5f48d78f918ad2d0953b3fd26ac Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Tue, 4 Aug 2026 15:00:25 +1200 Subject: [PATCH 5/9] Pin the checklist gate by SHA and document both reusable workflows Centralizing removes the reason the gate floated on main: an update is now one SHA bump here instead of a change in every plugin repo. The README section will conflict trivially with #44's; whichever merges second rebases the append. --- .github/workflows/plugin-ai-checklist.yml | 2 +- README.md | 32 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.github/workflows/plugin-ai-checklist.yml b/.github/workflows/plugin-ai-checklist.yml index 36eefba..be6b7e4 100644 --- a/.github/workflows/plugin-ai-checklist.yml +++ b/.github/workflows/plugin-ai-checklist.yml @@ -22,4 +22,4 @@ jobs: fail-fast: false steps: - name: Run tests - uses: matomo-org/github-action-checklist-gate@main + uses: matomo-org/github-action-checklist-gate@d5f101a2538ef30ddb3b06cc366f852c9851b588 # main as of 2026-08-04 diff --git a/README.md b/README.md index c4c668b..f7ea5df 100644 --- a/README.md +++ b/README.md @@ -154,3 +154,35 @@ This action is able to run certain test suites for Matomo or any Matomo plugin. dependent-plugins: 'slug/plugin-AdditionalPlugin' github-token: ${{ secrets.TESTS_ACCESS_TOKEN || secrets.GITHUB_TOKEN }} ``` + +### PHPCS (`.github/workflows/plugin-phpcs.yml`) + +Runs the plugin's own `phpcs.xml` against the matomo-coding-standards ruleset. Inputs: +`plugin-name` (required), `php-version` (optional, default `7.4`). + +```yaml +name: PHPCS check +on: pull_request +jobs: + phpcs: + uses: matomo-org/github-action-tests/.github/workflows/plugin-phpcs.yml@main + with: + plugin-name: MyPlugin +``` + +### AI Checklist (`.github/workflows/plugin-ai-checklist.yml`) + +Runs the org's checklist gate against the pull request description. No inputs. + +```yaml +name: AI Checklist +on: + pull_request: + types: [opened, synchronize, reopened, edited] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +jobs: + AiChecklist: + uses: matomo-org/github-action-tests/.github/workflows/plugin-ai-checklist.yml@main +``` From 74ca2cf17cd39e40f1f645e99e33856129740a44 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Tue, 4 Aug 2026 15:02:38 +1200 Subject: [PATCH 6/9] Document the pinning trade-off for the workflow references --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index f7ea5df..9573409 100644 --- a/README.md +++ b/README.md @@ -186,3 +186,11 @@ jobs: AiChecklist: uses: matomo-org/github-action-tests/.github/workflows/plugin-ai-checklist.yml@main ``` + +Both examples use `@main` to match how plugin repositories currently consume this repository. +For immutability, pin the `uses:` reference to a full commit SHA — release tags stay mutable +unless the repository enforces immutable releases: + +```yaml + uses: matomo-org/github-action-tests/.github/workflows/plugin-phpcs.yml@ +``` From d915c8325289f4ee5d7df252f3bf188d51fc5235 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Tue, 4 Aug 2026 15:11:31 +1200 Subject: [PATCH 7/9] Grant callers-compatible minimal permissions A called workflow cannot request more than its caller holds, so the inherited blanket read scopes made every default-permission caller fail at startup. PHPCS needs only contents: read; the checklist gate needs pull-requests: read, which its callers grant explicitly. --- .github/workflows/plugin-ai-checklist.yml | 10 ++-------- .github/workflows/plugin-phpcs.yml | 11 ++--------- README.md | 3 +++ 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/.github/workflows/plugin-ai-checklist.yml b/.github/workflows/plugin-ai-checklist.yml index be6b7e4..70ecdef 100644 --- a/.github/workflows/plugin-ai-checklist.yml +++ b/.github/workflows/plugin-ai-checklist.yml @@ -3,17 +3,11 @@ name: AI Checklist on: workflow_call: {} +# The gate reads the pull request description; callers must grant these two +# scopes in their own permissions block. permissions: actions: read - checks: none - contents: none - deployments: none - issues: none - packages: none pull-requests: read - repository-projects: none - security-events: none - statuses: none jobs: AiChecklist: diff --git a/.github/workflows/plugin-phpcs.yml b/.github/workflows/plugin-phpcs.yml index d4d4f2e..ea6f581 100644 --- a/.github/workflows/plugin-phpcs.yml +++ b/.github/workflows/plugin-phpcs.yml @@ -13,17 +13,10 @@ on: type: string default: '7.4' +# The job only reads the repository; everything else stays at none so any caller +# with default workflow permissions can use this without granting scopes. permissions: - actions: read - checks: read contents: read - deployments: none - issues: read - packages: none - pull-requests: read - repository-projects: none - security-events: none - statuses: read jobs: phpcs: diff --git a/README.md b/README.md index 9573409..67be083 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,9 @@ name: AI Checklist on: pull_request: types: [opened, synchronize, reopened, edited] +permissions: + actions: read + pull-requests: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true From 66feecfa3cc786be65e440cc3a3d3c22f4de7e89 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Tue, 4 Aug 2026 15:11:52 +1200 Subject: [PATCH 8/9] Quote the derived composer package name --- .github/workflows/plugin-phpcs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/plugin-phpcs.yml b/.github/workflows/plugin-phpcs.yml index ea6f581..8c45ad3 100644 --- a/.github/workflows/plugin-phpcs.yml +++ b/.github/workflows/plugin-phpcs.yml @@ -45,7 +45,7 @@ jobs: env: PLUGIN_NAME: ${{ inputs.plugin-name }} run: - composer init --name=matomo/$(echo "$PLUGIN_NAME" | tr '[:upper:]' '[:lower:]') --quiet; + composer init --name="matomo/$(echo "$PLUGIN_NAME" | tr '[:upper:]' '[:lower:]')" --quiet; composer --no-plugins config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true -n; composer config repositories.matomo-coding-standards vcs https://github.com/matomo-org/matomo-coding-standards -n; composer require matomo-org/matomo-coding-standards:dev-master; From 608b7b6bb982d9e1fbc3d2b47d7f86f20b8982c9 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Wed, 5 Aug 2026 17:12:17 +1200 Subject: [PATCH 9/9] Give the checklist gate job a display name --- .github/workflows/plugin-ai-checklist.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/plugin-ai-checklist.yml b/.github/workflows/plugin-ai-checklist.yml index 70ecdef..49b5f14 100644 --- a/.github/workflows/plugin-ai-checklist.yml +++ b/.github/workflows/plugin-ai-checklist.yml @@ -11,6 +11,7 @@ permissions: jobs: AiChecklist: + name: AI checklist gate runs-on: ubuntu-24.04 strategy: fail-fast: false