cbfa23c4c4
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Generic: Repo Health / Scripts governance (push) Successful in 5s
Generic: Repo Health / Release configuration (push) Successful in 5s
Generic: Repo Health / Repository health (push) Successful in 12s
Platform: moko-platform CI / Gate 1: Code Quality (push) Successful in 45s
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 4s
Universal: PR Check / Validate PR (pull_request) Successful in 5s
Universal: PR Check / Build RC Package (pull_request) Successful in 2s
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Failing after 44s
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Failing after 48s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Failing after 48s
Platform: moko-platform CI / Gate 4: Governance (push) Successful in 48s
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Failing after 50s
Platform: moko-platform CI / Gate 5: Template Integrity (push) Failing after 12s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Successful in 1m13s
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Failing after 5s
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Failing after 42s
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Failing after 45s
Platform: moko-platform CI / Gate 4: Governance (pull_request) Successful in 44s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Failing after 47s
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Failing after 49s
Real bugs found and fixed: - bulk_joomla_template: $org undefined in heredoc (missing parameter) - RepositorySynchronizer: $root undefined (should be $repoRoot), duplicate array key - RepositoryHealthChecker: wrong class name (UnifiedValidation → UnifiedValidator) - scan_drift: missing $adapter property declaration - auto_detect_platform: wrong method name (detectProjectType → detect) - EnterpriseReadinessValidator: void return used as value - check_client_theme: extra parameter to printSummary() - ApiClient: unused constructor parameter now stored - GitPlatformAdapter: added listBranches/getCloneUrl/cloneRepo to interface - MokoGiteaAdapter/GitHubAdapter: implemented new interface methods 3 legacy CLIApp scripts excluded (need migration to CliFramework): repo_cleanup.php, push_files.php, joomla_release.php Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
252 lines
8.3 KiB
PHP
Executable File
252 lines
8.3 KiB
PHP
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
|
|
/**
|
|
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
*
|
|
* This file is part of a Moko Consulting project.
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* FILE INFORMATION
|
|
* DEFGROUP: MokoStandards.Scripts.Validate
|
|
* INGROUP: MokoStandards
|
|
* REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
|
|
* PATH: /validate/check_enterprise_readiness.php
|
|
* BRIEF: Enterprise readiness checker - PHP implementation
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../../vendor/autoload.php';
|
|
|
|
use MokoEnterprise\{
|
|
AuditLogger,
|
|
CliFramework,
|
|
SecurityValidator,
|
|
PluginFactory,
|
|
ProjectTypeDetector
|
|
};
|
|
|
|
/**
|
|
* Enterprise Readiness Checker
|
|
*
|
|
* Validates repository against enterprise standards
|
|
*/
|
|
class EnterpriseReadinessChecker extends CliFramework
|
|
{
|
|
private AuditLogger $logger;
|
|
private SecurityValidator $securityValidator;
|
|
private PluginFactory $pluginFactory;
|
|
private ?object $projectPlugin = null;
|
|
|
|
private array $results = [];
|
|
|
|
protected function configure(): void
|
|
{
|
|
$this->setDescription('Check enterprise readiness compliance');
|
|
$this->addArgument('--path', 'Repository path to check', '.');
|
|
$this->addArgument('--strict', 'Fail on any non-compliance', false);
|
|
}
|
|
|
|
protected function initialize(): void
|
|
{
|
|
parent::initialize();
|
|
|
|
$this->logger = new AuditLogger('enterprise_readiness');
|
|
$this->securityValidator = new SecurityValidator();
|
|
$metrics = new \MokoEnterprise\MetricsCollector();
|
|
$this->pluginFactory = new PluginFactory($this->logger, $metrics);
|
|
|
|
$this->log('Enterprise readiness checker initialized with plugin system');
|
|
}
|
|
|
|
protected function run(): int
|
|
{
|
|
$path = $this->getArgument('--path');
|
|
$strict = $this->getArgument('--strict');
|
|
|
|
$this->section('Initialising');
|
|
$this->log("Checking enterprise readiness: {$path}");
|
|
|
|
// Try to load the project plugin
|
|
$this->projectPlugin = $this->pluginFactory->createForProject($path);
|
|
|
|
if ($this->projectPlugin) {
|
|
$pluginName = $this->projectPlugin->getPluginName();
|
|
$projectType = $this->projectPlugin->getProjectType();
|
|
$this->log("Using plugin: {$pluginName} for type: {$projectType}");
|
|
|
|
// Use plugin's readiness check if available
|
|
$pluginReadiness = $this->projectPlugin->checkReadiness($path, []);
|
|
|
|
if (!empty($pluginReadiness)) {
|
|
$this->log("Plugin readiness check: " . ($pluginReadiness['ready'] ? 'READY' : 'NOT READY'));
|
|
$this->results['plugin_readiness'] = [
|
|
'passed' => $pluginReadiness['ready'],
|
|
'score' => $pluginReadiness['score'] ?? 0,
|
|
'blockers' => $pluginReadiness['blockers'] ?? [],
|
|
'warnings' => $pluginReadiness['warnings'] ?? [],
|
|
];
|
|
}
|
|
} else {
|
|
$this->log("No plugin found, using generic readiness checks");
|
|
}
|
|
|
|
// Run standard enterprise checks (backwards compatible)
|
|
$this->section('Enterprise libraries');
|
|
$this->checkEnterpriseLibraries($path);
|
|
$this->section('Monitoring & audit');
|
|
$this->checkMonitoring($path);
|
|
$this->checkAuditLogging($path);
|
|
$this->section('Security compliance');
|
|
$this->checkSecurityCompliance($path);
|
|
$this->section('Documentation');
|
|
$this->checkDocumentation($path);
|
|
|
|
// Display results using visual API
|
|
$this->section('Results');
|
|
$passed = 0;
|
|
$failed = 0;
|
|
foreach ($this->results as $result) {
|
|
$this->status($result['passed'], $result['check'], $result['passed'] ? '' : $result['message']);
|
|
if ($result['passed']) {
|
|
$passed++;
|
|
} else {
|
|
$failed++;
|
|
}
|
|
}
|
|
|
|
$this->printSummary($passed, $failed, $this->elapsed());
|
|
|
|
$failures = $failed;
|
|
|
|
if ($strict && $failures > 0) {
|
|
$this->error("Enterprise readiness check failed (strict mode): {$failures} issues found");
|
|
return 1;
|
|
}
|
|
|
|
if ($failures > 0) {
|
|
$this->warning("{$failures} enterprise readiness issues found");
|
|
} else {
|
|
$this->success('All enterprise readiness checks passed');
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private function checkEnterpriseLibraries(string $path): void
|
|
{
|
|
$required = ['ApiClient', 'AuditLogger', 'Config', 'ErrorRecovery', 'MetricsCollector'];
|
|
|
|
// Enterprise libs may live in vendor/ (Composer install) or lib/Enterprise/ (MokoStandards itself).
|
|
// A single vendor/ directory confirms the whole package is present — no need to check per-file.
|
|
$vendorPkg = "{$path}/vendor/mokoconsulting-tech/enterprise";
|
|
$inVendor = is_dir($vendorPkg);
|
|
|
|
foreach ($required as $library) {
|
|
$localFile = "{$path}/lib/Enterprise/{$library}.php";
|
|
$found = $inVendor || file_exists($localFile);
|
|
$this->addResult(
|
|
"Enterprise library: {$library}",
|
|
$found,
|
|
"Missing enterprise library (not in vendor/mokoconsulting-tech/enterprise or lib/Enterprise/)"
|
|
);
|
|
}
|
|
}
|
|
|
|
private function checkMonitoring(string $path): void
|
|
{
|
|
// Check for metrics collection
|
|
$metricsDir = "{$path}/var/logs/metrics";
|
|
$this->addResult(
|
|
'Metrics directory configured',
|
|
is_dir($metricsDir) || !file_exists($path . '/composer.json'),
|
|
'Metrics logging not configured'
|
|
);
|
|
|
|
// Check for monitoring documentation
|
|
$monitoringDocs = "{$path}/docs/monitoring";
|
|
$this->addResult(
|
|
'Monitoring documentation exists',
|
|
is_dir($monitoringDocs) || file_exists("{$path}/docs/monitoring.md"),
|
|
'Monitoring documentation not found'
|
|
);
|
|
}
|
|
|
|
private function checkAuditLogging(string $path): void
|
|
{
|
|
$auditDir = "{$path}/var/logs/audit";
|
|
$this->addResult(
|
|
'Audit logging directory configured',
|
|
is_dir($auditDir) || !file_exists($path . '/composer.json'),
|
|
'Audit logging not configured'
|
|
);
|
|
}
|
|
|
|
private function checkSecurityCompliance(string $path): void
|
|
{
|
|
// Check for security policy
|
|
$this->addResult(
|
|
'Security policy exists',
|
|
file_exists("{$path}/SECURITY.md") || file_exists("{$path}/.github/SECURITY.md"),
|
|
'SECURITY.md not found'
|
|
);
|
|
|
|
// Check for CodeQL configuration
|
|
$codeqlConfig = "{$path}/.github/codeql";
|
|
$this->addResult(
|
|
'CodeQL configured',
|
|
is_dir($codeqlConfig) || file_exists("{$path}/.github/codeql/codeql-config.yml"),
|
|
'CodeQL not configured'
|
|
);
|
|
|
|
// Run security scan on PHP files
|
|
if (is_dir("{$path}/src")) {
|
|
$this->securityValidator->scanDirectory("{$path}/src", ['.php']);
|
|
$findings = $this->securityValidator->getFindings();
|
|
$this->addResult(
|
|
'No security vulnerabilities in source code',
|
|
empty($findings),
|
|
count($findings) . ' security issues found'
|
|
);
|
|
}
|
|
}
|
|
|
|
private function checkDocumentation(string $path): void
|
|
{
|
|
// Check for architecture documentation
|
|
$this->addResult(
|
|
'Architecture documentation exists',
|
|
file_exists("{$path}/docs/architecture.md") ||
|
|
file_exists("{$path}/docs/guide/architecture.md"),
|
|
'Architecture documentation not found'
|
|
);
|
|
|
|
// Check for API documentation
|
|
$this->addResult(
|
|
'API documentation exists',
|
|
file_exists("{$path}/docs/api.md") || is_dir("{$path}/docs/api"),
|
|
'API documentation not found'
|
|
);
|
|
}
|
|
|
|
private function addResult(string $check, bool $passed, string $message): void
|
|
{
|
|
$this->results[] = [
|
|
'check' => $check,
|
|
'passed' => $passed,
|
|
'message' => $message,
|
|
];
|
|
}
|
|
|
|
private function displayResults(): void
|
|
{
|
|
// Results are now displayed directly in run() using visual API methods.
|
|
}
|
|
}
|
|
|
|
// Run the application
|
|
$app = new EnterpriseReadinessChecker();
|
|
exit($app->execute());
|