This post may contain affiliate links. Please read my disclaimer for more info.

I’ve been storing my Home Assistant configuration on GitHub for a while now. Right now, there are over 350 other people doing the same thing! There are some great benefits of using git to manage your configuration, especially if you already have familiarity with the tools. You can go back and see any change you’ve made with comments from your past self explaining the change. You can try out things in a branch and quickly revert back if the experiment didn’t work, or needs more development time.

In today’s article, I’ll be showing how I use git hooks to manage my configuration. It adds some automated tests to run on your configuration every time you make a change. You can check your YAML’s syntax and make sure it is following best practices, check any AppDaemon Python code for potential errors, and even check other formats like XML and JSON if you have some of those in your configuration.

This article assumes you’re already using git to manage your Home Assistant configuration and know about adding files and committing.

What are git hooks?

If you’ve been using git for a while, you’re familiar with the process of adding files, committing them and then pushing them to the remote server. Git is a powerful tool and enables flexibility using something called git hooks. These allow you to run any scripts or tools at any part of the git process automatically.

In my case, I like to run a few automated tests on the files that got added or changed. I’m using a “pre-commit” hook. The checks are run automatically for me when I run git commit and are completed before the commit is made.

So if you’re thinking about your workflow, you’ll add files after making changes to them. Once you’re happy with the changes you commit them. This “pre-commit” hook runs when you commit your changes. The hook just double-checks that everything looks good before it’s actually committed. My typical flow on the command line:

# make some edits to configuration.yaml and then add it git add configuration.yaml # git automatically runs pre-commit hooks to check the files added when you run git commit git commit -m "Updated my configuration" 1 2 3 4 5 # make some edits to configuration.yaml and then add it git add configuration . yaml # git automatically runs pre-commit hooks to check the files added when you run git commit git commit - m "Updated my configuration"

While you can write your own pre-commit hooks, there is a great open-source tool called pre-commit that allows people to share these easily. It’s what I use to manage the git hooks for my configuration.

If you’re more interested in learning about Git hooks, githooks.com is a great resource.

Home Assistant Git Hooks

First off, you’ll need to install pre-commit on the machine you develop your configuration on. They have some good documentation on their website, but if you have python installed you can usually just do a pip install pre-commit to get running. For command-line tools written in Python like this, I’ve recently been using pipx to install and isolate their dependencies. Definitely not required, but check out the project if it interests you.

Now that pre-commit is installed, cd into your Home Assistant configuration directory and run:

pre-commit install 1 pre - commit install

This will tell git to run your pre-commit hooks. It essentially creates a file in your .git/hooks directory that is called during the commit phase.

To tell pre-commit about what hooks you want to run, you have to create a .pre-commit-config.yaml file in the root of your repository. This allows you to pull in hooks from other git repository and customize how they run. As of this blog post, mine looks like this:

--- exclude: homeassistant/custom_components repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.3.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer exclude: config/homeassistant/.HA_VERSION - id: check-added-large-files - id: check-json - id: check-merge-conflict - id: check-symlinks - id: mixed-line-ending - id: check-xml - id: check-yaml args: [--unsafe] - id: sort-simple-yaml - repo: https://github.com/IamTheFij/docker-pre-commit.git rev: v1.0.0 hooks: - id: docker-compose-check - repo: https://github.com/adrienverge/yamllint.git rev: v1.17.0 hooks: - id: yamllint - repo: https://github.com/psf/black.git rev: 19.3b0 hooks: - id: black 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 --- exclude : homeassistant/custom_components repos : - repo : https ://github.com/pre-commit/pre-commit-hooks rev : v2.3.0 hooks : - id : trailing-whitespace - id : end-of-file-fixer exclude : config/homeassistant/.HA_VERSION - id : check-added-large-files - id : check-json - id : check-merge-conflict - id : check-symlinks - id : mixed-line-ending - id : check-xml - id : check-yaml args : [--unsafe] - id : sort-simple-yaml - repo : https ://github.com/IamTheFij/docker-pre-commit.git rev : v1.0.0 hooks : - id : docker-compose-check - repo : https ://github.com/adrienverge/yamllint.git rev : v1.17.0 hooks : - id : yamllint - repo : https ://github.com/psf/black.git rev : 19.3b0 hooks : - id : black

I recommend though starting small and adding hooks incrementally. By design, pre-commit only runs on files that are being added in your commit. If you want to run it against all files sitting in your repository, run:

pre-commit run --all-files 1 pre - commit run -- all - files

Some good ones to start out with are the trailing-whitespace hook and the end-of-file-fixer , issues found by these are relatively straightforward to fix.

Check out the pre-commit documentation to learn the full syntax of this file.

YAML Configuration

Most of my repository is YAML configuration for Home Assistant. The yamllint hook checks for issues and ensures you are doing best practices when working with YAML. You can see in the configuration above I pass the --unsafe argument to the hook. This is to tell the hook that the !include statements frequent in Home Assistant YAML files are okay.

Underneath it all, this hook is using yamllint to get the job done. Although, we don’t have to worry about that since we are using pre-commit to manage the hooks. With that being said, we can customize how yamllint runs by adding a .yamllint file to the root of the configuration. In my case, I didn’t like that yamllint throws an error when lines are greater than 80 characters. So I configured that in the .yamllint file .

--- rules: line-length: level: warning 1 2 3 4 5 --- rules : line - length : level : warning

Python Formatting

If you’re using AppDaemon to write any of your automations, you may have a fair amount of Python code also sitting in your repository. To keep formatting consistent across all your source code, the black tool can be used to automatically format your Python code. Check my configuration above for how to add it.

After enabling it, run it across your whole repository to automatically format your Python code using best practices.

Checking Syntax of Files

You’ve probably got a myriad of other file formats in your Home Assistant configuration git repository. Maybe you’ve written some README Markdown files to provide some documentation for people viewing your repository. Or HTML and CSS files for a custom display panel you use in Home Assistant. Pre-commit has a community page where users share their hooks. Browse through the hooks or search for any keywords that might be useful for your configuration. I like to add some basic checks on XML and JSON files in my repository to ensure they don’t have broken syntax.

Other Tips

If you’re using Home Assistant custom components in your repository, you probably don’t want pre-commit telling you about issues in them. Luckily, there is an exclude keyword at the top of the .pre-commit-config.yaml file that you can use to exclude files. Look at my configuration above for how I excluded the custom_components directory.

The end-of-file-fixer ensures that files end with a newline character. However, the .HA_VERSION file that Home Assistant creates never ends with a newline character. I decided to disable this commit hook on the file to stop pre-commit from changing it.

Let me know if you have any other tips for managing your Home Assistant configuration with pre-commit hooks.

Summary

I’m all about making my workflow more efficient and correct for managing my Home Assistant configuration using git. Adding git hooks using pre-commit is a straightforward way to add some nice automated tests that the configuration won’t have any syntax errors and is following best practices.

Let me know if you are managing your Home Assistant configuration using git and any other tips you might have!