|
1 | | -# Husky Pre-Commit Hooks Documentation |
| 1 | +--- |
| 2 | +title: "Husky Pre-commit Hooks" |
| 3 | +description: "Using Husky to enforce quality gates (linting/tests) before commits" |
| 4 | +last_updated: "2025-11-14" |
| 5 | +version: "1.0" |
| 6 | +maintainers: ["LightSpeed DevOps"] |
| 7 | +tags: ["husky", "pre-commit", "automation", "linting"] |
| 8 | +--- |
2 | 9 |
|
3 | | -This document explains the Husky pre-commit setup, usage, and best practices for this repository. It is designed to be used alongside [LINTING.md](./LINTING.md), which details the linting tools and configuration. |
| 10 | +# Husky Pre-commit Hooks |
4 | 11 |
|
5 | | ---- |
| 12 | +**`docs/HUSKY-PRECOMMITS.md`** – *Pre-commit Hook as Quality Gate* |
6 | 13 |
|
7 | | -## Linting & Quality Checks |
| 14 | +We use **Husky** to run linting and formatting checks locally before code is committed, serving as a "first line" quality gate. This ensures that by the time code reaches CI, it has already passed basic standards. |
8 | 15 |
|
9 | | -Husky is tightly integrated with our linting workflow. For a full list of linting tools, configuration files, and what is checked before each commit, see [LINTING.md](./LINTING.md). This ensures that all code meets our standards before it is committed. |
| 16 | +## Status and Rationale |
10 | 17 |
|
11 | | ---- |
| 18 | +**Status:** *Implemented in develop (pending merge to main).* Previously, Husky was not set up in this repo, meaning developers could commit code that failed our style/test checks. We've now added a Husky *pre-commit* hook to mirror the checks that run in CI, closing this gap. |
| 19 | + |
| 20 | +**Why Husky:** Running checks locally speeds up feedback. It prevents "easy" issues (like code style or obvious test failures) from ever reaching the repo, which reduces CI failures and iteration time. This aligns with our goal that *"files are linted properly and tests pass"* before pushing. |
| 21 | + |
| 22 | +## Installation |
12 | 23 |
|
13 | | -## Overview |
| 24 | +Husky is managed as a dev dependency. To install and enable Husky in a fresh clone: |
14 | 25 |
|
15 | | -Husky is used to enforce code quality and consistency by running automated checks (such as linting and tests) before code is committed. This helps prevent errors and maintain standards across the codebase. |
| 26 | +1. After running `npm install` (or `npm ci`), activate Husky hooks: |
16 | 27 |
|
17 | | -## .husky Folder Structure |
| 28 | +```bash |
| 29 | +npx husky install |
| 30 | +``` |
| 31 | + |
| 32 | +This installs Git hooks into the local repo's `.husky/` directory (already present in source). |
| 33 | + |
| 34 | +2. Verify that a `.husky/pre-commit` file exists with our hook. It should have been created in the repo (or by the install command). |
18 | 35 |
|
19 | | -- `.husky/` — Contains all Husky hook scripts |
20 | | - - `pre-commit` — Main pre-commit hook script (runs linting, tests, etc.) |
21 | | - - `commit-msg` — Validates commit message format (if present) |
22 | | - - Other hooks as needed (e.g., `pre-push`) |
| 36 | +If Husky isn't working, ensure Git isn't bypassing hooks (no `--no-verify` flag used) and that you have the correct Node version. We specify Node version in `.nvmrc` to avoid incompatibilities (our CI uses the same Node version). |
23 | 37 |
|
24 | | -## How Pre-Commit Works |
| 38 | +## Pre-commit Hook Behavior |
25 | 39 |
|
26 | | -When you run `git commit`, Husky automatically executes the scripts in `.husky/pre-commit` before the commit is finalized. If any check fails, the commit is aborted. |
| 40 | +Our pre-commit hook is defined in **`.husky/pre-commit`**. It runs our formatting and linting checks before allowing a commit. In summary, it will: |
27 | 41 |
|
28 | | -## Bypassing Pre-Commit Hooks |
| 42 | +- **Format code** (auto-fix) by running **`npm run format`**. |
| 43 | +- **Run linters and tests** by running **`npm run check`** (a composite script that runs all linters and unit tests). |
29 | 44 |
|
30 | | -To bypass Husky pre-commit hooks (not recommended except for emergencies): |
| 45 | +If *either* of those steps fails, the commit is aborted. You must fix the issues and try again. This prevents committing code that would fail CI. |
31 | 46 |
|
32 | | -```sh |
33 | | -git commit --no-verify |
| 47 | +Below is the content of our `.husky/pre-commit` file for reference: |
| 48 | + |
| 49 | +```bash |
| 50 | +#!/bin/sh |
| 51 | +. "$(dirname "$0")/_/husky.sh" |
| 52 | + |
| 53 | +npm run format && npm run check |
34 | 54 | ``` |
35 | 55 |
|
36 | | -> **Note:** Use this only if you have a valid reason. All skipped checks must be run manually before pushing. |
| 56 | +This uses Husky's shell script shim and then runs our tasks. The `&&` ensures that if formatting fails or leaves changes, or if any check fails, the process halts with a non-zero exit (blocking the commit). |
37 | 57 |
|
38 | | -## Suppression Storage & Management |
| 58 | +## Adding Husky to an Existing Clone |
39 | 59 |
|
40 | | -- Husky does not store suppressions by default. If you bypass a hook, it is not recorded. |
41 | | -- If you want to re-enable hooks, simply commit as normal (without `--no-verify`). |
42 | | -- To update or remove a hook, edit or delete the relevant script in `.husky/`. |
| 60 | +If you already have the repo and just pulled the updated config, run `npm install` (to get Husky) and then `npx husky install` to set up the hooks. This is a one-time step per clone. After that, Git will trigger the hook on commits automatically. |
43 | 61 |
|
44 | | -## Recommended Commands |
| 62 | +## Ignoring Specific Files or Bypassing |
45 | 63 |
|
46 | | -- **Install Husky hooks:** |
| 64 | +Our goal is to run the hook on all source changes. However, large binary files or documentation-only changes shouldn't block a commit on lint rules: |
47 | 65 |
|
48 | | - ```sh |
49 | | - npx husky install |
| 66 | +- Husky will only lint the files you're committing (through our `npm run ...` scripts configuration). For instance, if you edit only Markdown, JS lint won't run, etc. |
| 67 | +- If absolutely necessary (e.g. an urgent hotfix), you can bypass hooks with `git commit --no-verify`. **Use this sparingly.** Bypassing means CI will catch any issues later. |
50 | 68 |
|
51 | | - ``` |
| 69 | +We intentionally do not run lengthy end-to-end tests on pre-commit (those run in CI), to keep commits fast. The pre-commit focuses on quick checks (formatting, linters, unit tests). This strikes a balance between safety and speed. |
52 | 70 |
|
53 | | -- **Add a new hook:** |
| 71 | +## CI Integration |
54 | 72 |
|
55 | | - ```sh |
56 | | - npx husky add .husky/pre-commit "npm run lint:js && npm run lint:css && npm run lint:md && npm test" |
| 73 | +The pre-commit hook runs the same `npm run check` that CI does. In our GitHub Actions CI, we also execute the full test suite on push. The idea is "fail fast, locally": |
57 | 74 |
|
58 | | - ``` |
| 75 | +- By the time CI runs, code should already be formatted and pass linting. CI then mainly validates integration (and runs heavier tests). |
| 76 | +- If a contributor bypasses Husky (or Husky wasn't installed), the CI will still fail on the same `npm run check` script in our workflow, acting as a safety net. |
59 | 77 |
|
60 | | -- **Bypass hooks:** |
| 78 | +Having duplicate checks may seem redundant, but it's intentional. It virtually eliminates trivial CI failures (saving time) and acts as a double-insurance policy. |
61 | 79 |
|
62 | | - ```sh |
63 | | - git commit --no-verify |
64 | | - ``` |
| 80 | +## Setup Commands (for reference) |
65 | 81 |
|
66 | | -## Getting Started |
| 82 | +For maintainers, these were the steps used to set up Husky in this repo: |
67 | 83 |
|
68 | | -1. Run `npm install` to install dependencies (including Husky). |
69 | | -2. Run `npx husky install` to set up hooks (usually done automatically on install). |
70 | | -3. Commit as usual — Husky will run checks before each commit. |
| 84 | +```bash |
| 85 | +npm install --save-dev husky # Add Husky to devDependencies |
| 86 | +npx husky install # Install Git hooks (creates .husky/ folder) |
| 87 | +npx husky add .husky/pre-commit "npm run format && npm run check" |
| 88 | +``` |
71 | 89 |
|
72 | | -## Best Practices |
| 90 | +This added the pre-commit file with the content shown above. Our `package.json` already had the necessary `format` and `check` scripts defined (mapping to Prettier/ESLint and our test runner). |
73 | 91 |
|
74 | | -- Do not bypass hooks unless absolutely necessary. |
75 | | -- Keep hook scripts up to date with project standards. |
76 | | -- Review and update hooks as new linting or test scripts are added. |
77 | | -- See [docs/LINTING.md](./LINTING.md) for details on what is checked by each hook. |
| 92 | +*(No changes are needed to developers' workflows aside from running `npm install` and having Node per `.nvmrc`. Commits are now gated, improving code quality upstream.)* |
78 | 93 |
|
79 | 94 | ## Related Files & Further Reading |
80 | 95 |
|
81 | 96 | - [docs/LINTING.md](./LINTING.md) — Linting tools and configuration |
82 | | -- [docs/HUSKY-LINITING-TASKS.md](./HUSKY-LINITING-TASKS.md) — Task list for Husky and linting documentation |
| 97 | +- [docs/METRICS.md](./METRICS.md) — Metrics and telemetry |
| 98 | +- [docs/config/workflow-husky.md](./config/workflow-husky.md) — Detailed Husky configuration |
83 | 99 | - [package.json](../package.json) — NPM scripts run by hooks |
84 | | -- [.husky/](../../.husky/) — Actual hook scripts |
| 100 | +- [.husky/](../.husky/) — Actual hook scripts |
85 | 101 |
|
86 | 102 | --- |
87 | 103 |
|
88 | | -### Last updated |
| 104 | +### Last Updated |
89 | 105 |
|
90 | | -24 October 2025 |
| 106 | +2025-11-14 |
0 commit comments