From 9d91b4de192e42a938db819660d5c47e59913549 Mon Sep 17 00:00:00 2001 From: Sarah Mount Date: Mon, 8 Jan 2024 07:55:09 +0000 Subject: [PATCH] WordPress Core versions check semver constraints In repos we have a config file that determines the version of WordPress Core that needs to be deployed to a live site. This can be a full semver version (e.g. 1.2.3) or a "version" that is actually a moveable tag related to a major release (e.g. v6). Previously, we did not check for this edge case, which means that in some cases, we did not return a full semver version and this caused a bug in updating language packs whereby old language packs would be written into repos and lockfiles. Now, we remove any leading 'v' characters and return a fully qualified semver version (e.g. 1.2.3). We make an assumption that the list of available core versions (e.g. https://api.wordpress.org/translations/core/1.0/?version=6) is ordered by most recent release first. --- src/Dependencies/Updater.php | 17 ++-------- src/Modules/Helpers/WhippetHelpers.php | 44 +++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/Dependencies/Updater.php b/src/Dependencies/Updater.php index 64c6854..36333d5 100644 --- a/src/Dependencies/Updater.php +++ b/src/Dependencies/Updater.php @@ -277,19 +277,6 @@ private function fetchDefault(string $src): \Result\Result return $this->fetchRef($src, 'master'); } - /** - * Version strings passed to WordPress APIs must not start with a v. - * - * So, v6.3.1 becomes 6.3.1. - */ - private function getCanonicalVersion($version) - { - if(str_starts_with($version, 'v')) { - return substr($version, 1); - } - return $version; - } - /** * Add a language pack to a lockfile, including translations for themes and plugins. * @@ -301,7 +288,7 @@ private function getCanonicalVersion($version) */ private function addLanguageToLockfile(array $dep) { - $wpCoreVersion = $this->getCanonicalVersion($this->get_wordpress_core_version()); + $wpCoreVersion = $this->get_bare_version_number($this->get_wordpress_core_version()); $result = TranslationsApi::fetchLanguageSrcAndRevision(DependencyTypes::LANGUAGES, $dep['name'], $wpCoreVersion, null); if ($result->isErr()) { return $result; @@ -317,7 +304,7 @@ private function addLanguageToLockfile(array $dep) if(substr($version, 0, 18) === 'No tags for commit') { continue; } else { - $version = $this->getCanonicalVersion($version); + $version = $this->get_bare_version_number($version); } $result = TranslationsApi::fetchLanguageSrcAndRevision($type, $dep['name'], $version, $name); if ($result->isErr()) { diff --git a/src/Modules/Helpers/WhippetHelpers.php b/src/Modules/Helpers/WhippetHelpers.php index 88c4ab1..be32b64 100644 --- a/src/Modules/Helpers/WhippetHelpers.php +++ b/src/Modules/Helpers/WhippetHelpers.php @@ -72,14 +72,56 @@ public function load_application_config() } } + /** + * Version strings passed to WordPress APIs must not start with a v. + * + * So, v6.3.1 becomes 6.3.1. + */ + public function get_bare_version_number($version) + { + if(substr($version, 0, 1) === 'v') { + return substr($version, 1); + } + return $version; + } + + /** Given a version in config/application.json, return a valid WP Core version. + * + * Note that version numbers in repos can be of the following forms: + * + * v6 + * 6.3.2 + * 6.3 + * 6 + * + * and should be translated into a full semver version, e.g. 6.3.2. + */ public function get_wordpress_core_version() { $config_version = $this->application_config->wordpress->revision; + if (substr_count($config_version, '.') === 2) { + return $config_version; + } if ($config_version == 'master') { $latest_core_version = json_decode(file_get_contents('https://api.wordpress.org/core/version-check/1.7/'), JSON_OBJECT_AS_ARRAY); return $latest_core_version['offers'][0]['version']; } - return $config_version; + // Version does not include a patch version, so we need to find the + // fully qualified version humber from the JSON. We assume that the + // JSON data is ordered by most recent release first. + $latest_core_version = json_decode(file_get_contents('https://api.wordpress.org/core/version-check/1.7/'), JSON_OBJECT_AS_ARRAY); + $i = 0; + $canonical_version = $this->get_bare_version_number($config_version); + $ver_len = strlen($canonical_version); + while ($i < count($latest_core_version['offers'])) { + print_r("counter: {$i} canonical version: {$canonical_version}\n"); + if (substr($latest_core_version['offers'][$i]['version'], 0, $ver_len) === $canonical_version) { + print_r("VERSION: {$latest_core_version['offers'][$i]['version']}\n"); + return $latest_core_version['offers'][$i]['version']; + } + $i++; + } + throw new \Exception("WordPress core version not valid or no longer available: {$config_version}"); } public function find_file($file, $include_dir = false)