Skip to main content

🪝 Git Hooks

Run flutter analyze, tests, or any FRX pipeline automatically — triggered by git itself.

FRX ships a Husky-like git hooks system powered by its own pipeline engine. Define hooks in config.yaml, install them once, and git does the rest. Fully opt-in, per hook.


How It Works

git commit
└─▶ .git/hooks/pre-commit ← written by frx hooks install
└─▶ frx hooks run pre-commit
└─▶ Reads config.yaml → hooks.pre-commit
└─▶ Runs your steps sequentially
└─▶ exit 0 → git proceeds ✅
exit 1 → git ABORTS ❌

No daemons. No extra processes. Just a tiny shell script that calls back into FRX.


Quick Start

# 1. Generate a starter config (includes hooks template)
frx init

# 2. Edit config.yaml — enable a hook
# hooks:
# pre-commit:
# enabled: true
# steps:
# - name: "Analyze"
# command: "flutter analyze"

# 3. Install hooks into .git/hooks/
frx hooks install

# 4. Verify
frx hooks list

That's it. Every git commit now runs your steps automatically.


Commands Reference

CommandDescription
frx hooks installInstall all enabled hooks into .git/hooks/
frx hooks install --dry-runPreview what would be installed (no files written)
frx hooks install --dir <path>Target a specific project directory
frx hooks uninstallRemove all FRX-managed hooks
frx hooks uninstall --hook <name>Remove a single hook by name
frx hooks listStatus table: config vs disk state
frx hooks run <name>Manually trigger a hook (great for testing)
frx hooks validateValidate config and show actionable warnings
tip

All commands accept --config <path> to point at a custom config file.


Configuration Schema

hooks:
pre-commit: # git hook name (any standard hook)
enabled: true # opt-in (default: false)
description: "Quality gates" # shown in frx hooks list
stop_on_failure: true # abort git op on any step failure
steps:
- name: "Analyze" # required — shown in output
command: "flutter analyze" # required — shell command to run
description: "Static analysis"
timeout: 60 # kill after 60s
allow_failure: false # true = warn only, don't abort
env: # per-step environment variables
CI: "true"
working_directory: "./app" # override cwd for this step

pre-push:
enabled: true
run_pipeline: ci # delegate to a named pipeline

Hook Fields

FieldTypeRequiredDefaultDescription
enabledboolYesfalseWhether this hook is active
descriptionstringNoShown in frx hooks list
stop_on_failureboolNotrueAbort git operation if any step fails
stepslistNo*[]Inline steps to run
run_pipelinestringNo*Delegate to a named FRX pipeline

*At least one of steps or run_pipeline is required.

Step Fields

FieldTypeRequiredDefaultDescription
namestringYesLabel shown in terminal output
commandstringYesShell command to execute
descriptionstringNoHuman-readable description
allow_failureboolNofalseIf true, failure is a warning — hook continues
timeoutintNoKill step after N seconds
envmapNo{}Extra environment variables for this step
working_directorystringNocurrent dirOverride working directory

Supported Hook Names

Any standard git hook name works as a key. Most commonly used:

HookWhen It FiresBest Used For
pre-commitBefore commit is createdLint, format, unit tests
commit-msgAfter you write the messageValidate commit format
prepare-commit-msgBefore message editor opensAuto-fill templates
post-commitAfter commit completes (can't abort)Notifications, logging
pre-merge-commitBefore merge commitMerge-specific checks
pre-pushBefore git pushIntegration tests, final checks
post-mergeAfter git merge or git pullflutter pub get, dependency sync
post-checkoutAfter git checkout/git switchEnvironment setup

Safety Guarantees

  • Never clobbers custom hooks — if .git/hooks/pre-commit already exists and wasn't written by FRX, FRX skips it and tells you exactly what to do.
  • FRX-marker identification — every FRX hook script contains a unique header. frx hooks uninstall only removes files it created.
  • Graceful degradation — if frx isn't in PATH when git triggers the hook, the hook exits 0 (safe) and prints installation instructions.
  • Idempotent installs — running frx hooks install multiple times is safe. It safely replaces its own scripts.

FAQ

Can I use hooks with a monorepo?

Yes. FRX walks up the directory tree to find .git/, so you can run frx hooks install from any subdirectory.

What happens if a step times out?

The step is killed and treated as a failure. If stop_on_failure: true, the hook exits 1 and git aborts.

Can I delegate to an existing FRX pipeline?

Yes — use run_pipeline: <name> instead of steps:. The pipeline must be defined in the pipelines: section of the same config.

hooks:
pre-push:
enabled: true
run_pipeline: ci # runs your "ci" pipeline

How do I temporarily disable a hook without uninstalling?

Set enabled: false in config.yaml. The script stays in .git/hooks/ but FRX skips execution.

Can I use this for non-Flutter projects?

Absolutely. Every command is a plain shell command. Use it with React, Python, Node, or any project that uses git.


See Also