Skip to content

feat: add lefthook pre-commit hooks with gitleaks secret scanning - #2019

Merged
Oluwapizzy merged 5 commits into
bcgov:mainfrom
panish16:feat/git-hooks-gitleaks
Sep 29, 2026
Merged

Oluwapizzy merged 5 commits into
bcgov:mainfrom
panish16:feat/git-hooks-gitleaks

Conversation

@panish16

@panish16 panish16 commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Part of the Git Hooks RFC rollout (bcgov/entity#34619). Now unblocked - the hold on namex changes (pending the solr migration) was lifted 2026-09-14.

No root package.json existed, so this adds a minimal hooks-only one, matching the approach used on bcgov/ppr#2364 (also a repo with no root package.json).

Scoped to secret scanning only - bare npx gitleaks-secret-scanner, no custom install script, matching the pattern now live on bcregistry/connect/ppr. This repo has 16 separately-versioned services (api, jobs, solr-admin-app, solr-feeder, solr-synonyms-api, etc.), each with its own CI-enforced lint already. Intentionally not attempting to replicate per-service lint wiring the way ppr's pilot did for its 3 services - that's a much larger, separate effort if wanted later.

prepare checks for git directly rather than swallowing a failure or relying on CI=true:

"prepare": "git --version && lefthook install || exit 0"

lefthook has no purpose in a non-interactive build, so it shouldn't attempt to run there at all - not just fail-safe. An earlier version of this checked CI=true, but that's not a safe assumption across CI systems: confirmed on bcgov/bcregistry#282 that Google Cloud Build doesn't set CI=true, so that check would have silently stayed broken there despite looking correct. Checking for git's actual presence avoids depending on any CI provider's conventions.

Note: unlike bcregistry, this repo has no CI job that installs at the repo root, so I can't prove this specific change through a real pipeline run the way #282 was verified. The logic itself is the same, just flagging that this one doesn't have the same live-fire confirmation.

Verified locally with real git commit: hook installs when git is present, and a fake secret gets caught and blocks the commit whether it's at repo root or nested under a subfolder like api/.

Update: Windows fix

The original command -v git >/dev/null 2>&1 && lefthook install || true guard silently did nothing on Windows. pnpm/npm run lifecycle scripts through cmd.exe there by default, command -v and /dev/null don't exist, and the failure fell through to || true, so the install exited 0 but no hook was installed. Windows devs would have had no secret scanning and no error telling them so.

Replaced with:

"prepare": "git --version && lefthook install || exit 0"

Same semantics (skip entirely when git is absent, never fail the install), works in both cmd.exe and POSIX sh. Verified all four combinations (cmd.exe / sh, git present / absent), plus a real git commit with a fake token on Windows is blocked.

Update: build approval moved to pnpm-workspace.yaml

The pnpm.onlyBuiltDependencies field in package.json is ignored by pnpm v11, so a root pnpm install failed with ERR_PNPM_IGNORED_BUILDS for anyone on default build-script approval (the hook still installed, but the install exited 1). Moved it to pnpm-workspace.yaml as allowBuilds: lefthook: false and added the lockfile. Re-tested with default approval: install exits 0, hook installed, fake token blocked.

panish16 and others added 4 commits September 28, 2026 17:04
Part of the Git Hooks RFC rollout (bcgov/entity#34619). No root
package.json existed, so this adds a minimal hooks-only one, matching
the approach used on bcgov/ppr#2364.

Scoped to secret scanning only (bare 'npx gitleaks-secret-scanner',
no custom install script, matching bcregistry/connect/ppr) - this repo
has 16 separately-versioned services each with their own CI-enforced
lint, so this intentionally doesn't attempt to replicate per-service
lint wiring the way ppr's pilot did; that's a separate, larger effort
if wanted later.

prepare is guarded with '|| exit 0' from the start, learned from
bcgov/bcregistry#281 breaking CD after merging this same base setup
unguarded.
lefthook's own npm postinstall already skips itself under CI=true by
default (only installs if LEFTHOOK=1/true is explicitly set - see
https://lefthook.dev/usage/envs/LEFTHOOK.html). Our prepare script
called 'lefthook install' directly though, which bypasses that and
always runs - that's what broke bcgov/bcregistry#281's CD build (no
git in the image).

'|| exit 0' (the fix used on bcregistry/ppr) stops the failure from
crashing the install, but still attempts the install in CI every
time. This skips it outright when CI is set, since hooks have no
purpose in a non-interactive build anyway.
CI=true isn't a safe assumption across CI systems - confirmed on
bcgov/bcregistry#282 that Google Cloud Build doesn't set it at all,
so that version of this guard would have silently kept failing there
despite looking correct. Checking for git's actual presence instead
doesn't depend on any CI provider's conventions.
pnpm/npm run lifecycle scripts through cmd.exe on Windows by default,
where `command -v` and `/dev/null` do not exist. The previous guard
errored and fell through to `|| true`, exiting 0 without installing
the hook, so Windows developers silently got no secret scanning.

`git --version && lefthook install || exit 0` has the same semantics
(skip entirely when git is absent, never fail the install) and works
in both cmd.exe and POSIX sh.
pnpm v11 no longer reads the package.json `pnpm` field, so
onlyBuiltDependencies was ignored and a root `pnpm install` failed with
ERR_PNPM_IGNORED_BUILDS for anyone on default build-script approval.
Disable lefthook's own postinstall via allowBuilds instead (prepare
already installs the hook), and commit the lockfile.
@sonarqubecloud

Copy link
Copy Markdown

@Oluwapizzy
Oluwapizzy merged commit 4ccebfa into bcgov:main Sep 29, 2026
3 checks passed
pwei1018 pushed a commit to pwei1018/bcregistry that referenced this pull request Oct 7, 2026
lefthook's own npm postinstall already skips itself under CI=true by
default (only installs if LEFTHOOK=1/true is explicitly set). Our
prepare script called 'lefthook install' directly, which bypasses
that and always runs regardless of environment.

'|| exit 0' stopped the crash but still attempted the install in CI
every time. This skips it outright, since hooks have no purpose in a
non-interactive build. Same fix already applied on bcgov/namex#2019.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants