[add] 設定settings/actions/secrets

This commit is contained in:
2025-08-15 11:39:08 +08:00
parent 3f363c9a3c
commit 91f314d297
10 changed files with 1740 additions and 276 deletions

301
run.php Normal file
View File

@@ -0,0 +1,301 @@
<?php
// run.php
require 'vendor/autoload.php';
use Google\Client;
use Google\Service\Sheets;
$GITEA_URL = 'https://git.catan.com.tw/api/v1';
$GITEA_TOKEN = '96ed6b6d33931b122c7f12f94153594be0d75b32';
$SERVICE_KEY = __DIR__ . '/google-service-key.json';
$SHEET_ID = '1e-8Cj3Szkb-P0lTKQTeeaS_wI4S7KLS4wyzf5PjNyHQ';
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
function logMsg($msg) {
echo "data: $msg\n\n";
@ob_flush();
flush();
}
function getExcelValue($excelRef, $orgInput) {
global $SERVICE_KEY, $SHEET_ID;
if (!preg_match('/^excel:(\d+):\$(\w)$/', $excelRef, $m)) return null;
$gid = $m[1];
$targetCol = strtoupper($m[2]);
$colIndex = ord($targetCol) - 65;
try {
$client = new Client();
$client->setAuthConfig($SERVICE_KEY);
$client->addScope(\Google\Service\Sheets::SPREADSHEETS_READONLY);
$service = new \Google\Service\Sheets($client);
$spreadsheet = $service->spreadsheets->get($SHEET_ID);
$sheetName = null;
foreach ($spreadsheet->getSheets() as $sheet) {
if ($sheet->getProperties()->getSheetId() === intval($gid)) {
$sheetName = $sheet->getProperties()->getTitle();
break;
}
}
if (!$sheetName) { logMsg("⚠️ 找不到 GID: $gid"); return null; }
$response = $service->spreadsheets_values->get($SHEET_ID, $sheetName);
$values = $response->getValues() ?? [];
$lastNonEmptyCol = []; // 保存每個欄位最後非空值
foreach ($values as $r => &$row) {
// 保證列長度至少到目標欄位
for ($c = 0; $c <= $colIndex; $c++) {
$cell = $row[$c] ?? '';
$cell = trim($cell);
if ($cell !== '') {
$lastNonEmptyCol[$c] = $cell;
} else if (isset($lastNonEmptyCol[$c])) {
$row[$c] = $lastNonEmptyCol[$c]; // 更新列
} else {
$row[$c] = ''; // 避免未設定
}
// logMsg("DEBUG row={$r} col={$c} value='{$row[$c]}'");
}
$cellOrg = $row[0] ?? '';
if ($cellOrg === $orgInput) {
$value = $row[$colIndex] ?? '';
// logMsg("DEBUG 找到 org='{$orgInput}',回傳 col={$colIndex} 值='{$value}'");
return $value;
}
}
unset($row);
logMsg("⚠️ Excel 找不到 org={$orgInput} 的資料 (sheet='{$sheetName}')");
return '';
} catch (\Exception $e) {
logMsg("⚠️ Excel 讀取錯誤: " . $e->getMessage());
return '';
}
}
function fetchJSON($url, $method='GET', $data=null) {
global $GITEA_TOKEN;
$ch = curl_init($url);
$headers = ["Content-Type: application/json"];
if ($GITEA_TOKEN) $headers[] = "Authorization: token $GITEA_TOKEN";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($method === 'POST') curl_setopt($ch, CURLOPT_POST, true);
if ($method === 'PUT') curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
if ($method === 'PATCH') curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
if ($data) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [$code, json_decode($res, true)];
}
function createTeams($org) {
global $GITEA_URL;
$teams = json_decode(file_get_contents('teams.json'), true) ?? [];
logMsg("🟢 開始執行 createTeams...");
// 先抓全部團隊
[$codeAll, $allTeams] = fetchJSON("$GITEA_URL/orgs/$org/teams", 'GET');
$allTeams = $allTeams ?? [];
foreach ($teams as $team) {
$foundTeam = null;
foreach ($allTeams as $t) {
if (strcasecmp($t['name'], $team['name']) === 0) {
$foundTeam = $t;
break;
}
}
if ($foundTeam) {
logMsg("🔄 團隊已存在,更新權限: {$team['name']}");
// 更新權限
fetchJSON("$GITEA_URL/teams/{$foundTeam['id']}", 'PATCH', [
'units_map' => $team['units_map'] ?? [],
'permission' => $team['permission'] ?? 'write'
]);
// 補齊成員
[$codeMembers, $resMembers] = fetchJSON("$GITEA_URL/teams/{$foundTeam['id']}/members", 'GET');
$existingMembers = array_column($resMembers ?? [], 'username');
foreach ($team['members'] ?? [] as $member) {
if (!in_array($member, $existingMembers)) {
[$codeAdd, $resAdd] = fetchJSON("$GITEA_URL/teams/{$foundTeam['id']}/members/$member", 'PUT');
if ($codeAdd === 204) {
logMsg("  ✅ 新增成員: $member");
} else {
logMsg("  ⚠️ 新增成員失敗: $member" . json_encode($resAdd, JSON_UNESCAPED_UNICODE));
}
}
}
} else {
logMsg(" 建立團隊: {$team['name']}");
[$codeCreate, $resCreate] = fetchJSON("$GITEA_URL/orgs/$org/teams", 'POST', [
'name' => $team['name'],
'units_map' => $team['units_map'] ?? [],
'permission' => $team['permission'] ?? 'write'
]);
if ($codeCreate === 201) {
$teamId = $resCreate['id'];
foreach ($team['members'] ?? [] as $member) {
[$codeAdd, $resAdd] = fetchJSON("$GITEA_URL/teams/$teamId/members/$member", 'PUT');
if ($codeAdd === 204) {
logMsg("  ✅ 新增成員: $member");
} else {
logMsg("  ⚠️ 新增成員失敗: $member" . json_encode($resAdd, JSON_UNESCAPED_UNICODE));
}
}
} else {
logMsg("⚠️ 建立團隊失敗: {$team['name']}" . json_encode($resCreate, JSON_UNESCAPED_UNICODE));
}
}
}
logMsg("✅ 所有團隊設定完成!");
}
function createRepos($org) {
global $GITEA_URL;
$repos = json_decode(file_get_contents('repos.json'), true) ?? [];
logMsg("🟢 開始執行 createRepos...");
// 先抓全部 repo避免重複建立
[$codeAll, $allRepos] = fetchJSON("$GITEA_URL/orgs/$org/repos");
$allRepos = $allRepos ?? [];
foreach ($repos as $repo) {
$repoExists = false;
foreach ($allRepos as $r) {
if ($r['name'] === $repo['name']) {
$repoExists = true;
break;
}
}
if ($repoExists) {
logMsg("⚠️ 儲存庫已存在,略過建立:{$repo['name']}");
continue;
}
$payload = [
'name' => $repo['name'],
'description' => $repo['description'] ?? '',
'default_branch' => $repo['default_branch'] ?? 'master',
'private' => false,
'auto_init' => true
];
[$codeCreate, $resCreate] = fetchJSON("$GITEA_URL/orgs/$org/repos", 'POST', $payload);
if ($codeCreate === 201) {
$repoName = $resCreate['name'];
logMsg("✅ 建立儲存庫:{$repoName}");
// 加入團隊
foreach ($repo['teams'] ?? [] as $teamName) {
[$codeTeams, $teamsList] = fetchJSON("$GITEA_URL/orgs/$org/teams");
$targetTeam = null;
foreach ($teamsList ?? [] as $t) {
if ($t['name'] === $teamName) {
$targetTeam = $t;
break;
}
}
if ($targetTeam) {
[$codeAdd, $resAdd] = fetchJSON("$GITEA_URL/teams/{$targetTeam['id']}/repos/$org/$repoName", 'PUT');
if (in_array($codeAdd, [200,204])) {
logMsg("  👥 已加入團隊:{$teamName}");
} else {
logMsg("  ⚠️ 加入團隊失敗:{$teamName}" . json_encode($resAdd, JSON_UNESCAPED_UNICODE));
}
} else {
logMsg("  ⚠️ 找不到團隊:{$teamName}");
}
}
// 建立 Issue
if (!empty($repo['issue'])) {
$issuePayload = [
'title' => $repo['issue']['title'] ?? '',
'body' => $repo['issue']['content'] ?? ''
];
[$codeIssue, $resIssue] = fetchJSON("$GITEA_URL/repos/$org/$repoName/issues", 'POST', $issuePayload);
if ($codeIssue === 201) logMsg("  📌 已建立 Issue{$issuePayload['title']}");
else logMsg("  ⚠️ 建立 Issue 失敗:{$issuePayload['title']}" . json_encode($resIssue, JSON_UNESCAPED_UNICODE));
}
} else {
logMsg("⚠️ 建立儲存庫失敗:{$repo['name']}" . json_encode($resCreate, JSON_UNESCAPED_UNICODE));
}
}
logMsg("✅ 所有儲存庫處理完成!");
}
function setActions($org) {
global $GITEA_URL;
$actions = json_decode(file_get_contents('actions_settings.json'), true) ?? [];
logMsg("🟢 開始執行 setActions...");
$projectSecrets = $actions['project_settings']['secrets'] ?? [];
logMsg("🔧 設定 project");
foreach($projectSecrets as $key=>$value) {
$finalValue = (is_string($value) && str_starts_with($value,'excel:'))
? getExcelValue($value,$org)
: $value;
if(trim($finalValue)==='') { logMsg("  ⚠️ 略過空值 Project Secret: $key"); continue; }
[$code,$res] = fetchJSON("$GITEA_URL/orgs/$org/actions/secrets/$key",'PUT',['data'=>$finalValue]);
if (in_array($code, [200,204,201])) logMsg("  ✅ Project Secret 設定成功: $key");
else logMsg("  ⚠️ Project Secret 設定失敗: $key".json_encode($res,JSON_UNESCAPED_UNICODE));
}
$reposArr = $actions['repos'] ?? [];
foreach($reposArr as $repo) {
$repoName = $repo['name'];
logMsg("🔧 設定 repo: $repoName");
$secrets = $repo['secrets'] ?? [];
foreach($secrets as $key=>$value) {
$finalValue = (is_string($value) && str_starts_with($value,'excel:'))
? getExcelValue($value,$org)
: $value;
if(trim($finalValue)==='') { logMsg("  ⚠️ 略過空值 Repo Secret: $key"); continue; }
[$code,$res] = fetchJSON("$GITEA_URL/repos/$org/$repoName/actions/secrets/$key",'PUT',['data'=>$finalValue]);
if (in_array($code, [200,204,201])) logMsg("  ✅ Repo Secret 設定成功: $key");
else logMsg("  ⚠️ Repo Secret 設定失敗: $key".json_encode($res,JSON_UNESCAPED_UNICODE));
}
}
logMsg("✅ 所有 Actions 設定完成!");
}
$org = $_GET['org'] ?? '';
$action = $_GET['action'] ?? '';
if (!$org) { logMsg("❌ 請輸入組織名稱"); exit; }
switch($action) {
case 'createTeams': createTeams($org); break;
case 'createRepos': createRepos($org); break;
case 'setActions': setActions($org); break;
default: logMsg("⚠️ 未知操作: $action"); break;
}
logMsg("✅ 任務完成");