Skip to content

Plugin Directory: Delay trunk-only imports on tag-releasing plugins#8

Open
dd32 wants to merge 1 commit into
fix/claude/plugin-import-merge-future-schedulefrom
fix/claude/plugin-import-delay-trunk-only
Open

Plugin Directory: Delay trunk-only imports on tag-releasing plugins#8
dd32 wants to merge 1 commit into
fix/claude/plugin-import-merge-future-schedulefrom
fix/claude/plugin-import-delay-trunk-only

Conversation

@dd32
Copy link
Copy Markdown
Owner

@dd32 dd32 commented May 13, 2026

Stacks on top of WordPress#631 to address the trunk-then-tag double-import problem.

The problem

Plugins that release from a tag commonly commit the version-bumped files to /trunk first and then svn cp trunk tags/X.Y shortly after — see r3530799 / r3530800 for a recent real-world example. Today the SVN watcher imports the trunk commit immediately: trunks Stable Tag points at the new version but /tags/X.Y does not exist yet, so the importer falls back to publishing the release from trunk (with the stable_tag_invalid_trunk_fallback warning). The follow-up tag commit then triggers a second import that re-publishes the same release from the tag.

The change

Reuses the merge model that this PR started with but expands it to cover this case. Plugin_Import::queue() now:

  1. If a future event already exists for the plugin and no job is running, merge the new args into it (restoring merge_plugin_data() and the per-key OR/union behavior).
  2. Decide the events run time from the merged args via a new queue_run_time() helper. If the result is a trunk-only update on a plugin whose current stable_tag is not trunk, run in 5 * MINUTE_IN_SECONDS; otherwise 5s.
  3. Use min( existing_nextrun, queue_run_time(merged) ) so a pending event is never pushed further out.

That collapses two previously-separate rules into one:

  • Bulk re-index pull-forward (this PRs current behavior): a far-future event merges with an arriving commit and runs at the usual time. Same outcome as before, just expressed as a merge.
  • Trunk-then-tag delay (new): a trunk-only commit on a tagged plugin schedules at now + 5min. If the follow-up tag commit arrives within that window, it merges in — the merged args are no longer trunk-only, so queue_run_time() returns now + 5s and the event pulls forward to run as a single import that publishes from the tag. If no tag arrives, the event runs as scheduled and publishes from trunk-fallback, same as today (but only once).

Why stable_tag != trunk rather than tagged_versions

stable_tag is the directorys current view of where the plugin releases from; if its set to a version like 1.2.2, the next release is almost certainly going to come in via a tag. A plugin thats genuinely releasing from trunk (e.g. brand-new plugins, or those that never tag) keeps stable_tag = trunk and doesnt get delayed.

Edge cases

  • Tag-touching commits, tag deletions, and plugins releasing from trunk run immediately — no behavior change.
  • Brand-new plugin without a published stable_tag postmeta yet → no delay (the meta is falsy).
  • An unrelated trunk-only bugfix that doesnt change Stable Tag → delayed 5 min, then runs and no-ops at import time. Harmless.
  • Running job concurrency guard (last_scheduled + 1hr, or now + 1hr if a job is in flight) is preserved.

Changes

  • Plugin_Import::queue() — unified merge model.
  • Plugin_Import::queue_run_time() + Plugin_Import::is_trunk_only_update_on_tagged_plugin() — new run-time decision.
  • Plugin_Import::merge_plugin_data() — restored from earlier in this PR.
  • tests/Plugin_Import_Merge_Test.php — restored and expanded with cases for the trunk-only detection.

Test plan

  • npm run plugins:test --filter Plugin_Import_Merge_Test — all merge + classification tests pass.
  • In staging: with a plugin whose stable_tag is 1.0, commit a trunk-only change → verify an event is scheduled ~now + 5min. Then commit svn cp trunk tags/1.1 → verify the events args now include the tag and its nextrun pulled forward to ~now + 5s, then a single import runs and publishes from tags/1.1.
  • In staging: with a plugin whose stable_tag is trunk (no tag history), commit a trunk-only change → verify the event is scheduled ~now + 5s (no delay).
  • In staging: with a plugin whose stable_tag is 1.0, queue a bulk re-index event 30 min out, then trigger a commit-driven queue() → verify the event is pulled forward and the args merged (existing PR-631 behavior, unchanged).

🤖 Generated with Claude Code

…o merge follow-up tag commit.

Plugins that release from a tag commonly commit version-bumped files to /trunk
first, then `svn cp trunk tags/X.Y` shortly after. Today's flow runs the import
immediately on the trunk commit and publishes a trunk-fallback release; the
follow-up tag commit then triggers a second import and re-publishes the same
release from the tag. See r3530799 / r3530800 for an example.

Delays trunk-only imports by 5 minutes when the plugin's current stable_tag is
not 'trunk' (i.e. it currently releases from a tag, so a tag is likely
incoming). Reinstates merge_plugin_data() and reshapes Plugin_Import::queue()
so any pending future event is folded into the new request; the merged args
determine the run time. The bulk re-index pull-forward from earlier in this PR
and the new trunk-then-tag delay are now expressions of the same rule:
"one pending event per plugin, run at the earlier of its existing schedule and
the natural schedule of the merged args."

Tag-touching changes, tag deletions, and plugins releasing from trunk run
immediately (no behavior change).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props dd32.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

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