130 lines
4 KiB
JavaScript
130 lines
4 KiB
JavaScript
#!/usr/bin/env node
|
|
import fs from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const __filename = fileURLToPath(import.meta.url)
|
|
const __dirname = path.dirname(__filename)
|
|
const repoRoot = path.resolve(__dirname, '..')
|
|
const sourcePath = path.join(
|
|
repoRoot,
|
|
'docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json',
|
|
)
|
|
const outputPath = path.join(
|
|
repoRoot,
|
|
'website/src/shared/generated/windows-package-validation-summary.json',
|
|
)
|
|
|
|
const FAMILY_LABELS = {
|
|
magic120cell: 'Magic120Cell dedicated-family training map',
|
|
magiccube5d: 'MagicCube5D dedicated-family training map',
|
|
}
|
|
|
|
function parseJson(content, label) {
|
|
try {
|
|
return JSON.parse(content)
|
|
} catch (error) {
|
|
throw new Error(`${label} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`)
|
|
}
|
|
}
|
|
|
|
function assertString(value, label) {
|
|
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
throw new Error(`${label} must be a non-empty string.`)
|
|
}
|
|
return value
|
|
}
|
|
|
|
function assertBoolean(value, label) {
|
|
if (typeof value !== 'boolean') {
|
|
throw new Error(`${label} must be a boolean.`)
|
|
}
|
|
return value
|
|
}
|
|
|
|
function normalizeSmokeResult(value, label) {
|
|
if (value === 'passed' || value === 'failed') {
|
|
return value
|
|
}
|
|
throw new Error(`${label} must be "passed" or "failed".`)
|
|
}
|
|
|
|
function buildFallbackLabel(mapUrl) {
|
|
const mapName = mapUrl.split('/').pop() || mapUrl
|
|
return `${mapName} packaged smoke map`
|
|
}
|
|
|
|
function buildSummary(report) {
|
|
const generatedAtUtc = assertString(report.generatedAtUtc, 'generatedAtUtc')
|
|
const configuration = assertString(report.configuration, 'configuration')
|
|
const skipBuild = assertBoolean(report.skipBuild, 'skipBuild')
|
|
const result = normalizeSmokeResult(report.result, 'result')
|
|
const validatedEntries = Array.isArray(report.authoringManifest?.validatedEntries)
|
|
? report.authoringManifest.validatedEntries
|
|
: []
|
|
const mapKindByUrl = new Map(
|
|
validatedEntries
|
|
.filter((entry) => typeof entry?.mapAssetPath === 'string' && typeof entry?.mapKind === 'string')
|
|
.map((entry) => [entry.mapAssetPath, entry.mapKind]),
|
|
)
|
|
const smokeReports = Array.isArray(report.smokeReports) ? report.smokeReports : []
|
|
|
|
const smokeMaps = smokeReports.map((smokeReport, index) => {
|
|
const mapUrl = assertString(smokeReport.mapUrl, `smokeReports[${index}].mapUrl`)
|
|
const mapKind = mapKindByUrl.get(mapUrl)
|
|
const label =
|
|
(mapKind && FAMILY_LABELS[mapKind]) ||
|
|
buildFallbackLabel(mapUrl)
|
|
|
|
return {
|
|
map_url: mapUrl,
|
|
label,
|
|
result: normalizeSmokeResult(smokeReport.result, `smokeReports[${index}].result`),
|
|
}
|
|
})
|
|
|
|
return {
|
|
lane: 'Windows Unreal packaged validation',
|
|
result,
|
|
generated_at: generatedAtUtc,
|
|
configuration,
|
|
skip_build: skipBuild,
|
|
smoke_map_count: smokeMaps.length,
|
|
smoke_maps: smokeMaps,
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
const checkOnly = process.argv.includes('--check')
|
|
const sourceContent = await fs.readFile(sourcePath, 'utf8')
|
|
const summary = buildSummary(parseJson(sourceContent, sourcePath))
|
|
const serialized = `${JSON.stringify(summary, null, 2)}\n`
|
|
|
|
if (checkOnly) {
|
|
let existing = null
|
|
try {
|
|
existing = await fs.readFile(outputPath, 'utf8')
|
|
} catch (error) {
|
|
if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {
|
|
console.error(`Generated summary missing: ${outputPath}`)
|
|
process.exit(1)
|
|
}
|
|
throw error
|
|
}
|
|
|
|
if (existing !== serialized) {
|
|
console.error('Generated web package-validation summary is stale.')
|
|
console.error(`Refresh with: node ${path.relative(repoRoot, __filename)}`)
|
|
process.exit(1)
|
|
}
|
|
|
|
console.log(`Validated packaged-validation summary freshness: ${path.relative(repoRoot, outputPath)}`)
|
|
return
|
|
}
|
|
|
|
await fs.mkdir(path.dirname(outputPath), { recursive: true })
|
|
await fs.writeFile(outputPath, serialized, 'utf8')
|
|
console.log(`Wrote ${path.relative(repoRoot, outputPath)}`)
|
|
}
|
|
|
|
await main()
|