From 3f2e7a64f30026e97397b4044555c21f770b52bb Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Thu, 16 Jul 2026 19:08:27 -0500 Subject: [PATCH 1/2] feat(workflow-sync): add --phase health drift detection + --repo-filter [#350] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Read-only health check that flags repos missing their synced .mokogit/workflows/ (non-zero exit) with optional critical ntfy push (--alert-ntfy) and auto-filed Git issue (--alert-issue). Adds --repo-filter to scope sync/health. Registers workflow:sync in bin/moko. Ported from the superseded PR #356 onto current main (the rest of #356 — rebrand, manifest retirement, template maps — already landed on main via #317-#355). --- CHANGELOG.md | 4 + bin/moko | 1 + cli/workflow_sync.php | 316 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 318 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d891950..9fb5c2f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ BRIEF: Release changelog ## [Unreleased] +### Added +- `workflow_sync.php`: `--phase health` — read-only drift detection that flags repos missing their synced `.mokogit/workflows/`, with a non-zero exit plus optional critical ntfy push (`--alert-ntfy`) and auto-filed Git issue (`--alert-issue`). +- `workflow_sync.php`: `--repo-filter` to scope sync/health to specific repos. + ## [09.42.00] --- 2026-07-04 ### Fixed diff --git a/bin/moko b/bin/moko index 21bff3c6..63ba3252 100644 --- a/bin/moko +++ b/bin/moko @@ -185,6 +185,7 @@ const COMMAND_MAP = [ // Bulk operations 'bulk:push-workflow' => 'cli/bulk_workflow_push.php', 'bulk:trigger' => 'cli/bulk_workflow_trigger.php', + 'workflow:sync' => 'cli/workflow_sync.php', 'bulk:sync-rulesets' => 'cli/sync_rulesets.php', 'bulk:push-files' => 'automation/push_files.php', 'bulk:push-manifest' => 'automation/push_manifest_xml.php', diff --git a/cli/workflow_sync.php b/cli/workflow_sync.php index 311baa70..0a1ad19d 100644 --- a/cli/workflow_sync.php +++ b/cli/workflow_sync.php @@ -59,6 +59,13 @@ class WorkflowSyncCli extends CliFramework /** Prefix for custom workflows preserved during orphan cleanup. */ private const CUSTOM_PREFIX = 'custom-'; + /** Default ntfy endpoint for critical drift alerts (matches notify.yml / gitleaks.yml). */ + private const DEFAULT_NTFY_URL = 'https://ntfy.mokoconsulting.tech'; + private const DEFAULT_NTFY_TOPIC = 'mokogit-ops'; + + /** Marker in auto-filed health issues, used for idempotency. */ + private const HEALTH_ISSUE_MARKER = '[workflow-health]'; + private int $updated = 0; private int $created = 0; private int $skipped = 0; @@ -72,9 +79,16 @@ class WorkflowSyncCli extends CliFramework $this->addArgument('--token', 'Git API token', ''); $this->addArgument('--org', 'Target organization', ''); $this->addArgument('--branch', 'Target branch (default: main)', 'main'); - $this->addArgument('--phase', 'Phase to run: all, templates, repos (default: all)', 'all'); + $this->addArgument('--phase', 'Phase to run: all, templates, repos, health (default: all)', 'all'); $this->addArgument('--platform-filter', 'Only sync repos matching this platform', ''); + $this->addArgument('--repo-filter', 'Only sync/check these repos (comma-separated names)', ''); $this->addArgument('--delete-orphans', 'Delete workflows not in template (preserves custom-* and custom/)', false); + + // Health-check (--phase health) options — read-only unless an alert flag is set. + $this->addArgument('--alert-ntfy', 'On drift, send a critical ntfy push notification', false); + $this->addArgument('--ntfy-url', 'ntfy server URL', self::DEFAULT_NTFY_URL); + $this->addArgument('--ntfy-topic', 'ntfy topic', self::DEFAULT_NTFY_TOPIC); + $this->addArgument('--alert-issue', 'On drift, open/update a Git issue on each affected repo', false); } protected function run(): int @@ -96,11 +110,16 @@ class WorkflowSyncCli extends CliFramework return 1; } - if (!in_array($phase, ['all', 'templates', 'repos'], true)) { - $this->log('ERROR', "--phase must be one of: all, templates, repos (got: {$phase})"); + if (!in_array($phase, ['all', 'templates', 'repos', 'health'], true)) { + $this->log('ERROR', "--phase must be one of: all, templates, repos, health (got: {$phase})"); return 1; } + // Health-check is a standalone, read-only phase — it never syncs. + if ($phase === 'health') { + return $this->runHealthCheck($gitUrl, $token, $org, $branch, $platformFilter); + } + $this->log('INFO', "Workflow Sync — org: {$org}, branch: {$branch}, phase: {$phase}"); if ($platformFilter !== '') { @@ -240,6 +259,12 @@ class WorkflowSyncCli extends CliFramework $this->log('INFO', '=== Phase 2: Sync Platform Templates → Live Repos ==='); echo "\n"; + $repoFilter = $this->parseRepoFilter(); + + if ($repoFilter !== []) { + $this->log('INFO', 'Repo filter: ' . implode(', ', $repoFilter)); + } + $repos = $this->fetchOrgRepos($gitUrl, $token, $org); if ($repos === null) { @@ -263,6 +288,11 @@ class WorkflowSyncCli extends CliFramework continue; } + // Apply repo filter + if ($repoFilter !== [] && !in_array($repoName, $repoFilter, true)) { + continue; + } + // Read manifest.platform $platform = $this->getRepoPlatform($gitUrl, $token, $org, $repoName, $branch); @@ -692,6 +722,286 @@ class WorkflowSyncCli extends CliFramework return $repos; } + // ========================================================================= + // Phase: health — read-only drift detection + alerting + // ========================================================================= + + /** + * Parse --repo-filter into a list of repo names (empty ⇒ no filter). + * + * @return string[] + */ + private function parseRepoFilter(): array + { + $raw = (string) $this->getArgument('--repo-filter'); + + return array_values(array_filter(array_map('trim', explode(',', $raw)), fn($n) => $n !== '')); + } + + /** + * Health-check phase: verify every live repo still has the synced workflows its + * platform template provides, and (optionally) alert on drift. Fails loudly + * (non-zero exit) when a repo is missing its canonical set, so a scheduled job, + * an ntfy push, and/or a Git issue surface silent loss instead of it rotting. + */ + private function runHealthCheck( + string $gitUrl, + string $token, + string $org, + string $branch, + string $platformFilter + ): int { + $alertNtfy = (bool) $this->getArgument('--alert-ntfy'); + $alertIssue = (bool) $this->getArgument('--alert-issue'); + $ntfyUrl = rtrim((string) $this->getArgument('--ntfy-url'), '/'); + $ntfyTopic = (string) $this->getArgument('--ntfy-topic'); + $repoFilter = $this->parseRepoFilter(); + + $this->log('INFO', "Workflow Health-Check — org: {$org}, branch: {$branch}"); + + if ($platformFilter !== '') { + $this->log('INFO', "Platform filter: {$platformFilter}"); + } + if ($repoFilter !== []) { + $this->log('INFO', 'Repo filter: ' . implode(', ', $repoFilter)); + } + + echo "\n"; + + $repos = $this->fetchOrgRepos($gitUrl, $token, $org); + + if ($repos === null) { + return self::EXIT_FAILURE; + } + + $this->log('INFO', 'Scanning ' . count($repos) . " repo(s) in \"{$org}\"."); + echo "\n"; + + $templateCache = []; + $unhealthy = []; + $checked = 0; + + foreach ($repos as $repoFullName) { + [, $repoName] = explode('/', $repoFullName, 2); + + if (str_starts_with($repoName, 'Template-')) { + continue; + } + + $platform = $this->getRepoPlatform($gitUrl, $token, $org, $repoName, $branch); + + if ($platformFilter !== '' && $platform !== $platformFilter) { + continue; + } + if ($repoFilter !== [] && !in_array($repoName, $repoFilter, true)) { + continue; + } + + // A repo that has no such branch is out of scope for this run, not unhealthy. + if (!$this->branchExists($gitUrl, $token, $org, $repoName, $branch)) { + continue; + } + + $templateRepo = self::PLATFORM_TEMPLATES[$platform] ?? self::DEFAULT_TEMPLATE; + + // Expected set = the template's workflows (cached), minus platform excludes. + // Do NOT fall back to Generic on an unreachable template — that assesses against + // the wrong baseline. Record null (missing) distinctly. + if (!array_key_exists($templateRepo, $templateCache)) { + $tpl = $this->listWorkflows($gitUrl, $token, $org, $templateRepo, $branch); + $templateCache[$templateRepo] = $tpl === null + ? null + : array_map(fn($w) => $w['name'], $tpl); + } + + if ($templateCache[$templateRepo] === null) { + $this->log('WARN', "Template '{$templateRepo}' for platform '{$platform}' is unreachable" + . " — cannot assess {$repoName}."); + continue; + } + + $expected = array_values(array_diff( + $templateCache[$templateRepo], + self::PLATFORM_EXCLUDES[$platform] ?? [] + )); + + if (count($expected) === 0) { + continue; + } + + $repoList = $this->listWorkflows($gitUrl, $token, $org, $repoName, $branch); + $actual = array_map(fn($w) => $w['name'], $repoList ?? []); + + $missing = $this->evaluateRepoHealth($expected, $actual); + $checked++; + + if (count($missing) > 0) { + $unhealthy[$repoName] = [ + 'full' => $repoFullName, + 'platform' => $platform, + 'expected' => count($expected), + 'present' => count(array_intersect($expected, $actual)), + 'missing' => $missing, + ]; + } + } + + echo "\n"; + + if (count($unhealthy) === 0) { + $this->success("All {$checked} in-scope repo(s) have their synced workflows on '{$branch}'."); + return self::EXIT_SUCCESS; + } + + $rows = []; + + foreach ($unhealthy as $repo => $info) { + $rows[] = [$repo, $info['platform'], "{$info['present']}/{$info['expected']}", (string) count($info['missing'])]; + } + + $this->log('ERROR', count($unhealthy) . " of {$checked} repo(s) are MISSING synced workflows on '{$branch}':"); + $this->table(['Repo', 'Platform', 'Present', 'Missing'], $rows); + + if ($alertNtfy) { + $this->sendNtfyAlert($ntfyUrl, $ntfyTopic, $org, $branch, $unhealthy); + } + if ($alertIssue) { + foreach ($unhealthy as $repo => $info) { + $this->openHealthIssue($gitUrl, $token, $org, $repo, $branch, $info); + } + } + + return self::EXIT_FAILURE; + } + + /** + * Health verdict policy — given the workflows a repo SHOULD have (its platform + * template's set, minus excludes) and what it ACTUALLY has, return the missing + * filenames. Non-empty ⇒ unhealthy. Extra/custom files are ignored. + * + * @param string[] $expected + * @param string[] $actual + * @return string[] + */ + private function evaluateRepoHealth(array $expected, array $actual): array + { + return array_values(array_diff($expected, $actual)); + } + + /** + * Return true when the given branch exists in the repo. + */ + private function branchExists( + string $gitUrl, + string $token, + string $org, + string $repoName, + string $branch + ): bool { + $response = $this->apiRequest($gitUrl, $token, 'GET', "/api/v1/repos/{$org}/{$repoName}/branches/{$branch}"); + + return $response['code'] === 200; + } + + /** + * Send a critical ntfy push notification about drift (matches notify.yml headers). + */ + private function sendNtfyAlert( + string $ntfyUrl, + string $topic, + string $org, + string $branch, + array $unhealthy + ): void { + if ($ntfyUrl === '' || $topic === '') { + $this->warn('ntfy alert requested but --ntfy-url/--ntfy-topic is empty; skipping.'); + return; + } + + $count = count($unhealthy); + $names = implode(', ', array_keys($unhealthy)); + $title = "Workflow drift: {$count} repo(s) missing workflows"; + $body = "Org {$org} ({$branch}): {$count} repo(s) missing synced .mokogit/workflows/.\n{$names}"; + + if ($this->dryRun) { + $this->log('INFO', "[DRY RUN] Would send critical ntfy to {$ntfyUrl}/{$topic}: {$title}"); + return; + } + + $ch = curl_init("{$ntfyUrl}/{$topic}"); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + "Title: {$title}", + 'Priority: urgent', + 'Tags: rotating_light,warning', + ]); + curl_exec($ch); + $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($code >= 200 && $code < 300) { + $this->success("Sent critical ntfy alert to {$ntfyUrl}/{$topic}."); + } else { + $this->warn("ntfy alert failed (HTTP {$code})."); + } + } + + /** + * Open a Git issue on an affected repo describing the missing workflows. + * Idempotent: skips if an open issue carrying the marker already exists. + */ + private function openHealthIssue( + string $gitUrl, + string $token, + string $org, + string $repoName, + string $branch, + array $info + ): void { + $existing = $this->apiRequest( + $gitUrl, $token, 'GET', + "/api/v1/repos/{$org}/{$repoName}/issues?state=open&type=issues&limit=50" + ); + + if ($existing['code'] === 200) { + $issues = json_decode($existing['body'], true) ?: []; + + foreach ($issues as $iss) { + if (str_contains((string) ($iss['title'] ?? ''), self::HEALTH_ISSUE_MARKER)) { + $this->log('INFO', "{$repoName}: health issue already open (#{$iss['number']}), skipping."); + return; + } + } + } + + $missingList = implode("\n", array_map(fn($f) => "- `{$f}`", $info['missing'])); + $title = self::HEALTH_ISSUE_MARKER . " Missing synced workflows on {$branch}"; + $body = 'Automated health-check found this repository is missing ' + . count($info['missing']) . " workflow(s) that its platform template " + . "(`{$info['platform']}`) provides in `.mokogit/workflows/` on `{$branch}`:\n\n" + . $missingList + . "\n\nRestore with:\n\n```\nphp bin/moko workflow:sync --org {$org} --branch {$branch} --token \$TOKEN\n```" + . "\n\nFiled by workflow_sync.php --phase health."; + + if ($this->dryRun) { + $this->log('INFO', "[DRY RUN] Would open health issue on {$org}/{$repoName}."); + return; + } + + $payload = json_encode(['title' => $title, 'body' => $body]); + + $resp = $this->apiRequest($gitUrl, $token, 'POST', "/api/v1/repos/{$org}/{$repoName}/issues", $payload); + + if ($resp['code'] === 201) { + $data = json_decode($resp['body'], true); + $this->success("Opened health issue {$org}/{$repoName}#" . ($data['number'] ?? '?') . '.'); + } else { + $this->warn("Failed to open issue on {$org}/{$repoName} (HTTP {$resp['code']})."); + } + } + /** * Make an HTTP request to the Git API. */ -- 2.52.0 From 99d55b63afbf4e07892fffe70b2d062695b8b576 Mon Sep 17 00:00:00 2001 From: "git-actions[bot]" Date: Fri, 17 Jul 2026 00:08:48 +0000 Subject: [PATCH 2/2] chore(version): auto-bump patch 09.45.01-dev [skip ci] --- .mokogit/workflows/issue-branch.yml | 2 +- README.md | 2 +- cli/branch_rename.php | 2 +- cli/bulk_workflow_push.php | 2 +- cli/bulk_workflow_trigger.php | 2 +- cli/client_dashboard.php | 2 +- cli/client_inventory.php | 2 +- cli/client_provision.php | 2 +- cli/grafana_dashboard.php | 2 +- cli/joomla_build.php | 2 +- cli/joomla_metadata_validate.php | 2 +- cli/manifest_detect.php | 2 +- cli/manifest_integrity.php | 2 +- cli/manifest_licensing.php | 2 +- cli/manifest_read.php | 2 +- cli/platform_detect.php | 2 +- cli/release_cascade.php | 2 +- cli/release_publish.php | 2 +- cli/scaffold_client.php | 2 +- cli/updates_xml_sync.php | 2 +- cli/version_auto_bump.php | 2 +- cli/version_bump.php | 2 +- cli/version_check.php | 2 +- cli/wiki_sync.php | 2 +- cli/workflow_sync.php | 2 +- deploy/backup-before-deploy.php | 2 +- deploy/deploy-dolibarr.php | 2 +- deploy/health-check.php | 2 +- deploy/rollback-joomla.php | 2 +- deploy/sync-joomla.php | 2 +- mcp/servers/mokocrm_api/CONTRIBUTING.md | 2 +- mcp/servers/mokocrm_api/SECURITY.md | 2 +- mcp/servers/mokosuite_api/CONTRIBUTING.md | 2 +- mcp/servers/mokosuite_api/SECURITY.md | 2 +- tests/Unit/VersionBumpTest.php | 2 +- tests/Unit/VersionReadTest.php | 4 ++-- validate/check_file_integrity.php | 2 +- 37 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.mokogit/workflows/issue-branch.yml b/.mokogit/workflows/issue-branch.yml index e736ca81..7cda27a0 100644 --- a/.mokogit/workflows/issue-branch.yml +++ b/.mokogit/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: MokoGIT.Workflow # INGROUP: MokoCLI.Automation -# VERSION: 01.00.00 +# VERSION: 09.45.01 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/README.md b/README.md index 987a0b54..1c923607 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ DEFGROUP: MokoCLI.Root INGROUP: MokoCLI REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli PATH: /README.md -VERSION: 09.45.00 +VERSION: 09.45.01 BRIEF: Project overview and documentation --> diff --git a/cli/branch_rename.php b/cli/branch_rename.php index ab1b0ea1..27089626 100644 --- a/cli/branch_rename.php +++ b/cli/branch_rename.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/branch_rename.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Rename a git branch via Git API (create new, update PR, delete old) */ diff --git a/cli/bulk_workflow_push.php b/cli/bulk_workflow_push.php index 77a11bae..98bf6c34 100644 --- a/cli/bulk_workflow_push.php +++ b/cli/bulk_workflow_push.php @@ -12,7 +12,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/bulk_workflow_push.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Push a workflow file to all governed repos via the Git Contents API */ diff --git a/cli/bulk_workflow_trigger.php b/cli/bulk_workflow_trigger.php index c12ffc84..40d1b89f 100644 --- a/cli/bulk_workflow_trigger.php +++ b/cli/bulk_workflow_trigger.php @@ -12,7 +12,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/bulk_workflow_trigger.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Trigger a workflow across multiple repos at once */ diff --git a/cli/client_dashboard.php b/cli/client_dashboard.php index 53de6f72..c079037a 100644 --- a/cli/client_dashboard.php +++ b/cli/client_dashboard.php @@ -12,7 +12,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/client_dashboard.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Generate unified client dashboard HTML */ diff --git a/cli/client_inventory.php b/cli/client_inventory.php index fd28e9bb..5583b678 100644 --- a/cli/client_inventory.php +++ b/cli/client_inventory.php @@ -12,7 +12,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/client_inventory.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Discover and list all client-waas repos with their server configuration status */ diff --git a/cli/client_provision.php b/cli/client_provision.php index a41ab1df..cb1f52b0 100644 --- a/cli/client_provision.php +++ b/cli/client_provision.php @@ -12,7 +12,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/client_provision.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Provision a new client environment end-to-end */ diff --git a/cli/grafana_dashboard.php b/cli/grafana_dashboard.php index 7ff707e8..fa493329 100644 --- a/cli/grafana_dashboard.php +++ b/cli/grafana_dashboard.php @@ -12,7 +12,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/grafana_dashboard.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Manage Grafana dashboards via API */ diff --git a/cli/joomla_build.php b/cli/joomla_build.php index 7a8b8217..77e119a2 100644 --- a/cli/joomla_build.php +++ b/cli/joomla_build.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/joomla_build.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Build a Joomla extension ZIP from manifest — all types supported * NOTE: Called by pre-release and auto-release workflows. */ diff --git a/cli/joomla_metadata_validate.php b/cli/joomla_metadata_validate.php index 5b56c9ac..a5300035 100644 --- a/cli/joomla_metadata_validate.php +++ b/cli/joomla_metadata_validate.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/joomla_metadata_validate.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Validate MokoGIT repo metadata against Joomla extension manifest XML */ diff --git a/cli/manifest_detect.php b/cli/manifest_detect.php index 86800d4a..e0ffdfb4 100644 --- a/cli/manifest_detect.php +++ b/cli/manifest_detect.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/manifest_detect.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Auto-detect manifest fields from source files and optionally push to API */ diff --git a/cli/manifest_integrity.php b/cli/manifest_integrity.php index 3393c616..462f9eeb 100644 --- a/cli/manifest_integrity.php +++ b/cli/manifest_integrity.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/manifest_integrity.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Cross-check manifest API fields against repo contents across the org */ diff --git a/cli/manifest_licensing.php b/cli/manifest_licensing.php index d247759e..a7169ec0 100644 --- a/cli/manifest_licensing.php +++ b/cli/manifest_licensing.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/manifest_licensing.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Ensure licensing tags (updateservers, dlid) in Joomla extension manifests */ diff --git a/cli/manifest_read.php b/cli/manifest_read.php index a864708c..a1e9fa2f 100644 --- a/cli/manifest_read.php +++ b/cli/manifest_read.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/manifest_read.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Read repo metadata from Git manifest API, auto-detect the rest */ diff --git a/cli/platform_detect.php b/cli/platform_detect.php index 4cb18b48..4892b65c 100644 --- a/cli/platform_detect.php +++ b/cli/platform_detect.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/platform_detect.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Auto-detect repository platform type and optionally update manifest */ diff --git a/cli/release_cascade.php b/cli/release_cascade.php index e4c9f080..4fc974cb 100644 --- a/cli/release_cascade.php +++ b/cli/release_cascade.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/release_cascade.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Cascade release zip to all lower stability channels */ diff --git a/cli/release_publish.php b/cli/release_publish.php index 7cd7f985..6e1b5c2f 100644 --- a/cli/release_publish.php +++ b/cli/release_publish.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/release_publish.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Publish a release and create copies for all lesser stability streams. */ diff --git a/cli/scaffold_client.php b/cli/scaffold_client.php index a88e1029..846ecd34 100644 --- a/cli/scaffold_client.php +++ b/cli/scaffold_client.php @@ -12,7 +12,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/scaffold_client.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Scaffold a new client-waas repo from Template-Client with pre-configured settings */ diff --git a/cli/updates_xml_sync.php b/cli/updates_xml_sync.php index b3c97c73..12e3a899 100644 --- a/cli/updates_xml_sync.php +++ b/cli/updates_xml_sync.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/updates_xml_sync.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Sync updates.xml to target branches via Git API * NOTE: Called by pre-release and auto-release workflows after updates.xml * is modified on the current branch. Pushes the file to other branches diff --git a/cli/version_auto_bump.php b/cli/version_auto_bump.php index 2a54dfef..b340fc90 100644 --- a/cli/version_auto_bump.php +++ b/cli/version_auto_bump.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/version_auto_bump.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Auto patch-bump, set stability suffix, and commit — single CLI replacing inline workflow bash */ diff --git a/cli/version_bump.php b/cli/version_bump.php index 2f0efafa..d6f26d2c 100644 --- a/cli/version_bump.php +++ b/cli/version_bump.php @@ -389,7 +389,7 @@ class VersionBumpCli extends CliFramework /** * Scan git release tags for the highest version across all channels. * - * Checks release names like "MokoSuiteClient (VERSION: 09.45.00)" in + * Checks release names like "MokoSuiteClient (VERSION: 09.45.01)" in * git tags (stable, release-candidate, development, etc.) to find the * highest version that has been released on any channel. */ diff --git a/cli/version_check.php b/cli/version_check.php index 6e551721..8979ee07 100644 --- a/cli/version_check.php +++ b/cli/version_check.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/version_check.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Validate version consistency across README, manifests, and sub-packages */ diff --git a/cli/wiki_sync.php b/cli/wiki_sync.php index 75d4b9ec..9842fa13 100644 --- a/cli/wiki_sync.php +++ b/cli/wiki_sync.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/wiki_sync.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Sync select wiki pages from mokocli to all template repos */ diff --git a/cli/workflow_sync.php b/cli/workflow_sync.php index 0a1ad19d..1e1514cd 100644 --- a/cli/workflow_sync.php +++ b/cli/workflow_sync.php @@ -10,7 +10,7 @@ * INGROUP: mokocli * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /cli/workflow_sync.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Sync workflows from Generic → platform templates → live repos based on manifest.platform */ diff --git a/deploy/backup-before-deploy.php b/deploy/backup-before-deploy.php index d304ac62..1d023155 100644 --- a/deploy/backup-before-deploy.php +++ b/deploy/backup-before-deploy.php @@ -12,7 +12,7 @@ * INGROUP: MokoCLI * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /deploy/backup-before-deploy.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Snapshot Joomla directories before deployment for rollback capability */ diff --git a/deploy/deploy-dolibarr.php b/deploy/deploy-dolibarr.php index 948c6a9b..af679279 100644 --- a/deploy/deploy-dolibarr.php +++ b/deploy/deploy-dolibarr.php @@ -12,7 +12,7 @@ * INGROUP: MokoCLI * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /deploy/deploy-dolibarr.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Deploy Dolibarr module files to a remote server via SFTP/rsync */ diff --git a/deploy/health-check.php b/deploy/health-check.php index 59c5f6ca..a84bbf62 100644 --- a/deploy/health-check.php +++ b/deploy/health-check.php @@ -12,7 +12,7 @@ * INGROUP: MokoCLI * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /deploy/health-check.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Post-deploy health check — verify a Joomla site is responding correctly */ diff --git a/deploy/rollback-joomla.php b/deploy/rollback-joomla.php index 4eeb7aec..19105f6f 100644 --- a/deploy/rollback-joomla.php +++ b/deploy/rollback-joomla.php @@ -12,7 +12,7 @@ * INGROUP: MokoCLI * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /deploy/rollback-joomla.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Rollback a Joomla deployment by restoring from a pre-deploy snapshot */ diff --git a/deploy/sync-joomla.php b/deploy/sync-joomla.php index f3e09637..0f5d2083 100644 --- a/deploy/sync-joomla.php +++ b/deploy/sync-joomla.php @@ -12,7 +12,7 @@ * INGROUP: MokoCLI * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /deploy/sync-joomla.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Sync Joomla site directories between two servers via rsync over SSH */ diff --git a/mcp/servers/mokocrm_api/CONTRIBUTING.md b/mcp/servers/mokocrm_api/CONTRIBUTING.md index c5200bbc..e833bd44 100644 --- a/mcp/servers/mokocrm_api/CONTRIBUTING.md +++ b/mcp/servers/mokocrm_api/CONTRIBUTING.md @@ -14,7 +14,7 @@ DEFGROUP: dolibarr-api-mcp.Documentation INGROUP: dolibarr-api-mcp REPO: https://git.mokoconsulting.tech/MokoConsulting/dolibarr-api-mcp - VERSION: 09.45.00 + VERSION: 09.45.01 PATH: ./CONTRIBUTING.md BRIEF: Contribution guidelines for the project --> diff --git a/mcp/servers/mokocrm_api/SECURITY.md b/mcp/servers/mokocrm_api/SECURITY.md index de339143..61b0095d 100644 --- a/mcp/servers/mokocrm_api/SECURITY.md +++ b/mcp/servers/mokocrm_api/SECURITY.md @@ -10,7 +10,7 @@ DEFGROUP: dolibarr-api-mcp.Documentation INGROUP: dolibarr-api-mcp REPO: https://git.mokoconsulting.tech/MokoConsulting/dolibarr-api-mcp PATH: /SECURITY.md -VERSION: 09.45.00 +VERSION: 09.45.01 BRIEF: Security vulnerability reporting and handling policy --> diff --git a/mcp/servers/mokosuite_api/CONTRIBUTING.md b/mcp/servers/mokosuite_api/CONTRIBUTING.md index b84d6409..88788e6e 100644 --- a/mcp/servers/mokosuite_api/CONTRIBUTING.md +++ b/mcp/servers/mokosuite_api/CONTRIBUTING.md @@ -14,7 +14,7 @@ DEFGROUP: INGROUP: Project.Documentation REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCli-Template-Generic - VERSION: 09.45.00 + VERSION: 09.45.01 PATH: ./CONTRIBUTING.md BRIEF: Contribution guidelines for the project --> diff --git a/mcp/servers/mokosuite_api/SECURITY.md b/mcp/servers/mokosuite_api/SECURITY.md index ead1c334..1252a77b 100644 --- a/mcp/servers/mokosuite_api/SECURITY.md +++ b/mcp/servers/mokosuite_api/SECURITY.md @@ -23,7 +23,7 @@ DEFGROUP: [PROJECT_NAME] INGROUP: [PROJECT_NAME].Documentation REPO: [REPOSITORY_URL] PATH: /SECURITY.md -VERSION: 09.45.00 +VERSION: 09.45.01 BRIEF: Security vulnerability reporting and handling policy --> diff --git a/tests/Unit/VersionBumpTest.php b/tests/Unit/VersionBumpTest.php index f0aa33cc..cf6e0d63 100644 --- a/tests/Unit/VersionBumpTest.php +++ b/tests/Unit/VersionBumpTest.php @@ -63,7 +63,7 @@ class VersionBumpTest extends TestCase { file_put_contents( "{$this->tmpDir}/README.md", - "\nSome content\n" + "\nSome content\n" ); $this->execute(); diff --git a/tests/Unit/VersionReadTest.php b/tests/Unit/VersionReadTest.php index 541ce243..77da06a0 100644 --- a/tests/Unit/VersionReadTest.php +++ b/tests/Unit/VersionReadTest.php @@ -34,7 +34,7 @@ class VersionReadTest extends TestCase { file_put_contents( "{$this->tmpDir}/README.md", - "# Test\n\n" + "# Test\n\n" ); $this->assertSame('02.03.04', trim($this->runScript())); @@ -68,7 +68,7 @@ class VersionReadTest extends TestCase { file_put_contents( "{$this->tmpDir}/README.md", - "\n" + "\n" ); mkdir("{$this->tmpDir}/src", 0755, true); file_put_contents( diff --git a/validate/check_file_integrity.php b/validate/check_file_integrity.php index a5caacf8..36485642 100644 --- a/validate/check_file_integrity.php +++ b/validate/check_file_integrity.php @@ -12,7 +12,7 @@ * INGROUP: MokoCLI * REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli * PATH: /validate/check_file_integrity.php - * VERSION: 09.45.00 + * VERSION: 09.45.01 * BRIEF: Compare deployed files on a remote server against the local repository to detect drift */ -- 2.52.0