Skip to content
Snippets Groups Projects
Commit 6c5f1e62 authored by Adam G-H's avatar Adam G-H
Browse files

Issue #3314143 by phenaproxima: Add documentation for testing minor updates

parent 4a71ccf6
No related branches found
No related tags found
No related merge requests found
...@@ -29,12 +29,20 @@ function automatic_updates_help($route_name, RouteMatchInterface $route_match) { ...@@ -29,12 +29,20 @@ function automatic_updates_help($route_name, RouteMatchInterface $route_match) {
$output .= '<p>' . t('Additionally, Automatic Updates periodically runs checks to ensure that updates can be installed, and will warn site administrators if problems are detected.') . '</p>'; $output .= '<p>' . t('Additionally, Automatic Updates periodically runs checks to ensure that updates can be installed, and will warn site administrators if problems are detected.') . '</p>';
$output .= '<h3>' . t('Requirements') . '</h3>'; $output .= '<h3>' . t('Requirements') . '</h3>';
$output .= '<p>' . t('Automatic Updates requires a Composer executable whose version satisfies <code>@version</code>, and PHP must have permission to run it. The path to the executable may be set in the <code>package_manager.settings:executables.composer</code> config setting, or it will be automatically detected.', ['@version' => ComposerExecutableValidator::MINIMUM_COMPOSER_VERSION_CONSTRAINT]) . '</p>'; $output .= '<p>' . t('Automatic Updates requires a Composer executable whose version satisfies <code>@version</code>, and PHP must have permission to run it. The path to the executable may be set in the <code>package_manager.settings:executables.composer</code> config setting, or it will be automatically detected.', ['@version' => ComposerExecutableValidator::MINIMUM_COMPOSER_VERSION_CONSTRAINT]) . '</p>';
$output .= '<p>' . t('For more information, see the <a href=":automatic-updates-documentation">online documentation for the Automatic Updates module</a>.', [':automatic-updates-documentation' => 'https://www.drupal.org/docs/8/update/automatic-updates']) . '</p>';
$output .= '<p id="cron-alternate-port">' . t('If your site is running on the built-in PHP web server, unattended (i.e., cron) updates may not work without one of the following workarounds:') . '</p>'; $output .= '<p id="cron-alternate-port">' . t('If your site is running on the built-in PHP web server, unattended (i.e., cron) updates may not work without one of the following workarounds:') . '</p>';
$output .= '<ul>'; $output .= '<ul>';
$output .= '<li>' . t('Use a multithreaded web server, such as Apache, NGINX, or on Windows, IIS.') . '</li>'; $output .= '<li>' . t('Use a multithreaded web server, such as Apache, NGINX, or on Windows, IIS.') . '</li>';
$output .= '<li>' . t('Run another instance of the built-in PHP web server on a different port and configure automatic updates accordingly: <code>$config["automatic_updates.settings"]["cron_port"] = $alternate_port_number;</code>') . '</li>'; $output .= '<li>' . t('Run another instance of the built-in PHP web server on a different port and configure automatic updates accordingly: <code>$config["automatic_updates.settings"]["cron_port"] = $alternate_port_number;</code>') . '</li>';
$output .= '</ul>'; $output .= '</ul>';
$output .= '<p>' . t('For more information, see the <a href=":automatic-updates-documentation">online documentation for the Automatic Updates module</a>.', [':automatic-updates-documentation' => 'https://www.drupal.org/docs/8/update/automatic-updates']) . '</p>';
$output .= '<h3 id="minor-update">' . t('Updating to another minor version of Drupal') . '</h3>';
$output .= '<p>';
$output .= t('Automatic Updates supports updating from one minor version of Drupal core to another; for example, from Drupal 9.4.8 to Drupal 9.5.0. This is only allowed when updating via <a href=":url">the user interface</a>. Unattended background updates can only update <em>within</em> the currently installed minor version (for example, Drupal 9.4.6 to 9.4.8).', [
':url' => Url::fromRoute('update.report_update')->toString(),
]);
$output .= '</p>';
$output .= '<p>' . t('This is because updating from one minor version of Drupal to another is riskier than staying within the current minor version. New minor versions of Drupal introduce changes that can, in some situations, be incompatible with installed modules and themes.') . '</p>';
$output .= '<p>' . t('Therefore, if you want to use Automatic Updates to update to another minor version of Drupal, it is strongly recommended to do a test update first, ideally on an isolated development copy of your site, before updating your production site.') . '</p>';
return $output; return $output;
} }
} }
......
...@@ -4,6 +4,7 @@ namespace Drupal\automatic_updates\Form; ...@@ -4,6 +4,7 @@ namespace Drupal\automatic_updates\Form;
use Drupal\automatic_updates\BatchProcessor; use Drupal\automatic_updates\BatchProcessor;
use Drupal\automatic_updates\Event\ReadinessCheckEvent; use Drupal\automatic_updates\Event\ReadinessCheckEvent;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\package_manager\FailureMarker; use Drupal\package_manager\FailureMarker;
use Drupal\package_manager\ProjectInfo; use Drupal\package_manager\ProjectInfo;
use Drupal\automatic_updates\ReleaseChooser; use Drupal\automatic_updates\ReleaseChooser;
...@@ -82,6 +83,13 @@ final class UpdaterForm extends FormBase { ...@@ -82,6 +83,13 @@ final class UpdaterForm extends FormBase {
*/ */
protected $failureMarker; protected $failureMarker;
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/** /**
* Constructs a new UpdaterForm object. * Constructs a new UpdaterForm object.
* *
...@@ -97,14 +105,17 @@ final class UpdaterForm extends FormBase { ...@@ -97,14 +105,17 @@ final class UpdaterForm extends FormBase {
* The renderer service. * The renderer service.
* @param \Drupal\package_manager\FailureMarker $failure_marker * @param \Drupal\package_manager\FailureMarker $failure_marker
* The failure marker service. * The failure marker service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
*/ */
public function __construct(StateInterface $state, Updater $updater, EventDispatcherInterface $event_dispatcher, ReleaseChooser $release_chooser, RendererInterface $renderer, FailureMarker $failure_marker) { public function __construct(StateInterface $state, Updater $updater, EventDispatcherInterface $event_dispatcher, ReleaseChooser $release_chooser, RendererInterface $renderer, FailureMarker $failure_marker, ModuleHandlerInterface $module_handler) {
$this->updater = $updater; $this->updater = $updater;
$this->state = $state; $this->state = $state;
$this->eventDispatcher = $event_dispatcher; $this->eventDispatcher = $event_dispatcher;
$this->releaseChooser = $release_chooser; $this->releaseChooser = $release_chooser;
$this->renderer = $renderer; $this->renderer = $renderer;
$this->failureMarker = $failure_marker; $this->failureMarker = $failure_marker;
$this->moduleHandler = $module_handler;
} }
/** /**
...@@ -124,7 +135,8 @@ final class UpdaterForm extends FormBase { ...@@ -124,7 +135,8 @@ final class UpdaterForm extends FormBase {
$container->get('event_dispatcher'), $container->get('event_dispatcher'),
$container->get('automatic_updates.release_chooser'), $container->get('automatic_updates.release_chooser'),
$container->get('renderer'), $container->get('renderer'),
$container->get('package_manager.failure_marker') $container->get('package_manager.failure_marker'),
$container->get('module_handler')
); );
} }
...@@ -284,6 +296,22 @@ final class UpdaterForm extends FormBase { ...@@ -284,6 +296,22 @@ final class UpdaterForm extends FormBase {
throw new \LogicException("Release information for Drupal $first_release_version is not available."); throw new \LogicException("Release information for Drupal $first_release_version is not available.");
} }
if ($this->moduleHandler->moduleExists('help')) {
$url = Url::fromRoute('help.page')
->setRouteParameter('name', 'automatic_updates')
->setOption('fragment', 'minor-update');
// @todo Updating this wording in https://www.drupal.org/i/3280403 to
// reflect that multiple minor branches may be visible.
$form['minor_update_help'] = [
'#markup' => $this->t('The following updates are in the next minor version of Drupal. <a href=":url">Learn more about updating to another minor version.</a>', [
':url' => $url->toString(),
]),
'#prefix' => '<p>',
'#suffix' => '</p>',
];
}
$form['next_minor'] = $this->createReleaseTable( $form['next_minor'] = $this->createReleaseTable(
$next_minor_release, $next_minor_release,
$installed_minor_release ? $this->t('Minor update') : $release_status, $installed_minor_release ? $this->t('Minor update') : $release_status,
......
...@@ -41,6 +41,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -41,6 +41,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
'block', 'block',
'automatic_updates', 'automatic_updates',
'automatic_updates_test', 'automatic_updates_test',
'help',
]; ];
/** /**
...@@ -127,9 +128,18 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -127,9 +128,18 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
* @dataProvider providerTableLooksCorrect * @dataProvider providerTableLooksCorrect
*/ */
public function testTableLooksCorrect(string $access_page): void { public function testTableLooksCorrect(string $access_page): void {
$assert_session = $this->assertSession();
$assert_minor_update_help = function () use ($assert_session): void {
$assert_session->pageTextContains('The following updates are in the next minor version of Drupal. Learn more about updating to another minor version.');
$assert_session->linkExists('Learn more about updating to another minor version.');
};
$assert_no_minor_update_help = function () use ($assert_session): void {
$assert_session->pageTextNotContains('The following updates are in the next minor version of Drupal. Learn more about updating to another minor version.');
};
$page = $this->getSession()->getPage(); $page = $this->getSession()->getPage();
$this->drupalPlaceBlock('local_tasks_block', ['primary' => TRUE]); $this->drupalPlaceBlock('local_tasks_block', ['primary' => TRUE]);
$assert_session = $this->assertSession();
$this->setCoreVersion('9.8.0'); $this->setCoreVersion('9.8.0');
$this->checkForUpdates(); $this->checkForUpdates();
...@@ -146,17 +156,19 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -146,17 +156,19 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
} }
$this->clickLink('Update'); $this->clickLink('Update');
// Check the form when there is an updates in the next minor only. // Check the form when there is an update in the installed minor only.
$assert_session->pageTextContainsOnce('Currently installed: 9.8.0 (Security update required!)'); $assert_session->pageTextContainsOnce('Currently installed: 9.8.0 (Security update required!)');
$this->checkReleaseTable('#edit-installed-minor', '.update-update-security', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (currently installed):'); $this->checkReleaseTable('#edit-installed-minor', '.update-update-security', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (currently installed):');
$assert_session->elementNotExists('css', '#edit-next-minor'); $assert_session->elementNotExists('css', '#edit-next-minor');
$assert_no_minor_update_help();
// Check the form when there is an updates in the next minor only. // Check the form when there is an update in the next minor only.
$this->config('automatic_updates.settings')->set('allow_core_minor_updates', TRUE)->save(); $this->config('automatic_updates.settings')->set('allow_core_minor_updates', TRUE)->save();
$this->setCoreVersion('9.7.0'); $this->setCoreVersion('9.7.0');
$page->clickLink('Check manually'); $page->clickLink('Check manually');
$this->checkForMetaRefresh(); $this->checkForMetaRefresh();
$this->checkReleaseTable('#edit-next-minor', '.update-update-recommended', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (next minor) (Release notes):'); $this->checkReleaseTable('#edit-next-minor', '.update-update-recommended', '9.8.1', TRUE, 'Latest version of Drupal 9.8 (next minor) (Release notes):');
$assert_minor_update_help();
$this->assertReleaseNotesLink(9, 8); $this->assertReleaseNotesLink(9, 8);
$assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Not supported!)'); $assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Not supported!)');
$assert_session->elementNotExists('css', '#edit-installed-minor'); $assert_session->elementNotExists('css', '#edit-installed-minor');
...@@ -170,6 +182,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -170,6 +182,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Update available)'); $assert_session->pageTextContainsOnce('Currently installed: 9.7.0 (Update available)');
$this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.7.1', TRUE, 'Latest version of Drupal 9.7 (currently installed):'); $this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.7.1', TRUE, 'Latest version of Drupal 9.7 (currently installed):');
$assert_session->elementNotExists('css', '#edit-next-minor'); $assert_session->elementNotExists('css', '#edit-next-minor');
$assert_no_minor_update_help();
// Check that if minor updates are enabled the update in the next minor will // Check that if minor updates are enabled the update in the next minor will
// be visible. // be visible.
...@@ -178,6 +191,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -178,6 +191,7 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->checkReleaseTable('#edit-installed-minor', '.update-update-recommended', '9.7.1', TRUE, 'Latest version of Drupal 9.7 (currently installed):'); $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) (Release notes):'); $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->assertReleaseNotesLink(9, 8);
$assert_minor_update_help();
$this->setCoreVersion('9.7.1'); $this->setCoreVersion('9.7.1');
$page->clickLink('Check manually'); $page->clickLink('Check manually');
...@@ -186,8 +200,18 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -186,8 +200,18 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$assert_session->elementNotExists('css', '#edit-installed-minor'); $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) (Release notes):'); $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->assertReleaseNotesLink(9, 8);
$assert_minor_update_help();
$this->assertUpdateStagedTimes(0); $this->assertUpdateStagedTimes(0);
// If the minor update help link exists, ensure it links to the right place.
$help_link = $page->findLink('Learn more about updating to another minor version.');
if ($help_link) {
$this->assertStringEndsWith('#minor-update', $help_link->getAttribute('href'));
$help_link->click();
$assert_session->statusCodeEquals(200);
$assert_session->responseContains('id="minor-update"');
}
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment