chore: add Gitea push helper (Node/PowerShell)

This commit is contained in:
ClassIsland Prompt Kit committed 2026-11-12 22:00:47 +08:00
1 parent 22c1784bab
commit 67694183eb
1 file changed
+89
+89
View File
@@ -0,0 +1,89 @@
#!/usr/bin/env node
/**
* 创建/推送到 Gitea(默认 http://10.126.232.10:3000)。
* 用法:
* GITEA_TOKEN=<token> node scripts/push-to-gitea.mjs
* 可选环境变量:GITEA_URL、GITEA_REPO、GITEA_PUBLIC=1
* 令牌只从环境变量读取,不写入仓库文件;推送完成后 origin 会还原为不含凭据的 URL。
*/
import { spawnSync } from 'node:child_process';
const base = (process.env.GITEA_URL || 'http://10.126.232.10:3000').replace(/\/+$/, '');
const token = (process.env.GITEA_TOKEN || '').trim();
const repo = process.env.GITEA_REPO || 'classhelper-island-refactor-prompt';
const isPublic = process.env.GITEA_PUBLIC === '1';
if (!token) {
console.error('缺少环境变量 GITEA_TOKEN(Gitea 访问令牌)。');
process.exit(2);
}
const headers = { Authorization: `token ${token}`, 'Content-Type': 'application/json', Accept: 'application/json' };
async function api(path, init = {}) {
const res = await fetch(`${base}/api/v1${path}`, { ...init, headers, signal: AbortSignal.timeout(20000) });
const text = await res.text();
let data = null;
try { data = text ? JSON.parse(text) : null; } catch { data = text; }
return { res, data };
}
function git(args, opts = {}) {
return spawnSync('git', args, { stdio: 'inherit', ...opts });
}
const main = async () => {
console.log(`[1/4] 校验令牌:GET ${base}/api/v1/user`);
const u = await api('/user');
if (!u.res.ok || !u.data?.login) {
throw new Error(`无法获取当前用户(HTTP ${u.res.status})。请检查 Gitea 地址、网络与令牌。`);
}
const login = u.data.login;
console.log(` 当前用户:${login}`);
console.log(`[2/4] 创建仓库:${repo}(${isPublic ? '公开' : '私有'})`);
const existing = await api(`/repos/${encodeURIComponent(login)}/${encodeURIComponent(repo)}`);
if (existing.res.ok) {
console.log(' 仓库已存在,直接推送。');
} else if (existing.res.status !== 404) {
console.log(` 仓库探测返回 HTTP ${existing.res.status},继续尝试创建。`);
}
if (!existing.res.ok) {
const created = await api('/user/repos', {
method: 'POST',
body: JSON.stringify({
name: repo,
private: !isPublic,
auto_init: false,
description: 'ClassIsland / ClassHelper 灵动岛提示词套件(静态分析产物)',
}),
});
if (created.res.ok) {
console.log(` 已创建:${created.data.full_name}`);
console.log(` 网页地址:${created.data.html_url}`);
} else if (created.res.status === 409) {
console.log(' 仓库已存在(409),继续推送。');
} else {
throw new Error(`创建仓库失败(HTTP ${created.res.status}):${JSON.stringify(created.data)}`);
}
}
console.log('[3/4] 推送 main 分支');
const cleanUrl = `${base}/${login}/${repo}.git`;
const scheme = base.split('://')[0];
const host = base.split('://')[1];
const authUrl = `${scheme}://${encodeURIComponent(login)}:${encodeURIComponent(token)}@${host}/${login}/${repo}.git`;
git(['remote', 'remove', 'origin']);
git(['remote', 'add', 'origin', authUrl]);
try {
const pushed = git(['push', '-u', 'origin', 'HEAD:main']);
if (pushed.status !== 0) throw new Error(`git push 失败(exit ${pushed.status})`);
} finally {
git(['remote', 'set-url', 'origin', cleanUrl]);
console.log(` 已将 origin 还原为不含凭据的地址:${cleanUrl}`);
}
console.log(`[4/4] 完成\n仓库:${cleanUrl}`);
};
main().catch((e) => {
console.error(`错误:${e.message}`);
process.exit(1);
});