From 3707e14377514d95c86d09ebad2801845fd5d6f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eW=C9=98yn?= <5607939+Llewellynvdm@users.noreply.github.com> Date: Mon, 28 Sep 2026 18:40:51 +0200 Subject: [PATCH 1/2] Correct plugin release metadata and first-package instructions --- AGENTS.md | 2 +- CHANGELOG.md | 6 ++++++ docs/IMPLEMENTATION.md | 4 +++- docs/RELEASE.md | 10 ++++++++-- joomengine_mcp_changelog.xml | 5 +++++ tests/release.php | 31 ++++++++++++++++++++++++++++++- tools/release.php | 18 ++++++++++++++++-- 7 files changed, 69 insertions(+), 7 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 0e3aca1..273a0c4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,7 +6,7 @@ The migration PR #1 has been merged. Branch new work from current `main`, or con Use element `joomengine_mcp`, group `console`, namespace `VDM\Plugin\Console\JoomEngineMcp`; dependency `com_joomengine_mcp`, namespace `VDM\Component\JoomEngineMcp`. Joomla 6 native plugin/event/DI/console contracts are authoritative. Follow JCB's plugin-root manifest/installer/services/src/language/update layout. PHP style authority: https://github.com/extension-builder/joomla/blob/main/docs/development/php-code-style.md (tabs, LF, Allman braces, explicit typed properties/constructor injection, meaningful docblocks, no closing tags or isolated strict_types/promotion/readonly changes). Preserve inherited signatures. -External Composer client and remote stdio bridge belong only to `joomengine/mcp_client`, package `joomengine/mcp-client`. Do not implement or depend on them here. The component owns HTTP routing glue, catalogue/schema resolution, business handlers, permissions/plans, jobs/artifacts, verification and audit. The plugin supplies local entry and adaptation only. +External Composer client and remote stdio bridge belong only to `joomengine/mcp_client`, package `joomengine/mcp-client`. Do not implement or depend on them here. The independent `joomengine/mcp_webservices` plugin owns HTTP routing. The component owns catalogue/schema resolution, business handlers, permissions/plans, jobs/artifacts, verification and audit. This console plugin supplies local entry and adaptation only. Only the real console application under CLI can establish server-owner authority. JSON, headers, tokens and database rows cannot do so. Local requests still validate inputs and bindings and retain audit/recovery; HTTP-originated jobs never acquire unrestricted authority just because a local worker executes them. diff --git a/CHANGELOG.md b/CHANGELOG.md index f59e8d8..52b2b4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## [[[NEXT_VERSION]]] +### Fix + +- Publish the native Joomla information URL and explicit site client in console update entries. +- Reject reused changelog versions, misplaced pending markers and update entries for unprepared future versions without changing release files. + ### Addition - Add a manual next-version release workflow that freezes both changelogs, creates an immutable tag, updates the native Joomla feed and waits for OctoShoom to commit its checksum. @@ -22,6 +27,7 @@ - Install the compatible component before the console plugin. The plugin release does not invoke OctoJPack. - Configure the six git-user secrets documented in docs/RELEASE.md before releasing. +- Complete both plugin release workflows before running the component workflow to publish the first combined package. ## 0.1.0 — development baseline diff --git a/docs/IMPLEMENTATION.md b/docs/IMPLEMENTATION.md index 5c10b80..162c86c 100644 --- a/docs/IMPLEMENTATION.md +++ b/docs/IMPLEMENTATION.md @@ -2,7 +2,7 @@ ## Branch -The migration [PR #1](https://github.com/joomengine/mcp_plugin/pull/1) is merged. Source-installation and release realignment is on `fix/octo-release-workflow`; the [component acceptance checklist](https://github.com/joomengine/mcp_component/pull/1#issuecomment-5732685349) tracks coordinated Joomla/JCB execution evidence. +The migration [PR #1](https://github.com/joomengine/mcp_plugin/pull/1) is merged. First-package release readiness is on `fix/first-package-release`; the [component acceptance checklist](https://github.com/joomengine/mcp_component/pull/1#issuecomment-5732685349) tracks coordinated Joomla/JCB execution evidence. Plugin version 0.1.0 requires component version 0.1.1 or later within the same major version, because the explicit JCB synchronization operation is part of that runtime contract. @@ -42,4 +42,6 @@ Installed CI uses the component's main branch by default; configuration and reus The simplified release support passes actionlint, PHP 8.3 syntax checks, 13 isolated metadata checks, and the source manifest/language/installation-completeness checks. These checks do not exercise publication credentials or replace the installed runtime evidence above. +The first-package readiness changes pass 18 isolated release metadata checks and the source manifest/language/installation-completeness checks on PHP 8.3.6. These include native feed identity/information, rejection without file changes for reused or unprepared versions and misplaced pending markers, and checksum preservation across retries and successive releases. Runtime code is unchanged. Release instructions now cover both independent plugin workflows before the component's package release; actual publication still requires running those workflows with configured credentials. + The component golden-image suite exercises shared JCB operations, native options/dependencies, persisted read-back, generated/install artifacts, state isolation, long jobs/cancellation/recovery and cleanup. Each result belongs to its recorded component/JCB/plugin revisions. The linked PR and acceptance checklist are authoritative for current completion; historical runs do not certify later runtime changes. External-client interoperability is tracked in `mcp_client` and the coordinated component suite. Review/merge and deliberate release publication remain separate actions. diff --git a/docs/RELEASE.md b/docs/RELEASE.md index af3f8c8..65de7d7 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -4,13 +4,19 @@ The repository source ZIP installs directly into Joomla after the compatible com ## Release a version -Open Actions → **Release console plugin with OctoShoom**, select `main`, and enter the next version, such as `1.2.3`. A `v` prefix is optional. +Open Actions → **Release console plugin with OctoShoom** → **Run workflow**, select `main`, and enter an unused next version. A `v` prefix is optional. For the first package, `0.1.2` is an example that is newer than the development baselines across all three extension repositories; the workflow input chooses the actual release version. The workflow uses [git-user](https://github.com/octoleo/git-user#workflows) to configure Git authentication and signing. Its small metadata step freezes `[[[NEXT_VERSION]]]` in both changelogs, updates the manifest version/date, commits and tags the source, then adds the tagged ZIP to `joomengine_mcp_update_server.xml`. It calls the [OctoShoom action](https://github.com/octoleo/octoshoom#quick-start) directly to hash the downloads and commit the update feed. Repository `joomengine/mcp_plugin`, branch `main` and the update-feed path are fixed in the workflow. OctoShoom inherits the Git identity and authentication from git-user. Existing tags and feed entries are left unchanged when rerunning the same version. -The plugin workflow stops after OctoShoom. Release the plugin before the component; OctoJPack reads the component's standalone `.octojpack` configuration and selects the latest plugin tag for the combined package. +The plugin workflow stops after OctoShoom. To create the first combined package: + +1. Run this console plugin's release workflow and wait for it to succeed. +2. In `joomengine/mcp_webservices`, use **Actions → Run workflow** to release the webservices plugin and wait for it to succeed. The two plugin releases may run independently. +3. In `joomengine/mcp_component`, run the component release workflow. OctoJPack reads its standalone `.octojpack`, selects the latest plugin tags, and publishes the package at the component version. The component workflow then updates the package feed and runs OctoShoom. + +These workflows start through **Run workflow**; pushing a tag alone does not trigger them. Both plugins must have a published tag before the component release can assemble the package. ## GitHub secrets diff --git a/joomengine_mcp_changelog.xml b/joomengine_mcp_changelog.xml index cb4c9e6..260dc81 100644 --- a/joomengine_mcp_changelog.xml +++ b/joomengine_mcp_changelog.xml @@ -5,6 +5,10 @@ plugin console [[[NEXT_VERSION]]] + + Publish the native Joomla information URL and explicit site client in console update entries. + Reject reused changelog versions, misplaced pending markers and update entries for unprepared future versions without changing release files. + Add manual version releases with changelog freezing, immutable tags, Joomla update entries and synchronous OctoShoom checksums. Add a categorized Joomla changelog and document GitHub secrets and agent responsibilities. @@ -21,6 +25,7 @@ Install the compatible component first. The plugin release never invokes OctoJPack. Configure the six git-user secrets documented in docs/RELEASE.md before releasing. + Complete both plugin release workflows before running the component workflow to publish the first combined package. diff --git a/tests/release.php b/tests/release.php index 56d4efc..abd06ac 100644 --- a/tests/release.php +++ b/tests/release.php @@ -26,10 +26,36 @@ . '[[[NEXT_VERSION]]]Release metadata.'; file_put_contents($root . '/joomengine_mcp.xml', '' . '1.0.0January 2026'); - file_put_contents($root . '/joomengine_mcp_changelog.xml', $pending); + $initialChangelog = str_replace('', 'joomengine_mcp' + . 'pluginconsole1.0.0' + . 'Development baseline.', $pending); + file_put_contents($root . '/joomengine_mcp_changelog.xml', $initialChangelog); file_put_contents($root . '/CHANGELOG.md', "# Changelog\n\n## [[[NEXT_VERSION]]]\n\n### Fix\n\n- Release metadata.\n"); file_put_contents($root . '/joomengine_mcp_update_server.xml', ''); + $rejectUnchanged = static function (array $arguments, string $message) use ($root, $check): void + { + $before = array_map('file_get_contents', glob($root . '/*')); + $rejected = false; + + try + { + mcpRelease($arguments, $root); + } + catch (RuntimeException) + { + $rejected = true; + } + + $check($rejected && $before === array_map('file_get_contents', glob($root . '/*')), $message); + }; + $rejectUnchanged(['prepare', '1.0.0'], 'A baseline already in the XML changelog cannot be released again.'); + $rejectUnchanged(['feed', '1.1.0'], 'An unprepared future version cannot change the feed.'); + file_put_contents($root . '/joomengine_mcp_changelog.xml', str_replace('[[[NEXT_VERSION]]]', + '1.0.1[[[NEXT_VERSION]]]', $initialChangelog)); + $rejectUnchanged(['prepare', '1.1.0'], 'A marker outside the XML version cannot freeze a release.'); + file_put_contents($root . '/joomengine_mcp_changelog.xml', $initialChangelog); + $originalFeed = file_get_contents($root . '/joomengine_mcp_update_server.xml'); mcpRelease(['prepare', 'v1.1.0'], $root); $manifest = mcpReleaseXml($root . '/joomengine_mcp.xml'); @@ -45,6 +71,9 @@ $check($query->evaluate('string(/updates/update[version="1.1.0"]/downloads/downloadurl)') === 'https://github.com/joomengine/mcp_plugin/archive/refs/tags/v1.1.0.zip', 'Feed downloads the immutable source tag.'); $check($query->evaluate('string(/updates/update[version="1.1.0"]/folder)') === 'console', 'Feed identifies the console plugin.'); + $check($query->evaluate('string(/updates/update[version="1.1.0"]/client)') === 'site', 'Feed matches the installed plugin client.'); + $check($query->evaluate('string(/updates/update[version="1.1.0"]/infourl)') + === 'https://github.com/joomengine/mcp_plugin/tree/v1.1.0', 'Feed exposes release information through the native Joomla field.'); $check($query->query('/updates/update[version="1.1.0"]/sha512')->length === 0, 'Checksum generation belongs to OctoShoom.'); mcpReleaseAppend($feed->documentElement->firstChild, 'sha512', str_repeat('a', 128)); $feed->save($root . '/joomengine_mcp_update_server.xml'); diff --git a/tools/release.php b/tools/release.php index e304c82..abb807c 100644 --- a/tools/release.php +++ b/tools/release.php @@ -49,6 +49,14 @@ function mcpRelease(array $arguments, string $root): void if ($command === 'prepare') { + $changelog = new DOMXPath(mcpReleaseXml($root . '/joomengine_mcp_changelog.xml')); + + if ($changelog->query('/changelogs/changelog[version="' . $version . '"]')->length !== 0 + || $changelog->query('/changelogs/changelog[version="[[[NEXT_VERSION]]]"]')->length !== 1) + { + throw new RuntimeException('Choose an unreleased version with exactly one pending XML changelog version.'); + } + foreach (['CHANGELOG.md', 'joomengine_mcp_changelog.xml'] as $path) { $contents = file_get_contents($root . '/' . $path); @@ -68,6 +76,11 @@ function mcpRelease(array $arguments, string $root): void } else { + if (version_compare($version, $manifestVersion->textContent, '>')) + { + throw new RuntimeException('Prepare the plugin version before adding its update entry.'); + } + $feed = mcpReleaseXml($root . '/joomengine_mcp_update_server.xml'); if ((new DOMXPath($feed))->query('/updates/update[version="' . $version . '"]')->length > 0) @@ -79,7 +92,8 @@ function mcpRelease(array $arguments, string $root): void $feed->documentElement->insertBefore($entry, $feed->documentElement->firstChild); foreach (['name' => 'JoomEngine MCP Console', 'description' => 'JoomEngine MCP console plugin.', - 'element' => 'joomengine_mcp', 'type' => 'plugin', 'version' => $version, 'folder' => 'console'] as $name => $value) + 'element' => 'joomengine_mcp', 'type' => 'plugin', 'version' => $version, 'folder' => 'console', + 'client' => 'site'] as $name => $value) { mcpReleaseAppend($entry, $name, $value); } @@ -93,7 +107,7 @@ function mcpRelease(array $arguments, string $root): void $platform->setAttribute('name', 'joomla'); $platform->setAttribute('version', '6\\.[1-9][0-9]*'); mcpReleaseAppend($entry, 'php_minimum', '8.3.0'); - mcpReleaseAppend($entry, 'detailsurl', 'https://github.com/joomengine/mcp_plugin/tree/v' . $version); + mcpReleaseAppend($entry, 'infourl', 'https://github.com/joomengine/mcp_plugin/tree/v' . $version); mcpReleaseAppend($entry, 'changelogurl', 'https://raw.githubusercontent.com/joomengine/mcp_plugin/main/joomengine_mcp_changelog.xml'); $writes['joomengine_mcp_update_server.xml'] = $feed->saveXML(); } From 6e45707ac228a8e3854b745ac54afb744d10db59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eW=C9=98yn?= <5607939+Llewellynvdm@users.noreply.github.com> Date: Mon, 28 Sep 2026 18:44:18 +0200 Subject: [PATCH 2/2] Install the independent webservices plugin in console CI --- .github/workflows/installed.yml | 8 ++++++++ CHANGELOG.md | 1 + joomengine_mcp_changelog.xml | 1 + 3 files changed, 10 insertions(+) diff --git a/.github/workflows/installed.yml b/.github/workflows/installed.yml index fa84fcf..946cc93 100644 --- a/.github/workflows/installed.yml +++ b/.github/workflows/installed.yml @@ -64,6 +64,13 @@ jobs: ref: ${{ steps.component.outputs.ref }} path: component persist-credentials: false + - name: Check out the independent webservices plugin + uses: actions/checkout@v7 + with: + repository: joomengine/mcp_webservices + ref: 94fd2a2b4ef802e1deef1050563cca2c0d879e1f + path: webservices + persist-credentials: false - uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} @@ -75,6 +82,7 @@ jobs: MCP_TEST_ALLOW_DESTRUCTIVE: '1' JOOMLA_ROOT: ${{ runner.temp }}/joomla MCP_PLUGIN_SOURCE: ${{ github.workspace }}/plugin + MCP_WEBSERVICES_SOURCE: ${{ github.workspace }}/webservices MCP_TEST_DB_TYPE: mysqli MCP_TEST_DB_HOST: 127.0.0.1:3306 MCP_TEST_DB_USER: mcp_test diff --git a/CHANGELOG.md b/CHANGELOG.md index 52b2b4a..60e9d8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fix +- Check out the independent webservices plugin for the shared installed Joomla tests after its extraction from the component. - Publish the native Joomla information URL and explicit site client in console update entries. - Reject reused changelog versions, misplaced pending markers and update entries for unprepared future versions without changing release files. diff --git a/joomengine_mcp_changelog.xml b/joomengine_mcp_changelog.xml index 260dc81..9370e7c 100644 --- a/joomengine_mcp_changelog.xml +++ b/joomengine_mcp_changelog.xml @@ -6,6 +6,7 @@ console [[[NEXT_VERSION]]] + Check out the independent webservices plugin for the shared installed Joomla tests after its extraction from the component. Publish the native Joomla information URL and explicit site client in console update entries. Reject reused changelog versions, misplaced pending markers and update entries for unprepared future versions without changing release files.