chore(catalog): initialize production plugin source

This commit is contained in:
2026-09-11 10:58:33 +08:00
commit 557ed8afd0
18 changed files with 596 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
import { readFile } from 'node:fs/promises';
import { createHash } from 'node:crypto';
import { api, download, repositoryPath } from './gitea.mjs';
const config = JSON.parse(await readFile('release.json', 'utf8'));
const descriptorBytes = await readFile('dist/release/trove-release.json');
const descriptor = JSON.parse(descriptorBytes);
const { repository, tag } = descriptor;
if (descriptor.schemaVersion !== 1 || repository !== config.repository) throw new Error('Unexpected release descriptor');
const route = `/repos/${repositoryPath(repository)}`;
const files = new Map();
for (const plugin of descriptor.plugins) {
for (const artifact of plugin.artifacts) {
if (!/^[a-zA-Z0-9._+-]+\.curio$/.test(artifact.asset)) throw new Error('Invalid asset filename');
const bytes = await readFile(`dist/release/${artifact.asset}`);
if (bytes.length !== artifact.size || createHash('sha256').update(bytes).digest('hex') !== artifact.sha256) throw new Error('Package changed after release preparation');
files.set(artifact.asset, bytes);
}
}
files.set('trove-release.json', descriptorBytes);
let release = await api(`${route}/releases/tags/${encodeURIComponent(tag)}`, { missing: true });
if (!release) release = await api(`${route}/releases`, { method: 'POST', body: {
tag_name: tag, target_commitish: descriptor.commit, name: tag, draft: true,
prerelease: tag.slice(1).split('+')[0].includes('-'),
body: `${config.name} ${tag}\n\n通过 Trove 软件源安装和更新。`,
} });
for (const [name, bytes] of files) {
const existing = release.assets.find(asset => asset.name === name);
if (existing) {
const published = await download(existing.browser_download_url, undefined, bytes.length);
if (!published.equals(bytes)) throw new Error(`Release asset is immutable: ${name}; publish a new version`);
continue;
}
if (!release.draft) throw new Error(`Published release is incomplete: ${name}; publish a new version`);
const form = new FormData(); form.append('attachment', new Blob([bytes]), name);
const asset = await api(`${route}/releases/${release.id}/assets?name=${encodeURIComponent(name)}`, { method: 'POST', body: form });
release.assets.push(asset);
}
if (release.draft) await api(`${route}/releases/${release.id}`, { method: 'PATCH', body: { draft: false } });
console.log(`Published ${repository}@${tag}`);
console.log('The release workflow will register these packages in the catalog.');