Adds a config-sync sidecar to the home-assistant pod so merges to main of the homeassistant repo auto-deploy into the running instance. Closes the gap found while verifying PR #8 (notifications): HA's /config is an RWO PVC git checkout with no automated pull, so merged config sat undeployed.
How it works
A small alpine/git:2.54.0 sidecar shares the config PVC. Loop (30s):
git fetch origin main
on change, force-sync only the HA config paths — automations.yaml + automations/, packages/, scripts.yaml, templates.yaml, configuration.yaml, notify.yaml, groups.yaml, powercalc.yaml, blueprints/ — via git checkout origin/main -- <paths>, then advance the branch ref without touching the working tree
POST /api/services/homeassistant/reload_all (no restart)
Left untouched on purpose:www/ (HACS rewrites those tracked files at runtime) and untracked runtime state (.storage/, *.db, secrets.yaml). git auth reuses the PAT already embedded in the PVC's remote URL; reload auth uses a long-lived token in a sops secret (config-sync-token.sops.yaml, same age recipient as the other HA secrets).
Script lives in config-sync.sh (mounted via configMapGenerator, hash suffix disabled like the nginx one — editing it needs a manual rollout restart).
⚠️ Behavioral consequence — git is now source of truth
Uncommitted edits to a synced path made directly in code-server, or via HA's UI automation editor (which writes automations.yaml), are reverted within ~30s. Commit + push to persist. Helpers/integrations configured through the HA UI live in .storage/ (untracked) and are unaffected.
🔑 Follow-up — rotate the token
The reload token currently reuses the existing HA long-lived token, to get this live with zero extra steps. Recommend minting a dedicated config-sync LLAT (HA → Profile → Security) and replacing the secret, so it's revocable independently of the personal token.
Notes / limits
First sync deploys everything merged-but-not-yet-pulled (currently PR #7 Solcast + PR #8 notifications) and reloads.
reload_all covers automations/scripts/templates/packages; a change to the notify: rest platform or a new integration would still need a restart (not the case here).
File deletions of a synced path aren't propagated by checkout -- <path> (edits/adds are); rare for config, can harden later.
Validated: kubectl kustomize builds (32 objects), all refs resolve, token sealed (sops, 0 plaintext leak). Not yet applied — Flux deploys on merge.
## What
Adds a `config-sync` sidecar to the home-assistant pod so merges to `main` of the `homeassistant` repo auto-deploy into the running instance. Closes the gap found while verifying PR #8 (notifications): HA's `/config` is an RWO PVC git checkout with **no** automated pull, so merged config sat undeployed.
## How it works
A small `alpine/git:2.54.0` sidecar shares the `config` PVC. Loop (30s):
1. `git fetch origin main`
2. on change, **force-sync only the HA config paths** — `automations.yaml` + `automations/`, `packages/`, `scripts.yaml`, `templates.yaml`, `configuration.yaml`, `notify.yaml`, `groups.yaml`, `powercalc.yaml`, `blueprints/` — via `git checkout origin/main -- <paths>`, then advance the branch ref without touching the working tree
3. `POST /api/services/homeassistant/reload_all` (no restart)
**Left untouched on purpose:** `www/` (HACS rewrites those tracked files at runtime) and untracked runtime state (`.storage/`, `*.db`, `secrets.yaml`). git auth reuses the PAT already embedded in the PVC's remote URL; reload auth uses a long-lived token in a sops secret (`config-sync-token.sops.yaml`, same age recipient as the other HA secrets).
Script lives in `config-sync.sh` (mounted via `configMapGenerator`, hash suffix disabled like the nginx one — editing it needs a manual `rollout restart`).
## ⚠️ Behavioral consequence — git is now source of truth
Uncommitted edits to a **synced path** made directly in code-server, **or via HA's UI automation editor** (which writes `automations.yaml`), are reverted within ~30s. Commit + push to persist. Helpers/integrations configured through the HA UI live in `.storage/` (untracked) and are unaffected.
## 🔑 Follow-up — rotate the token
The reload token currently **reuses the existing HA long-lived token**, to get this live with zero extra steps. Recommend minting a dedicated `config-sync` LLAT (HA → Profile → Security) and replacing the secret, so it's revocable independently of the personal token.
## Notes / limits
- First sync deploys everything merged-but-not-yet-pulled (currently PR #7 Solcast + PR #8 notifications) and reloads.
- `reload_all` covers automations/scripts/templates/packages; a change to the `notify:` rest platform or a new integration would still need a restart (not the case here).
- File deletions of a synced path aren't propagated by `checkout -- <path>` (edits/adds are); rare for config, can harden later.
- Validated: `kubectl kustomize` builds (32 objects), all refs resolve, token sealed (sops, 0 plaintext leak). **Not yet applied** — Flux deploys on merge.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
HA's /config is an RWO PVC that is a git checkout of the homeassistant repo,
edited via the code-server sidecar. There was no automated path from a merge to
the running instance, so merged config (e.g. the notification-queue work) sat
undeployed until a manual pull+reload.
Adds a `config-sync` sidecar (alpine/git) sharing the config PVC. Every 30s it
fetches origin/main and, on change, force-syncs ONLY the HA YAML config paths
(automations(.yaml+dir), packages/, scripts.yaml, templates.yaml,
configuration.yaml, notify.yaml, groups.yaml, powercalc.yaml, blueprints) into
the working tree, advances the branch ref without touching the working tree, and
calls homeassistant.reload_all so the change goes live with no restart.
Deliberately left untouched: www/ (HACS rewrites those tracked files at runtime)
and untracked runtime state (.storage/, *.db, secrets.yaml). git auth reuses the
PAT already embedded in the PVC's remote URL; reload auth uses a dedicated
long-lived token in a sops secret.
Consequence (git becomes source of truth): uncommitted edits to a synced path
made directly in code-server OR via HA's UI automation editor are reverted on the
next sync. Commit + push to persist.
NOTE: the reload token currently reuses the existing HA long-lived token; rotate
it to a dedicated `config-sync` token (revocable independently) — see PR.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgbyKgrN1yYWrkAA32rJE5
The previous loop reloaded on any advance of origin/main, including commits that
touch only unsynced paths (www/, shelly_scripts/, docs). Now the reload trigger
is `git diff --quiet <remote> -- <config paths>`: HA is reloaded only when the
synced config paths differ. Non-config commits just advance the branch ref with
no reload. As a side effect the loop now also reverts local drift on synced
paths continuously (reloading only when something actually changed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgbyKgrN1yYWrkAA32rJE5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What
Adds a
config-syncsidecar to the home-assistant pod so merges tomainof thehomeassistantrepo auto-deploy into the running instance. Closes the gap found while verifying PR #8 (notifications): HA's/configis an RWO PVC git checkout with no automated pull, so merged config sat undeployed.How it works
A small
alpine/git:2.54.0sidecar shares theconfigPVC. Loop (30s):git fetch origin mainautomations.yaml+automations/,packages/,scripts.yaml,templates.yaml,configuration.yaml,notify.yaml,groups.yaml,powercalc.yaml,blueprints/— viagit checkout origin/main -- <paths>, then advance the branch ref without touching the working treePOST /api/services/homeassistant/reload_all(no restart)Left untouched on purpose:
www/(HACS rewrites those tracked files at runtime) and untracked runtime state (.storage/,*.db,secrets.yaml). git auth reuses the PAT already embedded in the PVC's remote URL; reload auth uses a long-lived token in a sops secret (config-sync-token.sops.yaml, same age recipient as the other HA secrets).Script lives in
config-sync.sh(mounted viaconfigMapGenerator, hash suffix disabled like the nginx one — editing it needs a manualrollout restart).⚠️ Behavioral consequence — git is now source of truth
Uncommitted edits to a synced path made directly in code-server, or via HA's UI automation editor (which writes
automations.yaml), are reverted within ~30s. Commit + push to persist. Helpers/integrations configured through the HA UI live in.storage/(untracked) and are unaffected.🔑 Follow-up — rotate the token
The reload token currently reuses the existing HA long-lived token, to get this live with zero extra steps. Recommend minting a dedicated
config-syncLLAT (HA → Profile → Security) and replacing the secret, so it's revocable independently of the personal token.Notes / limits
reload_allcovers automations/scripts/templates/packages; a change to thenotify:rest platform or a new integration would still need a restart (not the case here).checkout -- <path>(edits/adds are); rare for config, can harden later.kubectl kustomizebuilds (32 objects), all refs resolve, token sealed (sops, 0 plaintext leak). Not yet applied — Flux deploys on merge.🤖 Generated with Claude Code