Files
houseplan-card/scripts/wsl-setup.sh
T
Claude f0c8ae24ba infra: portable Windows gate, CI toolchain pins, task packet, deterministic wait, gate:small --smokes
Windows portability (the three red tests on the owner's machine at green CI):
- scripts/spawn-portable.mjs: isMainModule via pathToFileURL (the
  `file://${argv[1]}` form gives file:///C:/C:/... and the CLI stays silent);
  portableCommand — a shell only for npm/npx/.cmd, node and git run directly
  (spawn via shell dropped the quotes of `node -e "…"`). Applied to
  classify-changes, mutation-gate-report, review-doc-guard, check-inputs,
  merge-candidate, gate-small, rebase-on-dev.
- the rebase-on-dev test pins core.autocrlf=false / core.eol=lf through
  GIT_CONFIG_* for its temp repository instead of touching the user's git
  config; test/windows-portability.test.mjs forbids both anti-patterns.

Pins: scripts/toolchain-pins.mjs reads Node/Python from validate.yml, the HA
stack from tests_backend/requirements.txt, Playwright/Chromium from the
lockfile — no second dictionary; `npm run toolchain:check` compares the
machine; .nvmrc/.python-version are derived and tested equal;
scripts/wsl-setup.sh provisions WSL/Linux with those pins.

scripts/task-packet.mjs: one derived view of an issue (status, rights, owner
decisions, branch vs dev, Validate on the tip, previous verdict with recorded
tree, AC → evidence, unwitnessed). scripts/wait-verdict.mjs: polls labels,
pipeline comments and optionally Validate, prints only on state change, exit
0/3/4, writes nothing.

gate:small --smokes: after build the browser phase runs bundle-sync and then
the directly matched and registered smokes, two at a time; broad matches stay
with the reviewer. package.json changed, so the bundle is rebuilt here.

Issue: #496
User-Visible: no
2026-09-09 01:11:24 +03:00

52 lines
2.6 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 # только сверить с пинами
#
# Требует: git, curl. Node ставится через nvm (в ~/.nvm), Python — через uv
# (в .venv репозитория), Chromium — Playwright той версии, что в lockfile.
set -euo pipefail
cd "$(dirname "$0")/.."
if [ "${1:-}" = "--check" ]; then
exec node scripts/toolchain-pins.mjs --check
fi
# Node нужен уже для чтения пинов; bootstrap — из .nvmrc (тест держит его равным CI).
NODE_PIN=$(tr -d '[:space:]' < .nvmrc)
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
if [ ! -s "$NVM_DIR/nvm.sh" ]; then
echo "nvm не найден — устанавливаю в $NVM_DIR"
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
fi
# shellcheck disable=SC1091
. "$NVM_DIR/nvm.sh"
nvm install "$NODE_PIN" >/dev/null
nvm use "$NODE_PIN" >/dev/null
echo "node $(node --version) (пин $NODE_PIN)"
npm ci --no-audit --no-fund
PY_PIN=$(node scripts/toolchain-pins.mjs --json | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>process.stdout.write(JSON.parse(s).python))')
if ! command -v uv >/dev/null 2>&1; then
echo "uv не найден — устанавливаю"
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
fi
uv python install "$PY_PIN" >/dev/null
[ -d .venv ] || uv venv --python "$PY_PIN" .venv >/dev/null
uv pip install --python .venv/bin/python -r tests_backend/requirements.txt >/dev/null
echo "python $(.venv/bin/python --version) + HA-стек из tests_backend/requirements.txt"
npx playwright install chromium >/dev/null
echo "chromium: $(node -e 'console.log(require("playwright").chromium.executablePath())')"
# Сверка тем же скриптом, что и на Windows; python берётся из .venv.
PATH="$PWD/.venv/bin:$PATH" node scripts/toolchain-pins.mjs --check