Files
huly-platform/scripts/verify-changed.sh
2026-04-08 20:05:04 +07:00

136 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Verify only packages touched by current branch changes.
# Usage:
# ./scripts/verify-changed.sh # local unstaged/staged/untracked changes
# Options:
# SKIP_TESTS=1 ./scripts/verify-changed.sh # run validate only
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"
ensure_node_version() {
# Best-effort: align shell Node with repo .nvmrc to avoid rush/pnpm engine issues.
if [[ -f ".nvmrc" ]] && command -v nvm >/dev/null 2>&1; then
local required
required="$(tr -d '[:space:]' < .nvmrc)"
if [[ -n "$required" ]]; then
echo "Switching Node via nvm: $required"
# shellcheck disable=SC1090
nvm use "$required" >/dev/null
echo "Using Node $(node -v)"
fi
elif [[ -f ".nvmrc" ]]; then
echo "Note: .nvmrc found but 'nvm' is unavailable in this shell."
echo " Consider running: nvm use"
fi
}
run_rush() {
if command -v rush >/dev/null 2>&1; then
rush "$@"
else
node common/scripts/install-run-rush.js "$@"
fi
}
run_validate_with_transient_retry() {
local pkg="$1"
local out_file
out_file="$(mktemp)"
if run_rush validate -t "$pkg" 2>&1 | tee "$out_file"; then
rm -f "$out_file"
return 0
fi
# When workspace package declarations are stale, TS can fail with missing module declarations.
# Do one targeted rebuild and retry validate once.
if rg -n "Cannot find module '@hcengineering/|or its corresponding type declarations" "$out_file" >/dev/null 2>&1; then
echo "Detected likely transient workspace declaration error. Rebuilding $pkg and retrying validate once..."
run_rush rebuild -t "$pkg"
run_rush validate -t "$pkg"
rm -f "$out_file"
return 0
fi
rm -f "$out_file"
return 1
}
ensure_node_version
mapfile -t CHANGED_FILES < <(
{
git diff --name-only
git diff --name-only --cached
git ls-files --others --exclude-standard
} | awk 'NF' | sort -u
)
if [[ ${#CHANGED_FILES[@]} -eq 0 ]]; then
echo "No local changed files."
exit 0
fi
declare -A PKG_DIRS=()
for file in "${CHANGED_FILES[@]}"; do
[[ "$file" == *"/node_modules/"* ]] && continue
[[ "$file" == common/temp/* ]] && continue
[[ ! -e "$file" ]] && continue
dir="$file"
[[ -f "$dir" ]] && dir="$(dirname "$dir")"
while [[ "$dir" != "." && "$dir" != "/" ]]; do
if [[ -f "$dir/package.json" ]]; then
PKG_DIRS["$dir"]=1
break
fi
dir="$(dirname "$dir")"
done
done
if [[ ${#PKG_DIRS[@]} -eq 0 ]]; then
echo "No changed Rush package directories detected."
exit 0
fi
echo "Detected changed package directories:"
for d in "${!PKG_DIRS[@]}"; do
echo " - $d"
done
echo
echo "Resolving package names..."
PACKAGE_NAMES=()
for d in "${!PKG_DIRS[@]}"; do
name="$(node -e "const p=require('./${d}/package.json'); process.stdout.write(p.name || '')")"
if [[ -n "$name" ]]; then
PACKAGE_NAMES+=("$name")
fi
done
if [[ ${#PACKAGE_NAMES[@]} -eq 0 ]]; then
echo "No package names resolved from changed directories."
exit 0
fi
echo "Running targeted validate/test per package:"
for name in "${PACKAGE_NAMES[@]}"; do
echo
echo "==> $name :: validate"
run_validate_with_transient_retry "$name"
if [[ "${SKIP_TESTS:-0}" != "1" ]]; then
echo "==> $name :: test"
run_rush test -t "$name"
fi
done
echo
echo "Done."