| name | push-flow-convention |
| description | Enforce pre-commit/pre-push hooks, lint-staged checks, and semver version bump on every push |
Push Flow Convention
Every repository MUST enforce the same pre-commit, pre-push, and versioning flow. No push lands without hooks, lint-staged, and a version bump.
Required Setup
1. Lefthook (pre-commit + pre-push)
Always use Lefthook for git hooks. Never use husky.
Install once per repo:
pnpm add -D lefthook lint-staged
pnpm exec lefthook install
Create lefthook.yml in project root:
pre-commit:
commands:
lint-staged:
run: pnpm exec lint-staged
pre-push:
commands:
lint-staged:
run: pnpm exec lint-staged --diff="origin/{push_remote_branch}...HEAD"
bump:
run: pnpm run bump
2. lint-staged
Declared in package.json. Runs ONLY on staged files so commits stay fast.
{
"lint-staged": {
"*.{ts,tsx,js,jsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,yml,yaml}": [
"prettier --write"
]
}
}
3. Version bump script
package.json MUST expose a bump script used by pre-push:
{
"scripts": {
"bump": "node scripts/bump-version.mjs"
}
}
The script inspects the diff between the current branch and its upstream, applies the semver rule below, and writes the new version back to package.json. Commit the bump before pushing (amend the previous commit or create a chore: adjust package.json version (bump) commit — see commit-convention).
Semver Rules (applied on every push)
The bump is based on the changes in the commits being pushed:
| Change size / kind | Bump |
|---|
< 5 changed files across pushed commits | patch (x.y.Z) |
>= 5 changed files across pushed commits | minor (x.Y.0) |
New feature OR new behaviour (any feat: commit) | major (X.0.0) |
Rules in order of precedence:
- If ANY commit being pushed is a
feat(...) → major bump.
- Otherwise, count files changed (
git diff --name-only origin/<branch>...HEAD | wc -l):
- fewer than 5 → patch
- 5 or more → minor
The feat rule always wins — a new feature is always a major bump regardless of file count.
Non-negotiables
- NEVER push without pre-commit and pre-push hooks installed.
- NEVER bypass hooks with
--no-verify — if a hook fails, fix the root cause.
- NEVER push without a version bump. Every push = new version.
- The bump commit MUST use the
chore: adjust package.json version (bump) message (see commit-convention).
- lint-staged MUST run on every commit. A green lint-staged is a prerequisite for the commit to be created.
- If
pnpm is not the package manager, substitute with npm or yarn but keep the same flow.
Quick verification checklist
Before declaring the push flow set up, confirm: