✨ feat: implement build version check and update build info handling
This commit is contained in:
@@ -1,6 +1,36 @@
|
||||
const fs = require("fs")
|
||||
const { execSync } = require("child_process")
|
||||
const postcssPlugin = require("esbuild-postcss")
|
||||
|
||||
// Resolve version at build time via git describe (tag + hash), fallback to env var or "dev"
|
||||
let gitHash = "dev"
|
||||
try {
|
||||
gitHash = process.env.GIT_HASH || execSync("git describe --tags --always --dirty").toString().trim()
|
||||
} catch (_) {
|
||||
// .git not available (e.g. Docker build without .git context)
|
||||
}
|
||||
|
||||
// Generate buildInfo module that can be imported by frontend code
|
||||
function writeBuildInfo() {
|
||||
const info = {
|
||||
gitHash,
|
||||
buildTime: new Date().toISOString(),
|
||||
}
|
||||
fs.writeFileSync(
|
||||
__dirname + "/frontend/src/lib/buildInfo.ts",
|
||||
`// AUTO-GENERATED by esbuild.config.js \u2013 do not edit\nexport const gitHash = ${JSON.stringify(info.gitHash)}\nexport const buildTime = ${JSON.stringify(info.buildTime)}\n`
|
||||
)
|
||||
// Write same buildInfo for backend hooks (X-Build-Time / X-Release headers)
|
||||
fs.writeFileSync(
|
||||
__dirname + "/api/hooks/lib/buildInfo.js",
|
||||
`// AUTO-GENERATED by esbuild.config.js \u2013 do not edit\nmodule.exports = { gitHash: ${JSON.stringify(info.gitHash)}, buildTime: ${JSON.stringify(info.buildTime)} }\n`
|
||||
)
|
||||
}
|
||||
// NOTE: writeBuildInfo() is NOT called here at top-level.
|
||||
// It is called by esbuild-wrapper.js before each build.
|
||||
// This prevents the server build from overwriting the frontend's timestamp
|
||||
// (which would cause a version mismatch and spurious auto-reload).
|
||||
|
||||
const resolvePlugin = {
|
||||
name: "resolvePlugin",
|
||||
setup(build) {
|
||||
@@ -63,7 +93,7 @@ const options = {
|
||||
".ttf": "file",
|
||||
},
|
||||
sourcemap: true,
|
||||
target: ["es2020", "chrome61", "firefox60", "safari11", "edge18"],
|
||||
target: ["es2022", "chrome100", "firefox100", "safari15", "edge100"],
|
||||
}
|
||||
|
||||
const bsMiddleware = []
|
||||
@@ -83,6 +113,56 @@ if (process.argv[2] == "start") {
|
||||
})
|
||||
)
|
||||
|
||||
// Sentry tunnel proxy: forwards /_s requests to Sentry ingest to avoid ad-blockers
|
||||
const https = require("https")
|
||||
const http = require("http")
|
||||
bsMiddleware.push(function (req, res, next) {
|
||||
if (req.url !== "/_s" || req.method !== "POST") return next()
|
||||
let body = []
|
||||
req.on("data", (chunk) => body.push(chunk))
|
||||
req.on("end", () => {
|
||||
const payload = Buffer.concat(body).toString()
|
||||
const firstLine = payload.split("\n")[0]
|
||||
let envelope
|
||||
try {
|
||||
envelope = JSON.parse(firstLine)
|
||||
} catch {
|
||||
res.writeHead(400)
|
||||
res.end()
|
||||
return
|
||||
}
|
||||
const dsn = envelope.dsn || ""
|
||||
let sentryUrl
|
||||
try {
|
||||
sentryUrl = new URL(dsn)
|
||||
} catch {
|
||||
res.writeHead(400)
|
||||
res.end()
|
||||
return
|
||||
}
|
||||
const projectId = sentryUrl.pathname.replace(/\//g, "")
|
||||
const ingestUrl = `${sentryUrl.protocol}//${sentryUrl.host}/api/${projectId}/envelope/`
|
||||
const transport = ingestUrl.startsWith("https") ? https : http
|
||||
const proxyReq = transport.request(
|
||||
ingestUrl,
|
||||
{
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-sentry-envelope" },
|
||||
},
|
||||
(proxyRes) => {
|
||||
res.writeHead(proxyRes.statusCode || 200)
|
||||
proxyRes.pipe(res)
|
||||
}
|
||||
)
|
||||
proxyReq.on("error", () => {
|
||||
res.writeHead(502)
|
||||
res.end()
|
||||
})
|
||||
proxyReq.write(payload)
|
||||
proxyReq.end()
|
||||
})
|
||||
})
|
||||
|
||||
if (process.env.SSR) {
|
||||
bsMiddleware.push(
|
||||
createProxyMiddleware({
|
||||
@@ -103,6 +183,7 @@ if (process.argv[2] == "start") {
|
||||
module.exports = {
|
||||
sveltePlugin: sveltePlugin,
|
||||
resolvePlugin: resolvePlugin,
|
||||
writeBuildInfo: writeBuildInfo,
|
||||
options: options,
|
||||
distDir,
|
||||
watch: {
|
||||
@@ -121,6 +202,20 @@ module.exports = {
|
||||
...bsMiddleware,
|
||||
require("connect-history-api-fallback")({
|
||||
index: "/spa.html",
|
||||
// Allow dots in URL paths (e.g. /version-3.7.1) to fall through to SPA,
|
||||
// but only if they don't look like actual file requests.
|
||||
rewrites: [
|
||||
{
|
||||
from: /\.(js|css|mjs|map|woff2?|ttf|eot|svg|png|jpe?g|gif|webp|ico|json|pdf)(\?.*)?$/i,
|
||||
to: function (context) {
|
||||
return context.parsedUrl.pathname
|
||||
},
|
||||
},
|
||||
{
|
||||
from: /./,
|
||||
to: "/spa.html",
|
||||
},
|
||||
],
|
||||
// verbose: true,
|
||||
}),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user