Skip to content

fix: a generic plugin update keeps the plugin active (2.23.1) - #143

Merged
BenKalsky merged 4 commits into
mainfrom
fix/update-keeps-plugin-active
Sep 29, 2026
Merged

BenKalsky merged 4 commits into
mainfrom
fix/update-keeps-plugin-active

Conversation

@BenKalsky

Copy link
Copy Markdown
Member

Problem

When a plugin is updated through POST /aura/v1/update/plugin (and the v2 batch or update_plugin_safely), it ends up deactivated. When the target is SiteAgent itself, the site loses every aura/* route, and Aura can no longer reach it to repair anything.

Root cause:

  • Plugin_Upgrader::upgrade() runs inside a REST request, so core's deactivate_plugin_before_upgrade fires at upgrader_pre_install.
  • In wp-admin, the skin's re-activation iframe turns the plugin back on. The REST path has no equivalent step.

The same path also:

  • reported every run() failure (null) as "No update available", which lost the real error. On staging that error was "could not copy files", a file-permissions problem;
  • never refreshed a stale update list before upgrading.

Fix (one helper, upgrade_plugin_keeping_activation(), used by the single update and every batch entry)

  1. Activation state is preserved.
    • The helper records is_plugin_active and network-active before the upgrade.
    • In a finally, it re-activates silently when needed: on success, on failure and on a throw.
    • The result carries reactivated, plus reactivation_error when re-activation fails.
    • A plugin that was inactive is never activated.
  2. SiteAgent itself is refused with 409 aura_use_self_update, and the upgrader is never reached. SiteAgent updates itself only through /self-update. The multisite, host and busy refusals keep their precedence.
  3. Results are mapped correctly:
    • null becomes aura_update_failed with the skin's own reason;
    • false becomes 409 aura_no_update_offered;
    • a WP_Error keeps its code.
  4. The offer is refreshed: when there's no update_plugins entry, the helper calls wp_update_plugins() once and re-reads. It reports offered_version.

Tests

  • 33 new PHPUnit tests: activation (single, batch, network), the self refusal, result mapping, and REST status.
  • The full suite is green (5701), and phpcs is clean.
  • 3 existing tests were changed, as a direct consequence of the design:
    • the ledger structural test now counts 3 upgrader calls, not 4;
    • generic self-update is now refused;
    • the lost-claim-in-self-upgrade test is gone, since that upgrade can no longer happen.

Release

The second commit bumps to 2.23.1 (header, readme.txt, README.md, CLAUDE.md). Publishing the GitHub release, which deploys to wp.org, is a separate step that needs owner approval.

Aura side (follow-up)

Aura will route a SiteAgent target to /self-update, surface the typed codes, and warn on reactivated: false. Until then Aura shows the new 409s as its generic "Failed to execute update".

🤖 Generated with Claude Code

BenKalsky and others added 2 commits September 29, 2026 22:59
Plugin_Upgrader::upgrade() deactivates its target at upgrader_pre_install
outside cron, and only wp-admin's skin turns it back on. Every plugin updated
through /aura/v1/update/plugin, the v2 batch or update_plugin_safely came back
inactive; for SiteAgent itself that removed every aura/* route.

- One helper, upgrade_plugin_keeping_activation(), is the only generic plugin
  upgrade call. It records is_plugin_active / network activation before the
  upgrade and re-activates silently in a finally (success, failure, throw),
  never activating a plugin that was inactive; it reports `reactivated` and
  `reactivation_error`.
- SiteAgent's own file is refused on the generic paths with
  aura_use_self_update (REST 409) after the multisite, host and busy-claim
  refusals; the upgrader is never reached. A batch refuses only that entry.
- upgrade() null is aura_update_failed with the skin's reason (never "No
  update available"); false is aura_no_update_offered (REST 409); a WP_Error
  keeps its code and message.
- A missing update_plugins offer is refreshed once with wp_update_plugins()
  before the upgrade; `offered_version` is reported when offered.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…active

Version header, AURA_WORKER_VERSION, readme.txt Stable tag + Changelog,
README.md badge + Changelog; CLAUDE.md documents the generic-update
activation guard, aura_use_self_update, aura_no_update_offered,
aura_update_failed, reactivated / reactivation_error and offered_version.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-29T20:22:22.231275Z 637ba40 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 83d9400f88

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread digitizer-site-worker/includes/class-aura-worker-updater.php
Comment thread digitizer-site-worker/includes/class-aura-worker-updater.php Outdated
…dex r1 on #143)

- A missing update_plugins entry now forces the list stale before the
  refresh: last_checked = 0 is written back with set_site_transient (never
  deleted, so the other plugins' offers survive), because
  wp_update_plugins() returns early inside its timeout. The write is core's
  key and is acknowledged as a foreign dynamic write in UninstallCoverageTest.
- The batch refuses SiteAgent's own entry (aura_use_self_update) inside its
  guarded work, before the recovery helper is built and before
  batch_update_one()'s backup, so no backup is taken and an unwritable
  backup directory cannot turn it into a backup failure. The multisite,
  host and busy refusals still come first; the shared helper keeps its
  check.
- Three batch-only SA#80 lease tests for a SiteAgent entry are retired
  (unreachable now; the self-update path pins the same guarantees); the
  three in-phase heartbeat tests move to self_update()'s install().

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 576481e257

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread digitizer-site-worker/includes/class-aura-worker-updater.php
When the upgrade succeeded but activate_plugin() returned a WP_Error, the
result stayed success:true: REST answered 200, the batch entry was
'updated' and update_plugin_safely dropped the error while the plugin was
left disabled. It is now success:false with code aura_reactivation_failed
(REST 500), updated:true and reactivation_error; the batch entry is
'failed' with that code. A failed upgrade keeps its own code as primary and
still carries reactivation_error.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@BenKalsky

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: 637ba40d01

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@BenKalsky
BenKalsky merged commit c1652b4 into main Sep 29, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant