From f9de2f2c9737f92eacd32c797cb24b9a4e8be42a Mon Sep 17 00:00:00 2001 From: Jonathan Miller <230051081+jmiller-moko@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:08:33 -0500 Subject: [PATCH] ci: update AI instructions + auto-release src/ filter Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/CLAUDE.md | 378 ++++++++++++++------------ .github/copilot-instructions.md | 412 ++++++++++++++++++++--------- .github/workflows/auto-release.yml | 35 +-- 3 files changed, 511 insertions(+), 314 deletions(-) diff --git a/.github/CLAUDE.md b/.github/CLAUDE.md index 602a449..68e796a 100644 --- a/.github/CLAUDE.md +++ b/.github/CLAUDE.md @@ -1,3 +1,22 @@ + + > [!IMPORTANT] > **๐Ÿ”ง AI Self-Update Required on First Use** > @@ -19,135 +38,34 @@ > |---|---| > | `MokoWaaS` | The GitHub repository name (visible in the URL, `README.md` heading, or `git remote -v`) | > | `https://github.com/mokoconsulting-tech/MokoWaaS` | Full GitHub URL, e.g. `https://github.com/mokoconsulting-tech/` | -> | `MokoWaaS is a Joomla 5.x system plugin that provides a comprehensive identity override layer for the MokoWaaS platform. It ensures consistent branding, terminology, and user experience across all Joomla administrative and frontend interfaces.` | First paragraph of `README.md` body, or the GitHub repo description | > | `{{EXTENSION_NAME}}` | The `` element in `manifest.xml` at the repository root | > | `{{EXTENSION_TYPE}}` | The `type` attribute of the `` tag in `manifest.xml` (`component`, `module`, `plugin`, or `template`) | > | `{{EXTENSION_ELEMENT}}` | The `` tag in `manifest.xml`, or the filename prefix (e.g. `com_myextension`, `mod_mymodule`) | > > --- -# What This Repo Is +# MokoWaaS โ€” GitHub Copilot Custom Instructions -**MokoWaaS** is a Moko Consulting **MokoWaaS** (Joomla) extension repository. +## What This Repo Is -MokoWaaS is a Joomla 5.x system plugin that provides a comprehensive identity override layer for the MokoWaaS platform. It ensures consistent branding, terminology, and user experience across all Joomla administrative and frontend interfaces. +This is a **Moko Consulting MokoWaaS** (Joomla) repository governed by [MokoStandards](https://github.com/mokoconsulting-tech/MokoStandards). All coding standards, workflows, and policies are defined there and enforced here via bulk sync. +Repository URL: https://github.com/mokoconsulting-tech/MokoWaaS Extension name: **{{EXTENSION_NAME}}** Extension type: **{{EXTENSION_TYPE}}** (`{{EXTENSION_ELEMENT}}`) -Repository URL: https://github.com/mokoconsulting-tech/MokoWaaS - -This repository is governed by [MokoStandards](https://github.com/mokoconsulting-tech/MokoStandards) โ€” the single source of truth for coding standards, file-header policies, GitHub Actions workflows, and Terraform configuration templates across all Moko Consulting repositories. +Platform: **Joomla 4.x / MokoWaaS** --- -# Repo Structure +## Primary Language -``` -MokoWaaS/ -โ”œโ”€โ”€ manifest.xml # Joomla installer manifest (root โ€” required) -โ”œโ”€โ”€ update.xml # Update server manifest (root โ€” required) -โ”œโ”€โ”€ site/ # Frontend (site) code -โ”‚ โ”œโ”€โ”€ controller.php -โ”‚ โ”œโ”€โ”€ controllers/ -โ”‚ โ”œโ”€โ”€ models/ -โ”‚ โ””โ”€โ”€ views/ -โ”œโ”€โ”€ admin/ # Backend (admin) code -โ”‚ โ”œโ”€โ”€ controller.php -โ”‚ โ”œโ”€โ”€ controllers/ -โ”‚ โ”œโ”€โ”€ models/ -โ”‚ โ”œโ”€โ”€ views/ -โ”‚ โ””โ”€โ”€ sql/ -โ”œโ”€โ”€ language/ # Language INI files -โ”œโ”€โ”€ media/ # CSS, JS, images -โ”œโ”€โ”€ docs/ # Technical documentation -โ”œโ”€โ”€ tests/ # Test suite -โ”œโ”€โ”€ .github/ -โ”‚ โ”œโ”€โ”€ workflows/ # CI/CD workflows (synced from MokoStandards) -โ”‚ โ”œโ”€โ”€ copilot-instructions.md -โ”‚ โ””โ”€โ”€ CLAUDE.md # This file -โ”œโ”€โ”€ README.md # Version source of truth -โ”œโ”€โ”€ CHANGELOG.md -โ”œโ”€โ”€ CONTRIBUTING.md -โ””โ”€โ”€ LICENSE # GPL-3.0-or-later -``` +**PHP** (โ‰ฅ 7.4) is the primary language for this Joomla extension. JavaScript may be used for frontend enhancements. YAML uses 2-space indentation. All other text files use tabs per `.editorconfig`. --- -# Primary Language +## File Header โ€” Always Required on New Files -**PHP** (โ‰ฅ 7.4) is the primary language for this Joomla extension. YAML uses 2-space indentation. All other text files use tabs per `.editorconfig`. - ---- - -# Version Management - -**`README.md` is the single source of truth for the repository version.** - -- **Bump the patch version on every PR** โ€” increment `XX.YY.ZZ` (e.g. `01.02.03` โ†’ `01.02.04`) in `README.md` before opening the PR; the `sync-version-on-merge` workflow propagates it to all `FILE INFORMATION` headers automatically on merge. -- Version format is zero-padded semver: `XX.YY.ZZ` (e.g. `01.02.03`). -- Never hardcode a version number in body text โ€” use the badge or FILE INFORMATION header only. - -### Joomla Version Alignment - -Three files must **always have the same version**: - -| File | Where the version lives | -|------|------------------------| -| `README.md` | `FILE INFORMATION` block + badge | -| `manifest.xml` | `` tag | -| `update.xml` | `` in the most recent `` block | - -The `make release` command / release workflow syncs all three automatically. - ---- - -# update.xml โ€” Required in Repo Root - -`update.xml` is the Joomla update server manifest. It allows Joomla installations to check for new versions of this extension via: - -```xml - - - - https://github.com/mokoconsulting-tech/MokoWaaS/raw/main/update.xml - - -``` - -**Rules:** -- Every release prepends a new `` block at the top โ€” older entries are preserved. -- `` in `update.xml` must exactly match `` in `manifest.xml` and `README.md`. -- `` must be a publicly accessible GitHub Releases asset URL. -- `` โ€” backslash is literal (Joomla regex syntax). - -Example `update.xml` entry for a new release: -```xml - - - {{EXTENSION_NAME}} - MokoWaaS - {{EXTENSION_ELEMENT}} - {{EXTENSION_TYPE}} - 01.02.04 - https://github.com/mokoconsulting-tech/MokoWaaS/releases/tag/01.02.04 - - - https://github.com/mokoconsulting-tech/MokoWaaS/releases/download/01.02.04/{{EXTENSION_ELEMENT}}-01.02.04.zip - - - - 7.4 - Moko Consulting - https://mokoconsulting.tech - - -``` - ---- - -# File Header Requirements - -Every new file **must** have a copyright header as its first content. JSON files, binary files, generated files, and third-party files are exempt. +Every new file needs a copyright header as its first content. **PHP:** ```php @@ -162,47 +80,141 @@ Every new file **must** have a copyright header as its first content. JSON files * DEFGROUP: MokoWaaS.{{EXTENSION_TYPE}} * INGROUP: MokoWaaS * REPO: https://github.com/mokoconsulting-tech/MokoWaaS - * PATH: /site/controllers/item.php + * PATH: /path/to/file.php * VERSION: XX.YY.ZZ - * BRIEF: One-line description of file purpose + * BRIEF: One-line description of purpose */ defined('_JEXEC') or die; ``` -**Markdown / YAML / Shell / XML:** Use the appropriate comment syntax with the same fields. +**Markdown:** +```markdown + +``` + +**YAML / Shell / XML:** Use the appropriate comment syntax with the same fields. JSON files are exempt. --- -# Coding Standards +## Version Management -## Naming Conventions +**`README.md` is the single source of truth for the repository version.** -| Context | Convention | Example | -|---------|-----------|---------| -| PHP class | `PascalCase` | `ItemModel` | -| PHP method / function | `camelCase` | `getItems()` | -| PHP variable | `$snake_case` | `$item_id` | -| PHP constant | `UPPER_SNAKE_CASE` | `MAX_ITEMS` | -| PHP class file | `PascalCase.php` | `ItemModel.php` | -| YAML workflow | `kebab-case.yml` | `ci-joomla.yml` | -| Markdown doc | `kebab-case.md` | `installation-guide.md` | +- **Bump the patch version on every PR** โ€” increment `XX.YY.ZZ` (e.g. `01.02.03` โ†’ `01.02.04`) in `README.md` before opening the PR; the `sync-version-on-merge` workflow propagates it automatically to all badges and `FILE INFORMATION` headers on merge to `main`. +- The `VERSION: XX.YY.ZZ` field in `README.md` governs all other version references. +- Version format is zero-padded semver: `XX.YY.ZZ` (e.g. `01.02.03`). +- Never hardcode a specific version in document body text โ€” use the badge or FILE INFORMATION header only. -## Commit Messages +### Joomla Version Alignment -Format: `(): ` โ€” imperative, lower-case subject, no trailing period. +The version in `README.md` **must always match** the `` tag in `manifest.xml` and the latest entry in `updates.xml`. The `make release` command / release workflow updates all three automatically. -Valid types: `feat` ยท `fix` ยท `docs` ยท `chore` ยท `ci` ยท `refactor` ยท `style` ยท `test` ยท `perf` ยท `revert` ยท `build` +```xml + +01.02.04 -## Branch Naming - -Format: `/[/description]` - -Approved prefixes: `dev/` ยท `rc/` ยท `version/` ยท `patch/` ยท `copilot/` ยท `dependabot/` + + + + {{EXTENSION_NAME}} + 01.02.04 + + + https://github.com/mokoconsulting-tech/MokoWaaS/releases/download/01.02.04/{{EXTENSION_ELEMENT}}-01.02.04.zip + + + + + + +``` --- -# GitHub Actions โ€” Token Usage +## Joomla Extension Structure + +``` +MokoWaaS/ +โ”œโ”€โ”€ manifest.xml # Joomla installer manifest (root โ€” required) +โ”œโ”€โ”€ updates.xml # Update server manifest (root โ€” required, see below) +โ”œโ”€โ”€ site/ # Frontend (site) code +โ”‚ โ”œโ”€โ”€ controller.php +โ”‚ โ”œโ”€โ”€ controllers/ +โ”‚ โ”œโ”€โ”€ models/ +โ”‚ โ””โ”€โ”€ views/ +โ”œโ”€โ”€ admin/ # Backend (admin) code +โ”‚ โ”œโ”€โ”€ controller.php +โ”‚ โ”œโ”€โ”€ controllers/ +โ”‚ โ”œโ”€โ”€ models/ +โ”‚ โ”œโ”€โ”€ views/ +โ”‚ โ””โ”€โ”€ sql/ +โ”œโ”€โ”€ language/ # Language INI files +โ”œโ”€โ”€ media/ # CSS, JS, images (deployed to /media/{{EXTENSION_ELEMENT}}/) +โ”œโ”€โ”€ docs/ # Technical documentation +โ”œโ”€โ”€ tests/ # Test suite +โ”œโ”€โ”€ .github/ +โ”‚ โ”œโ”€โ”€ workflows/ +โ”‚ โ”œโ”€โ”€ copilot-instructions.md # This file +โ”‚ โ””โ”€โ”€ CLAUDE.md +โ”œโ”€โ”€ README.md # Version source of truth +โ”œโ”€โ”€ CHANGELOG.md +โ”œโ”€โ”€ CONTRIBUTING.md +โ”œโ”€โ”€ LICENSE # GPL-3.0-or-later +โ””โ”€โ”€ Makefile # Build automation +``` + +--- + +## updates.xml โ€” Required in Repo Root + +`updates.xml` **must exist at the repository root**. It is the Joomla update server manifest that allows Joomla installations to check for new versions of this extension. + +The `manifest.xml` must reference it via: +```xml + + + https://github.com/mokoconsulting-tech/MokoWaaS/raw/main/updates.xml + + +``` + +**Rules:** +- Every release must prepend a new `` block at the top of `updates.xml` โ€” old entries must be preserved below. +- The `` in `updates.xml` must exactly match `` in `manifest.xml` and the version in `README.md`. +- The `` must be a publicly accessible direct download link (GitHub Releases asset URL). +- `` โ€” the backslash is a **literal backslash character** in the XML attribute value; Joomla's update-server parser treats the value as a regular expression, so `\.` matches a literal dot and `[0-9]+` matches one or more digits. Do not double-escape it. + +--- + +## manifest.xml Rules + +- Lives at the repo root as `manifest.xml` (not inside `site/` or `admin/`). +- `` tag must be kept in sync with `README.md` version and `updates.xml`. +- Must include `` block pointing to this repo's `updates.xml`. +- Must include `` and `` sections. +- Joomla 4.x requires `Moko\{{EXTENSION_NAME}}` for namespaced extensions. + +--- + +## GitHub Actions โ€” Token Usage Every workflow must use **`secrets.GH_TOKEN`** (the org-level Personal Access Token). @@ -217,58 +229,76 @@ env: ``` ```yaml -# โŒ Wrong โ€” never use these +# โŒ Wrong โ€” never use these in workflows token: ${{ github.token }} token: ${{ secrets.GITHUB_TOKEN }} ``` --- -# Keeping Documentation Current +## MokoStandards Reference -| Change type | Documentation to update | -|-------------|------------------------| -| New or renamed PHP class/method | PHPDoc block; `docs/api/` entry | -| New or changed `manifest.xml` | Sync version to `update.xml` and `README.md` | -| New release | Prepend `` to `update.xml`; update `CHANGELOG.md`; bump `README.md` | -| New or changed workflow | `docs/workflows/.md` | -| Any modified file | Update the `VERSION` field in that file's `FILE INFORMATION` block | -| **Every PR** | **Bump the patch version** โ€” increment `XX.YY.ZZ` in `README.md`; `sync-version-on-merge` propagates it | - ---- - -# What NOT to Do - -- **Never commit directly to `main`** โ€” all changes go through a PR. -- **Never hardcode version numbers** in body text โ€” update `README.md` and let automation propagate. -- **Never let `manifest.xml`, `update.xml`, and `README.md` versions diverge.** -- **Never skip the FILE INFORMATION block** on a new source file. -- **Never use bare `catch (\Throwable $e) {}`** โ€” always log or re-throw. -- **Never mix tabs and spaces** within a file โ€” follow `.editorconfig`. -- **Never use `github.token` or `secrets.GITHUB_TOKEN` in workflows** โ€” always use `secrets.GH_TOKEN`. -- **Never remove `defined('_JEXEC') or die;`** from web-accessible PHP files. - ---- - -# PR Checklist - -Before opening a PR, verify: - -- [ ] Patch version bumped in `README.md` (e.g. `01.02.03` โ†’ `01.02.04`) -- [ ] If this is a release: `manifest.xml` version updated; `update.xml` updated with new entry -- [ ] FILE INFORMATION headers updated in modified files -- [ ] CHANGELOG.md updated -- [ ] Tests pass - ---- - -# Key Policy Documents (MokoStandards) +This repository is governed by [MokoStandards](https://github.com/mokoconsulting-tech/MokoStandards). Authoritative policies: | Document | Purpose | |----------|---------| | [file-header-standards.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/file-header-standards.md) | Copyright-header rules for every file type | | [coding-style-guide.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/coding-style-guide.md) | Naming and formatting conventions | | [branching-strategy.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/branching-strategy.md) | Branch naming, hierarchy, and release workflow | -| [merge-strategy.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/merge-strategy.md) | Squash-merge policy and PR conventions | +| [merge-strategy.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/merge-strategy.md) | Squash-merge policy and PR title/body conventions | | [changelog-standards.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/changelog-standards.md) | How and when to update CHANGELOG.md | -| [joomla-development-guide.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/guide/waas/joomla-development-guide.md) | MokoWaaS Joomla extension development guide | \ No newline at end of file +| [joomla-development-guide.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/guide/waas/joomla-development-guide.md) | MokoWaaS Joomla extension development guide | + +--- + +## Naming Conventions + +| Context | Convention | Example | +|---------|-----------|---------| +| PHP class | `PascalCase` | `MyController` | +| PHP method / function | `camelCase` | `getItems()` | +| PHP variable | `$snake_case` | `$item_id` | +| PHP constant | `UPPER_SNAKE_CASE` | `MAX_ITEMS` | +| PHP class file | `PascalCase.php` | `ItemModel.php` | +| YAML workflow | `kebab-case.yml` | `ci-joomla.yml` | +| Markdown doc | `kebab-case.md` | `installation-guide.md` | + +--- + +## Commit Messages + +Format: `(): ` โ€” imperative, lower-case subject, no trailing period. + +Valid types: `feat` ยท `fix` ยท `docs` ยท `chore` ยท `ci` ยท `refactor` ยท `style` ยท `test` ยท `perf` ยท `revert` ยท `build` + +--- + +## Branch Naming + +Format: `/[/description]` + +Approved prefixes: `dev/` ยท `rc/` ยท `version/` ยท `patch/` ยท `copilot/` ยท `dependabot/` + +--- + +## Keeping Documentation Current + +| Change type | Documentation to update | +|-------------|------------------------| +| New or renamed PHP class/method | PHPDoc block; `docs/api/` entry | +| New or changed manifest.xml | Update `updates.xml` version; bump README.md version | +| New release | Prepend `` block to `updates.xml`; update CHANGELOG.md; bump README.md version | +| New or changed workflow | `docs/workflows/.md` | +| Any modified file | Update the `VERSION` field in that file's `FILE INFORMATION` block | +| **Every PR** | **Bump the patch version** โ€” increment `XX.YY.ZZ` in `README.md`; `sync-version-on-merge` propagates it | + +--- + +## Key Constraints + +- Never commit directly to `main` โ€” all changes go via PR, squash-merged +- Never skip the FILE INFORMATION block on a new file +- Never add `defined('_JEXEC') or die;` to CLI scripts or model tests โ€” only to web-accessible PHP files +- Never hardcode version numbers in body text โ€” update `README.md` and let automation propagate +- Never use `github.token` or `secrets.GITHUB_TOKEN` in workflows โ€” always use `secrets.GH_TOKEN` +- Never let `manifest.xml` version, `updates.xml` version, and `README.md` version go out of sync diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index e443deb..68e796a 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,140 +1,304 @@ -# Copilot Instructions for MokoWaaS + + +> [!IMPORTANT] +> **๐Ÿ”ง AI Self-Update Required on First Use** +> +> This file may contain unfilled `{{TOKEN}}` placeholders. The MokoStandards bulk-sync system +> replaces them automatically at sync time; if you can still see them, sync has not yet run for +> this repository โ€” or this is a brand-new repo. +> +> **On your very first interaction in this repository, before answering any other question:** +> +> 1. Check whether any `{{TOKEN}}` placeholders remain in this file. +> 2. If they do, locate the values as described in the table below and replace every occurrence +> in **both** `.github/copilot-instructions.md` and `.github/CLAUDE.md`. +> 3. After replacing all tokens, **delete this entire notice block** (from `> [!IMPORTANT]` +> through the closing `> ---` line) in both files. +> 4. Tell the developer: *"I've self-updated the AI context files with this repository's +> values โ€” all set."* +> +> | Placeholder | Where to find the value | +> |---|---| +> | `MokoWaaS` | The GitHub repository name (visible in the URL, `README.md` heading, or `git remote -v`) | +> | `https://github.com/mokoconsulting-tech/MokoWaaS` | Full GitHub URL, e.g. `https://github.com/mokoconsulting-tech/` | +> | `{{EXTENSION_NAME}}` | The `` element in `manifest.xml` at the repository root | +> | `{{EXTENSION_TYPE}}` | The `type` attribute of the `` tag in `manifest.xml` (`component`, `module`, `plugin`, or `template`) | +> | `{{EXTENSION_ELEMENT}}` | The `` tag in `manifest.xml`, or the filename prefix (e.g. `com_myextension`, `mod_mymodule`) | +> +> --- + +# MokoWaaS โ€” GitHub Copilot Custom Instructions + +## What This Repo Is + +This is a **Moko Consulting MokoWaaS** (Joomla) repository governed by [MokoStandards](https://github.com/mokoconsulting-tech/MokoStandards). All coding standards, workflows, and policies are defined there and enforced here via bulk sync. + +Repository URL: https://github.com/mokoconsulting-tech/MokoWaaS +Extension name: **{{EXTENSION_NAME}}** +Extension type: **{{EXTENSION_TYPE}}** (`{{EXTENSION_ELEMENT}}`) +Platform: **Joomla 4.x / MokoWaaS** + +--- + +## Primary Language + +**PHP** (โ‰ฅ 7.4) is the primary language for this Joomla extension. JavaScript may be used for frontend enhancements. YAML uses 2-space indentation. All other text files use tabs per `.editorconfig`. + +--- + +## File Header โ€” Always Required on New Files + +Every new file needs a copyright header as its first content. + +**PHP:** +```php + + * + * This file is part of a Moko Consulting project. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + * FILE INFORMATION + * DEFGROUP: MokoWaaS.{{EXTENSION_TYPE}} + * INGROUP: MokoWaaS + * REPO: https://github.com/mokoconsulting-tech/MokoWaaS + * PATH: /path/to/file.php + * VERSION: XX.YY.ZZ + * BRIEF: One-line description of purpose + */ + +defined('_JEXEC') or die; ``` -## Build and Validation +**Markdown:** +```markdown + ``` -### Validate Plugin Manifest -```bash -./scripts/validate_manifest.sh -``` +**YAML / Shell / XML:** Use the appropriate comment syntax with the same fields. JSON files are exempt. -### Verify Changelog Format -```bash -./scripts/verify_changelog.sh -``` - -### Update Changelog (CI mode โ€” checks for uncommitted changes) -```bash -./scripts/update_changelog.sh --ci -``` - -### Build Installable ZIP -```bash -cd src/plugins/system/mokowaas -zip -r ../../../../dist/MokoWaaS-.zip . -``` - -### CI Pipeline (runs on every PR and push to `main`/`version/*`) -1. PHP lint โ€” `find src -name "*.php" | xargs php -l` -2. Composer install and test (if `composer.json` exists) -3. Manifest validation โ€” `scripts/validate_manifest.sh` -4. Changelog verification โ€” `scripts/update_changelog.sh --ci` - -## Coding Standards - -- Follow **[MokoStandards](https://github.com/mokoconsulting-tech/MokoStandards)** coding standards. -- PHP files must comply with **PSR-12** (enforced by `phpcs.xml`). -- Maximum line length: **120 characters** (hard limit 150). -- Forbidden PHP functions: `eval`, `create_function`, `var_dump`, `print_r`. -- Use **tab characters** for indentation in PHP, XML, shell scripts, and Markdown; editors should display tabs as 2 spaces wide (configured via `.editorconfig`). -- Use **spaces** for YAML (2 spaces) and JSON (2 spaces). -- All files must use **UTF-8 encoding** and **LF line endings** (CRLF only for `.ps1`, `.bat`, `.cmd`). - -### Required File Header - -Every PHP, XML, shell, and Markdown file must include: - -1. **SPDX license header** with GPL-3.0-or-later -2. **FILE INFORMATION metadata block**: - ``` - # FILE INFORMATION - DEFGROUP: Joomla.Plugin - INGROUP: MokoWaaS[.] - REPO: https://github.com/mokoconsulting-tech/mokowaas - VERSION: - PATH: / - BRIEF: - ``` - -### Joomla 5.x Plugin Architecture - -- Plugin namespace: `Moko\Plugin\System\MokoWaaS` (declared **before** `defined('_JEXEC')`) -- Main class: `MokoWaaS` in `src/Extension/MokoWaaS.php` -- Service provider: `services/provider.php` registers the plugin via DI container -- All methods implementing `InstallerScriptInterface` must have explicit `: bool` return types -- Avoid deprecated Joomla APIs; use Joomla 5.x event-driven patterns - -### Language Files - -- Frontend `.ini` files โ†’ `language/en-GB/` and `language/en-US/` -- Admin `.sys.ini` files โ†’ `administrator/language/en-GB/` and `administrator/language/en-US/` -- Frontend `.override.ini` files โ†’ `language/en-GB/` and `language/en-US/` -- Admin `.override.ini` files โ†’ `administrator/language/en-GB/` and `administrator/language/en-US/` -- Language override files must **not** be declared in the XML manifest `` sections +--- ## Version Management -- Versioning: `MAJOR.MINOR.PATCH` with zero-padded two-digit components (e.g., `02.00.00`) โ€” this is intentional per MokoStandards for consistent sorting and display -- Version must be updated consistently across: - - `src/plugins/system/mokowaas/mokowaas.xml` - - All PHP file headers - - `CHANGELOG.md` - - `updates.xml` - - Documentation metadata -- MAJOR: structural or architectural changes -- MINOR: feature updates or terminology expansion -- PATCH: bug fixes or language corrections +**`README.md` is the single source of truth for the repository version.** -## Branching Model +- **Bump the patch version on every PR** โ€” increment `XX.YY.ZZ` (e.g. `01.02.03` โ†’ `01.02.04`) in `README.md` before opening the PR; the `sync-version-on-merge` workflow propagates it automatically to all badges and `FILE INFORMATION` headers on merge to `main`. +- The `VERSION: XX.YY.ZZ` field in `README.md` governs all other version references. +- Version format is zero-padded semver: `XX.YY.ZZ` (e.g. `01.02.03`). +- Never hardcode a specific version in document body text โ€” use the badge or FILE INFORMATION header only. -- `main` โ€” production stable -- `develop` โ€” next minor release aggregation -- `feature/*` โ€” new enhancements -- `bugfix/*` โ€” hotfixes and corrections -- `version/*` โ€” release preparation branches (trigger CI) +### Joomla Version Alignment -## Key Guidelines +The version in `README.md` **must always match** the `` tag in `manifest.xml` and the latest entry in `updates.xml`. The `make release` command / release workflow updates all three automatically. -1. Preserve **load order compatibility** with other Joomla system plugins. -2. Do not introduce deprecated Joomla APIs. -3. When modifying language overrides, update **both** `en-GB` and `en-US` variants. -4. When changing the plugin version, update it in **all** locations listed above. -5. Pull requests must include a description, version bump (when applicable), and reference to related issues. -6. Documentation in `docs/` must include metadata and maintain revision history following MokoStandards. -7. The `updates.xml` file in the repository root is automatically updated by the `release_from_version.yml` workflow after stable releases โ€” do not edit it manually unless necessary. +```xml + +01.02.04 + + + + + {{EXTENSION_NAME}} + 01.02.04 + + + https://github.com/mokoconsulting-tech/MokoWaaS/releases/download/01.02.04/{{EXTENSION_ELEMENT}}-01.02.04.zip + + + + + + +``` + +--- + +## Joomla Extension Structure + +``` +MokoWaaS/ +โ”œโ”€โ”€ manifest.xml # Joomla installer manifest (root โ€” required) +โ”œโ”€โ”€ updates.xml # Update server manifest (root โ€” required, see below) +โ”œโ”€โ”€ site/ # Frontend (site) code +โ”‚ โ”œโ”€โ”€ controller.php +โ”‚ โ”œโ”€โ”€ controllers/ +โ”‚ โ”œโ”€โ”€ models/ +โ”‚ โ””โ”€โ”€ views/ +โ”œโ”€โ”€ admin/ # Backend (admin) code +โ”‚ โ”œโ”€โ”€ controller.php +โ”‚ โ”œโ”€โ”€ controllers/ +โ”‚ โ”œโ”€โ”€ models/ +โ”‚ โ”œโ”€โ”€ views/ +โ”‚ โ””โ”€โ”€ sql/ +โ”œโ”€โ”€ language/ # Language INI files +โ”œโ”€โ”€ media/ # CSS, JS, images (deployed to /media/{{EXTENSION_ELEMENT}}/) +โ”œโ”€โ”€ docs/ # Technical documentation +โ”œโ”€โ”€ tests/ # Test suite +โ”œโ”€โ”€ .github/ +โ”‚ โ”œโ”€โ”€ workflows/ +โ”‚ โ”œโ”€โ”€ copilot-instructions.md # This file +โ”‚ โ””โ”€โ”€ CLAUDE.md +โ”œโ”€โ”€ README.md # Version source of truth +โ”œโ”€โ”€ CHANGELOG.md +โ”œโ”€โ”€ CONTRIBUTING.md +โ”œโ”€โ”€ LICENSE # GPL-3.0-or-later +โ””โ”€โ”€ Makefile # Build automation +``` + +--- + +## updates.xml โ€” Required in Repo Root + +`updates.xml` **must exist at the repository root**. It is the Joomla update server manifest that allows Joomla installations to check for new versions of this extension. + +The `manifest.xml` must reference it via: +```xml + + + https://github.com/mokoconsulting-tech/MokoWaaS/raw/main/updates.xml + + +``` + +**Rules:** +- Every release must prepend a new `` block at the top of `updates.xml` โ€” old entries must be preserved below. +- The `` in `updates.xml` must exactly match `` in `manifest.xml` and the version in `README.md`. +- The `` must be a publicly accessible direct download link (GitHub Releases asset URL). +- `` โ€” the backslash is a **literal backslash character** in the XML attribute value; Joomla's update-server parser treats the value as a regular expression, so `\.` matches a literal dot and `[0-9]+` matches one or more digits. Do not double-escape it. + +--- + +## manifest.xml Rules + +- Lives at the repo root as `manifest.xml` (not inside `site/` or `admin/`). +- `` tag must be kept in sync with `README.md` version and `updates.xml`. +- Must include `` block pointing to this repo's `updates.xml`. +- Must include `` and `` sections. +- Joomla 4.x requires `Moko\{{EXTENSION_NAME}}` for namespaced extensions. + +--- + +## GitHub Actions โ€” Token Usage + +Every workflow must use **`secrets.GH_TOKEN`** (the org-level Personal Access Token). + +```yaml +# โœ… Correct +- uses: actions/checkout@v4 + with: + token: ${{ secrets.GH_TOKEN }} + +env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} +``` + +```yaml +# โŒ Wrong โ€” never use these in workflows +token: ${{ github.token }} +token: ${{ secrets.GITHUB_TOKEN }} +``` + +--- + +## MokoStandards Reference + +This repository is governed by [MokoStandards](https://github.com/mokoconsulting-tech/MokoStandards). Authoritative policies: + +| Document | Purpose | +|----------|---------| +| [file-header-standards.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/file-header-standards.md) | Copyright-header rules for every file type | +| [coding-style-guide.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/coding-style-guide.md) | Naming and formatting conventions | +| [branching-strategy.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/branching-strategy.md) | Branch naming, hierarchy, and release workflow | +| [merge-strategy.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/merge-strategy.md) | Squash-merge policy and PR title/body conventions | +| [changelog-standards.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/changelog-standards.md) | How and when to update CHANGELOG.md | +| [joomla-development-guide.md](https://github.com/mokoconsulting-tech/MokoStandards/blob/main/docs/guide/waas/joomla-development-guide.md) | MokoWaaS Joomla extension development guide | + +--- + +## Naming Conventions + +| Context | Convention | Example | +|---------|-----------|---------| +| PHP class | `PascalCase` | `MyController` | +| PHP method / function | `camelCase` | `getItems()` | +| PHP variable | `$snake_case` | `$item_id` | +| PHP constant | `UPPER_SNAKE_CASE` | `MAX_ITEMS` | +| PHP class file | `PascalCase.php` | `ItemModel.php` | +| YAML workflow | `kebab-case.yml` | `ci-joomla.yml` | +| Markdown doc | `kebab-case.md` | `installation-guide.md` | + +--- + +## Commit Messages + +Format: `(): ` โ€” imperative, lower-case subject, no trailing period. + +Valid types: `feat` ยท `fix` ยท `docs` ยท `chore` ยท `ci` ยท `refactor` ยท `style` ยท `test` ยท `perf` ยท `revert` ยท `build` + +--- + +## Branch Naming + +Format: `/[/description]` + +Approved prefixes: `dev/` ยท `rc/` ยท `version/` ยท `patch/` ยท `copilot/` ยท `dependabot/` + +--- + +## Keeping Documentation Current + +| Change type | Documentation to update | +|-------------|------------------------| +| New or renamed PHP class/method | PHPDoc block; `docs/api/` entry | +| New or changed manifest.xml | Update `updates.xml` version; bump README.md version | +| New release | Prepend `` block to `updates.xml`; update CHANGELOG.md; bump README.md version | +| New or changed workflow | `docs/workflows/.md` | +| Any modified file | Update the `VERSION` field in that file's `FILE INFORMATION` block | +| **Every PR** | **Bump the patch version** โ€” increment `XX.YY.ZZ` in `README.md`; `sync-version-on-merge` propagates it | + +--- + +## Key Constraints + +- Never commit directly to `main` โ€” all changes go via PR, squash-merged +- Never skip the FILE INFORMATION block on a new file +- Never add `defined('_JEXEC') or die;` to CLI scripts or model tests โ€” only to web-accessible PHP files +- Never hardcode version numbers in body text โ€” update `README.md` and let automation propagate +- Never use `github.token` or `secrets.GITHUB_TOKEN` in workflows โ€” always use `secrets.GH_TOKEN` +- Never let `manifest.xml` version, `updates.xml` version, and `README.md` version go out of sync diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index e9c2570..5acbe07 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -8,7 +8,7 @@ # REPO: https://github.com/mokoconsulting-tech/MokoStandards # PATH: /templates/workflows/joomla/auto-release.yml.template # VERSION: 04.05.13 -# BRIEF: Joomla build & release โ€” ZIP package, update.xml, SHA-256 checksum +# BRIEF: Joomla build & release โ€” ZIP package, updates.xml, SHA-256 checksum # # +========================================================================+ # | BUILD & RELEASE PIPELINE (JOOMLA) | @@ -20,10 +20,10 @@ # | 1. Read version from README.md | # | 3. Set platform version (Joomla ) | # | 4. Update [VERSION: XX.YY.ZZ] badges in markdown files | -# | 5. Write update.xml (Joomla update server XML) | +# | 5. Write updates.xml (Joomla update server XML) | # | 6. Create git tag vXX.YY.ZZ | # | 7a. Patch: update existing GitHub Release for this minor | -# | 8. Build ZIP, upload asset, write SHA-256 to update.xml | +# | 8. Build ZIP, upload asset, write SHA-256 to updates.xml | # | | # | Every version change: archives main -> version/XX.YY branch | # | Patch 00 = development (no release). First release = patch 01. | @@ -39,6 +39,9 @@ on: branches: - main - master + paths: + - 'src/**' + - 'htdocs/**' env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true @@ -256,8 +259,8 @@ jobs: fi done - # -- STEP 5: Write update.xml (Joomla update server) --------------------- - - name: "Step 5: Write update.xml" + # -- STEP 5: Write updates.xml (Joomla update server) --------------------- + - name: "Step 5: Write updates.xml" if: >- steps.version.outputs.skip != 'true' && steps.check.outputs.already_released != 'true' @@ -268,7 +271,7 @@ jobs: # -- Parse extension metadata from XML manifest ---------------- MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1) if [ -z "$MANIFEST" ]; then - echo "Warning: No Joomla XML manifest found โ€” skipping update.xml" >> $GITHUB_STEP_SUMMARY + echo "Warning: No Joomla XML manifest found โ€” skipping updates.xml" >> $GITHUB_STEP_SUMMARY exit 0 fi @@ -313,7 +316,7 @@ jobs: DOWNLOAD_URL="https://github.com/${REPO}/releases/download/v${VERSION}/${EXT_ELEMENT}-${VERSION}.zip" INFO_URL="https://github.com/${REPO}/releases/tag/v${VERSION}" - # -- Write update.xml (stable release) -------------------------- + # -- Write updates.xml (stable release) -------------------------- { printf '%s\n' '' printf '%s\n' '' @@ -338,9 +341,9 @@ jobs: printf '%s\n' ' https://mokoconsulting.tech' printf '%s\n' ' ' printf '%s\n' '' - } > update.xml + } > updates.xml - echo "update.xml: ${VERSION} (stable) โ€” ${EXT_TYPE}/${EXT_ELEMENT}" >> $GITHUB_STEP_SUMMARY + echo "updates.xml: ${VERSION} (stable) โ€” ${EXT_TYPE}/${EXT_ELEMENT}" >> $GITHUB_STEP_SUMMARY # -- Commit all changes --------------------------------------------------- - name: Commit release changes @@ -469,19 +472,19 @@ jobs: gh release upload "$RELEASE_TAG" "/tmp/${PACKAGE_NAME}" 2>/dev/null || true } - # -- Update update.xml with SHA-256 for latest patch ------------- - if [ -f "update.xml" ]; then - if grep -q '' update.xml; then - sed -i "s|.*|sha256:${SHA256}|" update.xml + # -- Update updates.xml with SHA-256 for latest patch ------------- + if [ -f "updates.xml" ]; then + if grep -q '' updates.xml; then + sed -i "s|.*|sha256:${SHA256}|" updates.xml else - sed -i "s||\n sha256:${SHA256}|" update.xml + sed -i "s||\n sha256:${SHA256}|" updates.xml fi # Also update the download URL to point to this patch's ZIP DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${RELEASE_TAG}/${PACKAGE_NAME}" - sed -i "s|]*>[^<]*|${DOWNLOAD_URL}|" update.xml + sed -i "s|]*>[^<]*|${DOWNLOAD_URL}|" updates.xml - git add update.xml + git add updates.xml git commit -m "chore(release): SHA-256 + download URL for ${VERSION} [skip ci]" \ --author="github-actions[bot] " || true git push || true