| 1 | import { mkdir, readFile, writeFile } from "node:fs/promises"; |
| 2 | import { resolve } from "node:path"; |
| 3 | import { validateReleaseEvent } from "../../scripts/release-event.mjs"; |
| 4 | |
| 5 | const siteRoot = resolve(import.meta.dirname, ".."); |
| 6 | const repoRoot = resolve(siteRoot, ".."); |
| 7 | const catalog = JSON.parse(await readFile(resolve(repoRoot, "release-notes/releases.json"), "utf8")); |
| 8 | const output = resolve(siteRoot, ".generated/publications.json"); |
| 9 | const headers = { |
| 10 | Accept: "application/vnd.github+json", |
| 11 | "User-Agent": "reasonix-site-publications", |
| 12 | }; |
| 13 | if (process.env.GITHUB_TOKEN) headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`; |
| 14 | |
| 15 | const publications = []; |
| 16 | for (const release of catalog.releases) { |
| 17 | // Legacy entries predate publication markers and remain public. Every new |
| 18 | // reviewed entry fails closed until its exact CLI release carries the marker |
| 19 | // uploaded by the all-surface postflight. |
| 20 | if (!release.status || release.status === "published") { |
| 21 | publications.push(release.version); |
| 22 | continue; |
| 23 | } |
| 24 | const tag = `v${release.version}`; |
| 25 | try { |
| 26 | const response = await fetch( |
| 27 | `https://api.github.com/repos/esengine/DeepSeek-Reasonix/releases/tags/${encodeURIComponent(tag)}`, |
| 28 | { headers, signal: AbortSignal.timeout(20_000) }, |
| 29 | ); |
| 30 | if (!response.ok) continue; |
| 31 | const githubRelease = await response.json(); |
| 32 | const marker = githubRelease.assets?.find((asset) => asset.name === "release-event.json" && asset.size > 0); |
| 33 | if (!marker?.browser_download_url) continue; |
| 34 | const markerResponse = await fetch(marker.browser_download_url, { |
| 35 | headers, |
| 36 | signal: AbortSignal.timeout(20_000), |
| 37 | }); |
| 38 | if (!markerResponse.ok) continue; |
| 39 | const event = await markerResponse.json(); |
| 40 | validateReleaseEvent(event, release); |
| 41 | publications.push(release.version); |
| 42 | } catch { |
| 43 | // A reviewed release must never become public because an upstream lookup |
| 44 | // failed. The next Pages build retries after the release postflight. |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | await mkdir(resolve(siteRoot, ".generated"), { recursive: true }); |
| 49 | await writeFile(output, `${JSON.stringify({ schemaVersion: 1, publications }, null, 2)}\n`); |
| 50 | console.log(`Resolved ${publications.length} public release note(s).`); |
| 51 |