refactor: derive the release identity from the package name
The supply-chain builder id and the two verifier ids each hardcoded the
repository name, in three source files plus a copy in the test fixture.
A project derived from this template had to edit all four, and all four
then became permanent conflict points for every merge back from here.
They now read the `name` this repository already declares in
package.json, so deriving a project is one line. The name is read once
at module load from a URL relative to the module itself, not from the
working directory, because these ids end up in signed provenance and
must not depend on where a script was invoked from. A missing or empty
name throws rather than falling back, for the same reason.
The value is hosted in scripts/lib/supply-chain.ts because all three
consumers already import it and it is already registered in
LOCAL_EVIDENCE_VERIFIER_SOURCE_PATHS. A new module would have needed to
join that list, which is itself part of the evidence surface.
This repository's own name is unchanged, so every emitted id is
byte-identical to before.
Also registers the three adapter files that 5cc4146 added without
updating the inventory ledger, which had left check:adapter-inventory
failing on develop.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8dd7cbaea3
commit
ebea300e4f
@@ -65,6 +65,7 @@ import { secretScanRules } from "./secret-scan.ts";
|
||||
import {
|
||||
isValidSha512Integrity,
|
||||
parsePnpmLockfilePackages,
|
||||
PROJECT_NAME,
|
||||
supplyChainDigest,
|
||||
verifySupplyChainCoherence,
|
||||
} from "./supply-chain.ts";
|
||||
@@ -303,8 +304,7 @@ export async function verifyLocalSupplyChainEvidence(
|
||||
});
|
||||
}
|
||||
|
||||
export const LOCAL_EVIDENCE_VERIFIER_ID =
|
||||
"clean-architecture-frontend-template/local-evidence-verifier";
|
||||
export const LOCAL_EVIDENCE_VERIFIER_ID = `${PROJECT_NAME}/local-evidence-verifier`;
|
||||
export const LOCAL_EVIDENCE_VERIFIER_VERSION = "1";
|
||||
export {
|
||||
LOCAL_EVIDENCE_POLICY_INPUT_PATHS,
|
||||
|
||||
@@ -4,13 +4,13 @@ import { z } from "zod";
|
||||
|
||||
import {
|
||||
canonicalizeSupplyChainValue,
|
||||
PROJECT_NAME,
|
||||
supplyChainDigest,
|
||||
} from "./supply-chain.ts";
|
||||
|
||||
export const PROVIDER_FUTURE_SKEW_MS = 5 * 60 * 1_000;
|
||||
export const PROVIDER_MAX_LIFETIME_MS = 2 * 60 * 60 * 1_000;
|
||||
export const PROMOTION_VERIFIER_ID =
|
||||
"clean-architecture-frontend-template/promotion-verifier";
|
||||
export const PROMOTION_VERIFIER_ID = `${PROJECT_NAME}/promotion-verifier`;
|
||||
export const PROMOTION_VERIFIER_VERSION = "3";
|
||||
|
||||
const sha256 = z.string().regex(/^[a-f0-9]{64}$/u);
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { readFile } from "node:fs/promises";
|
||||
|
||||
function readProjectName(): string {
|
||||
const manifest: unknown = JSON.parse(
|
||||
readFileSync(new URL("../../package.json", import.meta.url), "utf8"),
|
||||
);
|
||||
const name =
|
||||
typeof manifest === "object" && manifest !== null
|
||||
? (manifest as { name?: unknown }).name
|
||||
: undefined;
|
||||
if (typeof name !== "string" || name.length === 0) {
|
||||
throw new TypeError("package.json must declare a non-empty \"name\"");
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identity every release artifact is attributed to. A project derived from this
|
||||
* template renames itself by editing `name` in package.json and nothing else.
|
||||
*/
|
||||
export const PROJECT_NAME = readProjectName();
|
||||
|
||||
export type DependencyScope = "production" | "development";
|
||||
export type LockfilePackage = Readonly<{
|
||||
name: string;
|
||||
|
||||
Reference in New Issue
Block a user