Plugins: Store releases as CPT records#675
Conversation
|
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 Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
There was a problem hiding this comment.
Pull request overview
This PR migrates the Plugin Directory “releases” storage layer from a single releases postmeta array to a private plugin_release custom post type (CPT), while preserving the legacy release array contract consumed by existing cooldown/ZIP/confirmation code paths.
Changes:
- Introduces a headless
Plugin_Releasestorage/compatibility layer backed by a privateplugin_releaseCPT, with lazy backfill from legacyreleasespostmeta and (fallback)tags/SVN metadata. - Replaces
Plugin_Directory::get_release(s),add_release(), andremove_release()to delegate to the new CPT-backed implementation. - Adds PHPUnit coverage for CPT writes, lazy backfill, merge/update semantics, unconfirmed deletion rules, and the
trunk@versionfallback.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
wordpress.org/public_html/wp-content/plugins/plugin-directory/class-plugin-directory.php |
Switches the public legacy release APIs to delegate to the new CPT-backed layer and initializes release support. |
wordpress.org/public_html/wp-content/plugins/plugin-directory/class-plugin-release.php |
Adds the CPT storage + legacy compatibility implementation, including lazy migration/backfill logic. |
wordpress.org/public_html/wp-content/plugins/plugin-directory/tests/Plugin_Release_Test.php |
Adds focused tests covering CPT persistence, backfill behavior, updates/merges, deletion rules, and trunk fallback. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| foreach ( $replace_meta_keys as $meta_key ) { | ||
| if ( metadata_exists( 'post', $release_post->ID, $meta_key ) ) { | ||
| update_post_meta( $plugin->ID, $meta_key, wp_slash( get_post_meta( $release_post->ID, $meta_key, true ) ) ); | ||
| } else { | ||
| delete_post_meta( $plugin->ID, $meta_key ); | ||
| } | ||
| } | ||
|
|
||
| foreach ( array( 'plugin_name_history', 'last_version', 'last_stable_tag', 'last_version_date', 'version_date' ) as $meta_key ) { | ||
| if ( metadata_exists( 'post', $release_post->ID, $meta_key ) ) { | ||
| update_post_meta( $plugin->ID, $meta_key, wp_slash( get_post_meta( $release_post->ID, $meta_key, true ) ) ); | ||
| } | ||
| } |
There was a problem hiding this comment.
I think this is correct as-is. update_post_meta() unslashes before storing, and get_post_meta() returns the unslashed value. The import stores the release meta with wp_slash() so the release post keeps the original value, then sync reads that unslashed value and applies wp_slash() again before writing to the plugin post, matching the legacy direct update_post_meta( ..., wp_slash( $value ) ) behavior.
| if ( metadata_exists( 'post', $release_post->ID, '_missing_blueprint_notice' ) ) { | ||
| add_post_meta( $plugin->ID, '_missing_blueprint_notice', get_post_meta( $release_post->ID, '_missing_blueprint_notice', true ), true ); | ||
| } | ||
| } |
There was a problem hiding this comment.
I checked trunk and the legacy importer does not delete _missing_blueprint_notice when blueprints are present. It only updates assets_blueprints in that branch, and only adds _missing_blueprint_notice in the missing-blueprint branch. The current sync keeps that behavior by adding the notice when the release import has it and otherwise leaving existing plugin notice state untouched.
Summary
plugin_releaseCPT from PR Add a release page #407 without the release-page UI/components.Plugin_Directory::get_release(s),add_release(), andremove_release()storage layer with CPT-backed records while preserving the legacy release array shape used by release confirmations, ZIP building, and cooldown code.releasespostmeta, thentagsmetadata/SVN as the existing polyfill path did, and mirrors PR Add a release page #407-style release meta for future UI work.trunk@versionlookup fallback.Testing
php -l wordpress.org/public_html/wp-content/plugins/plugin-directory/class-plugin-directory.phpphp -l wordpress.org/public_html/wp-content/plugins/plugin-directory/class-plugin-release.phpphp -l wordpress.org/public_html/wp-content/plugins/plugin-directory/tests/Plugin_Release_Test.php./vendor/bin/phpcs --standard=wordpress.org/public_html/wp-content/plugins/plugin-directory/phpcs.xml.dist wordpress.org/public_html/wp-content/plugins/plugin-directory/class-plugin-release.php wordpress.org/public_html/wp-content/plugins/plugin-directory/tests/Plugin_Release_Test.phpgit diff --checkTargeted PHPUnit was attempted with
WP_TESTS_DIR=/home/user/wordpress-develop/tests/phpunit ./vendor/bin/phpunit -c wordpress.org/public_html/wp-content/plugins/plugin-directory/phpunit.xml --filter Plugin_Release_Test, but local WordPress bootstrap fails because this PHP runtime has no MySQLi extension.Refs #664, #407.