From 57f507d25290f81fdd33007fcc8827ba5b0a3700 Mon Sep 17 00:00:00 2001 From: Nikita Date: Fri, 23 Oct 2026 22:18:41 +0300 Subject: [PATCH] fix(activate): upgrade the database before activating After a switch of the WordPress core version, wp-admin redirects to upgrade.php until the database is upgraded, and the E2E setup's requestUtils.activateTheme fails with "The theme ... is not installed". wp core update-db is a no-op on a current database. --- README.md | 6 +++-- scripts/activate-plugin.js | 18 +++++++++++---- scripts/self-test.js | 45 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b3c306a..52cfeeb 100644 --- a/README.md +++ b/README.md @@ -111,8 +111,10 @@ checkout keeps 8888/8889, linked worktrees derive their own pair, and explicit `WP_ENV_PORT` / `WP_ENV_TESTS_PORT` always win. Several branches can run their own WordPress at the same time. -`nk-activate-plugins` activates the list in `nkPluginToolkit.plugins`, in order, -in both environments, retrying while the site is still coming up. Wire it into +`nk-activate-plugins` runs `wp core update-db`, then activates the list in +`nkPluginToolkit.plugins`, in order, in both environments, retrying while the +site is still coming up. The database upgrade matters after a switch of the +WordPress core version, when wp-admin redirects to `upgrade.php`. Wire it into `.wp-env.json`: ```json diff --git a/scripts/activate-plugin.js b/scripts/activate-plugin.js index 9f71a9a..cd4860f 100755 --- a/scripts/activate-plugin.js +++ b/scripts/activate-plugin.js @@ -1,7 +1,8 @@ #!/usr/bin/env node /** - * Activates the plugins in both `wp-env` environments after a start. + * Upgrades the database and activates the plugins in both `wp-env` + * environments after a start. * * Plugins are mounted through `mappings` in `.wp-env.json` rather than through * `plugins`, so that each directory inside WordPress keeps a fixed name no @@ -171,9 +172,18 @@ function activateIn(container) { wpCli(container, ['plugin', 'deactivate', ...plugins]); } - const activated = wpCli(container, ['plugin', 'activate', ...plugins]); - - if (activated.status === 0) { + // After a switch of the WordPress core version, wp-admin redirects to + // upgrade.php until the database is upgraded, and REST calls from the + // E2E setup (activateTheme) fail. A no-op when the database is current. + const upgraded = wpCli(container, ['core', 'update-db', '--quiet']); + const activated = + upgraded.status === 0 + ? wpCli(container, ['plugin', 'activate', ...plugins]) + : null; + + if (!activated) { + output = `wp core update-db failed: ${upgraded.output}`; + } else if (activated.status === 0) { // `wp plugin activate` can report success for the set while an // individual plugin stayed inactive, so confirm rather than trust. const missing = findInactive(container); diff --git a/scripts/self-test.js b/scripts/self-test.js index a18bf80..8358726 100755 --- a/scripts/self-test.js +++ b/scripts/self-test.js @@ -309,6 +309,51 @@ check('slow tests are reported', () => { ); }); +check('activation upgrades the database first, in both sites', () => { + const os = require('node:os'); + const { spawnSync } = require('node:child_process'); + const project = fs.mkdtempSync(path.join(os.tmpdir(), 'nk-activate-')); + const bin = path.join(project, 'node_modules', '.bin'); + const log = path.join(project, 'calls.log'); + + fs.mkdirSync(bin, { recursive: true }); + fs.writeFileSync( + path.join(project, 'package.json'), + JSON.stringify({ nkPluginToolkit: { plugins: ['my-plugin'] } }) + ); + // Records each call; `plugin list` answers with the plugin active. + fs.writeFileSync( + path.join(bin, 'wp-env'), + `#!/bin/sh\necho "$*" >> "${log}"\ncase "$*" in *"plugin list"*) echo '["my-plugin"]';; esac\n`, + { mode: 0o755 } + ); + + try { + const result = spawnSync( + process.execPath, + [path.join(root, 'scripts', 'activate-plugin.js')], + { cwd: project, encoding: 'utf-8' } + ); + + assert.equal(result.status, 0, result.stderr); + + const calls = fs + .readFileSync(log, 'utf-8') + .trim() + .split('\n') + .filter((line) => !line.includes('plugin list')); + + assert.deepEqual(calls, [ + 'run cli wp core update-db --quiet', + 'run cli wp plugin activate my-plugin', + 'run tests-cli wp core update-db --quiet', + 'run tests-cli wp plugin activate my-plugin', + ]); + } finally { + fs.rmSync(project, { recursive: true, force: true }); + } +}); + check('every runtime require is a declared dependency', () => { const declared = new Set([ ...Object.keys(pkg.dependencies || {}),