diff --git a/packages/bin-infra/lib/build-stubs.mts b/packages/bin-infra/lib/build-stubs.mts index 32af7171..16fb8af9 100644 --- a/packages/bin-infra/lib/build-stubs.mts +++ b/packages/bin-infra/lib/build-stubs.mts @@ -28,7 +28,7 @@ import { parsePlatformArch, tarSupportsNoAbsoluteNames, } from 'build-infra/lib/platform-mappings' -import { verifyReleaseChecksum } from 'build-infra/lib/release-checksums' +import { verifyReleaseChecksum } from 'build-infra/lib/release-checksums/core' import { ensureCurl } from 'curl-builder/lib/ensure-curl' import { WIN32 } from '@socketsecurity/lib/constants/platform' diff --git a/packages/build-infra/lib/release-checksums.mts b/packages/build-infra/lib/release-checksums.mts deleted file mode 100644 index 86ef23cd..00000000 --- a/packages/build-infra/lib/release-checksums.mts +++ /dev/null @@ -1,352 +0,0 @@ -/** - * Utility for fetching and verifying release checksums from GitHub releases. - * - * Checksum lookup priority: - * 1. In-memory cache (fastest, avoids re-parsing) - * 2. Embedded checksums from release-checksums.json (works offline) - * 3. Download checksums.txt from GitHub releases (fallback for updates) - * - * This hybrid approach provides: - * - Offline builds with embedded checksums - * - Automatic updates when connected to network - * - Consistent verification across all environments - */ - -import crypto from 'node:crypto' -import { - createReadStream, - existsSync, - readFileSync, - promises as fs, -} from 'node:fs' -import path from 'node:path' -import process from 'node:process' - -import { fileURLToPath } from 'node:url' - -import { safeMkdir } from '@socketsecurity/lib/fs' -import { getDefaultLogger } from '@socketsecurity/lib/logger' -import { getLatestRelease } from '@socketsecurity/lib/releases/github-api' -import { downloadReleaseAsset } from '@socketsecurity/lib/releases/github-downloads' -import { SOCKET_BTM_REPO } from '@socketsecurity/lib/releases/socket-btm' - -import { errorMessage } from './error-utils.mts' - -const logger = getDefaultLogger() - -const __filename = fileURLToPath(import.meta.url) -const __dirname = path.dirname(__filename) - -/** Cache for downloaded checksums by tool and release tag. */ -const checksumCache = new Map() - -/** Embedded checksums loaded from release-checksums.json (lazy-loaded). */ -let embeddedChecksums - -/** - * Load embedded checksums from release-checksums.json. - * Returns cached result on subsequent calls. - * - * @returns {Record}>} - */ -function getEmbeddedChecksums() { - if (embeddedChecksums === undefined) { - try { - const checksumPath = path.join(__dirname, '..', 'release-assets.json') - embeddedChecksums = JSON.parse(readFileSync(checksumPath, 'utf8')) - } catch { - // File not found or invalid JSON - disable embedded checksums. - embeddedChecksums = undefined - } - } - return embeddedChecksums -} - -/** - * Get embedded checksum for a specific tool and asset. - * - * @param {string} tool - Tool name (e.g., 'lief', 'curl'). - * @param {string} assetName - Asset filename. - * @returns {{checksum: string, tag: string} | undefined} Checksum and release tag if found. - */ -function getEmbeddedChecksum(tool, assetName) { - const embedded = getEmbeddedChecksums() - if (!embedded) { - return undefined - } - const toolConfig = embedded[tool] - if (!toolConfig?.checksums) { - return undefined - } - const checksum = toolConfig.checksums[assetName] - if (!checksum) { - return undefined - } - return { checksum, tag: toolConfig.tag } -} - -/** - * Compute SHA256 hash of a file. - * - * @param {string} filePath - Path to file. - * @returns {Promise} SHA256 hex digest. - */ -export async function computeFileHash(filePath) { - const hash = crypto.createHash('sha256') - const stream = createReadStream(filePath) - for await (const chunk of stream) { - hash.update(chunk) - } - return hash.digest('hex') -} - -/** - * Parse checksums.txt content into a map. - * Supports standard format: "hash filename" (two spaces or whitespace between). - * - * @param {string} content - Raw checksums.txt content. - * @returns {Record} Map of filename to SHA256 checksum. - */ -export function parseChecksums(content) { - const checksums = { __proto__: null } - for (const line of content.split('\n')) { - const trimmed = line.trim() - if (!trimmed) { - continue - } - // Format: hash filename (two spaces or whitespace between) - const match = trimmed.match(/^([a-f0-9]{64})\s+(.+)$/) - if (match) { - checksums[match[2]] = match[1] - } - } - return checksums -} - -/** - * Get checksums for a socket-btm release. - * - * Lookup priority: - * 1. In-memory cache (fastest) - * 2. Embedded checksums from release-checksums.json (works offline) - * 3. Download checksums.txt from GitHub releases (latest/updated checksums) - * - * @param {object} options - Options. - * @param {string} options.tool - Tool name prefix (e.g., 'lief', 'curl', 'stubs'). - * @param {string} [options.releaseTag] - Optional release tag. If not provided, uses embedded or latest. - * @param {string} [options.tempDir] - Directory to store downloaded checksums. Defaults to cwd/build/temp. - * @param {boolean} [options.quiet] - Suppress log messages. Defaults to false. - * @param {boolean} [options.preferEmbedded] - Prefer embedded checksums over network fetch. Defaults to true. - * @returns {Promise<{checksums: Record, tag: string, source: 'cache'|'embedded'|'network'}>} - */ -export async function getSocketBtmReleaseChecksums(options) { - const { - preferEmbedded = true, - quiet = false, - releaseTag, - tempDir, - tool, - } = options - const toolPrefix = `${tool}-` - - // 1. Check in-memory cache first. - const cacheKey = `${tool}:${releaseTag ?? 'latest'}` - const cached = checksumCache.get(cacheKey) - if (cached) { - return cached - } - - // 2. Check embedded checksums (works offline). - const embedded = getEmbeddedChecksums() - const toolEmbedded = embedded?.[tool] - if ( - toolEmbedded?.checksums && - Object.keys(toolEmbedded.checksums).length > 0 - ) { - // If no specific tag requested, or tag matches embedded, use embedded. - if (preferEmbedded && (!releaseTag || releaseTag === toolEmbedded.tag)) { - const result = { - checksums: toolEmbedded.checksums, - source: 'embedded', - tag: toolEmbedded.tag, - } - checksumCache.set(cacheKey, result) - checksumCache.set(`${tool}:${toolEmbedded.tag}`, result) - if (!quiet) { - logger.info( - `Using embedded checksums for ${tool} (${toolEmbedded.tag})`, - ) - } - return result - } - } - - // 3. Fall back to network fetch. - // Resolve release tag if not provided. - const tag = - releaseTag ?? - toolEmbedded?.tag ?? - (await getLatestRelease(toolPrefix, SOCKET_BTM_REPO, { quiet: true })) - if (!tag) { - if (!quiet) { - logger.warn(`No ${tool} release found, cannot fetch checksums`) - } - return { checksums: {}, source: 'network', tag: '' } - } - - // Check if we have cached result for this specific tag. - const tagCacheKey = `${tool}:${tag}` - const tagCached = checksumCache.get(tagCacheKey) - if (tagCached) { - // Also cache under 'latest' key if that's what was requested. - if (!releaseTag) { - checksumCache.set(cacheKey, tagCached) - } - return tagCached - } - - // Download checksums.txt to temp file. - const resolvedTempDir = tempDir ?? path.join(process.cwd(), 'build', 'temp') - await safeMkdir(resolvedTempDir) - const checksumPath = path.join( - resolvedTempDir, - `${tool}-checksums-${tag}.txt`, - ) - - // Check if already downloaded. - if (existsSync(checksumPath)) { - try { - const content = await fs.readFile(checksumPath, 'utf8') - const checksums = parseChecksums(content) - const result = { checksums, source: 'network', tag } - checksumCache.set(tagCacheKey, result) - if (!releaseTag) { - checksumCache.set(cacheKey, result) - } - return result - } catch { - // Fall through to download. - } - } - - try { - if (!quiet) { - logger.info(`Downloading checksums for ${tool} release ${tag}...`) - } - await downloadReleaseAsset( - tag, - 'checksums.txt', - checksumPath, - SOCKET_BTM_REPO, - { quiet: true }, - ) - - const content = await fs.readFile(checksumPath, 'utf8') - const checksums = parseChecksums(content) - - const result = { checksums, source: 'network', tag } - checksumCache.set(tagCacheKey, result) - if (!releaseTag) { - checksumCache.set(cacheKey, result) - } - - if (!quiet) { - logger.info( - `Loaded ${Object.keys(checksums).length} checksums for ${tool}`, - ) - } - return result - } catch (e) { - // If network fetch fails, try embedded as last resort. - if ( - toolEmbedded?.checksums && - Object.keys(toolEmbedded.checksums).length > 0 - ) { - if (!quiet) { - logger.warn( - `Network fetch failed, using embedded checksums for ${tool}: ${errorMessage(e)}`, - ) - } - const result = { - checksums: toolEmbedded.checksums, - source: 'embedded', - tag: toolEmbedded.tag, - } - checksumCache.set(cacheKey, result) - return result - } - - if (!quiet) { - logger.warn( - `Failed to download checksums.txt for ${tool}: ${errorMessage(e)}`, - ) - } - return { checksums: {}, source: 'network', tag } - } -} - -/** - * Verify a downloaded file against embedded release checksums. - * - * Embedded checksums in release-assets.json are the source of truth. - * If checksums exist for the tool but not the asset, verification fails - * (run 'pnpm --filter build-infra update-checksums' to update). - * - * @param {object} options - Options. - * @param {string} options.filePath - Path to the downloaded file. - * @param {string} options.assetName - Asset name to look up in checksums. - * @param {string} options.tool - Tool name prefix for fetching checksums. - * @param {boolean} [options.quiet] - Suppress log messages. - * @returns {Promise<{valid: boolean, expected?: string, actual?: string, skipped?: boolean, source?: string}>} - */ -export async function verifyReleaseChecksum(options) { - const { assetName, filePath, quiet = false, tool } = options - - // Embedded checksums are the source of truth. - const embedded = getEmbeddedChecksum(tool, assetName) - if (embedded) { - const actual = await computeFileHash(filePath) - if (actual !== embedded.checksum) { - return { - actual, - expected: embedded.checksum, - source: 'embedded', - valid: false, - } - } - return { - actual, - expected: embedded.checksum, - source: 'embedded', - valid: true, - } - } - - // Embedded checksums exist for this tool but not this asset — reject. - const embeddedData = getEmbeddedChecksums() - if ( - embeddedData?.[tool]?.checksums && - Object.keys(embeddedData[tool].checksums).length > 0 - ) { - if (!quiet) { - logger.fail( - `No embedded checksum for ${assetName} in release-assets.json (tool: ${tool})`, - ) - logger.fail(`Run 'pnpm --filter build-infra update-checksums' to update`) - } - return { source: 'embedded', valid: false } - } - - // No embedded checksums at all for this tool — skip verification. - if (!quiet) { - logger.warn(`No checksums found for ${tool}, skipping verification`) - } - return { skipped: true, valid: true } -} - -/** - * Clear the checksum cache. Useful for testing or forcing re-download. - */ -export function clearChecksumCache() { - checksumCache.clear() -} diff --git a/packages/build-infra/lib/release-checksums/core.mts b/packages/build-infra/lib/release-checksums/core.mts new file mode 100644 index 00000000..e67648d3 --- /dev/null +++ b/packages/build-infra/lib/release-checksums/core.mts @@ -0,0 +1,206 @@ +/** + * Release-checksum core: format primitives + embedded-checksum loader + verify. + * + * This file is the **shared core** used by every fleet repo that publishes + * artifacts whose integrity is gated by SHA-256 checksums. It contains no + * network code and no producer code — see `consumer.mts` for the network + * fetch path, and `producer.mts` for the writer side. + * + * Fleet-canonical: byte-identical across every repo that ships + * `packages/build-infra/lib/release-checksums/`. Drift caught by + * sync-scaffolding. + */ + +import crypto from 'node:crypto' +import { createReadStream, readFileSync } from 'node:fs' +import path from 'node:path' + +import { fileURLToPath } from 'node:url' + +import { getDefaultLogger } from '@socketsecurity/lib/logger' + +const logger = getDefaultLogger() + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +// --------------------------------------------------------------------------- +// Public types — match the JSON Schema at packages/build-infra/release-assets.schema.json. +// --------------------------------------------------------------------------- + +export interface ToolConfig { + description?: string + tag: string + checksums: Record +} + +export type EmbeddedChecksums = Record + +export interface VerifyResult { + actual?: string + expected?: string + source?: string + skipped?: boolean + valid: boolean +} + +// --------------------------------------------------------------------------- +// Embedded loader. +// +// Reads `packages/build-infra/release-assets.json` from the repo root. +// Lazy + cached: file is read at most once per process. The `null` sentinel +// distinguishes "tried and failed" from "not yet tried" so we don't retry +// on every call. +// --------------------------------------------------------------------------- + +let embeddedChecksums: EmbeddedChecksums | undefined | null + +export function getEmbeddedChecksums(): EmbeddedChecksums | undefined { + if (embeddedChecksums === null) { + return undefined + } + if (embeddedChecksums === undefined) { + try { + const checksumPath = path.join( + __dirname, + '..', + '..', + 'release-assets.json', + ) + embeddedChecksums = JSON.parse( + readFileSync(checksumPath, 'utf8'), + ) as EmbeddedChecksums + } catch { + embeddedChecksums = null + return undefined + } + } + return embeddedChecksums +} + +export function getEmbeddedChecksum( + tool: string, + assetName: string, +): { checksum: string; tag: string } | undefined { + const embedded = getEmbeddedChecksums() + if (!embedded) { + return undefined + } + const toolConfig = embedded[tool] + if (!toolConfig?.checksums) { + return undefined + } + const checksum = toolConfig.checksums[assetName] + if (!checksum) { + return undefined + } + return { checksum, tag: toolConfig.tag } +} + +// --------------------------------------------------------------------------- +// Format primitives. +// --------------------------------------------------------------------------- + +/** + * Compute SHA256 hash of a file as lowercase hex. + */ +export async function computeFileHash(filePath: string): Promise { + const hash = crypto.createHash('sha256') + const stream = createReadStream(filePath) + for await (const chunk of stream) { + hash.update(chunk) + } + return hash.digest('hex') +} + +/** + * Parse `checksums.txt` content into a map. + * + * Format: one entry per line, ` ` (two spaces or any + * whitespace between hash and name). Blank lines are skipped. Lines that + * don't match the expected shape are silently ignored — defensive against + * tools that prepend a header or comments. + */ +export function parseChecksums(content: string): Record { + const checksums: Record = { __proto__: null as never } + for (const line of content.split('\n')) { + const trimmed = line.trim() + if (!trimmed) { + continue + } + const match = trimmed.match(/^([a-f0-9]{64})\s+(.+)$/) + if (match) { + checksums[match[2]!] = match[1]! + } + } + return checksums +} + +// --------------------------------------------------------------------------- +// Verify. +// --------------------------------------------------------------------------- + +interface VerifyOptions { + filePath: string + assetName: string + tool: string + quiet?: boolean +} + +/** + * Verify a downloaded file against the embedded SHA-256 in `release-assets.json`. + * + * Embedded checksums are the source of truth. Three outcomes: + * + * 1. Embedded match found and SHA-256 agrees → `{ valid: true }`. + * 2. Embedded match found but SHA-256 disagrees → `{ valid: false }` with + * `actual` + `expected` populated. **Fail loudly.** + * 3. Tool is in `release-assets.json` but `assetName` isn't listed → return + * `{ valid: false }`. The likely cause is a stale embedded manifest; + * bump `tag` + `checksums` in `release-assets.json` and re-run. + * 4. Tool isn't in `release-assets.json` at all → return + * `{ valid: true, skipped: true }` with a warning. This is the + * "release-assets.json doesn't track this tool yet" path; callers that + * need strict verification should treat `skipped` as a failure. + */ +export async function verifyReleaseChecksum( + options: VerifyOptions, +): Promise { + const { assetName, filePath, quiet = false, tool } = options + + const embedded = getEmbeddedChecksum(tool, assetName) + if (embedded) { + const actual = await computeFileHash(filePath) + if (actual !== embedded.checksum) { + return { + actual, + expected: embedded.checksum, + source: 'embedded', + valid: false, + } + } + return { + actual, + expected: embedded.checksum, + source: 'embedded', + valid: true, + } + } + + const embeddedData = getEmbeddedChecksums() + const toolBlock = embeddedData?.[tool] + if (toolBlock?.checksums && Object.keys(toolBlock.checksums).length > 0) { + if (!quiet) { + logger.fail( + `No embedded checksum for ${assetName} in release-assets.json (tool: ${tool})`, + ) + logger.fail(`Bump the tag + checksums in release-assets.json to update`) + } + return { source: 'embedded', valid: false } + } + + if (!quiet) { + logger.warn(`No checksums found for ${tool}, skipping verification`) + } + return { skipped: true, valid: true } +} diff --git a/packages/build-infra/lib/release-checksums/producer.mts b/packages/build-infra/lib/release-checksums/producer.mts new file mode 100644 index 00000000..4e9f159a --- /dev/null +++ b/packages/build-infra/lib/release-checksums/producer.mts @@ -0,0 +1,139 @@ +/** + * Release-checksum producer: write `checksums.txt` for a directory of + * artifacts; update a `release-assets.json` block. + * + * Use this when your repo *produces* releases (e.g. socket-btm builds + * `.node` binaries and ships them to GH Releases). The output of + * `writeChecksumsFile()` is what consumers download and verify against + * via `consumer.mts`. + * + * Repos that only consume releases don't need this file — see `consumer.mts`. + * + * Fleet-canonical: byte-identical across every repo that ships + * `packages/build-infra/lib/release-checksums/`. + */ + +import { promises as fs, readFileSync, writeFileSync } from 'node:fs' +import path from 'node:path' + +import { getDefaultLogger } from '@socketsecurity/lib/logger' + +import { computeFileHash, type EmbeddedChecksums } from './core.mts' + +const logger = getDefaultLogger() + +/** + * Walk a directory and compute SHA-256 hashes for every regular file in it. + * + * Sub-paths are relative to `dir`. Symlinks and directories are not + * recursed — pass a flat directory of artifacts. + */ +export async function hashDirectory( + dir: string, +): Promise> { + const entries = await fs.readdir(dir, { withFileTypes: true }) + const out: Record = { __proto__: null as never } + for (const entry of entries) { + if (!entry.isFile()) { + continue + } + const filePath = path.join(dir, entry.name) + out[entry.name] = await computeFileHash(filePath) + } + return out +} + +interface WriteChecksumsOptions { + /** Directory containing the artifacts to hash. */ + inputDir: string + /** Path of the `checksums.txt` to write. */ + outputPath: string + /** Optional ordering. If omitted, entries are sorted alphabetically. */ + order?: 'alphabetical' | readonly string[] + /** Suppress info logging (errors still log). */ + quiet?: boolean +} + +/** + * Write a `checksums.txt` file from a directory of artifacts. + * + * Output format: ` \n`, matching the format + * `consumer.mts:parseChecksums` expects. Filenames are sorted + * alphabetically by default for stable diffs. + */ +export async function writeChecksumsFile( + options: WriteChecksumsOptions, +): Promise> { + const { + inputDir, + order = 'alphabetical', + outputPath, + quiet = false, + } = options + + const checksums = await hashDirectory(inputDir) + const names = + order === 'alphabetical' ? Object.keys(checksums).sort() : [...order] + + const lines: string[] = [] + for (const name of names) { + const hash = checksums[name] + if (!hash) { + if (!quiet) { + logger.warn(`No file matched ordering entry: ${name}`) + } + continue + } + lines.push(`${hash} ${name}`) + } + // POSIX-style trailing newline. + await fs.writeFile(outputPath, lines.join('\n') + '\n', 'utf8') + if (!quiet) { + logger.info(`Wrote ${lines.length} checksums to ${outputPath}`) + } + return checksums +} + +interface UpdateAssetsOptions { + /** Path to `release-assets.json`. */ + manifestPath: string + /** Tool key inside the manifest (e.g. `iocraft`, `lief`). */ + tool: string + /** Release tag, e.g. `iocraft-20260424-18f0f46`. */ + tag: string + /** Asset → SHA-256 map (typically the return value of `writeChecksumsFile`). */ + checksums: Record + /** Optional human-readable description for the tool block. */ + description?: string +} + +/** + * Update a tool's block in `release-assets.json` in place. + * + * Reads the existing manifest, replaces the block for `tool` with the + * new `tag` + `checksums`, and writes the result back. Other tool blocks + * are preserved untouched. + * + * The manifest's $schema field (if present) is preserved. + */ +export function updateReleaseAssets(options: UpdateAssetsOptions): void { + const { checksums, description, manifestPath, tag, tool } = options + + let manifest: EmbeddedChecksums & { + $schema?: string + $comment?: string + } = { __proto__: null as never } as never + try { + manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) + } catch { + // New file — start fresh. + } + + manifest[tool] = { + ...(description !== undefined ? { description } : {}), + tag, + checksums, + } + + writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n', 'utf8') +} diff --git a/packages/build-infra/package.json b/packages/build-infra/package.json index cfe225ba..589ae743 100644 --- a/packages/build-infra/package.json +++ b/packages/build-infra/package.json @@ -30,7 +30,8 @@ "./lib/platform-mappings": "./lib/platform-mappings.mts", "./lib/pinned-versions": "./lib/pinned-versions.mts", "./lib/preflight-checks": "./lib/preflight-checks.mts", - "./lib/release-checksums": "./lib/release-checksums.mts", + "./lib/release-checksums/core": "./lib/release-checksums/core.mts", + "./lib/release-checksums/producer": "./lib/release-checksums/producer.mts", "./lib/python-installer": "./lib/python-installer.mts", "./lib/script-runner": "./lib/script-runner.mts", "./lib/setup-build-toolchain": "./lib/setup-build-toolchain.mts", diff --git a/packages/build-infra/release-assets.json b/packages/build-infra/release-assets.json index 5f7bad01..1574dbf3 100644 --- a/packages/build-infra/release-assets.json +++ b/packages/build-infra/release-assets.json @@ -1,5 +1,5 @@ { - "$schema": "Release checksums for Socket BTM build dependencies", + "$schema": "./release-assets.schema.json", "$comment": "SHA-256 checksums for GitHub release assets. Run 'pnpm --filter build-infra update-checksums' to update.", "binflate": { "description": "Binary decompression tool", diff --git a/packages/build-infra/release-assets.schema.json b/packages/build-infra/release-assets.schema.json new file mode 100644 index 00000000..d9e8349f --- /dev/null +++ b/packages/build-infra/release-assets.schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/SocketDev/socket-repo-template/main/template/packages/build-infra/release-assets.schema.json", + "title": "Release Assets Manifest", + "description": "Embedded SHA-256 manifest for release artifacts. One block per tool: identifies the upstream release tag and the SHA-256 of every asset that release published. Consumers verify downloads against these hashes before installing or republishing. Producers (e.g. socket-btm) update this file when cutting a new release.", + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/toolConfig" + }, + "properties": { + "$schema": { + "type": "string", + "description": "Pointer back to this schema for editor hints." + }, + "$comment": { + "type": "string", + "description": "Free-form note. Conventionally explains how to bump entries." + } + }, + "$defs": { + "toolConfig": { + "type": "object", + "additionalProperties": false, + "required": ["tag", "checksums"], + "properties": { + "description": { + "type": "string", + "description": "Human-readable label for this tool." + }, + "tag": { + "type": "string", + "description": "Full release tag, including the tool prefix (e.g. `iocraft-20260424-18f0f46`).", + "minLength": 1 + }, + "checksums": { + "type": "object", + "description": "Asset filename → SHA-256 hex digest. Keys are typically flat filenames; some manifests use relative paths (e.g. `./model/model.onnx`) when the producer ships nested artifacts.", + "additionalProperties": { + "type": "string", + "pattern": "^[a-f0-9]{64}$" + }, + "minProperties": 1 + } + } + } + } +} diff --git a/packages/build-infra/scripts/update-checksums.mts b/packages/build-infra/scripts/update-checksums.mts index 9893af87..ed84f8a6 100644 --- a/packages/build-infra/scripts/update-checksums.mts +++ b/packages/build-infra/scripts/update-checksums.mts @@ -27,7 +27,7 @@ import { downloadReleaseAsset } from '@socketsecurity/lib/releases/github-downlo import { SOCKET_BTM_REPO } from '@socketsecurity/lib/releases/socket-btm' import { errorMessage } from '../lib/error-utils.mts' -import { parseChecksums } from '../lib/release-checksums.mts' +import { parseChecksums } from '../lib/release-checksums/core.mts' const logger = getDefaultLogger() @@ -205,7 +205,7 @@ async function main() { // Symbol ones — so the canonical text was effectively dead code. const { $schema: _s, $comment: _c, ...rest } = currentData const output = { - $schema: 'Release checksums for Socket BTM build dependencies', + $schema: './release-assets.schema.json', $comment: "SHA-256 checksums for GitHub release assets. Run 'pnpm --filter build-infra update-checksums' to update.", ...rest, diff --git a/packages/curl-builder/scripts/build.mts b/packages/curl-builder/scripts/build.mts index 8d3d1fc1..12e0b18c 100755 --- a/packages/curl-builder/scripts/build.mts +++ b/packages/curl-builder/scripts/build.mts @@ -30,7 +30,7 @@ import { getCurrentPlatformArch, isMusl, } from 'build-infra/lib/platform-mappings' -import { verifyReleaseChecksum } from 'build-infra/lib/release-checksums' +import { verifyReleaseChecksum } from 'build-infra/lib/release-checksums/core' import { extractTarball } from 'build-infra/lib/tarball-utils' import { getSubmoduleVersion } from 'build-infra/lib/version-helpers' import { errorMessage } from 'build-infra/lib/error-utils' diff --git a/packages/libpq-builder/scripts/build.mts b/packages/libpq-builder/scripts/build.mts index 1085cfd7..8d84434c 100644 --- a/packages/libpq-builder/scripts/build.mts +++ b/packages/libpq-builder/scripts/build.mts @@ -33,7 +33,7 @@ import { getCurrentPlatformArch, isMusl, } from 'build-infra/lib/platform-mappings' -import { verifyReleaseChecksum } from 'build-infra/lib/release-checksums' +import { verifyReleaseChecksum } from 'build-infra/lib/release-checksums/core' import { extractTarball } from 'build-infra/lib/tarball-utils' import { getSubmoduleVersion } from 'build-infra/lib/version-helpers' import { errorMessage } from 'build-infra/lib/error-utils' diff --git a/packages/lief-builder/scripts/build.mts b/packages/lief-builder/scripts/build.mts index 6210ee3f..ed32a3f7 100755 --- a/packages/lief-builder/scripts/build.mts +++ b/packages/lief-builder/scripts/build.mts @@ -22,7 +22,7 @@ import { logTransientErrorHelp } from 'build-infra/lib/github-error-utils' import { appendCCRemapFlags } from 'build-infra/lib/path-remap-flags' import { getDownloadedDir } from 'build-infra/lib/paths' import { getAssetPlatformArch, isMusl } from 'build-infra/lib/platform-mappings' -import { verifyReleaseChecksum } from 'build-infra/lib/release-checksums' +import { verifyReleaseChecksum } from 'build-infra/lib/release-checksums/core' import { extractTarball } from 'build-infra/lib/tarball-utils' import { getSubmoduleVersion } from 'build-infra/lib/version-helpers' import { errorMessage } from 'build-infra/lib/error-utils'