mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-09-06 18:03:32 +02:00
* fix(skill): stop the workflow scripts reporting verdicts they have not established
Every defect here is the same species: a check printed as passed that never ran, or
never proved what it claims. All six were reproduced before and after.
validate.sh
- `run`/`finish` were selected by filename and fed to bash -n and shellcheck. 25 of the
97 such files here are `#!/usr/bin/execlineb`, so 21 add-ons -- calibre_web and seerr
among them -- reported `local validation FAILED` and a wall of parse errors no matter
what the diff contained. One list, filtered by shebang, now feeds both checks; seerr
went from 15 shellcheck findings and two bash -n failures to the single finding the
test diff actually introduced.
- `grep -q "$ADDON/CHANGELOG.md"` was unanchored with `.` as a wildcard, so a diff
bumping zzz_archived_overseerr/CHANGELOG.md reported seerr's as updated -- a false
green on the one hard CI gate. Five such name collisions exist in this repo
(also birdnet-pi/battybirdnet-pi, mealie/social_to_mealie, plex/spotify_to_plex).
`grep -Fxq`.
- The --vs-master section skipped any file absent from origin/master, so a newly added
script's findings -- all of which are by definition added by the diff -- were never
reported, under a line reading "your diff introduced no new lint findings". An added
file now compares against an empty base. A deleted one is skipped: it was being linted
at a path that no longer exists, which turned every deletion into a fabricated
`openBinaryFile: does not exist` finding.
- That loop ran as the right-hand side of a pipe, so it could not have reached `fail`
even had it tried. It now runs in this shell and new findings fail the script; the
all-clear line is printed only when nothing was listed. Findings that merely moved
lines still cancel -- the comparison strips file:line:col before comm.
- `bash -n ok` stood for an add-on with no shell files at all, and hadolint could print
`clean` directly after printing findings (`A && {...} || C` with pipefail). Counted
and branched properly.
preflight.sh
- `MATCH -- this checkout corresponds to the running image` was concluded from
config.yaml's version equalling $BUILD_VERSION. Version is bumped once per PR, so any
later commit or a dirty tree matches while differing from what runs -- the one
conclusion the script exists to establish was the one it overstated.
pr_review.sh
- `watch` exhausting its minutes with checks still pending fell out of the loop and
exited 0, reporting success for checks that never settled. Unsettled is now exit 2.
Checks reported as `skipping` still count as passing, which is correct -- for this PR
itself, three jobs skipped because no */config.* changed, and that is the right
outcome, not a failure. But a skipped job tested nothing, so `watch` now says so.
Reviewed by Codex (gpt-5.6-sol), which corrected two claims in the audit behind this:
the .templates CHANGELOG assertion (CI skips the gate entirely for a template-only PR,
so that fix is not in this diff) and a tradeoff that did not exist. The deleted-file and
watch-timeout defects are its finds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(skill): address review — cwd independence, no pass verdict for an empty check
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
89 lines
3.8 KiB
Bash
Executable File
89 lines
3.8 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
|
|
# version is bumped once per PR, so a later commit or a dirty tree matches here.
|
|
echo " VERSION MATCH — source revision itself is not verified."
|
|
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."
|