ai generated solutions to our ai generated problems
This commit is contained in:
+54
-8
@@ -61,6 +61,7 @@ const ALLOWED_REPOSITORY = (process.env.GITHUB_WEBHOOK_REPOSITORY || '').trim()
|
||||
const RESTART_AFTER_MS = 24 * 60 * 60 * 1000
|
||||
|
||||
let deploying = false
|
||||
let queuedPush = null
|
||||
|
||||
function json(res, status, body) {
|
||||
res.writeHead(status, { 'content-type': 'application/json; charset=utf-8' })
|
||||
@@ -347,6 +348,27 @@ function promoteBuiltDist() {
|
||||
}
|
||||
}
|
||||
|
||||
function validateBuiltDist() {
|
||||
const indexPath = path.join(NEXT_DIST_DIR, 'index.html')
|
||||
if (!fs.existsSync(indexPath)) {
|
||||
throw new Error('Frontend build did not produce dist-next/index.html')
|
||||
}
|
||||
|
||||
const html = fs.readFileSync(indexPath, 'utf8')
|
||||
if (/\sintegrity=(["'])sha(?:256|384|512)-[^"']+\1/i.test(html)) {
|
||||
throw new Error('Frontend build contains integrity attributes that may not match the obfuscated assets')
|
||||
}
|
||||
|
||||
const assetPaths = [...html.matchAll(/(?:src|href)=(["'])\/(assets\/[^"']+)\1/g)]
|
||||
.map((match) => match[2])
|
||||
|
||||
for (const assetPath of assetPaths) {
|
||||
if (!fs.existsSync(path.join(NEXT_DIST_DIR, assetPath))) {
|
||||
throw new Error(`Frontend build references missing asset: /${assetPath}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function postDiscordWebhook(payload) {
|
||||
if (!DISCORD_WEBHOOK_URL) return Promise.resolve()
|
||||
|
||||
@@ -510,6 +532,7 @@ async function deploy(push) {
|
||||
diff = await deployDiff(push)
|
||||
await ensureBuildDependencies()
|
||||
await run('npm', ['run', 'build', '--', '--outDir', '../dist-next'])
|
||||
validateBuiltDist()
|
||||
await run('cargo', ['build', '--manifest-path', 'backend/Cargo.toml', '--release'])
|
||||
promoteBuiltDist()
|
||||
|
||||
@@ -524,9 +547,36 @@ async function deploy(push) {
|
||||
}
|
||||
}
|
||||
|
||||
async function runDeployQueue(initialPush) {
|
||||
let push = initialPush
|
||||
|
||||
while (push) {
|
||||
queuedPush = null
|
||||
|
||||
try {
|
||||
await deploy(push)
|
||||
console.log('GitHub push deploy completed')
|
||||
} catch (error) {
|
||||
console.error('GitHub push deploy failed:', error)
|
||||
try {
|
||||
await notifyDeployFailed(push, error, error.deployDiff)
|
||||
} catch (notificationError) {
|
||||
console.error('Failed to send deploy failure notification:', notificationError)
|
||||
}
|
||||
}
|
||||
|
||||
push = queuedPush
|
||||
}
|
||||
}
|
||||
|
||||
const webhookServer = http.createServer((req, res) => {
|
||||
if (req.method === 'GET' && req.url === '/health') {
|
||||
json(res, 200, { ok: true, deploying, restart_targets: RESTART_TARGETS })
|
||||
json(res, 200, {
|
||||
ok: true,
|
||||
deploying,
|
||||
queued: Boolean(queuedPush),
|
||||
restart_targets: RESTART_TARGETS,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -583,19 +633,15 @@ const webhookServer = http.createServer((req, res) => {
|
||||
}
|
||||
|
||||
if (deploying) {
|
||||
json(res, 202, { queued: false, deploying: true })
|
||||
queuedPush = push
|
||||
json(res, 202, { queued: true, deploying: true })
|
||||
return
|
||||
}
|
||||
|
||||
deploying = true
|
||||
json(res, 202, { accepted: true, restart_targets: RESTART_TARGETS })
|
||||
|
||||
deploy(push)
|
||||
.then(() => console.log('GitHub push deploy completed'))
|
||||
.catch((error) => {
|
||||
console.error('GitHub push deploy failed:', error)
|
||||
notifyDeployFailed(push, error, error.deployDiff)
|
||||
})
|
||||
runDeployQueue(push)
|
||||
.finally(() => {
|
||||
deploying = false
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user