Skip to content

Release - #1390

Open
pirate-bot wants to merge 5 commits into
masterfrom
development
Open

Release#1390
pirate-bot wants to merge 5 commits into
masterfrom
development

Conversation

@pirate-bot

@pirate-bot pirate-bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Linked issues

This release will close the following issues once merged:

Public changelog

  • Fixed queue cleanup to skip actions another process removed or failed.
  • Updated dependencies

pirate-bot and others added 3 commits September 30, 2026 12:30
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.2.14 to 2.2.15.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@pirate-bot

Copy link
Copy Markdown
Contributor Author

Make sure you've reviewed the themeisle_sdk_compatibilities filter of the plugin and updated it accordingly.

@pirate-bot

pirate-bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Plugin build for 0c49f5c is ready 🛎️!

dependabot Bot and others added 2 commits October 2, 2026 21:01
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.2.15 to 2.2.16.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
)

* fix: survive a failed action that another process already handled

Action Scheduler's `mark_failure()` throws "Unidentified action" when its
UPDATE changes no row. That happens when another process deleted the
action, and also when an overlapping cleaner already marked it failed:
WP-Cron's queue run takes no lock, only the async runner does. Two
callers let that exception escape and end the request with a fatal:
the queue cleaner loop and the runner's action error path.

The bundled copy is patched at `composer install` so both callers skip
that action and continue, the same guard `delete_actions()` already
uses. `composer-exit-on-patch-failure` makes a future Action Scheduler
bump fail loudly instead of dropping the fix. Upstream 4.2.0 still
throws; see woocommerce/action-scheduler#970.

Refs: #1369

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test: keep WordPress update checks out of AJAX tests for any file order

The framework snapshots hooks at the first test of the run and restores
that snapshot after every test. WP_Ajax_UnitTestCase removes the
`_maybe_update_*` admin_init hooks once per class, which only holds when
an AJAX class runs first. A test file that sorts before test-ajax.php
put the hooks back into the snapshot, so every later AJAX test called
api.wordpress.org and failed on the response. Remove the hooks in the
bootstrap so the order of test files does not matter.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: let real database errors surface when marking an action failed

The guard caught every Exception, so a database error inside
`mark_failure()` was swallowed together with the race it targets. The
store throws the same InvalidArgumentException for both; only
`$wpdb->last_error` tells them apart. Catch that type only and rethrow
when the database reported an error.

Tests: one-shot guard in the query interceptor, so an injected UPDATE
cannot re-enter it; a pattern that accepts quoted ids; a test that
breaks the UPDATE and expects the exception to surface.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* build: refresh composer.lock content hash

composer.json changed after the lock was written, so `composer validate`
failed and every install warned that the lock file was stale.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test: restore the previous suppress_errors() setting

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test: name the SQL predicate; note why last_error is trustworthy in the guard

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test: seed through the store API; cover the runner path with a deleted action

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: tolerate zero changed rows inside the store instead of at each caller

`wpdb::update()` returns false on a database error and 0 when no row
changed. `ActionScheduler_DBStore::mark_failure()` now throws only on
false, so the race (deleted or already failed by another process) is
handled once for every caller and no caller reads `$wpdb->last_error`.
One hunk replaces the two caller guards.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test: intercept only the UPDATE that sets status to failed

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix: replace the vendor patch with a store class of our own

Patching the bundled Action Scheduler needed a Composer plugin, a patch
file kept in the repo, and a re-roll on every dependency bump.

Action Scheduler resolves its store through `action_scheduler_store_class`.
Visualizer now answers that filter with a subclass of the database store
that tolerates zero changed rows in `mark_failure()`, and still throws
when the UPDATE itself failed. The library stays untouched, so a version
bump needs no work, and the fix applies to whichever copy of Action
Scheduler is loaded. Other stores, including another plugin's, are left
alone.

Refs: #1369

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

* test: cover the store filter priority and tidy the mark-failure tests

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

* fix: tell a database error from zero changed rows by the UPDATE result

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

* fix: format the action ID with %d in the failure message

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

* test: escape the status value in the UPDATE matcher

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

* docs: say which parts of the UPDATE matcher accept quotes

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

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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.

Action Scheduler queue cleanup fatals with "Unidentified action" after concurrent deletion

2 participants