homelab-codex-ws/scripts/ha/deploy.sh
oskar 6dffa5c565 fix(kb): przepiecie wszystkich odwolan wewnetrznych po migracji
126 plikow (md, yaml, sh, py) odwolywalo sie do sciezek sprzed migracji.

  15  markdown-linkow [..](..) -> policzona sciezka WZGLEDNA wobec pliku
      odsylajacego (wczesniej czesc z nich byla repo-root-relative i nie
      rozwiazywala sie z katalogu, w ktorym lezala)
 200  odwolan tekstowych (backticki, proza, yaml, importy w kodzie)
      -> nowa sciezka repo-root-relative, zgodnie z konwencja repo
   5  linkow rodzenstwa (gole nazwy plikow, np. "](DEPLOY.md)") — dzialaly
      tylko w starym katalogu; przeliczone recznie

Objete m.in.: CLAUDE.md (scripts/onboard/README.md -> kb/runbooks/
node-onboarding-tool.md, docs/backlog.md -> kb/phases/backlog.md),
README.md, .claude/skills/, 20 session logow, kod jobow.

Ostatnie 5 odwolan pochodzi z tresci wciagnietej rebasem z origin/master
(session log 2026-07-31, override node-agenta na SOLARII, dwie pozycje
backlogu) — wskazywaly na docs/incidents/, docs/kb/modules/ i
services/narty27/README.md sprzed migracji.

Dodany wzajemny link miedzy kb/services/control-plane.md (stub kodu)
a kb/subsystems/control-plane.md (opis, deprecated) — dwa dokumenty o tym
samym systemie, latwe do pomylenia.

Weryfikacja na 790 plikach: 0 odwolan do starych sciezek,
0 martwych linkow markdown. Lint OKF: 190/190 plikow ZGODNE.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 16:21:16 +02:00

97 lines
3.5 KiB
Bash
Executable file

#!/usr/bin/env bash
# Write path: repo -> HA instance, for the "api" adapter only (see
# kb/decisions/ha-configs-as-code.md, "Deploy path: adapter per instance",
# "Sync model", "Validation gate").
#
# Scope: automations/scripts/scenes only. Dashboards and helpers are
# WebSocket-only (scripts/ha/lib/ha_ws.py has no mutating command,
# deliberately) — writing those is a separate, not-yet-built task.
#
# Hard sequence enforced in lib/deploy_api.py, no shortcuts: DRIFT-CHECK ->
# VALIDATE (local + live check_config) -> WRITE (per object) -> VERIFY (per
# object). Any drift or validation failure aborts before a single mutating
# call is made. --dry-run runs the same DRIFT-CHECK/VALIDATE steps (both
# read-only in effect) and stops before WRITE/VERIFY.
#
# Instances with status != "active" (e.g. ken-legacy: archived, chelsty-ha:
# offline) or adapter != "api" are refused unconditionally — see
# instances.yaml and DESIGN.md's "Incident log" for why ken-legacy must
# never be a deploy target again.
#
# Usage: deploy.sh <instance> [--dry-run] [file...]
# no file args -> every automations/scripts/scenes file currently in
# services/home-assistant/config/<instance>/
# file args -> only those objects (path as given, repo-root-relative,
# or config-dir-relative all accepted)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_DIR="$(cd "$SCRIPT_DIR/../../services/home-assistant" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
INSTANCES_FILE="$SERVICE_DIR/instances.yaml"
usage() {
echo "usage: $0 <instance> [--dry-run] [file...]" >&2
}
if [[ $# -lt 1 ]]; then
usage
exit 2
fi
INSTANCE="$1"
shift
DRY_RUN=0
FILE_ARGS=()
for arg in "$@"; do
case "$arg" in
--dry-run) DRY_RUN=1 ;;
--) ;;
*) FILE_ARGS+=("$arg") ;;
esac
done
if [[ ! -f "$INSTANCES_FILE" ]]; then
echo "error: instances file not found: $INSTANCES_FILE" >&2
exit 1
fi
INSTANCE_CONFIG_OUTPUT="$(python3 "$SCRIPT_DIR/lib/instance_config.py" "$INSTANCES_FILE" "$INSTANCE")" || exit 1
eval "$INSTANCE_CONFIG_OUTPUT"
if [[ "$HA_STATUS" != "active" ]]; then
echo "error: instance '$INSTANCE' has status='$HA_STATUS', not 'active' — deploy.sh refuses" >&2
echo " non-active instances unconditionally, no override flag (see instances.yaml)." >&2
exit 1
fi
if [[ "$HA_ADAPTER" != "api" ]]; then
echo "error: instance '$INSTANCE' uses adapter='$HA_ADAPTER' — deploy.sh only implements" >&2
echo " the 'api' write path (see DESIGN.md, 'Deploy path: adapter per instance')." >&2
exit 1
fi
api_token_file="${HA_TOKEN_PATH/#\~/$HOME}"
if [[ -z "$HA_TOKEN_PATH" || ! -f "$api_token_file" ]]; then
echo "error: instance '$INSTANCE' has no token at '${api_token_file:-<unset>}' — deploy.sh" >&2
echo " has no fallback without a deploy_agent long-lived access token (see" >&2
echo " DESIGN.md, 'Tokens')." >&2
exit 1
fi
CONFIG_DIR="$SERVICE_DIR/config/$INSTANCE"
CONFIG_RELPATH="services/home-assistant/config/$INSTANCE"
if [[ ! -d "$CONFIG_DIR" ]]; then
echo "error: no config/$INSTANCE/ directory — run scripts/ha/import.sh $INSTANCE at least" >&2
echo " once first, so there is a last-known snapshot to drift-check against." >&2
exit 1
fi
echo "== ha deploy: instance=$INSTANCE adapter=$HA_ADAPTER dry_run=$DRY_RUN ==" >&2
python3 "$SCRIPT_DIR/lib/deploy_api.py" \
"$HA_BASE_URL" "$api_token_file" "$REPO_ROOT" "$CONFIG_DIR" "$CONFIG_RELPATH" "$INSTANCE" "$DRY_RUN" \
"${FILE_ARGS[@]}"