Files
DndGamePlayer/scripts/sync-update-feed.mjs
T
2026-05-11 22:20:14 +08:00

103 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Складывает артефакты electron-builder (win + mac) в публичный репозиторий,
* ветка `updates`, чтобы generic URL …/raw/branch/updates/ указывал на актуальные latest*.yml и установщики.
*
* Переменные окружения (имена без префикса GITEA_ — в Gitea секреты GITEA_* зарезервированы):
* DND_UPDATES_SERVER — https://git.example.com (без слэша в конце)
* UPDATES_REPO — owner/repo (публичный репозиторий «только релизы»)
* DND_UPDATES_PUSH_TOKEN — PAT с правом push в UPDATES_REPO
* ARTIFACT_WIN — каталог с файлами сборки Windows
* ARTIFACT_MAC — каталог с файлами сборки macOS
* GIT_COMMIT_TAG — опционально, для сообщения коммита
*/
import { execFileSync } from 'node:child_process';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ALLOWED_EXT = new Set(['.yml', '.yaml', '.exe', '.blockmap', '.zip', '.dmg', '.pkg']);
function mustEnv(name) {
const v = process.env[name]?.trim();
if (!v) throw new Error(`Missing env ${name}`);
return v;
}
function copyFlatReleaseFiles(fromDir, toDir) {
if (!fs.existsSync(fromDir)) {
console.warn(`[sync-update-feed] skip missing dir: ${fromDir}`);
return 0;
}
let n = 0;
for (const name of fs.readdirSync(fromDir)) {
const src = path.join(fromDir, name);
if (!fs.statSync(src).isFile()) continue;
const ext = path.extname(name).toLowerCase();
if (!ALLOWED_EXT.has(ext)) continue;
fs.copyFileSync(src, path.join(toDir, name));
n += 1;
}
return n;
}
function runGit(args, cwd) {
execFileSync('git', args, { cwd, stdio: 'inherit' });
}
function emptyWorkingTreeExceptGit(cwd) {
for (const ent of fs.readdirSync(cwd)) {
if (ent === '.git') continue;
fs.rmSync(path.join(cwd, ent), { recursive: true, force: true });
}
}
function main() {
const server = mustEnv('DND_UPDATES_SERVER').replace(/\/+$/u, '');
const updatesRepo = mustEnv('UPDATES_REPO');
const token = mustEnv('DND_UPDATES_PUSH_TOKEN');
const winDir = mustEnv('ARTIFACT_WIN');
const macDir = mustEnv('ARTIFACT_MAC');
const u = new URL(server);
const host = u.host;
const cloneUrl = `https://oauth2:${encodeURIComponent(token)}@${host}/${updatesRepo}.git`;
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'dnd-feed-'));
const work = path.join(tmp, 'repo');
try {
execFileSync('git', ['clone', '--depth', '1', '-b', 'updates', cloneUrl, work], { stdio: 'inherit' });
} catch {
execFileSync('git', ['clone', '--depth', '1', cloneUrl, work], { stdio: 'inherit' });
runGit(['checkout', '-B', 'updates'], work);
}
runGit(['config', 'user.email', 'ci@gitea-actions.local'], work);
runGit(['config', 'user.name', 'gitea-actions'], work);
emptyWorkingTreeExceptGit(work);
const copied = copyFlatReleaseFiles(winDir, work) + copyFlatReleaseFiles(macDir, work);
if (copied === 0) {
throw new Error('[sync-update-feed] no release files copied (check ARTIFACT_WIN / ARTIFACT_MAC)');
}
const tag = process.env.GIT_COMMIT_TAG?.trim() || 'ci';
runGit(['add', '-A'], work);
const st = execFileSync('git', ['status', '--porcelain'], { cwd: work }).toString().trim();
if (st) {
runGit(['commit', '-m', `update feed ${tag}`], work);
runGit(['push', '-u', 'origin', 'updates'], work);
} else {
console.warn('[sync-update-feed] nothing to commit (identical artifacts?)');
}
fs.rmSync(tmp, { recursive: true, force: true });
console.log(`[sync-update-feed] done (${String(copied)} file(s) staged)`);
}
main();