[add] 設定settings/actions/secrets
This commit is contained in:
302
index.html
302
index.html
@@ -2,294 +2,44 @@
|
||||
<html lang="zh-TW">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta charset="UTF-8">
|
||||
<title>手動輸入組織,批次建立 Gitea 儲存庫與團隊</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
#log {
|
||||
white-space: pre-wrap;
|
||||
background: #f0f0f0;
|
||||
padding: 1em;
|
||||
border-radius: 8px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
label,
|
||||
input {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="icon" href="favicon.svg" type="image/svg+xml">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>
|
||||
輸入組織名稱並從 JSON 建立儲存庫+設定團隊
|
||||
<br />
|
||||
PS.請先建好團隊(或使用下方按鈕批次建立)
|
||||
</h2>
|
||||
<h2>輸入組織名稱並從 JSON 建立儲存庫+設定團隊<br>PS.請先建好團隊(或使用下方按鈕批次建立)</h2>
|
||||
|
||||
<label for="orgInput">組織名稱:</label>
|
||||
<input type="text" id="orgInput" placeholder="請輸入組織名稱" />
|
||||
<button onclick="loadAndCreateTeams()">創建團隊</button>
|
||||
<button onclick="loadAndCreateRepos()">開始建立儲存庫</button>
|
||||
<label>組織名稱:<input type="text" id="orgInput"></label>
|
||||
<button data-action="createTeams">創建團隊</button>
|
||||
<button data-action="createRepos">建立儲存庫</button>
|
||||
<button data-action="setActions">設定 Actions</button>
|
||||
|
||||
<div id="log"></div>
|
||||
|
||||
<script>
|
||||
const accessToken = "96ed6b6d33931b122c7f12f94153594be0d75b32";
|
||||
const proxy = "https://cors-anywhere.bir840124.workers.dev/?url=";
|
||||
const giteaAPIBase = "https://git.catan.com.tw/api/v1";
|
||||
const logDiv = document.getElementById('log');
|
||||
|
||||
const logBox = document.getElementById("log");
|
||||
function log(message) {
|
||||
logBox.textContent += message + "\n";
|
||||
logBox.scrollTop = logBox.scrollHeight;
|
||||
}
|
||||
|
||||
// 建立儲存庫功能
|
||||
async function loadAndCreateRepos() {
|
||||
logBox.textContent = "";
|
||||
const orgInput = document.getElementById("orgInput").value.trim();
|
||||
if (!orgInput) {
|
||||
alert("請輸入組織名稱");
|
||||
return;
|
||||
}
|
||||
log(`✅ 開始建立儲存庫:${orgInput}`);
|
||||
|
||||
try {
|
||||
const res = await fetch("repos.json");
|
||||
const repoList = await res.json();
|
||||
|
||||
for (const repo of repoList) {
|
||||
repo.org = orgInput;
|
||||
await createRepoWithSettings(repo);
|
||||
document.querySelectorAll('button').forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
logDiv.innerHTML = ""; // ← 清空舊訊息
|
||||
const org = document.getElementById('orgInput').value.trim();
|
||||
if (!org) {
|
||||
logDiv.innerHTML = "❌ 請輸入組織名稱<br>";
|
||||
return;
|
||||
}
|
||||
|
||||
log("✅ 所有儲存庫處理完成!");
|
||||
} catch (err) {
|
||||
log("❌ 讀取 repos.json 失敗:" + err.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function repoExists(org, repoName) {
|
||||
const url = `${giteaAPIBase}/orgs/${org}/repos`;
|
||||
const res = await fetch(proxy + url, {
|
||||
headers: { "Authorization": `token ${accessToken}` }
|
||||
const evt = new EventSource(`run.php?org=${encodeURIComponent(org)}&action=${btn.dataset.action}`);
|
||||
evt.onmessage = e => {
|
||||
logDiv.innerHTML += e.data + "<br>";
|
||||
logDiv.scrollTop = logDiv.scrollHeight;
|
||||
};
|
||||
evt.onerror = () => {
|
||||
// logDiv.innerHTML += "執行完成<br>";
|
||||
evt.close();
|
||||
};
|
||||
});
|
||||
if (!res.ok) {
|
||||
throw new Error(`查詢儲存庫失敗,狀態碼:${res.status}`);
|
||||
}
|
||||
const repos = await res.json();
|
||||
return repos.some(r => r.name === repoName);
|
||||
}
|
||||
|
||||
async function createRepoWithSettings(repo) {
|
||||
if (await repoExists(repo.org, repo.name)) {
|
||||
log(`⚠️ 儲存庫已存在,略過建立:${repo.org}/${repo.name}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const createUrl = `${giteaAPIBase}/orgs/${repo.org}/repos`;
|
||||
|
||||
const payload = {
|
||||
name: repo.name,
|
||||
description: repo.description || "",
|
||||
default_branch: repo.default_branch || "master",
|
||||
private: false,
|
||||
auto_init: true
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(proxy + createUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `token ${accessToken}`
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
log(`✅ 建立儲存庫:${repo.org}/${repo.name}`);
|
||||
|
||||
if (repo.teams?.length > 0) {
|
||||
for (const team of repo.teams) {
|
||||
await addTeamToRepo(repo.org, repo.name, team);
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:建立 Issue
|
||||
if (repo.issue) {
|
||||
await createIssue(repo.org, repo.name, repo.issue);
|
||||
}
|
||||
|
||||
} else {
|
||||
log(`⚠️ 建立失敗:${repo.org}/${repo.name} - ${data.message}`);
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
log(`❌ 建立錯誤:${repo.org}/${repo.name} - ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function createIssue(org, repoName, issue) {
|
||||
const url = `${giteaAPIBase}/repos/${org}/${repoName}/issues`;
|
||||
const payload = {
|
||||
title: issue.title || "",
|
||||
body: issue.content || ""
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await fetch(proxy + url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `token ${accessToken}`
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
log(`📌 已建立 Issue:${issue.title}`);
|
||||
} else {
|
||||
const data = await res.json();
|
||||
log(`⚠️ 建立 Issue 失敗:${data.message || res.statusText}`);
|
||||
}
|
||||
} catch (err) {
|
||||
log(`❌ 建立 Issue 錯誤:${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function addTeamToRepo(org, repo, teamName) {
|
||||
const teamsURL = `${giteaAPIBase}/orgs/${org}/teams`;
|
||||
const teamRes = await fetch(proxy + teamsURL, {
|
||||
headers: { "Authorization": `token ${accessToken}` }
|
||||
});
|
||||
const teams = await teamRes.json();
|
||||
const targetTeam = teams.find(t => t.name === teamName);
|
||||
|
||||
if (!targetTeam) {
|
||||
log(`⚠️ 找不到團隊:${teamName}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const url = `${giteaAPIBase}/teams/${targetTeam.id}/repos/${org}/${repo}`;
|
||||
const res = await fetch(proxy + url, {
|
||||
method: "PUT",
|
||||
headers: { "Authorization": `token ${accessToken}` }
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
log(`👥 加入團隊:${teamName}`);
|
||||
} else {
|
||||
log(`⚠️ 加團隊失敗:${teamName}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 創建團隊功能
|
||||
async function loadAndCreateTeams() {
|
||||
logBox.textContent = "";
|
||||
const orgInput = document.getElementById("orgInput").value.trim();
|
||||
if (!orgInput) {
|
||||
alert("請輸入組織名稱");
|
||||
return;
|
||||
}
|
||||
log(`✅ 開始建立團隊:${orgInput}`);
|
||||
|
||||
try {
|
||||
const res = await fetch("teams.json");
|
||||
const teamList = await res.json();
|
||||
|
||||
for (const team of teamList) {
|
||||
await createTeam(orgInput, team);
|
||||
}
|
||||
|
||||
log("✅ 所有團隊建立完成!");
|
||||
} catch (err) {
|
||||
log("❌ 讀取 teams.json 失敗:" + err.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function createTeam(org, team) {
|
||||
const url = `${giteaAPIBase}/orgs/${org}/teams`;
|
||||
|
||||
const payload = {
|
||||
name: team.name,
|
||||
description: team.description || "",
|
||||
permission: "none",
|
||||
units: team.units || [],
|
||||
units_map: team.units_map || {},
|
||||
can_create_org_repo: false,
|
||||
includes_all_repositories: false
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(proxy + url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `token ${accessToken}`
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
log(`✅ 團隊建立成功:${team.name}`);
|
||||
if (team.members?.length > 0) {
|
||||
for (const username of team.members) {
|
||||
await addMemberToTeam(data.id, username);
|
||||
}
|
||||
}
|
||||
} else if (data.message?.includes("team already exists")) {
|
||||
log(`⚠️ 團隊已存在,略過:${team.name}`);
|
||||
} else {
|
||||
log(`⚠️ 建立團隊失敗:${team.name} - ${data.message}`);
|
||||
}
|
||||
} catch (err) {
|
||||
log(`❌ 團隊建立錯誤:${team.name} - ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function addMemberToTeam(teamId, username) {
|
||||
const url = `${giteaAPIBase}/teams/${teamId}/members/${username}`;
|
||||
|
||||
try {
|
||||
const res = await fetch(proxy + url, {
|
||||
method: "PUT",
|
||||
headers: { "Authorization": `token ${accessToken}` }
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
log(`👤 新增成員:${username}`);
|
||||
} else {
|
||||
const data = await res.json();
|
||||
log(`⚠️ 新增成員失敗:${username} - ${data.message || res.statusText}`);
|
||||
}
|
||||
} catch (err) {
|
||||
log(`❌ 新增成員錯誤:${username} - ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function delay(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user