chore: aktuellen Live-Stand sichern (Admin-API, Services, Auth-Erweiterungen)
Sichert den bisher uncommitteten Produktionsstand des Kundenbereich-Servers, damit kuenftige Deploys (git reset --hard) nichts mehr verwerfen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
89
server/services/previewDeploy.js
Normal file
89
server/services/previewDeploy.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import { execFile } from 'node:child_process'
|
||||
import { promisify } from 'node:util'
|
||||
import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import { config } from '../config.js'
|
||||
|
||||
const execFileAsync = promisify(execFile)
|
||||
|
||||
export async function fetchPreviewConfig(repoFullName, branch) {
|
||||
const [owner, repo] = repoFullName.split('/')
|
||||
if (!owner || !repo || !config.gitea.apiToken) {
|
||||
return null
|
||||
}
|
||||
|
||||
const url = `${config.gitea.baseUrl}/api/v1/repos/${owner}/${repo}/contents/.webklar-preview.json?ref=${encodeURIComponent(branch)}`
|
||||
const response = await fetch(url, {
|
||||
headers: { Authorization: `token ${config.gitea.apiToken}` },
|
||||
})
|
||||
|
||||
if (!response.ok) return null
|
||||
|
||||
const data = await response.json()
|
||||
const content = Buffer.from(data.content || '', 'base64').toString('utf8')
|
||||
return JSON.parse(content)
|
||||
}
|
||||
|
||||
export function defaultPreviewConfig(repoFullName) {
|
||||
const repoName = repoFullName.split('/').pop() || 'preview'
|
||||
return {
|
||||
enabled: false,
|
||||
type: 'static',
|
||||
branch: 'main',
|
||||
displayName: repoName,
|
||||
subdomain: repoName,
|
||||
}
|
||||
}
|
||||
|
||||
async function cloneRepo(cloneUrl, targetDir, branch) {
|
||||
await fs.rm(targetDir, { recursive: true, force: true })
|
||||
await fs.mkdir(targetDir, { recursive: true })
|
||||
await execFileAsync('git', [
|
||||
'clone',
|
||||
'--depth',
|
||||
'1',
|
||||
'--branch',
|
||||
branch,
|
||||
cloneUrl,
|
||||
targetDir,
|
||||
])
|
||||
}
|
||||
|
||||
async function deployStatic(sourceDir, targetDir, indexSubdir = '') {
|
||||
const webroot = indexSubdir ? path.join(sourceDir, indexSubdir) : sourceDir
|
||||
await fs.rm(targetDir, { recursive: true, force: true })
|
||||
await fs.mkdir(targetDir, { recursive: true })
|
||||
await execFileAsync('cp', ['-R', `${webroot}/.`, targetDir])
|
||||
}
|
||||
|
||||
async function deployNodeBuild(sourceDir, targetDir) {
|
||||
await execFileAsync('npm', ['ci'], { cwd: sourceDir })
|
||||
await execFileAsync('npm', ['run', 'build'], { cwd: sourceDir })
|
||||
const distDir = path.join(sourceDir, 'dist')
|
||||
await deployStatic(distDir, targetDir)
|
||||
}
|
||||
|
||||
export function buildPreviewUrl(subdomain) {
|
||||
return `https://${subdomain}.${config.preview.baseHost}`
|
||||
}
|
||||
|
||||
export async function runDeploy(repoFullName, branch, previewConfig) {
|
||||
if (!config.preview.deployRoot) {
|
||||
return { deployed: false, reason: 'PREVIEW_DEPLOY_ROOT nicht gesetzt' }
|
||||
}
|
||||
|
||||
const subdomain = previewConfig.subdomain || repoFullName.split('/').pop()
|
||||
const cloneUrl = `${config.gitea.baseUrl}/${repoFullName}.git`
|
||||
const workDir = path.join(process.cwd(), 'preview-data', repoFullName.replace(/\//g, '_'))
|
||||
const targetDir = path.join(config.preview.deployRoot, subdomain)
|
||||
|
||||
await cloneRepo(cloneUrl, workDir, branch)
|
||||
|
||||
if (previewConfig.type === 'node_build') {
|
||||
await deployNodeBuild(workDir, targetDir)
|
||||
} else {
|
||||
await deployStatic(workDir, targetDir, previewConfig.index || '')
|
||||
}
|
||||
|
||||
return { deployed: true, subdomain, targetDir }
|
||||
}
|
||||
Reference in New Issue
Block a user