Manifestbasierter Production-Updater 3.3, Modulnavigation, optionales Produktbild Studio, Listing-Studio-Aktionsleiste sowie plattformübergreifende Windows-/Linux-Release-Gates.
58 lines
2.3 KiB
JavaScript
58 lines
2.3 KiB
JavaScript
import {
|
|
copyFileSync,
|
|
mkdirSync,
|
|
readFileSync,
|
|
readdirSync,
|
|
rmSync,
|
|
statSync,
|
|
writeFileSync,
|
|
} from 'node:fs';
|
|
import { createHash } from 'node:crypto';
|
|
import { dirname, join, relative, sep } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { generateReleaseManifest } from './generate-release-manifest.mjs';
|
|
import { MANIFEST_FILE, readAndValidateManifest } from './release-manifest-lib.mjs';
|
|
|
|
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
|
|
const outputRoot = join(root, 'release-output');
|
|
const packageName = `Vendoo_${pkg.version}`;
|
|
const stage = join(outputRoot, packageName);
|
|
const normalize = value => value.split(sep).join('/');
|
|
|
|
// The committed manifest is the only release payload contract. Regenerate it first so
|
|
// stale hashes or accidentally omitted source files make the release fail immediately.
|
|
generateReleaseManifest(root);
|
|
const manifest = readAndValidateManifest(root);
|
|
|
|
rmSync(outputRoot, { recursive: true, force: true });
|
|
mkdirSync(stage, { recursive: true });
|
|
for (const entry of manifest.files) {
|
|
const source = join(root, entry.path);
|
|
const target = join(stage, entry.path);
|
|
mkdirSync(dirname(target), { recursive: true });
|
|
copyFileSync(source, target);
|
|
if (statSync(target).size !== entry.size) throw new Error(`Release-Kopie hat falsche Größe: ${entry.path}`);
|
|
}
|
|
copyFileSync(join(root, MANIFEST_FILE), join(stage, MANIFEST_FILE));
|
|
|
|
const checksums = [];
|
|
function hashTree(dir) {
|
|
for (const name of readdirSync(dir).sort((a, b) => a.localeCompare(b, 'en'))) {
|
|
const abs = join(dir, name);
|
|
const stat = statSync(abs);
|
|
if (stat.isDirectory()) hashTree(abs);
|
|
else {
|
|
const rel = normalize(relative(stage, abs));
|
|
if (rel === 'FILE_CHECKSUMS_SHA256.txt') continue;
|
|
const digest = createHash('sha256').update(readFileSync(abs)).digest('hex');
|
|
checksums.push(`${digest} ${rel}`);
|
|
}
|
|
}
|
|
}
|
|
hashTree(stage);
|
|
writeFileSync(join(stage, 'FILE_CHECKSUMS_SHA256.txt'), `${checksums.join('\n')}\n`, 'utf8');
|
|
writeFileSync(join(outputRoot, 'RELEASE_NAME.txt'), `${packageName}\n`, 'utf8');
|
|
console.log(`Manifestbasiertes Release-Staging erstellt: ${stage}`);
|
|
console.log(`${manifest.files.length} Payload-Dateien und ${checksums.length} Paketdateien mit SHA-256 erfasst.`);
|