Tag: pre-commit

  • 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.