# 002 - Pre-commit hooks

By
Gil Ferreira
,
Mina Wahba

Last Modified: July 1st, 2025

Title: Adoption of Pre-commit hooks

Status: Accepted


# Context

Our development teams have historically lacked a standardized approach to code formatting and linting. Each developer has been using their own tools and configurations, leading to inconsistencies in code style, formatting, and structure across the codebase. These discrepancies are particularly evident when collaborating across different operating systems (e.g., Ubuntu, macOS, Windows), where line endings, file permissions, and formatting behaviors can vary.

To address these issues, we are introducing pre-commit hooks as a standard across all projects. These hooks will ensure a consistent, readable, and high-quality codebase. By adhering to these practices, we aim to improve collaboration, reduce bugs, and create a smoother development experience for everyone involved.


# Decision

We will adopt pre-commit hooks as a mandatory standard across all projects to enforce consistent linting, formatting, and code quality checks before code is committed.


# Rationale

  1. Consistency: Enforces uniform linting and formatting across all developers and platforms.
  2. Automation: Reduces manual effort and human error by running checks automatically before commits.
  3. Cross-platform support: Handles OS-specific differences (e.g., line endings) seamlessly.
  4. Improved code reviews: Prevents unnecessary diffs caused by whitespace or formatting changes, making Git history cleaner and reviews more focused on actual logic and functionality.
  5. Scalability: Simplifies onboarding and ensures standards are upheld as the team grows.

# Implications

  1. People/Training:
  • Minimal training is needed, as the setup.sh script automates the installation of pre-commit hooks and applies necessary fixes.
  • Developers should understand how to handle failures from tools like bandit (security checks) and pytest (unit tests), and be prepared to write missing tests when needed.
  1. Process Adjustments:
  • Developers must run setup.sh when joining or cloning a project to ensure the environment is correctly configured.
  • The first run may trigger many linting changes, requiring multiple git add and git commit --amend steps to clean up the commit history.
  1. Tooling: The setup.sh script will install:
  • Pre-commit hooks
  • TFLint for Terraform linting
  • Chocolatey (on Windows) for dependency management
  • python or npm requirements
  1. Risks:
  • Initial friction: Large volumes of auto-fixes on first run may confuse developers unfamiliar with the tools.
  • Test enforcement: If pytest or bandit fail, developers must know how to resolve issues or write appropriate tests.
  • Platform-specific edge cases: While the script handles most OS differences, some manual fixes may still be required.

# Trade-Offs

  • Benefits:
  • Consistent codebase across all developers and platforms.
  • Cleaner Git history with fewer formatting-only commits.
  • Faster onboarding with automated setup and enforced standards.
  • Reduced manual effort through automated linting and testing.
  • Drawbacks:
  • Initial friction due to large formatting changes on first run.
  • Learning curve for handling failures from tools like bandit and pytest.
  • Slight overhead in commit workflow (e.g., re-committing after fixes).

# Key Evaluation Metrics

  • Decrease in merge conflicts caused by whitespace or style differences.
  • Number of projects successfully adopting and running pre-commit hooks.
  • Developer feedback on ease of setup and day-to-day usage.

# Conclusion

# What is the final recommendation?

We recommend standardizing pre-commit hooks across all projects to enforce consistent code quality, reduce review overhead, and streamline collaboration across platforms. While there may be some initial setup friction and a minor learning curve, the long-term benefits, such as cleaner code, faster onboarding, and fewer formatting issues, significantly outweigh the drawbacks. The next step is to roll out the setup.sh script and .pre-commit-config.yaml across all repositories and support teams during the initial adoption phase.


# References

Example from the ibp_authorizer project:

pre-commit run --all-files
trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
check for added large files..............................................Passed
check yaml...............................................................Passed
ruff-format..............................................................Passed
ruff.....................................................................Passed
bandit...................................................................Passed
mypy.....................................................................Passed
Run terraform linter.....................................................Passed
- hook id: tflint
- duration: 0.5s
Run pytest tests.........................................................Passed
- hook id: pytest
- duration: 0.86s