Compare commits
1
Commits
v1.3.0
...
228b66164f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
228b66164f |
@@ -71,6 +71,7 @@ Peer-конфликт решай совместимыми версиями бе
|
||||
| Итерация | Адресные тесты, typecheck и lint по затронутому поведению и риску. При изменении поведения добавь/обнови содержательную регрессию, если существующая проверка не ловит её; для косметики не создавай искусственный тест. |
|
||||
| Итоговый code/dependency diff | Перед объявлением готовности и передачей к интеграции выполни один полный `npm run verify` на итоговых входах. Дополнительные risk checks из testing convention и явно утверждённые task checks обязательны; CI проверяет независимо. |
|
||||
| Только Markdown | Проверь тексты, ссылки/якоря, маршруты чтения и `git diff --check`; application build не нужен. При изменении verification-контура проверь его работу. |
|
||||
| Pre-commit | Hook не скачивает tools: вызывай установленные бинарники из `node_modules/.bin` (не `npx`). Full graph не входит в hook; он выполняется в `npm run verify` и CI. |
|
||||
|
||||
Повтори routing по staged/unstaged/new files. В отчёте по задаче/PR запиши
|
||||
проверенные входы, команду, exit code, результат и ограничения. Повторяй
|
||||
|
||||
+5
-2
@@ -1,3 +1,6 @@
|
||||
gitleaks git --pre-commit --staged --redact=100 --no-banner || exit $?
|
||||
npx lint-staged
|
||||
npm run deps
|
||||
if [ ! -x node_modules/.bin/lint-staged ]; then
|
||||
echo "lint-staged is not installed; run npm ci" >&2
|
||||
exit 1
|
||||
fi
|
||||
node_modules/.bin/lint-staged
|
||||
|
||||
@@ -19,8 +19,10 @@ npm run dev
|
||||
|
||||
Для commits установите [Gitleaks](https://github.com/gitleaks/gitleaks/releases/tag/v8.30.1)
|
||||
8.30.1 в `PATH` (macOS: `brew install gitleaks`). Pre-commit сначала проверяет
|
||||
staged diff с полной редакцией секретов, затем запускает formatting и FSD checks.
|
||||
Находка или отсутствие Gitleaks блокирует commit.
|
||||
staged diff с полной редакцией секретов, затем запускает установленный
|
||||
`node_modules/.bin/lint-staged` только для staged JS/TS. Hook не скачивает tools и
|
||||
не запускает full graph: полный `npm run verify` выполняется в CI и перед передачей.
|
||||
Находка или отсутствие Gitleaks либо lint-staged блокирует commit.
|
||||
Проверка этого поведения: `node --test scripts/test-pre-commit.mjs`.
|
||||
|
||||
## Контейнерный image
|
||||
|
||||
@@ -47,6 +47,12 @@ test("pre-commit scans the index, redacts findings and fails closed", () => {
|
||||
}
|
||||
|
||||
git("init", "--quiet");
|
||||
// The hook must run the installed lint-staged binary, never download one.
|
||||
const localBin = nodePath.join(cwd, "node_modules", ".bin");
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is built from this check’s private mkdtemp directory and fixed filenames.
|
||||
mkdirSync(localBin, { recursive: true });
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is built from this check’s private mkdtemp directory and fixed filenames.
|
||||
writeFileSync(nodePath.join(localBin, "lint-staged"), "#!/bin/sh\necho ran >> downstream\n", { mode: 0o755 });
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is built from this check’s private mkdtemp directory and fixed filenames.
|
||||
writeFileSync(nodePath.join(cwd, "sample.txt"), "safe staged content\n");
|
||||
git("add", "sample.txt");
|
||||
@@ -77,3 +83,37 @@ test("pre-commit scans the index, redacts findings and fails closed", () => {
|
||||
rmSync(cwd, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("pre-commit never downloads tools and blocks when lint-staged is missing", () => {
|
||||
const hook = nodePath.resolve(".husky/pre-commit");
|
||||
const cwd = mkdtempSync(nodePath.join(tmpdir(), "frontend-hook-"));
|
||||
const bin = nodePath.join(cwd, "bin");
|
||||
const marker = nodePath.join(cwd, "downstream");
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is built from this check’s private mkdtemp directory and fixed filenames.
|
||||
mkdirSync(bin);
|
||||
// Gitleaks passes; npx/npm must never be reached, even if present on PATH.
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is built from this check’s private mkdtemp directory and fixed filenames.
|
||||
writeFileSync(nodePath.join(bin, "gitleaks"), "#!/bin/sh\nexit 0\n", { mode: 0o755 });
|
||||
|
||||
for (const command of ["npx", "npm"]) {
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is built from this check’s private mkdtemp directory and fixed filenames.
|
||||
writeFileSync(nodePath.join(bin, command), "#!/bin/sh\necho ran >> downstream\n", { mode: 0o755 });
|
||||
}
|
||||
|
||||
const result = spawnSync("/bin/sh", ["-e", hook], {
|
||||
cwd,
|
||||
encoding: "utf8",
|
||||
env: { ...process.env, PATH: `${bin}${nodePath.delimiter}${process.env.PATH}` },
|
||||
});
|
||||
|
||||
assert.notEqual(result.status, 0, "missing lint-staged must block commit");
|
||||
assert.match(result.stderr, /lint-staged is not installed/);
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Path is built from this check’s private mkdtemp directory and fixed filenames.
|
||||
assert.ok(!existsSync(marker), "hook must not invoke npx or npm");
|
||||
}
|
||||
finally {
|
||||
rmSync(cwd, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user