From 819bbec9b4ec6a604b0c438d9b535f52f8e42894 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 19 Jun 2026 14:08:12 +0200 Subject: [PATCH] [ci] add autoremoval of unused deps --- .github/workflows/code_analysis.yaml | 4 -- .github/workflows/remove_unused_deps.yaml | 39 ++++++++++++++++++ phpstan.neon | 5 +++ scripts/remove-unused-deps.php | 48 +++++++++++++++++++++++ 4 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/remove_unused_deps.yaml create mode 100644 scripts/remove-unused-deps.php diff --git a/.github/workflows/code_analysis.yaml b/.github/workflows/code_analysis.yaml index 7aba285c880..1670042a6bc 100644 --- a/.github/workflows/code_analysis.yaml +++ b/.github/workflows/code_analysis.yaml @@ -71,10 +71,6 @@ jobs: name: 'Check no "*.php" files in rules Fixture directory' run: php scripts/no-php-file-in-fixtures.php - - - name: 'Detect composer dependency issues' - run: vendor/bin/composer-dependency-analyser - - name: "PHP Linter" run: | diff --git a/.github/workflows/remove_unused_deps.yaml b/.github/workflows/remove_unused_deps.yaml new file mode 100644 index 00000000000..b5e50383456 --- /dev/null +++ b/.github/workflows/remove_unused_deps.yaml @@ -0,0 +1,39 @@ +name: Remove Unused Dependencies + +on: + pull_request: null + +jobs: + remove_unused_deps: + strategy: + fail-fast: false + + runs-on: ubuntu-latest + timeout-minutes: 8 + + if: github.event.pull_request.head.repo.full_name == 'rectorphp/rector-src' + steps: + - + uses: actions/checkout@v4 + with: + # Must be used to trigger workflow after push + token: ${{ secrets.ACCESS_TOKEN }} + + - + uses: shivammathur/setup-php@v2 + with: + php-version: 8.3 + coverage: none + + - run: composer install --no-progress --ansi + + ## detect unused dependencies and remove them from composer.json + - run: php scripts/remove-unused-deps.php --ansi + + - + # commit only to core contributors who have repository access + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: '[ci-review] Remove unused dependencies' + commit_author: 'GitHub Action ' + commit_user_email: 'action@github.com' diff --git a/phpstan.neon b/phpstan.neon index 8841ba4af95..7ee0150788f 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -445,3 +445,8 @@ parameters: - message: '#Access to deprecated property \$file of class Rector\\Rector\\AbstractRector#' path: src/Rector/AbstractRector.php + + # allowed + - + message: '#"@\\simplexml_load_string\(\$junitXml\)" is forbidden to use#' + path: scripts/remove-unused-deps.php diff --git a/scripts/remove-unused-deps.php b/scripts/remove-unused-deps.php new file mode 100644 index 00000000000..11e6277505f --- /dev/null +++ b/scripts/remove-unused-deps.php @@ -0,0 +1,48 @@ +/dev/null', $outputLines); +$junitXml = implode("\n", $outputLines); + +$simpleXml = @simplexml_load_string($junitXml); +if (! $simpleXml instanceof SimpleXMLElement) { + $symfonyStyle->error('Failed to parse composer-dependency-analyser output'); + exit(1); +} + +// 2. collect unused dependencies from the "unused dependencies" testsuite +$unusedDependencies = []; +foreach ($simpleXml->testsuite as $testsuite) { + if ((string) $testsuite['name'] !== 'unused dependencies') { + continue; + } + + foreach ($testsuite->testcase as $testcase) { + $unusedDependencies[] = (string) $testcase['name']; + } +} + +if ($unusedDependencies === []) { + $symfonyStyle->success('No unused dependencies found'); + exit(0); +} + +$symfonyStyle->listing($unusedDependencies); + +// 3. remove unused dependencies from composer.json (composer auto-detects require/require-dev) +// the autocommit to the branch is handled by the workflow's git-auto-commit-action +foreach ($unusedDependencies as $unusedDependency) { + exec(sprintf('composer remove %s --no-update --no-interaction 2>&1', escapeshellarg($unusedDependency))); +} + +$symfonyStyle->success(sprintf('Removed %d unused dependency(ies) from composer.json', count($unusedDependencies)));