Runner: index.html-Rueckfall wie bisheriger Deploy (Kandidat/Platzhalter/Unterordner)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-09-30 22:15:27 +00:00
1 parent 54f307d12a
commit 8a028ce75a
7 files changed
+294 -10

No files matched your search

+59
View File
@@ -0,0 +1,59 @@
import { test } from 'node:test'
import assert from 'node:assert/strict'
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import { previewDeployInternals as legacy } from '../server/services/previewDeploy.js'
import { createJobs } from '../runner/src/jobs.js'
const FIXTURES = {
doener: { 'Doener_Nation_Website.html': '<html>Döner</html>', '.webklar-preview.json': '{"type":"static"}' },
leer: { 'readme.txt': 'x' },
mehrere: { 'a.html': 'aaaa', 'z.html': 'zzzzzzzz', 'css/s.css': 'c' },
bevorzugt: { 'about.html': 'AAAAAAAAAA', 'main.html': 'm' },
index: { 'index.html': 'I', 'other.html': 'o' },
unterordner: { 'site/home.html': 'H', 'site/a.css': 'c', 'root.html': 'r' },
}
function walk(dir, base = dir) {
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) => {
const p = path.join(dir, e.name)
return e.isDirectory() ? walk(p, base) : [path.relative(base, p)]
}).sort()
}
async function viaRunner(files, index) {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'parity-r-'))
const config = { giteaUrl: 'https://g', giteaToken: 'tok_SECRET_123456', previewsRoot: path.join(root, 'p'), workRoot: path.join(root, 'w'), cacheRoot: path.join(root, 'c'), minFreeBytes: 1, buildTimeoutMs: 1e6 }
const git = async ({ dir }) => {
for (const [f, c] of Object.entries(files)) { fs.mkdirSync(path.dirname(path.join(dir, f)), { recursive: true }); fs.writeFileSync(path.join(dir, f), c) }
fs.mkdirSync(path.join(dir, '.git'), { recursive: true }); fs.writeFileSync(path.join(dir, '.git/config'), 'x')
}
const jobs = createJobs({ config, docker: { run: async () => ({ code: 0 }) }, git, mem: () => 1e10, fs: { chownR: async () => {} }, setTimer: () => {} })
const id = jobs.submit({ sub: 'demo', repo: 'o/r', sha: 'abcdef1', branch: 'main', mode: 'auto', env: {}, displayName: 'Demo', ...(index ? { index } : {}) })
for (let i = 0; i < 400 && !['done', 'failed'].includes(jobs.get(id).state); i++) await new Promise((r) => setTimeout(r, 5))
assert.equal(jobs.get(id).state, 'done')
return path.join(config.previewsRoot, 'demo')
}
async function viaLegacy(files, index) {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'parity-l-'))
const src = path.join(root, 'src')
for (const [f, c] of Object.entries(files)) { fs.mkdirSync(path.dirname(path.join(src, f)), { recursive: true }); fs.writeFileSync(path.join(src, f), c) }
fs.mkdirSync(path.join(src, '.git'), { recursive: true }); fs.writeFileSync(path.join(src, '.git/config'), 'x')
const target = path.join(root, 'out')
await legacy.deployStatic(src, target, index || '')
await legacy.ensureIndexHtml(target, 'Demo')
return target
}
for (const [name, files] of Object.entries(FIXTURES)) {
for (const index of name === 'unterordner' ? ['', 'site', 'fehlt'] : ['']) {
test(`Parität Altpfad/Runner: ${name}${index ? ` (index=${index})` : ''}`, async () => {
const a = await viaLegacy(files, index)
const b = await viaRunner(files, index)
assert.deepEqual(walk(b), walk(a))
for (const f of walk(a)) assert.deepEqual(fs.readFileSync(path.join(b, f)), fs.readFileSync(path.join(a, f)), f)
})
}
}
+13 -2
View File
@@ -104,7 +104,7 @@ test('Schalter aus: kein Runner-Aufruf, alter Pfad', async () => {
})
test('an: Auftrag mit entschlüsselten Variablen, sofortige Rückgabe, Ergebnis online', async () => {
const { id, repo, doc } = await project({ previewEnv: envLib.encryptEnv({ API_URL: 'https://x.test' }, key) })
const { id, repo, doc } = await project({ projectName: 'Mein Projekt', previewEnv: envLib.encryptEnv({ API_URL: 'https://x.test' }, key) })
const r = await pd.runDeploy(repo, 'main', cfg(repo), { project: doc, sha: SHA })
assert.equal(r.queued, true)
assert.equal(r.deployed, false)
@@ -112,7 +112,7 @@ test('an: Auftrag mit entschlüsselten Variablen, sofortige Rückgabe, Ergebnis
assert.equal(aw.get('websiteProjects', id).previewState, 'building')
const [sub] = submits()
assert.equal(sub.auth, 'Bearer sekret')
assert.deepEqual(sub.body, { sub: repo.split('/')[1], repo, sha: SHA, branch: 'main', mode: 'auto', env: { API_URL: 'https://x.test' } })
assert.deepEqual(sub.body, { sub: repo.split('/')[1], repo, sha: SHA, branch: 'main', mode: 'auto', displayName: 'Mein Projekt', env: { API_URL: 'https://x.test' } })
await pd.waitForRunFollowers()
const d = aw.get('websiteProjects', id)
assert.equal(d.previewState, 'online')
@@ -123,6 +123,17 @@ test('an: Auftrag mit entschlüsselten Variablen, sofortige Rückgabe, Ergebnis
assert.equal((await logs.listRunLogs(id)).length, 1)
})
test('displayName: previewConfig.displayName hat Vorrang vor projectName, sonst projectName', async () => {
const a = await project({ projectName: 'Projektname' })
await pd.runDeploy(a.repo, 'main', { ...cfg(a.repo), displayName: 'Doener Nation' }, { project: a.doc, sha: SHA })
await pd.waitForRunFollowers()
assert.equal(submits().at(-1).body.displayName, 'Doener Nation')
const b = await project({ projectName: 'Projektname' })
await pd.runDeploy(b.repo, 'main', cfg(b.repo), { project: b.doc, sha: SHA })
await pd.waitForRunFollowers()
assert.equal(submits().at(-1).body.displayName, 'Projektname')
})
test('Sha fehlt: Branch-Kopf per Gitea-API', async () => {
const { repo, doc } = await project()
await pd.runDeploy(repo, 'main', cfg(repo), { project: doc })