pbs-projects/Tech/Projects/pre-commit-framework-migration.md

189 lines
6.4 KiB
Markdown

---
project: pre-commit-framework-migration
type: project-plan
status: active
path: Tech/Projects
tags:
- homelab
- tooling
- git
- ansible
- security
created: 2026-05-03
updated: 2026-05-03
---
# pre-commit framework migration
## Goal
Replace the raw `.git/hooks/pre-commit` bash script (currently shared via
`core.hooksPath`) with the [pre-commit framework](https://pre-commit.com),
and adopt it as the standard for all new repos. Codify a curated set of
checks that catch the mistakes most likely to bite a solo homelab operator
working across Python, Go, Ansible, and YAML-heavy infra repos.
## Why
The current raw hook works but has limits:
- not version-controlled (lives in `.git/hooks/`, not tracked)
- single-purpose (vault encryption check only)
- adding more checks means growing a bash script
- no portability across machines without re-running the `core.hooksPath`
setup
The framework solves all four: config lives in `.pre-commit-config.yaml` at
the repo root, gets committed, and gives access to a large ecosystem of
pre-built hooks.
## Scope
### In scope
- Install `pre-commit` framework on dev machines
- Migrate the existing ansible-vault check from raw bash to a framework hook
- Curate a default `.pre-commit-config.yaml` template covering Python, Go,
Ansible, YAML, and secret-detection
- Document the install/onboarding flow as the standard for new repos
- Decide how the framework coexists with (or replaces) the current
`core.hooksPath` setup
- Add the template to project scaffolding so new repos start with it
pre-wired
### Out of scope
- Migrating every existing repo today (do them as they're touched)
- Full CI integration (pre-commit can also run in GitHub Actions, but
that's a follow-up)
- Replacing `zero-check` or other post-generation validation skills
## Decisions to confirm
- **Coexistence with `core.hooksPath`** — once the framework is in a repo,
its `pre-commit install` will overwrite `.git/hooks/pre-commit` for that
repo. Need to decide: leave `core.hooksPath` as a fallback for repos
without `.pre-commit-config.yaml`, or unset it once all active repos are
migrated?
- **Vault check location** — keep the bash script in-repo at
`scripts/check-vault.sh` (referenced as a `local` hook), or rewrite as a
tiny standalone repo and pin like other framework hooks?
- **Template repo or scaffold-generated** — does the default
`.pre-commit-config.yaml` live in a `homelab-templates` repo for
`web_fetch` access, or get generated by the project scaffolding tool?
## Curated check list
Grouped by category. Each is a separate hook entry; opt in per repo by
what's actually relevant.
### Universal (every repo)
- `trailing-whitespace` — strip trailing spaces
- `end-of-file-fixer` — ensure files end with a newline
- `check-merge-conflict` — block commits with unresolved conflict markers
- `check-added-large-files` — block accidental large file commits (default
500KB)
- `mixed-line-ending` — enforce LF
- `detect-private-key` — block committing SSH/TLS private keys
### Secrets & sensitive data
- `detect-secrets` (Yelp) — broader secret scanning beyond just private
keys; catches AWS keys, API tokens, high-entropy strings
- `gitleaks` — alternative or complement; well-maintained, fast
- **Custom: ansible-vault encryption check** — port of the existing bash
hook
### YAML / config
- `check-yaml` — basic YAML syntax validation
- `yamllint` — style + structure (line length, indentation, truthy values)
- `check-json` — JSON syntax
- `check-toml` — TOML syntax
### Python
- `ruff` — lint + format in one tool (replaces flake8, isort, black for
most cases)
- `ruff-format` — formatter
- `mypy` — optional, type-checking (heavier; opt in per project)
### Go
- `go-fmt` — gofmt enforcement
- `go-vet` — basic static analysis
- `golangci-lint` — broader linting (opt in per project)
### Ansible-specific
- **Custom: ansible-vault encryption check** (existing logic, ported)
- `ansible-lint` — full Ansible playbook/role linting
- `yamllint` (already covered above, but Ansible repos lean on it heavily)
### Shell scripts
- `shellcheck` — catches common bash bugs and bad patterns
- `shfmt` — formatter for shell scripts
### Markdown / docs
- `markdownlint` — style/structure for `.md` files
- (Skip if it gets noisy on Obsidian-flavored markdown — the project notes
use front-matter and Obsidian syntax that vanilla markdownlint may complain
about.)
## Migration path
1. Pick one active repo as the pilot — likely the new project where this
conversation started.
2. `pip install pre-commit` (or `uv tool install pre-commit`) on the dev
machine.
3. Drop in a starter `.pre-commit-config.yaml` covering universal + secrets
+ ansible + relevant language checks.
4. Port the vault check as a `local` hook pointing at
`scripts/check-vault.sh`.
5. `pre-commit install` to wire it up.
6. `pre-commit run --all-files` to flush out anything the existing code
violates.
7. Iterate on the config until baseline is clean.
8. Once stable, copy `.pre-commit-config.yaml` to the template location
(TBD — see decisions).
9. Decide on `core.hooksPath` — leave or unset.
10. Add `pre-commit install` to the project scaffolding flow so new repos
get it automatically.
## Tasks
- [ ] Confirm decisions: coexistence with `core.hooksPath`, vault check
location, template hosting
- [ ] Install `pre-commit` framework on dev machines
- [ ] Pilot on one active repo
- [ ] Port vault encryption check as a `local` hook
- [ ] Build default `.pre-commit-config.yaml` template covering universal +
secrets + Python + Go + Ansible + YAML
- [ ] Run `pre-commit run --all-files` on pilot, fix or ignore findings
- [ ] Document the install/onboarding flow (README section or standalone
doc)
- [ ] Decide whether to keep or unset `core.hooksPath`
- [ ] Migrate active repos one by one as they're touched
- [ ] Add template to scaffolding tool or `homelab-templates` repo
- [ ] Evaluate whether to add CI run of `pre-commit run --all-files` on PRs
(follow-up)
## Open questions
- Does `pre-commit` play well with the `zero-check` skill, or is there
overlap to resolve?
- For Obsidian-flavored markdown, is `markdownlint` worth the noise or skip
entirely?
- Should `mypy` be in the default Python config, or opt-in per project?
## References
- pre-commit docs: https://pre-commit.com
- Hook list: https://pre-commit.com/hooks.html
- Existing raw hook: stored at `~/.config/git-hooks/pre-commit` (per
`core.hooksPath` setup)
...sent from Jenny & Travis