fix: close the v7 migration gate on pre-release builds#576
Merged
Conversation
Updater::run() runs on every request via Plugin::init(). The v7 block is gated on version_compare( $version, '7.0.0', '<' ), but the shipped build is a pre-release (currently '7.0.0-beta.1'). run() writes that suffixed string back into beyondwords_version, and every pre-release suffix compares < '7.0.0', so the gate never closed: ~40 uncached DB deletes plus a slow beyondwords_disabled postmeta JOIN ran on every page load, anonymous front-end traffic included — a WordPress VIP performance violation. Add a version-equality early return at the top of run(): once a build has recorded its own version, the next request bails before any DB work. This short-circuits the entire migration chain (not just the v7 block), needs no new option, and self-heals every future pre-release gate. Migrations still run once per version change and all three v7 migrations are idempotent, so the rare beta->beta re-run is safe. Also correct three now-inaccurate comments (file header, run() docblock, and the migrate_preselect_format() docblock that claimed the gate fires on every load). Add two UpdaterTest regression tests: run() is a no-op once the recorded version matches this build, and still migrates + records the version when outdated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
✅ WordPress Plugin Check Report
📊 ReportAll checks passed! No errors or warnings found. 🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check |
galbus
marked this pull request as ready for review
July 19, 2026 07:03
gouravkhunger
approved these changes
Jul 19, 2026
gouravkhunger
approved these changes
Jul 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Updater::run()runs on every request (viaPlugin::init()at plugin-include time). The v7 migration block is gated onversion_compare( $version, '7.0.0', '<' ), but the shipped build is a pre-release — currently7.0.0-beta.1.run()writes that same suffixed string back intobeyondwords_version, and every pre-release suffix compares< '7.0.0', so the gate never closed.The result, on every single page load (anonymous front-end traffic included):
delete_deprecated_options()— 39delete_option()/delete_site_option()calls; WP core'sdelete_option()issues aSELECT autoload ...even when the option doesn't exist.migrate_disabled_to_embed_none()— aWP_Querywith an unindexedmeta_valuepostmeta JOIN (WordPress.DB.SlowDBQuerypattern).migrate_preselect_format()— an extra option read.That's ~40 uncached primary-DB SELECTs plus a slow postmeta scan per request — a direct WordPress VIP performance violation (worse on large publisher DBs, and 39 network-meta lookups per request on multisite).
version_compare('7.0.0-beta.1', '7.0.0', '<') === true— verified withphp -r. (The bug was originally reported against7.0.0-dev-2.0; identical defect — any-dev/-beta/-rcsuffix triggers it.)Fix
Add a version-equality early return at the top of
run():Once a build has booted once and recorded its own version, the next request bails before touching the database.
Chosen over the alternative one-shot
beyondwords_migrated_7_0_0flag because it's strictly better: it short-circuits the entire migration chain on the hot path (not just the v7 block), adds no new option, and self-heals every future pre-release gate. Migrations still run exactly once per version change, and all three v7 migrations are idempotent, so the rare beta→beta re-run is safe.Also corrected three now-inaccurate comments: the file header, the
run()docblock, and themigrate_preselect_format()docblock that explicitly claimed the gate "fires on every load".No
phpcs:ignoreadded; the pre-existing one on the meta_query is untouched (that query now runs only once per upgrade, as a migration should).Tests
Two new
UpdaterTestregression tests:run_is_a_noop_once_the_recorded_version_matches_this_build— proves the gate closes (a post's legacybeyondwords_disabledflag is left untouched).run_migrates_and_records_the_version_when_outdated— proves the real upgrade path still migrates and normalises the stored version.Verification
WordPress-VIP-Gostandard): clean, zero errors/warnings onclass-updater.php.UpdaterTest: 8/8 pass, 29 assertions (6 pre-existing + 2 new).🤖 Generated with Claude Code