07ea171af9
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 1s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 43s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: moko-platform CI / Gate 4: Governance (push) Has been cancelled
Platform: moko-platform CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: moko-platform CI / CI Summary (push) Has been cancelled
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
New CLI tools: - manifest_element.php — extract element/type/prefix from any platform manifest - release_create.php — create/overwrite Gitea releases with proper naming - release_package.php — build ZIP+tar.gz, SHA-256, upload assets - release_promote.php — promote releases between channels (dev→RC→stable) - version_reset_dev.php — reset platform version on dev branch after release Updated CLI tools: - version_bump.php — now writes to manifests, Dolibarr mod, composer.json (not just README) - release_cascade.php — added --version for version-aware deletion of stale releases - release_validate.php — auto-detect platform, --github-output, source dir check Workflow changes (auto-release.yml): - Draft PR to main → auto-promote highest pre-release to RC - Merged PR to main → promote RC to stable (skip rebuild when RC exists) - Removed paths filter for Go/Node/generic repo compatibility - Fixed cascade --api-base parameter bug Workflow changes (pre-release.yml): - Auto-trigger development pre-release on feature branch merge to dev - Removed paths filter Infrastructure: - RepositorySynchronizer: fixed template repo names, .mokogitea/workflows path, universal workflow cascade (Template-Generic → other templates) - bulk_sync.php: syncs universal workflows to templates before repo sync - PHPDoc added to 4 classes missing class-level docs - Version bump 09.00.00 → 09.01.00 Closes #152 #153 #154 #155 #156 #157 #158 #159 #161 #162 Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
161 lines
5.2 KiB
PHP
161 lines
5.2 KiB
PHP
#!/usr/bin/env php
|
|
<?php
|
|
|
|
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* FILE INFORMATION
|
|
* DEFGROUP: MokoStandards.Validate
|
|
* INGROUP: MokoStandards
|
|
* REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
|
|
* PATH: /validate/check_wiki_health.php
|
|
* BRIEF: Validate wiki health — checks Home page exists, has MokoStandards link, pages are indexed
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../vendor/autoload.php';
|
|
|
|
use MokoEnterprise\CliFramework;
|
|
|
|
/**
|
|
* Wiki Health Checker
|
|
*
|
|
* Validates Gitea wiki structure and content for a repository,
|
|
* checking for required pages, broken links, and formatting issues.
|
|
*
|
|
* @since 04.00.00
|
|
*/
|
|
class CheckWikiHealth extends CliFramework
|
|
{
|
|
protected function configure(): void
|
|
{
|
|
$this->setDescription('Validate wiki health for a repository');
|
|
$this->addArgument('--path', 'Repository path (default: current directory)', '.');
|
|
$this->addArgument('--gitea-url', 'Gitea base URL', 'https://git.mokoconsulting.tech');
|
|
$this->addArgument('--token', 'Gitea API token (or set GITEA_TOKEN env var)', '');
|
|
$this->addArgument('--json', 'Output as JSON', false);
|
|
}
|
|
|
|
protected function run(): int
|
|
{
|
|
$repoPath = realpath($this->getArgument('--path', '.')) ?: '.';
|
|
$giteaUrl = $this->getArgument('--gitea-url', 'https://git.mokoconsulting.tech');
|
|
$token = $this->getArgument('--token', getenv('GITEA_TOKEN') ?: '');
|
|
|
|
// Detect repo owner/name from git config
|
|
$configFile = $repoPath . '/.git/config';
|
|
$remote = '';
|
|
if (is_file($configFile)) {
|
|
$config = file_get_contents($configFile);
|
|
if (preg_match('/url\s*=\s*(.+)/', $config, $m)) {
|
|
$remote = trim($m[1]);
|
|
}
|
|
}
|
|
|
|
if (empty($remote)) {
|
|
$this->log('Cannot determine git remote — skipping wiki check', 'WARNING');
|
|
return 0;
|
|
}
|
|
|
|
// Parse owner/repo from remote URL
|
|
if (preg_match('#[:/]([^/]+)/([^/.]+?)(?:\.git)?$#', $remote, $m)) {
|
|
$owner = $m[1];
|
|
$repo = $m[2];
|
|
} else {
|
|
$this->log("Cannot parse owner/repo from remote: {$remote}", 'WARNING');
|
|
return 0;
|
|
}
|
|
|
|
$this->log("Checking wiki: {$owner}/{$repo}");
|
|
$issues = 0;
|
|
|
|
// Check wiki pages via API
|
|
$apiUrl = "{$giteaUrl}/api/v1/repos/{$owner}/{$repo}/wiki/pages";
|
|
$headers = $token ? ["Authorization: token {$token}"] : [];
|
|
$pages = $this->apiGet($apiUrl, $headers);
|
|
|
|
if ($pages === null) {
|
|
$this->log(' No wiki found or API error', 'WARNING');
|
|
$issues++;
|
|
if ($this->getArgument("--json", false)) {
|
|
echo json_encode(['status' => 'no_wiki', 'issues' => $issues]);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
$pageCount = count($pages);
|
|
$this->log(" Found {$pageCount} wiki page(s)");
|
|
|
|
// Check Home exists
|
|
$hasHome = false;
|
|
$pageTitles = [];
|
|
foreach ($pages as $page) {
|
|
$title = $page['title'] ?? '';
|
|
$pageTitles[] = $title;
|
|
if (strtolower($title) === 'home') {
|
|
$hasHome = true;
|
|
}
|
|
}
|
|
|
|
if (!$hasHome) {
|
|
$this->log(' FAIL: No Home page', 'ERROR');
|
|
$issues++;
|
|
} else {
|
|
$this->log(' OK: Home page exists');
|
|
}
|
|
|
|
// Check Home has MokoStandards link
|
|
if ($hasHome) {
|
|
$homeUrl = "{$giteaUrl}/api/v1/repos/{$owner}/{$repo}/wiki/page/Home";
|
|
$home = $this->apiGet($homeUrl, $headers);
|
|
if ($home) {
|
|
$content = base64_decode($home['content_base64'] ?? '');
|
|
if (stripos($content, 'moko-platform/wiki') !== false || stripos($content, 'MokoStandards') !== false) {
|
|
$this->log(' OK: Has MokoStandards reference');
|
|
} else {
|
|
$this->log(' WARN: Home page missing MokoStandards reference', 'WARNING');
|
|
$issues++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($this->getArgument("--json", false)) {
|
|
echo json_encode([
|
|
'repo' => "{$owner}/{$repo}",
|
|
'pages' => $pageCount,
|
|
'has_home' => $hasHome,
|
|
'issues' => $issues,
|
|
'page_titles' => $pageTitles,
|
|
], JSON_PRETTY_PRINT);
|
|
}
|
|
|
|
return $issues > 0 ? 1 : 0;
|
|
}
|
|
|
|
private function apiGet(string $url, array $headers = []): ?array
|
|
{
|
|
$ctx = stream_context_create([
|
|
'http' => [
|
|
'method' => 'GET',
|
|
'header' => array_merge(['Accept: application/json'], $headers),
|
|
'timeout' => 10,
|
|
'ignore_errors' => true,
|
|
],
|
|
'ssl' => ['verify_peer' => false],
|
|
]);
|
|
|
|
$response = @file_get_contents($url, false, $ctx);
|
|
if ($response === false) {
|
|
return null;
|
|
}
|
|
|
|
$data = json_decode($response, true);
|
|
return is_array($data) ? $data : null;
|
|
}
|
|
}
|
|
|
|
$app = new CheckWikiHealth();
|
|
exit($app->execute());
|