Git Hooks (Husky)
This repository uses Husky to run Git hooks from the root .husky/ directory. Hooks run automatically at specific points in the Git workflow to keep code style and commit messages consistent across the monorepo.
Hook scripts live in .husky/ (pre-commit, commit-msg).
Setup
Hooks are configured when you run at the repository root:
npm installThe prepare script runs automatically and points Git at .husky/.
NOTE
Husky lives in the root package.json because hooks apply to the entire monorepo. Vue lint still uses zmscitizenview; docs formatting uses docs/.
After cloning, run npm install once at the repo root (also in the root README). For doc changes, install docs dependencies once: cd docs && npm install.
Hooks
pre-commit
No-op placeholder. Git always runs pre-commit before commit-msg; the real checks are in commit-msg so the commit subject is validated before Vue/docs/PHP.
commit-msg
All checks run in this hook, in fail-fast order:
- Commit message — subject line from the message file Git passes to this hook
- Vue code style — Prettier check in
zmscitizenview(npm run lint) - Docs formatting — Prettier check in
docs/(npm run format:check) - PHP code style — PHP CodeSniffer (PSR-12) across PHP modules via the
zms-webcontainer
Container detection
The PHP check detects your runtime automatically:
- Podman — if a container named
zms-webis running - Docker — fallback when Podman is unavailable
- Skip — if no container is running (warning only, non-blocking)
Behavior
- Commit message, Vue, and docs checks block the commit on failure
- PHP checks run only when
zms-webis up; otherwise they are skipped with a warning
See also Code formatting for manual PHPCS/Prettier commands.
Commit message format (step 1):
type(PROJECT-123): commit message
type(PROJECT): commit messageThe ticket number is optional — use PROJECT-123 or just PROJECT (uppercase).
Merge commits
Git’s default merge subjects (for example Merge branch 'main' into feature-branch) are allowed automatically so git merge can finish without renaming the message. You can still use a conventional subject if you prefer, for example chore(ZMS): merge main into feature-branch.
Full rules, types, projects, and examples: Commit message convention.
Troubleshooting
Vue lint fails
cd zmscitizenview
npm run formatThen commit again.
Docs formatting fails
If Prettier reports issues under docs/:
cd docs
npm run formatInstall dependencies first if needed: cd docs && npm install.
PHP CodeSniffer fails
The hook prints a fix command for your container engine:
# Podman
podman exec -it zms-web bash -lc "./cli modules loop 'vendor/bin/phpcbf --standard=psr12 src/'"
# Docker
docker exec -it zms-web bash -lc "./cli modules loop 'vendor/bin/phpcbf --standard=psr12 src/'"Container not detected
If you see a warning that zms-web is not running:
podman ps | grep zms-web
docker ps | grep zms-webStart the dev environment if needed (DDEV and Devcontainer, Podman and Dev Containers). PHP checks are skipped when the container is down; the commit is not blocked for PHP alone.
Invalid commit message format
Common mistakes:
- Missing project:
feat: add feature - Lowercase project:
feat(zms-123): add feature - Missing colon:
feat(ZMS-123) add feature
Correct examples:
feat(ZMS-123): add featurechore(ZMSKVR): clean up
Merge blocked by commit-msg
If git merge fails with “Invalid commit message format” and a subject like Merge branch 'main' into …, update .husky/commit-msg from the latest main or feature branch (merge subjects should be accepted). As a workaround, finish the merge with a conventional message:
git commit -m "chore(ZMS): merge main into your-branch"Bypassing hooks
In emergencies, use Git’s --no-verify flag:
git commit --no-verify -m "feat(ZMS-123): urgent fix"CAUTION
Use --no-verify only when necessary. Bypassing hooks can hurt code quality and affect other contributors.