Skip to content

CI/CD Pipelines

Three GitHub Actions workflows automate config validation, deployment, and documentation publishing. All workflows run on GitHub-hosted runners — no self-hosted runner needed.

Validate (validate.yml)

Triggers on every push and every pull request to main.

Spins up a real Home Assistant container using frenck/action-home-assistant and runs a full config check against all YAML files in the repo. A fake secrets.yaml is injected so real credentials never touch CI. Catches broken YAML, invalid entity references, and bad automation syntax before anything reaches the live system.

Deploy (deploy.yml)

Triggers on pushes to main that change any root-level *.yaml file, excluding secrets.yaml and dashboard.yaml.

  1. Connects to the home network via Tailscale using a short-lived ephemeral node (OAuth client tagged tag:ci)
  2. Injects the HAOS SSH deploy key and SCPs only the changed files to /config/ on HAOS
  3. Makes a smart reload decision:
    • Only automations.yaml changed → automation.reload via REST API (~2 seconds, no downtime)
    • Any other config file changed → homeassistant.restart via REST API, then waits 60 seconds and verifies HA is up

The REST API is used for reload/restart (not SSH) to avoid a known HAOS issue where ha core restart over SSH leaves a stuck supervisor job.

Docs (docs.yml)

Triggers on pushes to main that change files under docs/ or mkdocs.yml.

Builds the MkDocs Material site with --strict (fails on warnings) and deploys to Cloudflare Pages via cloudflare/pages-action.

Published at: blairmont.pages.dev

Required GitHub Secrets

Secret Purpose
HAOS_HOST HAOS Tailscale IP (100.x.x.x)
HAOS_SSH_KEY Ed25519 private key for SCP to HAOS
HA_TOKEN HA long-lived access token for REST API calls
TAILSCALE_OAUTH_CLIENT_ID OAuth client ID (tag: tag:ci)
TAILSCALE_OAUTH_CLIENT_SECRET OAuth client secret
CLOUDFLARE_ACCOUNT_ID Cloudflare account ID
CLOUDFLARE_API_TOKEN Cloudflare API token with Pages Edit permission

Infrastructure Decisions

Private repo — home automation config reveals occupancy patterns, camera placements, and alarm zones. Kept private; the docs site is the public-facing portfolio artifact.

Tailscale over self-hosted runner — GitHub warns against self-hosted runners on public repos (fork PRs can execute arbitrary code). Tailscale lets GitHub-hosted runners reach the local network without that risk, and provides secure remote HAOS access as a side benefit.

Cloudflare Pages over GitHub Pages — GitHub Pages on private repos requires a paid plan. Cloudflare Pages is free and the published docs site is the resume link, not the raw repo.