From 63263abb973e127fcd5114d441139ceb9059f23b Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Mon, 2 Mar 2026 18:14:03 -0800 Subject: [PATCH] Switch git hooks from pre-commit to prek prek is a faster, Rust-native drop-in replacement for pre-commit. Migrates config from .pre-commit-config.yaml to prek.toml, adds built-in checks for case conflicts, private key detection, and executable shebangs. Updates all doc references. Co-Authored-By: Claude Opus 4.6 --- .github/USE_FORGE_WORKFLOWS.md | 2 +- .pre-commit-config.yaml | 148 --------------- README.md | 8 +- docs/changelog.d/switch-to-prek.infra.md | 1 + docs/how-to/agent-change-process.md | 2 +- .../update-tooling-dependencies.md | 10 +- docs/how-to/how-to.md | 2 +- .../zot/add-container-version-sync-check.md | 6 +- .../zot/adopt-commit-based-container-tags.md | 2 +- docs/tutorials/contributing.md | 10 +- mise.toml | 2 +- prek.toml | 169 ++++++++++++++++++ 12 files changed, 192 insertions(+), 170 deletions(-) delete mode 100644 .pre-commit-config.yaml create mode 100644 docs/changelog.d/switch-to-prek.infra.md create mode 100644 prek.toml diff --git a/.github/USE_FORGE_WORKFLOWS.md b/.github/USE_FORGE_WORKFLOWS.md index bea6b15..026adf6 100644 --- a/.github/USE_FORGE_WORKFLOWS.md +++ b/.github/USE_FORGE_WORKFLOWS.md @@ -6,4 +6,4 @@ This directory contains configuration for GitHub-ecosystem tooling only. ## Contents -- `actionlint.yaml` - Configuration for actionlint pre-commit hook (custom runner labels) +- `actionlint.yaml` - Configuration for actionlint prek hook (custom runner labels) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 9bf1fd8..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,148 +0,0 @@ ---- -# See https://pre-commit.com for more information -# Run: uvx pre-commit run --all-files -# Install: uvx pre-commit install && uvx pre-commit install --hook-type commit-msg - -repos: - # General file hygiene - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v6.0.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-added-large-files - args: ['--maxkb=1000'] - - id: check-merge-conflict - - id: check-json - - id: check-yaml - args: ['--unsafe'] # Allow custom tags (ansible uses them) - - id: check-toml - - # Secret detection - - repo: https://github.com/trufflesecurity/trufflehog - rev: v3.93.4 - hooks: - - id: trufflehog - entry: trufflehog git file://. --since-commit HEAD --no-verification --fail - stages: [pre-commit, pre-push] - - # YAML linting - - repo: https://github.com/adrienverge/yamllint - rev: v1.38.0 - hooks: - - id: yamllint - args: ['-c', '.yamllint.yaml'] - - # Ansible linting - - repo: local - hooks: - - id: ansible-lint - name: ansible-lint - entry: env ANSIBLE_ROLES_PATH=ansible/roles ansible-lint - language: python - files: ^ansible/ - additional_dependencies: - - ansible-lint>=26.1.1 - - ansible-core>=2.15 - - # Python - ruff for linting and formatting - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.2 - hooks: - - id: ruff - args: ['--fix'] - - id: ruff-format - - # Shell scripts - shellcheck and shfmt - - repo: https://github.com/shellcheck-py/shellcheck-py - rev: v0.11.0.1 - hooks: - - id: shellcheck - args: ['--severity=warning'] - - - repo: https://github.com/scop/pre-commit-shfmt - rev: v3.12.0-2 - hooks: - - id: shfmt - args: ['-i', '2', '-ci', '-bn'] # 2-space indent, case indent, binary newline - - # TOML - taplo - - repo: https://github.com/ComPWA/taplo-pre-commit - rev: v0.9.3 - hooks: - - id: taplo-format - - id: taplo-lint - - # JSON formatting (prettier for consistent style) - - repo: https://github.com/rbubley/mirrors-prettier - rev: v3.8.1 - hooks: - - id: prettier - types_or: [json] - args: ['--tab-width', '2'] - - # GitHub/Forgejo Actions workflow linting - - repo: https://github.com/rhysd/actionlint - rev: v1.7.11 - hooks: - - id: actionlint-system - args: ['-config-file', '.github/actionlint.yaml'] - files: ^\.forgejo/workflows/ - - # Forgejo workflow schema validation (via Dagger + forgejo-runner validate) - - repo: local - hooks: - - id: validate-workflows - name: validate-workflows - entry: mise run validate-workflows - language: system - files: ^\.forgejo/workflows/ - pass_filenames: false - - # Container version consistency - - repo: local - hooks: - - id: container-version-check - name: container-version-check - entry: mise run container-version-check - language: system - files: ^(containers/|service-versions\.yaml) - pass_filenames: false - - # Mikado Branch Invariant (C2 changes) - - repo: local - hooks: - - id: mikado-branch-invariant-check - name: mikado-branch-invariant-check - entry: mise run mikado-branch-invariant-check - language: system - always_run: true - stages: [commit-msg] - - # Documentation validation - - repo: local - hooks: - - id: docs-check-filenames - name: docs-check-filenames - entry: mise run docs-check-filenames - language: system - files: ^docs/.*\.md$ - pass_filenames: false - - id: docs-check-links - name: docs-check-links - entry: mise run docs-check-links - language: system - files: ^docs/.*\.md$ - pass_filenames: false - - id: docs-check-index - name: docs-check-index - entry: mise run docs-check-index - language: system - files: ^docs/.*\.md$ - pass_filenames: false - - id: docs-check-frontmatter - name: docs-check-frontmatter - entry: mise run docs-check-frontmatter - language: system - files: ^docs/.*\.md$ - pass_filenames: false diff --git a/README.md b/README.md index 9d4d9d9..722d370 100644 --- a/README.md +++ b/README.md @@ -58,12 +58,12 @@ You'll need [Homebrew](https://brew.sh) and [mise](https://mise.jdx.dev): ```bash brew bundle # install CLI tools (argocd, tea, flyctl, etc.) mise install # install managed toolchains (ansible, pulumi, dagger, etc.) -uvx pre-commit install # set up pre-commit hooks +prek install # set up git hooks ``` -Pre-commit hooks enforce secret scanning (TruffleHog), linting, formatting, and -custom checks like doc link validation and the Mikado branch invariant. Run -them manually with `uvx pre-commit run --all-files`. +Git hooks (via [prek](https://github.com/j178/prek)) enforce secret scanning +(TruffleHog), linting, formatting, and custom checks like doc link validation +and the Mikado branch invariant. Run them manually with `prek run --all-files`. Operational tasks are driven through mise. Run `mise tasks` to see what's available. Key examples: diff --git a/docs/changelog.d/switch-to-prek.infra.md b/docs/changelog.d/switch-to-prek.infra.md new file mode 100644 index 0000000..dc245de --- /dev/null +++ b/docs/changelog.d/switch-to-prek.infra.md @@ -0,0 +1 @@ +Switch git hooks from pre-commit to [prek](https://github.com/j178/prek), a faster Rust-native drop-in replacement. Adds built-in checks for case conflicts, private key detection, and executable shebangs. Configuration migrated from `.pre-commit-config.yaml` to `prek.toml`. diff --git a/docs/how-to/agent-change-process.md b/docs/how-to/agent-change-process.md index b9f70ff..0e19cf5 100644 --- a/docs/how-to/agent-change-process.md +++ b/docs/how-to/agent-change-process.md @@ -281,7 +281,7 @@ tags: | `mise run docs-mikado --resume` | Resume a chain: detect branch, show state and next steps | | `mise run docs-mikado --resume ` | Resume a specific chain with branch consistency check | -The `mikado-branch-invariant-check` commit-msg hook runs automatically on `mikado/*` branches, validating commit message conventions and invariant ordering. Requires `uvx pre-commit install --hook-type commit-msg`. +The `mikado-branch-invariant-check` commit-msg hook runs automatically on `mikado/*` branches, validating commit message conventions and invariant ordering. Requires `prek install --hook-type commit-msg`. ## Related diff --git a/docs/how-to/configuration/update-tooling-dependencies.md b/docs/how-to/configuration/update-tooling-dependencies.md index 6468348..8b09e6d 100644 --- a/docs/how-to/configuration/update-tooling-dependencies.md +++ b/docs/how-to/configuration/update-tooling-dependencies.md @@ -17,7 +17,7 @@ Monthly maintenance cycle for updating development tooling and CI dependencies. | Category | Location | What to check | |----------|----------|---------------| -| Pre-commit hooks | `.pre-commit-config.yaml` | `rev:` tags for all remote repos | +| Prek hooks | `prek.toml` | `rev:` tags for all remote repos | | Fly.io proxy | `fly/Dockerfile` | Pinned image tags (nginx, alloy) | | Mise task scripts | `mise-tasks/*` | Python `# dependencies` lower bounds | | Forgejo workflows | `.forgejo/workflows/*.yaml` | `uses:` action versions | @@ -26,14 +26,14 @@ Out of scope: ArgoCD-deployed service images, Ansible role versions, NixOS flake ## Procedure -### 1. Check pre-commit hook versions +### 1. Check prek hook versions -For each repo in `.pre-commit-config.yaml` with a `rev:` tag, check the upstream GitHub releases page for a newer tag. Update each `rev:` to the latest release tag. Also check `additional_dependencies` entries for PyPI version bumps. +For each repo in `prek.toml` with a `rev =` value, check the upstream GitHub releases page for a newer tag. Update each `rev` to the latest release tag. Also check `additional_dependencies` entries for PyPI version bumps. Verify after updating: ```fish -uvx pre-commit run --all-files +prek run --all-files ``` ### 2. Check Fly.io Dockerfile pins @@ -77,5 +77,5 @@ Create a single PR with all dependency bumps. The changelog fragment type is `in ## Notes - **Alloy version gaps**: Grafana Alloy releases frequently. Large version jumps (e.g., v1.5 to v1.13) are normal and generally safe — check the [changelog](https://github.com/grafana/alloy/releases) for breaking changes in the Alloy River config syntax. -- **Ruff minor bumps**: Ruff adds new lint rules in minor versions. A bump may surface new warnings. Run `uvx pre-commit run ruff --all-files` to check before committing. +- **Ruff minor bumps**: Ruff adds new lint rules in minor versions. A bump may surface new warnings. Run `prek run ruff --all-files` to check before committing. - **shellcheck bumps**: New shellcheck versions may flag previously-ignored patterns. Review any new failures before updating. diff --git a/docs/how-to/how-to.md b/docs/how-to/how-to.md index 2a80d7d..f28cad7 100644 --- a/docs/how-to/how-to.md +++ b/docs/how-to/how-to.md @@ -28,7 +28,7 @@ Task-oriented instructions for common BlumeOps operations. These guides assume y | [[expose-service-publicly]] | Expose a service to the public internet via Fly.io + Tailscale | | [[manage-forgejo-mirrors]] | Create mirrors, update PATs, and rotate GitHub credentials | | [[update-documentation]] | Publish docs via build-blumeops workflow | -| [[update-tooling-dependencies]] | Monthly update cycle for pre-commit, Fly, mise, and workflow deps | +| [[update-tooling-dependencies]] | Monthly update cycle for prek hooks, Fly, mise, and workflow deps | ## Knowledge Base diff --git a/docs/how-to/zot/add-container-version-sync-check.md b/docs/how-to/zot/add-container-version-sync-check.md index cd9f39e..2ebe3d8 100644 --- a/docs/how-to/zot/add-container-version-sync-check.md +++ b/docs/how-to/zot/add-container-version-sync-check.md @@ -14,7 +14,7 @@ tags: # Add Container Version Sync Check -Add a pre-commit check that validates version consistency across the three places container versions are declared: Dockerfile ARGs, `service-versions.yaml`, and nix derivations. No VERSION files needed — the existing sources are the source of truth, and the check enforces they agree. +Add a prek check that validates version consistency across the three places container versions are declared: Dockerfile ARGs, `service-versions.yaml`, and nix derivations. No VERSION files needed — the existing sources are the source of truth, and the check enforces they agree. ## Context @@ -38,7 +38,7 @@ Blacklisted containers (utility images, not tracked services): `kubectl`, `nette Container-to-service name mapping: `quartz` → `docs`, `kiwix-serve` → `kiwix`. -### 2. Added pre-commit hook +### 2. Added prek hook ```yaml - id: container-version-check @@ -62,7 +62,7 @@ The check discovered that ntfy's Dockerfile pins v2.17.0 but nixpkgs has ntfy-sh | File | Change | |------|--------| | `mise-tasks/container-version-check` | New: typer CLI sync validation script | -| `.pre-commit-config.yaml` | Add `container-version-check` hook | +| `prek.toml` | Add `container-version-check` hook | | `service-versions.yaml` | Populate `current-version` for all hybrid services + authentik | ## Verification diff --git a/docs/how-to/zot/adopt-commit-based-container-tags.md b/docs/how-to/zot/adopt-commit-based-container-tags.md index 86fd46b..c8b1087 100644 --- a/docs/how-to/zot/adopt-commit-based-container-tags.md +++ b/docs/how-to/zot/adopt-commit-based-container-tags.md @@ -42,7 +42,7 @@ Each container's version is extracted at build time from existing declarations - **Dockerfile builds**: parsed from `ARG CONTAINER_APP_VERSION=` in the Dockerfile - **Nix builds**: extracted from `version = "..."` in `default.nix`, or `CONTAINER_APP_VERSION` from the Dockerfile, or `dagger call nix-version` for nixpkgs packages -The [[add-container-version-sync-check]] pre-commit check ensures these declarations stay in sync with `service-versions.yaml`. See [[pin-container-versions]] for the work to ensure every container has a parseable version. +The [[add-container-version-sync-check]] prek check ensures these declarations stay in sync with `service-versions.yaml`. See [[pin-container-versions]] for the work to ensure every container has a parseable version. ### Image Tag Format diff --git a/docs/tutorials/contributing.md b/docs/tutorials/contributing.md index c10a235..61d32e8 100644 --- a/docs/tutorials/contributing.md +++ b/docs/tutorials/contributing.md @@ -27,7 +27,7 @@ The repo includes a `Brewfile` and `mise.toml` for easy setup, but these are opt - `tea` - Gitea/Forgejo CLI for creating PRs - `argocd` - ArgoCD CLI for deployments -- `pre-commit` - Git hooks for validation +- `prek` - Git hooks for validation ### Using Brewfile (Optional) @@ -42,12 +42,12 @@ Mise manages language toolchains and runs tasks: mise install # installs Python, Node.js, etc. from mise.toml ``` -### Pre-commit Hooks +### Git Hooks (prek) -Pre-commit hooks validate changes on `git commit`: +Git hooks validate changes on `git commit`: ```bash -pre-commit install -pre-commit run --all-files # verify setup +prek install +prek run --all-files # verify setup ``` All hooks should pass on a fresh clone. diff --git a/mise.toml b/mise.toml index c53f19d..6bba97e 100644 --- a/mise.toml +++ b/mise.toml @@ -1,5 +1,5 @@ [tools] "pipx:ansible-core" = { version = "latest", uvx = "true", uvx_args = "--with botocore --with boto3" } -"pipx:pre-commit" = { version = "latest", uvx = "true" } +prek = "latest" pulumi = "latest" dagger = "latest" diff --git a/prek.toml b/prek.toml new file mode 100644 index 0000000..7b9e06b --- /dev/null +++ b/prek.toml @@ -0,0 +1,169 @@ +# prek.toml - Git hooks configuration +# Run: prek run --all-files +# Install: prek install && prek install --hook-type commit-msg + +# Built-in hooks (fast, Rust-native — no external dependencies) +[[repos]] +repo = "builtin" +hooks = [ + { id = "trailing-whitespace" }, + { id = "end-of-file-fixer" }, + { id = "check-added-large-files", args = [ + "--maxkb=1000", + ] }, + { id = "check-merge-conflict" }, + { id = "check-json" }, + { id = "check-toml" }, + { id = "check-case-conflict" }, + { id = "detect-private-key" }, + { id = "check-executables-have-shebangs" }, +] + +# check-yaml with --unsafe (builtin fast path doesn't support --unsafe yet) +[[repos]] +repo = "https://github.com/pre-commit/pre-commit-hooks" +rev = "v6.0.0" +hooks = [{ id = "check-yaml", args = ["--unsafe"] }] + +# Secret detection +[[repos]] +repo = "https://github.com/trufflesecurity/trufflehog" +rev = "v3.93.4" +hooks = [ + { id = "trufflehog", entry = "trufflehog git file://. --since-commit HEAD --no-verification --fail", stages = [ + "pre-commit", + "pre-push", + ] }, +] + +# YAML linting +[[repos]] +repo = "https://github.com/adrienverge/yamllint" +rev = "v1.38.0" +hooks = [{ id = "yamllint", args = ["-c", ".yamllint.yaml"] }] + +# Ansible linting +[[repos]] +repo = "local" + +[[repos.hooks]] +id = "ansible-lint" +name = "ansible-lint" +entry = "env ANSIBLE_ROLES_PATH=ansible/roles ansible-lint" +language = "python" +files = "^ansible/" +additional_dependencies = ["ansible-lint>=26.1.1", "ansible-core>=2.15"] + +# Python - ruff for linting and formatting +[[repos]] +repo = "https://github.com/astral-sh/ruff-pre-commit" +rev = "v0.15.2" +hooks = [{ id = "ruff", args = ["--fix"] }, { id = "ruff-format" }] + +# Shell scripts - shellcheck and shfmt +[[repos]] +repo = "https://github.com/shellcheck-py/shellcheck-py" +rev = "v0.11.0.1" +hooks = [{ id = "shellcheck", args = ["--severity=warning"] }] + +[[repos]] +repo = "https://github.com/scop/pre-commit-shfmt" +rev = "v3.12.0-2" +hooks = [{ id = "shfmt", args = ["-i", "2", "-ci", "-bn"] }] + +# TOML - taplo +[[repos]] +repo = "https://github.com/ComPWA/taplo-pre-commit" +rev = "v0.9.3" +hooks = [{ id = "taplo-format" }, { id = "taplo-lint" }] + +# JSON formatting (prettier for consistent style) +[[repos]] +repo = "https://github.com/rbubley/mirrors-prettier" +rev = "v3.8.1" +hooks = [{ id = "prettier", types_or = ["json"], args = ["--tab-width", "2"] }] + +# GitHub/Forgejo Actions workflow linting +[[repos]] +repo = "https://github.com/rhysd/actionlint" +rev = "v1.7.11" +hooks = [ + { id = "actionlint-system", args = [ + "-config-file", + ".github/actionlint.yaml", + ], files = '\.forgejo/workflows/' }, +] + +# Custom local hooks + +# Forgejo workflow schema validation (via Dagger + forgejo-runner validate) +[[repos]] +repo = "local" + +[[repos.hooks]] +id = "validate-workflows" +name = "validate-workflows" +entry = "mise run validate-workflows" +language = "system" +files = '\.forgejo/workflows/' +pass_filenames = false + +# Container version consistency +[[repos]] +repo = "local" + +[[repos.hooks]] +id = "container-version-check" +name = "container-version-check" +entry = "mise run container-version-check" +language = "system" +files = "^(containers/|service-versions\\.yaml)" +pass_filenames = false + +# Mikado Branch Invariant (C2 changes) +[[repos]] +repo = "local" + +[[repos.hooks]] +id = "mikado-branch-invariant-check" +name = "mikado-branch-invariant-check" +entry = "mise run mikado-branch-invariant-check" +language = "system" +always_run = true +stages = ["commit-msg"] + +# Documentation validation +[[repos]] +repo = "local" + +[[repos.hooks]] +id = "docs-check-filenames" +name = "docs-check-filenames" +entry = "mise run docs-check-filenames" +language = "system" +files = '^docs/.*\.md$' +pass_filenames = false + +[[repos.hooks]] +id = "docs-check-links" +name = "docs-check-links" +entry = "mise run docs-check-links" +language = "system" +files = '^docs/.*\.md$' +pass_filenames = false + +[[repos.hooks]] +id = "docs-check-index" +name = "docs-check-index" +entry = "mise run docs-check-index" +language = "system" +files = '^docs/.*\.md$' +pass_filenames = false + +[[repos.hooks]] +id = "docs-check-frontmatter" +name = "docs-check-frontmatter" +entry = "mise run docs-check-frontmatter" +language = "system" +files = '^docs/.*\.md$' +pass_filenames = false