#!/usr/bin/env php * * This file is part of a Moko Consulting project. * * 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/scaffold_client.php * VERSION: 01.00.00 * BRIEF: Scaffold a new client-waas repo from Template-Client-WaaS with pre-configured settings */ declare(strict_types=1); final class ScaffoldClient { private string $name = ''; private string $org = ''; private string $giteaUrl = 'https://git.mokoconsulting.tech'; private string $token = ''; private bool $dryRun = false; public function run(): int { $this->parseArgs(); if ($this->name === '' || $this->org === '' || $this->token === '') { $this->log('ERROR: --name, --org, and --token are required.'); $this->printUsage(); return 1; } $repoName = 'client-waas-' . $this->name; $this->log("Scaffolding client repo: {$this->org}/{$repoName}"); $this->log("Gitea URL: {$this->giteaUrl}"); if ($this->dryRun) { $this->log('[DRY RUN] Would create repo from template MokoConsulting/Template-Client-WaaS'); $this->log("[DRY RUN] Repo: {$this->org}/{$repoName}"); $this->log("[DRY RUN] Description: \"{$this->name} WaaS site\""); $this->log('[DRY RUN] Would create dev branch from main'); $this->printPostSetupInstructions($repoName); return 0; } // Step 1: Create repo from template $this->log('Step 1: Creating repo from template...'); $createPayload = json_encode([ 'owner' => $this->org, 'name' => $repoName, 'description' => "{$this->name} WaaS site", 'private' => true, 'git_content' => true, 'topics' => true, 'labels' => true, ]); $response = $this->apiRequest( 'POST', "/api/v1/repos/MokoConsulting/Template-Client-WaaS/generate", $createPayload ); if ($response['code'] < 200 || $response['code'] >= 300) { $this->log("ERROR: Failed to create repo (HTTP {$response['code']})."); $this->log("Response: {$response['body']}"); return 1; } $this->log("Repo created: {$this->org}/{$repoName}"); // Step 2: Set repo description (already set via generate, but confirm) $this->log('Step 2: Updating repo description...'); $updatePayload = json_encode([ 'description' => "{$this->name} WaaS site", ]); $response = $this->apiRequest( 'PATCH', "/api/v1/repos/{$this->org}/{$repoName}", $updatePayload ); if ($response['code'] >= 200 && $response['code'] < 300) { $this->log('Description updated.'); } else { $this->log("WARNING: Could not update description (HTTP {$response['code']})."); } // Step 3: Create dev branch from main $this->log('Step 3: Creating dev branch from main...'); $branchPayload = json_encode([ 'new_branch_name' => 'dev', 'old_branch_name' => 'main', ]); $response = $this->apiRequest( 'POST', "/api/v1/repos/{$this->org}/{$repoName}/branches", $branchPayload ); if ($response['code'] >= 200 && $response['code'] < 300) { $this->log('Branch "dev" created from "main".'); } else { $this->log("WARNING: Could not create dev branch (HTTP {$response['code']})."); $this->log("Response: {$response['body']}"); } // Step 4: Print post-setup instructions $this->printPostSetupInstructions($repoName); $this->log('Scaffold complete.'); return 0; } private function parseArgs(): void { $args = $_SERVER['argv'] ?? []; $count = count($args); for ($i = 1; $i < $count; $i++) { switch ($args[$i]) { case '--name': $this->name = $args[++$i] ?? ''; break; case '--org': $this->org = $args[++$i] ?? ''; break; case '--gitea-url': $this->giteaUrl = rtrim($args[++$i] ?? '', '/'); break; case '--token': $this->token = $args[++$i] ?? ''; break; case '--dry-run': $this->dryRun = true; break; case '--help': case '-h': $this->printUsage(); exit(0); default: $this->log("WARNING: Unknown argument: {$args[$i]}"); break; } } } private function printUsage(): void { $this->log('Usage: scaffold_client.php --name --org --token [options]'); $this->log(''); $this->log('Options:'); $this->log(' --name Client name (e.g., "clarksvillefurs")'); $this->log(' --org Gitea organization (e.g., "ClarksvilleFurs")'); $this->log(' --gitea-url Gitea URL (default: https://git.mokoconsulting.tech)'); $this->log(' --token Gitea API token'); $this->log(' --dry-run Show what would be done without making changes'); $this->log(' --help, -h Show this help'); } private function printPostSetupInstructions(string $repoName): void { $this->log(''); $this->log('=== POST-SETUP INSTRUCTIONS ==='); $this->log(''); $this->log("Navigate to: {$this->giteaUrl}/{$this->org}/{$repoName}/settings"); $this->log(''); $this->log('Set the following REPO VARIABLES (Settings > Actions > Variables):'); $this->log(' DEV_SYNC_HOST - Dev server hostname or IP'); $this->log(' DEV_SYNC_PORT - Dev server SSH port (default: 22)'); $this->log(' DEV_SYNC_USER - Dev server SSH username'); $this->log(' DEV_SYNC_PATH - Dev server deploy path'); $this->log(' LIVE_SSH_HOST - Live server hostname or IP'); $this->log(' LIVE_SSH_PORT - Live server SSH port (default: 22)'); $this->log(' LIVE_SSH_USER - Live server SSH username'); $this->log(' LIVE_SYNC_PATH - Live server deploy path'); $this->log(''); $this->log('Set the following REPO SECRETS (Settings > Actions > Secrets):'); $this->log(' DEV_SYNC_KEY - Private SSH key for dev server'); $this->log(' LIVE_SSH_KEY - Private SSH key for live server'); $this->log(''); $this->log('================================'); } private function apiRequest(string $method, string $endpoint, ?string $body = null): array { $url = $this->giteaUrl . $endpoint; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Accept: application/json', "Authorization: token {$this->token}", ]); if ($body !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, $body); } $responseBody = curl_exec($ch); $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); if (curl_errno($ch)) { $error = curl_error($ch); curl_close($ch); return ['code' => 0, 'body' => "cURL error: {$error}"]; } curl_close($ch); return ['code' => $httpCode, 'body' => $responseBody]; } private function log(string $message): void { fwrite(STDERR, $message . PHP_EOL); } } $app = new ScaffoldClient(); exit($app->run());