mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
Добавлены безопасные pinned entrypoints, вывод фактических путей, идемпотентный Windows setup и WSL verification с настоящим HA subset и Linux capture. Issue: #557 User-Visible: no
104 lines
4.9 KiB
Bash
104 lines
4.9 KiB
Bash
#!/usr/bin/env bash
|
|
# Воспроизводимый локальный Linux-контур с пинами CI (#496): WSL2 или любой Linux.
|
|
#
|
|
# Пины не задаются здесь — читаются `node scripts/toolchain-pins.mjs --json`
|
|
# (тот же источник, что у CI). Скрипт идемпотентен: повторный запуск ничего не
|
|
# ломает. Полный HA-харнесс и каноническое релизное доказательство остаются за
|
|
# Linux CI на точном SHA; этот контур — ранняя обратная связь.
|
|
#
|
|
# bash scripts/wsl-setup.sh # установить/обновить окружение
|
|
# bash scripts/wsl-setup.sh --check # только сверить dedicated entrypoints
|
|
# bash scripts/wsl-setup.sh --verify # setup + HA subset + one visual capture
|
|
#
|
|
# Требует: git, curl. Node ставится через nvm (в ~/.nvm), Python — через uv
|
|
# (в .venv репозитория), Chromium — Playwright той версии, что в lockfile.
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
MODE=${1:-setup}
|
|
case "$MODE" in
|
|
setup|--check|--verify) ;;
|
|
*) echo "usage: bash scripts/wsl-setup.sh [--check|--verify]" >&2; exit 2 ;;
|
|
esac
|
|
START_SECONDS=$SECONDS
|
|
|
|
# Node нужен уже для чтения пинов; bootstrap — из .nvmrc (тест держит его равным CI).
|
|
NODE_PIN=$(tr -d '[:space:]' < .nvmrc)
|
|
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
|
if [ ! -s "$NVM_DIR/nvm.sh" ]; then
|
|
if [ "$MODE" = "--check" ]; then
|
|
echo "nvm не найден в $NVM_DIR; сначала: bash scripts/wsl-setup.sh" >&2
|
|
exit 1
|
|
fi
|
|
echo "nvm не найден — устанавливаю в $NVM_DIR"
|
|
# Не менять shell profile: nvm нужен только этому явному entrypoint.
|
|
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | PROFILE=/dev/null bash
|
|
fi
|
|
# shellcheck disable=SC1091
|
|
. "$NVM_DIR/nvm.sh"
|
|
if [ "$MODE" != "--check" ]; then nvm install "$NODE_PIN" >/dev/null; fi
|
|
nvm use "$NODE_PIN" >/dev/null
|
|
echo "node $(node --version): $(command -v node) (пин $NODE_PIN)"
|
|
|
|
# До npm ci полного `toolchain-pins --json` ещё нет: Chromium pin живёт в
|
|
# node_modules/playwright-core/browsers.json. Bootstrap берёт стандартный
|
|
# Python pin-файл; тест гарантирует его равенство каноническому CI workflow.
|
|
PY_PIN=$(tr -d '[:space:]' < .python-version)
|
|
UV_BIN=""
|
|
if [ -x "$HOME/.local/bin/uv" ]; then
|
|
UV_BIN="$HOME/.local/bin/uv"
|
|
elif command -v uv >/dev/null 2>&1; then
|
|
UV_BIN=$(command -v uv)
|
|
fi
|
|
if [ -z "$UV_BIN" ] && [ "$MODE" != "--check" ]; then
|
|
echo "uv не найден — устанавливаю"
|
|
# Как и nvm, не прописывать локальный helper в пользовательский shell profile.
|
|
curl -LsSf https://astral.sh/uv/install.sh | UV_NO_MODIFY_PATH=1 sh
|
|
UV_BIN="$HOME/.local/bin/uv"
|
|
fi
|
|
VENV=${HOUSEPLAN_VENV:-.venv-ci}
|
|
PYTHON_EXE="$PWD/$VENV/bin/python"
|
|
if [ "$MODE" != "--check" ]; then
|
|
"$UV_BIN" python install "$PY_PIN" >/dev/null
|
|
if [ -x "$PYTHON_EXE" ]; then
|
|
EXISTING_MINOR=$($PYTHON_EXE -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
|
|
if [ "$EXISTING_MINOR" != "$PY_PIN" ]; then
|
|
echo "$VENV использует Python $EXISTING_MINOR, нужен $PY_PIN; окружение не удалено, выберите другое HOUSEPLAN_VENV" >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
"$UV_BIN" venv --python "$PY_PIN" "$VENV" >/dev/null
|
|
fi
|
|
"$UV_BIN" pip install --python "$PYTHON_EXE" -r tests_backend/requirements.txt >/dev/null
|
|
fi
|
|
if [ ! -x "$PYTHON_EXE" ]; then
|
|
echo "$PYTHON_EXE не найден; сначала: bash scripts/wsl-setup.sh" >&2
|
|
exit 1
|
|
fi
|
|
echo "python $($PYTHON_EXE --version): $PYTHON_EXE + HA-стек из tests_backend/requirements.txt"
|
|
|
|
if [ "$MODE" != "--check" ]; then
|
|
npm ci --no-audit --no-fund
|
|
npx playwright install chromium >/dev/null
|
|
fi
|
|
echo "chromium: $(node -e 'console.log(require("playwright").chromium.executablePath())')"
|
|
|
|
# Сверка тем же скриптом, что и на Windows; Python передаётся явно и не зависит от PATH.
|
|
node scripts/toolchain-pins.mjs --check --python "$PYTHON_EXE"
|
|
|
|
if [ "$MODE" = "--verify" ]; then
|
|
echo "HA subset: tests_backend/test_ha_setup.py"
|
|
"$PYTHON_EXE" -c 'import fcntl; from importlib.metadata import version; print("HA import: " + version("homeassistant"))'
|
|
"$PYTHON_EXE" -m pytest tests_backend/test_ha_setup.py -q
|
|
|
|
echo "visual capture: panel-wide-view-light-en"
|
|
npm run build
|
|
node scripts/bundle-sync.mjs
|
|
node demo/golden/run.mjs --mode=capture --scenario=panel-wide-view-light-en
|
|
CAPTURE="$PWD/artifacts/golden/actual/panel-wide-view-light-en.png"
|
|
test -s "$CAPTURE"
|
|
echo "capture: $CAPTURE ($(wc -c < "$CAPTURE") bytes)"
|
|
fi
|
|
|
|
echo "WSL toolchain $MODE: $((SECONDS - START_SECONDS))s"
|