Skip to content

tobydoescode/hass-config-sync

Repository files navigation

Home Assistant Config Sync

A Home Assistant add-on that pulls configuration from a git repository and intelligently reloads only the affected domains instead of performing a full restart. Supports SOPS-encrypted secrets and webhook triggers.

Features

  • Selective reload — only reloads domains whose files changed (automations, scripts, scenes, themes, etc.)
  • Full restart fallback — for configuration.yaml, secrets.yaml, packages/, custom_components/, or unknown files
  • SOPS integration — decrypts secrets.enc.yamlsecrets.yaml after each pull using age encryption
  • Webhook + polling — GitHub can trigger immediate sync via POST, plus regular polling interval
  • Config validation — checks config before any reload/restart
  • Local changes protection — if someone edits config via the HA UI, changes are saved to a branch and a persistent notification is raised

Installation

  1. Clone this repo into /addons/ on your HA host:
    cd /addons
    git clone git@github.com:tobydoescode/ha-app-git-sync.git
  2. In HA: Settings → Add-ons → Add-on Store → ⋮ (top right) → Check for updates
  3. Find "Git Sync with Selective Reload" under Local add-ons and install it

Configuration

Option Default Description
repository required Git repo URL (SSH or HTTPS)
branch main Branch to track
ssh_key SSH private key for git auth
git_token HTTPS token for git auth
poll_interval 300 Seconds between polls (30–86400)
auto_restart true Restart HA if reload isn't sufficient
check_config true Validate config before reload/restart
restart_on_unknown true Restart when changed files can't be mapped to a reload
reload_map see below INI-style file-to-action mapping
sops_enabled false Decrypt encrypted files after pull
sops_age_key_file Path to age key file
sops_files see below List of encrypted = decrypted file pairs
webhook_enabled false Listen for webhook triggers
webhook_port 8199 Port for webhook listener

Setting up SOPS encryption

This keeps secrets.yaml out of your git repo. Only the encrypted secrets.enc.yaml is committed.

1. Generate an age key

Run this locally (or anywhere with age installed):

age-keygen -o sops-age-key.txt

This prints a public key like age1abc123.... Save it — you'll need it next.

Copy the key file to your HA host:

scp sops-age-key.txt root@<ha-host>:/config/.sops-age-key.txt

2. Create .sops.yaml in your HA config repo

creation_rules:
  - path_regex: secrets\.enc\.yaml$
    age: "age1abc123..."  # your public key from step 1

3. Encrypt your secrets

sops -e secrets.yaml > secrets.enc.yaml

4. Update .gitignore

# Decrypted secrets — never commit
secrets.yaml
.sops-age-key.txt

# HA runtime files
home-assistant_v2.db
home-assistant_v2.db-wal
home-assistant_v2.db-shm
__pycache__/
*.pyc
tts/
.cloud/
.storage/auth*
backups/

5. Configure the add-on

Set these options in the add-on configuration:

sops_enabled: true
sops_age_key_file: /config/.sops-age-key.txt
sops_files:
  - "secrets.enc.yaml = secrets.yaml"
  - "esphome/secrets.enc.yaml = esphome/secrets.yaml"

The add-on will decrypt each encrypted file to its decrypted counterpart after every pull. Paths are relative to /config/.

6. Editing secrets

Use sops to edit — it decrypts in your editor and re-encrypts on save:

sops secrets.enc.yaml

Or edit secrets.yaml directly and re-encrypt:

sops -e secrets.yaml > secrets.enc.yaml

Development workflow

Setup

# Clone onto HA host
ssh root@<ha-host>
cd /addons
git clone git@github.com:tobydoescode/ha-app-git-sync.git

Install from HA: Settings → Add-ons → Add-on Store → Local add-ons

Local tasks

Requires Task:

task test              # run all tests
task test:unit         # unit tests only
task test:integration  # integration tests only
task build             # build the Docker image
task shell             # build + open a shell in the container

Iterate

# On your local machine — make changes, push
git add -A && git commit -m "..." && git push

# On HA host — pull changes
ssh root@<ha-host> "cd /addons/ha-app-git-sync && git pull"

Then in HA: Add-on page → ⋮ (three-dot menu, top right) → Rebuild

Check logs: Add-on page → Log tab

Local changes protection

If someone edits config through the HA UI (e.g. automations, scripts), the add-on will detect uncommitted changes before syncing and:

  1. Commit them to a timestamped branch (e.g. local/changes-20260409-120000)
  2. Attempt to push the branch to the remote
  3. Raise a persistent notification in the HA UI
  4. Continue syncing from the main branch

If push fails, the branch is kept locally on the HA host.

Reload mapping

The reload_map option controls which files trigger which actions. It uses an INI-style format where sections are actions and lines are glob patterns:

[automation/reload]
automations.yaml
automations/*

[script/reload]
scripts.yaml
scripts/*

[RESTART]
configuration.yaml
secrets.yaml
packages/*
custom_components/*

[IGNORE]
.gitignore
*.md

Actions:

  • [domain/service] — calls the HA reload service (e.g. automation/reload)
  • [RESTART] — triggers a full HA restart
  • [IGNORE] — skips the file entirely

Files not matching any pattern are treated as unknown (restart if restart_on_unknown is true).

To add a custom integration, just add a new section:

[pyscript/reload]
pyscript/*

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors