#!/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/release_cascade.php * BRIEF: Delete lesser pre-release channels from Gitea when promoting stability * * Usage: * php release_cascade.php --stability stable --token TOKEN --api-base URL * php release_cascade.php --stability rc --token TOKEN --api-base URL * * Cascade rules: * stable -> deletes development, alpha, beta, release-candidate * rc -> deletes development, alpha, beta * beta -> deletes development, alpha * alpha -> deletes development */ declare(strict_types=1); $stability = null; $token = null; $apiBase = null; foreach ($argv as $i => $arg) { if ($arg === '--stability' && isset($argv[$i + 1])) $stability = $argv[$i + 1]; if ($arg === '--token' && isset($argv[$i + 1])) $token = $argv[$i + 1]; if ($arg === '--api-base' && isset($argv[$i + 1])) $apiBase = $argv[$i + 1]; } // Allow token from environment if ($token === null) { $token = getenv('GA_TOKEN') ?: getenv('GITEA_TOKEN') ?: null; } if ($stability === null || $token === null || $apiBase === null) { fwrite(STDERR, "Usage: release_cascade.php --stability [stable|rc|beta|alpha] --token TOKEN --api-base URL\n"); fwrite(STDERR, " --api-base: e.g. https://git.mokoconsulting.tech/api/v1/repos/Org/Repo\n"); fwrite(STDERR, " Token can also be set via GA_TOKEN or GITEA_TOKEN env var\n"); exit(1); } // Define cascade hierarchy $cascadeMap = [ 'stable' => ['development', 'alpha', 'beta', 'release-candidate'], 'rc' => ['development', 'alpha', 'beta'], 'beta' => ['development', 'alpha'], 'alpha' => ['development'], ]; if (!isset($cascadeMap[$stability])) { fwrite(STDERR, "Unknown stability level: {$stability}\n"); fwrite(STDERR, "Valid options: stable, rc, beta, alpha\n"); exit(1); } $tagsToDelete = $cascadeMap[$stability]; $deleted = 0; foreach ($tagsToDelete as $tag) { // Get release by tag $ch = curl_init("{$apiBase}/releases/tags/{$tag}"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: token {$token}"], CURLOPT_TIMEOUT => 30, ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200 || empty($response)) { continue; } $data = json_decode($response, true); $releaseId = $data['id'] ?? null; if ($releaseId === null) { continue; } // Delete release $ch = curl_init("{$apiBase}/releases/{$releaseId}"); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'DELETE', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: token {$token}"], CURLOPT_TIMEOUT => 30, ]); curl_exec($ch); curl_close($ch); // Delete tag $ch = curl_init("{$apiBase}/tags/{$tag}"); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'DELETE', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: token {$token}"], CURLOPT_TIMEOUT => 30, ]); curl_exec($ch); curl_close($ch); echo "Deleted: {$tag} (release id: {$releaseId})\n"; $deleted++; } echo "Cleaned up {$deleted} pre-release channel(s)\n"; exit(0);