1d87be7d5e
Branch Policy Check / Verify merge target (pull_request) Successful in 1s
- Update REPO: from MokoStandards-API to moko-platform in 125 files - Fix wrong org path (mokoconsulting-tech → MokoConsulting) in 10 files - Fix SPDX-LICENSE-IDENTIFIER case in 2 template files - Add missing REPO: field to 3 files Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
172 lines
6.5 KiB
PHP
172 lines
6.5 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.CLI
|
|
* INGROUP: MokoStandards
|
|
* REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
|
|
* PATH: /cli/release.php
|
|
* BRIEF: Automate the MokoStandards version branch release flow
|
|
*
|
|
* USAGE
|
|
* php cli/release.php # Release current version
|
|
* php cli/release.php --bump minor # Bump minor, then release
|
|
* php cli/release.php --bump major # Bump major, then release
|
|
* php cli/release.php --dry-run # Preview without changes
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
$dryRun = in_array('--dry-run', $argv);
|
|
$bumpType = null;
|
|
foreach ($argv as $i => $arg) {
|
|
if ($arg === '--bump' && isset($argv[$i + 1])) {
|
|
$bumpType = $argv[$i + 1]; // patch | minor | major
|
|
}
|
|
}
|
|
|
|
$repoRoot = dirname(__DIR__, 2);
|
|
$syncFile = "{$repoRoot}/lib/Enterprise/RepositorySynchronizer.php";
|
|
// Check both workflow directories for the bulk-repo-sync workflow
|
|
$bulkSyncFile = file_exists("{$repoRoot}/.gitea/workflows/bulk-repo-sync.yml")
|
|
? "{$repoRoot}/.gitea/workflows/bulk-repo-sync.yml"
|
|
: "{$repoRoot}/.github/workflows/bulk-repo-sync.yml";
|
|
$cleanupFile = "{$repoRoot}/templates/workflows/shared/repository-cleanup.yml.template";
|
|
|
|
// ── Step 1: Read current version ────────────────────────────────────────
|
|
$readme = "{$repoRoot}/README.md";
|
|
$content = file_get_contents($readme);
|
|
if (!preg_match('/^\s*VERSION:\s*(\d{2})\.(\d{2})\.(\d{2})/m', $content, $m)) {
|
|
fwrite(STDERR, "No VERSION found in README.md\n");
|
|
exit(1);
|
|
}
|
|
|
|
$major = (int)$m[1];
|
|
$minor = (int)$m[2];
|
|
$patch = (int)$m[3];
|
|
$currentVersion = sprintf('%02d.%02d.%02d', $major, $minor, $patch);
|
|
|
|
// ── Step 2: Bump version if requested ───────────────────────────────────
|
|
if ($bumpType) {
|
|
switch ($bumpType) {
|
|
case 'major': $major++; $minor = 0; $patch = 0; break;
|
|
case 'minor': $minor++; $patch = 0; break;
|
|
case 'patch': $patch++; break;
|
|
default:
|
|
fwrite(STDERR, "Invalid bump type: {$bumpType} (use patch/minor/major)\n");
|
|
exit(1);
|
|
}
|
|
$newVersion = sprintf('%02d.%02d.%02d', $major, $minor, $patch);
|
|
echo "Bumping: {$currentVersion} → {$newVersion}\n";
|
|
|
|
if (!$dryRun) {
|
|
// Update README.md
|
|
$content = preg_replace(
|
|
'/^(\s*VERSION:\s*)\d{2}\.\d{2}\.\d{2}/m',
|
|
'${1}' . $newVersion,
|
|
$content,
|
|
1
|
|
);
|
|
file_put_contents($readme, $content);
|
|
|
|
// Propagate to all files
|
|
echo "Propagating version to all files...\n";
|
|
passthru("php {$repoRoot}/api/maintenance/update_version_from_readme.php --path {$repoRoot}");
|
|
}
|
|
$currentVersion = $newVersion;
|
|
} else {
|
|
echo "Version: {$currentVersion}\n";
|
|
}
|
|
|
|
// Derive major.minor for branch naming (patches update existing branch)
|
|
$versionParts = explode('.', $currentVersion);
|
|
$minorVersion = $versionParts[0] . '.' . $versionParts[1];
|
|
$branch = "version/{$minorVersion}";
|
|
|
|
// ── Step 3: Update STANDARDS_VERSION + STANDARDS_MINOR constants ────────
|
|
echo "Updating STANDARDS_VERSION → {$currentVersion}\n";
|
|
echo "Updating STANDARDS_MINOR → {$minorVersion}\n";
|
|
if (!$dryRun) {
|
|
$syncContent = file_get_contents($syncFile);
|
|
$syncContent = preg_replace(
|
|
"/STANDARDS_VERSION\s*=\s*'[^']+'/",
|
|
"STANDARDS_VERSION = '{$currentVersion}'",
|
|
$syncContent
|
|
);
|
|
$syncContent = preg_replace(
|
|
"/STANDARDS_MINOR\s*=\s*'[^']+'/",
|
|
"STANDARDS_MINOR = '{$minorVersion}'",
|
|
$syncContent
|
|
);
|
|
file_put_contents($syncFile, $syncContent);
|
|
}
|
|
|
|
// ── Step 4: Update bulk-repo-sync.yml checkout ref ──────────────────────
|
|
echo "Updating bulk-repo-sync.yml → {$branch}\n";
|
|
if (!$dryRun) {
|
|
$bulkContent = file_get_contents($bulkSyncFile);
|
|
$bulkContent = preg_replace(
|
|
'/ref:\s*version\/[\d.]+/',
|
|
"ref: {$branch}",
|
|
$bulkContent
|
|
);
|
|
file_put_contents($bulkSyncFile, $bulkContent);
|
|
}
|
|
|
|
// ── Step 5: Update repository-cleanup.yml current branch ────────────────
|
|
echo "Updating repository-cleanup.yml → chore/sync-mokostandards-v{$minorVersion}\n";
|
|
if (!$dryRun) {
|
|
$cleanupContent = file_get_contents($cleanupFile);
|
|
$cleanupContent = preg_replace(
|
|
'/CURRENT="chore\/sync-mokostandards-v[^"]*"/',
|
|
"CURRENT=\"chore/sync-mokostandards-v{$minorVersion}\"",
|
|
$cleanupContent
|
|
);
|
|
file_put_contents($cleanupFile, $cleanupContent);
|
|
}
|
|
|
|
// ── Step 6: Commit changes ──────────────────────────────────────────────
|
|
if (!$dryRun) {
|
|
echo "Committing...\n";
|
|
passthru("cd {$repoRoot} && git add -A && git commit -m \"chore(release): prepare {$currentVersion} release [skip ci]\"");
|
|
passthru("cd {$repoRoot} && git pull --rebase 2>/dev/null; git push");
|
|
}
|
|
|
|
// ── Step 7: Create or update version branch ─────────────────────────────
|
|
$isPatch = ($versionParts[2] ?? '00') !== '00';
|
|
if ($isPatch) {
|
|
echo "Updating version branch: {$branch} (patch update)\n";
|
|
if (!$dryRun) {
|
|
passthru("cd " . escapeshellarg($repoRoot) . " && git push origin main:{$branch} --force 2>&1");
|
|
}
|
|
} else {
|
|
echo "Creating version branch: {$branch} (minor release)\n";
|
|
if (!$dryRun) {
|
|
$exitCode = 0;
|
|
passthru("cd " . escapeshellarg($repoRoot) . " && git push origin main:{$branch} 2>&1", $exitCode);
|
|
if ($exitCode !== 0) {
|
|
echo "Branch {$branch} already exists — force updating\n";
|
|
passthru("cd " . escapeshellarg($repoRoot) . " && git push origin main:{$branch} --force 2>&1");
|
|
}
|
|
}
|
|
}
|
|
|
|
// ── Step 8: Create git tag (never overwrite existing) ───────────────────
|
|
$tag = "v{$currentVersion}";
|
|
echo "Creating tag {$tag}\n";
|
|
if (!$dryRun) {
|
|
$exitCode = 0;
|
|
passthru("cd {$repoRoot} && git tag {$tag} 2>/dev/null && git push origin {$tag} 2>/dev/null", $exitCode);
|
|
if ($exitCode !== 0) {
|
|
echo "⚠️ Tag {$tag} already exists — skipping\n";
|
|
}
|
|
}
|
|
|
|
echo "\n✅ Release {$currentVersion} complete\n";
|
|
echo " Branch: {$branch}\n";
|
|
echo " Tag: {$tag}\n";
|
|
echo " Next: run bulk sync to push to all repos\n";
|