Files
certd/scripts/stable.js
T

161 lines
4.6 KiB
JavaScript

import axios from "axios";
import { createInterface } from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";
const AtomgitAccessToken = process.env.ATOMGIT_TOKEN;
if (!AtomgitAccessToken) {
console.error("错误: 请设置环境变量 ATOMGIT_TOKEN");
console.error(" $env:ATOMGIT_TOKEN='your_token' (Windows PowerShell)");
console.error(" 或 export ATOMGIT_TOKEN=your_token (Linux/Mac)");
process.exit(1);
}
const API_BASE = "https://api.atomgit.com/api/v5/repos/certd/certd";
/**
* 获取发布版本列表
*/
async function listReleases() {
const response = await axios.request({
method: "GET",
url: `${API_BASE}/releases`,
params: {
access_token: AtomgitAccessToken,
direction: "desc",
per_page: 10,
},
});
return response.data;
}
/**
* 触发 GitHub Actions workflow_dispatch 来执行稳定版发布
*/
async function triggerWorkflow(version) {
const token = process.env.GH_TOKEN;
if (!token) {
console.error("错误: 请设置环境变量 GH_TOKEN");
console.error(" $env:GH_TOKEN='your_token' (Windows PowerShell)");
console.error(" 需要在 https://github.com/settings/tokens 生成具有 repo 权限的 token");
process.exit(1);
}
try {
await axios.request({
method: "POST",
url: "https://api.github.com/repos/certd/certd/actions/workflows/stable-release.yml/dispatches",
headers: {
"Accept": "application/vnd.github.v3+json",
"Authorization": `Bearer ${token}`,
},
data: {
ref: "v2-dev",
inputs: {
version: version,
},
},
});
console.log(`
✓ 已触发 GitHub Actions workflow`);
console.log(` 版本: ${version}`);
console.log(` 请前往 https://github.com/certd/certd/actions/workflows/stable-release.yml 查看执行状态`);
} catch (error) {
const status = error?.response?.status;
const msg = error?.response?.data?.message || error.message;
if (status === 404) {
console.error(`
请求失败 (404): 工作流文件 stable-release.yml 尚未推送到远程仓库`);
console.error(" 请先提交并推送代码到 v2-dev 分支:");
console.error(" git add .");
console.error(' git commit -m "feat: add stable-release workflow"');
console.error(" git push");
} else {
console.error(`
请求失败 (${status}): ${msg}`);
}
console.error(" 请检查 GH_TOKEN 是否具有 actions:write 权限");
process.exit(1);
}
}
/**
* 格式化输出版本列表
*/
function printReleases(releases) {
console.log("\n");
console.log("序号 | Tag 版本 | 名称 | 状态");
console.log("------|--------------------|-----------------------------------|--------");
releases.forEach((r, i) => {
const idx = String(i + 1).padEnd(4);
const tag = (r.tag_name || "").padEnd(18);
const name = (r.name || "").substring(0, 33).padEnd(33);
const status = releaseStatusLabel(r.release_status);
console.log(`${idx} | ${tag} | ${name} | ${status}`);
});
console.log("\n");
}
function releaseStatusLabel(status) {
if (status === "latest") {
return "稳定版";
}
if (status === "pre") {
return "预览版";
}
return status || "-";
}
async function main() {
try {
console.log("======= 获取发布版本列表... =======");
const releases = await listReleases();
if (!releases || releases.length === 0) {
console.error("没有找到任何发布版本");
process.exit(1);
}
printReleases(releases);
const rl = createInterface({ input, output });
// 请用户选择序号
const answer = await rl.question("请输入序号 (1-" + releases.length + "): ");
const idx = parseInt(answer.trim(), 10);
if (isNaN(idx) || idx < 1 || idx > releases.length) {
console.error("请输入有效序号 (1-" + releases.length + ")");
rl.close();
process.exit(1);
}
const selected = releases[idx - 1];
const tag = selected.tag_name;
// 确认
const confirm = await rl.question(`确定要将 ${tag} 设置为稳定版(Stable)吗?(y/N): `);
rl.close();
if (confirm.trim().toLowerCase() !== "y") {
console.log("已取消");
process.exit(0);
}
// 触发 GitHub Actions workflow
console.log(`
正在触发稳定版发布流程: ${tag}`);
await triggerWorkflow(tag);
} catch (error) {
if (error?.response?.data) {
console.error("请求失败:", JSON.stringify(error.response.data, null, 2));
} else {
console.error("请求失败:", error.message || error);
}
process.exit(1);
}
}
main();