From 565e1b8d3d89af2f019184f7ee59def782edd4bb Mon Sep 17 00:00:00 2001 From: Stuart McAlpine Date: Mon, 6 Jul 2026 07:48:58 +0100 Subject: [PATCH 1/4] docs(changelog): draft v7.0.0 release notes Expand the 7.0.0 changelog with the merged v7 PRs, organised into the standard Enhancements / Fixes / Deprecations / Compatibility / Codebase Enhancements categories. Headlines the new settings page and editor sidebar overhaul. Remaining items can be added before release. Co-Authored-By: Claude Opus 4.8 --- readme.txt | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/readme.txt b/readme.txt index 202c88af..0d3a1c42 100755 --- a/readme.txt +++ b/readme.txt @@ -83,10 +83,44 @@ Release date: tbc **Enhancements** +* [#520](https://github.com/beyondwords-io/wordpress-plugin/pull/520) New settings page and project-wide rewrite. + * Simplifies the plugin settings — removing many tabs, fields and options — so that audio/video generation and player display are managed from your BeyondWords project settings. + * Standardises the codebase to WordPress VIP coding standards and migrates CI tooling from Yarn to npm. * [#527](https://github.com/beyondwords-io/wordpress-plugin/pull/527) BeyondWords editor redesign for the block and classic editors. * New Content (Source, Script template), Format (Output, Video template, Video size), Voice (Language, Model, Voice) and Player (Embed) settings, available in both editors. * The Player "Embed" setting replaces the "Display player" checkbox — choose "None" to hide the player on a post. -* [#520](https://github.com/beyondwords-io/wordpress-plugin/pull/520) Settings page updates for WordPress v7. +* [#536](https://github.com/beyondwords-io/wordpress-plugin/pull/536) Wire up the Player "Embed" setting. + * The Embed choice (audio/video × post/script) now controls the rendered player, rather than only showing or hiding it. +* [#537](https://github.com/beyondwords-io/wordpress-plugin/pull/537) Opt-in "Customize" voice and language controls. + * A per-post "Customize" toggle (off by default) reveals the Language and Voice pickers; the project's default language is pre-selected when enabled. + * The Voice and Language settings are consolidated into the plugin sidebar. +* [#558](https://github.com/beyondwords-io/wordpress-plugin/pull/558) Reorder the voice picker to Language → Model → Voice. + * "Model" is now a language-level filter that narrows the Voice list. +* [#557](https://github.com/beyondwords-io/wordpress-plugin/pull/557) Preselect "Generate audio" by taxonomy term. + * Reinstates preselecting audio generation for posts assigned specific terms, now across all hierarchical taxonomies and without marking posts as having unsaved changes. +* [#555](https://github.com/beyondwords-io/wordpress-plugin/pull/555) Live player preview for the "Add Player" block. + * The block renders a non-interactive preview of the actual player, or a prompt to generate audio when none exists. +* [#563](https://github.com/beyondwords-io/wordpress-plugin/pull/563) State-reflecting generation labels and "Legacy" model rename. + * The "Generate audio" toggle now reads "Generation enabled" / "Generation disabled"; the "Standard" voice model bucket is relabelled "Legacy". +* [#532](https://github.com/beyondwords-io/wordpress-plugin/pull/532) Cache API reads and defer audio generation on WordPress VIP. + * Editor dropdown data is cached in 15-minute transients; on VIP, audio create/update is deferred to WP-Cron so the save request returns immediately. + +**Fixes** + +* [#540](https://github.com/beyondwords-io/wordpress-plugin/pull/540) Escape the player `onload` attribute to prevent stored XSS via the Content ID. +* [#539](https://github.com/beyondwords-io/wordpress-plugin/pull/539) Add capability checks to the bulk-edit AJAX handler. +* [#541](https://github.com/beyondwords-io/wordpress-plugin/pull/541) Prevent a player SDK error from clobbering saved content on Fetch. +* [#546](https://github.com/beyondwords-io/wordpress-plugin/pull/546) Prevent the classic editor Voice/Model dropdowns breaking on a voices REST error. +* [#545](https://github.com/beyondwords-io/wordpress-plugin/pull/545) Persist settings-validation errors across the save redirect. +* [#554](https://github.com/beyondwords-io/wordpress-plugin/pull/554) Return JSON from the bulk-edit AJAX handler and catch delete errors. +* [#553](https://github.com/beyondwords-io/wordpress-plugin/pull/553) Resolve the post ID in `Content::get_content_without_excluded_blocks`. +* [#552](https://github.com/beyondwords-io/wordpress-plugin/pull/552) Re-check the BeyondWords namespace in an effect to avoid a player init race. +* [#551](https://github.com/beyondwords-io/wordpress-plugin/pull/551) Track live meta for the Inspect panel Remove button. +* [#550](https://github.com/beyondwords-io/wordpress-plugin/pull/550) Coerce non-string API error messages to avoid a fatal `TypeError`. +* [#548](https://github.com/beyondwords-io/wordpress-plugin/pull/548) Guard against undefined post meta in the settings-panel sections. +* [#544](https://github.com/beyondwords-io/wordpress-plugin/pull/544) Prevent a `TypeError` in the deferred audio-generation cron when a post is deleted. +* [#543](https://github.com/beyondwords-io/wordpress-plugin/pull/543) Guard a null languages API result in the classic editor voice select. +* [#542](https://github.com/beyondwords-io/wordpress-plugin/pull/542) Surface a `WP_Error` from `get_content()` instead of a fatal `TypeError`. **Deprecations** @@ -97,10 +131,21 @@ Release date: tbc **Compatibility** * Tested up to WordPress 7.0. -* PHP 8.5 support. +* [#515](https://github.com/beyondwords-io/wordpress-plugin/pull/515) PHP 8.5 support. * Run unit and e2e tests against PHP 8.0 and PHP 8.5 in GitHub Actions. * Bumped `phpVersion` in wp-env to 8.5. +**Codebase Enhancements** + +* [#533](https://github.com/beyondwords-io/wordpress-plugin/pull/533) Fix failing Cypress tests for v7. +* [#538](https://github.com/beyondwords-io/wordpress-plugin/pull/538) Remove the unused `updatePostMeta` util from the Inspect panel. +* [#562](https://github.com/beyondwords-io/wordpress-plugin/pull/562) Re-enable Plugin Check on `plugin-check-action` v1.1.7. +* [#560](https://github.com/beyondwords-io/wordpress-plugin/pull/560) Cancel superseded CI runs via a concurrency group. +* [#516](https://github.com/beyondwords-io/wordpress-plugin/pull/516) Remove `environment` from the GitHub workflows. +* [#517](https://github.com/beyondwords-io/wordpress-plugin/pull/517), [#535](https://github.com/beyondwords-io/wordpress-plugin/pull/535) Update GitHub Actions dependencies. +* [#514](https://github.com/beyondwords-io/wordpress-plugin/pull/514), [#529](https://github.com/beyondwords-io/wordpress-plugin/pull/529), [#534](https://github.com/beyondwords-io/wordpress-plugin/pull/534) Dependency upgrades. +* Various dependency updates to clear Dependabot security warnings. + = 6.3.0 = Release date: 12th April 2026 From dc3efca53c8687b9ca3fb06907ab0e59c0c41f30 Mon Sep 17 00:00:00 2001 From: Stuart McAlpine Date: Mon, 6 Jul 2026 07:56:14 +0100 Subject: [PATCH 2/4] docs(changelog): move 6.x entries to historic changelog.txt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit readme.txt now lists only the current (7.0.0) release; the 6.0.0–6.3.0 entries are relocated to changelog.txt above 5.5.0. Co-Authored-By: Claude Opus 4.8 --- changelog.txt | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++ readme.txt | 127 -------------------------------------------------- 2 files changed, 127 insertions(+), 127 deletions(-) diff --git a/changelog.txt b/changelog.txt index 93c7b0fb..911db058 100755 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,133 @@ **This is a list detailing changes for past BeyondWords releases. For more information about the current release, see readme.txt.** += 6.3.0 = + +Release date: 12th April 2026 + +**Enhancements** + +* [#500](https://github.com/beyondwords-io/wordpress-plugin/pull/500) Editable content ID field. + * Adds a new "Content ID" feature, allowing users to input and fetch audio metadata by Content ID directly from the editor and classic metabox. + +**Codebase Enhancements** + +* Bump BeyondWords Player block `apiVersion` to fix failing Plugin Check jobs in CI. +* Various dependency updates to clear Dependabot security warnings. + += 6.2.0 = + +Release date: 11th March 2026 + +**Enhancements** + +* [#498](https://github.com/beyondwords-io/wordpress-plugin/pull/498) "Generate Audio" component improvements. + * Stability and performance updates for the Generate Audio component in the block editor. + +**Codebase Enhancements** + +* [#474](https://github.com/beyondwords-io/wordpress-plugin/pull/474) Replace Mock API responses with pre_http_request filter. + * Mockoon has been replaced with WordPress HTTP filters, and completely removed. + += 6.1.0 = + +Release date: 2nd March 2026 + +**Fixes** + +* [#483](https://github.com/beyondwords-io/wordpress-plugin/pull/483) and [#494](https://github.com/beyondwords-io/wordpress-plugin/pull/494) Fix reported REST API 404 responses. + * Skip the second `wp_after_insert_post` triggered by Gutenberg's meta box save. + * If the audio update request to our REST API results in a 404 then clear the stale content ID in WordPress and create new audio. + * `hasContent()` guard on `onTrashPost()` / `onDeletePost()` now skips posts without BeyondWords content IDs e.g. revisions. + +**Enhancements** + +* [#481](https://github.com/beyondwords-io/wordpress-plugin/pull/481) Add `$context` param to `beyondwords_player_html` filter. + * Use the `$context` param to enable filtering of the player HTML based on whether it was auto-prepended to `the_content` or added manually using a shortcode. + * This filter can be used to hide only the auto-prepended players, enabling the shortcode to be used effectively in PHP template files. + * Check the [Examples](https://docs.beyondwords.io/docs-and-guides/integrations/wordpress/filters?utm_source=wordpress&utm_medium=referral&utm_campaign=&utm_content=plugin#beyondwords_player_html) in our docs for further information. + += 6.0.4 = + +Release date: 7th January 2026 + +**Fixes** + +* [#477](https://github.com/beyondwords-io/wordpress-plugin/pull/477) Fix `saveErrorMessage()` bug. + * In the error message saving method we were incorrectly checking the integration method for the plugin instead of the post, which may explain a reported problem where unexpected 404 error messages were being saved. + +**Codebase Enhancements** + +* Improve the Cypress test suite by adding more assertions and testing more post statuses. +* Check for `ABSPATH` at the top of all PHP files. + += 6.0.3 = + +Release date: 16th December 2025 + +**Compatibility** + +* [#473](https://github.com/beyondwords-io/wordpress-plugin/pull/473) Reintroduce support for **PHP 8.0**. + += 6.0.2 = + +Release date: 3rd December 2025 + +**Enhancements and Features** + +* [#468](https://github.com/beyondwords-io/wordpress-plugin/pull/468) Tested up to WordPress 6.9. + +**Fixes** + +* [#469](https://github.com/beyondwords-io/wordpress-plugin/pull/469) Add `beyondwords_integration_method` into Inspect Panel copied data. +* [#466](https://github.com/beyondwords-io/wordpress-plugin/pull/466) Removed PHP type hints from methods hooked directly into WordPress `add_action`/`add_filter`. + += 6.0.1 = + +Release date: 26th November 2025 + +**Fixes** + +* [#464](https://github.com/beyondwords-io/wordpress-plugin/pull/464) Use `CoreUtils::getPostMetaKeys` to get all keys for removal. +* [#461](https://github.com/beyondwords-io/wordpress-plugin/pull/461) Accept `null` params from WP Core for `isProtectedMeta`. +* [#460](https://github.com/beyondwords-io/wordpress-plugin/pull/460) Accept a `null` parameter in `getLangCodeFromJsonIfEmpty`. + += 6.0.0 = + +Release date: 10th November 2025 + +**Enhancements and Features** + +* [#449](https://github.com/beyondwords-io/wordpress-plugin/pull/449) Added support for Magic Embed integration within the plugin. + * A new **"Magic Embed"** option has been added under **Content > Integration method** in the plugin settings. + * This option is intended for users working with **page builders such as Elementor**, who may have experienced issues getting the **REST API** to function correctly during initial setup. + * **Enabling Magic Embed** will automatically add the Magic Embed script to each of your posts. + * For correct functionality: + * Magic Embed must be **selected in the WordPress plugin**. + * Magic Embed must also be **[enabled and configured](https://docs.beyondwords.io/docs-and-guides/integrations/magic-embed/overview?utm_source=wordpress&utm_medium=referral&utm_campaign=&utm_content=plugin#setup) in your BeyondWords dashboard**. + * Posts previously created using the **REST API** will continue to use that method. + * Refer to our [Magic Embed documentation](https://docs.beyondwords.io/docs-and-guides/integrations/magic-embed/overview?utm_source=wordpress&utm_medium=referral&utm_campaign=&utm_content=plugin) for more information. + +***If your plugin is already working as expected with the REST API, we recommend continuing to use that integration.*** + +**Fixes** + +* [#457](https://github.com/beyondwords-io/wordpress-plugin/pull/457) Removed segment marker assignment. + * Fixes a reported JS issue where the block editor "+" button was not being displayed. + +**Code Coverage** + +* [#455](https://github.com/beyondwords-io/wordpress-plugin/pull/455) Increased PHPUnit test coverage. + +**Refactoring** + +* [#454](https://github.com/beyondwords-io/wordpress-plugin/pull/454) PHP type declarations. +* [#447](https://github.com/beyondwords-io/wordpress-plugin/pull/447) Make PHP methods static. + +**Compatibility** + +* ~~**PHP 8.1** is now our minimum supported version.~~ + = 5.5.0 = Release date: 2nd July 2025 diff --git a/readme.txt b/readme.txt index 0d3a1c42..51e33224 100755 --- a/readme.txt +++ b/readme.txt @@ -146,133 +146,6 @@ Release date: tbc * [#514](https://github.com/beyondwords-io/wordpress-plugin/pull/514), [#529](https://github.com/beyondwords-io/wordpress-plugin/pull/529), [#534](https://github.com/beyondwords-io/wordpress-plugin/pull/534) Dependency upgrades. * Various dependency updates to clear Dependabot security warnings. -= 6.3.0 = - -Release date: 12th April 2026 - -**Enhancements** - -* [#500](https://github.com/beyondwords-io/wordpress-plugin/pull/500) Editable content ID field. - * Adds a new "Content ID" feature, allowing users to input and fetch audio metadata by Content ID directly from the editor and classic metabox. - -**Codebase Enhancements** - -* Bump BeyondWords Player block `apiVersion` to fix failing Plugin Check jobs in CI. -* Various dependency updates to clear Dependabot security warnings. - -= 6.2.0 = - -Release date: 11th March 2026 - -**Enhancements** - -* [#498](https://github.com/beyondwords-io/wordpress-plugin/pull/498) "Generate Audio" component improvements. - * Stability and performance updates for the Generate Audio component in the block editor. - -**Codebase Enhancements** - -* [#474](https://github.com/beyondwords-io/wordpress-plugin/pull/474) Replace Mock API responses with pre_http_request filter. - * Mockoon has been replaced with WordPress HTTP filters, and completely removed. - -= 6.1.0 = - -Release date: 2nd March 2026 - -**Fixes** - -* [#483](https://github.com/beyondwords-io/wordpress-plugin/pull/483) and [#494](https://github.com/beyondwords-io/wordpress-plugin/pull/494) Fix reported REST API 404 responses. - * Skip the second `wp_after_insert_post` triggered by Gutenberg's meta box save. - * If the audio update request to our REST API results in a 404 then clear the stale content ID in WordPress and create new audio. - * `hasContent()` guard on `onTrashPost()` / `onDeletePost()` now skips posts without BeyondWords content IDs e.g. revisions. - -**Enhancements** - -* [#481](https://github.com/beyondwords-io/wordpress-plugin/pull/481) Add `$context` param to `beyondwords_player_html` filter. - * Use the `$context` param to enable filtering of the player HTML based on whether it was auto-prepended to `the_content` or added manually using a shortcode. - * This filter can be used to hide only the auto-prepended players, enabling the shortcode to be used effectively in PHP template files. - * Check the [Examples](https://docs.beyondwords.io/docs-and-guides/integrations/wordpress/filters?utm_source=wordpress&utm_medium=referral&utm_campaign=&utm_content=plugin#beyondwords_player_html) in our docs for further information. - -= 6.0.4 = - -Release date: 7th January 2026 - -**Fixes** - -* [#477](https://github.com/beyondwords-io/wordpress-plugin/pull/477) Fix `saveErrorMessage()` bug. - * In the error message saving method we were incorrectly checking the integration method for the plugin instead of the post, which may explain a reported problem where unexpected 404 error messages were being saved. - -**Codebase Enhancements** - -* Improve the Cypress test suite by adding more assertions and testing more post statuses. -* Check for `ABSPATH` at the top of all PHP files. - -= 6.0.3 = - -Release date: 16th December 2025 - -**Compatibility** - -* [#473](https://github.com/beyondwords-io/wordpress-plugin/pull/473) Reintroduce support for **PHP 8.0**. - -= 6.0.2 = - -Release date: 3rd December 2025 - -**Enhancements and Features** - -* [#468](https://github.com/beyondwords-io/wordpress-plugin/pull/468) Tested up to WordPress 6.9. - -**Fixes** - -* [#469](https://github.com/beyondwords-io/wordpress-plugin/pull/469) Add `beyondwords_integration_method` into Inspect Panel copied data. -* [#466](https://github.com/beyondwords-io/wordpress-plugin/pull/466) Removed PHP type hints from methods hooked directly into WordPress `add_action`/`add_filter`. - -= 6.0.1 = - -Release date: 26th November 2025 - -**Fixes** - -* [#464](https://github.com/beyondwords-io/wordpress-plugin/pull/464) Use `CoreUtils::getPostMetaKeys` to get all keys for removal. -* [#461](https://github.com/beyondwords-io/wordpress-plugin/pull/461) Accept `null` params from WP Core for `isProtectedMeta`. -* [#460](https://github.com/beyondwords-io/wordpress-plugin/pull/460) Accept a `null` parameter in `getLangCodeFromJsonIfEmpty`. - -= 6.0.0 = - -Release date: 10th November 2025 - -**Enhancements and Features** - -* [#449](https://github.com/beyondwords-io/wordpress-plugin/pull/449) Added support for Magic Embed integration within the plugin. - * A new **"Magic Embed"** option has been added under **Content > Integration method** in the plugin settings. - * This option is intended for users working with **page builders such as Elementor**, who may have experienced issues getting the **REST API** to function correctly during initial setup. - * **Enabling Magic Embed** will automatically add the Magic Embed script to each of your posts. - * For correct functionality: - * Magic Embed must be **selected in the WordPress plugin**. - * Magic Embed must also be **[enabled and configured](https://docs.beyondwords.io/docs-and-guides/integrations/magic-embed/overview?utm_source=wordpress&utm_medium=referral&utm_campaign=&utm_content=plugin#setup) in your BeyondWords dashboard**. - * Posts previously created using the **REST API** will continue to use that method. - * Refer to our [Magic Embed documentation](https://docs.beyondwords.io/docs-and-guides/integrations/magic-embed/overview?utm_source=wordpress&utm_medium=referral&utm_campaign=&utm_content=plugin) for more information. - -***If your plugin is already working as expected with the REST API, we recommend continuing to use that integration.*** - -**Fixes** - -* [#457](https://github.com/beyondwords-io/wordpress-plugin/pull/457) Removed segment marker assignment. - * Fixes a reported JS issue where the block editor "+" button was not being displayed. - -**Code Coverage** - -* [#455](https://github.com/beyondwords-io/wordpress-plugin/pull/455) Increased PHPUnit test coverage. - -**Refactoring** - -* [#454](https://github.com/beyondwords-io/wordpress-plugin/pull/454) PHP type declarations. -* [#447](https://github.com/beyondwords-io/wordpress-plugin/pull/447) Make PHP methods static. - -**Compatibility** - -* ~~**PHP 8.1** is now our minimum supported version.~~ - -------- [See the previous changelogs here](https://plugins.trac.wordpress.org/browser/speechkit/trunk/changelog.txt). From 41b57e8625508da8e5869444eb216a53fe5e959a Mon Sep 17 00:00:00 2001 From: Stuart McAlpine Date: Mon, 6 Jul 2026 07:58:21 +0100 Subject: [PATCH 3/4] chore: bump version to 7.0.0-beta.1; add #564 to changelog - Bump version across speechkit.php, package.json, package-lock.json and the readme.txt stable tag to 7.0.0-beta.1 (semver pre-release). - Add the #564 video_settings fix to the 7.0.0 changelog (merges before this branch). - Update the AGENTS.md pre-release version-convention note. Co-Authored-By: Claude Opus 4.8 --- AGENTS.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- readme.txt | 4 +++- speechkit.php | 4 ++-- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 9f12d00a..ac166915 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -281,7 +281,7 @@ Plugin version lives in two places — keep them in sync: - `BEYONDWORDS__PLUGIN_VERSION` constant in the same file - `version` in [package.json](package.json) (informational; npm publish is not used) -Bump on any release. Pre-release versions use `7.0.0-dev-3.0` style (matches existing convention). +Bump on any release. Pre-release versions use semver pre-release identifiers, e.g. `7.0.0-beta.1`. ## Known issues diff --git a/package-lock.json b/package-lock.json index 4d867315..2f014ac7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "beyondwords-wordpress-plugin", - "version": "7.0.0-dev-3.0", + "version": "7.0.0-beta.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "beyondwords-wordpress-plugin", - "version": "7.0.0-dev-3.0", + "version": "7.0.0-beta.1", "license": "MIT", "devDependencies": { "@wordpress/api-fetch": "^7.47.0", diff --git a/package.json b/package.json index 782a611a..4f65ea58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "beyondwords-wordpress-plugin", - "version": "7.0.0-dev-3.0", + "version": "7.0.0-beta.1", "private": true, "description": "BeyondWords WordPress Plugin", "repository": { diff --git a/readme.txt b/readme.txt index 51e33224..7901c041 100755 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: beyondwords, stuartmcalpine Donate link: https://beyondwords.io Tags: text-to-speech, tts, audio, AI, voice cloning -Stable tag: 7.0.0-dev-3.0 +Stable tag: 7.0.0-beta.1 Requires at least: 5.9 Requires PHP: 8.0 Tested up to: 7.0 @@ -107,6 +107,8 @@ Release date: tbc **Fixes** +* [#564](https://github.com/beyondwords-io/wordpress-plugin/pull/564) Send the full `video_settings` payload so videos generate. + * Selecting "Video" or "Audio + video" output now sends the complete video settings (seeded from the project defaults), fixing posts that produced no video. * [#540](https://github.com/beyondwords-io/wordpress-plugin/pull/540) Escape the player `onload` attribute to prevent stored XSS via the Content ID. * [#539](https://github.com/beyondwords-io/wordpress-plugin/pull/539) Add capability checks to the bulk-edit AJAX handler. * [#541](https://github.com/beyondwords-io/wordpress-plugin/pull/541) Prevent a player SDK error from clobbering saved content on Fetch. diff --git a/speechkit.php b/speechkit.php index 5a2bb0a9..cf6580f0 100755 --- a/speechkit.php +++ b/speechkit.php @@ -15,7 +15,7 @@ * Description: The effortless way to make content listenable. Automatically create audio versions and embed via our customizable player. * Author: BeyondWords * Author URI: https://beyondwords.io - * Version: 7.0.0-dev-3.0 + * Version: 7.0.0-beta.1 * License: GPL-2.0+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt * Text Domain: speechkit @@ -32,7 +32,7 @@ // Define constants // phpcs:disable -define('BEYONDWORDS__PLUGIN_VERSION', '7.0.0-dev-3.0'); +define('BEYONDWORDS__PLUGIN_VERSION', '7.0.0-beta.1'); define('BEYONDWORDS__PLUGIN_DIR', plugin_dir_path(__FILE__)); define('BEYONDWORDS__PLUGIN_URI', plugin_dir_url(__FILE__)); // phpcs:enable From c1b38b938542fe6f300d26da638b08af509452df Mon Sep 17 00:00:00 2001 From: Stuart McAlpine Date: Mon, 6 Jul 2026 08:07:29 +0100 Subject: [PATCH 4/4] build: add scripts/bump-version.sh to set the version in one command Bumping the plugin version meant hand-editing five places (speechkit.php header + constant, package.json, package-lock.json, readme.txt stable tag), which drifts easily. This script takes a semver version, validates it, updates every location (JSON edited via node so only the plugin's own version fields change), and verifies each one before finishing. Document it in AGENTS.md as the required way to bump the version, so every agent session uses it instead of editing by hand. Co-Authored-By: Claude Opus 4.8 --- AGENTS.md | 14 ++++- scripts/bump-version.sh | 130 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100755 scripts/bump-version.sh diff --git a/AGENTS.md b/AGENTS.md index ac166915..aa77a904 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -275,13 +275,25 @@ Source: `tests/cypress/e2e/` — same delete-when-the-UI-is-removed rule. (Detai ## Versioning -Plugin version lives in two places — keep them in sync: +**Always bump the version with the script — never edit the version by hand:** + +```sh +scripts/bump-version.sh 7.0.0-beta.1 +``` + +It sets the version everywhere it lives (and verifies each one), then you review +the diff and commit. It does not commit, tag, or touch the changelog. + +The version lives in five places, all kept in sync by the script: - [speechkit.php](speechkit.php) plugin header `Version:` line - `BEYONDWORDS__PLUGIN_VERSION` constant in the same file - `version` in [package.json](package.json) (informational; npm publish is not used) +- root `version` and `packages[""].version` in [package-lock.json](package-lock.json) +- `Stable tag:` in [readme.txt](readme.txt) Bump on any release. Pre-release versions use semver pre-release identifiers, e.g. `7.0.0-beta.1`. +If you add a new place the version needs to appear, update [scripts/bump-version.sh](scripts/bump-version.sh) too. ## Known issues diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh new file mode 100755 index 00000000..74eb672b --- /dev/null +++ b/scripts/bump-version.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +# +# bump-version.sh — set the plugin version in every place it lives, in one command. +# +# Usage: +# scripts/bump-version.sh +# +# Example: +# scripts/bump-version.sh 7.0.0-beta.1 +# scripts/bump-version.sh 7.0.0 +# +# Updates, atomically-ish (all-or-nothing after validation): +# - speechkit.php plugin header `Version:` line +# - speechkit.php BEYONDWORDS__PLUGIN_VERSION constant +# - package.json "version" +# - package-lock.json root "version" and packages[""]."version" +# - readme.txt "Stable tag:" +# +# It does NOT touch the changelog headings (those are curated by hand) and does +# not create a git commit or tag — run it, review the diff, then commit. + +set -euo pipefail + +# --- locate the repo root relative to this script, so it works from any cwd --- +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT" + +SPEECHKIT="speechkit.php" +PACKAGE_JSON="package.json" +PACKAGE_LOCK="package-lock.json" +README="readme.txt" + +usage() { + cat >&2 < + + Semver, with optional pre-release/build metadata. + e.g. 7.0.0 · 7.0.0-beta.1 · 7.1.0-rc.2 + +Sets the version in speechkit.php (header + constant), package.json, +package-lock.json and the readme.txt stable tag. Review the diff, then commit. +EOF + exit 2 +} + +die() { echo "bump-version: error: $*" >&2; exit 1; } + +# --- args ------------------------------------------------------------------- +[ $# -eq 1 ] || usage +NEW="$1" + +case "$NEW" in + -h|--help) usage ;; +esac + +# Semver: MAJOR.MINOR.PATCH with optional -prerelease and +build (dot-separated +# alphanumeric identifiers). Rejects a leading "v", trailing spaces, etc. +if ! printf '%s' "$NEW" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z]+(\.[0-9A-Za-z]+)*)?(\+[0-9A-Za-z]+(\.[0-9A-Za-z]+)*)?$'; then + die "'$NEW' is not a valid semver version (expected e.g. 7.0.0 or 7.0.0-beta.1)" +fi + +# --- preflight: required tools and files ------------------------------------ +command -v node >/dev/null 2>&1 || die "node is required (used to edit the JSON files safely)" +command -v perl >/dev/null 2>&1 || die "perl is required" +for f in "$SPEECHKIT" "$PACKAGE_JSON" "$PACKAGE_LOCK" "$README"; do + [ -f "$f" ] || die "expected file not found: $f (is the repo layout as expected?)" +done + +# --- current canonical version (from the plugin constant) ------------------- +OLD="$(perl -ne "print \$1 if /BEYONDWORDS__PLUGIN_VERSION\x27\s*,\s*\x27([^\x27]*)\x27/" "$SPEECHKIT")" +[ -n "$OLD" ] || die "could not read the current version from $SPEECHKIT" + +if [ "$OLD" = "$NEW" ]; then + echo "bump-version: already at $NEW — nothing to do." + exit 0 +fi + +echo "bump-version: $OLD -> $NEW" + +# --- edit speechkit.php: header line + constant ----------------------------- +NEW="$NEW" perl -i -pe 's{^(\s*\*\s*Version:\s*)\S+}{$1$ENV{NEW}}' "$SPEECHKIT" +NEW="$NEW" perl -i -pe 's{(BEYONDWORDS__PLUGIN_VERSION\x27\s*,\s*\x27)[^\x27]*}{$1$ENV{NEW}}' "$SPEECHKIT" + +# --- edit readme.txt: Stable tag -------------------------------------------- +NEW="$NEW" perl -i -pe 's{^(Stable tag:\s*)\S+}{$1$ENV{NEW}}' "$README" + +# --- edit package.json + package-lock.json via node (targeted, keeps format) - +# Editing the exact JSON paths avoids clobbering any dependency's "version". +NEW="$NEW" node -e ' + const fs = require("fs"); + const v = process.env.NEW; + const edits = [ + ["package.json", (j) => { j.version = v; }], + ["package-lock.json", (j) => { + j.version = v; + if (j.packages && j.packages[""]) j.packages[""].version = v; + }], + ]; + for (const [path, apply] of edits) { + const json = JSON.parse(fs.readFileSync(path, "utf8")); + apply(json); + fs.writeFileSync(path, JSON.stringify(json, null, 2) + "\n"); + } +' + +# --- verify every location now reads NEW ------------------------------------ +declare -a checks=( + "speechkit.php (header)|$(perl -ne 'print $1 if /^\s*\*\s*Version:\s*(\S+)/' "$SPEECHKIT")" + "speechkit.php (constant)|$(perl -ne "print \$1 if /BEYONDWORDS__PLUGIN_VERSION\x27\s*,\s*\x27([^\x27]*)\x27/" "$SPEECHKIT")" + "package.json|$(node -p "require('$ROOT/package.json').version")" + "package-lock.json (root)|$(node -p "require('$ROOT/package-lock.json').version")" + "package-lock.json (packages)|$(node -p "require('$ROOT/package-lock.json').packages[''].version")" + "readme.txt (Stable tag)|$(perl -ne 'print $1 if /^Stable tag:\s*(\S+)/' "$README")" +) + +failed=0 +for entry in "${checks[@]}"; do + label="${entry%%|*}" + got="${entry#*|}" + if [ "$got" = "$NEW" ]; then + printf ' ok %-32s %s\n' "$label" "$got" + else + printf ' FAIL %-32s got "%s" (expected "%s")\n' "$label" "$got" "$NEW" >&2 + failed=1 + fi +done + +[ "$failed" -eq 0 ] || die "one or more files did not update — review the diff and re-run" + +echo "bump-version: done. Review 'git diff' and commit."