A framework to prevent invalid stuff in your GIT repository

A framework to prevent invalid stuff in your GIT repository

The following blog post describes a a framework for managing and maintaining multi-language pre-commit hooks. The described methods adding a comprehensive quality gate to your publishing workflow. If you are using SVN instead of GIT you can skip this blog post 😛

The framework was designed by Yelp three years ago. It brings many pre defined checks designed for a generated GIT pre-commit hook. Most of the checks are made to to run against python files. This is not a blocker for PHP developers. Fortunately the framework can be extended by scripts. It’s also possible to share the checks in extra remote repositories. So you can build a pre-commit kit for your purposes. The standard repository comes with some nice checks for i.e. XML or YAML files. Other stuff like checking for broken symlinks or “merge residues”. A complete list and a documentation can be found on project website.

Installation

The installation is simple. It can be done by brew or the python installer pip. Most Linux distributions come with pip already installed. Mac users can install python with pip or use brew.

On Mac:

brew install pre-commit

or with Python PIP:

pip install pre-commit

After the installation we should have a binary “pre-commit”.

Config

For configuration a YAML format is used. All the configs are validated by pre-commit. That’s a good thing. If you have a mistake in your config file it will print out a long list of syntax rules. Config entries start with a „repo“ which must be a git repository URL. The example shows the external repository provided by hootsuite.

- repo: git@github.com:hootsuite/pre-commit-php.git
   sha: 1.2.0
   hooks:
   - id: php-lint
   - id: php-unit
   - id: php-cs-fixer
     files: \.(php)$

Hooks can also be defined locally. Add the pseudo repository name „local“:

- repo: local
  hooks:
    - id: "run-unit-tests"
      name: "Run Unit-Tests"
      entry: "./vendor/bin/phpunit"
      language: "script"
      always_run: true
      files: \.(php)$

Every rule must have an IDE. That’s important if you share a rule in your own repository. If the rule is provided by an external repository it must be defined in a „hooks.yaml“ file. To use the hooks in your lokal project a .pre-commit-config.yaml file must be created.

Install the hooks

The installation of the hooks in your config can be done by running pre-commit install. That’s all we need to do. After that all our commits are checked by the installed hooks.
It’s also possible to update the YAML file versions like „composer update“ with pre-commit autoupdate. This fetches the newest version of the commits from remote repositories.

Test the hooks

Simply run pre-commit run --all-files to test all hooks against the whole local working copy.

Commit your code

Congratulations! You have now a QA step between you and your CI server. If you commit some code the automatic checks should run and prevent bigger issues. To secure the complete project it’s necessary to setup the same checks on your continuous integration server. If you don’t have a CI-Server like Jenkins, Gitlab etc. and working for your own this setup is good enough.

git commit -a

Example config for a PHP library

This config provides us the following checks:

  • Validate composer.json file with composer
  • Prevent large files in commits like a database dump
  • Check for valid JSON and XML files
  • Check if merge conflict entries are not resolved
  • Check if a file has a wrong BOM
  • Run php-cs-fixer and fix code against a .php_cs file.

Example .pre-commit-config.yaml:

-   repo: local
    hooks:
    -   id: validate-composer-json
        name: Validate Composer JSON
        entry: "composer validate --strict"
        language: system
        files: composer\.json
-   repo: git://github.com/pre-commit/pre-commit-hooks
    sha: 5da199bb8d60f764c0f77a20b0a1dc3a7640bcdd
    hooks:
    -   id: check-added-large-files
    -   id: php-unit
    -   id: check-json
    -   id: check-xml
    -   id: check-merge-conflict
    -   id: check-byte-order-marker
-   repo: git://github.com/hootsuite/pre-commit-php.git
    sha: 1.2.0
    hooks:
    -   id: php-cs-fixer
        args:
        - -q
        - --config-file=.php_cs
    -   id: php-lint-all

Output:

If you find the concept good, we would be happy if you leave a comment.

Have fun!

 

PS: Thanks to David Lambauer for discovering the framework at netz98.

One thought on “A framework to prevent invalid stuff in your GIT repository

Leave a Reply

%d bloggers like this: