diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 57c5edf..c894bc1 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -3,7 +3,7 @@ set -eu changed="$(git diff --cached --name-only --diff-filter=ACMR)" case "$changed" in - *catalog.json*|*catalog.envelope.json*|*scripts/*|*.github/workflows/*) + *catalog.json*|*catalog.envelope.json*|*scripts/*|*.github/workflows/*|*.githooks/*|*README.md*|*package.json*) node scripts/validate-catalog.mjs node --test scripts/validate-catalog.test.mjs scripts/check-release-sequence.test.mjs ;; diff --git a/.githooks/pre-push b/.githooks/pre-push new file mode 100755 index 0000000..4d1e579 --- /dev/null +++ b/.githooks/pre-push @@ -0,0 +1,3 @@ +#!/bin/sh +set -eu +bun run check diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index e9f0df0..0fa116a 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -6,7 +6,10 @@ on: - "catalog.json" - "catalog.envelope.json" - "scripts/**" + - ".githooks/**" - ".github/workflows/**" + - "README.md" + - "package.json" push: branches: [main] @@ -22,15 +25,19 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - - name: Validate catalog without secrets - run: node scripts/validate-catalog.mjs --strict-envelope - - name: Validate catalog fixtures - run: node --test scripts/validate-catalog.test.mjs - - name: Run ephemeral signing dry-run - run: node scripts/dry-run.mjs + with: + fetch-depth: 0 + - name: Secret scan + uses: trufflesecurity/trufflehog@20652fbbdefffcdaa493a5bf57ab2ac6b1db715b # v3.97.1 + with: + version: "3.97.1" + extra_args: --results=verified,unknown + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 + with: + bun-version: 1.3.14 + - name: Install dependencies and hooks + run: bun install --frozen-lockfile + - name: Run aggregate verification + run: bun run check - name: Check Actions syntax uses: raven-actions/actionlint@3d39aea434753780c3b3d4a1a31c854b4dbf49d7 # v2 - - name: Check signing script syntax - run: node --check scripts/sign-catalog.mjs - - name: Check release preflight script syntax - run: node --check scripts/check-release-sequence.mjs diff --git a/README.md b/README.md index c313ae4..bddd034 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,7 @@ references/cycles, and the committed envelope signature without accessing `STORE_SIGNING_KEY`: ```powershell -node scripts/validate-catalog.mjs -node --test scripts/validate-catalog.test.mjs +bun run check ``` The dry-run path exercises ephemeral Ed25519 signing without publishing or @@ -46,14 +45,12 @@ node scripts/dry-run.mjs The dry-run creates an in-memory ephemeral Ed25519 key, validates the complete catalog and envelope, and never writes a release or uses `STORE_SIGNING_KEY`. -For a lightweight local pre-commit check, opt into the repository hook once: - -```powershell -git config core.hooksPath .githooks -``` - -The hook only runs when catalog, workflow, or validation scripts are staged; -CI remains authoritative. +`bun install --frozen-lockfile` installs the repository hooks automatically. +Pre-commit validates staged catalog, workflow, hook, documentation, and toolchain +metadata changes; pre-push and CI run the aggregate `bun run check` contract. +Store has no runtime or development dependencies, so Bun intentionally omits an +empty lockfile and dependency audit is not applicable. Frozen install, signature, +provenance, secret scan, and immutable-release gates remain required. After signing, publication operators require the envelope payload to match the catalog bytes with: diff --git a/package.json b/package.json new file mode 100644 index 0000000..654158b --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "@makekosmos/store", + "version": "0.0.0", + "private": true, + "type": "module", + "packageManager": "bun@1.3.14", + "scripts": { + "prepare": "node scripts/install-hooks.mjs", + "test": "node --test scripts/*.test.mjs", + "check:signature": "node scripts/validate-catalog.mjs --strict-envelope && bun run test && node scripts/dry-run.mjs && node --check scripts/sign-catalog.mjs && node --check scripts/check-release-sequence.mjs", + "check": "bun run check:signature" + } +} diff --git a/scripts/install-hooks.mjs b/scripts/install-hooks.mjs new file mode 100644 index 0000000..d2eaa54 --- /dev/null +++ b/scripts/install-hooks.mjs @@ -0,0 +1,10 @@ +#!/usr/bin/env node +import { execFileSync } from "node:child_process"; + +try { + execFileSync("git", ["rev-parse", "--show-toplevel"], { stdio: "ignore" }); + execFileSync("git", ["config", "--local", "core.hooksPath", ".githooks"]); + console.log("Installed Store hooks."); +} catch { + console.log("Git hooks skipped: not inside a checkout."); +}