56e53dff55
Universal: Cascade Main → Dev / Cascade main → branches (push) Has been cancelled
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Access control (push) Has been cancelled
Authored-by: Moko Consulting
251 lines
7.1 KiB
PHP
251 lines
7.1 KiB
PHP
#!/usr/bin/env php
|
|
<?php
|
|
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
*
|
|
* This file is part of a Moko Consulting project.
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* FILE INFORMATION
|
|
* DEFGROUP: MokoStandards.Scripts.CLI
|
|
* INGROUP: MokoStandards
|
|
* 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 <client-name> --org <gitea-org> --token <token> [options]');
|
|
$this->log('');
|
|
$this->log('Options:');
|
|
$this->log(' --name <name> Client name (e.g., "clarksvillefurs")');
|
|
$this->log(' --org <org> Gitea organization (e.g., "ClarksvilleFurs")');
|
|
$this->log(' --gitea-url <url> Gitea URL (default: https://git.mokoconsulting.tech)');
|
|
$this->log(' --token <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());
|