Files
vendoo/tools/verify-deployment-1.33.0.mjs
Masterluke77andGitHub 6f48827f4d Vendoo 1.41.2 – Git Ignore Boundary & Module Tracking Hotfix (#18)
* docs: prepare Vendoo 1.41.2 git-ignore boundary hotfix

* fix: track native source modules with root-anchored runtime ignores
2026-07-09 17:09:00 +02:00

93 lines
5.4 KiB
JavaScript

import { readFileSync, readdirSync, statSync, existsSync } from 'fs';
import { join } from 'path';
const root = new URL('..', import.meta.url).pathname;
const read = rel => readFileSync(join(root, rel), 'utf8');
const failures = [];
const expect = (text, marker, label = marker) => { if (!text.includes(marker)) failures.push(`Fehlt: ${label}`); };
const forbid = (text, marker, label = marker) => { if (text.includes(marker)) failures.push(`Darf nicht enthalten sein: ${label}`); };
const pkg = JSON.parse(read('package.json'));
const lock = JSON.parse(read('package-lock.json'));
const manifest = JSON.parse(read('update-manifest.json'));
const server = read('server.mjs');
const auth = read('lib/auth.mjs');
const runtimePaths = read('lib/runtime-paths.mjs');
const dockerfile = read('Dockerfile');
const compose = read('compose.yaml');
const env = read('.env.example');
const html = read('public/index.html');
const app = read('public/app.js');
const setupPs = read('setup.ps1');
const setupSh = read('setup.sh');
const workflow = read('local-ai/workflows/vendoo_flux_schnell_api.json');
for (const [label, value] of [
['package.json', pkg.version], ['package-lock.json', lock.version],
['package-lock root', lock.packages?.['']?.version], ['update-manifest', manifest.version],
]) if (value !== '1.33.0') failures.push(`${label}-Version ist ${value}`);
for (const marker of ['content="1.33.0"', 'style.css?v=1.33.0', 'app.js?v=1.33.0']) expect(html, marker, `UI-Build ${marker}`);
if (!app.startsWith("const VENDOO_UI_BUILD = '1.33.0';")) failures.push('UI-Build ist nicht 1.33.0');
for (const marker of ["$Version = '1.33.0'", '?build=1.33.0']) expect(setupPs, marker, `Windows-Setup ${marker}`);
for (const marker of [
"app.get('/healthz'", "app.get('/readyz'", 'gracefulShutdown', "process.once('SIGTERM'",
'verifyRuntimeWritable', 'VENDOO_SETUP_TOKEN', 'VENDOO_EXTENSION_ORIGINS', 'setup_required: true',
"app.use('/uploads', requireAuth", 'allowed.includes(ext) && isImageMime',
]) expect(server, marker);
for (const marker of ['VENDOO_DATA_DIR', 'VENDOO_DB_PATH', 'VENDOO_UPLOADS_DIR', 'VENDOO_BACKUP_DIR', 'VENDOO_OPERATIONS_DIR']) expect(runtimePaths, marker);
forbid(server, 'if (isSetupMode()) return next();', 'unsichere globale Setup-Auth-Ausnahme');
for (const marker of ['FROM node:22-bookworm-slim', 'npm ci --omit=dev', 'USER node', 'HEALTHCHECK', 'ENTRYPOINT']) expect(dockerfile, marker);
for (const marker of ['read_only: true', 'no-new-privileges:true', 'cap_drop:', 'vendoo_db:', 'vendoo_uploads:', 'vendoo_backups:', '/readyz', 'pids_limit: 256', 'max-size: "10m"', 'host.docker.internal:host-gateway']) expect(compose, marker);
for (const marker of ['VENDOO_SETUP_TOKEN=', 'VENDOO_COOKIE_SECURE=', 'VENDOO_COOKIE_SAMESITE=', 'VENDOO_EXTENSION_ORIGINS=']) expect(env, marker);
if (workflow.includes('LoadImage')) failures.push('Freier FLUX-Workflow enthält LoadImage');
for (const marker of [
"Wo soll Vendoo betrieben werden?", 'Lokal auf diesem Windows-PC', 'Docker Desktop auf diesem Windows-PC',
'NAS / Portainer / Docker-Server', 'VPS / öffentlicher Linux-Server', 'Install-VendooDocker',
"Get-VendooInstallMode", "Set-VendooInstallMode 'docker'",
]) expect(setupPs, marker, `Windows-Deployment-Assistent ${marker}`);
if (!existsSync(join(root, 'setup.sh'))) failures.push('setup.sh fehlt');
for (const marker of [
'Multiplatform Deployment Assistant', 'Docker auf diesem Linux-/Docker-Host',
'NAS / Portainer / Docker-Host', 'VPS / öffentlicher Server hinter HTTPS-Reverse-Proxy',
'compose build --pull', 'VENDOO_SETUP_TOKEN', 'docker-backup.sh', 'docker-restore.sh',
]) expect(setupSh, marker, `Linux-Deployment-Assistent ${marker}`);
for (const marker of [
'id="flux-studio-reset"', 'Arbeitsbereich zurücksetzen', 'id="edit-user-email"',
'type="button" class="primary-btn" id="edit-user-save-btn"',
]) expect(html, marker, `UI-Fix ${marker}`);
for (const marker of [
'function resetFluxStudioWorkspace', "renderFluxStudioPreview(null)",
"document.getElementById('flux-studio-reset')", 'data-user-edit=',
'adminUsersCache', "button.textContent = 'Wird gespeichert …'",
]) expect(app, marker, `Frontend-Fix ${marker}`);
forbid(app, 'if (!state.fluxStudioCurrent && state.fluxStudioHistory[0])', 'automatische Auswahl des ersten FLUX-Historienbilds');
forbid(app, 'onclick="openEditUser(', 'fragile Inline-Benutzerbearbeitung');
for (const marker of ['return getUsers().find(user => Number(user.id) === Number(id)) || null;']) expect(auth, marker, 'sanitisierte Benutzerantwort nach Update');
function walk(dir, rel = '') {
const out = [];
for (const name of readdirSync(dir)) {
const path = join(dir, name); const child = join(rel, name);
if (statSync(path).isDirectory()) out.push(...walk(path, child)); else out.push(child.replaceAll('\\', '/'));
}
return out;
}
const forbiddenRuntime = walk(root).filter(rel =>
/(^|\/)(vendoo\.db|\.env|node_modules|uploads|backups|operations|logs|runtime|data)(\/|$)/i.test(rel)
&& rel !== '.env.example'
);
if (forbiddenRuntime.length) failures.push(`Verbotene Laufzeitdaten im Paket: ${forbiddenRuntime.slice(0, 10).join(', ')}`);
if (failures.length) {
console.error(`Deployment-Gate 1.33.0 fehlgeschlagen (${failures.length}):`);
failures.forEach(item => console.error(`- ${item}`));
process.exit(1);
}
console.log('Deployment-Gate 1.33.0 erfolgreich: Multiplatform-Assistent, Container-Härtung, leerer FLUX-Start, Reset und stabile Benutzerbearbeitung geprüft.');