previewDeploy: node_build-Autodetect fuer App-Repos + Build-Output-Erkennung
- runDeploy: Repos mit package.json-build-Script ohne index.html werden automatisch als node_build gebaut (Expo/Vite/React zeigen sonst nur den Platzhalter); Build-Fehler fallen auf static+Platzhalter zurueck - deployNodeBuild: npm-ci-Fallback auf npm install, Output-Erkennung dist/build/out/web-build, maxBuffer+Timeout - updateWebsiteProject: bestehenden type/index aus .webklar-preview.json erhalten statt bei jedem Edit auf static zurueckzusetzen Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -432,9 +432,20 @@ export async function updateWebsiteProject(projectId, { projectName, subdomain,
|
|||||||
/* Default main */
|
/* Default main */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deploy-Typ (z.B. node_build) und index-Unterordner aus der vorhandenen
|
||||||
|
// Repo-Config uebernehmen - sonst wuerde jedes Bearbeiten im Portal
|
||||||
|
// App-Projekte (Expo/Vite/React) wieder auf "static" zuruecksetzen.
|
||||||
|
let existingCfg = null
|
||||||
|
try {
|
||||||
|
existingCfg = await fetchPreviewConfig(repoFullName, branch)
|
||||||
|
} catch {
|
||||||
|
/* keine bestehende Config -> Defaults */
|
||||||
|
}
|
||||||
|
|
||||||
const previewConfig = {
|
const previewConfig = {
|
||||||
enabled: hasWebsite,
|
enabled: hasWebsite,
|
||||||
type: 'static',
|
type: existingCfg?.type || 'static',
|
||||||
|
...(existingCfg?.index ? { index: existingCfg.index } : {}),
|
||||||
branch,
|
branch,
|
||||||
displayName: nextName,
|
displayName: nextName,
|
||||||
templateName: doc.templateName || config.gitea.templateRepo,
|
templateName: doc.templateName || config.gitea.templateRepo,
|
||||||
|
|||||||
@@ -215,11 +215,60 @@ async function ensureIndexHtml(targetDir, displayName) {
|
|||||||
return { placeholder: true }
|
return { placeholder: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erkennt App-Repos, die einen Build-Schritt brauchen (Expo, Vite, React ...):
|
||||||
|
* package.json mit "build"-Script vorhanden, aber keine index.html im Webroot.
|
||||||
|
* Solche Repos wuerden als "static" nur den Platzhalter zeigen - deshalb wird
|
||||||
|
* der Deploy-Typ automatisch auf node_build angehoben (Langzeit-Fix, damit
|
||||||
|
* App-Projekte ohne manuelle Config-Pflege korrekt angezeigt werden).
|
||||||
|
*/
|
||||||
|
async function shouldAutoBuild(sourceDir, indexSubdir = '') {
|
||||||
|
try {
|
||||||
|
const pkg = JSON.parse(await fs.readFile(path.join(sourceDir, 'package.json'), 'utf8'))
|
||||||
|
if (!pkg?.scripts?.build) return false
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const webroot = indexSubdir ? path.join(sourceDir, indexSubdir) : sourceDir
|
||||||
|
try {
|
||||||
|
await fs.access(path.join(webroot, 'index.html'))
|
||||||
|
return false // echte statische Startseite vorhanden -> kein Build noetig
|
||||||
|
} catch {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* npm ci + npm run build, dann das Build-Ausgabeverzeichnis deployen.
|
||||||
|
* Ausgabeverzeichnis wird erkannt (dist > build > out > web-build), weil
|
||||||
|
* Toolchains unterschiedliche Defaults haben (Expo/Vite: dist, CRA: build).
|
||||||
|
*/
|
||||||
async function deployNodeBuild(sourceDir, targetDir) {
|
async function deployNodeBuild(sourceDir, targetDir) {
|
||||||
await execFileAsync('npm', ['ci'], { cwd: sourceDir })
|
const execOpts = {
|
||||||
await execFileAsync('npm', ['run', 'build'], { cwd: sourceDir })
|
cwd: sourceDir,
|
||||||
const distDir = path.join(sourceDir, 'dist')
|
maxBuffer: 64 * 1024 * 1024,
|
||||||
await deployStatic(distDir, targetDir)
|
timeout: 15 * 60 * 1000,
|
||||||
|
env: { ...process.env, CI: '1' },
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await execFileAsync('npm', ['ci'], execOpts)
|
||||||
|
} catch {
|
||||||
|
// Ohne (passendes) package-lock.json schlaegt npm ci fehl -> npm install.
|
||||||
|
await execFileAsync('npm', ['install', '--no-audit', '--no-fund'], execOpts)
|
||||||
|
}
|
||||||
|
await execFileAsync('npm', ['run', 'build'], execOpts)
|
||||||
|
|
||||||
|
for (const dirName of ['dist', 'build', 'out', 'web-build']) {
|
||||||
|
const candidate = path.join(sourceDir, dirName)
|
||||||
|
try {
|
||||||
|
await fs.access(path.join(candidate, 'index.html'))
|
||||||
|
await deployStatic(candidate, targetDir)
|
||||||
|
return
|
||||||
|
} catch {
|
||||||
|
/* naechsten Kandidaten pruefen */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error('Build erzeugte kein Ausgabeverzeichnis mit index.html (dist/build/out/web-build)')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildPreviewUrl(subdomain) {
|
export function buildPreviewUrl(subdomain) {
|
||||||
@@ -310,8 +359,21 @@ export async function runDeploy(repoFullName, branch, previewConfig) {
|
|||||||
|
|
||||||
await cloneRepo(cloneUrl, workDir, branch, config.gitea.apiToken)
|
await cloneRepo(cloneUrl, workDir, branch, config.gitea.apiToken)
|
||||||
|
|
||||||
if (previewConfig.type === 'node_build') {
|
let deployType = previewConfig.type
|
||||||
|
if (deployType !== 'node_build' && (await shouldAutoBuild(workDir, previewConfig.index || ''))) {
|
||||||
|
console.log(`[previewDeploy] ${repoFullName}: package.json mit build-Script, keine index.html -> node_build (auto)`)
|
||||||
|
deployType = 'node_build'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deployType === 'node_build') {
|
||||||
|
try {
|
||||||
await deployNodeBuild(workDir, targetDir)
|
await deployNodeBuild(workDir, targetDir)
|
||||||
|
} catch (err) {
|
||||||
|
// Build-Fehler duerfen die Subdomain nicht toeten: statisch deployen,
|
||||||
|
// ensureIndexHtml haelt sie mit Kandidat/Platzhalter erreichbar.
|
||||||
|
console.error(`[previewDeploy] node_build fuer ${repoFullName} fehlgeschlagen, Fallback auf static:`, err.message)
|
||||||
|
await deployStatic(workDir, targetDir, previewConfig.index || '')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
await deployStatic(workDir, targetDir, previewConfig.index || '')
|
await deployStatic(workDir, targetDir, previewConfig.index || '')
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user