diff --git a/src/Form/UpdaterForm.php b/src/Form/UpdaterForm.php index e9430027b7e00490e994034caa38688809a73cf1..1c27cdf6b1e3b86e1eb57f3681abdc3bd611d4dc 100644 --- a/src/Form/UpdaterForm.php +++ b/src/Form/UpdaterForm.php @@ -248,14 +248,29 @@ final class UpdaterForm extends FormBase { // only that there is newer version available. $is_primary = !$installed_minor_release && !($project['status'] === UpdateManagerInterface::CURRENT || $project['status'] === UpdateManagerInterface::NOT_CURRENT); $next_minor_version = ExtensionVersion::createFromVersionString($next_minor_release->getVersion()); - // @todo Add documentation to explain what is different about a minor - // update in https://www.drupal.org/i/3291730. + + // Since updating to another minor version of Drupal is more disruptive + // than updating within the currently installed minor version, ensure we + // display a link to the release notes for the first (x.y.0) release of + // the next minor version, which will inform site owners of any potential + // pitfalls or major changes. We should always be able to get release info + // for it; if we can't, that's an error condition. + $first_release_version = $next_minor_version->getMajorVersion() . '.' . $next_minor_version->getMinorVersion() . '.0'; + $available_updates = update_get_available(TRUE); + if (isset($available_updates['drupal']['releases'][$first_release_version])) { + $next_minor_first_release = ProjectRelease::createFromArray($available_updates['drupal']['releases'][$first_release_version]); + } + else { + throw new \LogicException("Release information for Drupal $first_release_version is not available."); + } + $form['next_minor'] = $this->createReleaseTable( $next_minor_release, $installed_minor_release ? $this->t('Minor update') : $release_status, - $this->t('Latest version of Drupal @major.@minor (next minor):', [ + $this->t('Latest version of Drupal @major.@minor (next minor) (<a href=":url">Release notes</a>):', [ '@major' => $next_minor_version->getMajorVersion(), '@minor' => $next_minor_version->getMinorVersion(), + ':url' => $next_minor_first_release->getReleaseUrl(), ]), $installed_minor_release ? 'update-optional' : $type, $create_update_buttons, diff --git a/tests/src/Functional/UpdaterFormTest.php b/tests/src/Functional/UpdaterFormTest.php index 7d5f4e610bb07e219cfa98e7c60b2e70aa30b820..3a96b95756139732d0627cd2bcec1879840d7d7f 100644 --- a/tests/src/Functional/UpdaterFormTest.php +++ b/tests/src/Functional/UpdaterFormTest.php @@ -152,7 +152,8 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { $this->setCoreVersion('9.7.0'); $page->clickLink('Check manually'); $this->checkForMetaRefresh(); - $this->checkReleaseTable('#edit-next-minor', '.update-update-recommended', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (next minor):'); + $this->checkReleaseTable('#edit-next-minor', '.update-update-recommended', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (next minor) (Release notes):'); + $this->assertReleaseNotesLink(9, 8); $assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Not supported!)'); $assert_session->elementNotExists('css', '#edit-installed-minor'); @@ -171,14 +172,16 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { $this->config('automatic_updates.settings')->set('allow_core_minor_updates', TRUE)->save(); $this->getSession()->reload(); $this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.7.1', TRUE, 'Latest version of Drupal 9.7 (currently installed):'); - $this->checkReleaseTable('#edit-next-minor', '.update-update-optional', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor):'); + $this->checkReleaseTable('#edit-next-minor', '.update-update-optional', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor) (Release notes):'); + $this->assertReleaseNotesLink(9, 8); $this->setCoreVersion('9.7.1'); $page->clickLink('Check manually'); $this->checkForMetaRefresh(); $assert_session->pageTextContainsOnce('Currently installed: 9.7.1 (Update available)'); $assert_session->elementNotExists('css', '#edit-installed-minor'); - $this->checkReleaseTable('#edit-next-minor', '.update-update-recommended', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor):'); + $this->checkReleaseTable('#edit-next-minor', '.update-update-recommended', '9.8.2', FALSE, 'Latest version of Drupal 9.8 (next minor) (Release notes):'); + $this->assertReleaseNotesLink(9, 8); $this->assertUpdateStagedTimes(0); } @@ -695,4 +698,19 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { $this->assertSession()->elementNotExists('css', "input[value*='Update']"); } + /** + * Asserts that the release notes link for a given minor version is correct. + * + * @param int $major + * Major version of next minor release. + * @param int $minor + * Minor version of next minor release. + */ + private function assertReleaseNotesLink(int $major, int $minor): void { + $assert_session = $this->assertSession(); + $row = $assert_session->elementExists('css', '#edit-next-minor'); + $link_href = $assert_session->elementExists('named', ['link', 'Release notes'], $row)->getAttribute('href'); + $this->assertSame('http://example.com/drupal-' . $major . '-' . $minor . '-0-release', $link_href); + } + }