mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-08-24 13:53:32 +02:00
* chore: add hassio-addon-workflow skill for Claude Code Checks in the repo-specific skill so future Claude Code sessions get the tiered scope->measure->plan->implement->verify workflow, repo traps, and helper scripts (preflight/measure/env_trace/validate/pr_review) without depending on a local machine's ~/.claude config. * fix(skill): address PR review feedback from Copilot and Codex - SKILL.md: repo-relative script invocation (skill is now checked in); correct the CI-gates list — the PR add-on linter is blocking, only the weekly Super-Linter is non-blocking - preflight.sh: git-aware repo detection (worktrees have a .git file) - pr_review.sh: header now documents resolve's actual --all behavior - measure.sh: CPU% uses getconf CLK_TCK; sample all processes, not the top-24 by RSS - env_trace.sh: validate VAR as a strict env-var name before regex use - validate.sh: shellcheck also covers extensionless run/finish; --vs-master skips visibly when a linter is missing instead of reporting a false clean * fix(skill): address CodeRabbit review feedback - pr_review.sh: resolve exits nonzero unless every thread actually resolved; watch exits nonzero and says so when checks settle with failures instead of reporting bare "settled" - validate.sh: pass the config.yaml path to Python as argv instead of interpolating $ADDON into the source (CWE-94)
88 lines
3.7 KiB
Bash
Executable File
88 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Orient before starting add-on work: what tools exist, are we inside the running add-on, and
|
|
# — the one that actually bites — does the checkout match what is running?
|
|
#
|
|
# Usage: preflight.sh [repo-path] [addon-slug]
|
|
set -uo pipefail
|
|
|
|
REPO="${1:-/data/claude/hassio-addons}"
|
|
SLUG="${2:-}"
|
|
|
|
echo "== tools =="
|
|
for c in gh git codex rtk headroom tokensave shellcheck hadolint yamllint python3 jq; do
|
|
printf ' %-11s %s\n' "$c" "$(command -v "$c" > /dev/null 2>&1 && echo yes || echo MISSING)"
|
|
done
|
|
[ -x /data/codex/bin/codex-real ] && echo " codex-real yes (prefer: codex exec --model gpt-5.6-sol)"
|
|
|
|
echo
|
|
echo "== running add-on =="
|
|
if [ -n "${BUILD_VERSION:-}" ]; then
|
|
echo " BUILD_VERSION=$BUILD_VERSION HOME=${HOME:-?}"
|
|
echo " -> live measurement is possible; see measure.sh"
|
|
else
|
|
echo " not inside a running add-on (no BUILD_VERSION); source-only analysis"
|
|
fi
|
|
|
|
echo
|
|
echo "== repo =="
|
|
# git-aware check: in a worktree .git is a file, not a directory
|
|
if ! git -C "$REPO" rev-parse --git-dir > /dev/null 2>&1; then
|
|
echo " no git repo at $REPO"
|
|
exit 0
|
|
fi
|
|
cd "$REPO" || exit 0
|
|
branch=$(git branch --show-current 2> /dev/null || echo "(detached)")
|
|
echo " path=$REPO"
|
|
echo " branch=$branch"
|
|
|
|
# Another session may be mid-operation in this shared checkout.
|
|
echo " recent reflog (entries you did not make mean another session is active):"
|
|
git reflog --date=iso -3 2> /dev/null | sed 's/^/ /'
|
|
|
|
# The trap this exists for: a stale branch looks entirely normal.
|
|
if [ -n "${BUILD_VERSION:-}" ]; then
|
|
# Hostname is <8-hex>-<slug-with-dashes>. Anchor the hex to 8 chars: an unanchored
|
|
# [0-9a-f]* also eats real prefixes (dab-radio -> radio, cafe-monitor -> monitor).
|
|
# Slugs may legitimately contain dashes (birdnet-go), so try both forms.
|
|
if [ -z "$SLUG" ] && [ -n "${HOSTNAME:-}" ]; then
|
|
base=$(printf '%s' "$HOSTNAME" | sed 's/^[0-9a-f]\{8\}-//')
|
|
for cand in "$(printf '%s' "$base" | tr '-' '_')" "$base"; do
|
|
[ -f "$REPO/$cand/config.yaml" ] && { SLUG="$cand"; break; }
|
|
done
|
|
[ -z "$SLUG" ] && SLUG="$base"
|
|
fi
|
|
cfg="$REPO/$SLUG/config.yaml"
|
|
if [ ! -f "$cfg" ]; then
|
|
echo
|
|
echo " could not find $SLUG/config.yaml — pass the slug as \$2 to enable the"
|
|
echo " revision check (this is the check the script exists for)." >&2
|
|
exit 3
|
|
fi
|
|
if [ -f "$cfg" ]; then
|
|
here=$(grep -E '^version:' "$cfg" | head -1 | tr -d "\"'" | awk '{print $2}')
|
|
echo
|
|
echo " $SLUG/config.yaml version = $here"
|
|
echo " running image BUILD_VERSION = $BUILD_VERSION"
|
|
if [ "$here" = "$BUILD_VERSION" ]; then
|
|
echo " MATCH — this checkout corresponds to the running image."
|
|
else
|
|
echo " MISMATCH — this branch is NOT what is running."
|
|
git fetch origin master --quiet 2> /dev/null
|
|
master=$(git show origin/master:"$SLUG/config.yaml" 2> /dev/null |
|
|
grep -E '^version:' | head -1 | tr -d "\"'" | awk '{print $2}')
|
|
echo " origin/master version = ${master:-unknown}"
|
|
echo " -> work from origin/master; analysing this branch will mislead you."
|
|
echo
|
|
echo "== suggested isolated worktree (/tmp is noexec; use /data) =="
|
|
echo " git worktree add --detach /data/claude/.work/<task> origin/master"
|
|
echo " NOTE: never 'git stash' under /data/claude — refs/stash is shared."
|
|
exit 2
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo
|
|
echo "== suggested isolated worktree (/tmp is noexec; use /data) =="
|
|
echo " git worktree add --detach /data/claude/.work/<task> origin/master"
|
|
echo " NOTE: never 'git stash' under /data/claude — refs/stash is shared across worktrees."
|