feat: add runner conversion scripts and strengthen cutover automation

This commit is contained in:
S
2026-03-04 13:32:06 -06:00
parent e624885bb9
commit c2087d5087
43 changed files with 6995 additions and 42 deletions

View File

@@ -0,0 +1,89 @@
#!/usr/bin/env bash
# validate-tdd.sh
# Guard that production code changes are accompanied by tests.
set -euo pipefail
BASE_REF="${1:-origin/main}"
if ! git rev-parse --verify "$BASE_REF" >/dev/null 2>&1; then
BASE_REF="HEAD~1"
fi
CHANGED_FILES=()
while IFS= read -r line; do
[[ -n "$line" ]] && CHANGED_FILES+=("$line")
done < <(git diff --name-only "$BASE_REF"...HEAD)
if [[ ${#CHANGED_FILES[@]} -eq 0 ]]; then
echo "[validate-tdd] No changed files."
exit 0
fi
is_production_file() {
local f="$1"
[[ "$f" == shared/src/commonMain/* ]] && return 0
[[ "$f" == androidApp/src/main/* ]] && return 0
[[ "$f" == iosApp/iosApp/* ]] && [[ "$f" != iosApp/iosAppUITests/* ]] && [[ "$f" != iosApp/iosAppTests/* ]] && return 0
return 1
}
is_test_file() {
local f="$1"
[[ "$f" == shared/src/commonTest/* ]] && return 0
[[ "$f" == shared/src/jvmTest/* ]] && return 0
[[ "$f" == androidApp/src/androidTest/* ]] && return 0
[[ "$f" == androidApp/src/test/* ]] && return 0
[[ "$f" == iosApp/iosAppUITests/* ]] && return 0
[[ "$f" == iosApp/iosAppTests/* ]] && return 0
return 1
}
PROD_COUNT=0
TEST_COUNT=0
for file in "${CHANGED_FILES[@]}"; do
if is_production_file "$file"; then
PROD_COUNT=$((PROD_COUNT + 1))
fi
if is_test_file "$file"; then
TEST_COUNT=$((TEST_COUNT + 1))
fi
done
if [[ "$PROD_COUNT" -gt 0 && "$TEST_COUNT" -eq 0 ]]; then
echo "[validate-tdd] Failing: production code changed without matching test updates."
echo "[validate-tdd] Production files changed: $PROD_COUNT"
exit 1
fi
CHANGED_TEST_FILES=()
TEST_PATH_REGEX='^(shared/src/(commonTest|jvmTest)/|androidApp/src/(androidTest|test)/|iosApp/iosApp(UI)?Tests/)'
while IFS= read -r line; do
[[ -n "$line" ]] && CHANGED_TEST_FILES+=("$line")
done < <(
if command -v rg >/dev/null 2>&1; then
printf '%s\n' "${CHANGED_FILES[@]}" | rg "$TEST_PATH_REGEX" || true
else
printf '%s\n' "${CHANGED_FILES[@]}" | grep -E "$TEST_PATH_REGEX" || true
fi
)
for test_file in "${CHANGED_TEST_FILES[@]:-}"; do
if [[ -f "$test_file" ]]; then
if command -v rg >/dev/null 2>&1; then
if rg -q 'catch[[:space:]]*\([[:space:]]*AssertionError|XCTExpectFailure|@Ignore|@Disabled' "$test_file"; then
echo "[validate-tdd] Failing: potential weak assertion/skip anti-pattern in $test_file"
exit 1
fi
else
if grep -Eq 'catch[[:space:]]*\([[:space:]]*AssertionError|XCTExpectFailure|@Ignore|@Disabled' "$test_file"; then
echo "[validate-tdd] Failing: potential weak assertion/skip anti-pattern in $test_file"
exit 1
fi
fi
fi
done
if [[ "${FORCE_AUDIT_GATES:-0}" == "1" ]]; then
echo "[validate-tdd] FORCE_AUDIT_GATES enabled."
fi
echo "[validate-tdd] PASS ($BASE_REF...HEAD)"