From 5ea3b1c947f13aa3cfc4c09ed422eea6f44bec39 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 09:42:40 -0300 Subject: [PATCH 01/33] Bump DI52 to ^4. Do a composer update --- src/composer.json | 4 +- src/composer.lock | 195 +++++++++++++++++++++++----------------------- 2 files changed, 101 insertions(+), 98 deletions(-) diff --git a/src/composer.json b/src/composer.json index d4055480..8480d90a 100644 --- a/src/composer.json +++ b/src/composer.json @@ -27,7 +27,7 @@ "symfony/console": "^5", "symfony/process": "^5", "symfony/filesystem": "^5", - "lucatume/di52": "^3", + "lucatume/di52": "^4", "stecman/symfony-console-completion": "^0.11.0", "composer/ca-bundle": "^1.4", "symfony/serializer": "^5", @@ -37,7 +37,7 @@ "require-dev": { "phpunit/phpunit": "^8", "phpstan/phpstan": "^1", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2", + "dealerdirect/phpcodesniffer-composer-installer": "^1", "wp-coding-standards/wpcs": "dev-develop", "phpcompatibility/php-compatibility": "^9", "spatie/phpunit-snapshot-assertions": "^3.0" diff --git a/src/composer.lock b/src/composer.lock index 80c7a09b..b4ce15d9 100644 --- a/src/composer.lock +++ b/src/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9e635ae6113c810bc73c47f103647982", + "content-hash": "576baaeda71fcabf51ca5a82755561a7", "packages": [ { "name": "composer/ca-bundle", - "version": "1.5.2", + "version": "1.5.4", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "48a792895a2b7a6ee65dd5442c299d7b835b6137" + "reference": "bc0593537a463e55cadf45fd938d23b75095b7e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/48a792895a2b7a6ee65dd5442c299d7b835b6137", - "reference": "48a792895a2b7a6ee65dd5442c299d7b835b6137", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/bc0593537a463e55cadf45fd938d23b75095b7e1", + "reference": "bc0593537a463e55cadf45fd938d23b75095b7e1", "shasum": "" }, "require": { @@ -64,7 +64,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.5.2" + "source": "https://github.com/composer/ca-bundle/tree/1.5.4" }, "funding": [ { @@ -80,7 +80,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T07:49:53+00:00" + "time": "2024-11-27T15:35:25+00:00" }, { "name": "graham-campbell/result-type", @@ -146,21 +146,21 @@ }, { "name": "lucatume/di52", - "version": "3.3.7", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/lucatume/di52.git", - "reference": "76c0c2ad0422ce595e2e38138456f3475888e32c" + "reference": "c629a194cde339bd09b97724ff96ae57be392e55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lucatume/di52/zipball/76c0c2ad0422ce595e2e38138456f3475888e32c", - "reference": "76c0c2ad0422ce595e2e38138456f3475888e32c", + "url": "https://api.github.com/repos/lucatume/di52/zipball/c629a194cde339bd09b97724ff96ae57be392e55", + "reference": "c629a194cde339bd09b97724ff96ae57be392e55", "shasum": "" }, "require": { "ext-json": "*", - "php": ">=5.6", + "php": ">=7.1", "psr/container": "^1.0" }, "require-dev": { @@ -185,9 +185,9 @@ "description": "A PHP 5.6 compatible dependency injection container.", "support": { "issues": "https://github.com/lucatume/di52/issues", - "source": "https://github.com/lucatume/di52/tree/3.3.7" + "source": "https://github.com/lucatume/di52/tree/4.0.0" }, - "time": "2024-04-26T14:46:26+00:00" + "time": "2024-12-14T10:54:28+00:00" }, { "name": "phpoption/phpoption", @@ -363,16 +363,16 @@ }, { "name": "symfony/console", - "version": "v5.4.45", + "version": "v5.4.47", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "108d436c2af470858bdaba3257baab3a74172017" + "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/108d436c2af470858bdaba3257baab3a74172017", - "reference": "108d436c2af470858bdaba3257baab3a74172017", + "url": "https://api.github.com/repos/symfony/console/zipball/c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", + "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", "shasum": "" }, "require": { @@ -442,7 +442,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.45" + "source": "https://github.com/symfony/console/tree/v5.4.47" }, "funding": [ { @@ -458,20 +458,20 @@ "type": "tidelift" } ], - "time": "2024-10-08T07:27:17+00:00" + "time": "2024-11-06T11:30:55+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.3", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "80d075412b557d41002320b96a096ca65aa2c98d" + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/80d075412b557d41002320b96a096ca65aa2c98d", - "reference": "80d075412b557d41002320b96a096ca65aa2c98d", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918", + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918", "shasum": "" }, "require": { @@ -509,7 +509,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.3" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4" }, "funding": [ { @@ -525,7 +525,7 @@ "type": "tidelift" } ], - "time": "2023-01-24T14:02:46+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/filesystem", @@ -620,8 +620,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -696,8 +696,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -774,8 +774,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -858,8 +858,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -932,8 +932,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -1008,8 +1008,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -1070,16 +1070,16 @@ }, { "name": "symfony/process", - "version": "v5.4.45", + "version": "v5.4.47", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "95f3f19d0f8f06e4253c66a0828ddb69f8b8ede4" + "reference": "5d1662fb32ebc94f17ddb8d635454a776066733d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/95f3f19d0f8f06e4253c66a0828ddb69f8b8ede4", - "reference": "95f3f19d0f8f06e4253c66a0828ddb69f8b8ede4", + "url": "https://api.github.com/repos/symfony/process/zipball/5d1662fb32ebc94f17ddb8d635454a776066733d", + "reference": "5d1662fb32ebc94f17ddb8d635454a776066733d", "shasum": "" }, "require": { @@ -1112,7 +1112,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.45" + "source": "https://github.com/symfony/process/tree/v5.4.47" }, "funding": [ { @@ -1128,7 +1128,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:11:13+00:00" + "time": "2024-11-06T11:36:42+00:00" }, { "name": "symfony/serializer", @@ -1235,16 +1235,16 @@ }, { "name": "symfony/service-contracts", - "version": "v2.5.3", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3" + "reference": "f37b419f7aea2e9abf10abd261832cace12e3300" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a2329596ddc8fd568900e3fc76cba42489ecc7f3", - "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f37b419f7aea2e9abf10abd261832cace12e3300", + "reference": "f37b419f7aea2e9abf10abd261832cace12e3300", "shasum": "" }, "require": { @@ -1298,7 +1298,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.3" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.4" }, "funding": [ { @@ -1314,20 +1314,20 @@ "type": "tidelift" } ], - "time": "2023-04-21T15:04:16+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/string", - "version": "v5.4.45", + "version": "v5.4.47", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "7f6807add88b1e2635f3c6de5e1ace631ed7cad2" + "reference": "136ca7d72f72b599f2631aca474a4f8e26719799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/7f6807add88b1e2635f3c6de5e1ace631ed7cad2", - "reference": "7f6807add88b1e2635f3c6de5e1ace631ed7cad2", + "url": "https://api.github.com/repos/symfony/string/zipball/136ca7d72f72b599f2631aca474a4f8e26719799", + "reference": "136ca7d72f72b599f2631aca474a4f8e26719799", "shasum": "" }, "require": { @@ -1384,7 +1384,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.45" + "source": "https://github.com/symfony/string/tree/v5.4.47" }, "funding": [ { @@ -1400,7 +1400,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:11:13+00:00" + "time": "2024-11-10T20:33:58+00:00" }, { "name": "symfony/yaml", @@ -1565,35 +1565,38 @@ "packages-dev": [ { "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", + "version": "v1.0.0", "source": { "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "4be43904336affa5c2f70744a348312336afd0da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", + "reference": "4be43904336affa5c2f70744a348312336afd0da", "shasum": "" }, "require": { "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", + "php": ">=5.4", "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" }, "require-dev": { "composer/composer": "*", + "ext-json": "*", + "ext-zip": "*", "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" }, "type": "composer-plugin", "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, "autoload": { "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1609,7 +1612,7 @@ }, { "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", @@ -1633,10 +1636,10 @@ "tests" ], "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "source": "https://github.com/PHPCSStandards/composer-installer" }, - "time": "2022-02-04T12:51:07+00:00" + "time": "2023-01-05T11:28:13+00:00" }, { "name": "doctrine/instantiator", @@ -1710,16 +1713,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.12.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { @@ -1758,7 +1761,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { @@ -1766,7 +1769,7 @@ "type": "tidelift" } ], - "time": "2024-06-12T14:39:25+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { "name": "phar-io/manifest", @@ -2116,16 +2119,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.7", + "version": "1.12.12", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "dc2b9976bd8b0f84ec9b0e50cc35378551de7af0" + "reference": "b5ae1b88f471d3fd4ba1aa0046234b5ca3776dd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc2b9976bd8b0f84ec9b0e50cc35378551de7af0", - "reference": "dc2b9976bd8b0f84ec9b0e50cc35378551de7af0", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/b5ae1b88f471d3fd4ba1aa0046234b5ca3776dd0", + "reference": "b5ae1b88f471d3fd4ba1aa0046234b5ca3776dd0", "shasum": "" }, "require": { @@ -2170,7 +2173,7 @@ "type": "github" } ], - "time": "2024-10-18T11:12:07+00:00" + "time": "2024-11-28T22:13:23+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2471,16 +2474,16 @@ }, { "name": "phpunit/phpunit", - "version": "8.5.40", + "version": "8.5.41", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "48ed828b72c35b38cdddcd9059339734cb06b3a7" + "reference": "d843cb5bcf0bf9ae3484016444fe0c5b6ec7e4fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/48ed828b72c35b38cdddcd9059339734cb06b3a7", - "reference": "48ed828b72c35b38cdddcd9059339734cb06b3a7", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d843cb5bcf0bf9ae3484016444fe0c5b6ec7e4fa", + "reference": "d843cb5bcf0bf9ae3484016444fe0c5b6ec7e4fa", "shasum": "" }, "require": { @@ -2491,7 +2494,7 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.0", + "myclabs/deep-copy": "^1.12.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=7.2", @@ -2549,7 +2552,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.40" + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.41" }, "funding": [ { @@ -2565,7 +2568,7 @@ "type": "tidelift" } ], - "time": "2024-09-19T10:47:04+00:00" + "time": "2024-12-05T13:44:26+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -3351,16 +3354,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.10.3", + "version": "3.11.2", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "62d32998e820bddc40f99f8251958aed187a5c9c" + "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/62d32998e820bddc40f99f8251958aed187a5c9c", - "reference": "62d32998e820bddc40f99f8251958aed187a5c9c", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/1368f4a58c3c52114b86b1abe8f4098869cb0079", + "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079", "shasum": "" }, "require": { @@ -3427,7 +3430,7 @@ "type": "open_collective" } ], - "time": "2024-09-18T10:38:58+00:00" + "time": "2024-12-11T16:04:26+00:00" }, { "name": "theseer/tokenizer", @@ -3485,12 +3488,12 @@ "source": { "type": "git", "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", - "reference": "2133137c33fa898df70b5f879a65d83af4dbb97d" + "reference": "9f9726a01a886b3dcced5327390470a56314aa56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/2133137c33fa898df70b5f879a65d83af4dbb97d", - "reference": "2133137c33fa898df70b5f879a65d83af4dbb97d", + "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/9f9726a01a886b3dcced5327390470a56314aa56", + "reference": "9f9726a01a886b3dcced5327390470a56314aa56", "shasum": "" }, "require": { @@ -3544,7 +3547,7 @@ "type": "custom" } ], - "time": "2024-10-05T00:46:24+00:00" + "time": "2024-12-02T08:21:11+00:00" } ], "aliases": [], From 8e83dc06baf71ebc40c441ca8c1d6e08b6dcda02 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 10:01:35 -0300 Subject: [PATCH 02/33] Run PHPUnit on multiple versions --- .github/phpunit.yml | 34 +++++++++++++++++++ Makefile | 13 ++++--- _build/docker/php/Dockerfile | 14 ++++++++ _build/docker/{php83 => php}/ini/xdebug.ini | 4 +-- _build/docker/{php83 => php}/xdebug/.gitkeep | 0 _build/docker/{php83 => php}/xdebug/README.md | 0 _build/docker/php/xdebug/xdebug.log | 0 _build/docker/php83/Dockerfile | 15 -------- 8 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 .github/phpunit.yml create mode 100644 _build/docker/php/Dockerfile rename _build/docker/{php83 => php}/ini/xdebug.ini (83%) rename _build/docker/{php83 => php}/xdebug/.gitkeep (100%) rename _build/docker/{php83 => php}/xdebug/README.md (100%) create mode 100644 _build/docker/php/xdebug/xdebug.log delete mode 100644 _build/docker/php83/Dockerfile diff --git a/.github/phpunit.yml b/.github/phpunit.yml new file mode 100644 index 00000000..59984159 --- /dev/null +++ b/.github/phpunit.yml @@ -0,0 +1,34 @@ +name: PHPUnit Tests +on: + push: + paths: + - 'src/**.php' + workflow_dispatch: + +jobs: + phpunit_tests: + name: PHPUnit on PHP ${{ matrix.php }} + runs-on: ubuntu-latest + strategy: + matrix: + php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache composer dependencies + uses: actions/cache@v3 + with: + path: src/vendor + key: ${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('src/composer.lock') }} + + - name: Composer install + if: steps.cache-composer.outputs.cache-hit != 'true' + run: | + cd src + composer install --no-interaction --no-suggest --prefer-dist + + - name: Run PHPUnit tests + env: + PHP_VERSION: ${{ matrix.php }} + run: make phpunit \ No newline at end of file diff --git a/Makefile b/Makefile index 9c1d1c3b..799e1091 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ ROOT ?= 0 DEBUG ?= 0 ARGS ?= +PHP_VERSION ?= 8.3 VERSION ?= qit_dev_build ifeq (1, $(ROOT)) @@ -17,16 +18,18 @@ endif ## Run a command inside an alpine PHP 8 CLI image. ## 1. Command to execute, eg: "./vendor/bin/phpcs" 2. Working dir (optional) define execPhpAlpine - @docker image inspect qit-cli-php-xdebug-pcntl > /dev/null 2>&1 || docker build --build-arg CI=${CI} -t qit-cli-php-xdebug-pcntl ./_build/docker/php83 - docker run --rm \ + @docker image inspect qit-cli-php-$(PHP_VERSION) > /dev/null 2>&1 || \ + (echo "Docker image not found. Building qit-cli-php-$(PHP_VERSION)..." && \ + docker build --build-arg CI=${CI} --build-arg PHP_VERSION=$(PHP_VERSION) -t qit-cli-php-$(PHP_VERSION) ./_build/docker/php) + + @docker run --rm \ --user $(DOCKER_USER) \ -v "${PWD}:/app" \ - -v "${PWD}/_build/docker/php83/ini/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini" \ + -v "${PWD}/_build/docker/php/ini/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini" \ --env QIT_HOME=/tmp \ --env PHP_IDE_CONFIG=serverName=qit_cli \ --workdir "$(2:=/)" \ - --add-host host.docker.internal:host-gateway \ - qit-cli-php-xdebug-pcntl \ + qit-cli-php-$(PHP_VERSION) \ bash -c "php -d xdebug.start_with_request=$(if $(filter 1,$(DEBUG)),yes,no) -d memory_limit=1G $(1)" endef diff --git a/_build/docker/php/Dockerfile b/_build/docker/php/Dockerfile new file mode 100644 index 00000000..4fe8d23d --- /dev/null +++ b/_build/docker/php/Dockerfile @@ -0,0 +1,14 @@ +# Use an ARG for the PHP version. Default to 8.3 if not provided. +ARG PHP_VERSION=8.3 +FROM php:${PHP_VERSION}-cli + +ARG CI +RUN apt-get update \ + && apt-get install -y libzip-dev \ + && docker-php-ext-install zip pcntl \ + && docker-php-ext-enable zip pcntl + +# Install Xdebug only if not in CI environment +RUN if [ "$CI" != "true" ]; then \ + pecl install xdebug && docker-php-ext-enable xdebug; \ + fi diff --git a/_build/docker/php83/ini/xdebug.ini b/_build/docker/php/ini/xdebug.ini similarity index 83% rename from _build/docker/php83/ini/xdebug.ini rename to _build/docker/php/ini/xdebug.ini index fea14732..12208c65 100644 --- a/_build/docker/php83/ini/xdebug.ini +++ b/_build/docker/php/ini/xdebug.ini @@ -1,7 +1,7 @@ xdebug.client_host = host.docker.internal xdebug.client_port = 9003 -xdebug.output_dir = /app/_build/docker/php83/xdebug/output -xdebug.log = /app/_build/docker/php83/xdebug/xdebug.log +xdebug.output_dir = /app/_build/docker/php/xdebug/output +xdebug.log = /app/_build/docker/php/xdebug/xdebug.log # Enabled at runtime with DEBUG=1 xdebug.start_with_request = no diff --git a/_build/docker/php83/xdebug/.gitkeep b/_build/docker/php/xdebug/.gitkeep similarity index 100% rename from _build/docker/php83/xdebug/.gitkeep rename to _build/docker/php/xdebug/.gitkeep diff --git a/_build/docker/php83/xdebug/README.md b/_build/docker/php/xdebug/README.md similarity index 100% rename from _build/docker/php83/xdebug/README.md rename to _build/docker/php/xdebug/README.md diff --git a/_build/docker/php/xdebug/xdebug.log b/_build/docker/php/xdebug/xdebug.log new file mode 100644 index 00000000..e69de29b diff --git a/_build/docker/php83/Dockerfile b/_build/docker/php83/Dockerfile deleted file mode 100644 index 0676b6bb..00000000 --- a/_build/docker/php83/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM php:8.3-cli - -ARG CI - -RUN apt-get update \ - && apt-get install -y libzip-dev \ - && docker-php-ext-install zip \ - && docker-php-ext-enable zip \ - && docker-php-ext-install pcntl \ - && docker-php-ext-enable pcntl - -# Install Xdebug only if not in CI environment -RUN if [ "$CI" != "true" ]; then \ - pecl install xdebug && docker-php-ext-enable xdebug; \ - fi \ No newline at end of file From d5846b5c51c823e24644d4782255d79cba965a4c Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 10:15:54 -0300 Subject: [PATCH 03/33] Only install xdebug in 8+ --- _build/docker/php/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_build/docker/php/Dockerfile b/_build/docker/php/Dockerfile index 4fe8d23d..3a00d760 100644 --- a/_build/docker/php/Dockerfile +++ b/_build/docker/php/Dockerfile @@ -8,7 +8,7 @@ RUN apt-get update \ && docker-php-ext-install zip pcntl \ && docker-php-ext-enable zip pcntl -# Install Xdebug only if not in CI environment -RUN if [ "$CI" != "true" ]; then \ +# Install Xdebug only if not in CI environment and PHP major version >= 8 +RUN if [ "$CI" != "true" ] && [ "${PHP_VERSION%%.*}" -ge 8 ]; then \ pecl install xdebug && docker-php-ext-enable xdebug; \ fi From ce4f87009a9d1108201d40486b5031f740e6d3fc Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 10:16:05 -0300 Subject: [PATCH 04/33] Tweak test so that it's PHP 7 compatible --- .../Environment/ExtensionDownloaderTest.php | 114 +++++++----------- 1 file changed, 46 insertions(+), 68 deletions(-) diff --git a/src/tests/Environment/ExtensionDownloaderTest.php b/src/tests/Environment/ExtensionDownloaderTest.php index 9c95232c..7920a6cb 100644 --- a/src/tests/Environment/ExtensionDownloaderTest.php +++ b/src/tests/Environment/ExtensionDownloaderTest.php @@ -82,12 +82,12 @@ protected function make_extension( string $type, ?string $slug = null, $source = public function test_categorize_extensions() { $plugins = [ - $this->make_extension( 'plugin', slug: 'plugin1' ), - $this->make_extension( 'plugin', slug: 'plugin2' ), + $this->make_extension( 'plugin', 'plugin1' ), + $this->make_extension( 'plugin', 'plugin2' ), ]; $themes = [ - $this->make_extension( 'theme', slug: 'theme1' ), - $this->make_extension( 'theme', slug: 'theme2' ), + $this->make_extension( 'theme', 'theme1' ), + $this->make_extension( 'theme', 'theme2' ), ]; $this->assertMatchesJsonSnapshot( $this->sut->categorize_extensions( $plugins, $themes, '/tmp/cache/' ) ); @@ -95,35 +95,24 @@ public function test_categorize_extensions() { public function test_numeric_extensions() { $plugins = [ - $this->make_extension( 'plugin', slug: 'plugin1', source: '123' ), - $this->make_extension( 'plugin', slug: 'plugin2', source: '456' ), + $this->make_extension( 'plugin', 'plugin1', '123' ), + $this->make_extension( 'plugin', 'plugin2', '456' ), ]; $themes = [ - $this->make_extension( 'theme', slug: 'theme1', source: '789' ), + $this->make_extension( 'theme', 'theme1', '789' ), ]; $this->assertMatchesJsonSnapshot( $this->sut->categorize_extensions( $plugins, $themes, '/tmp/cache/' ) ); } public function test_valid_ur_extensions() { $plugins = [ - $this->make_extension( 'plugin', source: 'http://example.com/plugin.zip' ), - $this->make_extension( 'plugin', source: 'https://example.com/plugin2.zip' ), + $this->make_extension( 'plugin', null, 'http://example.com/plugin.zip' ), + $this->make_extension( 'plugin', null, 'https://example.com/plugin2.zip' ), ]; $themes = []; $this->assertMatchesJsonSnapshot( $this->sut->categorize_extensions( $plugins, $themes, '/tmp/cache/' ) ); } - /* - public function test_invalid_url_extensions() { - $plugins = [ - $this->make_extension( 'plugin', source: 'http://example.com/plugin' ), - $this->make_extension( 'plugin', source: 'https://example.com/plugin2.tar.gz' ), - ]; - $this->expectException( InvalidArgumentException::class ); - $this->sut->categorize_extensions( $plugins, [], '/tmp/cache/' ); - } - */ - public function test_file_path_extensions() { $plugin1 = sys_get_temp_dir() . '/plugin'; $plugin2 = sys_get_temp_dir() . '/plugin2.zip'; @@ -136,20 +125,20 @@ public function test_file_path_extensions() { $this->to_delete = [ $plugin1, $plugin2, $theme1, $theme2 ]; $plugins = [ - $this->make_extension( 'plugin', source: $plugin1 ), - $this->make_extension( 'plugin', source: $plugin2 ), + $this->make_extension( 'plugin', null, $plugin1 ), + $this->make_extension( 'plugin', null, $plugin2 ), ]; $themes = [ - $this->make_extension( 'theme', source: $theme1 ), - $this->make_extension( 'theme', source: $theme2 ), + $this->make_extension( 'theme', null, $theme1 ), + $this->make_extension( 'theme', null, $theme2 ), ]; $this->assertMatchesJsonSnapshot( $this->sut->categorize_extensions( $plugins, $themes, '/tmp/cache/' ) ); } public function test_github_repository_string() { $plugins = [ - $this->make_extension( 'plugin', source: 'user/repository' ), - $this->make_extension( 'plugin', source: 'user2/repo2#branch' ), + $this->make_extension( 'plugin', null, 'user/repository' ), + $this->make_extension( 'plugin', null, 'user2/repo2#branch' ), ]; $this->expectException( InvalidArgumentException::class ); $this->sut->categorize_extensions( $plugins, [], '/tmp/cache/' ); @@ -157,10 +146,10 @@ public function test_github_repository_string() { public function test_SSH_url() { $plugins = [ - $this->make_extension( 'plugin', source: 'ssh://example.com/plugin' ), + $this->make_extension( 'plugin', null, 'ssh://example.com/plugin' ), ]; $themes = [ - $this->make_extension( 'theme', source: 'ssh://example.com/theme' ), + $this->make_extension( 'theme', null, 'ssh://example.com/theme' ), ]; $this->expectException( InvalidArgumentException::class ); $this->sut->categorize_extensions( $plugins, $themes, '/tmp/cache/' ); @@ -168,15 +157,15 @@ public function test_SSH_url() { public function test_mixed_valid_and_invalid_extensions() { $plugins = [ - $this->make_extension( 'plugin', source: 'plugin' ), - $this->make_extension( 'plugin', source: 'http://validurl.com/plugin.zip' ), - $this->make_extension( 'plugin', source: 'invalidurl.com' ), - $this->make_extension( 'plugin', source: 'user/repo' ), + $this->make_extension( 'plugin', null, 'plugin' ), + $this->make_extension( 'plugin', null, 'http://validurl.com/plugin.zip' ), + $this->make_extension( 'plugin', null, 'invalidurl.com' ), + $this->make_extension( 'plugin', null, 'user/repo' ), ]; $themes = [ - $this->make_extension( 'theme', source: 'theme' ), - $this->make_extension( 'theme', source: '123' ), - $this->make_extension( 'theme', source: 'ssh://example.com/theme' ), + $this->make_extension( 'theme', null, 'theme' ), + $this->make_extension( 'theme', null, '123' ), + $this->make_extension( 'theme', null, 'ssh://example.com/theme' ), ]; $this->expectException( InvalidArgumentException::class ); $this->assertMatchesJsonSnapshot( $this->sut->categorize_extensions( $plugins, $themes, '/tmp/cache/' ) ); @@ -186,25 +175,14 @@ public function test_empty_arrays() { $this->assertMatchesJsonSnapshot( $this->sut->categorize_extensions( [], [], '/tmp/cache/' ) ); } - /* - public function test_non_zip_urls_in_mixed_scenarios() { - $plugins = [ - $this->make_extension( 'plugin', source: 'http://example.com/plugin' ), - $this->make_extension( 'plugin', source: 'https://example.com/plugin.zip' ), - ]; - $this->expectException( \InvalidArgumentException::class ); - $this->sut->categorize_extensions( $plugins, [], '/tmp/cache/' ); - } - */ - public function test_extensions_with_special_characters() { $plugins = [ - $this->make_extension( 'plugin', source: 'special_plugin@1.0' ), - $this->make_extension( 'plugin', source: 'another-plugin#version' ), + $this->make_extension( 'plugin', null, 'special_plugin@1.0' ), + $this->make_extension( 'plugin', null, 'another-plugin#version' ), ]; $themes = [ - $this->make_extension( 'theme', source: 'theme with spaces' ), - $this->make_extension( 'theme', source: 'theme_special*chars' ), + $this->make_extension( 'theme', null, 'theme with spaces' ), + $this->make_extension( 'theme', null, 'theme_special*chars' ), ]; $this->expectException( InvalidArgumentException::class ); $this->expectExceptionMessage( 'Could not find extension' ); @@ -213,22 +191,22 @@ public function test_extensions_with_special_characters() { public function test_long_extension_names() { $plugins = [ - $this->make_extension( 'plugin', slug: 'this-is-a-very-long-plugin-name-that-might-exceed-typical-limits' ), + $this->make_extension( 'plugin', 'this-is-a-very-long-plugin-name-that-might-exceed-typical-limits' ), ]; $themes = [ - $this->make_extension( 'theme', slug: 'this-is-a-very-long-theme-name-that-might-exceed-typical-limits' ), + $this->make_extension( 'theme', 'this-is-a-very-long-theme-name-that-might-exceed-typical-limits' ), ]; $this->assertMatchesJsonSnapshot( $this->sut->categorize_extensions( $plugins, $themes, '/tmp/cache/' ) ); } public function test_duplicate_entries() { $plugins = [ - $this->make_extension( 'plugin', slug: 'duplicate-plugin' ), - $this->make_extension( 'plugin', slug: 'duplicate-plugin' ), + $this->make_extension( 'plugin', 'duplicate-plugin' ), + $this->make_extension( 'plugin', 'duplicate-plugin' ), ]; $themes = [ - $this->make_extension( 'theme', slug: 'duplicate-theme' ), - $this->make_extension( 'theme', slug: 'duplicate-theme' ), + $this->make_extension( 'theme', 'duplicate-theme' ), + $this->make_extension( 'theme', 'duplicate-theme' ), ]; $this->expectException( InvalidArgumentException::class ); $this->expectExceptionMessage( 'Duplicate extension found.' ); @@ -237,21 +215,21 @@ public function test_duplicate_entries() { public function test_extensions_with_dot() { $plugins = [ - $this->make_extension( 'plugin', slug: 'plugin-v1.2.3' ), - $this->make_extension( 'plugin', slug: 'plugin-v4.5.6' ), + $this->make_extension( 'plugin', 'plugin-v1.2.3' ), + $this->make_extension( 'plugin', 'plugin-v4.5.6' ), ]; $themes = [ - $this->make_extension( 'theme', slug: 'theme-v7.8.9' ), + $this->make_extension( 'theme', 'theme-v7.8.9' ), ]; $this->assertMatchesJsonSnapshot( $this->sut->categorize_extensions( $plugins, $themes, '/tmp/cache/' ) ); } public function test_mixed_extension_types_in_single_array() { $plugins = [ - $this->make_extension( 'plugin', source: '123' ), - $this->make_extension( 'plugin', source: 'https://example.com/plugin.zip' ), - $this->make_extension( 'plugin', source: '/path/to/plugin' ), - $this->make_extension( 'plugin', source: 'user/repository' ), + $this->make_extension( 'plugin', null, '123' ), + $this->make_extension( 'plugin', null, 'https://example.com/plugin.zip' ), + $this->make_extension( 'plugin', null, '/path/to/plugin' ), + $this->make_extension( 'plugin', null, 'user/repository' ), ]; $this->expectException( \InvalidArgumentException::class ); $this->sut->categorize_extensions( $plugins, [], '/tmp/cache/' ); @@ -259,12 +237,12 @@ public function test_mixed_extension_types_in_single_array() { public function test_custom_handler() { $plugins = [ - $this->make_extension( 'plugin', slug: 'foo-custom-1' ), - $this->make_extension( 'plugin', slug: 'foo-custom-2' ), + $this->make_extension( 'plugin', 'foo-custom-1' ), + $this->make_extension( 'plugin', 'foo-custom-2' ), ]; $themes = [ - $this->make_extension( 'theme', slug: 'foo-custom-theme-1' ), - $this->make_extension( 'theme', slug: 'foo-custom-theme-2' ), + $this->make_extension( 'theme', 'foo-custom-theme-1' ), + $this->make_extension( 'theme', 'foo-custom-theme-2' ), ]; $this->assertMatchesJsonSnapshot( $this->sut->categorize_extensions( $plugins, $themes, '/tmp/cache/' ) ); } @@ -338,4 +316,4 @@ public function provider_invalid_slugs_from_file() { public function test_invalid_slugs_from_file( $slug ) { $this->assertFalse( ExtensionDownloader::is_valid_plugin_slug( $slug ) ); } -} +} \ No newline at end of file From aa103b018c48b93067cb82e584d7c36dcbac3e13 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 10:16:30 -0300 Subject: [PATCH 05/33] Add command to run or check all phpunit versions as convenience --- Makefile | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 799e1091..a68c0d35 100644 --- a/Makefile +++ b/Makefile @@ -6,9 +6,11 @@ ROOT ?= 0 DEBUG ?= 0 ARGS ?= -PHP_VERSION ?= 8.3 VERSION ?= qit_dev_build +PHP_VERSIONS = 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 +PHP_VERSION ?= 8.3 + ifeq (1, $(ROOT)) DOCKER_USER ?= "0:0" else @@ -77,6 +79,20 @@ phpstan: phpunit: $(call execPhpAlpine,/app/src/vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS)) +phpunit-all: + @for ver in $(PHP_VERSIONS); do \ + echo "Running PHPUnit on PHP $$ver..."; \ + $(MAKE) phpunit PHP_VERSION=$$ver || exit 1; \ + done + +check-php-versions: + @for ver in $(PHP_VERSIONS); do \ + echo "Checking PHP version in qit-cli-php-$$ver..."; \ + docker image inspect qit-cli-php-$$ver >/dev/null 2>&1 || (echo "Image not found for $$ver, building..." && docker build --build-arg CI=${CI} --build-arg PHP_VERSION=$$ver -t qit-cli-php-$$ver ./_build/docker/php); \ + docker run --rm qit-cli-php-$$ver php -v; \ + echo "-----------------------------------"; \ + done + phan: docker run --rm \ -v ${PWD}/src:/mnt/src \ From 8cef3a4e9ffc89b4060b37fdca6c6f03eb17a0bf Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 10:21:40 -0300 Subject: [PATCH 06/33] Move file --- .github/{ => workflows}/phpunit.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflows}/phpunit.yml (100%) diff --git a/.github/phpunit.yml b/.github/workflows/phpunit.yml similarity index 100% rename from .github/phpunit.yml rename to .github/workflows/phpunit.yml From 8565697ab34eb6d1ce76d238a1fa174968405f02 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 10:22:11 -0300 Subject: [PATCH 07/33] Remove make phpunit from code-tests.yml --- .github/workflows/code-tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/code-tests.yml b/.github/workflows/code-tests.yml index 0d07ea12..62e71242 100644 --- a/.github/workflows/code-tests.yml +++ b/.github/workflows/code-tests.yml @@ -26,5 +26,3 @@ jobs: run: make phpstan - name: Run Phan run: make phan - - name: Run PHPUnit - run: make phpunit From d861a5d9378aa444f229fb6bb827747d9cb59f29 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 10:23:39 -0300 Subject: [PATCH 08/33] Re-add phpunit workflow --- .github/workflows/phpunit.yml | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 0e64a70b..e1ad11fd 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -3,10 +3,32 @@ on: pull_request: paths: - 'src/**.php' + workflow_dispatch: jobs: phpunit_tests: + name: PHPUnit on PHP ${{ matrix.php }} runs-on: ubuntu-latest + strategy: + matrix: + php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] steps: - - name: Echo Bogus - run: echo "Bogus workflow to allow PR-based testing." + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache composer dependencies + uses: actions/cache@v3 + with: + path: src/vendor + key: ${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('src/composer.lock') }} + + - name: Composer install + if: steps.cache-composer.outputs.cache-hit != 'true' + run: | + cd src + composer install --no-interaction --no-suggest --prefer-dist + + - name: Run PHPUnit tests + env: + PHP_VERSION: ${{ matrix.php }} + run: make phpunit \ No newline at end of file From f27ba546d2ce720c9f23eaf7744d6a0cf6fcfa2c Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 11:15:09 -0300 Subject: [PATCH 09/33] Run locally in CI and Dockerized locally --- .github/workflows/phpunit.yml | 10 +++++++++- Makefile | 11 ++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index e1ad11fd..10fcea5e 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -12,12 +12,20 @@ jobs: strategy: matrix: php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + steps: - name: Checkout code uses: actions/checkout@v4 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + - name: Cache composer dependencies uses: actions/cache@v3 + id: cache-composer with: path: src/vendor key: ${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('src/composer.lock') }} @@ -31,4 +39,4 @@ jobs: - name: Run PHPUnit tests env: PHP_VERSION: ${{ matrix.php }} - run: make phpunit \ No newline at end of file + run: make phpunit diff --git a/Makefile b/Makefile index a68c0d35..9bd94c11 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ ROOT ?= 0 DEBUG ?= 0 ARGS ?= VERSION ?= qit_dev_build +PHPUNIT_CMD = vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS) PHP_VERSIONS = 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 PHP_VERSION ?= 8.3 @@ -76,8 +77,16 @@ phpcs: phpstan: $(call execPhpAlpine,/app/src/vendor/bin/phpstan -vvv analyse -c /app/src/phpstan.neon) +PHPUNIT_CMD = vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS) + phpunit: - $(call execPhpAlpine,/app/src/vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS)) +ifeq ($(CI),true) + # In CI: run PHPUnit directly (assuming dependencies already installed) + cd src && ../vendor/bin/phpunit -c phpunit.xml.dist $(ARGS) +else + # Locally: run PHPunit in Docker + $(call execPhpAlpine,$(PHPUNIT_CMD)) +endif phpunit-all: @for ver in $(PHP_VERSIONS); do \ From 5492304d0b301ccbc793ed4667c0290c68440d12 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 11:22:37 -0300 Subject: [PATCH 10/33] Fix paths --- .github/workflows/phpunit.yml | 1 + Makefile | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 10fcea5e..40bc69cb 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -22,6 +22,7 @@ jobs: with: php-version: ${{ matrix.php }} coverage: none + extensions: zip - name: Cache composer dependencies uses: actions/cache@v3 diff --git a/Makefile b/Makefile index 9bd94c11..fd7b7a9f 100644 --- a/Makefile +++ b/Makefile @@ -81,11 +81,11 @@ PHPUNIT_CMD = vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS) phpunit: ifeq ($(CI),true) - # In CI: run PHPUnit directly (assuming dependencies already installed) - cd src && ../vendor/bin/phpunit -c phpunit.xml.dist $(ARGS) + # In CI: run PHPUnit directly + cd src && vendor/bin/phpunit -c phpunit.xml.dist $(ARGS) else - # Locally: run PHPunit in Docker - $(call execPhpAlpine,$(PHPUNIT_CMD)) + # Locally: run via Docker + $(call execPhpAlpine,/app/src/vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS)) endif phpunit-all: From 8e91b83c252d61eb58aa7f9d97f9ac3454105775 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 11:29:51 -0300 Subject: [PATCH 11/33] Revert "Fix paths" This reverts commit 5492304d0b301ccbc793ed4667c0290c68440d12. --- .github/workflows/phpunit.yml | 1 - Makefile | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 40bc69cb..10fcea5e 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -22,7 +22,6 @@ jobs: with: php-version: ${{ matrix.php }} coverage: none - extensions: zip - name: Cache composer dependencies uses: actions/cache@v3 diff --git a/Makefile b/Makefile index fd7b7a9f..9bd94c11 100644 --- a/Makefile +++ b/Makefile @@ -81,11 +81,11 @@ PHPUNIT_CMD = vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS) phpunit: ifeq ($(CI),true) - # In CI: run PHPUnit directly - cd src && vendor/bin/phpunit -c phpunit.xml.dist $(ARGS) + # In CI: run PHPUnit directly (assuming dependencies already installed) + cd src && ../vendor/bin/phpunit -c phpunit.xml.dist $(ARGS) else - # Locally: run via Docker - $(call execPhpAlpine,/app/src/vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS)) + # Locally: run PHPunit in Docker + $(call execPhpAlpine,$(PHPUNIT_CMD)) endif phpunit-all: From daf648f047a72c0ac0ac575eeaaaf7a06b193e45 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 11:29:56 -0300 Subject: [PATCH 12/33] Revert "Run locally in CI and Dockerized locally" This reverts commit f27ba546d2ce720c9f23eaf7744d6a0cf6fcfa2c. --- .github/workflows/phpunit.yml | 10 +--------- Makefile | 11 +---------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 10fcea5e..e1ad11fd 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -12,20 +12,12 @@ jobs: strategy: matrix: php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] - steps: - name: Checkout code uses: actions/checkout@v4 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - coverage: none - - name: Cache composer dependencies uses: actions/cache@v3 - id: cache-composer with: path: src/vendor key: ${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('src/composer.lock') }} @@ -39,4 +31,4 @@ jobs: - name: Run PHPUnit tests env: PHP_VERSION: ${{ matrix.php }} - run: make phpunit + run: make phpunit \ No newline at end of file diff --git a/Makefile b/Makefile index 9bd94c11..a68c0d35 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,6 @@ ROOT ?= 0 DEBUG ?= 0 ARGS ?= VERSION ?= qit_dev_build -PHPUNIT_CMD = vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS) PHP_VERSIONS = 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 PHP_VERSION ?= 8.3 @@ -77,16 +76,8 @@ phpcs: phpstan: $(call execPhpAlpine,/app/src/vendor/bin/phpstan -vvv analyse -c /app/src/phpstan.neon) -PHPUNIT_CMD = vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS) - phpunit: -ifeq ($(CI),true) - # In CI: run PHPUnit directly (assuming dependencies already installed) - cd src && ../vendor/bin/phpunit -c phpunit.xml.dist $(ARGS) -else - # Locally: run PHPunit in Docker - $(call execPhpAlpine,$(PHPUNIT_CMD)) -endif + $(call execPhpAlpine,/app/src/vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS)) phpunit-all: @for ver in $(PHP_VERSIONS); do \ From 4c57356aa6525c7c31e1fde2feba5b33b63eb52a Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 11:45:07 -0300 Subject: [PATCH 13/33] Cache built image --- .github/workflows/phpunit.yml | 25 ++++++++++++++++++++++++- Makefile | 25 ++++++++++++------------- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index e1ad11fd..ca8cbb22 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -11,13 +11,36 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ] + steps: - name: Checkout code uses: actions/checkout@v4 + # Attempt to restore cached Docker image tarball for the specific PHP version + - name: Restore Docker image cache + uses: actions/cache@v3 + id: cache-docker + with: + path: qit-cli-tests-${{ matrix.php }}.tar + key: ${{ runner.os }}-qit-cli-tests-${{ matrix.php }}-${{ hashFiles('_build/docker/php/**') }} + + # If not cached, build the Docker image for this specific PHP version + - name: Build Docker image if needed + if: steps.cache-docker.outputs.cache-hit != 'true' + run: | + docker build --build-arg CI=true --build-arg PHP_VERSION=${{ matrix.php }} -t qit-cli-tests:${{ matrix.php }} ./_build/docker/php + docker save qit-cli-tests:${{ matrix.php }} -o qit-cli-tests-${{ matrix.php }}.tar + + # If image is cached, load it + - name: Load Docker image from cache + if: steps.cache-docker.outputs.cache-hit == 'true' + run: | + docker load -i qit-cli-tests-${{ matrix.php }}.tar + - name: Cache composer dependencies uses: actions/cache@v3 + id: cache-composer with: path: src/vendor key: ${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('src/composer.lock') }} diff --git a/Makefile b/Makefile index a68c0d35..45356d76 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,9 @@ DEBUG ?= 0 ARGS ?= VERSION ?= qit_dev_build +# List all PHP versions you want to test/build images for: PHP_VERSIONS = 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4 +# Default PHP version used if none specified PHP_VERSION ?= 8.3 ifeq (1, $(ROOT)) @@ -17,12 +19,13 @@ else DOCKER_USER ?= "$(shell id -u):$(shell id -g)" endif -## Run a command inside an alpine PHP 8 CLI image. -## 1. Command to execute, eg: "./vendor/bin/phpcs" 2. Working dir (optional) +## Run a command inside a PHP CLI Docker image built for a specific PHP_VERSION. +## 1. Command to execute, e.g.: "./vendor/bin/phpcs" +## 2. Working dir (optional) define execPhpAlpine - @docker image inspect qit-cli-php-$(PHP_VERSION) > /dev/null 2>&1 || \ - (echo "Docker image not found. Building qit-cli-php-$(PHP_VERSION)..." && \ - docker build --build-arg CI=${CI} --build-arg PHP_VERSION=$(PHP_VERSION) -t qit-cli-php-$(PHP_VERSION) ./_build/docker/php) + @docker image inspect qit-cli-tests:$(PHP_VERSION) > /dev/null 2>&1 || \ + (echo "Docker image not found. Building qit-cli-tests:$(PHP_VERSION)..." && \ + docker build --build-arg CI=${CI} --build-arg PHP_VERSION=$(PHP_VERSION) -t qit-cli-tests:$(PHP_VERSION) ./_build/docker/php) @docker run --rm \ --user $(DOCKER_USER) \ @@ -31,7 +34,7 @@ define execPhpAlpine --env QIT_HOME=/tmp \ --env PHP_IDE_CONFIG=serverName=qit_cli \ --workdir "$(2:=/)" \ - qit-cli-php-$(PHP_VERSION) \ + qit-cli-tests:$(PHP_VERSION) \ bash -c "php -d xdebug.start_with_request=$(if $(filter 1,$(DEBUG)),yes,no) -d memory_limit=1G $(1)" endef @@ -49,14 +52,11 @@ build: composer \ install --no-dev --quiet --optimize-autoloader --ignore-platform-reqs - # Create a temporary configuration file with the specified VERSION @sed "s/QIT_VERSION_REPLACE/$(VERSION)/g" ./_build/box.json.dist > ./_build/box.json - # Ensure the Docker image is built and run Box with the temporary configuration file @docker images -q | grep qit-cli-box || docker build -t qit-cli-box ./_build/docker/box @docker run --rm -v ${PWD}:${PWD} -w ${PWD} -u "$(shell id -u):$(shell id -g)" qit-cli-box ./_build/box.phar compile -c ./_build/box.json --no-parallel || rm -rf src-tmp - # Clean up the temporary directory and configuration file @rm -rf src-tmp @rm -f ./_build/box.json @@ -87,9 +87,9 @@ phpunit-all: check-php-versions: @for ver in $(PHP_VERSIONS); do \ - echo "Checking PHP version in qit-cli-php-$$ver..."; \ - docker image inspect qit-cli-php-$$ver >/dev/null 2>&1 || (echo "Image not found for $$ver, building..." && docker build --build-arg CI=${CI} --build-arg PHP_VERSION=$$ver -t qit-cli-php-$$ver ./_build/docker/php); \ - docker run --rm qit-cli-php-$$ver php -v; \ + echo "Checking PHP version in qit-cli-tests:$$ver..."; \ + docker image inspect qit-cli-tests:$$ver >/dev/null 2>&1 || (echo "Image not found for $$ver, building..." && docker build --build-arg CI=${CI} --build-arg PHP_VERSION=$$ver -t qit-cli-tests:$$ver ./_build/docker/php); \ + docker run --rm qit-cli-tests:$$ver php -v; \ echo "-----------------------------------"; \ done @@ -98,4 +98,3 @@ phan: -v ${PWD}/src:/mnt/src \ -u "$$(id -u):$$(id -g)" \ phanphp/phan:latest $(ARGS) - # PS: To update Phan, run: docker image pull phanphp/phan:latest \ No newline at end of file From d73ed7675d0e65c7e5274c0ee674f5353a4795d9 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 11:49:09 -0300 Subject: [PATCH 14/33] Test cached run --- src/src/Auth.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/Auth.php b/src/src/Auth.php index 14a7c32e..f6406513 100644 --- a/src/src/Auth.php +++ b/src/src/Auth.php @@ -11,7 +11,7 @@ public function __construct( Cache $cache ) { } /** - * @return string|null base64 encoded string of user:application_password, or null if not defined. + * @return string|null base64 encoded string of "user:application_password", or null if not defined. */ public function get_partner_auth() { // Migrate "application_password" to "qit_token" if it exists. From ad593a9b7bdf5c162303fc990c7a00e2f5bac103 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 11:52:23 -0300 Subject: [PATCH 15/33] Test cache burst if needed --- _build/docker/php/Dockerfile | 1 + src/src/Auth.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/_build/docker/php/Dockerfile b/_build/docker/php/Dockerfile index 3a00d760..520dc94d 100644 --- a/_build/docker/php/Dockerfile +++ b/_build/docker/php/Dockerfile @@ -1,4 +1,5 @@ # Use an ARG for the PHP version. Default to 8.3 if not provided. +# Make a change to Dockerfile ARG PHP_VERSION=8.3 FROM php:${PHP_VERSION}-cli diff --git a/src/src/Auth.php b/src/src/Auth.php index f6406513..14a7c32e 100644 --- a/src/src/Auth.php +++ b/src/src/Auth.php @@ -11,7 +11,7 @@ public function __construct( Cache $cache ) { } /** - * @return string|null base64 encoded string of "user:application_password", or null if not defined. + * @return string|null base64 encoded string of user:application_password, or null if not defined. */ public function get_partner_auth() { // Migrate "application_password" to "qit_token" if it exists. From ffa870bd7a9485d480f3bfef31d046491a38a335 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 11:55:46 -0300 Subject: [PATCH 16/33] Revert cache burst check --- _build/docker/php/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/_build/docker/php/Dockerfile b/_build/docker/php/Dockerfile index 520dc94d..3a00d760 100644 --- a/_build/docker/php/Dockerfile +++ b/_build/docker/php/Dockerfile @@ -1,5 +1,4 @@ # Use an ARG for the PHP version. Default to 8.3 if not provided. -# Make a change to Dockerfile ARG PHP_VERSION=8.3 FROM php:${PHP_VERSION}-cli From 5ac812076b120a7f6372cb66a4e5f1ce86a369a6 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 12:55:39 -0300 Subject: [PATCH 17/33] Also run Phan on multiple PHP versions --- .github/workflows/phan.yml | 46 +- Makefile | 63 +- _build/docker/php/Dockerfile | 3 + src/.phan/config.php | 2 +- src/composer.json | 3 +- src/composer.lock | 847 +++++++++++++++++- .../Commands/CustomTests/RunE2ECommand.php | 2 +- 7 files changed, 937 insertions(+), 29 deletions(-) diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index 0d839281..1cdff3d0 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -3,10 +3,52 @@ on: pull_request: paths: - 'src/**.php' + workflow_dispatch: jobs: phan_tests: runs-on: ubuntu-latest + strategy: + matrix: + php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + steps: - - name: Echo Bogus - run: echo "Bogus workflow to allow PR-based testing." + - name: Checkout code + uses: actions/checkout@v4 + + # Restore Docker image cache for qit-cli-tests: + - name: Restore Docker image cache + uses: actions/cache@v3 + id: cache-docker + with: + path: qit-cli-tests-${{ matrix.php }}.tar + key: ${{ runner.os }}-qit-cli-tests-${{ matrix.php }}-${{ hashFiles('_build/docker/php/**') }} + + - name: Build Docker image if needed + if: steps.cache-docker.outputs.cache-hit != 'true' + run: | + docker build --build-arg CI=true --build-arg PHP_VERSION=${{ matrix.php }} -t qit-cli-tests:${{ matrix.php }} ./_build/docker/php + docker save qit-cli-tests:${{ matrix.php }} -o qit-cli-tests-${{ matrix.php }}.tar + + - name: Load Docker image from cache + if: steps.cache-docker.outputs.cache-hit == 'true' + run: | + docker load -i qit-cli-tests-${{ matrix.php }}.tar + + - name: Cache composer dependencies + uses: actions/cache@v3 + id: cache-composer + with: + path: src/vendor + key: ${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('src/composer.lock') }} + + - name: Composer install + if: steps.cache-composer.outputs.cache-hit != 'true' + run: | + cd src + composer install --no-interaction --no-suggest --prefer-dist + + - name: Run Phan + env: + PHP_VERSION: ${{ matrix.php }} + run: make phan \ No newline at end of file diff --git a/Makefile b/Makefile index 45356d76..f4cf7baf 100644 --- a/Makefile +++ b/Makefile @@ -20,22 +20,25 @@ DOCKER_USER ?= "$(shell id -u):$(shell id -g)" endif ## Run a command inside a PHP CLI Docker image built for a specific PHP_VERSION. -## 1. Command to execute, e.g.: "./vendor/bin/phpcs" +## 1. Command to execute, e.g.: "php /app/src/vendor/bin/phpcs" ## 2. Working dir (optional) define execPhpAlpine - @docker image inspect qit-cli-tests:$(PHP_VERSION) > /dev/null 2>&1 || \ - (echo "Docker image not found. Building qit-cli-tests:$(PHP_VERSION)..." && \ - docker build --build-arg CI=${CI} --build-arg PHP_VERSION=$(PHP_VERSION) -t qit-cli-tests:$(PHP_VERSION) ./_build/docker/php) - - @docker run --rm \ - --user $(DOCKER_USER) \ - -v "${PWD}:/app" \ - -v "${PWD}/_build/docker/php/ini/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini" \ - --env QIT_HOME=/tmp \ - --env PHP_IDE_CONFIG=serverName=qit_cli \ - --workdir "$(2:=/)" \ - qit-cli-tests:$(PHP_VERSION) \ - bash -c "php -d xdebug.start_with_request=$(if $(filter 1,$(DEBUG)),yes,no) -d memory_limit=1G $(1)" + @docker image inspect qit-cli-tests:$(PHP_VERSION) > /dev/null 2>&1 || \ + (echo "Docker image not found. Building qit-cli-tests:$(PHP_VERSION)..." && \ + docker build --build-arg CI=${CI} --build-arg PHP_VERSION=$(PHP_VERSION) -t qit-cli-tests:$(PHP_VERSION) ./_build/docker/php) + + @docker run --rm \ + --user $(DOCKER_USER) \ + -v "${PWD}:/app" \ + -v "${PWD}/_build/docker/php/ini/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini" \ + --env QIT_HOME=/tmp \ + --env PHP_IDE_CONFIG=serverName=qit_cli \ + --env TARGET_PHP_VERSION=$(PHP_VERSION) \ + --env PHAN_DISABLE_XDEBUG_WARN=1 \ + --env PHAN_ALLOW_XDEBUG=1 \ + --workdir "$(2:=/)" \ + qit-cli-tests:$(PHP_VERSION) \ + bash -c "$(1)" endef watch: @@ -66,18 +69,25 @@ tests: $(MAKE) phpunit $(MAKE) phan +tests-all: + $(MAKE) phpcs + $(MAKE) phpstan + $(MAKE) phpunit-all + $(MAKE) phan-all + phpcbf: - $(call execPhpAlpine,/app/src/vendor/bin/phpcbf /app/src/qit-cli.php /app/src/src -s --standard=/app/src/.phpcs.xml.dist) + $(call execPhpAlpine,php /app/src/vendor/bin/phpcbf /app/src/qit-cli.php /app/src/src -s --standard=/app/src/.phpcs.xml.dist) phpcs: $(MAKE) phpcbf || true - $(call execPhpAlpine,/app/src/vendor/bin/phpcs /app/src/qit-cli.php /app/src/src -s --standard=/app/src/.phpcs.xml.dist) + $(call execPhpAlpine,php /app/src/vendor/bin/phpcs /app/src/qit-cli.php /app/src/src -s --standard=/app/src/.phpcs.xml.dist) +# Added --memory-limit=1G here phpstan: - $(call execPhpAlpine,/app/src/vendor/bin/phpstan -vvv analyse -c /app/src/phpstan.neon) + $(call execPhpAlpine,php /app/src/vendor/bin/phpstan -vvv analyse -c /app/src/phpstan.neon --memory-limit=1G) phpunit: - $(call execPhpAlpine,/app/src/vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS)) + $(call execPhpAlpine,php /app/src/vendor/bin/phpunit -c /app/src/phpunit.xml.dist $(ARGS),/app/src) phpunit-all: @for ver in $(PHP_VERSIONS); do \ @@ -85,6 +95,12 @@ phpunit-all: $(MAKE) phpunit PHP_VERSION=$$ver || exit 1; \ done +phan-all: + @for ver in $(PHP_VERSIONS); do \ + echo "Running Phan on PHP $$ver..."; \ + $(MAKE) phan PHP_VERSION=$$ver || exit 1; \ + done + check-php-versions: @for ver in $(PHP_VERSIONS); do \ echo "Checking PHP version in qit-cli-tests:$$ver..."; \ @@ -93,8 +109,11 @@ check-php-versions: echo "-----------------------------------"; \ done +rebuild-images: + @for ver in $(PHP_VERSIONS); do \ + echo "Rebuilding qit-cli-tests:$$ver..."; \ + docker build --no-cache --build-arg CI=${CI} --build-arg PHP_VERSION=$$ver -t qit-cli-tests:$$ver ./_build/docker/php || exit 1; \ + done + phan: - docker run --rm \ - -v ${PWD}/src:/mnt/src \ - -u "$$(id -u):$$(id -g)" \ - phanphp/phan:latest $(ARGS) + $(call execPhpAlpine,php -d xdebug.mode=off /app/src/vendor/bin/phan $(ARGS),/app/src) diff --git a/_build/docker/php/Dockerfile b/_build/docker/php/Dockerfile index 3a00d760..4e40ec5e 100644 --- a/_build/docker/php/Dockerfile +++ b/_build/docker/php/Dockerfile @@ -8,6 +8,9 @@ RUN apt-get update \ && docker-php-ext-install zip pcntl \ && docker-php-ext-enable zip pcntl +# Install php-ast +RUN pecl install ast && docker-php-ext-enable ast + # Install Xdebug only if not in CI environment and PHP major version >= 8 RUN if [ "$CI" != "true" ] && [ "${PHP_VERSION%%.*}" -ge 8 ]; then \ pecl install xdebug && docker-php-ext-enable xdebug; \ diff --git a/src/.phan/config.php b/src/.phan/config.php index 737b0805..2a41c1ca 100644 --- a/src/.phan/config.php +++ b/src/.phan/config.php @@ -50,7 +50,7 @@ // Note that the **only** effect of choosing `'5.6'` is to infer that functions removed in php 7.0 exist. // (See `backward_compatibility_checks` for additional options) // Automatically inferred from composer.json requirement for "php" of "^7.2.5 | ^8" - 'target_php_version' => '7.2', + 'target_php_version' => getenv( 'TARGET_PHP_VERSION' ) ?: '7.2', // If enabled, missing properties will be created when // they are first seen. If false, we'll report an diff --git a/src/composer.json b/src/composer.json index 8480d90a..0b742f18 100644 --- a/src/composer.json +++ b/src/composer.json @@ -40,6 +40,7 @@ "dealerdirect/phpcodesniffer-composer-installer": "^1", "wp-coding-standards/wpcs": "dev-develop", "phpcompatibility/php-compatibility": "^9", - "spatie/phpunit-snapshot-assertions": "^3.0" + "spatie/phpunit-snapshot-assertions": "^3.0", + "phan/phan": "^5.4" } } diff --git a/src/composer.lock b/src/composer.lock index b4ce15d9..659c2f6a 100644 --- a/src/composer.lock +++ b/src/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "576baaeda71fcabf51ca5a82755561a7", + "content-hash": "186bd38aa16994a414f80e09889ba04e", "packages": [ { "name": "composer/ca-bundle", @@ -1563,6 +1563,232 @@ } ], "packages-dev": [ + { + "name": "composer/pcre", + "version": "2.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "ebb81df8f52b40172d14062ae96a06939d80a069" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/ebb81df8f52b40172d14062ae96a06939d80a069", + "reference": "ebb81df8f52b40172d14062ae96a06939d80a069", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/2.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:24:47+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.3", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-09-19T14:15:21+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, { "name": "dealerdirect/phpcodesniffer-composer-installer", "version": "v1.0.0", @@ -1711,6 +1937,96 @@ ], "time": "2022-12-30T00:15:36+00:00" }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "php": "^7.1 || ^8.0", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + }, + "time": "2021-06-11T22:34:44+00:00" + }, + { + "name": "microsoft/tolerant-php-parser", + "version": "v0.1.2", + "source": { + "type": "git", + "url": "https://github.com/microsoft/tolerant-php-parser.git", + "reference": "3eccfd273323aaf69513e2f1c888393f5947804b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/microsoft/tolerant-php-parser/zipball/3eccfd273323aaf69513e2f1c888393f5947804b", + "reference": "3eccfd273323aaf69513e2f1c888393f5947804b", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.15" + }, + "type": "library", + "autoload": { + "psr-4": { + "Microsoft\\PhpParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Lourens", + "email": "roblou@microsoft.com" + } + ], + "description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios", + "support": { + "issues": "https://github.com/microsoft/tolerant-php-parser/issues", + "source": "https://github.com/microsoft/tolerant-php-parser/tree/v0.1.2" + }, + "time": "2022-10-05T17:30:19+00:00" + }, { "name": "myclabs/deep-copy", "version": "1.12.1", @@ -1769,7 +2085,138 @@ "type": "tidelift" } ], - "time": "2024-11-08T17:47:46+00:00" + "time": "2024-11-08T17:47:46+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v4.5.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "8e76efb98ee8b6afc54687045e1b8dba55ac76e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8e76efb98ee8b6afc54687045e1b8dba55ac76e5", + "reference": "8e76efb98ee8b6afc54687045e1b8dba55ac76e5", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/v4.5.0" + }, + "time": "2024-09-08T10:13:13+00:00" + }, + { + "name": "phan/phan", + "version": "5.4.5", + "source": { + "type": "git", + "url": "https://github.com/phan/phan.git", + "reference": "2b15302175931a0629a85c57d0c1f91d68b26a4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phan/phan/zipball/2b15302175931a0629a85c57d0c1f91d68b26a4d", + "reference": "2b15302175931a0629a85c57d0c1f91d68b26a4d", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4|^2.0|^3.0", + "composer/xdebug-handler": "^2.0|^3.0", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.0.4", + "microsoft/tolerant-php-parser": "0.1.2", + "netresearch/jsonmapper": "^1.6.0|^2.0|^3.0|^4.0", + "php": "^7.2.0|^8.0.0", + "sabre/event": "^5.1.3", + "symfony/console": "^3.2|^4.0|^5.0|^6.0|^7.0", + "symfony/polyfill-mbstring": "^1.11.0", + "symfony/polyfill-php80": "^1.20.0", + "tysonandre/var_representation_polyfill": "^0.0.2|^0.1.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.0" + }, + "suggest": { + "ext-ast": "Needed for parsing ASTs (unless --use-fallback-parser is used). 1.0.1+ is needed, 1.0.16+ is recommended.", + "ext-iconv": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-igbinary": "Improves performance of polyfill when ext-ast is unavailable", + "ext-mbstring": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-tokenizer": "Needed for fallback/polyfill parser support and file/line-based suppressions.", + "ext-var_representation": "Suggested for converting values to strings in issue messages" + }, + "bin": [ + "phan", + "phan_client", + "tocheckstyle" + ], + "type": "project", + "autoload": { + "psr-4": { + "Phan\\": "src/Phan" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + }, + { + "name": "Rasmus Lerdorf" + }, + { + "name": "Andrew S. Morrison" + } + ], + "description": "A static analyzer for PHP", + "keywords": [ + "analyzer", + "php", + "static", + "static analysis" + ], + "support": { + "issues": "https://github.com/phan/phan/issues", + "source": "https://github.com/phan/phan/tree/5.4.5" + }, + "time": "2024-08-13T21:41:35+00:00" }, { "name": "phar-io/manifest", @@ -2117,6 +2564,166 @@ ], "time": "2024-05-20T13:34:27+00:00" }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "77a32518733312af16a44300404e945338981de3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + }, + "time": "2022-03-15T21:29:03+00:00" + }, { "name": "phpstan/phpstan", "version": "1.12.12", @@ -2570,6 +3177,122 @@ ], "time": "2024-12-05T13:44:26+00:00" }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, + { + "name": "sabre/event", + "version": "5.1.7", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/event.git", + "reference": "86d57e305c272898ba3c28e9bd3d65d5464587c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/event/zipball/86d57e305c272898ba3c28e9bd3d65d5464587c2", + "reference": "86d57e305c272898ba3c28e9bd3d65d5464587c2", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.17.1||^3.63", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" + }, + "type": "library", + "autoload": { + "files": [ + "lib/coroutine.php", + "lib/Loop/functions.php", + "lib/Promise/functions.php" + ], + "psr-4": { + "Sabre\\Event\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "async", + "coroutine", + "eventloop", + "events", + "hooks", + "plugin", + "promise", + "reactor", + "signal" + ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/event/issues", + "source": "https://github.com/fruux/sabre-event" + }, + "time": "2024-08-27T11:23:05+00:00" + }, { "name": "sebastian/code-unit-reverse-lookup", "version": "1.0.3", @@ -3482,6 +4205,126 @@ ], "time": "2024-03-03T12:36:25+00:00" }, + { + "name": "tysonandre/var_representation_polyfill", + "version": "0.1.3", + "source": { + "type": "git", + "url": "https://github.com/TysonAndre/var_representation_polyfill.git", + "reference": "e9116c2c352bb0835ca428b442dde7767c11ad32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TysonAndre/var_representation_polyfill/zipball/e9116c2c352bb0835ca428b442dde7767c11ad32", + "reference": "e9116c2c352bb0835ca428b442dde7767c11ad32", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.2.0|^8.0.0" + }, + "provide": { + "ext-var_representation": "*" + }, + "require-dev": { + "phan/phan": "^5.4.1", + "phpunit/phpunit": "^8.5.0" + }, + "suggest": { + "ext-var_representation": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.3-dev" + } + }, + "autoload": { + "files": [ + "src/var_representation.php" + ], + "psr-4": { + "VarRepresentation\\": "src/VarRepresentation" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + } + ], + "description": "Polyfill for var_representation: convert a variable to a string in a way that fixes the shortcomings of var_export", + "keywords": [ + "var_export", + "var_representation" + ], + "support": { + "issues": "https://github.com/TysonAndre/var_representation_polyfill/issues", + "source": "https://github.com/TysonAndre/var_representation_polyfill/tree/0.1.3" + }, + "time": "2022-08-31T12:59:22+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + }, { "name": "wp-coding-standards/wpcs", "version": "dev-develop", diff --git a/src/src/Commands/CustomTests/RunE2ECommand.php b/src/src/Commands/CustomTests/RunE2ECommand.php index d0de0b38..b557356c 100644 --- a/src/src/Commands/CustomTests/RunE2ECommand.php +++ b/src/src/Commands/CustomTests/RunE2ECommand.php @@ -361,7 +361,7 @@ private function handle_termination(): void { if ( function_exists( 'pcntl_signal' ) ) { $signal_handler = static function (): void { static::shutdown_test_run(); - exit; + exit( 0 ); }; pcntl_signal( SIGINT, $signal_handler ); pcntl_signal( SIGTERM, $signal_handler ); From 0692aca8aac6c49e27254e95c3f80495cc6472b6 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 12:59:46 -0300 Subject: [PATCH 18/33] Debug CI --- src/src/Auth.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/Auth.php b/src/src/Auth.php index 14a7c32e..f6406513 100644 --- a/src/src/Auth.php +++ b/src/src/Auth.php @@ -11,7 +11,7 @@ public function __construct( Cache $cache ) { } /** - * @return string|null base64 encoded string of user:application_password, or null if not defined. + * @return string|null base64 encoded string of "user:application_password", or null if not defined. */ public function get_partner_auth() { // Migrate "application_password" to "qit_token" if it exists. From dcb763c5e0d3092459b85fdcb39cdb23bf0554ff Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 13:05:16 -0300 Subject: [PATCH 19/33] Also use the docker cache in"code tests" workflow --- .github/workflows/code-tests.yml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/.github/workflows/code-tests.yml b/.github/workflows/code-tests.yml index 62e71242..04e1a088 100644 --- a/.github/workflows/code-tests.yml +++ b/.github/workflows/code-tests.yml @@ -4,25 +4,54 @@ on: push: paths: - 'src/**.php' + jobs: code_tests: name: Code tests runs-on: ubuntu-20.04 + env: + DEFAULT_PHP_VERSION: 8.3 steps: - name: Checkout code uses: actions/checkout@v4 + + # Attempt to restore cached Docker image tarball for the default PHP version + - name: Restore Docker image cache + uses: actions/cache@v3 + id: cache-docker + with: + path: qit-cli-tests-${{ env.DEFAULT_PHP_VERSION }}.tar + key: ${{ runner.os }}-qit-cli-tests-${{ env.DEFAULT_PHP_VERSION }}-${{ hashFiles('_build/docker/php/**') }} + + # If not cached, build the Docker image for this default PHP version + - name: Build Docker image if needed + if: steps.cache-docker.outputs.cache-hit != 'true' + run: | + docker build --build-arg CI=true --build-arg PHP_VERSION=${{ env.DEFAULT_PHP_VERSION }} -t qit-cli-tests:${{ env.DEFAULT_PHP_VERSION }} ./_build/docker/php + docker save qit-cli-tests:${{ env.DEFAULT_PHP_VERSION }} -o qit-cli-tests-${{ env.DEFAULT_PHP_VERSION }}.tar + + # If image is cached, load it + - name: Load Docker image from cache + if: steps.cache-docker.outputs.cache-hit == 'true' + run: | + docker load -i qit-cli-tests-${{ env.DEFAULT_PHP_VERSION }}.tar + - uses: actions/cache@v3 id: cache-composer with: path: src/vendor key: ${{ runner.os }}-${{ hashFiles('src/composer.lock') }} + - name: Composer install if: steps.cache-composer.outputs.cache-hit != 'true' working-directory: src run: composer install + - name: Run PHPCS run: make phpcs + - name: Run PHPStan run: make phpstan + - name: Run Phan - run: make phan + run: make phan \ No newline at end of file From 810d48713467c85f67cbdea42968da72ca290fb5 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 13:08:33 -0300 Subject: [PATCH 20/33] Reuse docker cache logic --- .github/workflows/code-tests.yml | 27 +++------------- .github/workflows/phan.yml | 22 +++---------- .github/workflows/phpunit.yml | 36 +++++----------------- .github/workflows/restore-docker-cache.yml | 32 +++++++++++++++++++ 4 files changed, 47 insertions(+), 70 deletions(-) create mode 100644 .github/workflows/restore-docker-cache.yml diff --git a/.github/workflows/code-tests.yml b/.github/workflows/code-tests.yml index 04e1a088..5e25d428 100644 --- a/.github/workflows/code-tests.yml +++ b/.github/workflows/code-tests.yml @@ -12,29 +12,10 @@ jobs: env: DEFAULT_PHP_VERSION: 8.3 steps: - - name: Checkout code - uses: actions/checkout@v4 - - # Attempt to restore cached Docker image tarball for the default PHP version - - name: Restore Docker image cache - uses: actions/cache@v3 - id: cache-docker + - name: Restore Docker image using reusable workflow + uses: ./.github/workflows/restore-docker-cache.yml with: - path: qit-cli-tests-${{ env.DEFAULT_PHP_VERSION }}.tar - key: ${{ runner.os }}-qit-cli-tests-${{ env.DEFAULT_PHP_VERSION }}-${{ hashFiles('_build/docker/php/**') }} - - # If not cached, build the Docker image for this default PHP version - - name: Build Docker image if needed - if: steps.cache-docker.outputs.cache-hit != 'true' - run: | - docker build --build-arg CI=true --build-arg PHP_VERSION=${{ env.DEFAULT_PHP_VERSION }} -t qit-cli-tests:${{ env.DEFAULT_PHP_VERSION }} ./_build/docker/php - docker save qit-cli-tests:${{ env.DEFAULT_PHP_VERSION }} -o qit-cli-tests-${{ env.DEFAULT_PHP_VERSION }}.tar - - # If image is cached, load it - - name: Load Docker image from cache - if: steps.cache-docker.outputs.cache-hit == 'true' - run: | - docker load -i qit-cli-tests-${{ env.DEFAULT_PHP_VERSION }}.tar + php-version: ${{ env.DEFAULT_PHP_VERSION }} - uses: actions/cache@v3 id: cache-composer @@ -54,4 +35,4 @@ jobs: run: make phpstan - name: Run Phan - run: make phan \ No newline at end of file + run: make phan diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index 1cdff3d0..0e4fcefb 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -16,24 +16,10 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - # Restore Docker image cache for qit-cli-tests: - - name: Restore Docker image cache - uses: actions/cache@v3 - id: cache-docker + - name: Restore Docker image using reusable workflow + uses: ./.github/workflows/restore-docker-cache.yml with: - path: qit-cli-tests-${{ matrix.php }}.tar - key: ${{ runner.os }}-qit-cli-tests-${{ matrix.php }}-${{ hashFiles('_build/docker/php/**') }} - - - name: Build Docker image if needed - if: steps.cache-docker.outputs.cache-hit != 'true' - run: | - docker build --build-arg CI=true --build-arg PHP_VERSION=${{ matrix.php }} -t qit-cli-tests:${{ matrix.php }} ./_build/docker/php - docker save qit-cli-tests:${{ matrix.php }} -o qit-cli-tests-${{ matrix.php }}.tar - - - name: Load Docker image from cache - if: steps.cache-docker.outputs.cache-hit == 'true' - run: | - docker load -i qit-cli-tests-${{ matrix.php }}.tar + php-version: ${{ matrix.php }} - name: Cache composer dependencies uses: actions/cache@v3 @@ -51,4 +37,4 @@ jobs: - name: Run Phan env: PHP_VERSION: ${{ matrix.php }} - run: make phan \ No newline at end of file + run: make phan diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index ca8cbb22..bcaa4ee3 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -7,39 +7,18 @@ on: jobs: phpunit_tests: - name: PHPUnit on PHP ${{ matrix.php }} runs-on: ubuntu-latest strategy: matrix: php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ] steps: - - name: Checkout code - uses: actions/checkout@v4 - - # Attempt to restore cached Docker image tarball for the specific PHP version - - name: Restore Docker image cache - uses: actions/cache@v3 - id: cache-docker + - name: Restore Docker image using reusable workflow + uses: ./.github/workflows/restore-docker-cache.yml with: - path: qit-cli-tests-${{ matrix.php }}.tar - key: ${{ runner.os }}-qit-cli-tests-${{ matrix.php }}-${{ hashFiles('_build/docker/php/**') }} - - # If not cached, build the Docker image for this specific PHP version - - name: Build Docker image if needed - if: steps.cache-docker.outputs.cache-hit != 'true' - run: | - docker build --build-arg CI=true --build-arg PHP_VERSION=${{ matrix.php }} -t qit-cli-tests:${{ matrix.php }} ./_build/docker/php - docker save qit-cli-tests:${{ matrix.php }} -o qit-cli-tests-${{ matrix.php }}.tar - - # If image is cached, load it - - name: Load Docker image from cache - if: steps.cache-docker.outputs.cache-hit == 'true' - run: | - docker load -i qit-cli-tests-${{ matrix.php }}.tar + php-version: ${{ matrix.php }} - - name: Cache composer dependencies - uses: actions/cache@v3 + - uses: actions/cache@v3 id: cache-composer with: path: src/vendor @@ -47,11 +26,10 @@ jobs: - name: Composer install if: steps.cache-composer.outputs.cache-hit != 'true' - run: | - cd src - composer install --no-interaction --no-suggest --prefer-dist + working-directory: src + run: composer install - name: Run PHPUnit tests env: PHP_VERSION: ${{ matrix.php }} - run: make phpunit \ No newline at end of file + run: make phpunit diff --git a/.github/workflows/restore-docker-cache.yml b/.github/workflows/restore-docker-cache.yml new file mode 100644 index 00000000..aa668030 --- /dev/null +++ b/.github/workflows/restore-docker-cache.yml @@ -0,0 +1,32 @@ +name: Restore Docker Image Cache +on: + workflow_call: + inputs: + php-version: + required: true + type: string + +jobs: + restore-docker-cache: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Restore Docker image cache + uses: actions/cache@v3 + id: cache-docker + with: + path: qit-cli-tests-${{ inputs.php-version }}.tar + key: ${{ runner.os }}-qit-cli-tests-${{ inputs.php-version }}-${{ hashFiles('_build/docker/php/**') }} + + - name: Build Docker image if needed + if: steps.cache-docker.outputs.cache-hit != 'true' + run: | + docker build --build-arg CI=true --build-arg PHP_VERSION=${{ inputs.php-version }} -t qit-cli-tests:${{ inputs.php-version }} ./_build/docker/php + docker save qit-cli-tests:${{ inputs.php-version }} -o qit-cli-tests-${{ inputs.php-version }}.tar + + - name: Load Docker image from cache + if: steps.cache-docker.outputs.cache-hit == 'true' + run: | + docker load -i qit-cli-tests-${{ inputs.php-version }}.tar From 93647f300a54388ff361eb3d2c36e3bfa0c7d685 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 13:23:46 -0300 Subject: [PATCH 21/33] Checkout before reuse --- .github/workflows/code-tests.yml | 13 +++++++++---- .github/workflows/phan.yml | 6 +++++- .github/workflows/phpunit.yml | 18 ++++++++++++++---- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/.github/workflows/code-tests.yml b/.github/workflows/code-tests.yml index 5e25d428..119f1b04 100644 --- a/.github/workflows/code-tests.yml +++ b/.github/workflows/code-tests.yml @@ -5,17 +5,22 @@ on: paths: - 'src/**.php' +concurrency: + group: code-tests-${{ github.ref }} + cancel-in-progress: true + jobs: code_tests: name: Code tests runs-on: ubuntu-20.04 - env: - DEFAULT_PHP_VERSION: 8.3 steps: - - name: Restore Docker image using reusable workflow + - name: Checkout code + uses: actions/checkout@v4 + + - name: Reuse Docker restore & build uses: ./.github/workflows/restore-docker-cache.yml with: - php-version: ${{ env.DEFAULT_PHP_VERSION }} + php-version: 8.3 # Using default PHP version 8.3 - uses: actions/cache@v3 id: cache-composer diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index 0e4fcefb..0f527603 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -5,6 +5,10 @@ on: - 'src/**.php' workflow_dispatch: +concurrency: + group: phan-tests-${{ github.ref }} + cancel-in-progress: true + jobs: phan_tests: runs-on: ubuntu-latest @@ -16,7 +20,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Restore Docker image using reusable workflow + - name: Reuse Docker restore & build uses: ./.github/workflows/restore-docker-cache.yml with: php-version: ${{ matrix.php }} diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index bcaa4ee3..d2d0c600 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -5,20 +5,29 @@ on: - 'src/**.php' workflow_dispatch: +concurrency: + group: phpunit-tests-${{ github.ref }} + cancel-in-progress: true + jobs: phpunit_tests: + name: PHPUnit on PHP ${{ matrix.php }} runs-on: ubuntu-latest strategy: matrix: php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ] steps: - - name: Restore Docker image using reusable workflow + - name: Checkout code + uses: actions/checkout@v4 + + - name: Reuse Docker restore & build uses: ./.github/workflows/restore-docker-cache.yml with: php-version: ${{ matrix.php }} - - uses: actions/cache@v3 + - name: Cache composer dependencies + uses: actions/cache@v3 id: cache-composer with: path: src/vendor @@ -26,8 +35,9 @@ jobs: - name: Composer install if: steps.cache-composer.outputs.cache-hit != 'true' - working-directory: src - run: composer install + run: | + cd src + composer install --no-interaction --no-suggest --prefer-dist - name: Run PHPUnit tests env: From 5c9dd2713d43115fa34ef1d9967c6f8a35c7e7c4 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 13:29:42 -0300 Subject: [PATCH 22/33] Tweak syntax --- .github/workflows/code-tests.yml | 4 ++-- .github/workflows/phan.yml | 2 +- .github/workflows/phpunit.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/code-tests.yml b/.github/workflows/code-tests.yml index 119f1b04..ae8a158a 100644 --- a/.github/workflows/code-tests.yml +++ b/.github/workflows/code-tests.yml @@ -18,9 +18,9 @@ jobs: uses: actions/checkout@v4 - name: Reuse Docker restore & build - uses: ./.github/workflows/restore-docker-cache.yml + uses: ./.github/workflows/restore-docker-cache.yml@main with: - php-version: 8.3 # Using default PHP version 8.3 + php-version: 8.3 - uses: actions/cache@v3 id: cache-composer diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index 0f527603..ba8a8b97 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v4 - name: Reuse Docker restore & build - uses: ./.github/workflows/restore-docker-cache.yml + uses: ./.github/workflows/restore-docker-cache.yml@main with: php-version: ${{ matrix.php }} diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index d2d0c600..bcadc60e 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@v4 - name: Reuse Docker restore & build - uses: ./.github/workflows/restore-docker-cache.yml + uses: ./.github/workflows/restore-docker-cache.yml@main with: php-version: ${{ matrix.php }} From 1dd4a2cb26a1d729755461e200c3389f1ae89320 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 13:36:32 -0300 Subject: [PATCH 23/33] Fix syntax --- .github/workflows/code-tests.yml | 12 ++++++------ .github/workflows/phan.yml | 11 ++++++----- .github/workflows/phpunit.yml | 12 ++++++------ 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.github/workflows/code-tests.yml b/.github/workflows/code-tests.yml index ae8a158a..ca58f1cb 100644 --- a/.github/workflows/code-tests.yml +++ b/.github/workflows/code-tests.yml @@ -10,18 +10,18 @@ concurrency: cancel-in-progress: true jobs: + restore_docker_cache: + uses: ./.github/workflows/restore-docker-cache.yml@main + with: + php-version: "8.3" + code_tests: - name: Code tests runs-on: ubuntu-20.04 + needs: restore_docker_cache steps: - name: Checkout code uses: actions/checkout@v4 - - name: Reuse Docker restore & build - uses: ./.github/workflows/restore-docker-cache.yml@main - with: - php-version: 8.3 - - uses: actions/cache@v3 id: cache-composer with: diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index ba8a8b97..8af084c3 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -10,8 +10,14 @@ concurrency: cancel-in-progress: true jobs: + restore_docker_cache: + uses: ./.github/workflows/restore-docker-cache.yml@main + with: + php-version: ${{ matrix.php }} + phan_tests: runs-on: ubuntu-latest + needs: restore_docker_cache strategy: matrix: php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] @@ -20,11 +26,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Reuse Docker restore & build - uses: ./.github/workflows/restore-docker-cache.yml@main - with: - php-version: ${{ matrix.php }} - - name: Cache composer dependencies uses: actions/cache@v3 id: cache-composer diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index bcadc60e..d4912242 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -10,9 +10,14 @@ concurrency: cancel-in-progress: true jobs: + restore_docker_cache: + uses: ./.github/workflows/restore-docker-cache.yml@main + with: + php-version: ${{ matrix.php }} + phpunit_tests: - name: PHPUnit on PHP ${{ matrix.php }} runs-on: ubuntu-latest + needs: restore_docker_cache strategy: matrix: php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ] @@ -21,11 +26,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Reuse Docker restore & build - uses: ./.github/workflows/restore-docker-cache.yml@main - with: - php-version: ${{ matrix.php }} - - name: Cache composer dependencies uses: actions/cache@v3 id: cache-composer From 04cbea7a03b0d6ffae1717dd4d80c939c85c8ccb Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 13:39:03 -0300 Subject: [PATCH 24/33] Trigger CI --- src/src/Auth.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/Auth.php b/src/src/Auth.php index f6406513..14a7c32e 100644 --- a/src/src/Auth.php +++ b/src/src/Auth.php @@ -11,7 +11,7 @@ public function __construct( Cache $cache ) { } /** - * @return string|null base64 encoded string of "user:application_password", or null if not defined. + * @return string|null base64 encoded string of user:application_password, or null if not defined. */ public function get_partner_auth() { // Migrate "application_password" to "qit_token" if it exists. From 266f382a4460573f0efbbe5af02350c932a8b45c Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 13:47:16 -0300 Subject: [PATCH 25/33] Trigger CI --- .github/workflows/code-tests.yml | 4 ++-- src/src/Auth.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/code-tests.yml b/.github/workflows/code-tests.yml index ca58f1cb..c591deab 100644 --- a/.github/workflows/code-tests.yml +++ b/.github/workflows/code-tests.yml @@ -1,9 +1,9 @@ name: QIT CLI Code tests on: - workflow_call: - push: + pull_request: paths: - 'src/**.php' + workflow_dispatch: concurrency: group: code-tests-${{ github.ref }} diff --git a/src/src/Auth.php b/src/src/Auth.php index 14a7c32e..f6406513 100644 --- a/src/src/Auth.php +++ b/src/src/Auth.php @@ -11,7 +11,7 @@ public function __construct( Cache $cache ) { } /** - * @return string|null base64 encoded string of user:application_password, or null if not defined. + * @return string|null base64 encoded string of "user:application_password", or null if not defined. */ public function get_partner_auth() { // Migrate "application_password" to "qit_token" if it exists. From 8ee4b07cb7a9f4d0804ba49e121522fbebb93dc6 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 13:50:37 -0300 Subject: [PATCH 26/33] Typo --- .github/workflows/code-tests.yml | 2 +- .github/workflows/phan.yml | 2 +- .github/workflows/phpunit.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/code-tests.yml b/.github/workflows/code-tests.yml index c591deab..db0db9ae 100644 --- a/.github/workflows/code-tests.yml +++ b/.github/workflows/code-tests.yml @@ -11,7 +11,7 @@ concurrency: jobs: restore_docker_cache: - uses: ./.github/workflows/restore-docker-cache.yml@main + uses: ./.github/workflows/restore-docker-cache.yml with: php-version: "8.3" diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index 8af084c3..efc30e16 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -11,7 +11,7 @@ concurrency: jobs: restore_docker_cache: - uses: ./.github/workflows/restore-docker-cache.yml@main + uses: ./.github/workflows/restore-docker-cache.yml with: php-version: ${{ matrix.php }} diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index d4912242..92fd585a 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -11,7 +11,7 @@ concurrency: jobs: restore_docker_cache: - uses: ./.github/workflows/restore-docker-cache.yml@main + uses: ./.github/workflows/restore-docker-cache.yml with: php-version: ${{ matrix.php }} From 5809f63f15829997cfabd01b794a73601ba4fbec Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 13:50:48 -0300 Subject: [PATCH 27/33] Trigger CI --- src/src/Auth.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/Auth.php b/src/src/Auth.php index f6406513..14a7c32e 100644 --- a/src/src/Auth.php +++ b/src/src/Auth.php @@ -11,7 +11,7 @@ public function __construct( Cache $cache ) { } /** - * @return string|null base64 encoded string of "user:application_password", or null if not defined. + * @return string|null base64 encoded string of user:application_password, or null if not defined. */ public function get_partner_auth() { // Migrate "application_password" to "qit_token" if it exists. From 4e831128b68e5da5581429c5fcbcf7a6ba45fcc1 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 13:56:51 -0300 Subject: [PATCH 28/33] Restore docker cache at the right place in the matrix --- .github/workflows/phan.yml | 3 ++- .github/workflows/phpunit.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index efc30e16..276c7706 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -17,11 +17,12 @@ jobs: phan_tests: runs-on: ubuntu-latest - needs: restore_docker_cache strategy: matrix: php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + needs: restore_docker_cache + steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 92fd585a..c834258f 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -17,11 +17,12 @@ jobs: phpunit_tests: runs-on: ubuntu-latest - needs: restore_docker_cache strategy: matrix: php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ] + needs: restore_docker_cache + steps: - name: Checkout code uses: actions/checkout@v4 From 840935868e63c54dbb12dd66c2912dd49aa35f22 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 14:10:03 -0300 Subject: [PATCH 29/33] Try to use composite action --- .../actions/restore-docker-cache/action.yml | 29 +++++++++++++++++++ .github/workflows/code-tests.yml | 15 ++++------ .github/workflows/phan.yml | 13 +++------ .github/workflows/phpunit.yml | 13 +++------ 4 files changed, 43 insertions(+), 27 deletions(-) create mode 100644 .github/actions/restore-docker-cache/action.yml diff --git a/.github/actions/restore-docker-cache/action.yml b/.github/actions/restore-docker-cache/action.yml new file mode 100644 index 00000000..1ac2c069 --- /dev/null +++ b/.github/actions/restore-docker-cache/action.yml @@ -0,0 +1,29 @@ +name: Restore Docker Image Cache +description: Restores or builds docker image cache for a given PHP version +inputs: + php-version: + description: "PHP version to build/load the docker image for" + required: true +runs: + using: composite + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Restore Docker image cache + uses: actions/cache@v3 + id: cache-docker + with: + path: qit-cli-tests-${{ inputs.php-version }}.tar + key: ${{ runner.os }}-qit-cli-tests-${{ inputs.php-version }}-${{ hashFiles('_build/docker/php/**') }} + + - name: Build Docker image if needed + if: steps.cache-docker.outputs.cache-hit != 'true' + run: | + docker build --build-arg CI=true --build-arg PHP_VERSION=${{ inputs.php-version }} -t qit-cli-tests:${{ inputs.php-version }} ./_build/docker/php + docker save qit-cli-tests:${{ inputs.php-version }} -o qit-cli-tests-${{ inputs.php-version }}.tar + + - name: Load Docker image from cache + if: steps.cache-docker.outputs.cache-hit == 'true' + run: | + docker load -i qit-cli-tests-${{ inputs.php-version }}.tar \ No newline at end of file diff --git a/.github/workflows/code-tests.yml b/.github/workflows/code-tests.yml index db0db9ae..d679483d 100644 --- a/.github/workflows/code-tests.yml +++ b/.github/workflows/code-tests.yml @@ -10,19 +10,16 @@ concurrency: cancel-in-progress: true jobs: - restore_docker_cache: - uses: ./.github/workflows/restore-docker-cache.yml - with: - php-version: "8.3" - code_tests: runs-on: ubuntu-20.04 - needs: restore_docker_cache steps: - - name: Checkout code - uses: actions/checkout@v4 + - name: Restore Docker Cache (default PHP 8.3) + uses: ./.github/actions/restore-docker-cache + with: + php-version: "8.3" - - uses: actions/cache@v3 + - name: Cache composer dependencies + uses: actions/cache@v3 id: cache-composer with: path: src/vendor diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index 276c7706..2e58ac79 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -10,22 +10,17 @@ concurrency: cancel-in-progress: true jobs: - restore_docker_cache: - uses: ./.github/workflows/restore-docker-cache.yml - with: - php-version: ${{ matrix.php }} - phan_tests: runs-on: ubuntu-latest strategy: matrix: php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] - needs: restore_docker_cache - steps: - - name: Checkout code - uses: actions/checkout@v4 + - name: Restore Docker Cache + uses: ./.github/actions/restore-docker-cache + with: + php-version: ${{ matrix.php }} - name: Cache composer dependencies uses: actions/cache@v3 diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index c834258f..14ff4a67 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -10,22 +10,17 @@ concurrency: cancel-in-progress: true jobs: - restore_docker_cache: - uses: ./.github/workflows/restore-docker-cache.yml - with: - php-version: ${{ matrix.php }} - phpunit_tests: runs-on: ubuntu-latest strategy: matrix: php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ] - needs: restore_docker_cache - steps: - - name: Checkout code - uses: actions/checkout@v4 + - name: Restore Docker Cache + uses: ./.github/actions/restore-docker-cache + with: + php-version: ${{ matrix.php }} - name: Cache composer dependencies uses: actions/cache@v3 From 2673062f38b9d38168dea30339d8081c8c8208a4 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 14:13:48 -0300 Subject: [PATCH 30/33] Checkout first --- .github/workflows/code-tests.yml | 3 +++ .github/workflows/phan.yml | 3 +++ .github/workflows/phpunit.yml | 3 +++ 3 files changed, 9 insertions(+) diff --git a/.github/workflows/code-tests.yml b/.github/workflows/code-tests.yml index d679483d..86d2ca5f 100644 --- a/.github/workflows/code-tests.yml +++ b/.github/workflows/code-tests.yml @@ -13,6 +13,9 @@ jobs: code_tests: runs-on: ubuntu-20.04 steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Restore Docker Cache (default PHP 8.3) uses: ./.github/actions/restore-docker-cache with: diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index 2e58ac79..66962008 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -17,6 +17,9 @@ jobs: php: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Restore Docker Cache uses: ./.github/actions/restore-docker-cache with: diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 14ff4a67..250b5c00 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -17,6 +17,9 @@ jobs: php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ] steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Restore Docker Cache uses: ./.github/actions/restore-docker-cache with: From 38ded55a1de52d942c6ee1b09e13cb9d4a3017af Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Sat, 14 Dec 2024 14:16:19 -0300 Subject: [PATCH 31/33] Add missing shell properties --- .github/actions/restore-docker-cache/action.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/actions/restore-docker-cache/action.yml b/.github/actions/restore-docker-cache/action.yml index 1ac2c069..33732f9b 100644 --- a/.github/actions/restore-docker-cache/action.yml +++ b/.github/actions/restore-docker-cache/action.yml @@ -22,8 +22,10 @@ runs: run: | docker build --build-arg CI=true --build-arg PHP_VERSION=${{ inputs.php-version }} -t qit-cli-tests:${{ inputs.php-version }} ./_build/docker/php docker save qit-cli-tests:${{ inputs.php-version }} -o qit-cli-tests-${{ inputs.php-version }}.tar + shell: bash - name: Load Docker image from cache if: steps.cache-docker.outputs.cache-hit == 'true' run: | - docker load -i qit-cli-tests-${{ inputs.php-version }}.tar \ No newline at end of file + docker load -i qit-cli-tests-${{ inputs.php-version }}.tar + shell: bash From fa5bbe8858cfc5d2d949a4fcb8a5de2c55076da8 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Mon, 16 Dec 2024 14:10:37 -0300 Subject: [PATCH 32/33] build --- qit | Bin 2380393 -> 2383117 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/qit b/qit index 9d0b41a8419aaa7a32dae228684c018d9ab38476..82c442e920722e37781e03fcafe10b1499d68853 100755 GIT binary patch delta 84327 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 CrZmg| delta 81397 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 h Date: Mon, 16 Dec 2024 14:18:45 -0300 Subject: [PATCH 33/33] build --- qit | Bin 2381997 -> 2384721 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/qit b/qit index 531747c35957904ebd70caeb0c8fe9a58cd70c1f..1195ea20940fef800a83b82f4edd31da12c76ae3 100755 GIT binary patch delta 84187 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