feat: add changelog:prune CLI + integrate into auto-release workflow
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
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 1m18s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 5: Template Integrity (push) Blocked by required conditions
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Release configuration (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
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 1m18s
- cli/changelog_prune.php: keeps [Unreleased] + last N versioned entries (default 5) - Register changelog:promote and changelog:prune in bin/moko COMMAND_MAP - auto-release.yml Step 4b: promote [Unreleased] to version, then prune old entries Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -261,6 +261,18 @@ jobs:
|
||||
|
||||
# Step 5 (updates.xml) moved after Step 8 to include SHA-256 checksum
|
||||
|
||||
- name: "Step 4b: Promote and prune CHANGELOG"
|
||||
if: >-
|
||||
steps.version.outputs.skip != 'true' &&
|
||||
steps.check.outputs.already_released != 'true'
|
||||
run: |
|
||||
VERSION="${{ steps.bump.outputs.version || steps.version.outputs.version }}"
|
||||
MOKO_API="/tmp/moko-platform-api/cli"
|
||||
if [ -f "CHANGELOG.md" ]; then
|
||||
php ${MOKO_API}/changelog_promote.php --path . --version "$VERSION" 2>&1 || true
|
||||
php ${MOKO_API}/changelog_prune.php --path . --keep 5 2>&1 || true
|
||||
fi
|
||||
|
||||
- name: Commit release changes
|
||||
if: >-
|
||||
steps.version.outputs.skip != 'true' &&
|
||||
|
||||
@@ -132,6 +132,10 @@ const COMMAND_MAP = [
|
||||
'release:mirror' => 'cli/release_mirror.php',
|
||||
'release:package' => 'cli/release_package.php',
|
||||
|
||||
// Changelog
|
||||
'changelog:promote' => 'cli/changelog_promote.php',
|
||||
'changelog:prune' => 'cli/changelog_prune.php',
|
||||
|
||||
// Version management
|
||||
'version:read' => 'cli/version_read.php',
|
||||
'version:bump' => 'cli/version_bump.php',
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* FILE INFORMATION
|
||||
* DEFGROUP: moko-platform.CLI
|
||||
* INGROUP: moko-platform
|
||||
* REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
|
||||
* PATH: /cli/changelog_prune.php
|
||||
* BRIEF: Prune old CHANGELOG.md entries — keeps [Unreleased] + last N releases
|
||||
*
|
||||
* Usage:
|
||||
* php changelog_prune.php --path /repo --keep 5
|
||||
* php changelog_prune.php --path /repo --keep 3 --dry-run
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$path = '.';
|
||||
$keep = 5;
|
||||
$dryRun = false;
|
||||
|
||||
foreach ($argv as $i => $arg) {
|
||||
if ($arg === '--path' && isset($argv[$i + 1])) $path = $argv[$i + 1];
|
||||
if ($arg === '--keep' && isset($argv[$i + 1])) $keep = (int)$argv[$i + 1];
|
||||
if ($arg === '--dry-run') $dryRun = true;
|
||||
if ($arg === '--help') {
|
||||
echo "changelog_prune — Keep [Unreleased] + last N versioned entries\n\n";
|
||||
echo "Usage: php changelog_prune.php --path . --keep 5 [--dry-run]\n\n";
|
||||
echo "Options:\n";
|
||||
echo " --path Repository path (default: .)\n";
|
||||
echo " --keep Number of versioned releases to keep (default: 5)\n";
|
||||
echo " --dry-run Preview without writing\n";
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
$changelog = realpath($path) . '/CHANGELOG.md';
|
||||
if (!file_exists($changelog)) {
|
||||
fwrite(STDERR, "No CHANGELOG.md found at {$path}\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$content = file_get_contents($changelog);
|
||||
$lines = explode("\n", $content);
|
||||
|
||||
// Split into sections by ## headings
|
||||
$sections = [];
|
||||
$current = [];
|
||||
$currentHeading = null;
|
||||
|
||||
foreach ($lines as $line) {
|
||||
if (preg_match('/^## /', $line)) {
|
||||
if ($currentHeading !== null) {
|
||||
$sections[] = ['heading' => $currentHeading, 'lines' => $current];
|
||||
}
|
||||
$currentHeading = $line;
|
||||
$current = [$line];
|
||||
} else {
|
||||
$current[] = $line;
|
||||
}
|
||||
}
|
||||
if ($currentHeading !== null) {
|
||||
$sections[] = ['heading' => $currentHeading, 'lines' => $current];
|
||||
}
|
||||
|
||||
// Find the header (everything before the first ## section)
|
||||
$header = [];
|
||||
$contentLines = explode("\n", $content);
|
||||
foreach ($contentLines as $line) {
|
||||
if (preg_match('/^## /', $line)) {
|
||||
break;
|
||||
}
|
||||
$header[] = $line;
|
||||
}
|
||||
|
||||
// Separate [Unreleased] from versioned sections
|
||||
$unreleased = null;
|
||||
$versioned = [];
|
||||
|
||||
foreach ($sections as $section) {
|
||||
if (preg_match('/\[Unreleased\]/i', $section['heading'])) {
|
||||
$unreleased = $section;
|
||||
} else {
|
||||
$versioned[] = $section;
|
||||
}
|
||||
}
|
||||
|
||||
$totalVersioned = count($versioned);
|
||||
$pruned = $totalVersioned - $keep;
|
||||
|
||||
if ($pruned <= 0) {
|
||||
echo "CHANGELOG has {$totalVersioned} versioned entries — nothing to prune (keeping {$keep})\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Keep only the first N versioned sections
|
||||
$keptVersioned = array_slice($versioned, 0, $keep);
|
||||
$droppedVersioned = array_slice($versioned, $keep);
|
||||
|
||||
// Report
|
||||
echo "CHANGELOG: {$totalVersioned} versioned entries found\n";
|
||||
echo " Keeping: {$keep} most recent\n";
|
||||
echo " Pruning: {$pruned} old entries\n";
|
||||
|
||||
foreach ($droppedVersioned as $section) {
|
||||
$heading = trim($section['heading']);
|
||||
echo " - {$heading}\n";
|
||||
}
|
||||
|
||||
if ($dryRun) {
|
||||
echo "\n(dry-run) No changes written\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Rebuild the file
|
||||
$output = implode("\n", $header);
|
||||
|
||||
if ($unreleased !== null) {
|
||||
$output .= implode("\n", $unreleased['lines']) . "\n";
|
||||
}
|
||||
|
||||
foreach ($keptVersioned as $section) {
|
||||
$output .= implode("\n", $section['lines']) . "\n";
|
||||
}
|
||||
|
||||
// Clean up excessive blank lines at end
|
||||
$output = rtrim($output) . "\n";
|
||||
|
||||
file_put_contents($changelog, $output);
|
||||
echo "\nCHANGELOG pruned: removed {$pruned} old entries\n";
|
||||
exit(0);
|
||||
Reference in New Issue
Block a user