feat: expose verifiable deployment release
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import crypto from 'node:crypto';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
const DEFAULT_ASSET_ROOTS = [
|
||||
'/usr/share/nginx/html',
|
||||
path.resolve(process.cwd(), 'dist'),
|
||||
];
|
||||
|
||||
function cleanRelease(value) {
|
||||
const release = String(value || '').trim();
|
||||
if (!release || release === 'unknown' || release.length > 128) return null;
|
||||
return release;
|
||||
}
|
||||
|
||||
export function deployedRelease(env = process.env) {
|
||||
return cleanRelease(env.APP_RELEASE) || cleanRelease(env.SOURCE_COMMIT);
|
||||
}
|
||||
|
||||
export function frontendAssetInfo(roots = DEFAULT_ASSET_ROOTS) {
|
||||
for (const root of roots) {
|
||||
try {
|
||||
const indexPath = path.join(root, 'index.html');
|
||||
const html = fs.readFileSync(indexPath, 'utf8');
|
||||
const match = html.match(/<script[^>]+src=["']([^"']*\/assets\/[^"']+\.js(?:\?[^"']*)?)["']/i);
|
||||
if (!match) continue;
|
||||
const publicPath = new URL(match[1], 'https://ihaleist.invalid/').pathname;
|
||||
const assetPath = path.resolve(root, `.${publicPath}`);
|
||||
const rootPath = path.resolve(root) + path.sep;
|
||||
if (!assetPath.startsWith(rootPath)) continue;
|
||||
const bytes = fs.readFileSync(assetPath);
|
||||
return {
|
||||
path: publicPath,
|
||||
sha256: crypto.createHash('sha256').update(bytes).digest('hex'),
|
||||
bytes: bytes.length,
|
||||
};
|
||||
} catch {
|
||||
// Bu kökte derlenmiş arayüz yoksa sıradaki olası köke bakılır.
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function releaseInfo({ env = process.env, roots = DEFAULT_ASSET_ROOTS } = {}) {
|
||||
return {
|
||||
release: deployedRelease(env),
|
||||
version: '1.0.0',
|
||||
frontendAsset: frontendAssetInfo(roots),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user