mirror of
https://github.com/taigrr/hooks.git
synced 2026-04-02 03:18:55 -07:00
feat: add commit-msg hook, improve robustness
- Add commit-msg hook enforcing Conventional Commits format (allows merge, fixup, and squash commits) - Fix file size display: use MiB (binary) to match the binary limit calculation - Make gitleaks optional: skip gracefully if not installed - Suppress stderr on mg register in pre-push - Add shellcheck directive to pre-commit - Mark gitleaks as optional in README prerequisites - Clean up FUNDING.yml boilerplate
This commit is contained in:
13
.github/FUNDING.yml
vendored
13
.github/FUNDING.yml
vendored
@@ -1,12 +1 @@
|
|||||||
# These are supported funding model platforms
|
github: taigrr
|
||||||
|
|
||||||
github: taigrr # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
|
||||||
patreon: # Replace with a single Patreon username
|
|
||||||
open_collective: # Replace with a single Open Collective username
|
|
||||||
ko_fi: # Replace with a single Ko-fi username
|
|
||||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
|
||||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
||||||
liberapay: # Replace with a single Liberapay username
|
|
||||||
issuehunt: # Replace with a single IssueHunt username
|
|
||||||
otechie: # Replace with a single Otechie username
|
|
||||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
|
||||||
|
|||||||
33
README.md
33
README.md
@@ -15,7 +15,7 @@ is an annoying extra step, so `git lfs track` is used to short-circuit this logi
|
|||||||
|
|
||||||
- [git](https://git-scm.com/)
|
- [git](https://git-scm.com/)
|
||||||
- [git-lfs](https://git-lfs.github.com/)
|
- [git-lfs](https://git-lfs.github.com/)
|
||||||
- [gitleaks](https://github.com/gitleaks/gitleaks)
|
- [gitleaks](https://github.com/gitleaks/gitleaks) (optional, for secret scanning)
|
||||||
- [mg](https://github.com/taigrr/mg) (optional, for repo registration on push)
|
- [mg](https://github.com/taigrr/mg) (optional, for repo registration on push)
|
||||||
|
|
||||||
## What these hooks do
|
## What these hooks do
|
||||||
@@ -29,8 +29,9 @@ a couple of annoying blunders:
|
|||||||
|
|
||||||
| Hook | What it does |
|
| Hook | What it does |
|
||||||
|------|-------------|
|
|------|-------------|
|
||||||
| `pre-commit` | Blocks commits containing files over 5 MB (unless tracked by LFS) |
|
| `pre-commit` | Blocks commits containing files over 5 MiB (unless tracked by LFS) |
|
||||||
| `pre-commit` | Scans staged files for leaked secrets via gitleaks |
|
| `pre-commit` | Scans staged files for leaked secrets via gitleaks (skipped if gitleaks not installed) |
|
||||||
|
| `commit-msg` | Validates [Conventional Commits](https://www.conventionalcommits.org/) format |
|
||||||
| `post-checkout` | Runs `git lfs post-checkout` |
|
| `post-checkout` | Runs `git lfs post-checkout` |
|
||||||
| `post-commit` | Runs `git lfs post-commit` |
|
| `post-commit` | Runs `git lfs post-commit` |
|
||||||
| `post-merge` | Runs `git lfs post-merge` |
|
| `post-merge` | Runs `git lfs post-merge` |
|
||||||
@@ -78,11 +79,33 @@ git config core.hooksPath /path/to/other/hooks
|
|||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The file size limit in `pre-commit` defaults to **5 MB**. To change it, edit the
|
### File size limit
|
||||||
|
|
||||||
|
The file size limit in `pre-commit` defaults to **5 MiB**. To change it, edit the
|
||||||
`size_limit` variable at the top of the `pre-commit` file:
|
`size_limit` variable at the top of the `pre-commit` file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
size_limit=$((10 * 2**20)) # 10 MB
|
size_limit=$((10 * 2**20)) # 10 MiB
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conventional Commits
|
||||||
|
|
||||||
|
The `commit-msg` hook enforces [Conventional Commits](https://www.conventionalcommits.org/)
|
||||||
|
format on your commit messages:
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>(<scope>): <description>
|
||||||
|
```
|
||||||
|
|
||||||
|
Valid types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`,
|
||||||
|
`ci`, `chore`, `revert`. Add `!` after the type/scope for breaking changes.
|
||||||
|
|
||||||
|
Merge commits and fixup/squash commits are always allowed.
|
||||||
|
|
||||||
|
To disable this hook for a single commit:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git commit --no-verify -m "whatever"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Compatibility Notice
|
## Compatibility Notice
|
||||||
|
|||||||
32
commit-msg
Executable file
32
commit-msg
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Validates conventional commit format: type(scope): description
|
||||||
|
# Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
|
||||||
|
# Optional ! for breaking changes: feat(api)!: change response format
|
||||||
|
# Merge commits and fixup/squash commits are always allowed.
|
||||||
|
|
||||||
|
msg_file="$1"
|
||||||
|
msg=$(head -1 "$msg_file")
|
||||||
|
|
||||||
|
# Allow merge commits
|
||||||
|
if echo "$msg" | grep -qE '^Merge '; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Allow fixup/squash commits
|
||||||
|
if echo "$msg" | grep -qE '^(fixup|squash)! '; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
pattern='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-zA-Z0-9_/-]+\))?!?: .+'
|
||||||
|
|
||||||
|
if ! echo "$msg" | grep -qE "$pattern"; then
|
||||||
|
echo "ERROR: Commit message does not follow Conventional Commits format."
|
||||||
|
echo ""
|
||||||
|
echo " Expected: <type>(<scope>): <description>"
|
||||||
|
echo " Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert"
|
||||||
|
echo " Example: feat(auth): add OAuth2 support"
|
||||||
|
echo " Breaking: feat(api)!: change response format"
|
||||||
|
echo ""
|
||||||
|
echo " Your message: $msg"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
# shellcheck disable=SC2086
|
||||||
set +eou pipefail
|
set +eou pipefail
|
||||||
size_limit=$((5 * 2**20))
|
size_limit=$((5 * 2**20))
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ for file in $(git diff-index --cached --name-only "$against"); do
|
|||||||
fi
|
fi
|
||||||
file_size=$(stat --format='%s' "$file" 2>/dev/null || stat -f '%z' "$file" 2>/dev/null || echo 0)
|
file_size=$(stat --format='%s' "$file" 2>/dev/null || stat -f '%z' "$file" 2>/dev/null || echo 0)
|
||||||
if [ "$file_size" -gt "$size_limit" ]; then
|
if [ "$file_size" -gt "$size_limit" ]; then
|
||||||
echo "File $file is $((file_size / 10**6))MB, which is larger than our configured limit of $((size_limit / 10**6))MB"
|
echo "File $file is $((file_size / 2**20))MiB, which is larger than our configured limit of $((size_limit / 2**20))MiB"
|
||||||
hasLargeFile=true
|
hasLargeFile=true
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -39,4 +40,7 @@ if $hasLargeFile; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
popd > /dev/null 2>&1 || true
|
popd > /dev/null 2>&1 || true
|
||||||
|
|
||||||
|
if command -v gitleaks > /dev/null 2>&1; then
|
||||||
gitleaks protect --staged --verbose --no-banner --no-color 2>/dev/null
|
gitleaks protect --staged --verbose --no-banner --no-color 2>/dev/null
|
||||||
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user