diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml index f0efbee5f350165bdff7c006d51aa9519ccf9077..bf3916ff1c695af8161303b01d7e4a23f952e388 100644 --- a/automatic_updates.services.yml +++ b/automatic_updates.services.yml @@ -133,6 +133,10 @@ services: class: Drupal\automatic_updates\Validator\XdebugValidator tags: - { name: event_subscriber } + automatic_updates.validator.installed_version: + class: Drupal\automatic_updates\Validator\InstalledVersionValidator + tags: + - { name: event_subscriber } automatic_updates.validator.target_release: class: Drupal\automatic_updates\Validator\UpdateReleaseValidator tags: diff --git a/src/Validator/InstalledVersionValidator.php b/src/Validator/InstalledVersionValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..abb30dc61260d6f255e73bd162cdbd87fca4f6e5 --- /dev/null +++ b/src/Validator/InstalledVersionValidator.php @@ -0,0 +1,55 @@ +<?php + +namespace Drupal\automatic_updates\Validator; + +use Drupal\automatic_updates\Event\ReadinessCheckEvent; +use Drupal\automatic_updates\ProjectInfo; +use Drupal\automatic_updates\Updater; +use Drupal\Core\Extension\ExtensionVersion; +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\package_manager\Event\PreCreateEvent; +use Drupal\package_manager\Event\PreOperationStageEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Validates that the site can update from the installed version of Drupal. + */ +class InstalledVersionValidator implements EventSubscriberInterface { + + use StringTranslationTrait; + + /** + * Checks that the site can update from the installed version of Drupal. + * + * @param \Drupal\package_manager\Event\PreOperationStageEvent $event + * The event object. + */ + public function checkInstalledVersion(PreOperationStageEvent $event): void { + // This check only works with Automatic Updates. + if (!$event->getStage() instanceof Updater) { + return; + } + + $installed_version = (new ProjectInfo('drupal'))->getInstalledVersion(); + $extra = ExtensionVersion::createFromVersionString($installed_version) + ->getVersionExtra(); + + if ($extra === 'dev') { + $message = $this->t('Drupal cannot be automatically updated from the installed version, @installed_version, because automatic updates from a dev version to any other version are not supported.', [ + '@installed_version' => $installed_version, + ]); + $event->addError([$message]); + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + return [ + ReadinessCheckEvent::class => 'checkInstalledVersion', + PreCreateEvent::class => 'checkInstalledVersion', + ]; + } + +} diff --git a/src/Validator/UpdateVersionValidator.php b/src/Validator/UpdateVersionValidator.php index b4e090f4444bf80ba7cac57d73f822e4b4852f83..bd87af4ab8000da7c991acf94337f667162e7403 100644 --- a/src/Validator/UpdateVersionValidator.php +++ b/src/Validator/UpdateVersionValidator.php @@ -172,13 +172,9 @@ class UpdateVersionValidator implements EventSubscriberInterface { '@from_version' => $from_version_string, ]; $from_version = ExtensionVersion::createFromVersionString($from_version_string); + // @todo Return multiple validation messages and summary in // https://www.drupal.org/project/automatic_updates/issues/3272068. - if ($from_version->getVersionExtra() === 'dev') { - return ValidationResult::createError([ - $this->t('Drupal cannot be automatically updated from the installed version, @from_version, because automatic updates from a dev version to any other version are not supported.', $variables), - ]); - } if (Comparator::lessThan($to_version_string, $from_version_string)) { return ValidationResult::createError([ $this->t('Update version @to_version is lower than @from_version, downgrading is not supported.', $variables), diff --git a/tests/src/Kernel/ReadinessValidation/InstalledVersionValidatorTest.php b/tests/src/Kernel/ReadinessValidation/InstalledVersionValidatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3fb138504ee28be0b12914e9d9f8fedcbfa66b8d --- /dev/null +++ b/tests/src/Kernel/ReadinessValidation/InstalledVersionValidatorTest.php @@ -0,0 +1,32 @@ +<?php + +namespace Drupal\Tests\automatic_updates\Kernel\ReadinessValidation; + +use Drupal\package_manager\ValidationResult; +use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase; + +/** + * @covers \Drupal\automatic_updates\Validator\InstalledVersionValidator + * + * @group automatic_updates + */ +class InstalledVersionValidatorTest extends AutomaticUpdatesKernelTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['automatic_updates']; + + /** + * Tests that the installed version of Drupal is checked for updateability. + */ + public function testInstalledVersionValidation(): void { + $this->setCoreVersion('9.8.0-dev'); + + $result = ValidationResult::createError([ + 'Drupal cannot be automatically updated from the installed version, 9.8.0-dev, because automatic updates from a dev version to any other version are not supported.', + ]); + $this->assertCheckerResultsFromManager([$result], TRUE); + } + +} diff --git a/tests/src/Kernel/ReadinessValidation/UpdateVersionValidatorTest.php b/tests/src/Kernel/ReadinessValidation/UpdateVersionValidatorTest.php index 0d6aae08e7199acf0d4ee40ceacf86f2f3e2dc7c..3193ada45a681616108fd9598cbfccb4e74c8734 100644 --- a/tests/src/Kernel/ReadinessValidation/UpdateVersionValidatorTest.php +++ b/tests/src/Kernel/ReadinessValidation/UpdateVersionValidatorTest.php @@ -256,6 +256,7 @@ class UpdateVersionValidatorTest extends AutomaticUpdatesKernelTestBase { $unstable_current_version = ValidationResult::createError([ 'Drupal cannot be automatically updated during cron from its current version, 9.8.0-alpha1, because Automatic Updates only supports updating from stable versions during cron.', ]); + return [ 'unstable current version, cron disabled' => [ CronUpdater::DISABLED, @@ -275,21 +276,6 @@ class UpdateVersionValidatorTest extends AutomaticUpdatesKernelTestBase { '9.8.0-alpha1', [$unstable_current_version], ], - 'dev current version, cron disabled' => [ - CronUpdater::DISABLED, - '9.8.x-dev', - [], - ], - 'dev current version, security updates allowed' => [ - CronUpdater::SECURITY, - '9.8.x-dev', - [], - ], - 'dev current version, all updates allowed' => [ - CronUpdater::ALL, - '9.8.x-dev', - [], - ], // @todo In the 3 following test cases the installed version is not // in a supported branch. These test expectations should be changed or // moved to a new test when we add a validator to check if the installed