Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 10 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: PHP console plugin
on:
pull_request:
push:
branches: [main, feature/jcb-mcp-runtime]
branches: [main]

permissions:
contents: read
Expand All @@ -13,7 +13,7 @@ concurrency:
cancel-in-progress: true

jobs:
package:
source:
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
Expand All @@ -31,14 +31,18 @@ jobs:
coverage: none
- name: PHP syntax
run: find . -type f -name '*.php' -not -path './vendor/*' -print0 | xargs -0 -n1 php -l
- name: Manifest and reproducible package contracts
- name: Downloaded source ZIP and release contracts
run: |
php tests/run.php
source_archive="$(mktemp -d)"
trap 'rm -rf -- "$source_archive"' EXIT
git archive --format=zip --prefix=mcp_plugin/ --output="$source_archive/source.zip" HEAD
unzip -q "$source_archive/source.zip" -d "$source_archive/extracted"
php "$source_archive/extracted/mcp_plugin/tests/run.php"
php tests/release.php
- uses: actions/checkout@v7
with:
repository: joomengine/mcp_component
ref: feature/jcb-mcp-runtime
repository: ${{ vars.MCP_COMPONENT_REPOSITORY || 'joomengine/mcp_component' }}
ref: ${{ vars.MCP_COMPONENT_REF || 'main' }}
path: build/component-contract
persist-credentials: false
- name: Native Joomla console registration and runtime contracts
Expand All @@ -48,12 +52,3 @@ jobs:
run: |
bash tests/prepare-native.sh
php tests/native.php
- uses: actions/upload-artifact@v7
if: matrix.php == '8.3'
with:
name: console-plugin-development-package
path: |
build/plg_console_joomengine_mcp-*.zip
build/plg_console_joomengine_mcp-*.zip.sha256
if-no-files-found: error
retention-days: 7
32 changes: 21 additions & 11 deletions .github/workflows/installed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ on:
inputs:
component_ref:
type: string
default: main
pull_request:
push:
branches: [main, feature/jcb-mcp-runtime]
branches: [main]

permissions:
contents: read
Expand Down Expand Up @@ -42,24 +41,35 @@ jobs:
with:
path: plugin
persist-credentials: false
- name: Select the matching component revision
id: component
env:
COMPONENT_REPOSITORY: ${{ vars.MCP_COMPONENT_REPOSITORY || 'joomengine/mcp_component' }}
COMPONENT_REF: ${{ inputs.component_ref || vars.MCP_COMPONENT_REF }}
CANDIDATE_REF: ${{ github.head_ref || github.ref_name }}
run: |
set -euo pipefail
if [[ -z "$COMPONENT_REF" ]]; then
COMPONENT_REF=main
if [[ -n "$CANDIDATE_REF" ]] && git ls-remote --exit-code --heads \
"https://github.com/$COMPONENT_REPOSITORY.git" "refs/heads/$CANDIDATE_REF" >/dev/null 2>&1; then
COMPONENT_REF="$CANDIDATE_REF"
fi
fi
git check-ref-format --branch "$COMPONENT_REF" >/dev/null
printf 'ref=%s\n' "$COMPONENT_REF" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v7
with:
repository: joomengine/mcp_component
ref: ${{ inputs.component_ref || (github.ref_name == 'main' && 'main' || 'feature/jcb-mcp-runtime') }}
repository: ${{ vars.MCP_COMPONENT_REPOSITORY || 'joomengine/mcp_component' }}
ref: ${{ steps.component.outputs.ref }}
path: component
persist-credentials: false
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: curl, dom, fileinfo, intl, json, mbstring, mysqli, pdo_mysql, simplexml, sodium, xml, zip
tools: composer:v2
coverage: none
- name: Build the matching component
working-directory: component
run: |
bash tools/build.sh
bash tools/build-distribution.sh
- name: Install and exercise this plugin checkout through native Joomla CLI
- name: Install source ZIPs and exercise this plugin through native Joomla CLI
working-directory: component
env:
MCP_TEST_ALLOW_DESTRUCTIVE: '1'
Expand Down
87 changes: 39 additions & 48 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,74 +1,65 @@
name: Publish console plugin release
name: Release console plugin with OctoShoom

on:
workflow_dispatch:
inputs:
version:
description: 'Version to release (for example 1.2.3 or v1.2.3)'
required: true
type: string

permissions:
contents: read

concurrency:
group: console-plugin-release
group: joomla-extension-release
cancel-in-progress: false

jobs:
installed:
if: github.ref == 'refs/heads/main'
uses: ./.github/workflows/installed.yml
with:
component_ref: main
publish:
needs: installed
release:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write
steps:
- uses: actions/checkout@v7
with:
ref: main
fetch-depth: 0
persist-credentials: false
- name: Setup Git User
uses: octoleo/git-user@v2
with:
gpg-key: ${{ secrets.GPG_KEY }}
gpg-user: ${{ secrets.GPG_USER }}
ssh-key: ${{ secrets.SSH_KEY }}
ssh-pub: ${{ secrets.SSH_PUB }}
git-user: ${{ secrets.GIT_USER }}
git-email: ${{ secrets.GIT_EMAIL }}
- uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: dom, simplexml, zip
coverage: none
- name: Validate immutable version and rebuild package
- name: Publish the version and Joomla update entry
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
php tests/run.php
php tests/release.php
version="$(php -r 'echo (string) simplexml_load_file("joomengine_mcp.xml")->version;')"
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]
version="${VERSION#v}"
tag="v$version"
git fetch origin main --tags
[[ "$(git rev-parse origin/main)" == "$GITHUB_SHA" ]]
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null; then
echo 'This immutable version already exists; bump the manifest in a reviewed change.' >&2
exit 1
git remote set-url origin git@github.com:joomengine/mcp_plugin.git
if ! git show-ref --verify --quiet "refs/tags/$tag"; then
php tools/release.php prepare "$version"
git add joomengine_mcp.xml CHANGELOG.md joomengine_mcp_changelog.xml
git commit -m "Release $tag"
git tag -a "$tag" -m "Release $tag"
git push --atomic origin HEAD:main "refs/tags/$tag"
fi
printf 'PLUGIN_VERSION=%s\nPLUGIN_TAG=%s\n' "$version" "$tag" >> "$GITHUB_ENV"
- name: Publish verified versioned archive and checksum
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
archive="build/plg_console_joomengine_mcp-$PLUGIN_VERSION.zip"
gh release create "$PLUGIN_TAG" "$archive" "$archive.sha256" \
--target "$GITHUB_SHA" --title "JoomEngine MCP console $PLUGIN_VERSION" \
--notes-file CHANGELOG.md --draft
gh release edit "$PLUGIN_TAG" --draft=false
mkdir -p build/published
gh release download "$PLUGIN_TAG" --dir build/published --pattern '*.zip' --pattern '*.sha256'
cmp "$archive" "build/published/$(basename "$archive")"
gh api "repos/$GITHUB_REPOSITORY/releases/tags/$PLUGIN_TAG" > build/published/release.json
php tools/update-feed.php build/published/release.json "build/published/$(basename "$archive")"
- name: Commit feed only after publication succeeds
run: |
set -euo pipefail
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
php tools/release.php feed "$version"
git add joomengine_mcp_update_server.xml
git commit -m "Publish console plugin $PLUGIN_VERSION update metadata"
git push origin HEAD:main
if ! git diff --cached --quiet; then
git commit -m "Add $tag to the Joomla update server"
git push origin HEAD:main
fi
- name: Update hashes
uses: octoleo/octoshoom@master
with:
config-json: |
{"update_servers":[{"owner":"joomengine","repo":"mcp_plugin","branch":"main","path":"joomengine_mcp_update_server.xml"}]}
12 changes: 11 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Complete the original companion/CLI migration from `joomengine/joomla-mcp@2cff50f4f6b440da3c684f9995a77efad32e1a36` without losing supported commands, schemas, native actions, preview/plan, approval, verification or recovery. **Also complete the JCB CLI integration required by docs/JCB-INTEGRATION.md and the component's canonical JCB roadmap.** Core-only support is not the completed objective.

Stay on `feature/jcb-mcp-runtime` / PR #1. Push coherent commits and update docs/IMPLEMENTATION.md with actual tests and remaining work. Do not replace branches, force-push, merge, publish or alter the original MCP/JCB source repositories without separate instruction.
The migration PR #1 has been merged. Branch new work from current `main`, or continue the relevant open PR branch. Push coherent commits and update docs/IMPLEMENTATION.md with actual tests and remaining work. Do not force-push, merge, run a release or alter the original MCP/JCB source repositories without instruction.

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.

Expand All @@ -15,3 +15,13 @@ JCB's installed command plugin owns `componentbuilder:*` registration. Inventory
Stdio stdout contains only JSON-RPC. Keep banners/notices/logs off it; preserve nonzero failures and EOF/byte bounds. Missing/incompatible component or JCB dependencies must fail the affected operation clearly without breaking unrelated Joomla/core commands. Restore native identity/input/factory state or use isolated job workers so consecutive requests cannot contaminate one another.

Run syntax, provider/registration, manifest/package tests and coordinated installed Joomla/JCB API/CLI/stdio tests. Exercise true writes/read-back/cleanup, dependency queues, compile/install artifacts, command ordering, concurrency, cancellation, errors and HTTP/local-authority separation. Package checks are not live passes. Align server package versions/update feeds, retain licences and never advertise unpublished artifacts or completed JCB coverage without evidence.

## Source installation and releases

- This repository is exclusively the console plugin. Its GitHub source ZIP must install directly into a Joomla site with the compatible component installed. Keep every manifest file tracked; no build, Composer run or repacking is required downstream.
- Do not add plugin/package builders, copied component dependencies, combined package manifests or package feeds. The component's release invokes OctoJPack using its standalone `.octojpack` configuration, which selects this plugin's latest tag. The resulting Joomla package belongs to its own repository.
- The manual Release workflow accepts the next version, freezes manifest/changelog metadata, creates an immutable tag, adds its source ZIP to this plugin's Joomla update feed, and waits for OctoShoom to commit the checksum. This workflow never invokes OctoJPack. Keep the fixed `joomengine/mcp_plugin` repository, `main` branch and feed path in the workflow; never move an existing tag.
- Use `octoleo/git-user@v2` and `octoleo/octoshoom@master` directly as actions, following their quick starts. Configure authentication once through git-user's documented secrets; let OctoShoom inherit it. Do not add custom SSH setup, action checkouts, repository discovery, hash rechecks or wrappers around the shared tools. Local release support only freezes version metadata and appends the Joomla update entry. Engine changes require an explicit request.
- Log every meaningful change in **both** `CHANGELOG.md` and `joomengine_mcp_changelog.xml`. Pending entries use the exact version marker `[[[NEXT_VERSION]]]`. Create a pending section when absent; leave released sections unchanged. The release workflow replaces this marker with the selected version.
- Joomla changelog identity is element `joomengine_mcp`, type `plugin`, folder `console`. Native categories are `security`, `fix`, `language`, `addition`, `change`, `remove`, and `note`, with `item` children. Match their human headings in Markdown. Compatibility warnings belong under Note, errors fixed under Fix, and security fixes under Security. Keep both formats consistent and retain the manifest's valid `changelogurl`.
- Verify source archive completeness and release metadata for successive versions. Leave checksum generation and its verification to OctoShoom; do not maintain another implementation here.
40 changes: 32 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
# Changelog

## Unreleased
## [[[NEXT_VERSION]]]

### 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.
- Add the categorized Joomla plugin changelog and document GitHub secrets and agent responsibilities.

### Change

- Install and test the unchanged repository source ZIP; no build or Composer step is required.
- Keep combined package assembly in the component's external OctoJPack release process and its separate package repository.
- Call git-user and OctoShoom directly as actions with fixed repository/feed settings and inherited authentication.

### Remove

- Remove the local plugin ZIP builder and release-asset/checksum publication implementation.
- Remove custom SSH setup, temporary action checkouts, duplicate hash checks and release-tool configuration variables.

### Note

- 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.

## 0.1.0 — development baseline

### Addition

- Establish the exact joomengine_mcp console plugin identity, local-server authority and shared component contract.
- Add native plugin/provider/lazy command adapters, output isolation, installer checks, languages/update metadata and PHP-only reproducible packaging.
- Add native plugin/provider/lazy command adapters, output isolation, installer checks and language metadata.
- Expose explicit local JCB catalogue synchronization through the component-owned runtime without replacing JCB's commands.
- Preserve native global options, atomic command registration and output restoration after console errors.
- Verify native Joomla console contracts and 18 actual installed command/stdio assertions, including whitespace and exact-limit NDJSON frames, on PHP 8.3 and 8.4.
- Verify coordinated installed component/plugin/client execution on MySQL and PostgreSQL; retain separate JCB golden-image evidence in the component acceptance checklist.
- Add explicit main-only release publication with verified versioned archives, checksums and post-publication update metadata.
- Separate external Composer-client/remote-bridge ownership into `joomengine/mcp_client`; no server/plugin dependency on that package.
- Require complete first-class JCB API/CLI coverage and document native command registration, compiler/package semantics, shared jobs and installed acceptance responsibilities.
- Verify native Joomla console contracts and installed command/stdio behavior, including whitespace and exact-limit NDJSON frames.
- Verify coordinated installed component/plugin/client execution on MySQL and PostgreSQL; retain JCB golden-image evidence in the component acceptance checklist.
- Separate external Composer-client/remote-bridge ownership into joomengine/mcp_client; no server/plugin dependency on that package.
- Document native command registration, compiler/package semantics, shared jobs and installed acceptance responsibilities.

Exact tested revisions and workflow results are recorded in [implementation evidence](docs/IMPLEMENTATION.md). Coordinated JCB compiler/package/job acceptance is tracked in the [component checklist](https://github.com/joomengine/mcp_component/pull/1#issuecomment-5732685349). No release has been published by this implementation work.
Exact tested revisions are recorded in [implementation evidence](docs/IMPLEMENTATION.md). Development baseline entries describe source, not a previously published release. Published immutable tags establish release availability.
Loading
Loading