Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/wiki
Submodule wiki updated from 5e683c to c8ed75
70 changes: 65 additions & 5 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,33 @@ on:
required: false
type: number
default: 80
run-dependencies-check:
description: Whether to run the dependency health check during CI.
required: false
type: boolean
default: true
max-outdated:
description: Maximum number of outdated packages allowed by the dependencies command.
required: false
type: number
default: 5
workflow_dispatch:
inputs:
min-coverage:
description: Minimum line coverage percentage enforced by dev-tools tests.
required: false
type: number
default: 80
run-dependencies-check:
description: Whether to run the dependency health check during CI.
required: false
type: boolean
default: true
max-outdated:
description: Maximum number of outdated packages allowed by the dependencies command.
required: false
type: number
default: 5
pull_request:
paths:
- 'src/**'
Expand All @@ -29,8 +49,8 @@ permissions:
contents: read

concurrency:
group: "pages"
cancel-in-progress: false
group: ${{ github.event_name == 'pull_request' && format('tests-pr-{0}', github.event.pull_request.number) || format('tests-{0}', github.ref) }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
tests:
Expand All @@ -39,6 +59,8 @@ jobs:
strategy:
matrix:
php-version: [ '8.3', '8.4', '8.5' ]
env:
TESTS_ROOT_VERSION: ${{ github.event_name == 'pull_request' && format('dev-{0}', github.event.pull_request.head.ref) || 'dev-main' }}
steps:
- uses: actions/checkout@v6

Expand All @@ -64,12 +86,12 @@ jobs:
env:
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ github.token }}"} }'
COMPOSER_CACHE_DIR: /tmp/composer-cache
COMPOSER_ROOT_VERSION: dev-main
COMPOSER_ROOT_VERSION: ${{ env.TESTS_ROOT_VERSION }}
run: composer install --prefer-dist --no-progress --no-interaction --no-plugins --no-scripts

- name: Composer Audit
env:
COMPOSER_ROOT_VERSION: dev-main
COMPOSER_ROOT_VERSION: ${{ env.TESTS_ROOT_VERSION }}
run: composer audit

- name: Resolve minimum coverage
Expand All @@ -80,5 +102,43 @@ jobs:

- name: Run PHPUnit tests
env:
COMPOSER_ROOT_VERSION: dev-main
COMPOSER_ROOT_VERSION: ${{ env.TESTS_ROOT_VERSION }}
run: composer dev-tools tests -- --coverage=public/coverage --min-coverage=${{ steps.minimum-coverage.outputs.value }}

dependency-health:
name: Dependency Health
if: ${{ github.event_name != 'workflow_call' || inputs.run-dependencies-check }}
runs-on: ubuntu-latest
continue-on-error: true
env:
TESTS_ROOT_VERSION: ${{ github.event_name == 'pull_request' && format('dev-{0}', github.event.pull_request.head.ref) || 'dev-main' }}
steps:
- uses: actions/checkout@v6

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'

- name: Cache Composer dependencies
uses: actions/cache@v5
with:
path: /tmp/composer-cache
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-

- name: Mark workspace as safe for git
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"

- name: Install dependencies
env:
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ github.token }}"} }'
COMPOSER_CACHE_DIR: /tmp/composer-cache
COMPOSER_ROOT_VERSION: ${{ env.TESTS_ROOT_VERSION }}
run: composer install --prefer-dist --no-progress --no-interaction --no-plugins --no-scripts

- name: Run dependency health check
env:
COMPOSER_ROOT_VERSION: ${{ env.TESTS_ROOT_VERSION }}
run: composer dev-tools dependencies -- --max-outdated=${{ inputs.max-outdated || 5 }}
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ composer dev-tools tests
# Analyze missing and unused Composer dependencies
composer dependencies
vendor/bin/dev-tools dependencies
composer dev-tools dependencies -- --max-outdated=8
composer dev-tools dependencies -- --dev
composer dev-tools dependencies -- --upgrade --dev

# Analyze code metrics with PhpMetrics
composer metrics
Expand Down Expand Up @@ -105,7 +108,8 @@ composer dev-tools update-composer-json --force
composer dev-tools:sync
```

The `dependencies` command ships with both dependency analyzers as direct
The `dependencies` command ships with both dependency analyzers and
`rector/jack` as direct
dependencies of `fast-forward/dev-tools`, so it works without extra
installation in the consumer project.

Expand All @@ -125,7 +129,7 @@ automation assets.
|---------|---------|
| `composer dev-tools` | Runs the full `standards` pipeline. |
| `composer dev-tools tests` | Runs PHPUnit with local-or-packaged configuration. |
| `composer dev-tools dependencies` | Reports missing and unused Composer dependencies. |
| `composer dev-tools dependencies` | Previews Jack dependency updates, then reports missing, unused, and overly outdated Composer dependencies. |
| `composer dev-tools metrics` | Runs PhpMetrics for a working directory and generates requested report artifacts. |
| `composer dev-tools docs` | Builds the HTML documentation site from PSR-4 code and `docs/`. |
| `composer dev-tools skills` | Creates or repairs packaged skill links in `.agents/skills`. |
Expand Down
19 changes: 10 additions & 9 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,32 @@
"composer/composer": "^2.9",
"container-interop/service-provider": "^0.4.1",
"dg/bypass-finals": "^1.9",
"ergebnis/composer-normalize": "^2.50",
"ergebnis/rector-rules": "^1.14",
"ergebnis/composer-normalize": "^2.51",
"ergebnis/rector-rules": "^1.18",
"fakerphp/faker": "^1.24",
"fast-forward/phpdoc-bootstrap-template": "^1.0",
"friendsofphp/php-cs-fixer": "^3.94",
"friendsofphp/php-cs-fixer": "^3.95",
"icanhazstring/composer-unused": "^0.9.6",
"jolicode/jolinotif": "^3.3",
"nikic/php-parser": "^5.7",
"php-di/php-di": "^7.1",
"php-parallel-lint/php-parallel-lint": "^1.4",
"phpdocumentor/shim": "^3.9",
"phpmetrics/phpmetrics": "^2.9",
"phpro/grumphp-shim": "^2.19",
"phpro/grumphp-shim": "^2.20",
"phpspec/prophecy": "^1.26",
"phpspec/prophecy-phpunit": "^2.5",
"phpunit/php-code-coverage": "^12.5",
"phpunit/phpunit": "^12.5",
"phpunit/php-code-coverage": "^12.5 || ^13.0",
"phpunit/phpunit": "^12.5 || ^13.0",
"psr/clock": "^1.0",
"psr/container": "^2.0",
"psr/log": "^3.0",
"pyrech/composer-changelogs": "^2.2",
"rector/rector": "^2.3",
"rector/jack": "^0.5",
"rector/rector": "^2.4",
"saggre/phpdocumentor-markdown": "^1.0",
"shipmonk/composer-dependency-analyser": "^1.8.4",
"symfony/config": "^7.4",
"symfony/config": "^7.4 || ^8.0",
"symfony/console": "^7.4 || ^8.0",
"symfony/filesystem": "^7.4 || ^8.0",
"symfony/finder": "^7.4 || ^8.0",
Expand All @@ -65,7 +66,7 @@
"symfony/var-exporter": "^7.4 || ^8.0",
"symplify/easy-coding-standard": "^13.0",
"thecodingmachine/safe": "^3.4",
"twig/twig": "^3.0"
"twig/twig": "^3.24"
},
"minimum-stability": "stable",
"autoload": {
Expand Down
57 changes: 50 additions & 7 deletions docs/commands/dependencies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ Analyzes missing and unused Composer dependencies.
Description
-----------

The ``dependencies`` command (alias: ``deps``) analyzes missing and unused
The ``dependencies`` command (alias: ``deps``) analyzes missing, unused, and
overly outdated
Composer dependencies using two tools:

- ``composer-unused`` - detects unused packages
- ``composer-dependency-analyser`` - detects missing packages
- ``jack breakpoint`` - fails when too many outdated packages accumulate

This command ships as a direct dependency of ``fast-forward/dev-tools``.

Expand All @@ -31,7 +33,23 @@ Usage
Options
-------

This command does not accept additional options.
``--max-outdated=<count>`` (optional)
Maximum number of outdated packages allowed by ``jack breakpoint``.

Default: ``5``.

``--upgrade`` (optional)
Applies the Jack upgrade workflow before the analyzers:

- ``vendor/bin/jack open-versions``
- ``vendor/bin/jack raise-to-installed``
- ``composer update -W``

Without ``--upgrade``, the command runs the Jack workflow in preview mode
before the analyzers.

``--dev`` (optional)
Prioritizes dev dependencies where Jack supports it.

Examples
--------
Expand All @@ -42,6 +60,24 @@ Run dependency analysis:

composer dependencies

Allow up to 10 outdated packages:

.. code-block:: bash

composer dev-tools dependencies -- --max-outdated=10

Preview the upgrade workflow:

.. code-block:: bash

composer dev-tools dependencies -- --dev

Apply the upgrade workflow and then analyze dependencies:

.. code-block:: bash

composer dev-tools dependencies -- --upgrade --dev

Using the alias:

.. code-block:: bash
Expand All @@ -57,16 +93,23 @@ Exit Codes
* - Code
- Meaning
* - 0
- Success. No missing or unused dependencies.
- Success. No missing, unused, or excessive outdated dependencies.
* - 1
- Failure. Missing or unused dependencies found.
- Failure. A dependency analyzer or Jack reported findings or errors.

Behavior
---------

- Runs both ``composer-unused`` and ``composer-dependency-analyser``.
- Runs ``composer-unused``, ``composer-dependency-analyser``, and
``jack breakpoint``.
- ``composer-dependency-analyser`` is configured with:
- ``--ignore-unused-deps`` (leaves unused detection to ``composer-unused``)
- ``--ignore-prod-only-in-dev-deps`` (ignores dev-only usage in production code)
- Returns a non-zero exit code when missing or unused dependencies are found.
- Both tools must be available in ``vendor/bin/``.
- ``jack breakpoint`` maps ``--max-outdated`` to Jack's ``--limit`` option.
- It always previews Jack's ``open-versions`` and ``raise-to-installed``
commands before the analyzers.
- ``--upgrade`` applies Jack's ``open-versions`` and ``raise-to-installed``
commands before ``composer update -W``.
- Returns a non-zero exit code when missing, unused, or too many outdated
dependencies are found.
- All three tools must be available in ``vendor/bin/``.
15 changes: 12 additions & 3 deletions docs/running/specialized-commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,25 @@ Analyzes missing and unused Composer dependencies.
.. code-block:: bash

composer dependencies
composer dev-tools dependencies -- --max-outdated=10
composer dev-tools dependencies -- --dev
composer dev-tools dependencies -- --upgrade --dev

Important details:

- it ships ``shipmonk/composer-dependency-analyser`` and
``icanhazstring/composer-unused`` as direct dependencies of
``icanhazstring/composer-unused`` and ``rector/jack`` as direct dependencies of
``fast-forward/dev-tools``;
- it uses ``composer-dependency-analyser`` only for missing dependency checks
and leaves unused-package reporting to ``composer-unused``;
- it returns a non-zero exit code when missing or unused dependencies are
found.
- it uses ``jack breakpoint --limit=<max-outdated>`` to fail when too many
outdated dependencies accumulate;
- it previews ``jack open-versions`` and ``jack raise-to-installed`` before
the analyzers;
- ``--upgrade`` runs ``jack open-versions``, ``jack raise-to-installed``, and
``composer update -W`` before the analyzers;
- it returns a non-zero exit code when missing, unused, or too many outdated
dependencies are found.

``metrics``
-----------
Expand Down
14 changes: 14 additions & 0 deletions resources/github-actions/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,25 @@ name: "Fast Forward Test Suite"
on:
push:
workflow_dispatch:
inputs:
run-dependencies-check:
description: Whether to run the dependency health check during CI.
required: false
type: boolean
default: true
max-outdated:
description: Maximum number of outdated packages allowed by the dependencies command.
required: false
type: number
default: 5

permissions:
contents: read

jobs:
tests:
uses: php-fast-forward/dev-tools/.github/workflows/tests.yml@main
with:
run-dependencies-check: ${{ inputs.run-dependencies-check || true }}
max-outdated: ${{ inputs.max-outdated || 5 }}
secrets: inherit
Loading
Loading