From e9104a61e5d35d7338ef70880e79bdd1a062ce01 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 29 Oct 2026 04:58:05 +0000 Subject: [PATCH 1/5] Drop roave/security-advisories on PHP < 8.2 in CI It conflicts with every PHP release below 8.2, so composer install can never succeed there. Composer's policy.advisories.block still applies. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UWTd5mjnLFLCExqdULKVSB --- .github/workflows/reusable-functional.yml | 9 +++++++++ .github/workflows/reusable-unit.yml | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/.github/workflows/reusable-functional.yml b/.github/workflows/reusable-functional.yml index faa750e..aa3e225 100644 --- a/.github/workflows/reusable-functional.yml +++ b/.github/workflows/reusable-functional.yml @@ -188,6 +188,15 @@ jobs: shell: bash run: echo "value=$(date -u +%Y-%W)" >> "$GITHUB_OUTPUT" + # roave/security-advisories can't install on PHP < 8.2 (Roave/SecurityAdvisories#155). + # Composer's own `policy.advisories.block` still rejects vulnerable packages. + - name: Drop roave/security-advisories on PHP < 8.2 + shell: bash + run: | + if php -r 'exit(PHP_VERSION_ID < 80200 && isset(json_decode(file_get_contents("composer.json"), true)["require-dev"]["roave/security-advisories"]) ? 0 : 1);'; then + composer remove --dev --no-update --no-interaction roave/security-advisories + fi + - name: Install Composer dependencies & cache dependencies uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # 4.0.0 with: diff --git a/.github/workflows/reusable-unit.yml b/.github/workflows/reusable-unit.yml index b63b698..a1008cc 100644 --- a/.github/workflows/reusable-unit.yml +++ b/.github/workflows/reusable-unit.yml @@ -59,6 +59,15 @@ jobs: shell: bash run: echo "value=$(date -u +%Y-%W)" >> "$GITHUB_OUTPUT" + # roave/security-advisories can't install on PHP < 8.2 (Roave/SecurityAdvisories#155). + # Composer's own `policy.advisories.block` still rejects vulnerable packages. + - name: Drop roave/security-advisories on PHP < 8.2 + shell: bash + run: | + if php -r 'exit(PHP_VERSION_ID < 80200 && isset(json_decode(file_get_contents("composer.json"), true)["require-dev"]["roave/security-advisories"]) ? 0 : 1);'; then + composer remove --dev --no-update --no-interaction roave/security-advisories + fi + - name: Install Composer dependencies & cache dependencies uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # 4.0.0 with: From c5da57f1ab31e4ce520a2bd7f8beda4928a324f3 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 29 Oct 2026 05:10:46 +0000 Subject: [PATCH 2/5] Drop roave/security-advisories on all PHP versions Its PHP conflict covers patch releases of 8.3-8.5 too (e.g. Windows runners on PHP 8.5.11), not just < 8.2. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UWTd5mjnLFLCExqdULKVSB --- .github/workflows/reusable-functional.yml | 9 +++++---- .github/workflows/reusable-unit.yml | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/reusable-functional.yml b/.github/workflows/reusable-functional.yml index aa3e225..e2cdaa1 100644 --- a/.github/workflows/reusable-functional.yml +++ b/.github/workflows/reusable-functional.yml @@ -188,12 +188,13 @@ jobs: shell: bash run: echo "value=$(date -u +%Y-%W)" >> "$GITHUB_OUTPUT" - # roave/security-advisories can't install on PHP < 8.2 (Roave/SecurityAdvisories#155). - # Composer's own `policy.advisories.block` still rejects vulnerable packages. - - name: Drop roave/security-advisories on PHP < 8.2 + # roave/security-advisories conflicts with any PHP release that has known advisories, + # which includes most CI versions (Roave/SecurityAdvisories#155). Composer's own + # `policy.advisories.block` still rejects vulnerable packages. + - name: Drop roave/security-advisories shell: bash run: | - if php -r 'exit(PHP_VERSION_ID < 80200 && isset(json_decode(file_get_contents("composer.json"), true)["require-dev"]["roave/security-advisories"]) ? 0 : 1);'; then + if php -r 'exit(isset(json_decode(file_get_contents("composer.json"), true)["require-dev"]["roave/security-advisories"]) ? 0 : 1);'; then composer remove --dev --no-update --no-interaction roave/security-advisories fi diff --git a/.github/workflows/reusable-unit.yml b/.github/workflows/reusable-unit.yml index a1008cc..3445405 100644 --- a/.github/workflows/reusable-unit.yml +++ b/.github/workflows/reusable-unit.yml @@ -59,12 +59,13 @@ jobs: shell: bash run: echo "value=$(date -u +%Y-%W)" >> "$GITHUB_OUTPUT" - # roave/security-advisories can't install on PHP < 8.2 (Roave/SecurityAdvisories#155). - # Composer's own `policy.advisories.block` still rejects vulnerable packages. - - name: Drop roave/security-advisories on PHP < 8.2 + # roave/security-advisories conflicts with any PHP release that has known advisories, + # which includes most CI versions (Roave/SecurityAdvisories#155). Composer's own + # `policy.advisories.block` still rejects vulnerable packages. + - name: Drop roave/security-advisories shell: bash run: | - if php -r 'exit(PHP_VERSION_ID < 80200 && isset(json_decode(file_get_contents("composer.json"), true)["require-dev"]["roave/security-advisories"]) ? 0 : 1);'; then + if php -r 'exit(isset(json_decode(file_get_contents("composer.json"), true)["require-dev"]["roave/security-advisories"]) ? 0 : 1);'; then composer remove --dev --no-update --no-interaction roave/security-advisories fi From fda9694f1b3afb3d5edd0217a271512547c0b98f Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 29 Oct 2026 05:16:39 +0000 Subject: [PATCH 3/5] Only drop roave/security-advisories when it conflicts with the PHP in use Read roave's php conflict constraint from Packagist and drop the package only when the running PHP falls inside it, so up-to-date PHP versions keep the dependency check. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UWTd5mjnLFLCExqdULKVSB --- .github/workflows/reusable-functional.yml | 22 +++++++++++++++++----- .github/workflows/reusable-unit.yml | 22 +++++++++++++++++----- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/.github/workflows/reusable-functional.yml b/.github/workflows/reusable-functional.yml index e2cdaa1..85a0c20 100644 --- a/.github/workflows/reusable-functional.yml +++ b/.github/workflows/reusable-functional.yml @@ -188,13 +188,25 @@ jobs: shell: bash run: echo "value=$(date -u +%Y-%W)" >> "$GITHUB_OUTPUT" - # roave/security-advisories conflicts with any PHP release that has known advisories, - # which includes most CI versions (Roave/SecurityAdvisories#155). Composer's own - # `policy.advisories.block` still rejects vulnerable packages. - - name: Drop roave/security-advisories + # roave/security-advisories also conflicts with PHP releases that have known + # advisories, so it can't install on those (Roave/SecurityAdvisories#155). + # Drop it only when it conflicts with the PHP version in use. + - name: Drop roave/security-advisories if it conflicts with this PHP version shell: bash run: | - if php -r 'exit(isset(json_decode(file_get_contents("composer.json"), true)["require-dev"]["roave/security-advisories"]) ? 0 : 1);'; then + php -r 'exit(isset(json_decode(file_get_contents("composer.json"), true)["require-dev"]["roave/security-advisories"]) ? 0 : 1);' || exit 0 + export CONFLICT="$(composer show --available --format=json roave/security-advisories dev-latest | php -r 'echo json_decode(stream_get_contents(STDIN), true)["conflicts"]["php"] ?? "";')" + echo "roave/security-advisories conflicts with php ${CONFLICT:-(none)}" + if php -r ' + foreach (preg_split("/\s*\|\|?\s*/", getenv("CONFLICT"), -1, PREG_SPLIT_NO_EMPTY) as $range) { + $hit = true; + foreach (preg_split("/\s*,\s*|\s+/", $range) as $c) { + preg_match("/^(<=|>=|<|>|==|=|!=)?v?(.+)$/", $c, $m); + $hit = $hit && version_compare(PHP_VERSION, $m[2], $m[1] ?: "=="); + } + if ($hit) exit(0); + } + exit(1);'; then composer remove --dev --no-update --no-interaction roave/security-advisories fi diff --git a/.github/workflows/reusable-unit.yml b/.github/workflows/reusable-unit.yml index 3445405..da5ecc0 100644 --- a/.github/workflows/reusable-unit.yml +++ b/.github/workflows/reusable-unit.yml @@ -59,13 +59,25 @@ jobs: shell: bash run: echo "value=$(date -u +%Y-%W)" >> "$GITHUB_OUTPUT" - # roave/security-advisories conflicts with any PHP release that has known advisories, - # which includes most CI versions (Roave/SecurityAdvisories#155). Composer's own - # `policy.advisories.block` still rejects vulnerable packages. - - name: Drop roave/security-advisories + # roave/security-advisories also conflicts with PHP releases that have known + # advisories, so it can't install on those (Roave/SecurityAdvisories#155). + # Drop it only when it conflicts with the PHP version in use. + - name: Drop roave/security-advisories if it conflicts with this PHP version shell: bash run: | - if php -r 'exit(isset(json_decode(file_get_contents("composer.json"), true)["require-dev"]["roave/security-advisories"]) ? 0 : 1);'; then + php -r 'exit(isset(json_decode(file_get_contents("composer.json"), true)["require-dev"]["roave/security-advisories"]) ? 0 : 1);' || exit 0 + export CONFLICT="$(composer show --available --format=json roave/security-advisories dev-latest | php -r 'echo json_decode(stream_get_contents(STDIN), true)["conflicts"]["php"] ?? "";')" + echo "roave/security-advisories conflicts with php ${CONFLICT:-(none)}" + if php -r ' + foreach (preg_split("/\s*\|\|?\s*/", getenv("CONFLICT"), -1, PREG_SPLIT_NO_EMPTY) as $range) { + $hit = true; + foreach (preg_split("/\s*,\s*|\s+/", $range) as $c) { + preg_match("/^(<=|>=|<|>|==|=|!=)?v?(.+)$/", $c, $m); + $hit = $hit && version_compare(PHP_VERSION, $m[2], $m[1] ?: "=="); + } + if ($hit) exit(0); + } + exit(1);'; then composer remove --dev --no-update --no-interaction roave/security-advisories fi From 3910ab1039543deb11ee86eaefc12c448948a588 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 29 Oct 2026 05:22:24 +0000 Subject: [PATCH 4/5] Link setup-php security release notes in roave comment Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UWTd5mjnLFLCExqdULKVSB --- .github/workflows/reusable-functional.yml | 4 +++- .github/workflows/reusable-unit.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-functional.yml b/.github/workflows/reusable-functional.yml index 85a0c20..cdfd9c5 100644 --- a/.github/workflows/reusable-functional.yml +++ b/.github/workflows/reusable-functional.yml @@ -190,7 +190,9 @@ jobs: # roave/security-advisories also conflicts with PHP releases that have known # advisories, so it can't install on those (Roave/SecurityAdvisories#155). - # Drop it only when it conflicts with the PHP version in use. + # Drop it only when it conflicts with the PHP version in use. setup-php ships + # builds with security fixes backported, even for EOL versions, so this is + # safe on CI (shivammathur/setup-php#1139). - name: Drop roave/security-advisories if it conflicts with this PHP version shell: bash run: | diff --git a/.github/workflows/reusable-unit.yml b/.github/workflows/reusable-unit.yml index da5ecc0..71e28ae 100644 --- a/.github/workflows/reusable-unit.yml +++ b/.github/workflows/reusable-unit.yml @@ -61,7 +61,9 @@ jobs: # roave/security-advisories also conflicts with PHP releases that have known # advisories, so it can't install on those (Roave/SecurityAdvisories#155). - # Drop it only when it conflicts with the PHP version in use. + # Drop it only when it conflicts with the PHP version in use. setup-php ships + # builds with security fixes backported, even for EOL versions, so this is + # safe on CI (shivammathur/setup-php#1139). - name: Drop roave/security-advisories if it conflicts with this PHP version shell: bash run: | From c7459ef28c865347cc21a7e4e212a2b22843c5a2 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 29 Oct 2026 07:12:50 +0000 Subject: [PATCH 5/5] Update PHP to the latest patch on Windows runners Windows runners don't pick up patched setup-php builds automatically (shivammathur/setup-php#1139), so they lag a patch release behind and roave/security-advisories can't install there. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01UWTd5mjnLFLCExqdULKVSB --- .github/workflows/reusable-functional.yml | 2 ++ .github/workflows/reusable-unit.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/reusable-functional.yml b/.github/workflows/reusable-functional.yml index cdfd9c5..ff3266b 100644 --- a/.github/workflows/reusable-functional.yml +++ b/.github/workflows/reusable-functional.yml @@ -165,6 +165,8 @@ jobs: tools: composer env: COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Windows runners don't pick up patched PHP builds on their own (shivammathur/setup-php#1139). + update: ${{ runner.os == 'Windows' }} - name: Change ImageMagick policy to allow pdf->png conversion. # Keyed on the actual runner rather than the `os` input, and tolerant of diff --git a/.github/workflows/reusable-unit.yml b/.github/workflows/reusable-unit.yml index 71e28ae..0fc0cb7 100644 --- a/.github/workflows/reusable-unit.yml +++ b/.github/workflows/reusable-unit.yml @@ -48,6 +48,8 @@ jobs: tools: composer,cs2pr env: COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Windows runners don't pick up patched PHP builds on their own (shivammathur/setup-php#1139). + update: ${{ runner.os == 'Windows' }} # WP-CLI packages do not commit a lock file, so `composer update` resolves # dependencies on every run while the cache key stays pinned to composer.json.