ci: offline-тесты на Gitea runner (smoke/guardrails/gftest/cross-build)
Четыре workflow по образу и подобию runner-tests/examples, уровень C: - 01-smoke — runner жив, какие инструменты/либы есть в образе - 02-guardrails — grep-страж жёстких правил CLAUDE.md (rate 1920000, header_len=12 на TX и RX, только local:, static/ARM-флаги, нет тяжёлых зависимостей); логика в scripts/ci_guardrails.sh, гоняется и локально - 03-gftest — make gftest: нативная (не кросс-) сборка group_fec.c с -DGF_SELFTEST, 774 400 кейсов GF(256) - 04-cross-build — make check-env && make all под armhf; приёмка ARM-тулчейна проверяется реальной компиляцией + разбором e_machine из ELF-заголовка (od), а не command -v — на Alpine/musl наличие файла ничего не доказывает, если это glibc-бинарь без ld-linux E2E по радио и деплой на платы сознательно вне CI — нужны две живые Pluto-платы, это остаётся ручным чек-листом (scripts/test_file_link.sh).
This commit is contained in:
65
scripts/ci_guardrails.sh
Normal file
65
scripts/ci_guardrails.sh
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
# ci_guardrails.sh — статические grep-проверки жёстких правил CLAUDE.md.
|
||||
# Ловит регрессии до кросс-сборки и до платы: без тулчейна, без $XARM.
|
||||
# Запуск: scripts/ci_guardrails.sh (локально или из .gitea/workflows/02-guardrails.yml)
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
pass=0
|
||||
fail=0
|
||||
|
||||
check() {
|
||||
description="$1"
|
||||
if eval "$2" >/dev/null 2>&1; then
|
||||
printf ' [OK] %s\n' "$description"
|
||||
pass=$((pass + 1))
|
||||
else
|
||||
printf ' [FAIL] %s\n' "$description"
|
||||
fail=$((fail + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
echo "== Правило #1: язык C, без Python/GNU Radio в тракте =="
|
||||
check "нет .py в src/" '[ -z "$(find src -name "*.py")" ]'
|
||||
|
||||
echo ""
|
||||
echo "== Правило #2: libiio только local: в тракте =="
|
||||
check "нет буквального \"ip: в src/*.c" '! grep -rn "\"ip:" src/*.c'
|
||||
check "TX_URI_DEFAULT = local:" 'grep -q "TX_URI_DEFAULT.*\"local:\"" src/common.h'
|
||||
check "RX_URI_DEFAULT = local:" 'grep -q "RX_URI_DEFAULT.*\"local:\"" src/common.h'
|
||||
|
||||
echo ""
|
||||
echo "== Правило #3: статическая линковка, ARM-флаги (makefile) =="
|
||||
check "-static" 'grep -q -- "-static" makefile'
|
||||
check "-mcpu=cortex-a9" 'grep -q -- "-mcpu=cortex-a9" makefile'
|
||||
check "-mfpu=neon" 'grep -q -- "-mfpu=neon" makefile'
|
||||
check "-mfloat-abi=hard" 'grep -q -- "-mfloat-abi=hard" makefile'
|
||||
check "-ffast-math" 'grep -q -- "-ffast-math" makefile'
|
||||
|
||||
echo ""
|
||||
echo "== Правило #4: нет тяжёлых зависимостей =="
|
||||
check "нет cjson/curl/ffmpeg/libav в src/" \
|
||||
'! grep -rniE "cjson|curl/curl\.h|libav|ffmpeg" src/*.c src/*.h'
|
||||
|
||||
echo ""
|
||||
echo "== Правило #5: sample rate 1920000, никогда 3840000 =="
|
||||
check "DEFAULT_RATE = 1920000 в common.h" 'grep -q "DEFAULT_RATE.*1920000" src/common.h'
|
||||
check "нет 3840000 нигде в src/" '! grep -rn "3840000" src/'
|
||||
|
||||
echo ""
|
||||
echo "== Формат кадра: header_len=12 на обеих сторонах (техдолг #1) =="
|
||||
check "HDR_SIZE = 12 в common.h" 'grep -q "define HDR_SIZE *12" src/common.h'
|
||||
check "ofdmflexframegen_set_header_len(fg, HDR_SIZE) в transmitter.c" \
|
||||
'grep -q "ofdmflexframegen_set_header_len(fg, HDR_SIZE)" src/transmitter.c'
|
||||
check "ofdmflexframesync_set_header_len(fs, HDR_SIZE) в receiver.c" \
|
||||
'grep -q "ofdmflexframesync_set_header_len(fs, HDR_SIZE)" src/receiver.c'
|
||||
check "сигнатура заголовка 0xF0/0xAA в common.h" \
|
||||
'grep -q "HDR_SIGNATURE_0 *0xF0" src/common.h'
|
||||
check "сигнатура заголовка 0xF0/0xAA (байт 1) в common.h" \
|
||||
'grep -q "HDR_SIGNATURE_1 *0xAA" src/common.h'
|
||||
|
||||
echo ""
|
||||
echo "== Итог =="
|
||||
printf 'Пройдено: %d, Провалено: %d\n' "$pass" "$fail"
|
||||
|
||||
[ "$fail" -eq 0 ]
|
||||
Reference in New Issue
Block a user