fix(cli): updates_xml_build.php name prefix, SHA cascade, creationDate
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 4s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 1m13s
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

- Use type-prefixed display name (e.g. "Package - MokoWaaS") in <name>
  and <description> fields instead of raw extension name
- Cascade SHA-256 hash to ALL channel entries, not just the primary
  channel — all cascaded entries point to the same ZIP
- Add <creationDate> to every entry for Joomla update schema compliance
- Reorder XML fields to match Joomla conventions (client before version,
  tags after downloads)

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan Miller
2026-05-28 10:54:28 -05:00
parent beed1e628a
commit 475d2e33ef
+37 -15
View File
@@ -224,6 +224,19 @@ if (empty($extType)) {
$extType = 'component';
}
// Build display name with type prefix (e.g. "Package - MokoWaaS")
$typeDisplayMap = [
'package' => 'Package',
'plugin' => 'Plugin',
'module' => 'Module',
'component' => 'Component',
'template' => 'Template',
'library' => 'Library',
'file' => 'File',
];
$typeDisplay = $typeDisplayMap[$extType] ?? ucfirst($extType);
$displayName = "{$typeDisplay} - {$extName}";
// -- Build type prefix --------------------------------------------------------
$typePrefix = '';
switch ($extType) {
@@ -333,7 +346,8 @@ function buildEntry(
string $tagName,
string $entryVersion,
string $entryDownloadUrl,
string $extName,
string $displayName,
string $stabilityLabel,
string $extElement,
string $extType,
string $clientTag,
@@ -345,34 +359,33 @@ function buildEntry(
): string {
$lines = [];
$lines[] = ' <update>';
$lines[] = " <name>{$extName}</name>";
$lines[] = " <description>{$extName} update</description>";
$lines[] = " <name>{$displayName}</name>";
$lines[] = " <description>{$displayName} {$stabilityLabel} build.</description>";
// Element in updates.xml must match what Joomla stores in #__extensions
// For packages: pkg_elementname. For plugins: elementname (folder handles grouping).
$dbElement = ($extType === 'package') ? "pkg_{$extElement}" : $extElement;
$lines[] = " <element>{$dbElement}</element>";
$lines[] = " <type>{$extType}</type>";
$lines[] = $clientTag;
$lines[] = " <version>{$entryVersion}</version>";
if (!empty($clientTag)) {
$lines[] = $clientTag;
}
$lines[] = " <creationDate>" . date('Y-m-d') . "</creationDate>";
if (!empty($folderTag)) {
$lines[] = $folderTag;
}
$lines[] = " <tags><tag>{$tagName}</tag></tags>";
$lines[] = " <infourl title=\"{$extName}\">{$infoUrl}</infourl>";
$lines[] = " <infourl title='{$displayName}'>{$infoUrl}</infourl>";
$lines[] = ' <downloads>';
$lines[] = " <downloadurl type=\"full\" format=\"zip\">{$entryDownloadUrl}</downloadurl>";
$lines[] = " <downloadurl type='full' format='zip'>{$entryDownloadUrl}</downloadurl>";
$lines[] = ' </downloads>';
if (!empty($shaTag)) {
$lines[] = $shaTag;
}
$lines[] = " <tags><tag>{$tagName}</tag></tags>";
$lines[] = ' <maintainer>Moko Consulting</maintainer>';
$lines[] = ' <maintainerurl>https://mokoconsulting.tech</maintainerurl>';
$lines[] = " {$targetPlatform}";
if (!empty($phpTag)) {
$lines[] = $phpTag;
}
$lines[] = ' <maintainer>Moko Consulting</maintainer>';
$lines[] = ' <maintainerurl>https://mokoconsulting.tech</maintainerurl>';
$lines[] = ' </update>';
return implode("\n", $lines);
}
@@ -397,17 +410,26 @@ $channelVersion = $version . ($stabilitySuffixMap[$stability] ?? '');
$channelDownloadUrl = "{$giteaUrl}/{$org}/{$repo}/releases/download/{$giteaTag}/{$typePrefix}{$extElement}-{$channelVersion}.zip";
$channelInfoUrl = "{$giteaUrl}/{$org}/{$repo}/releases/tag/{$giteaTag}";
// Stability labels for descriptions
$stabilityLabelMap = [
'stable' => 'stable',
'rc' => 'rc',
'beta' => 'beta',
'alpha' => 'alpha',
'development' => 'development',
];
for ($i = 0; $i <= $stabilityIndex; $i++) {
$channelName = $allChannels[$i];
$joomlaTag = $stabilityTagMap[$channelName] ?? $channelName;
// Only attach SHA to the primary channel entry
$entrySha = ($i === $stabilityIndex) ? $shaTag : '';
$stabilityLabel = $stabilityLabelMap[$channelName] ?? $channelName;
$entries[] = buildEntry(
$joomlaTag,
$channelVersion,
$channelDownloadUrl,
$extName,
$displayName,
$stabilityLabel,
$extElement,
$extType,
$clientTag,
@@ -415,7 +437,7 @@ for ($i = 0; $i <= $stabilityIndex; $i++) {
$channelInfoUrl,
$targetPlatform,
$phpTag,
$entrySha
$shaTag
);
}