Skip to content

Cache certain GitHub URLs #385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 5, 2025
3 changes: 3 additions & 0 deletions features/plugin-install.feature
Original file line number Diff line number Diff line change
@@ -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

32 changes: 32 additions & 0 deletions features/upgradables.feature
Original file line number Diff line number Diff line change
@@ -212,3 +212,35 @@ 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 <zip_file>`
Then STDOUT should contain:
"""
Plugin installed successfully
"""
And STDOUT should not contain:
"""
Using cached file '{SUITE_CACHE_DIR}/plugin/<item>-<version>
"""

When I run `wp plugin delete --all`
And I run `wp plugin install <zip_file>`
Then STDOUT should contain:
"""
Plugin installed successfully
"""
And STDOUT should contain:
"""
Using cached file '{SUITE_CACHE_DIR}/plugin/<item>-<version>
"""

Examples:
| item | version | zip_file |
| one-time-login | 0.4.0 | https://github.com/danielbachhuber/one-time-login/releases/latest |
| 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 |
30 changes: 30 additions & 0 deletions src/WP_CLI/CommandWithUpgrade.php
Original file line number Diff line number Diff line change
@@ -227,6 +227,9 @@
add_filter( 'upgrader_source_selection', $filter, 10 );
}

// Add item to cache allowlist if it matches certain URL patterns.
self::maybe_cache( $slug, $this->item_type );

if ( $file_upgrader->install( $slug ) ) {
$slug = $file_upgrader->result['destination_name'];
$result = true;
@@ -841,6 +844,26 @@
return function_exists( 'wp_parse_url' ) ? wp_parse_url( $url, $component ) : parse_url( $url, $component );
}

/**
* Add versioned GitHub URLs to cache allowlist.
*
* @param string $url The URL to check.
*/
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/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/|)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`
} 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] );
}
}

/**
* Get the latest package version based on a given repo slug.
*
@@ -871,6 +894,13 @@
);
}

if ( 404 === wp_remote_retrieve_response_code( $response ) ) {
return new \WP_Error(
$decoded_body->status,
$decoded_body->message
);

Check warning on line 901 in src/WP_CLI/CommandWithUpgrade.php

Codecov / codecov/patch

src/WP_CLI/CommandWithUpgrade.php#L898-L901

Added lines #L898 - L901 were not covered by tests
}

if ( null === $decoded_body ) {
return new \WP_Error( 500, 'Empty response received from GitHub.com API' );
}