diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 6ff32f8..5f4a756 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -6,8 +6,8 @@ on: pull_request: ~ jobs: - test-php-74: - name: Code quality PHP 7.4 + test-php-8336: + name: Code quality PHP 8.3.36 runs-on: [ubuntu-latest] steps: - name: Checkout @@ -16,35 +16,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: 7.4 - coverage: xdebug - - - name: Validate composer.json and composer.lock - run: composer validate --strict - - - name: Install dependencies - run: composer install --prefer-dist --no-progress - - - name: Lint - run: composer lint:check - - - name: PHP Static Analysis - run: composer phpstan - - - name: Unit Test - run: composer phpunit - - test-php-80: - name: Code quality PHP 8.0 - runs-on: [ubuntu-latest] - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.0 + php-version: 8.3.36 coverage: xdebug - name: Validate composer.json and composer.lock diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index b27c648..7697fc6 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -8,14 +8,15 @@ $config ->setRules([ '@Symfony' => true, - '@PHP71Migration:risky' => true, - '@PHPUnit60Migration:risky' => true, + '@PHP7x1Migration:risky' => true, + '@PHPUnit6x0Migration:risky' => true, 'array_indentation' => true, 'array_syntax' => ['syntax' => 'short'], 'blank_line_after_opening_tag' => true, 'concat_space' => ['spacing' => 'one'], 'class_attributes_separation' => ['elements' => ['method'=>'one']], 'declare_strict_types' => true, + 'global_namespace_import' => false, 'increment_style' => ['style' => 'post'], 'list_syntax' => ['syntax' => 'short'], 'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'], @@ -45,10 +46,10 @@ // special handling of fabbot.io service if it's using too old PHP CS Fixer version if (false !== getenv('FABBOT_IO')) { try { - PhpCsFixer\FixerFactory::create() + (new PhpCsFixer\FixerFactory()) ->registerBuiltInFixers() ->registerCustomFixers($config->getCustomFixers()) - ->useRuleSet(new PhpCsFixer\RuleSet($config->getRules())) + ->useRuleSet(new PhpCsFixer\RuleSet\RuleSet($config->getRules())) ; } catch (PhpCsFixer\ConfigurationException\InvalidConfigurationException $e) { $config->setRules([]); diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7e6bcac --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM php:8.3.36-cli + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates libzip-dev unzip \ + && docker-php-ext-install zip \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=composer:2 /usr/bin/composer /usr/bin/composer + +COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint + +WORKDIR /app + +ENV COMPOSER_CACHE_DIR=/tmp/composer-cache + +ENTRYPOINT ["sh", "/usr/local/bin/docker-entrypoint"] diff --git a/README.md b/README.md index 07aa0a0..c1409a0 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,56 @@ $ composer install $ vendor/bin/phpunit ``` +### With Docker + +The project includes a PHP 8.3.36 CLI image for running Composer and the test +suite without installing PHP locally. + +```bash +$ docker compose build +$ docker compose run --rm php composer install +$ docker compose run --rm php composer test +``` + +To run an individual Composer script, replace `composer test` with a script +such as `composer phpunit` or `composer phpstan`. + +If an existing installation reports that PHP CS Fixer does not support PHP +8.3, update the development tools together: + +```bash +$ docker compose run --rm php composer update friendsofphp/php-cs-fixer phpunit/phpunit phpstan/phpstan --with-all-dependencies +$ docker compose run --rm php composer test +``` + +This refreshes an older local lock file; `composer install` alone keeps the +locked versions. Do not bypass the fixer's PHP version check with +`PHP_CS_FIXER_IGNORE_ENV`. + +The development tools use PHP CS Fixer 3.95+, PHPUnit 9.6, and PHPStan 2.2+. +PHPStan stays at level 8, the equivalent of `max` in the previous PHPStan 0.12 +configuration. + +If your network uses TLS inspection, ask your IT team for its root CA +certificate in PEM format. Do not disable Composer's TLS verification. Set +`CORPORATE_CA_CERT` to the certificate's path on your host, then use the +additional Compose file. It mounts the certificate and configures Composer to +trust it for both dependency installation and tests: + +```bash +$ export CORPORATE_CA_CERT=/path/to/corporate-root-ca.crt +$ docker compose -f compose.yaml -f compose.ca.yaml run --rm php composer install +$ docker compose -f compose.yaml -f compose.ca.yaml run --rm php composer test +``` + +Use the same `-f compose.yaml -f compose.ca.yaml` options for dependency updates +when your network requires the corporate CA. + +Run `composer test` only after `composer install` succeeds; otherwise test +tools such as `php-cs-fixer` will not be installed. The CA certificate is +mounted at runtime and appended to the system CA bundle for Composer only. It +is not added to the repository or Docker image. + JSON ---- diff --git a/compose.ca.yaml b/compose.ca.yaml new file mode 100644 index 0000000..f7773c0 --- /dev/null +++ b/compose.ca.yaml @@ -0,0 +1,7 @@ +services: + php: + volumes: + - type: bind + source: ${CORPORATE_CA_CERT:?Set CORPORATE_CA_CERT to your corporate CA certificate path} + target: /tmp/corporate-root-ca.crt + read_only: true diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..faf5d5a --- /dev/null +++ b/compose.yaml @@ -0,0 +1,7 @@ +services: + php: + build: . + working_dir: /app + user: "${UID:-1000}:${GID:-1000}" + volumes: + - .:/app diff --git a/composer.json b/composer.json index 0831665..fbfdf3d 100644 --- a/composer.json +++ b/composer.json @@ -5,12 +5,12 @@ "type": "library", "license": "BSD-3-Clause", "require": { - "php": "^7.4 || ^8.0" + "php": "~8.3.36 || ~8.4.27 || ~8.5.12" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.6", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^8.5" + "friendsofphp/php-cs-fixer": "^3.95", + "phpstan/phpstan": "^2.2", + "phpunit/phpunit": "^9.6" }, "autoload": { "psr-4": { diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..e327388 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -eu + +if [ -f /tmp/corporate-root-ca.crt ]; then + cat /etc/ssl/certs/ca-certificates.crt /tmp/corporate-root-ca.crt > /tmp/ca-bundle.crt + export COMPOSER_CAFILE=/tmp/ca-bundle.crt +fi + +exec "$@" diff --git a/phpstan.neon b/phpstan.neon index da5b10b..1ff472c 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,4 @@ parameters: - level: max - checkMissingIterableValueType: false + level: 8 paths: - src diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 206ad44..bcdc809 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,6 +1,6 @@ - - + + src - - + + diff --git a/tests/InflectorTest.php b/tests/InflectorTest.php index 9687c37..fbf3987 100644 --- a/tests/InflectorTest.php +++ b/tests/InflectorTest.php @@ -6,6 +6,9 @@ use PHPUnit\Framework\TestCase; +/** + * @covers \Linio\Component\Util\Inflector + */ class InflectorTest extends TestCase { public function testIsPascalizingSpinalCase(): void diff --git a/tests/JsonTest.php b/tests/JsonTest.php index 2854633..4f5329c 100644 --- a/tests/JsonTest.php +++ b/tests/JsonTest.php @@ -6,6 +6,9 @@ use PHPUnit\Framework\TestCase; +/** + * @covers \Linio\Component\Util\Json + */ class JsonTest extends TestCase { public function testIsEncoding(): void