#!/usr/bin/env php * * 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/version_auto_bump.php * VERSION: 09.17.00 * BRIEF: Auto patch-bump, set stability suffix, and commit — single CLI replacing inline workflow bash * * Usage: * php version_auto_bump.php --path . --branch dev * php version_auto_bump.php --path . --branch feature/my-feature --token TOKEN --repo-url URL * php version_auto_bump.php --path . --branch alpha --dry-run */ declare(strict_types=1); $path = '.'; $branch = null; $token = ''; $repoUrl = ''; $dryRun = false; $watchPath = ''; foreach ($argv as $i => $arg) { if ($arg === '--path' && isset($argv[$i + 1])) $path = $argv[$i + 1]; if ($arg === '--branch' && isset($argv[$i + 1])) $branch = $argv[$i + 1]; if ($arg === '--token' && isset($argv[$i + 1])) $token = $argv[$i + 1]; if ($arg === '--repo-url' && isset($argv[$i + 1])) $repoUrl = $argv[$i + 1]; if ($arg === '--watch-path' && isset($argv[$i + 1])) $watchPath = $argv[$i + 1]; if ($arg === '--dry-run') $dryRun = true; } // Auto-detect branch from git or CI env if ($branch === null) { $branch = getenv('GITHUB_REF_NAME') ?: trim((string) @shell_exec('git rev-parse --abbrev-ref HEAD 2>/dev/null')); if (empty($branch) || $branch === 'HEAD') { fwrite(STDERR, "Cannot detect branch — pass --branch\n"); exit(1); } } // Map branch to stability suffix $stabilityMap = [ 'dev' => 'dev', 'alpha' => 'alpha', 'beta' => 'beta', 'rc' => 'rc', ]; if (array_key_exists($branch, $stabilityMap)) { $stability = $stabilityMap[$branch]; } elseif (str_starts_with($branch, 'feature/') || str_starts_with($branch, 'patch/')) { $stability = 'dev'; } else { $stability = 'dev'; } $cli = __DIR__; $php = '"' . PHP_BINARY . '"'; // Auto-detect watch path from manifest.xml if not provided if (empty($watchPath)) { $manifestFile = realpath($path) . '/.mokogitea/manifest.xml'; if (file_exists($manifestFile)) { $xml = @simplexml_load_file($manifestFile); if ($xml && isset($xml->build->{'entry-point'})) { $watchPath = (string) $xml->build->{'entry-point'}; } } } // Check if code files actually changed (skip bump for docs/config-only changes) $shouldBump = true; if (!empty($watchPath)) { $root = realpath($path) ?: $path; $diffOutput = trim((string) @shell_exec( (PHP_OS_FAMILY === 'Windows' ? "cd /d " : "cd ") . escapeshellarg($root) . " && git diff --name-only HEAD~1 HEAD -- " . escapeshellarg($watchPath) . " 2>/dev/null" )); if (empty($diffOutput)) { echo "No changes in {$watchPath} — skipping version bump\n"; $shouldBump = false; } else { echo "Changes detected in {$watchPath}:\n{$diffOutput}\n"; } } if (!$shouldBump) { echo "No code changes — nothing to do\n"; exit(0); } // Step 1: Patch bump $bumpOutput = []; exec("{$php} {$cli}/version_bump.php --path " . escapeshellarg($path) . " 2>&1", $bumpOutput, $bumpRc); foreach ($bumpOutput as $line) { echo "{$line}\n"; } // Step 2: Read version $versionOutput = []; exec("{$php} {$cli}/version_read.php --path " . escapeshellarg($path) . " 2>&1", $versionOutput, $versionRc); $version = trim($versionOutput[0] ?? ''); if (empty($version)) { echo "No version found — skipping\n"; exit(0); } echo "Version: {$version} | Branch: {$branch} | Stability: {$stability}\n"; // Step 3: Set platform version with stability suffix exec("{$php} {$cli}/version_set_platform.php --path " . escapeshellarg($path) . " --version " . escapeshellarg($version) . " --branch " . escapeshellarg($branch) . " --stability " . escapeshellarg($stability) . " 2>&1", $setPlatOutput); foreach ($setPlatOutput as $line) { echo "{$line}\n"; } // Step 4: Version consistency check and fix exec("{$php} {$cli}/version_check.php --path " . escapeshellarg($path) . " --fix 2>&1", $checkOutput); // Re-read version (now includes suffix from version_set_platform) $suffixMap = [ 'dev' => '-dev', 'alpha' => '-alpha', 'beta' => '-beta', 'rc' => '-rc', ]; $displayVersion = preg_replace('/(-(dev|alpha|beta|rc))+$/', '', $version) . ($suffixMap[$stability] ?? ''); if ($dryRun) { echo "[DRY-RUN] Would commit and push {$displayVersion} to {$branch}\n"; exit(0); } // Step 5: Git commit and push $root = realpath($path) ?: $path; // Check if anything changed $diffStatus = trim((string) @shell_exec((PHP_OS_FAMILY === 'Windows' ? "cd /d " : "cd ") . escapeshellarg($root) . " && git diff --quiet && git diff --cached --quiet 2>&1 && echo clean || echo dirty")); if ($diffStatus === 'clean') { echo "No version changes to commit\n"; exit(0); } // Configure git @shell_exec((PHP_OS_FAMILY === 'Windows' ? "cd /d " : "cd ") . escapeshellarg($root) . " && git config --local user.email \"gitea-actions[bot]@mokoconsulting.tech\""); @shell_exec((PHP_OS_FAMILY === 'Windows' ? "cd /d " : "cd ") . escapeshellarg($root) . " && git config --local user.name \"gitea-actions[bot]\""); if (!empty($repoUrl)) { @shell_exec((PHP_OS_FAMILY === 'Windows' ? "cd /d " : "cd ") . escapeshellarg($root) . " && git remote set-url origin " . escapeshellarg($repoUrl)); } @shell_exec((PHP_OS_FAMILY === 'Windows' ? "cd /d " : "cd ") . escapeshellarg($root) . " && git add -A"); $commitMsg = $shouldBump ? "chore(version): auto-bump patch {$displayVersion} [skip ci]" : "chore(version): set {$stability} suffix {$displayVersion} [skip ci]"; @shell_exec((PHP_OS_FAMILY === 'Windows' ? "cd /d " : "cd ") . escapeshellarg($root) . " && git commit -m " . escapeshellarg($commitMsg) . " --author=\"gitea-actions[bot] \""); $pushResult = @shell_exec((PHP_OS_FAMILY === 'Windows' ? "cd /d " : "cd ") . escapeshellarg($root) . " && git push origin " . escapeshellarg($branch) . " 2>&1"); echo $pushResult ?? ''; echo "Bumped to {$displayVersion}\n"; exit(0);