@stll/oxlint-config 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/consumer-node-support.cjs +2 -2
- package/dist/consumer-node-support.mjs +1 -1
- package/dist/dependabot.d.cts +8 -0
- package/dist/dependabot.d.mts +8 -0
- package/dist/git-tracked-output.cjs +1 -1
- package/dist/git-tracked-output.mjs +1 -1
- package/dist/publish-contract-cli.cjs +1 -1
- package/dist/publish-contract-cli.mjs +1 -1
- package/dist/quarantine-cli.cjs +1 -1
- package/dist/quarantine-cli.mjs +1 -1
- package/dist/quarantine-policy2.cjs +2 -2
- package/dist/quarantine-policy2.mjs +2 -2
- package/dist/rust-policy-cli.cjs +481 -0
- package/dist/rust-policy-cli.cjs.map +1 -0
- package/dist/rust-policy-cli.d.cts +1 -0
- package/dist/rust-policy-cli.d.mts +1 -0
- package/dist/rust-policy-cli.mjs +479 -0
- package/dist/rust-policy-cli.mjs.map +1 -0
- package/dist/toolchain-changed-cli.cjs +1 -1
- package/dist/toolchain-changed-cli.mjs +1 -1
- package/dist/toolchain-dependabot.cjs +1 -1
- package/dist/toolchain-dependabot.mjs +2 -2
- package/dist/toolchain-dependabot.mjs.map +1 -1
- package/dist/toolchain-guard.cjs +5 -5
- package/dist/toolchain-guard.mjs +4 -4
- package/dist/toolchain-inputs.cjs +96 -17
- package/dist/toolchain-inputs.cjs.map +1 -1
- package/dist/toolchain-inputs.mjs +90 -17
- package/dist/toolchain-inputs.mjs.map +1 -1
- package/dist/toolchain-schema.cjs +6 -2
- package/dist/toolchain-schema.cjs.map +1 -1
- package/dist/toolchain-schema.mjs +6 -2
- package/dist/toolchain-schema.mjs.map +1 -1
- package/package.json +2 -1
- package/toolchain.json +12 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { c as isPythonDependencyManifest, d as pythonDependencyManifestKind, g as workspaceContains, h as isKubernetesDefinitionPath, i as isDockerDefinitionPath, m as isComposeDefinitionPath, p as containerDocumentImages, r as isDependabotGithubActionsPath, t as dependabotManifestEcosystem, u as javascriptDependencyLockfiles } from "./toolchain-inputs.mjs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { parse } from "smol-toml";
|
|
4
|
-
import { LineCounter, Scalar, isNode, parseAllDocuments, parseDocument, stringify } from "yaml";
|
|
5
4
|
import picomatch from "picomatch";
|
|
5
|
+
import { LineCounter, Scalar, isNode, parseAllDocuments, parseDocument, stringify as stringify$1 } from "yaml";
|
|
6
6
|
//#region src/toolchain-images.ts
|
|
7
7
|
/** Docker Hub spellings accepted by the shared runtime policy. */
|
|
8
8
|
const dockerHubRegistries = [
|
|
@@ -428,7 +428,7 @@ const generateDependabotConfig = ({ files, policy, updates: declarations, ignore
|
|
|
428
428
|
ignore: ignore.length > 0 ? ignore : void 0
|
|
429
429
|
};
|
|
430
430
|
});
|
|
431
|
-
return stringify({
|
|
431
|
+
return stringify$1({
|
|
432
432
|
version: 2,
|
|
433
433
|
updates
|
|
434
434
|
}, { aliasDuplicateObjects: false });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolchain-dependabot.mjs","names":["unexpected","parseToml"],"sources":["../src/toolchain-images.ts","../src/toolchain-dependabot.ts"],"sourcesContent":["/** Docker Hub spellings accepted by the shared runtime policy. */\nexport const dockerHubRegistries = [\n \"docker.io\",\n \"index.docker.io\",\n \"registry-1.docker.io\",\n] as const;\n\n/** Expand the full accepted repository alias class without parsing Dockerfile instructions. */\nexport const ownedDockerImageAliases = (images: readonly string[]) => {\n const aliases = new Set<string>();\n for (const image of images) {\n for (const repository of [image, `library/${image}`]) {\n aliases.add(repository);\n for (const registry of dockerHubRegistries)\n aliases.add(`${registry}/${repository}`);\n }\n }\n return [...aliases].sort();\n};\n\n/** Preserve tag/digest spelling while normalizing registry and namespace aliases. */\nexport const canonicalDockerRuntime = (image: string) => {\n const registry = dockerHubRegistries.find((entry) =>\n image.toLowerCase().startsWith(`${entry}/`),\n );\n const repository =\n registry === undefined ? image : image.slice(registry.length + 1);\n return repository.replace(/^library\\//i, \"\");\n};\n\n/** Preserve Rust release identity across official Debian slim and Alpine variants. */\nexport const rustImageVersion = (tag: string) =>\n tag.replace(\n /-(?:alpine(?:\\d+(?:\\.\\d+)*)?|(?:bookworm|bullseye|trixie|buster)(?:-slim)?|slim(?:-(?:bookworm|bullseye|trixie|buster))?)$/,\n \"\",\n );\n","import path from \"node:path\";\nimport picomatch from \"picomatch\";\nimport { parse as parseToml } from \"smol-toml\";\nimport {\n isNode,\n LineCounter,\n parseAllDocuments,\n parseDocument,\n Scalar,\n stringify,\n} from \"yaml\";\n\nimport {\n containerDocumentImages,\n isComposeDefinitionPath,\n isKubernetesDefinitionPath,\n} from \"./toolchain-container-inputs\";\nimport { ownedDockerImageAliases } from \"./toolchain-images\";\nimport {\n dependabotManifestEcosystem,\n isDependabotGithubActionsPath,\n isDockerDefinitionPath,\n isPythonDependencyManifest,\n javascriptDependencyLockfiles,\n pythonDependencyManifestKind,\n} from \"./toolchain-inputs\";\nimport { workspaceContains } from \"./toolchain-workspaces\";\n\nexport const dependabotRules = [\"dependabot-policy\"] as const;\n\n// https://docs.github.com/en/code-security/reference/supply-chain-security/dependabot-options-reference#package-ecosystem\nexport const supportedDependabotEcosystems = [\n \"bazel\",\n \"bun\",\n \"bundler\",\n \"cargo\",\n \"composer\",\n \"conda\",\n \"deno\",\n \"devcontainers\",\n \"docker\",\n \"docker-compose\",\n \"dotnet-sdk\",\n \"elm\",\n \"gitsubmodule\",\n \"github-actions\",\n \"gomod\",\n \"gradle\",\n \"helm\",\n \"julia\",\n \"maven\",\n \"mix\",\n \"nix\",\n \"npm\",\n \"nuget\",\n \"opentofu\",\n \"pip\",\n \"pre-commit\",\n \"pub\",\n \"rust-toolchain\",\n \"sbt\",\n \"swift\",\n \"terraform\",\n \"uv\",\n \"vcpkg\",\n] as const;\nexport type DependabotEcosystem =\n (typeof supportedDependabotEcosystems)[number];\nconst isDependabotEcosystem = (value: string): value is DependabotEcosystem =>\n supportedDependabotEcosystems.some((ecosystem) => ecosystem === value);\n\ntype DependabotPolicy = {\n schedule: { interval: string; day: string; time: string; timezone: string };\n cooldown: { defaultDays: number };\n actionGroups: Record<string, { patterns: readonly string[] }>;\n groups: Record<\n string,\n { patterns: readonly string[]; updateTypes: readonly string[] }\n >;\n ignoredPackages: readonly string[];\n ignoredActions: readonly string[];\n ignoredImages: readonly string[];\n};\n\ntype DependabotGroup = {\n patterns: readonly string[];\n updateTypes?: readonly string[] | undefined;\n};\n\n/** Ordered groups for one ecosystem: GitHub Actions first gathers first-party refs. */\nconst groupsFor = (\n ecosystem: string,\n policy: DependabotPolicy,\n): [string, DependabotGroup][] => [\n ...(ecosystem === \"github-actions\"\n ? Object.entries(policy.actionGroups)\n : []),\n ...Object.entries(policy.groups),\n];\n\ntype Diagnostic = {\n rule: (typeof dependabotRules)[number];\n path: string;\n line: number;\n message: string;\n};\n\nconst record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst strings = (value: unknown): value is string[] =>\n Array.isArray(value) &&\n value.every((entry: unknown) => typeof entry === \"string\");\n\nconst sameStrings = (value: unknown, expected: readonly string[]) => {\n if (!strings(value) || value.length !== expected.length) return false;\n const sortedExpected = [...expected].sort();\n return [...value]\n .sort()\n .every((entry, index) => entry === sortedExpected[index]);\n};\n\n// Version-update types only: security updates stay enabled for every ignore.\nexport const dependabotIgnoreUpdateTypes = [\n \"version-update:semver-major\",\n \"version-update:semver-minor\",\n \"version-update:semver-patch\",\n] as const;\nexport type DependabotIgnoreUpdateType =\n (typeof dependabotIgnoreUpdateTypes)[number];\nconst isIgnoreUpdateType = (\n value: unknown,\n): value is DependabotIgnoreUpdateType =>\n dependabotIgnoreUpdateTypes.some((updateType) => updateType === value);\n\nconst versionIgnore = (entry: unknown, updateTypes: readonly string[]) =>\n record(entry) &&\n Object.keys(entry).length === 2 &&\n typeof entry[\"dependency-name\"] === \"string\" &&\n sameStrings(entry[\"update-types\"], updateTypes);\n\nconst versionOnlyIgnore = (entry: unknown) =>\n versionIgnore(entry, dependabotIgnoreUpdateTypes);\n\n/** A reviewed repository decision to skip some version updates of one dependency. */\nexport type DependabotIgnoreDeclaration = {\n readonly ecosystem: DependabotEcosystem;\n /** Dependabot `dependency-name`; `*` is the only wildcard. */\n readonly dependency: string;\n /** Nonempty, unique and in canonical major, minor, patch order. */\n readonly updateTypes: readonly [\n DependabotIgnoreUpdateType,\n ...DependabotIgnoreUpdateType[],\n ];\n readonly reason: string;\n};\n\nconst ignoreDeclarationKeys = [\n \"ecosystem\",\n \"dependency\",\n \"updateTypes\",\n \"reason\",\n] as const;\n\n/** Parse `dependabotIgnores` from stll-toolchain.json; malformed decisions fail closed. */\nexport const parseDependabotIgnores = (\n input: unknown,\n): DependabotIgnoreDeclaration[] => {\n if (input === undefined) return [];\n if (!Array.isArray(input))\n throw new Error(\"dependabotIgnores must be an array\");\n const result: DependabotIgnoreDeclaration[] = [];\n const keys = new Set<string>();\n for (const entry of input) {\n if (\n !record(entry) ||\n Object.keys(entry).some(\n (key) => !ignoreDeclarationKeys.some((known) => known === key),\n ) ||\n typeof entry[\"reason\"] !== \"string\" ||\n entry[\"reason\"].trim() === \"\"\n )\n throw new Error(\n \"each Dependabot ignore requires ecosystem, dependency, updateTypes and a nonempty reason only\",\n );\n const ecosystem = entry[\"ecosystem\"];\n if (typeof ecosystem !== \"string\" || !isDependabotEcosystem(ecosystem))\n throw new Error(\n `unsupported Dependabot ignore ecosystem: ${String(ecosystem)}`,\n );\n const dependency = entry[\"dependency\"];\n if (\n typeof dependency !== \"string\" ||\n !/^[^\\s?[\\]{}!]+$/.test(dependency) ||\n /^\\*+$/.test(dependency)\n )\n throw new Error(\n `Dependabot ignore dependency must name a dependency; * is the only wildcard: ${String(dependency)}`,\n );\n const updateTypes = entry[\"updateTypes\"];\n if (\n !Array.isArray(updateTypes) ||\n !updateTypes.every(isIgnoreUpdateType) ||\n new Set(updateTypes).size !== updateTypes.length\n )\n throw new Error(\n `Dependabot ignore ${dependency} requires unique update types from ${dependabotIgnoreUpdateTypes.join(\", \")}`,\n );\n const [first, ...rest] = dependabotIgnoreUpdateTypes.filter((updateType) =>\n updateTypes.includes(updateType),\n );\n if (first === undefined)\n throw new Error(\n `Dependabot ignore ${dependency} requires at least one update type`,\n );\n const key = JSON.stringify([ecosystem, dependency]);\n if (keys.has(key))\n throw new Error(\n `duplicate Dependabot ignore: ${ecosystem} ${dependency}`,\n );\n keys.add(key);\n result.push({\n ecosystem,\n dependency,\n updateTypes: [first, ...rest],\n reason: entry[\"reason\"],\n });\n }\n return result;\n};\n\n/**\n * Read only `dependabotIgnores` from stll-toolchain.json text: stll-dependabot must not\n * fail on unrelated declarations, which stll-toolchain-check validates.\n */\nexport const readDependabotIgnores = (toolchain: string | undefined) => {\n if (toolchain === undefined) return [];\n const parsed: unknown = JSON.parse(toolchain);\n if (!record(parsed)) throw new Error(\"stll-toolchain.json must be an object\");\n return parseDependabotIgnores(parsed[\"dependabotIgnores\"]);\n};\n\nconst dependencyPattern = (dependency: string) =>\n new RegExp(\n `^${dependency\n .split(\"*\")\n .map((part) => part.replace(/[.+^${}()|[\\]\\\\/?]/g, \"\\\\$&\"))\n .join(\".*\")}$`,\n );\n\n/** Code-unit order keeps generated bytes independent of the host locale. */\nconst byDependency = (\n left: DependabotIgnoreDeclaration,\n right: DependabotIgnoreDeclaration,\n) => {\n if (left.dependency === right.dependency) return 0;\n return left.dependency < right.dependency ? -1 : 1;\n};\n\nconst directoryOf = (file: string) => {\n const directory = path.posix.dirname(file);\n return directory === \".\" ? \"/\" : `/${directory}`;\n};\n\nconst workspaceManifests = {\n npm: \"package.json\",\n cargo: \"Cargo.toml\",\n uv: \"pyproject.toml\",\n} as const;\n\nconst workspaceTable = (\n parsed: Record<string, unknown>,\n ecosystem: keyof typeof workspaceManifests,\n) => {\n switch (ecosystem) {\n case \"npm\":\n return parsed[\"workspaces\"];\n case \"cargo\":\n return parsed[\"workspace\"];\n case \"uv\": {\n const tool = parsed[\"tool\"];\n const uv = record(tool) ? tool[\"uv\"] : undefined;\n return record(uv) ? uv[\"workspace\"] : undefined;\n }\n default: {\n const unexpected: never = ecosystem;\n throw new Error(\"unknown workspace ecosystem\", { cause: unexpected });\n }\n }\n};\n\nconst declaresJavascriptInstallation = (text: string | undefined) => {\n try {\n const manifest: unknown = JSON.parse(text ?? \"\");\n if (!record(manifest)) return false;\n if (typeof manifest[\"packageManager\"] === \"string\") return true;\n return [\n \"dependencies\",\n \"devDependencies\",\n \"optionalDependencies\",\n \"peerDependencies\",\n ].some((field) => {\n const dependencies = manifest[field];\n return record(dependencies) && Object.keys(dependencies).length > 0;\n });\n } catch {\n // Manifest validation reports invalid JSON independently.\n return false;\n }\n};\n\n/** Dependency-bearing projects and workspace members need coverage without requiring a lock. */\nconst workspaceRoots = (\n files: Record<string, string>,\n ecosystem: keyof typeof workspaceManifests,\n) => {\n const manifests = Object.keys(files).filter(\n (file) =>\n path.posix.basename(file) === workspaceManifests[ecosystem] ||\n (ecosystem === \"npm\" &&\n path.posix.basename(file) === \"pnpm-workspace.yaml\"),\n );\n const workspaces = new Map<string, string[]>();\n const npmWorkspaceErrors = new Map<string, Error>();\n for (const file of manifests) {\n if (ecosystem === \"npm\") {\n const directory = path.posix.dirname(file);\n const workspaceFile = path.posix.join(directory, \"pnpm-workspace.yaml\");\n const text = files[workspaceFile];\n if (text !== undefined) {\n try {\n const document = parseDocument(text);\n if (document.errors.length > 0)\n throw new Error(`${workspaceFile}:1: invalid pnpm workspace YAML`);\n const parsed: unknown = document.toJS({ maxAliasCount: 100 });\n if (!record(parsed))\n throw new Error(\n `${workspaceFile}:1: pnpm workspace must contain an object`,\n );\n const patterns = parsed[\"packages\"] ?? [];\n if (!strings(patterns))\n throw new Error(\n `${workspaceFile}:1: pnpm packages must be a string array`,\n );\n workspaces.set(\n directory,\n patterns.map((pattern) =>\n pattern.startsWith(\"!\")\n ? `!${path.posix.normalize(pattern.slice(1))}`\n : path.posix.normalize(pattern),\n ),\n );\n } catch (error) {\n npmWorkspaceErrors.set(\n directory,\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n continue;\n }\n }\n try {\n const parsed: unknown =\n ecosystem === \"npm\"\n ? JSON.parse(files[file] ?? \"\")\n : parseToml(files[file] ?? \"\");\n if (!record(parsed)) continue;\n if (\n ecosystem === \"npm\" &&\n typeof parsed[\"packageManager\"] === \"string\" &&\n parsed[\"packageManager\"].startsWith(\"pnpm@\")\n )\n continue;\n const value = workspaceTable(parsed, ecosystem);\n const patterns = record(value)\n ? value[ecosystem === \"npm\" ? \"packages\" : \"members\"]\n : value;\n const members =\n ecosystem === \"cargo\" && record(value) && patterns === undefined\n ? []\n : patterns;\n if (strings(members)) {\n const excluded =\n ecosystem !== \"npm\" && record(value) && strings(value[\"exclude\"])\n ? value[\"exclude\"].map((pattern) => `!${pattern}`)\n : [];\n workspaces.set(path.posix.dirname(file), [...members, ...excluded]);\n }\n } catch {\n // Other toolchain rules validate manifests; retain the update root here.\n }\n }\n const implicitCargoMembers = new Map<string, Set<string>>();\n const declaredMember = (\n root: string,\n patterns: string[],\n directory: string,\n ) => {\n const relative = path.posix.relative(root, directory);\n if (relative === \"\" || relative === \"..\" || relative.startsWith(\"../\"))\n return false;\n return workspaceContains({\n directory: root,\n file: path.posix.join(directory, \"package.json\"),\n patterns,\n rootMembership: \"patterns\",\n });\n };\n const installable = new Set([\".\"]);\n if (ecosystem === \"npm\") {\n for (const file of manifests) {\n const directory = path.posix.dirname(file);\n if (\n declaresJavascriptInstallation(\n files[path.posix.join(directory, \"package.json\")],\n ) ||\n javascriptDependencyLockfiles.some(\n (name) => files[path.posix.join(directory, name)] !== undefined,\n )\n )\n installable.add(directory);\n }\n let changed = true;\n while (changed) {\n changed = false;\n for (const [root, patterns] of workspaces) {\n if (!installable.has(root)) {\n if (\n ![...installable].some((directory) =>\n declaredMember(root, patterns, directory),\n )\n )\n continue;\n installable.add(root);\n changed = true;\n }\n for (const file of manifests) {\n const directory = path.posix.dirname(file);\n if (\n installable.has(directory) ||\n !declaredMember(root, patterns, directory)\n )\n continue;\n installable.add(directory);\n changed = true;\n }\n }\n }\n }\n if (ecosystem === \"npm\") {\n for (const [directory, error] of npmWorkspaceErrors)\n if (installable.has(directory)) throw error;\n }\n if (ecosystem === \"cargo\") {\n for (const [root, patterns] of workspaces) {\n const includes = patterns.filter((pattern) => !pattern.startsWith(\"!\"));\n const excludes = patterns.filter((pattern) => pattern.startsWith(\"!\"));\n const memberDirectories = new Set([root]);\n for (const file of manifests) {\n const directory = path.posix.dirname(file);\n const relative = path.posix.relative(root, directory);\n if (\n includes.some((pattern) => picomatch.isMatch(relative, pattern)) &&\n !excludes.some((pattern) =>\n picomatch.isMatch(relative, pattern.slice(1)),\n )\n )\n memberDirectories.add(directory);\n }\n for (const directory of memberDirectories) {\n try {\n const parsed = parseToml(\n files[path.posix.join(directory, \"Cargo.toml\")] ?? \"\",\n );\n const rootParsed = parseToml(\n files[path.posix.join(root, \"Cargo.toml\")] ?? \"\",\n );\n const workspace = rootParsed[\"workspace\"];\n const inherited = record(workspace)\n ? workspace[\"dependencies\"]\n : undefined;\n const dependencyOwners = [parsed];\n const targets = parsed[\"target\"];\n if (record(targets)) {\n for (const target of Object.values(targets))\n if (record(target)) dependencyOwners.push(target);\n }\n for (const owner of dependencyOwners) {\n for (const key of [\n \"dependencies\",\n \"dev-dependencies\",\n \"build-dependencies\",\n ]) {\n const dependencies = owner[key];\n if (!record(dependencies)) continue;\n for (const [name, dependency] of Object.entries(dependencies)) {\n if (!record(dependency)) continue;\n const isInherited = dependency[\"workspace\"] === true;\n const resolved =\n isInherited && record(inherited)\n ? inherited[name]\n : dependency;\n if (!record(resolved) || typeof resolved[\"path\"] !== \"string\")\n continue;\n if (\n path.posix.isAbsolute(resolved[\"path\"]) ||\n /\\\\|\\$|^[A-Za-z]:/.test(resolved[\"path\"])\n )\n continue;\n const target = path.posix.normalize(\n path.posix.join(\n isInherited ? root : directory,\n resolved[\"path\"],\n ),\n );\n const relative = path.posix.relative(root, target);\n if (\n relative.startsWith(\"../\") ||\n relative === \"..\" ||\n files[path.posix.join(target, \"Cargo.toml\")] === undefined ||\n excludes.some((pattern) =>\n picomatch.isMatch(relative, pattern.slice(1)),\n )\n )\n continue;\n memberDirectories.add(target);\n }\n }\n }\n } catch {\n // Manifest validation diagnoses malformed TOML independently.\n }\n }\n implicitCargoMembers.set(root, memberDirectories);\n }\n }\n return manifests\n .filter(\n (file) =>\n ecosystem !== \"npm\" || installable.has(path.posix.dirname(file)),\n )\n .filter((file) => {\n const directory = path.posix.dirname(file);\n return ![...workspaces].some(([root, patterns]) => {\n if (ecosystem === \"npm\" && !installable.has(root)) return false;\n const relative = path.posix.relative(root, directory);\n if (relative === \"\" || relative.startsWith(\"../\")) return false;\n const includes = patterns.filter((pattern) => !pattern.startsWith(\"!\"));\n const excludes = patterns.filter((pattern) => pattern.startsWith(\"!\"));\n return (\n (implicitCargoMembers.get(root)?.has(directory) === true ||\n (ecosystem === \"npm\"\n ? declaredMember(root, patterns, directory)\n : includes.some((pattern) =>\n picomatch.isMatch(relative, pattern),\n ))) &&\n !excludes.some((pattern) =>\n picomatch.isMatch(relative, pattern.slice(1)),\n )\n );\n });\n })\n .map(directoryOf)\n .filter((directory, index, values) => values.indexOf(directory) === index);\n};\n\ntype CheckDependabotOptions = {\n files: Record<string, string>;\n policy: DependabotPolicy;\n /** Parsed stll-toolchain.json `dependabotIgnores`. */\n ignores?: readonly DependabotIgnoreDeclaration[] | undefined;\n};\n\nconst javascriptEcosystem = (\n directory: string,\n files: Record<string, string>,\n) => {\n let root = directory === \"/\" ? \".\" : directory.slice(1);\n for (;;) {\n if (files[path.posix.join(root, \"bun.lock\")] !== undefined) return \"bun\";\n try {\n const manifest: unknown = JSON.parse(\n files[path.posix.join(root, \"package.json\")] ?? \"{}\",\n );\n if (record(manifest) && typeof manifest[\"packageManager\"] === \"string\")\n return manifest[\"packageManager\"].startsWith(\"bun@\") ? \"bun\" : \"npm\";\n } catch {\n // Package rules diagnose malformed JSON; retain its update coverage.\n }\n for (const name of javascriptDependencyLockfiles)\n if (files[path.posix.join(root, name)] !== undefined) return \"npm\";\n if (root === \".\") return \"npm\";\n root = path.posix.dirname(root);\n }\n};\n\nconst pythonEcosystem = (file: string, files: Record<string, string>) => {\n const manifestKind = pythonDependencyManifestKind(file);\n if (\n manifestKind === \"pipfile\" ||\n manifestKind === \"pipfile-lock\" ||\n manifestKind === \"setup\"\n )\n return \"pip\";\n const root = path.posix.dirname(file);\n if (\n files[path.posix.join(root, \"uv.lock\")] !== undefined ||\n files[path.posix.join(root, \"uv.toml\")] !== undefined\n )\n return \"uv\";\n const pyproject = files[path.posix.join(root, \"pyproject.toml\")];\n if (pyproject !== undefined) {\n try {\n const parsed = parseToml(pyproject);\n const tool = parsed[\"tool\"];\n if (record(tool) && record(tool[\"uv\"])) return \"uv\";\n } catch {\n // Runtime rules diagnose malformed TOML; retain its update coverage.\n }\n }\n return \"pip\";\n};\n\nconst ecosystemRoots = (files: Record<string, string>) => {\n const roots = new Map<string, Set<string>>();\n const requireRoot = (ecosystem: string, directory: string) => {\n const directories = roots.get(ecosystem) ?? new Set<string>();\n directories.add(directory);\n roots.set(ecosystem, directories);\n };\n for (const directory of workspaceRoots(files, \"npm\"))\n requireRoot(javascriptEcosystem(directory, files), directory);\n for (const directory of workspaceRoots(files, \"cargo\"))\n requireRoot(\"cargo\", directory);\n for (const directory of workspaceRoots(files, \"uv\")) {\n const root = directory === \"/\" ? \".\" : directory.slice(1);\n requireRoot(\n pythonEcosystem(path.posix.join(root, \"pyproject.toml\"), files),\n directory,\n );\n }\n for (const file of Object.keys(files)) {\n if (isDependabotGithubActionsPath(file)) requireRoot(\"github-actions\", \"/\");\n const name = path.posix.basename(file);\n const manifestEcosystem = dependabotManifestEcosystem(file);\n if (manifestEcosystem !== undefined)\n requireRoot(manifestEcosystem, directoryOf(file));\n if (isDockerDefinitionPath(file)) requireRoot(\"docker\", directoryOf(file));\n if (isComposeDefinitionPath(file) || isKubernetesDefinitionPath(file)) {\n for (const document of parseAllDocuments(files[file] ?? \"\", {\n merge: true,\n })) {\n if (document.errors.length > 0) continue;\n try {\n const classified = containerDocumentImages(\n document.toJS({ maxAliasCount: 100 }),\n file,\n );\n if (classified !== undefined)\n requireRoot(classified.ecosystem, directoryOf(file));\n } catch {\n // Runtime validation reports malformed or excessive YAML aliases.\n }\n }\n }\n if (\n name === \"uv.lock\" ||\n name === \"uv.toml\" ||\n (name !== \"pyproject.toml\" && isPythonDependencyManifest(file))\n )\n requireRoot(pythonEcosystem(file, files), directoryOf(file));\n }\n return roots;\n};\n\nconst ignoredFor = (ecosystem: string, policy: DependabotPolicy) => {\n if (ecosystem === \"npm\" || ecosystem === \"bun\") return policy.ignoredPackages;\n if (ecosystem === \"github-actions\") return policy.ignoredActions;\n if (ecosystem === \"docker\" || ecosystem === \"docker-compose\")\n return ownedDockerImageAliases(policy.ignoredImages);\n return [];\n};\n\ntype DeclaredIgnoreConflictsOptions = {\n ignores: readonly DependabotIgnoreDeclaration[];\n policy: DependabotPolicy;\n};\n\n/** Shared pins stay owned by the shared policy; declarations cannot name or match them. */\nexport const declaredIgnoreConflicts = ({\n ignores,\n policy,\n}: DeclaredIgnoreConflictsOptions) =>\n ignores.flatMap(({ ecosystem, dependency }) => {\n const pattern = dependencyPattern(dependency);\n return ignoredFor(ecosystem, policy)\n .filter((pin) => pattern.test(pin))\n .map(\n (pin) =>\n `Dependabot ignore ${ecosystem} ${dependency} covers shared pin ${pin}; the shared policy owns its ignore`,\n );\n });\n\n/** Repository declarations own coverage only; shared policy owns every update option. */\nexport const parseDependabotInput = (input: unknown) => {\n if (\n !record(input) ||\n Object.keys(input).some((key) => key !== \"updates\") ||\n !Array.isArray(input[\"updates\"]) ||\n input[\"updates\"].length === 0\n )\n throw new Error(\n \"Dependabot input must contain a nonempty updates array only\",\n );\n const ecosystems = new Set<string>();\n return input[\"updates\"].map((entry: unknown) => {\n if (\n !record(entry) ||\n Object.keys(entry).some(\n (key) => ![\"ecosystem\", \"directories\"].includes(key),\n ) ||\n typeof entry[\"ecosystem\"] !== \"string\" ||\n !strings(entry[\"directories\"]) ||\n entry[\"directories\"].length === 0\n )\n throw new Error(\n \"each Dependabot update must contain ecosystem and nonempty directories only\",\n );\n const ecosystem = entry[\"ecosystem\"];\n if (!isDependabotEcosystem(ecosystem))\n throw new Error(`unsupported Dependabot ecosystem: ${ecosystem}`);\n const directories = entry[\"directories\"];\n if (ecosystems.has(ecosystem))\n throw new Error(`duplicate Dependabot ecosystem: ${ecosystem}`);\n ecosystems.add(ecosystem);\n const seen = new Set<string>();\n for (const directory of directories) {\n if (\n !directory.startsWith(\"/\") ||\n directory.includes(\"\\\\\") ||\n directory.split(\"/\").some((part) => part === \".\" || part === \"..\") ||\n path.posix.normalize(directory) !== directory ||\n (directory !== \"/\" && directory.endsWith(\"/\")) ||\n /[*?[\\]{}!]/.test(directory)\n )\n throw new Error(\n `Dependabot directory must be a literal absolute repository path: ${directory}`,\n );\n if (seen.has(directory))\n throw new Error(`duplicate Dependabot directory: ${directory}`);\n seen.add(directory);\n }\n return { ecosystem, directories };\n });\n};\n\ntype GenerateDependabotOptions = CheckDependabotOptions & {\n updates?: ReturnType<typeof parseDependabotInput> | undefined;\n};\n\n/** Generate canonical YAML from the same ecosystem enumeration used by the guard. */\nexport const generateDependabotConfig = ({\n files,\n policy,\n updates: declarations,\n ignores = [],\n}: GenerateDependabotOptions) => {\n const conflicts = declaredIgnoreConflicts({ ignores, policy });\n if (conflicts.length > 0) throw new Error(conflicts.join(\"\\n\"));\n const detected = ecosystemRoots(files);\n const roots =\n declarations === undefined\n ? detected\n : new Map(\n parseDependabotInput({ updates: declarations }).map(\n ({ ecosystem, directories }) => [ecosystem, new Set(directories)],\n ),\n );\n for (const [ecosystem, directories] of detected) {\n for (const directory of directories) {\n if (!roots.get(ecosystem)?.has(directory))\n throw new Error(\n `Dependabot input must cover ${ecosystem} directory ${directory}`,\n );\n }\n }\n for (const { ecosystem, dependency } of ignores)\n if (!roots.has(ecosystem))\n throw new Error(\n `Dependabot ignore ${ecosystem} ${dependency} has no ${ecosystem} update entry`,\n );\n const updates = [...roots]\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([ecosystem, ecosystemDirectories]) => {\n const directories = [...ecosystemDirectories].sort();\n const ignore = [\n ...ignoredFor(ecosystem, policy).map((name) => ({\n \"dependency-name\": name,\n \"update-types\": dependabotIgnoreUpdateTypes,\n })),\n ...ignores\n .filter((declared) => declared.ecosystem === ecosystem)\n .sort(byDependency)\n .map(({ dependency, updateTypes }) => ({\n \"dependency-name\": dependency,\n \"update-types\": updateTypes,\n })),\n ];\n const time = new Scalar(policy.schedule.time);\n time.type = Scalar.QUOTE_DOUBLE;\n return {\n \"package-ecosystem\": ecosystem,\n directory: directories.length === 1 ? directories.at(0) : undefined,\n directories: directories.length > 1 ? directories : undefined,\n schedule: {\n interval: policy.schedule.interval,\n day: policy.schedule.day,\n time,\n timezone: policy.schedule.timezone,\n },\n cooldown: { \"default-days\": policy.cooldown.defaultDays },\n groups: Object.fromEntries(\n groupsFor(ecosystem, policy).map(([name, group]) => [\n name,\n group.updateTypes === undefined\n ? { patterns: group.patterns }\n : { patterns: group.patterns, \"update-types\": group.updateTypes },\n ]),\n ),\n ignore: ignore.length > 0 ? ignore : undefined,\n };\n });\n return stringify({ version: 2, updates }, { aliasDuplicateObjects: false });\n};\n\n/** Validate the shared update policy against a hermetic tracked-file snapshot. */\nexport const checkDependabot = ({\n files,\n policy,\n ignores = [],\n}: CheckDependabotOptions): Diagnostic[] => {\n const roots = ecosystemRoots(files);\n const paths = [\".github/dependabot.yml\", \".github/dependabot.yaml\"].filter(\n (file) => files[file] !== undefined,\n );\n if (roots.size === 0 && paths.length === 0 && ignores.length === 0) return [];\n const file = paths.at(0) ?? \".github/dependabot.yml\";\n const diagnostics: Diagnostic[] = [];\n const add = (message: string, line = 1) => {\n diagnostics.push({ rule: \"dependabot-policy\", path: file, line, message });\n };\n if (paths.length === 0) {\n add(\n \"add a Dependabot configuration for the repository's package ecosystems\",\n );\n return diagnostics;\n }\n if (paths.length > 1) add(\"keep one Dependabot configuration file\");\n const lineCounter = new LineCounter();\n const document = parseDocument(files[file] ?? \"\", {\n lineCounter,\n });\n if (document.errors.length > 0) {\n for (const error of document.errors)\n add(\n `invalid Dependabot YAML: ${error.message}`,\n lineCounter.linePos(error.pos[0]).line,\n );\n return diagnostics;\n }\n let parsed: unknown;\n try {\n parsed = document.toJS({ maxAliasCount: 100 });\n } catch {\n add(\"cannot resolve Dependabot YAML aliases\");\n return diagnostics;\n }\n if (\n !record(parsed) ||\n parsed[\"version\"] !== 2 ||\n !Array.isArray(parsed[\"updates\"])\n ) {\n add(\"Dependabot must declare version: 2 and an updates array\");\n return diagnostics;\n }\n const covered = new Map<string, Set<string>>();\n let legacy: unknown;\n try {\n const legacyDocument = parseDocument(files[file] ?? \"\", {\n version: \"1.1\",\n schema: \"yaml-1.1\",\n });\n if (legacyDocument.errors.length === 0)\n legacy = legacyDocument.toJS({ maxAliasCount: 100 });\n } catch {\n // The canonical parser reports invalid aliases; incompatible times fail below.\n }\n const legacyUpdates =\n record(legacy) && Array.isArray(legacy[\"updates\"]) ? legacy[\"updates\"] : [];\n const rootClaims = new Map<string, Map<string, number>>();\n const updatedEcosystems = new Set<string>();\n const directoryClaims = new Map<string, Map<string, number>>();\n for (const [index, update] of parsed[\"updates\"].entries()) {\n const lineOf = (key: string) => {\n const node: unknown = document.getIn([\"updates\", index, key], true);\n const offset = isNode(node) ? node.range?.[0] : undefined;\n return offset === undefined ? 1 : lineCounter.linePos(offset).line;\n };\n const report = (key: string, message: string) => add(message, lineOf(key));\n if (!record(update) || typeof update[\"package-ecosystem\"] !== \"string\") {\n report(\n \"package-ecosystem\",\n \"each Dependabot update must declare a package ecosystem\",\n );\n continue;\n }\n const ecosystem = update[\"package-ecosystem\"];\n if (update[\"target-branch\"] !== undefined)\n report(\n \"target-branch\",\n `${ecosystem}: shared updates must target the default branch`,\n );\n if (update[\"open-pull-requests-limit\"] === 0)\n report(\n \"open-pull-requests-limit\",\n `${ecosystem}: version updates must remain enabled`,\n );\n const single = update[\"directory\"];\n const multiple = update[\"directories\"];\n let directories: string[] = [];\n if (typeof single === \"string\" && multiple === undefined)\n directories = [single];\n else if (single === undefined && strings(multiple)) directories = multiple;\n const validDirectories = directories.filter(\n (directory) =>\n directory.startsWith(\"/\") && !directory.split(\"/\").includes(\"..\"),\n );\n if (\n directories.length === 0 ||\n validDirectories.length !== directories.length\n ) {\n report(\n \"directory\",\n `${ecosystem}: declare directory or nonempty directories with absolute repository paths`,\n );\n }\n const normalizedDirectories = Array.from(\n new Set(\n validDirectories.map(\n (value) => path.posix.normalize(value).replace(/\\/+$/, \"\") || \"/\",\n ),\n ),\n );\n const matches = covered.get(ecosystem) ?? new Set<string>();\n const claimedDirectories =\n directoryClaims.get(ecosystem) ?? new Map<string, number>();\n for (const directory of normalizedDirectories) {\n const previous = claimedDirectories.get(directory);\n if (previous !== undefined)\n report(\n multiple === undefined ? \"directory\" : \"directories\",\n `${ecosystem}: directory ${directory} overlaps update entry ${previous + 1}`,\n );\n else claimedDirectories.set(directory, index);\n }\n directoryClaims.set(ecosystem, claimedDirectories);\n const claimedRoots = rootClaims.get(ecosystem) ?? new Map<string, number>();\n for (const root of roots.get(ecosystem) ?? []) {\n if (\n normalizedDirectories.some(\n (directory) =>\n directory === root ||\n (multiple !== undefined && picomatch.isMatch(root, directory)),\n )\n ) {\n const previous = claimedRoots.get(root);\n if (previous !== undefined)\n report(\n multiple === undefined ? \"directory\" : \"directories\",\n `${ecosystem}: update root ${root} overlaps update entry ${previous + 1}`,\n );\n else claimedRoots.set(root, index);\n matches.add(root);\n }\n }\n rootClaims.set(ecosystem, claimedRoots);\n covered.set(ecosystem, matches);\n const schedule = update[\"schedule\"];\n const legacyUpdate: unknown = legacyUpdates.at(index);\n const legacySchedule = record(legacyUpdate)\n ? legacyUpdate[\"schedule\"]\n : undefined;\n if (\n record(schedule) &&\n schedule[\"time\"] === policy.schedule.time &&\n (!record(legacySchedule) ||\n legacySchedule[\"time\"] !== policy.schedule.time)\n )\n report(\n \"schedule\",\n `${ecosystem}: quote schedule time to preserve its string value in YAML 1.1`,\n );\n if (\n !record(schedule) ||\n Object.keys(schedule).length !== Object.keys(policy.schedule).length ||\n Object.entries(policy.schedule).some(\n ([key, value]) => schedule[key] !== value,\n )\n )\n report(\"schedule\", `${ecosystem}: schedule must match the shared policy`);\n const cooldown = update[\"cooldown\"];\n if (\n !record(cooldown) ||\n Object.keys(cooldown).length !== 1 ||\n cooldown[\"default-days\"] !== policy.cooldown.defaultDays\n )\n report(\n \"cooldown\",\n `${ecosystem}: cooldown must contain only default-days: ${policy.cooldown.defaultDays}`,\n );\n const groups = update[\"groups\"];\n const expectedGroups = groupsFor(ecosystem, policy);\n if (\n !record(groups) ||\n // Dependabot assigns an update to the first matching group.\n JSON.stringify(Object.keys(groups)) !==\n JSON.stringify(expectedGroups.map(([name]) => name)) ||\n expectedGroups.some(([name, expected]) => {\n const group = groups[name];\n return (\n !record(group) ||\n Object.keys(group).length !==\n (expected.updateTypes === undefined ? 1 : 2) ||\n !sameStrings(group[\"patterns\"], expected.patterns) ||\n (expected.updateTypes !== undefined &&\n !sameStrings(group[\"update-types\"], expected.updateTypes))\n );\n })\n )\n report(\"groups\", `${ecosystem}: groups must match the shared policy`);\n const ignored = ignoredFor(ecosystem, policy);\n const declared = ignores.filter(\n (declaration) => declaration.ecosystem === ecosystem,\n );\n updatedEcosystems.add(ecosystem);\n const ignore = update[\"ignore\"];\n if (ignore !== undefined && (!Array.isArray(ignore) || ignore.length === 0))\n report(\"ignore\", `${ecosystem}: omit ignore or provide a nonempty array`);\n const entries: unknown[] = Array.isArray(ignore) ? ignore : [];\n const nameOf = (entry: unknown) =>\n record(entry) && typeof entry[\"dependency-name\"] === \"string\"\n ? entry[\"dependency-name\"]\n : undefined;\n if (\n entries.some((entry) => {\n const name = nameOf(entry);\n return (\n name === undefined ||\n (!ignored.includes(name) &&\n !declared.some(({ dependency }) => dependency === name))\n );\n })\n )\n report(\n \"ignore\",\n `${ecosystem}: ignore only packages owned by the shared policy or declared in stll-toolchain.json dependabotIgnores`,\n );\n if (\n entries.some((entry) => {\n const name = nameOf(entry);\n return (\n name !== undefined &&\n ignored.includes(name) &&\n !versionOnlyIgnore(entry)\n );\n })\n )\n report(\n \"ignore\",\n `${ecosystem}: each shared-pin ignore must contain only dependency-name and update-types for semver-major, semver-minor, and semver-patch version updates; security updates must remain enabled`,\n );\n for (const name of ignored) {\n if (\n !entries.some(\n (entry) => nameOf(entry) === name && versionOnlyIgnore(entry),\n )\n )\n report(\n \"ignore\",\n `${ecosystem}: ignore all version updates for shared pin ${name}`,\n );\n }\n for (const { dependency, updateTypes } of declared) {\n const matching = entries.filter((entry) => nameOf(entry) === dependency);\n if (\n matching.length !== 1 ||\n !matching.every((entry) => versionIgnore(entry, updateTypes))\n )\n report(\n \"ignore\",\n `${ecosystem}: ignore ${dependency} exactly once with only update-types ${updateTypes.join(\", \")} as declared in stll-toolchain.json`,\n );\n }\n }\n for (const { ecosystem, dependency } of ignores)\n if (!updatedEcosystems.has(ecosystem))\n add(\n `Dependabot ignore ${ecosystem} ${dependency} has no ${ecosystem} update entry`,\n );\n for (const [ecosystem, directories] of roots) {\n for (const directory of directories) {\n if (!covered.get(ecosystem)?.has(directory))\n add(`add a ${ecosystem} update entry covering ${directory}`);\n }\n }\n return diagnostics;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toolchain-dependabot.mjs","names":["unexpected","parseToml","stringify"],"sources":["../src/toolchain-images.ts","../src/toolchain-dependabot.ts"],"sourcesContent":["/** Docker Hub spellings accepted by the shared runtime policy. */\nexport const dockerHubRegistries = [\n \"docker.io\",\n \"index.docker.io\",\n \"registry-1.docker.io\",\n] as const;\n\n/** Expand the full accepted repository alias class without parsing Dockerfile instructions. */\nexport const ownedDockerImageAliases = (images: readonly string[]) => {\n const aliases = new Set<string>();\n for (const image of images) {\n for (const repository of [image, `library/${image}`]) {\n aliases.add(repository);\n for (const registry of dockerHubRegistries)\n aliases.add(`${registry}/${repository}`);\n }\n }\n return [...aliases].sort();\n};\n\n/** Preserve tag/digest spelling while normalizing registry and namespace aliases. */\nexport const canonicalDockerRuntime = (image: string) => {\n const registry = dockerHubRegistries.find((entry) =>\n image.toLowerCase().startsWith(`${entry}/`),\n );\n const repository =\n registry === undefined ? image : image.slice(registry.length + 1);\n return repository.replace(/^library\\//i, \"\");\n};\n\n/** Preserve Rust release identity across official Debian slim and Alpine variants. */\nexport const rustImageVersion = (tag: string) =>\n tag.replace(\n /-(?:alpine(?:\\d+(?:\\.\\d+)*)?|(?:bookworm|bullseye|trixie|buster)(?:-slim)?|slim(?:-(?:bookworm|bullseye|trixie|buster))?)$/,\n \"\",\n );\n","import path from \"node:path\";\nimport picomatch from \"picomatch\";\nimport { parse as parseToml } from \"smol-toml\";\nimport {\n isNode,\n LineCounter,\n parseAllDocuments,\n parseDocument,\n Scalar,\n stringify,\n} from \"yaml\";\n\nimport {\n containerDocumentImages,\n isComposeDefinitionPath,\n isKubernetesDefinitionPath,\n} from \"./toolchain-container-inputs\";\nimport { ownedDockerImageAliases } from \"./toolchain-images\";\nimport {\n dependabotManifestEcosystem,\n isDependabotGithubActionsPath,\n isDockerDefinitionPath,\n isPythonDependencyManifest,\n javascriptDependencyLockfiles,\n pythonDependencyManifestKind,\n} from \"./toolchain-inputs\";\nimport { workspaceContains } from \"./toolchain-workspaces\";\n\nexport const dependabotRules = [\"dependabot-policy\"] as const;\n\n// https://docs.github.com/en/code-security/reference/supply-chain-security/dependabot-options-reference#package-ecosystem\nexport const supportedDependabotEcosystems = [\n \"bazel\",\n \"bun\",\n \"bundler\",\n \"cargo\",\n \"composer\",\n \"conda\",\n \"deno\",\n \"devcontainers\",\n \"docker\",\n \"docker-compose\",\n \"dotnet-sdk\",\n \"elm\",\n \"gitsubmodule\",\n \"github-actions\",\n \"gomod\",\n \"gradle\",\n \"helm\",\n \"julia\",\n \"maven\",\n \"mix\",\n \"nix\",\n \"npm\",\n \"nuget\",\n \"opentofu\",\n \"pip\",\n \"pre-commit\",\n \"pub\",\n \"rust-toolchain\",\n \"sbt\",\n \"swift\",\n \"terraform\",\n \"uv\",\n \"vcpkg\",\n] as const;\nexport type DependabotEcosystem =\n (typeof supportedDependabotEcosystems)[number];\nconst isDependabotEcosystem = (value: string): value is DependabotEcosystem =>\n supportedDependabotEcosystems.some((ecosystem) => ecosystem === value);\n\ntype DependabotPolicy = {\n schedule: { interval: string; day: string; time: string; timezone: string };\n cooldown: { defaultDays: number };\n actionGroups: Record<string, { patterns: readonly string[] }>;\n groups: Record<\n string,\n { patterns: readonly string[]; updateTypes: readonly string[] }\n >;\n ignoredPackages: readonly string[];\n ignoredActions: readonly string[];\n ignoredImages: readonly string[];\n};\n\ntype DependabotGroup = {\n patterns: readonly string[];\n updateTypes?: readonly string[] | undefined;\n};\n\n/** Ordered groups for one ecosystem: GitHub Actions first gathers first-party refs. */\nconst groupsFor = (\n ecosystem: string,\n policy: DependabotPolicy,\n): [string, DependabotGroup][] => [\n ...(ecosystem === \"github-actions\"\n ? Object.entries(policy.actionGroups)\n : []),\n ...Object.entries(policy.groups),\n];\n\ntype Diagnostic = {\n rule: (typeof dependabotRules)[number];\n path: string;\n line: number;\n message: string;\n};\n\nconst record = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst strings = (value: unknown): value is string[] =>\n Array.isArray(value) &&\n value.every((entry: unknown) => typeof entry === \"string\");\n\nconst sameStrings = (value: unknown, expected: readonly string[]) => {\n if (!strings(value) || value.length !== expected.length) return false;\n const sortedExpected = [...expected].sort();\n return [...value]\n .sort()\n .every((entry, index) => entry === sortedExpected[index]);\n};\n\n// Version-update types only: security updates stay enabled for every ignore.\nexport const dependabotIgnoreUpdateTypes = [\n \"version-update:semver-major\",\n \"version-update:semver-minor\",\n \"version-update:semver-patch\",\n] as const;\nexport type DependabotIgnoreUpdateType =\n (typeof dependabotIgnoreUpdateTypes)[number];\nconst isIgnoreUpdateType = (\n value: unknown,\n): value is DependabotIgnoreUpdateType =>\n dependabotIgnoreUpdateTypes.some((updateType) => updateType === value);\n\nconst versionIgnore = (entry: unknown, updateTypes: readonly string[]) =>\n record(entry) &&\n Object.keys(entry).length === 2 &&\n typeof entry[\"dependency-name\"] === \"string\" &&\n sameStrings(entry[\"update-types\"], updateTypes);\n\nconst versionOnlyIgnore = (entry: unknown) =>\n versionIgnore(entry, dependabotIgnoreUpdateTypes);\n\n/** A reviewed repository decision to skip some version updates of one dependency. */\nexport type DependabotIgnoreDeclaration = {\n readonly ecosystem: DependabotEcosystem;\n /** Dependabot `dependency-name`; `*` is the only wildcard. */\n readonly dependency: string;\n /** Nonempty, unique and in canonical major, minor, patch order. */\n readonly updateTypes: readonly [\n DependabotIgnoreUpdateType,\n ...DependabotIgnoreUpdateType[],\n ];\n readonly reason: string;\n};\n\nconst ignoreDeclarationKeys = [\n \"ecosystem\",\n \"dependency\",\n \"updateTypes\",\n \"reason\",\n] as const;\n\n/** Parse `dependabotIgnores` from stll-toolchain.json; malformed decisions fail closed. */\nexport const parseDependabotIgnores = (\n input: unknown,\n): DependabotIgnoreDeclaration[] => {\n if (input === undefined) return [];\n if (!Array.isArray(input))\n throw new Error(\"dependabotIgnores must be an array\");\n const result: DependabotIgnoreDeclaration[] = [];\n const keys = new Set<string>();\n for (const entry of input) {\n if (\n !record(entry) ||\n Object.keys(entry).some(\n (key) => !ignoreDeclarationKeys.some((known) => known === key),\n ) ||\n typeof entry[\"reason\"] !== \"string\" ||\n entry[\"reason\"].trim() === \"\"\n )\n throw new Error(\n \"each Dependabot ignore requires ecosystem, dependency, updateTypes and a nonempty reason only\",\n );\n const ecosystem = entry[\"ecosystem\"];\n if (typeof ecosystem !== \"string\" || !isDependabotEcosystem(ecosystem))\n throw new Error(\n `unsupported Dependabot ignore ecosystem: ${String(ecosystem)}`,\n );\n const dependency = entry[\"dependency\"];\n if (\n typeof dependency !== \"string\" ||\n !/^[^\\s?[\\]{}!]+$/.test(dependency) ||\n /^\\*+$/.test(dependency)\n )\n throw new Error(\n `Dependabot ignore dependency must name a dependency; * is the only wildcard: ${String(dependency)}`,\n );\n const updateTypes = entry[\"updateTypes\"];\n if (\n !Array.isArray(updateTypes) ||\n !updateTypes.every(isIgnoreUpdateType) ||\n new Set(updateTypes).size !== updateTypes.length\n )\n throw new Error(\n `Dependabot ignore ${dependency} requires unique update types from ${dependabotIgnoreUpdateTypes.join(\", \")}`,\n );\n const [first, ...rest] = dependabotIgnoreUpdateTypes.filter((updateType) =>\n updateTypes.includes(updateType),\n );\n if (first === undefined)\n throw new Error(\n `Dependabot ignore ${dependency} requires at least one update type`,\n );\n const key = JSON.stringify([ecosystem, dependency]);\n if (keys.has(key))\n throw new Error(\n `duplicate Dependabot ignore: ${ecosystem} ${dependency}`,\n );\n keys.add(key);\n result.push({\n ecosystem,\n dependency,\n updateTypes: [first, ...rest],\n reason: entry[\"reason\"],\n });\n }\n return result;\n};\n\n/**\n * Read only `dependabotIgnores` from stll-toolchain.json text: stll-dependabot must not\n * fail on unrelated declarations, which stll-toolchain-check validates.\n */\nexport const readDependabotIgnores = (toolchain: string | undefined) => {\n if (toolchain === undefined) return [];\n const parsed: unknown = JSON.parse(toolchain);\n if (!record(parsed)) throw new Error(\"stll-toolchain.json must be an object\");\n return parseDependabotIgnores(parsed[\"dependabotIgnores\"]);\n};\n\nconst dependencyPattern = (dependency: string) =>\n new RegExp(\n `^${dependency\n .split(\"*\")\n .map((part) => part.replace(/[.+^${}()|[\\]\\\\/?]/g, \"\\\\$&\"))\n .join(\".*\")}$`,\n );\n\n/** Code-unit order keeps generated bytes independent of the host locale. */\nconst byDependency = (\n left: DependabotIgnoreDeclaration,\n right: DependabotIgnoreDeclaration,\n) => {\n if (left.dependency === right.dependency) return 0;\n return left.dependency < right.dependency ? -1 : 1;\n};\n\nconst directoryOf = (file: string) => {\n const directory = path.posix.dirname(file);\n return directory === \".\" ? \"/\" : `/${directory}`;\n};\n\nconst workspaceManifests = {\n npm: \"package.json\",\n cargo: \"Cargo.toml\",\n uv: \"pyproject.toml\",\n} as const;\n\nconst workspaceTable = (\n parsed: Record<string, unknown>,\n ecosystem: keyof typeof workspaceManifests,\n) => {\n switch (ecosystem) {\n case \"npm\":\n return parsed[\"workspaces\"];\n case \"cargo\":\n return parsed[\"workspace\"];\n case \"uv\": {\n const tool = parsed[\"tool\"];\n const uv = record(tool) ? tool[\"uv\"] : undefined;\n return record(uv) ? uv[\"workspace\"] : undefined;\n }\n default: {\n const unexpected: never = ecosystem;\n throw new Error(\"unknown workspace ecosystem\", { cause: unexpected });\n }\n }\n};\n\nconst declaresJavascriptInstallation = (text: string | undefined) => {\n try {\n const manifest: unknown = JSON.parse(text ?? \"\");\n if (!record(manifest)) return false;\n if (typeof manifest[\"packageManager\"] === \"string\") return true;\n return [\n \"dependencies\",\n \"devDependencies\",\n \"optionalDependencies\",\n \"peerDependencies\",\n ].some((field) => {\n const dependencies = manifest[field];\n return record(dependencies) && Object.keys(dependencies).length > 0;\n });\n } catch {\n // Manifest validation reports invalid JSON independently.\n return false;\n }\n};\n\n/** Dependency-bearing projects and workspace members need coverage without requiring a lock. */\nconst workspaceRoots = (\n files: Record<string, string>,\n ecosystem: keyof typeof workspaceManifests,\n) => {\n const manifests = Object.keys(files).filter(\n (file) =>\n path.posix.basename(file) === workspaceManifests[ecosystem] ||\n (ecosystem === \"npm\" &&\n path.posix.basename(file) === \"pnpm-workspace.yaml\"),\n );\n const workspaces = new Map<string, string[]>();\n const npmWorkspaceErrors = new Map<string, Error>();\n for (const file of manifests) {\n if (ecosystem === \"npm\") {\n const directory = path.posix.dirname(file);\n const workspaceFile = path.posix.join(directory, \"pnpm-workspace.yaml\");\n const text = files[workspaceFile];\n if (text !== undefined) {\n try {\n const document = parseDocument(text);\n if (document.errors.length > 0)\n throw new Error(`${workspaceFile}:1: invalid pnpm workspace YAML`);\n const parsed: unknown = document.toJS({ maxAliasCount: 100 });\n if (!record(parsed))\n throw new Error(\n `${workspaceFile}:1: pnpm workspace must contain an object`,\n );\n const patterns = parsed[\"packages\"] ?? [];\n if (!strings(patterns))\n throw new Error(\n `${workspaceFile}:1: pnpm packages must be a string array`,\n );\n workspaces.set(\n directory,\n patterns.map((pattern) =>\n pattern.startsWith(\"!\")\n ? `!${path.posix.normalize(pattern.slice(1))}`\n : path.posix.normalize(pattern),\n ),\n );\n } catch (error) {\n npmWorkspaceErrors.set(\n directory,\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n continue;\n }\n }\n try {\n const parsed: unknown =\n ecosystem === \"npm\"\n ? JSON.parse(files[file] ?? \"\")\n : parseToml(files[file] ?? \"\");\n if (!record(parsed)) continue;\n if (\n ecosystem === \"npm\" &&\n typeof parsed[\"packageManager\"] === \"string\" &&\n parsed[\"packageManager\"].startsWith(\"pnpm@\")\n )\n continue;\n const value = workspaceTable(parsed, ecosystem);\n const patterns = record(value)\n ? value[ecosystem === \"npm\" ? \"packages\" : \"members\"]\n : value;\n const members =\n ecosystem === \"cargo\" && record(value) && patterns === undefined\n ? []\n : patterns;\n if (strings(members)) {\n const excluded =\n ecosystem !== \"npm\" && record(value) && strings(value[\"exclude\"])\n ? value[\"exclude\"].map((pattern) => `!${pattern}`)\n : [];\n workspaces.set(path.posix.dirname(file), [...members, ...excluded]);\n }\n } catch {\n // Other toolchain rules validate manifests; retain the update root here.\n }\n }\n const implicitCargoMembers = new Map<string, Set<string>>();\n const declaredMember = (\n root: string,\n patterns: string[],\n directory: string,\n ) => {\n const relative = path.posix.relative(root, directory);\n if (relative === \"\" || relative === \"..\" || relative.startsWith(\"../\"))\n return false;\n return workspaceContains({\n directory: root,\n file: path.posix.join(directory, \"package.json\"),\n patterns,\n rootMembership: \"patterns\",\n });\n };\n const installable = new Set([\".\"]);\n if (ecosystem === \"npm\") {\n for (const file of manifests) {\n const directory = path.posix.dirname(file);\n if (\n declaresJavascriptInstallation(\n files[path.posix.join(directory, \"package.json\")],\n ) ||\n javascriptDependencyLockfiles.some(\n (name) => files[path.posix.join(directory, name)] !== undefined,\n )\n )\n installable.add(directory);\n }\n let changed = true;\n while (changed) {\n changed = false;\n for (const [root, patterns] of workspaces) {\n if (!installable.has(root)) {\n if (\n ![...installable].some((directory) =>\n declaredMember(root, patterns, directory),\n )\n )\n continue;\n installable.add(root);\n changed = true;\n }\n for (const file of manifests) {\n const directory = path.posix.dirname(file);\n if (\n installable.has(directory) ||\n !declaredMember(root, patterns, directory)\n )\n continue;\n installable.add(directory);\n changed = true;\n }\n }\n }\n }\n if (ecosystem === \"npm\") {\n for (const [directory, error] of npmWorkspaceErrors)\n if (installable.has(directory)) throw error;\n }\n if (ecosystem === \"cargo\") {\n for (const [root, patterns] of workspaces) {\n const includes = patterns.filter((pattern) => !pattern.startsWith(\"!\"));\n const excludes = patterns.filter((pattern) => pattern.startsWith(\"!\"));\n const memberDirectories = new Set([root]);\n for (const file of manifests) {\n const directory = path.posix.dirname(file);\n const relative = path.posix.relative(root, directory);\n if (\n includes.some((pattern) => picomatch.isMatch(relative, pattern)) &&\n !excludes.some((pattern) =>\n picomatch.isMatch(relative, pattern.slice(1)),\n )\n )\n memberDirectories.add(directory);\n }\n for (const directory of memberDirectories) {\n try {\n const parsed = parseToml(\n files[path.posix.join(directory, \"Cargo.toml\")] ?? \"\",\n );\n const rootParsed = parseToml(\n files[path.posix.join(root, \"Cargo.toml\")] ?? \"\",\n );\n const workspace = rootParsed[\"workspace\"];\n const inherited = record(workspace)\n ? workspace[\"dependencies\"]\n : undefined;\n const dependencyOwners = [parsed];\n const targets = parsed[\"target\"];\n if (record(targets)) {\n for (const target of Object.values(targets))\n if (record(target)) dependencyOwners.push(target);\n }\n for (const owner of dependencyOwners) {\n for (const key of [\n \"dependencies\",\n \"dev-dependencies\",\n \"build-dependencies\",\n ]) {\n const dependencies = owner[key];\n if (!record(dependencies)) continue;\n for (const [name, dependency] of Object.entries(dependencies)) {\n if (!record(dependency)) continue;\n const isInherited = dependency[\"workspace\"] === true;\n const resolved =\n isInherited && record(inherited)\n ? inherited[name]\n : dependency;\n if (!record(resolved) || typeof resolved[\"path\"] !== \"string\")\n continue;\n if (\n path.posix.isAbsolute(resolved[\"path\"]) ||\n /\\\\|\\$|^[A-Za-z]:/.test(resolved[\"path\"])\n )\n continue;\n const target = path.posix.normalize(\n path.posix.join(\n isInherited ? root : directory,\n resolved[\"path\"],\n ),\n );\n const relative = path.posix.relative(root, target);\n if (\n relative.startsWith(\"../\") ||\n relative === \"..\" ||\n files[path.posix.join(target, \"Cargo.toml\")] === undefined ||\n excludes.some((pattern) =>\n picomatch.isMatch(relative, pattern.slice(1)),\n )\n )\n continue;\n memberDirectories.add(target);\n }\n }\n }\n } catch {\n // Manifest validation diagnoses malformed TOML independently.\n }\n }\n implicitCargoMembers.set(root, memberDirectories);\n }\n }\n return manifests\n .filter(\n (file) =>\n ecosystem !== \"npm\" || installable.has(path.posix.dirname(file)),\n )\n .filter((file) => {\n const directory = path.posix.dirname(file);\n return ![...workspaces].some(([root, patterns]) => {\n if (ecosystem === \"npm\" && !installable.has(root)) return false;\n const relative = path.posix.relative(root, directory);\n if (relative === \"\" || relative.startsWith(\"../\")) return false;\n const includes = patterns.filter((pattern) => !pattern.startsWith(\"!\"));\n const excludes = patterns.filter((pattern) => pattern.startsWith(\"!\"));\n return (\n (implicitCargoMembers.get(root)?.has(directory) === true ||\n (ecosystem === \"npm\"\n ? declaredMember(root, patterns, directory)\n : includes.some((pattern) =>\n picomatch.isMatch(relative, pattern),\n ))) &&\n !excludes.some((pattern) =>\n picomatch.isMatch(relative, pattern.slice(1)),\n )\n );\n });\n })\n .map(directoryOf)\n .filter((directory, index, values) => values.indexOf(directory) === index);\n};\n\ntype CheckDependabotOptions = {\n files: Record<string, string>;\n policy: DependabotPolicy;\n /** Parsed stll-toolchain.json `dependabotIgnores`. */\n ignores?: readonly DependabotIgnoreDeclaration[] | undefined;\n};\n\nconst javascriptEcosystem = (\n directory: string,\n files: Record<string, string>,\n) => {\n let root = directory === \"/\" ? \".\" : directory.slice(1);\n for (;;) {\n if (files[path.posix.join(root, \"bun.lock\")] !== undefined) return \"bun\";\n try {\n const manifest: unknown = JSON.parse(\n files[path.posix.join(root, \"package.json\")] ?? \"{}\",\n );\n if (record(manifest) && typeof manifest[\"packageManager\"] === \"string\")\n return manifest[\"packageManager\"].startsWith(\"bun@\") ? \"bun\" : \"npm\";\n } catch {\n // Package rules diagnose malformed JSON; retain its update coverage.\n }\n for (const name of javascriptDependencyLockfiles)\n if (files[path.posix.join(root, name)] !== undefined) return \"npm\";\n if (root === \".\") return \"npm\";\n root = path.posix.dirname(root);\n }\n};\n\nconst pythonEcosystem = (file: string, files: Record<string, string>) => {\n const manifestKind = pythonDependencyManifestKind(file);\n if (\n manifestKind === \"pipfile\" ||\n manifestKind === \"pipfile-lock\" ||\n manifestKind === \"setup\"\n )\n return \"pip\";\n const root = path.posix.dirname(file);\n if (\n files[path.posix.join(root, \"uv.lock\")] !== undefined ||\n files[path.posix.join(root, \"uv.toml\")] !== undefined\n )\n return \"uv\";\n const pyproject = files[path.posix.join(root, \"pyproject.toml\")];\n if (pyproject !== undefined) {\n try {\n const parsed = parseToml(pyproject);\n const tool = parsed[\"tool\"];\n if (record(tool) && record(tool[\"uv\"])) return \"uv\";\n } catch {\n // Runtime rules diagnose malformed TOML; retain its update coverage.\n }\n }\n return \"pip\";\n};\n\nconst ecosystemRoots = (files: Record<string, string>) => {\n const roots = new Map<string, Set<string>>();\n const requireRoot = (ecosystem: string, directory: string) => {\n const directories = roots.get(ecosystem) ?? new Set<string>();\n directories.add(directory);\n roots.set(ecosystem, directories);\n };\n for (const directory of workspaceRoots(files, \"npm\"))\n requireRoot(javascriptEcosystem(directory, files), directory);\n for (const directory of workspaceRoots(files, \"cargo\"))\n requireRoot(\"cargo\", directory);\n for (const directory of workspaceRoots(files, \"uv\")) {\n const root = directory === \"/\" ? \".\" : directory.slice(1);\n requireRoot(\n pythonEcosystem(path.posix.join(root, \"pyproject.toml\"), files),\n directory,\n );\n }\n for (const file of Object.keys(files)) {\n if (isDependabotGithubActionsPath(file)) requireRoot(\"github-actions\", \"/\");\n const name = path.posix.basename(file);\n const manifestEcosystem = dependabotManifestEcosystem(file);\n if (manifestEcosystem !== undefined)\n requireRoot(manifestEcosystem, directoryOf(file));\n if (isDockerDefinitionPath(file)) requireRoot(\"docker\", directoryOf(file));\n if (isComposeDefinitionPath(file) || isKubernetesDefinitionPath(file)) {\n for (const document of parseAllDocuments(files[file] ?? \"\", {\n merge: true,\n })) {\n if (document.errors.length > 0) continue;\n try {\n const classified = containerDocumentImages(\n document.toJS({ maxAliasCount: 100 }),\n file,\n );\n if (classified !== undefined)\n requireRoot(classified.ecosystem, directoryOf(file));\n } catch {\n // Runtime validation reports malformed or excessive YAML aliases.\n }\n }\n }\n if (\n name === \"uv.lock\" ||\n name === \"uv.toml\" ||\n (name !== \"pyproject.toml\" && isPythonDependencyManifest(file))\n )\n requireRoot(pythonEcosystem(file, files), directoryOf(file));\n }\n return roots;\n};\n\nconst ignoredFor = (ecosystem: string, policy: DependabotPolicy) => {\n if (ecosystem === \"npm\" || ecosystem === \"bun\") return policy.ignoredPackages;\n if (ecosystem === \"github-actions\") return policy.ignoredActions;\n if (ecosystem === \"docker\" || ecosystem === \"docker-compose\")\n return ownedDockerImageAliases(policy.ignoredImages);\n return [];\n};\n\ntype DeclaredIgnoreConflictsOptions = {\n ignores: readonly DependabotIgnoreDeclaration[];\n policy: DependabotPolicy;\n};\n\n/** Shared pins stay owned by the shared policy; declarations cannot name or match them. */\nexport const declaredIgnoreConflicts = ({\n ignores,\n policy,\n}: DeclaredIgnoreConflictsOptions) =>\n ignores.flatMap(({ ecosystem, dependency }) => {\n const pattern = dependencyPattern(dependency);\n return ignoredFor(ecosystem, policy)\n .filter((pin) => pattern.test(pin))\n .map(\n (pin) =>\n `Dependabot ignore ${ecosystem} ${dependency} covers shared pin ${pin}; the shared policy owns its ignore`,\n );\n });\n\n/** Repository declarations own coverage only; shared policy owns every update option. */\nexport const parseDependabotInput = (input: unknown) => {\n if (\n !record(input) ||\n Object.keys(input).some((key) => key !== \"updates\") ||\n !Array.isArray(input[\"updates\"]) ||\n input[\"updates\"].length === 0\n )\n throw new Error(\n \"Dependabot input must contain a nonempty updates array only\",\n );\n const ecosystems = new Set<string>();\n return input[\"updates\"].map((entry: unknown) => {\n if (\n !record(entry) ||\n Object.keys(entry).some(\n (key) => ![\"ecosystem\", \"directories\"].includes(key),\n ) ||\n typeof entry[\"ecosystem\"] !== \"string\" ||\n !strings(entry[\"directories\"]) ||\n entry[\"directories\"].length === 0\n )\n throw new Error(\n \"each Dependabot update must contain ecosystem and nonempty directories only\",\n );\n const ecosystem = entry[\"ecosystem\"];\n if (!isDependabotEcosystem(ecosystem))\n throw new Error(`unsupported Dependabot ecosystem: ${ecosystem}`);\n const directories = entry[\"directories\"];\n if (ecosystems.has(ecosystem))\n throw new Error(`duplicate Dependabot ecosystem: ${ecosystem}`);\n ecosystems.add(ecosystem);\n const seen = new Set<string>();\n for (const directory of directories) {\n if (\n !directory.startsWith(\"/\") ||\n directory.includes(\"\\\\\") ||\n directory.split(\"/\").some((part) => part === \".\" || part === \"..\") ||\n path.posix.normalize(directory) !== directory ||\n (directory !== \"/\" && directory.endsWith(\"/\")) ||\n /[*?[\\]{}!]/.test(directory)\n )\n throw new Error(\n `Dependabot directory must be a literal absolute repository path: ${directory}`,\n );\n if (seen.has(directory))\n throw new Error(`duplicate Dependabot directory: ${directory}`);\n seen.add(directory);\n }\n return { ecosystem, directories };\n });\n};\n\ntype GenerateDependabotOptions = CheckDependabotOptions & {\n updates?: ReturnType<typeof parseDependabotInput> | undefined;\n};\n\n/** Generate canonical YAML from the same ecosystem enumeration used by the guard. */\nexport const generateDependabotConfig = ({\n files,\n policy,\n updates: declarations,\n ignores = [],\n}: GenerateDependabotOptions) => {\n const conflicts = declaredIgnoreConflicts({ ignores, policy });\n if (conflicts.length > 0) throw new Error(conflicts.join(\"\\n\"));\n const detected = ecosystemRoots(files);\n const roots =\n declarations === undefined\n ? detected\n : new Map(\n parseDependabotInput({ updates: declarations }).map(\n ({ ecosystem, directories }) => [ecosystem, new Set(directories)],\n ),\n );\n for (const [ecosystem, directories] of detected) {\n for (const directory of directories) {\n if (!roots.get(ecosystem)?.has(directory))\n throw new Error(\n `Dependabot input must cover ${ecosystem} directory ${directory}`,\n );\n }\n }\n for (const { ecosystem, dependency } of ignores)\n if (!roots.has(ecosystem))\n throw new Error(\n `Dependabot ignore ${ecosystem} ${dependency} has no ${ecosystem} update entry`,\n );\n const updates = [...roots]\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([ecosystem, ecosystemDirectories]) => {\n const directories = [...ecosystemDirectories].sort();\n const ignore = [\n ...ignoredFor(ecosystem, policy).map((name) => ({\n \"dependency-name\": name,\n \"update-types\": dependabotIgnoreUpdateTypes,\n })),\n ...ignores\n .filter((declared) => declared.ecosystem === ecosystem)\n .sort(byDependency)\n .map(({ dependency, updateTypes }) => ({\n \"dependency-name\": dependency,\n \"update-types\": updateTypes,\n })),\n ];\n const time = new Scalar(policy.schedule.time);\n time.type = Scalar.QUOTE_DOUBLE;\n return {\n \"package-ecosystem\": ecosystem,\n directory: directories.length === 1 ? directories.at(0) : undefined,\n directories: directories.length > 1 ? directories : undefined,\n schedule: {\n interval: policy.schedule.interval,\n day: policy.schedule.day,\n time,\n timezone: policy.schedule.timezone,\n },\n cooldown: { \"default-days\": policy.cooldown.defaultDays },\n groups: Object.fromEntries(\n groupsFor(ecosystem, policy).map(([name, group]) => [\n name,\n group.updateTypes === undefined\n ? { patterns: group.patterns }\n : { patterns: group.patterns, \"update-types\": group.updateTypes },\n ]),\n ),\n ignore: ignore.length > 0 ? ignore : undefined,\n };\n });\n return stringify({ version: 2, updates }, { aliasDuplicateObjects: false });\n};\n\n/** Validate the shared update policy against a hermetic tracked-file snapshot. */\nexport const checkDependabot = ({\n files,\n policy,\n ignores = [],\n}: CheckDependabotOptions): Diagnostic[] => {\n const roots = ecosystemRoots(files);\n const paths = [\".github/dependabot.yml\", \".github/dependabot.yaml\"].filter(\n (file) => files[file] !== undefined,\n );\n if (roots.size === 0 && paths.length === 0 && ignores.length === 0) return [];\n const file = paths.at(0) ?? \".github/dependabot.yml\";\n const diagnostics: Diagnostic[] = [];\n const add = (message: string, line = 1) => {\n diagnostics.push({ rule: \"dependabot-policy\", path: file, line, message });\n };\n if (paths.length === 0) {\n add(\n \"add a Dependabot configuration for the repository's package ecosystems\",\n );\n return diagnostics;\n }\n if (paths.length > 1) add(\"keep one Dependabot configuration file\");\n const lineCounter = new LineCounter();\n const document = parseDocument(files[file] ?? \"\", {\n lineCounter,\n });\n if (document.errors.length > 0) {\n for (const error of document.errors)\n add(\n `invalid Dependabot YAML: ${error.message}`,\n lineCounter.linePos(error.pos[0]).line,\n );\n return diagnostics;\n }\n let parsed: unknown;\n try {\n parsed = document.toJS({ maxAliasCount: 100 });\n } catch {\n add(\"cannot resolve Dependabot YAML aliases\");\n return diagnostics;\n }\n if (\n !record(parsed) ||\n parsed[\"version\"] !== 2 ||\n !Array.isArray(parsed[\"updates\"])\n ) {\n add(\"Dependabot must declare version: 2 and an updates array\");\n return diagnostics;\n }\n const covered = new Map<string, Set<string>>();\n let legacy: unknown;\n try {\n const legacyDocument = parseDocument(files[file] ?? \"\", {\n version: \"1.1\",\n schema: \"yaml-1.1\",\n });\n if (legacyDocument.errors.length === 0)\n legacy = legacyDocument.toJS({ maxAliasCount: 100 });\n } catch {\n // The canonical parser reports invalid aliases; incompatible times fail below.\n }\n const legacyUpdates =\n record(legacy) && Array.isArray(legacy[\"updates\"]) ? legacy[\"updates\"] : [];\n const rootClaims = new Map<string, Map<string, number>>();\n const updatedEcosystems = new Set<string>();\n const directoryClaims = new Map<string, Map<string, number>>();\n for (const [index, update] of parsed[\"updates\"].entries()) {\n const lineOf = (key: string) => {\n const node: unknown = document.getIn([\"updates\", index, key], true);\n const offset = isNode(node) ? node.range?.[0] : undefined;\n return offset === undefined ? 1 : lineCounter.linePos(offset).line;\n };\n const report = (key: string, message: string) => add(message, lineOf(key));\n if (!record(update) || typeof update[\"package-ecosystem\"] !== \"string\") {\n report(\n \"package-ecosystem\",\n \"each Dependabot update must declare a package ecosystem\",\n );\n continue;\n }\n const ecosystem = update[\"package-ecosystem\"];\n if (update[\"target-branch\"] !== undefined)\n report(\n \"target-branch\",\n `${ecosystem}: shared updates must target the default branch`,\n );\n if (update[\"open-pull-requests-limit\"] === 0)\n report(\n \"open-pull-requests-limit\",\n `${ecosystem}: version updates must remain enabled`,\n );\n const single = update[\"directory\"];\n const multiple = update[\"directories\"];\n let directories: string[] = [];\n if (typeof single === \"string\" && multiple === undefined)\n directories = [single];\n else if (single === undefined && strings(multiple)) directories = multiple;\n const validDirectories = directories.filter(\n (directory) =>\n directory.startsWith(\"/\") && !directory.split(\"/\").includes(\"..\"),\n );\n if (\n directories.length === 0 ||\n validDirectories.length !== directories.length\n ) {\n report(\n \"directory\",\n `${ecosystem}: declare directory or nonempty directories with absolute repository paths`,\n );\n }\n const normalizedDirectories = Array.from(\n new Set(\n validDirectories.map(\n (value) => path.posix.normalize(value).replace(/\\/+$/, \"\") || \"/\",\n ),\n ),\n );\n const matches = covered.get(ecosystem) ?? new Set<string>();\n const claimedDirectories =\n directoryClaims.get(ecosystem) ?? new Map<string, number>();\n for (const directory of normalizedDirectories) {\n const previous = claimedDirectories.get(directory);\n if (previous !== undefined)\n report(\n multiple === undefined ? \"directory\" : \"directories\",\n `${ecosystem}: directory ${directory} overlaps update entry ${previous + 1}`,\n );\n else claimedDirectories.set(directory, index);\n }\n directoryClaims.set(ecosystem, claimedDirectories);\n const claimedRoots = rootClaims.get(ecosystem) ?? new Map<string, number>();\n for (const root of roots.get(ecosystem) ?? []) {\n if (\n normalizedDirectories.some(\n (directory) =>\n directory === root ||\n (multiple !== undefined && picomatch.isMatch(root, directory)),\n )\n ) {\n const previous = claimedRoots.get(root);\n if (previous !== undefined)\n report(\n multiple === undefined ? \"directory\" : \"directories\",\n `${ecosystem}: update root ${root} overlaps update entry ${previous + 1}`,\n );\n else claimedRoots.set(root, index);\n matches.add(root);\n }\n }\n rootClaims.set(ecosystem, claimedRoots);\n covered.set(ecosystem, matches);\n const schedule = update[\"schedule\"];\n const legacyUpdate: unknown = legacyUpdates.at(index);\n const legacySchedule = record(legacyUpdate)\n ? legacyUpdate[\"schedule\"]\n : undefined;\n if (\n record(schedule) &&\n schedule[\"time\"] === policy.schedule.time &&\n (!record(legacySchedule) ||\n legacySchedule[\"time\"] !== policy.schedule.time)\n )\n report(\n \"schedule\",\n `${ecosystem}: quote schedule time to preserve its string value in YAML 1.1`,\n );\n if (\n !record(schedule) ||\n Object.keys(schedule).length !== Object.keys(policy.schedule).length ||\n Object.entries(policy.schedule).some(\n ([key, value]) => schedule[key] !== value,\n )\n )\n report(\"schedule\", `${ecosystem}: schedule must match the shared policy`);\n const cooldown = update[\"cooldown\"];\n if (\n !record(cooldown) ||\n Object.keys(cooldown).length !== 1 ||\n cooldown[\"default-days\"] !== policy.cooldown.defaultDays\n )\n report(\n \"cooldown\",\n `${ecosystem}: cooldown must contain only default-days: ${policy.cooldown.defaultDays}`,\n );\n const groups = update[\"groups\"];\n const expectedGroups = groupsFor(ecosystem, policy);\n if (\n !record(groups) ||\n // Dependabot assigns an update to the first matching group.\n JSON.stringify(Object.keys(groups)) !==\n JSON.stringify(expectedGroups.map(([name]) => name)) ||\n expectedGroups.some(([name, expected]) => {\n const group = groups[name];\n return (\n !record(group) ||\n Object.keys(group).length !==\n (expected.updateTypes === undefined ? 1 : 2) ||\n !sameStrings(group[\"patterns\"], expected.patterns) ||\n (expected.updateTypes !== undefined &&\n !sameStrings(group[\"update-types\"], expected.updateTypes))\n );\n })\n )\n report(\"groups\", `${ecosystem}: groups must match the shared policy`);\n const ignored = ignoredFor(ecosystem, policy);\n const declared = ignores.filter(\n (declaration) => declaration.ecosystem === ecosystem,\n );\n updatedEcosystems.add(ecosystem);\n const ignore = update[\"ignore\"];\n if (ignore !== undefined && (!Array.isArray(ignore) || ignore.length === 0))\n report(\"ignore\", `${ecosystem}: omit ignore or provide a nonempty array`);\n const entries: unknown[] = Array.isArray(ignore) ? ignore : [];\n const nameOf = (entry: unknown) =>\n record(entry) && typeof entry[\"dependency-name\"] === \"string\"\n ? entry[\"dependency-name\"]\n : undefined;\n if (\n entries.some((entry) => {\n const name = nameOf(entry);\n return (\n name === undefined ||\n (!ignored.includes(name) &&\n !declared.some(({ dependency }) => dependency === name))\n );\n })\n )\n report(\n \"ignore\",\n `${ecosystem}: ignore only packages owned by the shared policy or declared in stll-toolchain.json dependabotIgnores`,\n );\n if (\n entries.some((entry) => {\n const name = nameOf(entry);\n return (\n name !== undefined &&\n ignored.includes(name) &&\n !versionOnlyIgnore(entry)\n );\n })\n )\n report(\n \"ignore\",\n `${ecosystem}: each shared-pin ignore must contain only dependency-name and update-types for semver-major, semver-minor, and semver-patch version updates; security updates must remain enabled`,\n );\n for (const name of ignored) {\n if (\n !entries.some(\n (entry) => nameOf(entry) === name && versionOnlyIgnore(entry),\n )\n )\n report(\n \"ignore\",\n `${ecosystem}: ignore all version updates for shared pin ${name}`,\n );\n }\n for (const { dependency, updateTypes } of declared) {\n const matching = entries.filter((entry) => nameOf(entry) === dependency);\n if (\n matching.length !== 1 ||\n !matching.every((entry) => versionIgnore(entry, updateTypes))\n )\n report(\n \"ignore\",\n `${ecosystem}: ignore ${dependency} exactly once with only update-types ${updateTypes.join(\", \")} as declared in stll-toolchain.json`,\n );\n }\n }\n for (const { ecosystem, dependency } of ignores)\n if (!updatedEcosystems.has(ecosystem))\n add(\n `Dependabot ignore ${ecosystem} ${dependency} has no ${ecosystem} update entry`,\n );\n for (const [ecosystem, directories] of roots) {\n for (const directory of directories) {\n if (!covered.get(ecosystem)?.has(directory))\n add(`add a ${ecosystem} update entry covering ${directory}`);\n }\n }\n return diagnostics;\n};\n"],"mappings":"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"}
|
package/dist/toolchain-guard.cjs
CHANGED
|
@@ -7,13 +7,13 @@ const require_toolchain_dependabot = require("./toolchain-dependabot.cjs");
|
|
|
7
7
|
const require_toolchain_schema = require("./toolchain-schema.cjs");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
10
|
-
let node_child_process = require("node:child_process");
|
|
11
|
-
let node_fs = require("node:fs");
|
|
12
10
|
let smol_toml = require("smol-toml");
|
|
13
|
-
let
|
|
14
|
-
let yaml = require("yaml");
|
|
11
|
+
let node_fs = require("node:fs");
|
|
15
12
|
let picomatch = require("picomatch");
|
|
16
13
|
picomatch = require_rolldown_runtime.__toESM(picomatch, 1);
|
|
14
|
+
let node_child_process = require("node:child_process");
|
|
15
|
+
let semver = require("semver");
|
|
16
|
+
let yaml = require("yaml");
|
|
17
17
|
let node_module = require("node:module");
|
|
18
18
|
let node_url = require("node:url");
|
|
19
19
|
//#region src/toolchain-bun.ts
|
|
@@ -34,7 +34,7 @@ const repositoryBun = (floor, manifest) => {
|
|
|
34
34
|
};
|
|
35
35
|
//#endregion
|
|
36
36
|
//#region src/toolchain-consumer-checks.ts
|
|
37
|
-
const consumerRunnerVersion = "2.
|
|
37
|
+
const consumerRunnerVersion = "2.1.0";
|
|
38
38
|
const consumerCheckWorkflow = "stella/.github/.github/workflows/package-consumer-compat.yml";
|
|
39
39
|
const record$10 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
40
40
|
const repositoryDirectory = (value) => typeof value === "string" && value !== "" && !value.includes("\\") && !value.includes("${{") && !value.split("").some((character) => {
|
package/dist/toolchain-guard.mjs
CHANGED
|
@@ -6,12 +6,12 @@ import { d as rustImageVersion, i as dependabotRules, n as declaredIgnoreConflic
|
|
|
6
6
|
import { n as checkFormatter, r as formatterRule } from "./toolchain-schema.mjs";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import path, { extname } from "node:path";
|
|
9
|
-
import { execFileSync, spawnSync } from "node:child_process";
|
|
10
|
-
import { closeSync, lstatSync, openSync, readFileSync, readSync, realpathSync } from "node:fs";
|
|
11
9
|
import { parse } from "smol-toml";
|
|
10
|
+
import { closeSync, lstatSync, openSync, readFileSync, readSync, realpathSync } from "node:fs";
|
|
11
|
+
import picomatch from "picomatch";
|
|
12
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
12
13
|
import { gte, minVersion, satisfies, valid, validRange } from "semver";
|
|
13
14
|
import { LineCounter, isAlias, isMap, isNode, isScalar, isSeq, parseAllDocuments, parseDocument } from "yaml";
|
|
14
|
-
import picomatch from "picomatch";
|
|
15
15
|
import { pathToFileURL } from "node:url";
|
|
16
16
|
//#region src/toolchain-bun.ts
|
|
17
17
|
const STABLE_RELEASE = /^\d+\.\d+\.\d+$/u;
|
|
@@ -31,7 +31,7 @@ const repositoryBun = (floor, manifest) => {
|
|
|
31
31
|
};
|
|
32
32
|
//#endregion
|
|
33
33
|
//#region src/toolchain-consumer-checks.ts
|
|
34
|
-
const consumerRunnerVersion = "2.
|
|
34
|
+
const consumerRunnerVersion = "2.1.0";
|
|
35
35
|
const consumerCheckWorkflow = "stella/.github/.github/workflows/package-consumer-compat.yml";
|
|
36
36
|
const record$10 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37
37
|
const repositoryDirectory = (value) => typeof value === "string" && value !== "" && !value.includes("\\") && !value.includes("${{") && !value.split("").some((character) => {
|
|
@@ -2,12 +2,12 @@ const require_rolldown_runtime = require("./rolldown-runtime.cjs");
|
|
|
2
2
|
let node_path = require("node:path");
|
|
3
3
|
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
4
4
|
let smol_toml = require("smol-toml");
|
|
5
|
+
let picomatch = require("picomatch");
|
|
6
|
+
picomatch = require_rolldown_runtime.__toESM(picomatch, 1);
|
|
5
7
|
let node_crypto = require("node:crypto");
|
|
6
8
|
let semver = require("semver");
|
|
7
9
|
let node_util = require("node:util");
|
|
8
10
|
let yaml = require("yaml");
|
|
9
|
-
let picomatch = require("picomatch");
|
|
10
|
-
picomatch = require_rolldown_runtime.__toESM(picomatch, 1);
|
|
11
11
|
//#region src/cloud-setup-install.ts
|
|
12
12
|
const packageInstall = String.raw`
|
|
13
13
|
# Prevent package maintainer scripts from starting unmanaged system services.
|
|
@@ -42,20 +42,20 @@ apt_install() (
|
|
|
42
42
|
policy_state=installed
|
|
43
43
|
printf '%s\n' '#!/bin/sh' 'exit 101' > /usr/sbin/policy-rc.d
|
|
44
44
|
chmod 755 /usr/sbin/policy-rc.d
|
|
45
|
-
|
|
45
|
+
# The network deadline covers downloads only; unpacking and maintainer scripts
|
|
46
|
+
# (for example locale generation or cluster creation) run offline afterwards.
|
|
47
|
+
DEBIAN_FRONTEND=noninteractive apt_network install -y --no-install-recommends --download-only "$@"
|
|
48
|
+
local package pending
|
|
46
49
|
for package in "$@"; do
|
|
47
50
|
if [[ "$package" == */* ]]; then
|
|
48
|
-
# apt
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
# apt rejects --no-download for local archives, so prove instead that
|
|
52
|
+
# only local file: archives remain; --print-uris reads local state only.
|
|
53
|
+
pending="$(set -o pipefail; DEBIAN_FRONTEND=noninteractive apt-get --print-uris -qq -y --no-install-recommends install "$@" | awk '$1 !~ /^\047file:/')"
|
|
54
|
+
[[ -z "$pending" ]] || fail "Package downloads remain after the bounded download step: $pending"
|
|
55
|
+
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "$@"
|
|
53
56
|
return
|
|
54
57
|
fi
|
|
55
58
|
done
|
|
56
|
-
# The network deadline covers downloads only; unpacking and maintainer scripts
|
|
57
|
-
# (for example locale generation or cluster creation) run offline afterwards.
|
|
58
|
-
DEBIAN_FRONTEND=noninteractive apt_network install -y --no-install-recommends --download-only "$@"
|
|
59
59
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --no-download "$@"
|
|
60
60
|
)
|
|
61
61
|
|
|
@@ -337,6 +337,28 @@ apt_refresh_for() {
|
|
|
337
337
|
}
|
|
338
338
|
`;
|
|
339
339
|
//#endregion
|
|
340
|
+
//#region src/archive-pins.ts
|
|
341
|
+
const record$3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
342
|
+
/** Parse a map from exact releases to their amd64 and arm64 archive SHA256 values. */
|
|
343
|
+
const parseArchiveSha256 = (input, label) => {
|
|
344
|
+
if (input === void 0) return {};
|
|
345
|
+
if (!record$3(input)) throw new Error(`${label} must be a version map`);
|
|
346
|
+
const releases = {};
|
|
347
|
+
for (const [version, value] of Object.entries(input)) {
|
|
348
|
+
if ((0, semver.valid)(version) !== version || !record$3(value)) throw new Error(`${label} requires exact release keys`);
|
|
349
|
+
const keys = Object.keys(value);
|
|
350
|
+
if (keys.length !== 2 || !keys.includes("amd64") || !keys.includes("arm64")) throw new Error(`${label} ${version} requires amd64 and arm64 pins`);
|
|
351
|
+
const amd64 = value["amd64"];
|
|
352
|
+
const arm64 = value["arm64"];
|
|
353
|
+
if (typeof amd64 !== "string" || typeof arm64 !== "string" || !/^[a-f0-9]{64}$/.test(amd64) || !/^[a-f0-9]{64}$/.test(arm64)) throw new Error(`${label} ${version} requires lowercase SHA256 pins`);
|
|
354
|
+
releases[version] = {
|
|
355
|
+
amd64,
|
|
356
|
+
arm64
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
return releases;
|
|
360
|
+
};
|
|
361
|
+
//#endregion
|
|
340
362
|
//#region src/cloud-setup-artifacts.ts
|
|
341
363
|
const wasmBindgen0126 = {
|
|
342
364
|
version: "0.2.126",
|
|
@@ -550,6 +572,20 @@ const parseTools = (input) => {
|
|
|
550
572
|
}
|
|
551
573
|
return result;
|
|
552
574
|
};
|
|
575
|
+
const cloudRuntimes = ["node", "bun"];
|
|
576
|
+
const parseRuntimeArchives = (input) => {
|
|
577
|
+
if (input === void 0) return void 0;
|
|
578
|
+
if (!object(input) || Object.keys(input).some((key) => !cloudRuntimes.some((runtime) => runtime === key))) throw new Error("cloud.runtimeArchiveSha256 accepts only node and bun");
|
|
579
|
+
const result = {};
|
|
580
|
+
for (const runtime of cloudRuntimes) {
|
|
581
|
+
if (!Object.hasOwn(input, runtime)) continue;
|
|
582
|
+
const label = `cloud.runtimeArchiveSha256.${runtime}`;
|
|
583
|
+
const pins = parseArchiveSha256(input[runtime], label);
|
|
584
|
+
if (Object.keys(pins).length !== 1) throw new Error(`${label} pins exactly one release`);
|
|
585
|
+
result[runtime] = pins;
|
|
586
|
+
}
|
|
587
|
+
return result;
|
|
588
|
+
};
|
|
553
589
|
const cloudInstallCommand = "bun install --frozen-lockfile";
|
|
554
590
|
const cloudInstallCommands = [cloudInstallCommand, `${cloudInstallCommand} --ignore-scripts`];
|
|
555
591
|
const cloudInstall = (value) => cloudInstallCommands.some((command) => value === command);
|
|
@@ -578,16 +614,18 @@ const parsePrepare = (input) => {
|
|
|
578
614
|
const parseCloudSetup = (input) => {
|
|
579
615
|
if (input === void 0) return void 0;
|
|
580
616
|
if (typeof input !== "object" || input === null || Array.isArray(input)) throw new Error("cloud must be an object");
|
|
581
|
-
for (const key of Object.keys(input)) if (key !== "services" && key !== "install" && key !== "envFile" && key !== "rust" && key !== "tools" && key !== "prepare" && key !== "submodules") throw new Error(`unsupported cloud key: ${key}`);
|
|
617
|
+
for (const key of Object.keys(input)) if (key !== "services" && key !== "install" && key !== "envFile" && key !== "rust" && key !== "tools" && key !== "prepare" && key !== "submodules" && key !== "runtimeArchiveSha256") throw new Error(`unsupported cloud key: ${key}`);
|
|
582
618
|
const rust = parseRust("rust" in input ? input.rust : void 0);
|
|
583
619
|
const tools = parseTools("tools" in input ? input.tools : void 0);
|
|
584
620
|
const prepare = parsePrepare("prepare" in input ? input.prepare : void 0);
|
|
621
|
+
const runtimeArchiveSha256 = parseRuntimeArchives("runtimeArchiveSha256" in input ? input.runtimeArchiveSha256 : void 0);
|
|
585
622
|
const submodules = "submodules" in input ? input.submodules : false;
|
|
586
623
|
if (typeof submodules !== "boolean") throw new Error("cloud.submodules must be a boolean when provided");
|
|
587
624
|
const extensions = {
|
|
588
625
|
...rust === void 0 ? {} : { rust },
|
|
589
626
|
...tools === void 0 ? {} : { tools },
|
|
590
|
-
...prepare === void 0 ? {} : { prepare }
|
|
627
|
+
...prepare === void 0 ? {} : { prepare },
|
|
628
|
+
...runtimeArchiveSha256 === void 0 ? {} : { runtimeArchiveSha256 }
|
|
591
629
|
};
|
|
592
630
|
const selected = "services" in input ? input.services : [];
|
|
593
631
|
if (!Array.isArray(selected)) throw new Error("cloud.services must be an array when provided");
|
|
@@ -1155,8 +1193,8 @@ BUN_CACHE="/var/cache/stll-cloud/bun/$OUTPUT_UID"
|
|
|
1155
1193
|
[[ "$(awk 'NF { if (++count > 1 || NF != 1) exit 1; value=$1 } END { if (count != 1) exit 1; print value }' "$REPO_ROOT/.node-version")" == "$NODE_VERSION" ]] || fail 'Node selector changed; regenerate cloud-setup.sh'
|
|
1156
1194
|
cd -- "$REPO_ROOT"
|
|
1157
1195
|
case "$(uname -m)" in
|
|
1158
|
-
x86_64) ARCH=amd64; NODE_ARCH=x64; BUN_ARCH=x64 ;;
|
|
1159
|
-
aarch64|arm64) ARCH=arm64; NODE_ARCH=arm64; BUN_ARCH=aarch64 ;;
|
|
1196
|
+
x86_64) ARCH=amd64; NODE_ARCH=x64; BUN_ARCH=x64; NODE_SHA256='@NODE_AMD64_SHA@'; BUN_SHA256='@BUN_AMD64_SHA@' ;;
|
|
1197
|
+
aarch64|arm64) ARCH=arm64; NODE_ARCH=arm64; BUN_ARCH=aarch64; NODE_SHA256='@NODE_ARM64_SHA@'; BUN_SHA256='@BUN_ARM64_SHA@' ;;
|
|
1160
1198
|
*) fail 'Only amd64 and arm64 are supported' ;;
|
|
1161
1199
|
esac
|
|
1162
1200
|
|
|
@@ -1250,6 +1288,7 @@ install_runtimes() (
|
|
|
1250
1288
|
if ! node_ready; then
|
|
1251
1289
|
node_archive="node-v$NODE_VERSION-linux-$NODE_ARCH.tar.xz"
|
|
1252
1290
|
download_file "https://nodejs.org/dist/v$NODE_VERSION/$node_archive" "$scratch/$node_archive" 120
|
|
1291
|
+
(cd "$scratch"; printf '%s %s\n' "$NODE_SHA256" "$node_archive" | sha256sum --strict -c -)
|
|
1253
1292
|
download_file "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt" "$scratch/node-sums" 45
|
|
1254
1293
|
(cd "$scratch"; awk -v name="$node_archive" '$2 == name { print; count++ } END { if (count != 1) exit 1 }' node-sums | sha256sum --strict -c -)
|
|
1255
1294
|
install -d -m 755 "$NODE_DIR"
|
|
@@ -1259,6 +1298,7 @@ install_runtimes() (
|
|
|
1259
1298
|
bun_folder="bun-linux-$BUN_ARCH"
|
|
1260
1299
|
bun_archive="$bun_folder.zip"
|
|
1261
1300
|
download_file "https://github.com/oven-sh/bun/releases/download/bun-v$BUN_VERSION/$bun_archive" "$scratch/$bun_archive" 120
|
|
1301
|
+
(cd "$scratch"; printf '%s %s\n' "$BUN_SHA256" "$bun_archive" | sha256sum --strict -c -)
|
|
1262
1302
|
download_file "https://github.com/oven-sh/bun/releases/download/bun-v$BUN_VERSION/SHASUMS256.txt" "$scratch/bun-sums" 45
|
|
1263
1303
|
(cd "$scratch"; awk -v name="$bun_archive" '$2 == name || $2 == "*" name { print $1 " " name; count++ } END { if (count != 1) exit 1 }' bun-sums | sha256sum --strict -c -)
|
|
1264
1304
|
unzip -q "$scratch/$bun_archive" -d "$scratch/bun"
|
|
@@ -1462,11 +1502,40 @@ const renderPrepare = (prepare, files) => {
|
|
|
1462
1502
|
"}"
|
|
1463
1503
|
].join("\n");
|
|
1464
1504
|
};
|
|
1505
|
+
const runtimeArchiveManifests = {
|
|
1506
|
+
node: (version) => `https://nodejs.org/dist/v${version}/SHASUMS256.txt`,
|
|
1507
|
+
bun: (version) => `https://github.com/oven-sh/bun/releases/download/bun-v${version}/SHASUMS256.txt`
|
|
1508
|
+
};
|
|
1509
|
+
const runtimeArchivePins = ({ runtime, version, shared, declared }) => {
|
|
1510
|
+
const key = `cloud.runtimeArchiveSha256.${runtime}`;
|
|
1511
|
+
const sharedPins = shared[version];
|
|
1512
|
+
if (declared !== void 0) {
|
|
1513
|
+
if (sharedPins !== void 0) throw new Error(`the shared policy pins ${runtime} ${version} archives; remove ${key}`);
|
|
1514
|
+
const pins = declared[version];
|
|
1515
|
+
if (pins === void 0) throw new Error(`${key} pins ${Object.keys(declared).join(", ")}, but the repository selects ${runtime} ${version}; update it with the amd64 and arm64 values from ${runtimeArchiveManifests[runtime](version)}`);
|
|
1516
|
+
return pins;
|
|
1517
|
+
}
|
|
1518
|
+
if (sharedPins === void 0) throw new Error(`the shared policy has no ${runtime} ${version} archive SHA256 pins; declare ${key} for ${version} with the amd64 and arm64 values from ${runtimeArchiveManifests[runtime](version)}`);
|
|
1519
|
+
return sharedPins;
|
|
1520
|
+
};
|
|
1465
1521
|
const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExceptions = [] }) => {
|
|
1466
1522
|
const selected = parseCloudSetup(cloud);
|
|
1467
1523
|
if (selected === void 0) throw new Error("cloud declaration is required");
|
|
1468
1524
|
const exactNode = nodeVersion.trim();
|
|
1469
1525
|
if ((0, semver.valid)(exactNode) !== exactNode || !nodeSelectorMatches(exactNode, policy.node)) throw new Error("cloud requires a tracked exact .node-version within the shared Node series");
|
|
1526
|
+
const bunVersion = policy.bun;
|
|
1527
|
+
const nodeArchiveSha256 = runtimeArchivePins({
|
|
1528
|
+
runtime: "node",
|
|
1529
|
+
version: exactNode,
|
|
1530
|
+
shared: policy.nodeArchiveSha256,
|
|
1531
|
+
declared: selected.runtimeArchiveSha256?.node
|
|
1532
|
+
});
|
|
1533
|
+
const bunArchiveSha256 = runtimeArchivePins({
|
|
1534
|
+
runtime: "bun",
|
|
1535
|
+
version: bunVersion,
|
|
1536
|
+
shared: policy.bunArchiveSha256,
|
|
1537
|
+
declared: selected.runtimeArchiveSha256?.bun
|
|
1538
|
+
});
|
|
1470
1539
|
const toolchains = resolveCloudToolchains({
|
|
1471
1540
|
cloud: selected,
|
|
1472
1541
|
files,
|
|
@@ -1479,7 +1548,7 @@ const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExcept
|
|
|
1479
1548
|
["@NETWORK@", renderCloudNetwork()],
|
|
1480
1549
|
["@TOOL_INSTALL@", renderCloudToolInstall(toolchains) + renderCloudShellInstall({
|
|
1481
1550
|
nodeVersion: exactNode,
|
|
1482
|
-
bunVersion
|
|
1551
|
+
bunVersion,
|
|
1483
1552
|
rust: toolchains.rust
|
|
1484
1553
|
})],
|
|
1485
1554
|
["@INPUT_VALIDATION@", ["rust-toolchain.toml", "rust-toolchain"].flatMap((file) => {
|
|
@@ -1488,8 +1557,12 @@ const generateCloudSetup = ({ policy, cloud, nodeVersion, files = {}, rustExcept
|
|
|
1488
1557
|
const hash = (0, node_crypto.createHash)("sha256").update(content).digest("hex");
|
|
1489
1558
|
return [`[[ -f ${shellQuote(file)} && ! -L ${shellQuote(file)} ]] && [[ "$(sha256sum -- ${shellQuote(file)} | cut -d ' ' -f1)" == ${shellQuote(hash)} ]] || fail ${shellQuote(`${file} changed; regenerate cloud-setup.sh`)}`];
|
|
1490
1559
|
}).concat(selected.tools?.["wasm-bindgen-cli"] === void 0 ? [] : [renderWasmBindgenLockValidation(selected.tools["wasm-bindgen-cli"])]).join("\n")],
|
|
1491
|
-
["@BUN@",
|
|
1560
|
+
["@BUN@", bunVersion],
|
|
1492
1561
|
["@NODE@", exactNode],
|
|
1562
|
+
["@NODE_AMD64_SHA@", nodeArchiveSha256.amd64],
|
|
1563
|
+
["@NODE_ARM64_SHA@", nodeArchiveSha256.arm64],
|
|
1564
|
+
["@BUN_AMD64_SHA@", bunArchiveSha256.amd64],
|
|
1565
|
+
["@BUN_ARM64_SHA@", bunArchiveSha256.arm64],
|
|
1493
1566
|
["@ENV_ASSIGNMENTS@", selected.envFile === void 0 ? "" : `ENV_FILE=${shellQuote(selected.envFile)}\nENV_MARKER=${shellQuote(cloudEnvironmentMarker)}`],
|
|
1494
1567
|
["@ENV_FUNCTIONS@", selected.envFile === void 0 ? "" : environmentFunctions],
|
|
1495
1568
|
["@ENVIRONMENT_VALUES@", selected.services.length === 0 ? "" : environmentValuesFunction],
|
|
@@ -2095,6 +2168,12 @@ Object.defineProperty(exports, "nodeSupportRangeMatches", {
|
|
|
2095
2168
|
return nodeSupportRangeMatches;
|
|
2096
2169
|
}
|
|
2097
2170
|
});
|
|
2171
|
+
Object.defineProperty(exports, "parseArchiveSha256", {
|
|
2172
|
+
enumerable: true,
|
|
2173
|
+
get: function() {
|
|
2174
|
+
return parseArchiveSha256;
|
|
2175
|
+
}
|
|
2176
|
+
});
|
|
2098
2177
|
Object.defineProperty(exports, "parseCloudSetup", {
|
|
2099
2178
|
enumerable: true,
|
|
2100
2179
|
get: function() {
|