Switch git hooks from pre-commit to prek #276
12 changed files with 192 additions and 170 deletions
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 <noreply@anthropic.com>
commit
63263abb97
2
.github/USE_FORGE_WORKFLOWS.md
vendored
2
.github/USE_FORGE_WORKFLOWS.md
vendored
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
1
docs/changelog.d/switch-to-prek.infra.md
Normal file
1
docs/changelog.d/switch-to-prek.infra.md
Normal file
|
|
@ -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`.
|
||||
|
|
@ -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 <chain>` | 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ Each container's version is extracted at build time from existing declarations
|
|||
- **Dockerfile builds**: parsed from `ARG CONTAINER_APP_VERSION=<value>` 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
169
prek.toml
Normal file
169
prek.toml
Normal file
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue