These were development-only tooling for iterating on the family-aware
upgrade gate and the next_major migration hint:
- bin/gpm-cache-inject — synthetic GPM response injection
- bin/gpm-e2e-test — family-gate E2E runner
- bin/gpm-test-server.php — local fake grav.json server
Not referenced from production code or CI. Preserved in git stash
alongside bin/gpm-migration-probe and bin/gpm-migration-e2e for future
hint-flow testing.
Reads the new `next_major` block from grav.json (sent by a family-aware
resources server when a 1.x client is served a 1.x release alongside a 2.x
hint) and exposes it via Upgrader::isNextMajorAvailable(),
getNextMajorVersion(), getMigrationUrl(). The admin plugin uses these to
show a dashboard migration banner without implying an automatic upgrade.
isNextMajorAvailable() no longer compares raw remote vs local majors —
under family-aware serving, the remote version is already the client's
family, so the old logic would silently stop firing. It now requires
the server hint and verifies it truly points to a newer major.
Tests updated to inject the hint via an extended TestableUpgrader.
- Delete InstallSnapshotManifestTest: references isSnapshotManifest()
which no longer exists after safe-upgrade removal
- Fix InstallCompatibilityTest: GRAV_ROOT is a PHP constant that cannot
be redefined per-test; add optional $root param to detectIncompatiblePackages,
isPluginEnabled, and isThemeEnabled so tests can pass a tmpDir directly
- Remove SafeUpgradeService, RollbackCommand, SafeUpgradeRunCommand, and bin/restore
- Simplify Install.php: remove all snapshot logic; keep forceSafeUpgrade() as no-op stub
for backward compat with pre-2.0 upgrade scripts that call it in finally blocks
- Simplify SelfupgradeCommand: remove --safe/--legacy flags, safe-upgrade window tracking,
and manifest block; keep RecoveryManager plugin-disable calls
- Simplify PreflightCommand: use Install::instance()->generatePreflightReport() directly
- Simplify recovery.php: remove auth, rollback, and quarantine sections; keep
clear-flag and disable-recovery actions
- Upgrader::isUpgradable() now returns false when remote is a different major.minor family
(e.g. 1.8.x will not auto-upgrade to 2.0.x)
- Add Upgrader::isNextMajorAvailable() for future informational notices
- Add bin/gpm-cache-inject helper for local E2E testing without a live server
- Add UpgraderFamilyTest covering all cross-family and same-family scenarios (10/10)
Extends the 1.7/1.8 compatibility machinery to treat a grav >= 2.0
dependency as ['2.0']. SelfupgradeCommand's preflight already keys off
the target package's major.minor, so upgrading 1.8 → 2.0 now correctly
flags plugins that only declare 1.7 or 1.8 as blocking.
- GPM/Local/Package::inferCompatibility(): grav >= 2.0 → ['2.0']
- Installer/Install::inferCompatibleVersions(): grav >= 2.0 → ['2.0']
- IndexCommand / InfoCommand / UpdateCommand: magenta '2.0' badge
Ships as part of the final 1.8 beta so the installed base has a clean
upgrade gate when users run `bin/gpm selfupgrade` against a Grav 2.0
release. The actual migration wizard is a 2.0-only deliverable and is
NOT backported here.
Adds a new `compatibility:` field to plugin/theme blueprints.yaml that allows
authors to declare which Grav versions they've tested on:
compatibility:
grav: ['1.7', '1.8']
api: ['1.0']
When absent, compatibility is inferred from dependencies (grav >=1.8 means
1.8-only, otherwise assumes 1.7). This gates major upgrades (1.7→1.8) by
blocking if enabled plugins aren't marked as 1.8-compatible.
Core changes:
- Install.php: detectIncompatiblePackages() in preflight checks
- SafeUpgradeService: same detection for admin pre-download checks
- SelfupgradeCommand: interactive handling (disable/continue/abort)
- GPM Local/Package: computed compatibility property from blueprints
- CLI badges: IndexCommand, InfoCommand, UpdateCommand show 1.7/1.8 badges
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reads user/config/plugin-asset-map.php to map URL prefixes to physical
directories. Matching requests are served with readfile() and exit
before Grav boots, avoiding the full framework overhead for static
JS, CSS, fonts, and images.
Registers a new media:// stream pointing to user://media, providing
a dedicated writable stream for site-wide media files not tied to
specific pages. Supports all file types (not just images like the
existing image:// stream).
- Replace empty media.yaml blueprint stub with full form fields
- Add PLUGIN_ADMIN media translation keys (MEDIA, MEDIA_TYPES, FILE_EXTENSION,
TYPE, THUMB, MIME_TYPE, IMAGE_OPTIONS) to all 44 core language files
- Enables media configuration without the admin plugin being enabled
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The `schedule` field in backup profile configuration was never checked
when registering backup jobs with the scheduler. This meant backups
would always run on schedule even when `schedule: false` was set.
Fixes#4039
- Fix YamlUpdater.undefine() to actually remove lines from YAML files
- Add maintenance mode (503) during core upgrades via .upgrading flag
- Add opcache_reset in sophisticatedInstall() for reliable file operations
- Add early PHP 8.3 version check in bin/grav
- Add PHP CLI vs web version mismatch hint in Install error messages
- Update 1.7 bridge version references from 1.7.50 to 1.7.51
- Disable recovery_mode by default until stability confirmed
- Add standalone upgrade.php script (CLI + web)
- Update markdowndocs to ^3.0
* checkout correct version
Signed-off-by: Andy Miller <rhuk@mac.com>
* cache-cleanup command
Signed-off-by: Andy Miller <rhuk@mac.com>
* remove standlone binary
Signed-off-by: Andy Miller <rhuk@mac.com>
* "Claude PR Assistant workflow"
* "Claude Code Review workflow"
---------
Signed-off-by: Andy Miller <rhuk@mac.com>