From d0dc75660c15e1ae83fff7e172214e53a778526d Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Thu, 16 Nov 2023 17:51:49 +0100 Subject: [PATCH 01/12] cache certain GitHub URLs --- src/WP_CLI/CommandWithUpgrade.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/WP_CLI/CommandWithUpgrade.php b/src/WP_CLI/CommandWithUpgrade.php index 53c45df7a..f22016baa 100755 --- a/src/WP_CLI/CommandWithUpgrade.php +++ b/src/WP_CLI/CommandWithUpgrade.php @@ -196,6 +196,9 @@ public function install( $args, $assoc_args ) { add_filter( 'upgrader_source_selection', $filter, 10, 3 ); } + // Check if the URL the URL is cachable and whitelist it then. + self::maybe_cache( $slug, $this->item_type ); + if ( $file_upgrader->install( $slug ) ) { $slug = $file_upgrader->result['destination_name']; $result = true; @@ -771,4 +774,21 @@ private function parse_url_host_component( $url, $component ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url -- parse_url will only be used in absence of wp_parse_url. return function_exists( 'wp_parse_url' ) ? wp_parse_url( $url, $component ) : parse_url( $url, $component ); } + + /** + * Whitelist GitHub URLs for caching. + * + * @param string $url The URL to check. + */ + public static function maybe_cache( $url, $item_type ) { + $matches = []; + + // cache release URLs like `https://github.com/wp-cli-test/generic-example-plugin/releases/download/v0.1.0/generic-example-plugin.0.1.0.zip` + if ( preg_match( '#github\.com/[^/]+/([^/]+)/releases/download/tags/([^/]+)/(.+)\.zip#', $url, $matches ) ) { + WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[2], $matches[3] ); + // cache archive URLs like `https://github.com/wp-cli-test/generic-example-plugin/archive/v0.1.0.zip` + } elseif ( preg_match( '#github\.com/[^/]+/([^/]+)/archive/(version/|)([^/]+)\.zip#', $url, $matches ) ) { + WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[3] ); + } + } } From 8650d36eb8c79c2032ae23a4e3ce3549b1775ac1 Mon Sep 17 00:00:00 2001 From: Daniel Bachhuber Date: Thu, 16 Nov 2023 17:54:49 +0100 Subject: [PATCH 02/12] Stub unit tests --- .gitignore | 1 + phpunit.xml.dist | 17 +++++++++++++++++ tests/PluginCommandTest.php | 11 +++++++++++ 3 files changed, 29 insertions(+) create mode 100644 phpunit.xml.dist create mode 100644 tests/PluginCommandTest.php diff --git a/.gitignore b/.gitignore index bcf211b32..199fcd916 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ composer.lock phpunit.xml phpcs.xml .phpcs.xml +.phpunit.result.cache \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 000000000..0522c8566 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,17 @@ + + + + + tests + + + \ No newline at end of file diff --git a/tests/PluginCommandTest.php b/tests/PluginCommandTest.php new file mode 100644 index 000000000..46ca78a49 --- /dev/null +++ b/tests/PluginCommandTest.php @@ -0,0 +1,11 @@ +assertTrue( true ); + } +} From 4f8012f9a76ee2206213addb5c4b508883f69c1c Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 30 Apr 2025 15:55:08 +0200 Subject: [PATCH 03/12] Update `.gitignore` --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 199fcd916..fa48b47db 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,6 @@ composer.lock phpunit.xml phpcs.xml .phpcs.xml -.phpunit.result.cache \ No newline at end of file +.phpunit.result.cache +.phpunit.cache +build/logs From b4765a55bbf0967b155ebe7244cf6bb2fa44bd36 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 30 Apr 2025 15:55:27 +0200 Subject: [PATCH 04/12] Update PHPUnit config --- phpunit.xml.dist | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0522c8566..e837cd589 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,17 +1,26 @@ - - - - tests - - - \ No newline at end of file + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/4.8/phpunit.xsd" + bootstrap="vendor/autoload.php" + backupGlobals="false" + beStrictAboutCoversAnnotation="true" + beStrictAboutOutputDuringTests="true" + beStrictAboutTestsThatDoNotTestAnything="true" + beStrictAboutTodoAnnotatedTests="true" + convertErrorsToExceptions="true" + convertWarningsToExceptions="true" + convertNoticesToExceptions="true" + convertDeprecationsToExceptions="true" + colors="true" + verbose="true"> + + + tests + + + + + + src + + + From 6d50f4dbd3ffffe656924ccbc9bffa7768ce0d69 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 30 Apr 2025 16:14:20 +0200 Subject: [PATCH 05/12] Cache zipball URLs as well --- src/WP_CLI/CommandWithUpgrade.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/WP_CLI/CommandWithUpgrade.php b/src/WP_CLI/CommandWithUpgrade.php index 124630f68..bd2a6d08d 100755 --- a/src/WP_CLI/CommandWithUpgrade.php +++ b/src/WP_CLI/CommandWithUpgrade.php @@ -227,7 +227,7 @@ public function install( $args, $assoc_args ) { add_filter( 'upgrader_source_selection', $filter, 10 ); } - // Check if the URL the URL is cachable and whitelist it then. + // Add item to cache allowlist if it matches certain URL patterns. self::maybe_cache( $slug, $this->item_type ); if ( $file_upgrader->install( $slug ) ) { @@ -845,11 +845,11 @@ private function parse_url_host_component( $url, $component ) { } /** - * Whitelist GitHub URLs for caching. + * Add versioned GitHub URLs to cache allowlist. * * @param string $url The URL to check. */ - public static function maybe_cache( $url, $item_type ) { + protected static function maybe_cache( $url, $item_type ) { $matches = []; // cache release URLs like `https://github.com/wp-cli-test/generic-example-plugin/releases/download/v0.1.0/generic-example-plugin.0.1.0.zip` @@ -858,6 +858,8 @@ public static function maybe_cache( $url, $item_type ) { // cache archive URLs like `https://github.com/wp-cli-test/generic-example-plugin/archive/v0.1.0.zip` } elseif ( preg_match( '#github\.com/[^/]+/([^/]+)/archive/(version/|)([^/]+)\.zip#', $url, $matches ) ) { WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[3] ); + } elseif ( preg_match( '#api\.github\.com/repos/[^/]+/([^/]+)/zipball/([^/]+)#', $url, $matches ) ) { + WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[2] ); } } From 51482846ed93862a7ec60aa3e0daf1350756bfed Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 30 Apr 2025 16:51:17 +0200 Subject: [PATCH 06/12] Handle 404 from GitHub API --- src/WP_CLI/CommandWithUpgrade.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/WP_CLI/CommandWithUpgrade.php b/src/WP_CLI/CommandWithUpgrade.php index bd2a6d08d..c77cbe932 100755 --- a/src/WP_CLI/CommandWithUpgrade.php +++ b/src/WP_CLI/CommandWithUpgrade.php @@ -893,6 +893,13 @@ protected function get_the_latest_github_version( $repo_slug ) { ); } + if ( 404 === wp_remote_retrieve_response_code( $response ) ) { + return new \WP_Error( + $decoded_body->status, + $decoded_body->message + ); + } + if ( null === $decoded_body ) { return new \WP_Error( 500, 'Empty response received from GitHub.com API' ); } From 23779dee10a4144b9db3840e81d493eaa1dcda52 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 30 Apr 2025 18:00:59 +0200 Subject: [PATCH 07/12] Revert phpunit additions --- .gitignore | 3 --- phpunit.xml.dist | 26 -------------------------- tests/PluginCommandTest.php | 11 ----------- 3 files changed, 40 deletions(-) delete mode 100644 phpunit.xml.dist delete mode 100644 tests/PluginCommandTest.php diff --git a/.gitignore b/.gitignore index fa48b47db..bcf211b32 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,3 @@ composer.lock phpunit.xml phpcs.xml .phpcs.xml -.phpunit.result.cache -.phpunit.cache -build/logs diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index e837cd589..000000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,26 +0,0 @@ - - - - tests - - - - - - src - - - diff --git a/tests/PluginCommandTest.php b/tests/PluginCommandTest.php deleted file mode 100644 index 46ca78a49..000000000 --- a/tests/PluginCommandTest.php +++ /dev/null @@ -1,11 +0,0 @@ -assertTrue( true ); - } -} From da9ee193f3a7d75b4064bc2a49a4ff2bb9ec83dc Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 30 Apr 2025 18:50:30 +0200 Subject: [PATCH 08/12] Update regexes, add Behat tests --- features/upgradables.feature | 24 ++++++++++++++++++++++++ src/WP_CLI/CommandWithUpgrade.php | 9 +++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index 297781ec4..a8b8b7440 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -212,3 +212,27 @@ Feature: Manage WordPress themes and plugins | type | type_name | item | item_title | version | zip_file | file_to_check | | theme | Theme | moina | Moina | 1.1.2 | https://wordpress.org/themes/download/moina.1.1.2.zip | {CONTENT_DIR}/moina/style.css | | plugin | Plugin | category-checklist-tree | Category Checklist Tree | 1.2 | https://downloads.wordpress.org/plugin/category-checklist-tree.1.2.zip | {CONTENT_DIR}/category-checklist-tree/category-checklist-tree.php | + + @require-wp-4.5 + Scenario Outline: Caches certain GitHub URLs + Given a WP install + And I run `wp plugin delete --all` + + When I run `wp plugin install ` + Then STDOUT should contain: + """ + Plugin installed successfully + """ + + When I run `wp plugin delete --all` + And I run `wp plugin install ` + Then STDOUT should contain: + """ + Using cached file '{SUITE_CACHE_DIR}/plugin/- + """ + + Examples: + | item | version | zip_file | + | one-time-login | 0.4.0 | https://github.com/danielbachhuber/one-time-login/releases/latest | + | preferred-languages | 2.4.0 | https://github.com/swissspidy/preferred-languages/releases/download/2.4.0/preferred-languages.zip | + | generic-example-plugin | 0.1.1 | https://github.com/wp-cli-test/generic-example-plugin/archive/v0.1.1.zip | diff --git a/src/WP_CLI/CommandWithUpgrade.php b/src/WP_CLI/CommandWithUpgrade.php index c77cbe932..f600c328d 100755 --- a/src/WP_CLI/CommandWithUpgrade.php +++ b/src/WP_CLI/CommandWithUpgrade.php @@ -853,12 +853,13 @@ protected static function maybe_cache( $url, $item_type ) { $matches = []; // cache release URLs like `https://github.com/wp-cli-test/generic-example-plugin/releases/download/v0.1.0/generic-example-plugin.0.1.0.zip` - if ( preg_match( '#github\.com/[^/]+/([^/]+)/releases/download/tags/([^/]+)/(.+)\.zip#', $url, $matches ) ) { - WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[2], $matches[3] ); + if ( preg_match( '#github\.com/[^/]+/([^/]+)/releases/download/v?([^/]+)/.+\.zip#', $url, $matches ) ) { + WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[2] ); // cache archive URLs like `https://github.com/wp-cli-test/generic-example-plugin/archive/v0.1.0.zip` - } elseif ( preg_match( '#github\.com/[^/]+/([^/]+)/archive/(version/|)([^/]+)\.zip#', $url, $matches ) ) { + } elseif ( preg_match( '#github\.com/[^/]+/([^/]+)/archive/(version/|)v?([^/]+)\.zip#', $url, $matches ) ) { WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[3] ); - } elseif ( preg_match( '#api\.github\.com/repos/[^/]+/([^/]+)/zipball/([^/]+)#', $url, $matches ) ) { + // cache release URLs like `https://api.github.com/repos/danielbachhuber/one-time-login/zipball/v0.4.0` + } elseif ( preg_match( '#api\.github\.com/repos/[^/]+/([^/]+)/zipball/v?([^/]+)#', $url, $matches ) ) { WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[2] ); } } From 925e4cfc1890fe8dbef7d746929f709dfffb02df Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 30 Apr 2025 19:10:59 +0200 Subject: [PATCH 09/12] Fix formatting --- src/WP_CLI/CommandWithUpgrade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WP_CLI/CommandWithUpgrade.php b/src/WP_CLI/CommandWithUpgrade.php index f600c328d..5c03ae847 100755 --- a/src/WP_CLI/CommandWithUpgrade.php +++ b/src/WP_CLI/CommandWithUpgrade.php @@ -855,10 +855,10 @@ protected static function maybe_cache( $url, $item_type ) { // cache release URLs like `https://github.com/wp-cli-test/generic-example-plugin/releases/download/v0.1.0/generic-example-plugin.0.1.0.zip` if ( preg_match( '#github\.com/[^/]+/([^/]+)/releases/download/v?([^/]+)/.+\.zip#', $url, $matches ) ) { WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[2] ); - // cache archive URLs like `https://github.com/wp-cli-test/generic-example-plugin/archive/v0.1.0.zip` + // cache archive URLs like `https://github.com/wp-cli-test/generic-example-plugin/archive/v0.1.0.zip` } elseif ( preg_match( '#github\.com/[^/]+/([^/]+)/archive/(version/|)v?([^/]+)\.zip#', $url, $matches ) ) { WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[3] ); - // cache release URLs like `https://api.github.com/repos/danielbachhuber/one-time-login/zipball/v0.4.0` + // cache release URLs like `https://api.github.com/repos/danielbachhuber/one-time-login/zipball/v0.4.0` } elseif ( preg_match( '#api\.github\.com/repos/[^/]+/([^/]+)/zipball/v?([^/]+)#', $url, $matches ) ) { WP_CLI::get_http_cache_manager()->whitelist_package( $url, $item_type, $matches[1], $matches[2] ); } From 429515b614f5622bb1ffa92b415e2a3284f22b9a Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 30 Apr 2025 21:45:31 +0200 Subject: [PATCH 10/12] Force empty cache --- features/plugin-install.feature | 3 +++ 1 file changed, 3 insertions(+) diff --git a/features/plugin-install.feature b/features/plugin-install.feature index 48941dc37..f8b61ed5a 100644 --- a/features/plugin-install.feature +++ b/features/plugin-install.feature @@ -1,5 +1,8 @@ Feature: Install WordPress plugins + Background: + Given an empty cache + Scenario: Branch names should be removed from Github projects Given a WP install From 19d26ccf13d3ccd5814747cb3214d0c90f4185c1 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Wed, 30 Apr 2025 22:49:23 +0200 Subject: [PATCH 11/12] Use different plugin version --- features/upgradables.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/upgradables.feature b/features/upgradables.feature index a8b8b7440..516e82e4b 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -234,5 +234,5 @@ Feature: Manage WordPress themes and plugins Examples: | item | version | zip_file | | one-time-login | 0.4.0 | https://github.com/danielbachhuber/one-time-login/releases/latest | - | preferred-languages | 2.4.0 | https://github.com/swissspidy/preferred-languages/releases/download/2.4.0/preferred-languages.zip | + | preferred-languages | 1.8.0 | https://github.com/swissspidy/preferred-languages/releases/download/1.8.0/preferred-languages.zip | | generic-example-plugin | 0.1.1 | https://github.com/wp-cli-test/generic-example-plugin/archive/v0.1.1.zip | From d27b3b5b93f66a17fbc66b43eb9c5044fa2dd925 Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Mon, 5 May 2025 21:03:20 +0200 Subject: [PATCH 12/12] Improve tests to ensure caching works as expected --- features/upgradables.feature | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/features/upgradables.feature b/features/upgradables.feature index 516e82e4b..278f12750 100644 --- a/features/upgradables.feature +++ b/features/upgradables.feature @@ -223,10 +223,18 @@ Feature: Manage WordPress themes and plugins """ Plugin installed successfully """ + And STDOUT should not contain: + """ + Using cached file '{SUITE_CACHE_DIR}/plugin/- + """ When I run `wp plugin delete --all` And I run `wp plugin install ` Then STDOUT should contain: + """ + Plugin installed successfully + """ + And STDOUT should contain: """ Using cached file '{SUITE_CACHE_DIR}/plugin/- """