> [!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 | > |---|---| > | `{{REPO_NAME}}` | The GitHub repository name (visible in the URL, `README.md` heading, or `git remote -v`) | > | `{{REPO_URL}}` | Full GitHub URL, e.g. `https://git.mokoconsulting.tech/mokoconsulting-tech/` | > | `{{PRIMARY_LANGUAGE}}` | The dominant programming language (check file extensions in the repository) | > | `{{PLATFORM_TYPE}}` | The project type: `PHP library`, `Joomla extension`, `Dolibarr module`, `WaaS site`, etc. — infer from repo structure | > > --- # {{REPO_NAME}} — GitHub Copilot Custom Instructions ## What This Repo Is This is a **Moko Consulting** repository governed by [MokoStandards](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards). All coding standards, workflows, and policies are defined there and enforced here via bulk sync. Repository URL: {{REPO_URL}} Primary language: **{{PRIMARY_LANGUAGE}}** Platform type: **{{PLATFORM_TYPE}}** --- ## Primary Language **{{PRIMARY_LANGUAGE}} is the primary language for this repository.** Follow the conventions documented in [MokoStandards coding-style-guide](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/coding-style-guide.md). YAML uses 2-space indentation (spaces, not tabs). 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. Use the minimal form unless the file is a policy doc, README, or public API. **PHP:** ```php * * This file is part of a Moko Consulting project. * * SPDX-License-Identifier: GPL-3.0-or-later * * FILE INFORMATION * DEFGROUP: {{REPO_NAME}}.Module * INGROUP: {{REPO_NAME}} * REPO: {{REPO_URL}} * PATH: /path/to/file.php * VERSION: XX.YY.ZZ * BRIEF: One-line description of purpose */ declare(strict_types=1); ``` **Markdown:** ```markdown ``` **YAML / Shell:** Use `#` comments with the same fields. JSON files are exempt. --- ## 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 automatically to all badges and `FILE INFORMATION` headers on merge to `main`. - The `VERSION: XX.YY.ZZ` field in the README.md `FILE INFORMATION` block governs all other version references. - Update the version in `README.md` only — the `sync-version-on-merge` workflow propagates it automatically to all badges and `FILE INFORMATION` headers on merge to `main`. - Version format is zero-padded semver: `XX.YY.ZZ` (e.g. `04.00.04`). - Never hardcode a specific version in document body text — use the badge or FILE INFORMATION header only. ### Badge Colors Each badge type has a designated color — no two types share the same color: | Badge | Color | Example | |-------|-------|---------| | Version | `blue` | `badge/version-XX.YY.ZZ-blue?logo=v` | | License | `green` | `badge/license-GPL--3.0-green` | | PHP | `777BB4` | `badge/PHP-8.2%2B-777BB4?logo=php` | | Joomla | `red` | `badge/Joomla-5.x-red?logo=joomla` | | Dolibarr | `red` | `badge/Dolibarr-20.x-red` | | MokoStandards | `orange` | `badge/MokoStandards-04.06.00-orange` | --- ## GitHub Actions — Token Usage Every workflow must use **`secrets.GH_TOKEN`** (the org-level Personal Access Token). This applies to all `actions/checkout`, `gh` CLI calls, and any step that talks to the GitHub API. ```yaml # ✅ Correct - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 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 }} ``` PHP scripts read the token with: `getenv('GH_TOKEN') ?: getenv('GITHUB_TOKEN')` — `GH_TOKEN` is always preferred; `GITHUB_TOKEN` is accepted only as a local-dev fallback. --- ## Composer Package (PHP repositories) This repository requires the MokoStandards enterprise library. The `composer.json` must include: ```json { "repositories": [ { "type": "vcs", "url": "https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards" } ], "require": { "mokoconsulting/mokostandards": "^4.0" } } ``` Run `composer install` after adding the dependency. See [package-installation.md](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards/blob/main/docs/guide/package-installation.md) for full instructions. --- ## PHP Script Pattern All PHP scripts **must** extend `MokoStandards\Enterprise\CliFramework`. Never write standalone classes or extend the legacy `CliBase`. ```php #!/usr/bin/env php setDescription('One-line description'); $this->addArgument('--path', 'Repository root', '.'); $this->addArgument('--dry-run', 'Preview without writing', false); } protected function run(): int { $path = $this->getArgument('--path'); $dryRun = (bool) $this->getArgument('--dry-run'); $this->log('INFO', "Processing: {$path}"); return 0; } } $script = new MyScript('my_script', 'One-line description'); exit($script->execute()); ``` **Key rules:** - Abstract methods to implement: `configure()` and `run()` — **not** `execute()` - `execute()` is the **public entry point** that orchestrates setup (arg parsing, `initialize()`) and then calls your `run()` implementation; call it at the bottom with `exit($script->execute())` - Entry point at the bottom: `$script->execute()` — **not** `$script->run()` - Constructor always takes `(string $name, string $description = '')`; pass the description here — `setDescription()` inside `configure()` is only needed to override it - `log(string $level, string $message)` — level is the **first** argument (INFO / SUCCESS / WARNING / ERROR) - `$this->dryRun` and `$this->verbose` are set automatically from `--dry-run` / `--verbose` --- ## Naming Conventions | Context | Convention | Example | |---------|-----------|---------| | PHP class | `PascalCase` | `MyService` | | PHP method / function | `camelCase` | `getUserData()` | | PHP variable | `$snake_case` | `$repo_path` | | PHP constant | `UPPER_SNAKE_CASE` | `DEFAULT_THRESHOLD` | | PHP class file | `PascalCase.php` | `ApiClient.php` | | PHP script file | `snake_case.php` | `check_health.php` | | YAML workflow | `kebab-case.yml` | `bulk-repo-sync.yml` | | Markdown doc | `kebab-case.md` | `coding-style-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` Examples: - `feat(module): add user preference caching` - `fix(api): handle null response from external service` - `docs(readme): update installation instructions` - `chore(deps): bump phpunit to 11.x` --- ## Branch Naming Approved prefixes: `dev/` · `alpha/` · `beta/` · `rc/` · `version/` · `copilot/` · `dependabot/` Pipeline: `dev → [alpha] → [beta] → rc → version/XX → main → dev` - Alpha and beta are optional — dev can go straight to rc - `dev/XX.YY` or `dev/feature-name` — development (version optional) - `alpha/XX.YY.ZZ` — early internal testing (optional, three-part required) - `beta/XX.YY.ZZ` — broader external testing (optional, three-part required) - `rc/XX.YY.ZZ` — release candidate (three-part required) - `version/XX` — major version integration branch (major only, e.g., `version/04`) - Release tags: `vXX` (major only — one release per major version) - Pre-release tags: `development` · `alpha` · `beta` · `release-candidate` - Patch `00` = development (no release), first release = `01` Examples: - ✅ `dev/04.06` · `dev/new-dashboard` · `alpha/04.06.01` · `beta/04.06.01` · `rc/04.06.01` - ❌ `feature/my-thing` — rejected by branch protection --- ## Keeping Documentation Current Whenever you make code changes, update the corresponding documentation in the same commit or PR. Do not leave docs stale. | Change type | Documentation to update | |-------------|------------------------| | New or renamed public PHP method | PHPDoc block on the method; `docs/api/` index for that class | | New or changed CLI script argument | Script's own `--help` text; `docs/api/` or equivalent | | New or changed GitHub Actions workflow | `docs/workflows/.md` | | New or changed policy | Corresponding file under `docs/policy/` | | New library class or major feature | `CHANGELOG.md` entry under `Added` | | Bug fix | `CHANGELOG.md` entry under `Fixed` | | Breaking change | `CHANGELOG.md` entry under `Changed`; update `CONTRIBUTING.md` if contributor steps change | | 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 to all headers and badges on merge | If your code change makes any existing doc sentence false or incomplete, fix the doc before closing the PR. --- ## 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 use bare `catch (\Throwable $e) {}` without logging or re-throwing - 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 extend `CliBase` in PHP scripts — extend `MokoStandards\Enterprise\CliFramework` - Never call `$script->run()` as the entry point — call `$script->execute()` - Policy documents and guides must not be mixed --- ## MokoStandards Reference This repository is governed by [MokoStandards](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards). Authoritative policies: | Document | Purpose | |----------|---------| | [file-header-standards.md](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/file-header-standards.md) | Copyright-header rules for every file type | | [coding-style-guide.md](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/coding-style-guide.md) | Naming and formatting conventions | | [branching-strategy.md](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/branching-strategy.md) | Branch naming, hierarchy, and release workflow | | [merge-strategy.md](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/merge-strategy.md) | Squash-merge policy and PR title/body conventions | | [changelog-standards.md](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/changelog-standards.md) | How and when to update CHANGELOG.md | | [scripting-standards.md](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards/blob/main/docs/policy/scripting-standards.md) | PHP script requirements and CliFramework usage | | [package-installation.md](https://git.mokoconsulting.tech/mokoconsulting-tech/MokoStandards/blob/main/docs/guide/package-installation.md) | Installing `mokoconsulting/mokostandards` via Composer |