diff --git a/.githooks/pre-commit b/.githooks/pre-commit index edeb19b..d1ad62b 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -1,3 +1,3 @@ #!/usr/bin/env sh set -eu -bun run check +pnpm run check diff --git a/.githooks/pre-push b/.githooks/pre-push index edeb19b..d1ad62b 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -1,3 +1,3 @@ #!/usr/bin/env sh set -eu -bun run check +pnpm run check diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 7ed1e1a..eab16d3 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -19,10 +19,11 @@ jobs: with: version: "3.97.1" extra_args: --results=verified,unknown - - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 + - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4 with: - bun-version: 1.3.14 - - run: bun install --frozen-lockfile - - run: bun run check + version: 12.4.1 + - run: pnpm install --config.lockfile=false + - run: pnpm run check + - run: pnpm run test:package-manager - name: Actionlint uses: raven-actions/actionlint@3d39aea434753780c3b3d4a1a31c854b4dbf49d7 # v2 diff --git a/README.md b/README.md index 0fe78de..f9e8a3f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ boundary and delegates installer integrity verification to `cortex/desktop/scripts/verify-release-channel.mjs`. This repository does not build, sign, publish, or re-verify installer bytes. -Run `bun run check` before pushing channel-governance changes. Installation -also configures the repository-owned pre-commit and pre-push hooks. The +Run `pnpm --config.lockfile=false install` and `pnpm run check` before pushing +channel-governance changes. Installation also configures the repository-owned +pre-commit and pre-push hooks. The repository has no third-party package dependencies, so dependency audit is not applicable; CI instead runs the channel contract, secret scan, and Actionlint. diff --git a/package.json b/package.json index 2424c2c..0016b14 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,9 @@ "private": true, "scripts": { "check:channel": "node scripts/check-channel-contract.mjs", - "check": "bun run check:channel", + "check": "pnpm run check:channel", + "test:package-manager": "node scripts/check-pnpm-no-lock.mjs", "prepare": "git config core.hooksPath .githooks" }, - "packageManager": "bun@1.3.14" + "packageManager": "pnpm@12.4.1" } diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..d3e8e5b --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1 @@ +lockfile: false diff --git a/release-channel.json b/release-channel.json index 12476a2..e231a6a 100644 --- a/release-channel.json +++ b/release-channel.json @@ -14,6 +14,6 @@ "verification": { "repository": "makekosmos/cortex", "path": "desktop/scripts/verify-release-channel.mjs", - "command": "bun desktop/scripts/verify-release-channel.mjs" + "command": "pnpm exec node desktop/scripts/verify-release-channel.mjs" } } diff --git a/scripts/check-channel-contract.mjs b/scripts/check-channel-contract.mjs index 8bfe94b..2457506 100644 --- a/scripts/check-channel-contract.mjs +++ b/scripts/check-channel-contract.mjs @@ -20,7 +20,7 @@ assert.deepEqual(manifest, { verification: { repository: "makekosmos/cortex", path: "desktop/scripts/verify-release-channel.mjs", - command: "bun desktop/scripts/verify-release-channel.mjs", + command: "pnpm exec node desktop/scripts/verify-release-channel.mjs", }, }); @@ -32,7 +32,7 @@ for (const marker of [ "Release unit: one Kosmos Desktop release", "does not accept product source", "cortex/desktop/scripts/verify-release-channel.mjs", - "bun run check", + "pnpm run check", ]) { assert.ok(readme.includes(marker), `README is missing: ${marker}`); } diff --git a/scripts/check-pnpm-no-lock.mjs b/scripts/check-pnpm-no-lock.mjs new file mode 100644 index 0000000..0d4f73f --- /dev/null +++ b/scripts/check-pnpm-no-lock.mjs @@ -0,0 +1,26 @@ +import { execFileSync } from "node:child_process"; +import { existsSync, readFileSync } from "node:fs"; + +const pnpm = process.platform === "win32" ? process.env.ComSpec ?? "cmd.exe" : "pnpm"; +const pnpmArgs = (args) => + process.platform === "win32" ? ["/d", "/s", "/c", "pnpm.cmd", ...args] : args; + +execFileSync(pnpm, pnpmArgs(["--config.lockfile=false", "install", "--ignore-scripts"]), { + stdio: "inherit", +}); +execFileSync(pnpm, pnpmArgs(["--config.lockfile=false", "run", "check"]), { + stdio: "inherit", +}); + +if (existsSync("pnpm-lock.yaml")) { + throw new Error("No-lock policy failed: pnpm-lock.yaml was created"); +} + +for (const hook of [".githooks/pre-commit", ".githooks/pre-push"]) { + const contents = readFileSync(hook, "utf8"); + if (!contents.includes("pnpm run check") || /\bbun\b/i.test(contents)) { + throw new Error(`Hook policy failed: ${hook} must invoke pnpm run check`); + } +} + +console.log("pnpm no-lock policy passed");