Skip to content

Commit 70a1f19

Browse files
authored
Add Git Hooks documentation for automated code quality checks (#393)
* docs: add Git Hooks documentation for automated code quality checks * chore: update lint-staged configuration to use '.' for eslint and prettier commands across multiple package.json files * docs: enhance Git Hooks documentation to clarify project-wide linting and validation process
1 parent 6255d3b commit 70a1f19

9 files changed

Lines changed: 184 additions & 23 deletions

File tree

docs/docs.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"scheduler",
4646
"mailer",
4747
"github-actions",
48+
"git-hooks",
4849
{
4950
"group": "Web",
5051
"pages": [

docs/git-hooks.mdx

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
title: "Git Hooks"
3+
description: "Automated code quality checks with Husky and lint-staged"
4+
---
5+
6+
Ship uses [Husky](https://typicode.github.io/husky/) and [lint-staged](https://github.com/lint-staged/lint-staged) to automatically validate and auto-fix the entire project before each commit, ensuring consistent code quality across the codebase.
7+
8+
## How It Works
9+
10+
When you commit changes, Husky triggers a pre-commit hook that runs lint-staged. The configuration runs linters on the **entire project** to ensure project-wide code quality.
11+
12+
<Info>
13+
The pre-commit hook is automatically installed when you run `pnpm install` via the `prepare` script.
14+
</Info>
15+
16+
<Note>
17+
**Project-wide Validation**: Ship intentionally runs linters on ALL project files (using `.`), not just staged files. This defensive approach ensures that if someone bypassed hooks with `--no-verify`, the next commit will auto-fix those issues and prevent blocking other team members.
18+
</Note>
19+
20+
## Configuration
21+
22+
### API
23+
24+
<CodeGroup>
25+
```json TypeScript Files
26+
"lint-staged": {
27+
"*.ts": [
28+
"eslint . --fix",
29+
"bash -c 'tsc --noEmit'",
30+
"prettier . --write"
31+
]
32+
}
33+
```
34+
35+
```json JSON & Markdown
36+
"lint-staged": {
37+
"*.{json,md}": [
38+
"prettier . --write"
39+
]
40+
}
41+
```
42+
</CodeGroup>
43+
44+
When any `.ts` file is staged, runs on **entire project**:
45+
1. **ESLint** - Auto-fixes all `.ts` files (note the `.`)
46+
2. **TypeScript** - Type checks all files
47+
3. **Prettier** - Formats all files (note the `.`)
48+
49+
### Web
50+
51+
<CodeGroup>
52+
```json TypeScript/React Files
53+
"lint-staged": {
54+
"*.{ts,tsx}": [
55+
"eslint . --fix",
56+
"bash -c 'tsc --noEmit'",
57+
"prettier . --write"
58+
]
59+
}
60+
```
61+
62+
```json CSS Files
63+
"lint-staged": {
64+
"*.css": [
65+
"stylelint . --fix",
66+
"prettier . --write"
67+
]
68+
}
69+
```
70+
71+
```json JSON & Markdown
72+
"lint-staged": {
73+
"*.{json,md}": [
74+
"prettier . --write"
75+
]
76+
}
77+
```
78+
</CodeGroup>
79+
80+
### Packages
81+
82+
All shared packages (`schemas`, `mailer`, `app-types`, etc.) have similar lint-staged configurations tailored to their file types.
83+
84+
## Customization
85+
86+
### Modify Linters
87+
88+
Edit `lint-staged` in your `package.json`:
89+
90+
```json
91+
"lint-staged": {
92+
"*.ts": [
93+
"eslint . --fix", // The '.' runs on entire project
94+
"prettier . --write" // The '.' formats all files
95+
// Add or remove tools as needed
96+
]
97+
}
98+
```
99+
100+
### Run on Staged Files Only (Alternative)
101+
102+
If you prefer to only lint staged files instead of the entire project:
103+
104+
```json
105+
"lint-staged": {
106+
"*.ts": [
107+
"eslint --fix", // No '.' - only staged files
108+
"prettier --write" // No '.' - only staged files
109+
]
110+
}
111+
```
112+
113+
<Warning>
114+
Linting only staged files means errors in other parts of the codebase (e.g., from `--no-verify` commits) won't be caught or fixed until those files are modified.
115+
</Warning>
116+
117+
### Skip Hooks Temporarily
118+
119+
```bash
120+
# Bypass pre-commit hook (not recommended)
121+
git commit --no-verify -m "message"
122+
```
123+
124+
<Tip>
125+
Only skip hooks when absolutely necessary, as they help maintain code quality.
126+
</Tip>
127+
128+
## Troubleshooting
129+
130+
### Hook Not Running
131+
132+
If pre-commit hooks don't run:
133+
134+
1. Ensure Husky is installed:
135+
```bash
136+
pnpm install
137+
```
138+
139+
2. Check if `.husky/pre-commit` exists in your project root
140+
141+
3. Verify Git hooks path:
142+
```bash
143+
git config core.hooksPath
144+
```
145+
146+
### Linter Errors Blocking Commits
147+
148+
If linters fail:
149+
150+
1. Review the error output
151+
2. Fix the issues manually or let auto-fix handle them
152+
3. Stage the fixed files: `git add .`
153+
4. Commit again
154+
155+
## Best Practices
156+
157+
- **Never use `--no-verify`** - It bypasses quality checks and can break the build for teammates
158+
- **Fix issues early** - Don't accumulate linting errors across the codebase
159+
- **Keep configs in sync** - Ensure lint-staged matches your editor settings
160+

template/apps/api/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@
7676
},
7777
"lint-staged": {
7878
"*.ts": [
79-
"eslint --fix",
79+
"eslint . --fix",
8080
"bash -c 'tsc --noEmit'",
81-
"prettier --write"
81+
"prettier . --write"
8282
],
8383
"*.{json,md}": [
8484
"prettier --write"

template/apps/web/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,16 @@
6666
},
6767
"lint-staged": {
6868
"*.{ts,tsx}": [
69-
"eslint --fix",
69+
"eslint . --fix",
7070
"bash -c 'tsc --noEmit'",
71-
"prettier --write"
71+
"prettier . --write"
7272
],
7373
"*.css": [
74-
"stylelint --fix",
75-
"prettier --write"
74+
"stylelint . --fix",
75+
"prettier . --write"
7676
],
7777
"*.{json,md}": [
78-
"prettier --write"
78+
"prettier . --write"
7979
]
8080
}
8181
}

template/packages/app-constants/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
},
2323
"lint-staged": {
2424
"*.ts": [
25-
"eslint --fix",
25+
"eslint . --fix",
2626
"bash -c 'tsc --noEmit'",
27-
"prettier --write"
27+
"prettier . --write"
2828
],
2929
"*.{json,md}": [
30-
"prettier --write"
30+
"prettier . --write"
3131
]
3232
}
3333
}

template/packages/app-types/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@
2828
},
2929
"lint-staged": {
3030
"*.ts": [
31-
"eslint --fix",
31+
"eslint . --fix",
3232
"bash -c 'tsc --noEmit'",
33-
"prettier --write"
33+
"prettier . --write"
3434
],
3535
"*.{json,md}": [
36-
"prettier --write"
36+
"prettier . --write"
3737
]
3838
}
3939
}

template/packages/enums/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
},
2323
"lint-staged": {
2424
"*.ts": [
25-
"eslint --fix",
25+
"eslint . --fix",
2626
"bash -c 'tsc --noEmit'",
27-
"prettier --write"
27+
"prettier . --write"
2828
],
2929
"*.{json,md}": [
30-
"prettier --write"
30+
"prettier . --write"
3131
]
3232
}
3333
}

template/packages/mailer/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@
3636
},
3737
"lint-staged": {
3838
"*.{ts,tsx}": [
39-
"eslint --fix",
39+
"eslint . --fix",
4040
"bash -c 'tsc --noEmit'",
41-
"prettier --write"
41+
"prettier . --write"
4242
],
4343
"*.{json,md}": [
44-
"prettier --write"
44+
"prettier . --write"
4545
]
4646
}
4747
}

template/packages/schemas/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727
"typescript": "catalog:"
2828
},
2929
"lint-staged": {
30-
"*.ts": [
31-
"eslint --fix",
30+
"*.{ts,tsx}": [
31+
"eslint . --fix",
3232
"bash -c 'tsc --noEmit'",
33-
"prettier --write"
33+
"prettier . --write"
3434
],
3535
"*.{json,md}": [
36-
"prettier --write"
36+
"prettier . --write"
3737
]
3838
}
3939
}

0 commit comments

Comments
 (0)