#!/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/branch_rename.php * VERSION: 09.25.02 * BRIEF: Rename a git branch via Gitea API (create new, update PR, delete old) */ declare(strict_types=1); require_once __DIR__ . '/../lib/Enterprise/CliFramework.php'; use MokoEnterprise\CliFramework; class BranchRenameCli extends CliFramework { protected function configure(): void { $this->setDescription('Rename a git branch via Gitea API (create new, update PR, delete old)'); $this->addArgument('--from', 'Source branch name', ''); $this->addArgument('--to', 'Target branch name', ''); $this->addArgument('--token', 'API token', ''); $this->addArgument('--api-base', 'API base URL', ''); $this->addArgument('--pr', 'PR number to update head branch', ''); } protected function run(): int { $from = $this->getArgument('--from'); $to = $this->getArgument('--to'); $token = $this->getArgument('--token'); $apiBase = $this->getArgument('--api-base'); $prNum = $this->getArgument('--pr'); if (empty($from) || empty($to) || empty($token) || empty($apiBase)) { $this->log('ERROR', 'Usage: branch_rename.php --from BRANCH --to BRANCH --token TOKEN --api-base URL [--pr NUM] [--dry-run]'); return 1; } if ($from === $to) { echo "Source and target are the same ({$from}) — nothing to do\n"; return 0; } $headers = [ "Authorization: token {$token}", 'Content-Type: application/json', 'Accept: application/json', ]; // Step 1: Verify source branch exists echo "Checking source branch: {$from}\n"; $check = $this->apiRequest('GET', "{$apiBase}/branches/{$from}", $headers); if ($check['code'] !== 200) { $this->log('ERROR', "Source branch '{$from}' not found (HTTP {$check['code']})"); return 1; } // Step 2: Delete target branch if it already exists $targetCheck = $this->apiRequest('GET', "{$apiBase}/branches/{$to}", $headers); if ($targetCheck['code'] === 200) { echo "Target branch '{$to}' already exists — deleting\n"; if (!$this->dryRun) { $this->apiRequest('DELETE', "{$apiBase}/branches/{$to}", $headers); } } // Step 3: Create new branch from source echo "Creating branch: {$to} (from {$from})\n"; if (!$this->dryRun) { $create = $this->apiRequest('POST', "{$apiBase}/branches", $headers, [ 'new_branch_name' => $to, 'old_branch_name' => $from, ]); if ($create['code'] < 200 || $create['code'] >= 300) { $this->log('ERROR', "Failed to create branch '{$to}': HTTP {$create['code']}"); $this->log('ERROR', json_encode($create['body'])); return 1; } } // Step 4: Update PR head branch if PR number provided if (!empty($prNum)) { echo "Updating PR #{$prNum} head branch: {$from} -> {$to}\n"; if (!$this->dryRun) { $update = $this->apiRequest('PATCH', "{$apiBase}/pulls/{$prNum}", $headers, [ 'head' => $to, ]); if ($update['code'] < 200 || $update['code'] >= 300) { $this->log('ERROR', "Warning: Could not update PR head branch (HTTP {$update['code']})"); // Non-fatal — the PR may need manual update } } } // Step 5: Delete old source branch echo "Deleting old branch: {$from}\n"; if (!$this->dryRun) { $delete = $this->apiRequest('DELETE', "{$apiBase}/branches/{$from}", $headers); if ($delete['code'] !== 204 && $delete['code'] !== 200) { $this->log('ERROR', "Warning: Could not delete old branch '{$from}' (HTTP {$delete['code']})"); // Non-fatal — branch protection may prevent deletion } } echo "Renamed: {$from} -> {$to}\n"; return 0; } /** * Make an API request. */ private function apiRequest(string $method, string $url, array $headers, ?array $body = null): array { $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_TIMEOUT => 30, ]); if ($body !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); } $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return [ 'code' => $httpCode, 'body' => json_decode($response ?: '{}', true) ?: [], ]; } } $app = new BranchRenameCli(); exit($app->execute());