major/minor upgrade warnings

Signed-off-by: Andy Miller <rhuk@mac.com>
This commit is contained in:
Andy Miller
2025-11-09 12:51:54 +00:00
parent bd5b2633f7
commit 0764e37c8b
3 changed files with 87 additions and 33 deletions

View File

@@ -146,11 +146,28 @@ class SafeUpgradeService
/**
* Run preflight validations before attempting an upgrade.
*
* @return array{plugins_pending: array<string, array>, psr_log_conflicts: array<string, array>, warnings: string[]}
* @param string|null $targetVersion The target Grav version being upgraded to (e.g., '1.8.0')
* @return array{plugins_pending: array<string, array>, psr_log_conflicts: array<string, array>, warnings: string[], is_major_minor_upgrade: bool}
*/
public function preflight(): array
public function preflight(?string $targetVersion = null): array
{
$warnings = [];
$isMajorMinorUpgrade = false;
// Determine if this is a major/minor version upgrade (e.g., 1.7.x -> 1.8.y)
if ($targetVersion !== null) {
$currentVersion = GRAV_VERSION;
$currentParts = explode('.', $currentVersion);
$targetParts = explode('.', $targetVersion);
$currentMajor = (int)($currentParts[0] ?? 0);
$currentMinor = (int)($currentParts[1] ?? 0);
$targetMajor = (int)($targetParts[0] ?? 0);
$targetMinor = (int)($targetParts[1] ?? 0);
$isMajorMinorUpgrade = ($currentMajor !== $targetMajor) || ($currentMinor !== $targetMinor);
}
try {
$pending = $this->detectPendingPluginUpdates();
} catch (RuntimeException $e) {
@@ -160,8 +177,15 @@ class SafeUpgradeService
$psrLogConflicts = $this->detectPsrLogConflicts();
$monologConflicts = $this->detectMonologConflicts();
// Only enforce plugin updates for major/minor upgrades
// For patch upgrades, just warn but don't block
if ($pending) {
$warnings[] = 'One or more plugins/themes are not up to date.';
if ($isMajorMinorUpgrade) {
$warnings[] = 'One or more plugins/themes are not up to date and must be updated for major version upgrades.';
} else {
$warnings[] = 'One or more plugins/themes are not up to date.';
}
}
if ($psrLogConflicts) {
$warnings[] = 'Potential psr/log signature conflicts detected.';
@@ -175,6 +199,7 @@ class SafeUpgradeService
'psr_log_conflicts' => $psrLogConflicts,
'monolog_conflicts' => $monologConflicts,
'warnings' => $warnings,
'is_major_minor_upgrade' => $isMajorMinorUpgrade,
];
}

View File

@@ -232,29 +232,6 @@ class SelfupgradeCommand extends GpmCommand
$io->writeln("Grav v<cyan>{$remote}</cyan> is now available [release date: {$release}].");
$io->writeln('You are currently using v<cyan>' . GRAV_VERSION . '</cyan>.');
// Determine if this is a major/minor version upgrade
$localParts = explode('.', $local);
$remoteParts = explode('.', $remote);
$localMajor = (int)($localParts[0] ?? 0);
$localMinor = (int)($localParts[1] ?? 0);
$remoteMajor = (int)($remoteParts[0] ?? 0);
$remoteMinor = (int)($remoteParts[1] ?? 0);
// Check if this is a major/minor version change (e.g., 1.7.x -> 1.8.y)
$isMajorMinorUpgrade = ($localMajor !== $remoteMajor) || ($localMinor !== $remoteMinor);
if ($isMajorMinorUpgrade) {
$io->newLine();
$io->writeln('<yellow>NOTE</yellow>: This is a major version upgrade.');
$io->writeln('It is recommended to run `<cyan>bin/gpm update</cyan>` first to update all plugins and themes');
$io->writeln('to their latest compatible versions before upgrading Grav core.');
} else {
$io->newLine();
$io->writeln('<green>NOTE</green>: This is a patch version upgrade.');
$io->writeln('You can safely proceed. Grav will check for any plugin compatibility issues during the upgrade.');
}
if (!$this->all_yes) {
$question = new ConfirmationQuestion(
'Would you like to read the changelog before proceeding? [y|N] ',
@@ -423,6 +400,27 @@ class SelfupgradeCommand extends GpmCommand
}
if ($pending) {
// Use the is_major_minor_upgrade flag from preflight result if available
$isMajorMinorUpgrade = $preflight['is_major_minor_upgrade'] ?? false;
// Fall back to calculating it if not provided (for backwards compatibility)
if (!isset($preflight['is_major_minor_upgrade'])) {
$local = $this->upgrader->getLocalVersion();
$remote = $this->upgrader->getRemoteVersion();
$localParts = explode('.', $local);
$remoteParts = explode('.', $remote);
$localMajor = (int)($localParts[0] ?? 0);
$localMinor = (int)($localParts[1] ?? 0);
$remoteMajor = (int)($remoteParts[0] ?? 0);
$remoteMinor = (int)($remoteParts[1] ?? 0);
$isMajorMinorUpgrade = ($localMajor !== $remoteMajor) || ($localMinor !== $remoteMinor);
}
$local = $this->upgrader->getLocalVersion();
$remote = $this->upgrader->getRemoteVersion();
$io->newLine();
$io->writeln('<yellow>The following packages need updating before Grav upgrade:</yellow>');
foreach ($pending as $slug => $info) {
@@ -432,7 +430,16 @@ class SelfupgradeCommand extends GpmCommand
$io->writeln(sprintf(' - %s (%s) %s → %s', $slug, $type, $current, $available));
}
$io->writeln(' Please run `bin/gpm update` to bring these packages current before upgrading Grav.');
if ($isMajorMinorUpgrade) {
// For major/minor upgrades, this is EXPECTED behavior - updating plugins first is REQUIRED
$io->writeln(' For major version upgrades (v' . $local . ' → v' . $remote . '), plugins must be updated to their latest');
$io->writeln(' compatible versions BEFORE upgrading Grav core to ensure compatibility.');
$io->writeln(' Please run `bin/gpm update` to update these packages, then retry self-upgrade.');
} else {
// For patch upgrades, this shouldn't normally happen but plugins still need updating
$io->writeln(' Please run `bin/gpm update` to bring these packages current before upgrading Grav.');
}
$io->writeln('Aborting self-upgrade. Run `bin/gpm update` first.');
return false;

View File

@@ -346,7 +346,9 @@ ERR;
// Run preflight checks using the NEW SafeUpgradeService
// This ensures preflight logic is from the package being installed, not the old installation
try {
$preflight = $service->preflight();
$targetVersion = $this->getVersion();
$preflight = $service->preflight($targetVersion);
$isMajorMinorUpgrade = $preflight['is_major_minor_upgrade'] ?? false;
// Check for pending plugin/theme updates
if (!empty($preflight['plugins_pending'])) {
@@ -358,11 +360,31 @@ ERR;
$list[] = sprintf('%s (v%s → v%s)', $slug, $current, $available);
}
throw new RuntimeException(
'Please update the following plugins/themes before upgrading Grav: ' .
implode(', ', $list) . '. ' .
'Run "bin/gpm update" or update via Admin panel first.'
);
if ($isMajorMinorUpgrade) {
// For major/minor upgrades, block until plugins are updated
// This allows the NEW package to define and enforce the upgrade policy
$currentVersion = GRAV_VERSION;
$targetVersion = $this->getVersion();
throw new RuntimeException(
sprintf(
"Major version upgrade detected (v%s → v%s).\n\n" .
"The following plugins/themes have updates available:\n - %s\n\n" .
"For major version upgrades, plugins and themes must be updated FIRST.\n" .
"Please run 'bin/gpm update' to update these packages, then retry the upgrade.\n" .
"This ensures plugins have necessary compatibility fixes for the new Grav version.",
$currentVersion,
$targetVersion,
implode("\n - ", $list)
)
);
} else {
// For patch upgrades, just log a warning but allow upgrade
error_log(
'WARNING: The following plugins/themes have updates available: ' .
implode(', ', $list) . '. ' .
'Consider updating them after upgrading Grav.'
);
}
}
// PSR log conflicts - log warning but don't block for now