Merge pull request 'feat: deploy:verify — deploy with auto health check and rollback (#147)' (#293) from feature/147-deploy-verify into main
Platform: mokoplatform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: mokoplatform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: mokoplatform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: mokoplatform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: mokoplatform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: mokoplatform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: mokoplatform CI / CI Summary (push) Blocked by required conditions
Platform: mokoplatform CI / Gate 1: Code Quality (push) Failing after 49s

This commit was merged in pull request #293.
This commit is contained in:
2026-06-21 04:46:21 +00:00
40 changed files with 384 additions and 39 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: mokocli.Automation
# VERSION: 01.00.00
# VERSION: 09.35.02
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
+1 -1
View File
@@ -6,7 +6,7 @@ DEFGROUP: MokoPlatform.Root
INGROUP: MokoPlatform
REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
PATH: /README.md
VERSION: 09.35.00
VERSION: 09.35.02
BRIEF: Project overview and documentation
-->
+1 -1
View File
@@ -13,7 +13,7 @@
* INGROUP: MokoPlatform.Scripts
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /automation/update_dependencies.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Cross-repo dependency update automation — scan, update, PR, auto-merge
*/
+1
View File
@@ -199,6 +199,7 @@ const COMMAND_MAP = [
'deploy:sftp' => 'deploy/deploy-sftp.php',
'deploy:backup' => 'deploy/backup-before-deploy.php',
'deploy:health-check' => 'deploy/health-check.php',
'deploy:verify' => 'deploy/deploy-and-verify.php',
'deploy:rollback' => 'deploy/rollback-joomla.php',
'deploy:sync' => 'deploy/sync-joomla.php',
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/branch_rename.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Rename a git branch via Gitea API (create new, update PR, delete old)
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/bulk_workflow_push.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Push a workflow file to all governed repos via the Gitea Contents API
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/bulk_workflow_trigger.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Trigger a workflow across multiple repos at once
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/client_dashboard.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Generate unified client dashboard HTML
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/client_inventory.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Discover and list all client-waas repos with their server configuration status
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/client_provision.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Provision a new client environment end-to-end
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/grafana_dashboard.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Manage Grafana dashboards via API
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/joomla_build.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Build a Joomla extension ZIP from manifest — all types supported
* NOTE: Called by pre-release and auto-release workflows.
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/joomla_metadata_validate.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Validate MokoGitea repo metadata against Joomla extension manifest XML
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/manifest_detect.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Auto-detect manifest fields from source files and optionally push to API
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/manifest_integrity.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Cross-check manifest API fields against repo contents across the org
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/manifest_licensing.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Ensure licensing tags (updateservers, dlid) in Joomla extension manifests
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/manifest_read.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Read repo metadata from Gitea manifest API, auto-detect the rest
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/platform_detect.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Auto-detect repository platform type and optionally update manifest
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokocli
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /cli/release_cascade.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Cascade release zip to all lower stability channels
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/release_publish.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Publish a release and create copies for all lesser stability streams.
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/scaffold_client.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Scaffold a new client-waas repo from Template-Client-WaaS with pre-configured settings
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/updates_xml_sync.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Sync updates.xml to target branches via Gitea 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
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/version_auto_bump.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Auto patch-bump, set stability suffix, and commit — single CLI replacing inline workflow bash
*/
+1 -1
View File
@@ -370,7 +370,7 @@ class VersionBumpCli extends CliFramework
/**
* Scan git release tags for the highest version across all channels.
*
* Checks release names like "MokoSuiteClient (VERSION: 09.35.00)" in
* Checks release names like "MokoSuiteClient (VERSION: 09.35.02)" in
* git tags (stable, release-candidate, development, etc.) to find the
* highest version that has been released on any channel.
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/version_check.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Validate version consistency across README, manifests, and sub-packages
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: mokoplatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /cli/wiki_sync.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Sync select wiki pages from mokoplatform to all template repos
*/
+1 -1
View File
@@ -10,7 +10,7 @@
* INGROUP: moko-platform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
* PATH: /cli/workflow_sync.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Sync workflows from Generic → platform templates → live repos based on manifest.platform
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: MokoPlatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /deploy/backup-before-deploy.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Snapshot Joomla directories before deployment for rollback capability
*/
+344
View File
@@ -0,0 +1,344 @@
#!/usr/bin/env php
<?php
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* FILE INFORMATION
* DEFGROUP: MokoPlatform.Scripts.Deploy
* INGROUP: MokoPlatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
* PATH: /deploy/deploy-and-verify.php
* BRIEF: Deploy with automatic health check and rollback on failure
*/
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../lib/Enterprise/CliFramework.php';
use MokoCli\{AuditLogger, CliFramework};
/**
* Deploy-and-Verify: orchestrates backup → deploy → health-check → rollback.
*
* If the health check fails after deployment, automatically triggers a rollback
* using the pre-deploy snapshot, with full audit trail.
*
* @see https://git.mokoconsulting.tech/MokoConsulting/mokocli/issues/147
*/
class DeployAndVerify extends CliFramework
{
private ?AuditLogger $auditLogger = null;
protected function configure(): void
{
$this->setDescription('Deploy with automatic health check and rollback on failure');
$this->addArgument('--path', 'Repository root', '.');
$this->addArgument('--env', 'Target environment: dev, demo, rs, live', '');
$this->addArgument('--config', 'Explicit sftp-config path (overrides --env)', '');
$this->addArgument('--url', 'Site URL for health check', '');
$this->addArgument('--checks', 'Health checks: http,admin,api (comma-sep)', 'http');
$this->addArgument('--timeout', 'Health check timeout in seconds', '30');
$this->addArgument('--retries', 'Health check retries before rollback', '2');
$this->addArgument('--delay', 'Seconds between health check retries', '5');
}
protected function run(): int
{
$path = realpath($this->getArgument('--path', '.')) ?: '.';
$env = $this->getArgument('--env', '');
$config = $this->getArgument('--config', '');
$url = $this->getArgument('--url', '');
$checks = $this->getArgument('--checks', 'http');
$timeout = (int) $this->getArgument('--timeout', '30');
$retries = (int) $this->getArgument('--retries', '2');
$delay = (int) $this->getArgument('--delay', '5');
if ($url === '') {
$this->log('ERROR', 'The --url argument is required for health checks');
return self::EXIT_USAGE;
}
if ($env === '' && $config === '') {
$this->log('ERROR', 'Specify --env or --config for the deploy target');
return self::EXIT_USAGE;
}
try {
$this->auditLogger = new AuditLogger('deploy-and-verify');
} catch (\Exception $e) {
// Non-fatal — proceed without audit logging
}
$this->audit('start', ['path' => $path, 'env' => $env, 'url' => parse_url($url, PHP_URL_HOST) ?? $url]);
// ── Build subprocess args ────────────────────────────────────
$deployArgs = $this->buildDeployArgs($path, $env, $config);
// ── Step 1: Backup ───────────────────────────────────────────
$this->section('Step 1: Pre-deploy backup');
$snapshotDir = sys_get_temp_dir() . '/moko_deploy_snapshot_' . date('Ymd_His') . '_' . getmypid() . '_' . bin2hex(random_bytes(4));
if ($this->dryRun) {
$this->log('INFO', "[dry-run] Would create snapshot at {$snapshotDir}");
} else {
$backupExit = $this->runSubprocess('backup-before-deploy.php', array_merge(
$deployArgs, ['--snapshot-dir', $snapshotDir]
));
if ($backupExit !== 0) {
$this->log('ERROR', 'Pre-deploy backup failed — aborting deployment');
$this->audit('backup_failed', ['exit_code' => $backupExit]);
return self::EXIT_FAILURE;
}
$this->log('INFO', "Snapshot saved to {$snapshotDir}");
}
// ── Step 2: Deploy ───────────────────────────────────────────
$this->section('Step 2: Deploy');
if ($this->dryRun) {
$this->log('INFO', '[dry-run] Would run deploy-sftp.php ' . implode(' ', $deployArgs));
} else {
$deployExit = $this->runSubprocess('deploy-sftp.php', $deployArgs);
if ($deployExit !== 0) {
$this->log('ERROR', 'Deploy failed — rolling back to pre-deploy state');
$this->audit('deploy_failed', ['exit_code' => $deployExit]);
$this->runSubprocess('rollback-joomla.php', array_merge(
$deployArgs, ['--snapshot-dir', $snapshotDir]
));
$this->cleanup($snapshotDir);
return self::EXIT_FAILURE;
}
$this->log('INFO', 'Deploy completed successfully');
}
// ── Step 3: Health check (with retries) ──────────────────────
$this->section('Step 3: Health check');
if ($this->dryRun) {
$this->log('INFO', "[dry-run] Would check {$url} with checks: {$checks}");
$this->log('INFO', '[dry-run] Deploy-and-verify complete');
return self::EXIT_SUCCESS;
}
$healthy = false;
for ($attempt = 1; $attempt <= $retries; $attempt++) {
$this->log('INFO', "Health check attempt {$attempt}/{$retries}...");
if ($attempt > 1) {
$this->log('INFO', "Waiting {$delay}s before retry...");
sleep($delay);
}
$healthExit = $this->runHealthCheck($url, $checks, $timeout);
if ($healthExit === 0) {
$healthy = true;
break;
}
$this->log('WARNING', "Health check attempt {$attempt} failed (exit {$healthExit})");
}
if ($healthy) {
$this->section('Result: SUCCESS');
$this->log('INFO', 'Health check passed — deploy verified');
$this->audit('success', ['url' => $url, 'attempts' => $attempt]);
$this->cleanup($snapshotDir);
return self::EXIT_SUCCESS;
}
// ── Step 4: Rollback ─────────────────────────────────────────
$this->section('Step 4: ROLLBACK');
$this->log('ERROR', "Health check failed after {$retries} attempts — rolling back");
$this->audit('rollback_triggered', ['url' => $url, 'retries' => $retries]);
$rollbackExit = $this->runSubprocess('rollback-joomla.php', array_merge(
$deployArgs, ['--snapshot-dir', $snapshotDir]
));
if ($rollbackExit === 0) {
$this->log('INFO', 'Rollback completed — site restored to pre-deploy state');
$this->audit('rollback_success', []);
// Verify rollback worked
$postRollbackHealth = $this->runHealthCheck($url, $checks, $timeout);
if ($postRollbackHealth === 0) {
$this->log('INFO', 'Post-rollback health check passed — site is healthy');
} else {
$this->log('ERROR', 'Post-rollback health check FAILED — manual intervention needed');
$this->audit('rollback_verification_failed', []);
}
} else {
$this->log('ERROR', 'Rollback FAILED — manual intervention required');
$this->audit('rollback_failed', ['exit_code' => $rollbackExit]);
}
$this->cleanup($snapshotDir);
return self::EXIT_FAILURE;
}
// ── Health check (inline, no subprocess) ─────────────────────────
private function runHealthCheck(string $url, string $checks, int $timeout): int
{
$url = rtrim($url, '/');
$checkList = array_map('trim', explode(',', $checks));
$failed = 0;
foreach ($checkList as $check) {
$checkUrl = match ($check) {
'admin' => $url . '/administrator/',
'api' => $url . '/api/index.php/v1',
default => $url,
};
$result = $this->httpGet($checkUrl, $timeout);
if ($result === null) {
$this->log('ERROR', " [{$check}] FAIL: connection failed");
$failed++;
continue;
}
$validCodes = ($check === 'api') ? [200, 401] : [200];
if (!in_array($result['http_code'], $validCodes, true)) {
$this->log('ERROR', " [{$check}] FAIL: HTTP {$result['http_code']}");
$failed++;
continue;
}
if ($this->containsFatalError($result['body'])) {
$this->log('ERROR', " [{$check}] FAIL: PHP fatal error in response");
$failed++;
continue;
}
$this->log('INFO', " [{$check}] PASS: HTTP {$result['http_code']} ({$result['time_ms']}ms)");
}
return $failed > 0 ? 1 : 0;
}
private function httpGet(string $url, int $timeout): ?array
{
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_CONNECTTIMEOUT => $timeout,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_USERAGENT => 'MokoDeployVerify/1.0',
]);
$body = curl_exec($ch);
if (curl_errno($ch)) {
curl_close($ch);
return null;
}
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
$totalTime = curl_getinfo($ch, CURLINFO_TOTAL_TIME);
curl_close($ch);
return [
'http_code' => $httpCode,
'body' => is_string($body) ? $body : '',
'time_ms' => (int) round($totalTime * 1000),
];
}
private function containsFatalError(string $body): bool
{
foreach (['Fatal error:', 'Fatal Error', 'Parse error:', 'Uncaught Error:', 'Uncaught Exception:'] as $pattern) {
if (stripos($body, $pattern) !== false) {
return true;
}
}
return false;
}
// ── Subprocess helpers ───────────────────────────────────────────
private function runSubprocess(string $script, array $args): int
{
$scriptPath = __DIR__ . '/' . $script;
if (!is_file($scriptPath)) {
$this->log('ERROR', "Script not found: {$scriptPath}");
return 127;
}
$cmd = sprintf('php %s %s 2>&1',
escapeshellarg($scriptPath),
implode(' ', array_map('escapeshellarg', $args))
);
$this->log('DEBUG', "Running: {$cmd}");
passthru($cmd, $exitCode);
return $exitCode;
}
private function buildDeployArgs(string $path, string $env, string $config): array
{
$args = ['--path', $path];
if ($config !== '') {
$args[] = '--config';
$args[] = $config;
} elseif ($env !== '') {
$args[] = '--env';
$args[] = $env;
}
if ($this->dryRun) {
$args[] = '--dry-run';
}
return $args;
}
// ── Audit ────────────────────────────────────────────────────────
private function audit(string $event, array $data): void
{
if ($this->auditLogger === null) {
return;
}
try {
$this->auditLogger->logInfo("deploy-verify:{$event}", $data);
} catch (\Exception $e) {
// Non-fatal
}
}
// ── Cleanup ──────────────────────────────────────────────────────
private function cleanup(string $snapshotDir): void
{
if (is_dir($snapshotDir)) {
$this->removeDirectory($snapshotDir);
$this->log('DEBUG', "Cleaned up snapshot: {$snapshotDir}");
}
}
private function removeDirectory(string $dir): void
{
$entries = scandir($dir);
if ($entries === false) {
return;
}
foreach ($entries as $entry) {
if ($entry === '.' || $entry === '..') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $entry;
is_dir($path) ? $this->removeDirectory($path) : unlink($path);
}
rmdir($dir);
}
}
$app = new DeployAndVerify();
exit($app->execute());
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: MokoPlatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /deploy/deploy-dolibarr.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Deploy Dolibarr module files to a remote server via SFTP/rsync
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: MokoPlatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /deploy/health-check.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Post-deploy health check — verify a Joomla site is responding correctly
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: MokoPlatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /deploy/rollback-joomla.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Rollback a Joomla deployment by restoring from a pre-deploy snapshot
*/
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: MokoPlatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /deploy/sync-joomla.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Sync Joomla site directories between two servers via rsync over SSH
*/
+1 -1
View File
@@ -14,7 +14,7 @@
DEFGROUP: dolibarr-api-mcp.Documentation
INGROUP: dolibarr-api-mcp
REPO: https://git.mokoconsulting.tech/MokoConsulting/dolibarr-api-mcp
VERSION: 09.35.00
VERSION: 09.35.02
PATH: ./CONTRIBUTING.md
BRIEF: Contribution guidelines for the project
-->
+1 -1
View File
@@ -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.35.00
VERSION: 09.35.02
BRIEF: Security vulnerability reporting and handling policy
-->
+1 -1
View File
@@ -14,7 +14,7 @@
DEFGROUP:
INGROUP: Project.Documentation
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoCli-Template-Generic
VERSION: 09.35.00
VERSION: 09.35.02
PATH: ./CONTRIBUTING.md
BRIEF: Contribution guidelines for the project
-->
+1 -1
View File
@@ -23,7 +23,7 @@ DEFGROUP: [PROJECT_NAME]
INGROUP: [PROJECT_NAME].Documentation
REPO: [REPOSITORY_URL]
PATH: /SECURITY.md
VERSION: 09.35.00
VERSION: 09.35.02
BRIEF: Security vulnerability reporting and handling policy
-->
+1 -1
View File
@@ -63,7 +63,7 @@ class VersionBumpTest extends TestCase
{
file_put_contents(
"{$this->tmpDir}/README.md",
"<!-- VERSION: 09.35.00 -->\nSome content\n"
"<!-- VERSION: 09.35.02 -->\nSome content\n"
);
$this->execute();
+2 -2
View File
@@ -34,7 +34,7 @@ class VersionReadTest extends TestCase
{
file_put_contents(
"{$this->tmpDir}/README.md",
"# Test\n<!-- VERSION: 09.35.00 -->\n"
"# Test\n<!-- VERSION: 09.35.02 -->\n"
);
$this->assertSame('02.03.04', trim($this->runScript()));
@@ -68,7 +68,7 @@ class VersionReadTest extends TestCase
{
file_put_contents(
"{$this->tmpDir}/README.md",
"<!-- VERSION: 09.35.00 -->\n"
"<!-- VERSION: 09.35.02 -->\n"
);
mkdir("{$this->tmpDir}/src", 0755, true);
file_put_contents(
+1 -1
View File
@@ -12,7 +12,7 @@
* INGROUP: MokoPlatform
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokoplatform
* PATH: /validate/check_file_integrity.php
* VERSION: 09.35.00
* VERSION: 09.35.02
* BRIEF: Compare deployed files on a remote server against the local repository to detect drift
*/