Public Access
7728b6b4ac
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 12s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Universal: PR Check / Validate PR (pull_request) Failing after 7s
Universal: PR Check / Secret Scan (pull_request) Successful in 10s
Platform: mokocli CI / Gate 1: Code Quality (pull_request) Failing after 1m3s
Platform: mokocli CI / Gate 2: Unit Tests (8.1) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.2) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 2: Unit Tests (8.3) (pull_request) Has been cancelled
Platform: mokocli CI / Gate 3: Self-Health Check (pull_request) Has been cancelled
Platform: mokocli CI / Gate 4: Governance (pull_request) Has been cancelled
Platform: mokocli CI / Gate 5: Template Integrity (pull_request) Has been cancelled
Platform: mokocli CI / CI Summary (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
MokoGitea instance rebrand to MokoGit. Content sweep over 265 files (ordered to avoid
moko-prefix doubling) plus path renames:
- .mokogitea/ -> .mokogit/ (repo + all mcp/servers/*)
- templates/mokogitea/ -> templates/mokogit/
- lib/Enterprise/MokoGiteaAdapter.php -> MokoGitAdapter.php (class MokoGitAdapter)
- mcp/servers/mokogitea_{skill,api} -> mokogit_{skill,api}; skills/mokogitea -> skills/mokogit
- automation/migrate_to_gitea.php -> migrate_to_mokogit.php
- env/secret names GITEA_* -> MOKOGIT_*
Note: ~/.claude/.mcp.json server flipped to @mokoconsulting/mcp-mokogit (publish pending).
140 lines
5.4 KiB
PHP
140 lines
5.4 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: mokocli.CLI
|
|
* INGROUP: mokocli
|
|
* REPO: https://git.mokoconsulting.tech/MokoConsulting/mokocli
|
|
* PATH: /cli/version_read.php
|
|
* BRIEF: Read version — manifest.xml is canonical, falls back to README.md and Joomla XML
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../lib/Enterprise/CliFramework.php';
|
|
|
|
use MokoCli\{CliFramework, SourceResolver};
|
|
|
|
class VersionReadCli extends CliFramework
|
|
{
|
|
protected function configure(): void
|
|
{
|
|
$this->setDescription('Read version — manifest.xml is canonical, falls back to README.md and Joomla XML');
|
|
$this->addArgument('--path', 'Repository root path', '.');
|
|
}
|
|
|
|
protected function run(): int
|
|
{
|
|
$path = $this->getArgument('--path');
|
|
$root = realpath($path) ?: $path;
|
|
|
|
// The retired .mokogit/manifest.xml is no longer a version source; README.md is now
|
|
// canonical (version_prefix, when needed, comes from the MokoGit metadata API, not a
|
|
// committed manifest). Default to an empty prefix — non-prefixed repos parse normally.
|
|
$versionPrefix = '';
|
|
|
|
// -- 1. README.md (canonical) --
|
|
$readmeVersion = null;
|
|
$readme = "{$root}/README.md";
|
|
if (file_exists($readme)) {
|
|
$content = file_get_contents($readme);
|
|
if (!empty($versionPrefix)) {
|
|
// Prefix-aware: search for prefix followed by version
|
|
$prefixPattern = preg_quote($versionPrefix, '/');
|
|
if (preg_match('/' . $prefixPattern . '(\d{2}\.\d{2}\.\d{2})/m', $content, $m)) {
|
|
$readmeVersion = $m[1];
|
|
}
|
|
}
|
|
if ($readmeVersion === null && preg_match('/VERSION:\s*(\d{2}\.\d{2}\.\d{2})/m', $content, $m)) {
|
|
$readmeVersion = $m[1];
|
|
}
|
|
}
|
|
|
|
// -- 3. Fallback: Joomla manifest XML --
|
|
$manifestVersion = null;
|
|
$manifestFiles = array_merge(
|
|
SourceResolver::globSource($root, 'pkg_*.xml'),
|
|
SourceResolver::globSource($root, '*.xml'),
|
|
SourceResolver::globSource($root, 'packages/*/*.xml'),
|
|
glob("{$root}/*.xml") ?: []
|
|
);
|
|
|
|
foreach ($manifestFiles as $xmlFile) {
|
|
$xmlContent = file_get_contents($xmlFile);
|
|
if (strpos($xmlContent, '<extension') === false && strpos($xmlContent, '<version>') === false) {
|
|
continue;
|
|
}
|
|
if (!empty($versionPrefix)) {
|
|
// Prefix-aware: look for <version>prefix + XX.YY.ZZ</version>
|
|
$prefixPattern = preg_quote($versionPrefix, '#');
|
|
if (preg_match('#<version>' . $prefixPattern . '(\d{2}\.\d{2}\.\d{2})</version>#', $xmlContent, $xm)) {
|
|
$candidate = $xm[1];
|
|
$currentBase = $manifestVersion ? preg_replace('/(-(?:dev|alpha|beta|rc))+$/', '', $manifestVersion) : null;
|
|
if ($currentBase === null || version_compare($candidate, $currentBase, '>')) {
|
|
$manifestVersion = $candidate;
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
if (preg_match('#<version>(\d{2}\.\d{2}\.\d{2}(?:(?:-(?:dev|alpha|beta|rc))+)?)</version>#', $xmlContent, $xm)) {
|
|
$candidate = $xm[1];
|
|
$candidateBase = preg_replace('/(-(?:dev|alpha|beta|rc))+$/', '', $candidate);
|
|
$currentBase = $manifestVersion ? preg_replace('/(-(?:dev|alpha|beta|rc))+$/', '', $manifestVersion) : null;
|
|
if ($currentBase === null || version_compare($candidateBase, $currentBase, '>')) {
|
|
$manifestVersion = $candidate;
|
|
}
|
|
}
|
|
}
|
|
|
|
// -- 4. Fallback: package.json (Node.js / MCP) --
|
|
$packageJsonVersion = null;
|
|
$packageJsonFile = "{$root}/package.json";
|
|
if (file_exists($packageJsonFile)) {
|
|
$pkgData = json_decode(file_get_contents($packageJsonFile), true);
|
|
if (isset($pkgData['version']) && preg_match('/^\d{2}\.\d{2}\.\d{2}$/', $pkgData['version'])) {
|
|
$packageJsonVersion = $pkgData['version'];
|
|
}
|
|
}
|
|
|
|
// -- 5. Fallback: pyproject.toml (Python) --
|
|
$pyprojectVersion = null;
|
|
$pyprojectFile = "{$root}/pyproject.toml";
|
|
if (file_exists($pyprojectFile)) {
|
|
$pyContent = file_get_contents($pyprojectFile);
|
|
if (preg_match('/^version\s*=\s*"(\d{2}\.\d{2}\.\d{2})"/m', $pyContent, $pm)) {
|
|
$pyprojectVersion = $pm[1];
|
|
}
|
|
}
|
|
|
|
// -- Output the higher version --
|
|
$candidates = array_filter([
|
|
$readmeVersion,
|
|
$manifestVersion,
|
|
$packageJsonVersion,
|
|
$pyprojectVersion,
|
|
]);
|
|
|
|
$version = null;
|
|
foreach ($candidates as $candidate) {
|
|
if ($version === null || version_compare($candidate, $version, '>')) {
|
|
$version = $candidate;
|
|
}
|
|
}
|
|
|
|
if ($version === null) {
|
|
$this->log('ERROR', 'No version found in manifest.xml, README.md, Joomla XML, package.json, or pyproject.toml');
|
|
return 1;
|
|
}
|
|
|
|
echo $version . "\n";
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
$app = new VersionReadCli();
|
|
exit($app->execute());
|