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>
111 lines
3.6 KiB
JavaScript
111 lines
3.6 KiB
JavaScript
import { Router } from 'express'
|
|
import { config } from '../../config.js'
|
|
import { upsertWebsiteProjectByRepo } from '../../services/appwriteAdmin.js'
|
|
import {
|
|
fetchPreviewConfig,
|
|
defaultPreviewConfig,
|
|
runDeploy,
|
|
buildPreviewUrl,
|
|
} from '../../services/previewDeploy.js'
|
|
import { createGitPushWorksheet } from '../../services/gitWorksheet.js'
|
|
|
|
const router = Router()
|
|
|
|
function verifyWebhookToken(req) {
|
|
const token = config.gitea.webhookToken
|
|
if (!token) return false
|
|
const queryToken = req.query.token
|
|
const headerToken = req.get('X-Gitea-Token') || req.get('X-Gogs-Signature')
|
|
return queryToken === token || headerToken === token
|
|
}
|
|
|
|
router.post('/gitea', async (req, res) => {
|
|
if (!verifyWebhookToken(req)) {
|
|
return res.status(401).json({ error: 'Unauthorized' })
|
|
}
|
|
|
|
const payload = req.body || {}
|
|
const ref = payload.ref || ''
|
|
const repo = payload.repository || {}
|
|
const repoFullName = repo.full_name || ''
|
|
const commits = payload.commits || []
|
|
const pusher = payload.pusher || {}
|
|
const commitSha = payload.after || commits[commits.length - 1]?.id || ''
|
|
|
|
if (!repoFullName) {
|
|
return res.status(400).json({ error: 'repository.full_name fehlt' })
|
|
}
|
|
|
|
const branch = ref.replace('refs/heads/', '') || 'main'
|
|
|
|
try {
|
|
const previewConfigFile = await fetchPreviewConfig(repoFullName, branch)
|
|
const previewConfig = previewConfigFile || defaultPreviewConfig(repoFullName)
|
|
const hasPreview = Boolean(previewConfigFile?.enabled !== false && previewConfigFile)
|
|
const subdomain = previewConfig.subdomain || repoFullName.split('/').pop()
|
|
const previewUrl = subdomain ? buildPreviewUrl(subdomain) : ''
|
|
|
|
let deployResult = { deployed: false, skipped: true }
|
|
const configBranch = previewConfig.branch || 'main'
|
|
|
|
if (hasPreview && previewConfig.enabled !== false && branch === configBranch) {
|
|
try {
|
|
deployResult = await runDeploy(repoFullName, branch, previewConfig)
|
|
} catch (deployErr) {
|
|
console.error('[webhook] deploy failed:', deployErr.message)
|
|
deployResult = { deployed: false, error: deployErr.message }
|
|
}
|
|
}
|
|
|
|
const projectPayload = {
|
|
projectName: previewConfig.displayName || repo.name || subdomain,
|
|
templateName: previewConfig.templateName || config.gitea.templateRepo,
|
|
giteaRepoUrl: repo.html_url || `${config.gitea.baseUrl}/${repoFullName}`,
|
|
giteaRepoName: repo.name || subdomain,
|
|
repoFullName,
|
|
}
|
|
|
|
if (subdomain) projectPayload.subdomain = subdomain
|
|
if (previewUrl) projectPayload.previewUrl = previewUrl
|
|
|
|
if (deployResult.deployed) {
|
|
projectPayload.status = 'deployed'
|
|
projectPayload.provisioningStatus = 'ready'
|
|
} else if (hasPreview) {
|
|
projectPayload.status = 'pending'
|
|
projectPayload.provisioningStatus = deployResult.error ? 'deploy_failed' : 'pending'
|
|
} else {
|
|
projectPayload.status = 'synced'
|
|
}
|
|
|
|
const project = await upsertWebsiteProjectByRepo(repoFullName, projectPayload)
|
|
|
|
let gitWorksheet = null
|
|
if (project.ticketId && commitSha && commitSha !== '0000000000000000000000000000000000000000') {
|
|
gitWorksheet = await createGitPushWorksheet({
|
|
ticketId: project.ticketId,
|
|
repoFullName,
|
|
branch,
|
|
commits,
|
|
pusher,
|
|
commitSha,
|
|
})
|
|
}
|
|
|
|
return res.json({
|
|
ok: true,
|
|
repoFullName,
|
|
subdomain,
|
|
previewUrl,
|
|
deploy: deployResult,
|
|
projectId: project.$id,
|
|
gitWorksheet,
|
|
})
|
|
} catch (err) {
|
|
console.error('[webhook]', err)
|
|
return res.status(500).json({ error: err.message || 'Webhook-Verarbeitung fehlgeschlagen' })
|
|
}
|
|
})
|
|
|
|
export default router
|