feat: закрыть остаточный backlog

- keyset-пагинация аудита с курсором (occurred_at, id) и UI «Показать ещё»
- пакетный /api/v1/labs/details и переход progress на один запрос
- абсолютный потолок сессии 30 дней (identity V12 + web), очистка refresh
- админская инвентаризация legacy-активов (/admin/legacy-assets, скрипт)
- E2E в Chromium/Firefox/WebKit (18/18), CI preflight
- LDD: 51 claim, 346 тестов, docs и handoff обновлены
This commit is contained in:
2026-10-28 19:29:23 +03:00
parent d45137220c
commit 1e1e9ae0e4
64 changed files with 2124 additions and 372 deletions

111
scripts/ci-preflight.sh Executable file
View File

@@ -0,0 +1,111 @@
#!/usr/bin/env bash
# Проверка окружения shell-runner перед smoke/release. Ничего не устанавливает.
set -euo pipefail
cd "$(dirname "$0")/.."
release=0
case "${1:-}" in
"") ;;
--release) release=1 ;;
-h | --help)
echo "Usage: $0 [--release]"
exit 0
;;
*)
echo "Usage: $0 [--release]" >&2
exit 2
;;
esac
failures=()
ok() { printf 'OK %s\n' "$*"; }
fail() {
printf 'FAIL %s\n' "$*"
failures+=("$*")
}
if [[ -n "${BASH_VERSION:-}" ]]; then
ok "bash ${BASH_VERSION}"
else
fail "bash: не найден"
fi
if command -v java >/dev/null 2>&1; then
java_line=$(java -version 2>&1 | head -n 1 || true)
if [[ "$java_line" =~ version\ \"21([.\"-]|$) ]]; then
ok "java 21: ${java_line:-java}"
else
fail "java: нужна версия 21, найдено: ${java_line:-неизвестно}"
fi
else
fail "java: не найден в PATH"
fi
if command -v docker >/dev/null 2>&1; then
docker_line=$(docker --version 2>/dev/null | head -n 1 || true)
ok "docker: ${docker_line:-команда доступна}"
else
fail "docker: не найден в PATH"
fi
if command -v docker >/dev/null 2>&1; then
compose_short=$(docker compose version --short 2>/dev/null | head -n 1 || true)
if [[ -z "$compose_short" ]]; then
compose_short=$(docker compose version 2>/dev/null | head -n 1 || true)
compose_short=${compose_short#Docker Compose version }
compose_short=${compose_short#v}
fi
compose_short=${compose_short#v}
compose_major=${compose_short%%.*}
if [[ "$compose_major" =~ ^[0-9]+$ ]] && ((compose_major >= 2)); then
ok "docker compose v2+: ${compose_short:-неизвестно}"
else
fail "docker compose: нужен v2+, найдено: ${compose_short:-версия не определена}"
fi
else
fail "docker compose: docker не найден"
fi
if command -v python3 >/dev/null 2>&1; then
ok "python3: $(python3 --version 2>&1 | head -n 1)"
else
fail "python3: не найден в PATH"
fi
if ((release)); then
if command -v node >/dev/null 2>&1; then
ok "node: $(node --version 2>&1 | head -n 1)"
else
fail "node: не найден в PATH"
fi
if command -v npx >/dev/null 2>&1; then
ok "npx: $(npx --version 2>&1 | head -n 1)"
else
fail "npx: не найден в PATH"
fi
if [[ -d e2e/node_modules ]]; then
ok "e2e/node_modules: найден"
playwright_line=$(cd e2e && npx playwright --version 2>/dev/null | head -n 1 || true)
if [[ -n "$playwright_line" ]]; then
ok "playwright: $playwright_line"
else
fail "npx playwright --version: не удалось получить версию"
fi
else
fail "e2e/node_modules: не найден (выполните: cd e2e && npm ci)"
fail "npx playwright --version: пропущено без e2e/node_modules"
fi
fi
echo
if ((${#failures[@]} > 0)); then
echo "Preflight не пройден, ошибок: ${#failures[@]}."
printf ' - %s\n' "${failures[@]}"
exit 1
fi
echo "Preflight пройден."