Один коміт, а не десяток тематичних, свідомо: теми переплетені в
спільних файлах (store.go, docker-compose.yml, deploy/README.md), і
розділити їх можна було б лише індексуванням шматків. Коміти, які не
збираються, гірші за один великий — тим паче що це рівно той стан, який
перевірявся разом.
ЩО ПРАЦЮЄ НА СТЕНДІ Й ПЕРЕВІРЕНО ТАМ
0058 подієві алерти: syslog, ncm, compliance спрацьовують у мить
події; правило з нереалізованим джерелом більше не зберігається
мовчки
0059 snmp.walk і прототипи шаблонів — таблиці з динамічним індексом
описуються шаблоном, а не Go
0060 відкат конфігу: план як різниця, маскування паролів із підписом
плану, обов'язковий контрольний збір, verifying при обриві
0061 кнопки Telegram: довге опитування, авторизація не з callback_data
0062 аудит і архів хостів; тест на AST, що падає на ключі без назви
0063 RLS: три ролі, окремий пул для фонових тактів
0064 строки зберігання даних і сторінка сховища
0065 приймач SNMP-трапів; перевірено справжніми пакетами по дроту,
переклад v1→v2 за RFC 3584 дає правильний OID
0066 ескалації сповіщень
0067 алерт про вичерпання диска
0068 поля заливки конфігу переїхали в каталог профілів
Плюс: 137 тестів вебу з нуля (їх не було взагалі), одинадцять справжніх
вад, знайдених ними й виправлених, і виправлення двох інтеграційних
тестів grpcapi, які мовчки пропускались півтора року.
ЩО ЩЕ НЕ ЗАПУСКАЛОСЬ
netpulse установник: одна команда замість 18 змінних і
593 рядків інструкції
RLS з першого запуску нова інсталяція під політиками одразу;
RLS-EXISTING-INSTALL.md лишається тільки для
старих інсталяцій
.forgejo + CI раннер не зареєстрований
Ці три перевірені компіляцією й міркуванням, але не виконанням.
ГОЛОВНИЙ ВИСНОВОК ДВОХ СЕСІЙ
Зелена перевірка доводить рівно те, що вона перевіряє. Тест ізоляції RLS
був правильний і зелений — і пропустив зламаний вхід, бо перевіряв «чи
не видно чужого», коли зламалось «чи видно своє». Інтеграційні тести
grpcapi були зелені, бо не виконувались. Схема, довідник і протокол
описували те, чого в коді не існувало, і виглядало це як готове.
Тому в кожному завданні цих сесій стояла вимога назвати НЕПОКРИТЕ, а
чотири задачі закінчились не можливістю, а відмовою: правило з
нереалізованим джерелом не зберігається, профіль без команд заливки
каже про це замість мовчазної кнопки, міграція RLS валить сама себе на
таблиці без політики, тест словника аудиту падає на ключі без назви.
Подробиці — HISTORY.md, розділи за 26 і 27 серпня.
138 lines
6.5 KiB
Bash
138 lines
6.5 KiB
Bash
#!/usr/bin/env sh
|
||
#
|
||
# Усі перевірки NetPulse однією командою.
|
||
#
|
||
# Навіщо окремий скрипт, коли є .forgejo/workflows/ci.yml: раннера
|
||
# Forgejo досі немає, тобто CI не запускався жодного разу. Перевірка, яку
|
||
# нікому виконати, не ловить нічого — а та сама послідовність, запущена
|
||
# руками перед комітом, ловить уже сьогодні. Коли раннер зʼявиться, CI
|
||
# викликатиме ті самі кроки; розходитись їм нема з чого.
|
||
#
|
||
# Запуск:
|
||
# sh scripts/check.sh # усе
|
||
# sh scripts/check.sh web # лише веб
|
||
# sh scripts/check.sh go # лише server + agent
|
||
# sh scripts/check.sh repo # лише перевірки репозиторію
|
||
#
|
||
# На Windows — з Git Bash; PowerShell цей файл не виконує.
|
||
#
|
||
# Скрипт НЕ зупиняється на першій невдачі навмисно: інакше, щоб
|
||
# побачити три поламані місця, довелось би прогнати його тричі.
|
||
# Ненульовий код виходу все одно повертається — рівно для гачка
|
||
# pre-push і для CI.
|
||
|
||
set -u
|
||
|
||
ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||
cd "$ROOT" || exit 1
|
||
|
||
FAILED=""
|
||
PASSED=""
|
||
|
||
# Прогін одного кроку. Назва потрібна для підсумку: список «що саме
|
||
# впало» у кінці цінніший за чотириста рядків виводу вище.
|
||
step() {
|
||
name=$1
|
||
shift
|
||
printf '\n\033[1m== %s\033[0m\n' "$name"
|
||
if "$@"; then
|
||
PASSED="$PASSED|$name"
|
||
else
|
||
FAILED="$FAILED|$name"
|
||
fi
|
||
}
|
||
|
||
# gofmt -l друкує список файлів, а не код виходу: без явної перевірки
|
||
# порожнечі крива форма проїжджає в main непоміченою.
|
||
gofmt_check() {
|
||
bad=$(gofmt -l "$1")
|
||
if [ -n "$bad" ]; then
|
||
echo "не відформатовано (виправити: gofmt -w $1):"
|
||
echo "$bad"
|
||
# На Windows цей крок червоніє ще й від CRLF у робочій копії: gofmt
|
||
# вважає \r частиною рядка й пропонує переписати файл цілком. У
|
||
# репозиторії лежить LF (див. .gitattributes), тож на Linux-раннері
|
||
# той самий файл зелений. Різницю треба назвати вголос: інакше її
|
||
# «виправлять» через gofmt -w і закомітять зіпсовані переноси.
|
||
echo "якщо різниця в цілому файлі — це CRLF у робочій копії:"
|
||
echo " git ls-files --eol $1 | git add --renormalize ."
|
||
return 1
|
||
fi
|
||
echo "форма в порядку"
|
||
}
|
||
|
||
# Зонд їде на чуже залізо: перевіряємо, що збирається під усі платформи,
|
||
# які обіцяємо, а не лише під ту, де запустили скрипт.
|
||
agent_cross() {
|
||
out=${TMPDIR:-/tmp}/netpulse-crossbuild
|
||
mkdir -p "$out" || return 1
|
||
for target in linux/amd64 linux/arm64 linux/arm windows/amd64 darwin/arm64; do
|
||
os=${target%/*}
|
||
arch=${target#*/}
|
||
echo "-- $os/$arch"
|
||
( cd agent && CGO_ENABLED=0 GOOS="$os" GOARCH="$arch" go build -trimpath \
|
||
-o "$out/netpulse-agent-$os-$arch" ./cmd/netpulse-agent ) || return 1
|
||
done
|
||
rm -rf "$out"
|
||
}
|
||
|
||
go_in() { ( cd "$1" && shift && "$@" ); }
|
||
|
||
check_go() {
|
||
step "server: gofmt" gofmt_check server
|
||
step "server: vet" go_in server go vet ./...
|
||
# Тести проти бази самі пропускаються без NETPULSE_TEST_DSN — локальний
|
||
# прогін не має ні піднімати Postgres, ні тим паче чіпати бойову базу.
|
||
step "server: тести" go_in server go test ./...
|
||
step "agent: gofmt" gofmt_check agent
|
||
step "agent: vet" go_in agent go vet ./...
|
||
step "agent: тести" go_in agent go test ./...
|
||
step "agent: крос-збірка" agent_cross
|
||
}
|
||
|
||
# Перевірки самого репозиторію — не коду, а того, як він лежить.
|
||
#
|
||
# Обидві ловлять поломки, яких не видно в diff і які проявляються вже на
|
||
# стенді: розходження каталогу профілів зі згенерованою міграцією і CRLF,
|
||
# що змінює sha256 тієї ж міграції. Чому саме так — у шапках
|
||
# scripts/check-eol.sh і db/profiles/build.py.
|
||
#
|
||
# Тут вони без --strict: у робочій копії на Windows CRLF цілком буває, і
|
||
# це попередження, а не привід не дати закомітити. У CI той самий скрипт
|
||
# викликається з --strict — там свіжий клон на Linux, і CRLF означав би
|
||
# зламане викачування.
|
||
check_repo() {
|
||
step "репозиторій: закінчення рядків" sh scripts/check-eol.sh
|
||
# python3 на Linux, python у Git Bash на Windows: різні імена одного
|
||
# й того самого, і вгадувати не треба — беремо той, що є.
|
||
py=python3
|
||
command -v python3 >/dev/null 2>&1 || py=python
|
||
step "репозиторій: каталог профілів" "$py" db/profiles/build.py --check
|
||
}
|
||
|
||
check_web() {
|
||
# npm ci лише коли залежностей немає: на кожному прогоні він викидає
|
||
# node_modules і ставить наново — хвилини замість секунд.
|
||
if [ ! -d web/node_modules ]; then
|
||
step "web: залежності" go_in web npm ci
|
||
fi
|
||
step "web: типи" go_in web npx tsc --noEmit
|
||
step "web: тести" go_in web npx vitest run
|
||
step "web: збірка" go_in web npx vite build
|
||
}
|
||
|
||
case "${1:-all}" in
|
||
web) check_web ;;
|
||
go) check_go ;;
|
||
repo) check_repo ;;
|
||
all) check_repo; check_go; check_web ;;
|
||
*) echo "невідомий набір: $1 (є: all, repo, go, web)"; exit 2 ;;
|
||
esac
|
||
|
||
printf '\n\033[1m== підсумок\033[0m\n'
|
||
echo "$PASSED" | tr '|' '\n' | sed '/^$/d' | sed 's/^/ ok /'
|
||
if [ -n "$FAILED" ]; then
|
||
echo "$FAILED" | tr '|' '\n' | sed '/^$/d' | sed 's/^/ ВПАЛО /'
|
||
exit 1
|
||
fi
|
||
echo "усе зелене"
|