Fix build and code structure improvements. New but essential UI functionality. CI improvements. Documentation improvements. AI module improvements.
This commit is contained in:
318
devops/scripts/validate-before-commit.sh
Normal file
318
devops/scripts/validate-before-commit.sh
Normal file
@@ -0,0 +1,318 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# PRE-COMMIT VALIDATION SCRIPT
|
||||
# =============================================================================
|
||||
# Run this script before committing to ensure all CI checks will pass.
|
||||
#
|
||||
# Usage:
|
||||
# ./devops/scripts/validate-before-commit.sh [level]
|
||||
#
|
||||
# Levels:
|
||||
# quick - Smoke test only (~2 min)
|
||||
# pr - Full PR-gating suite (~15 min) [default]
|
||||
# full - All tests including extended (~45 min)
|
||||
#
|
||||
# Examples:
|
||||
# ./devops/scripts/validate-before-commit.sh # PR-gating
|
||||
# ./devops/scripts/validate-before-commit.sh quick # Smoke only
|
||||
# ./devops/scripts/validate-before-commit.sh full # Everything
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Validation level
|
||||
LEVEL="${1:-pr}"
|
||||
|
||||
# =============================================================================
|
||||
# UTILITIES
|
||||
# =============================================================================
|
||||
|
||||
print_header() {
|
||||
echo ""
|
||||
echo -e "${CYAN}=============================================${NC}"
|
||||
echo -e "${CYAN} $1${NC}"
|
||||
echo -e "${CYAN}=============================================${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_step() {
|
||||
echo -e "${BLUE}>>> $1${NC}"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[PASS] $1${NC}"
|
||||
}
|
||||
|
||||
print_fail() {
|
||||
echo -e "${RED}[FAIL] $1${NC}"
|
||||
}
|
||||
|
||||
print_warn() {
|
||||
echo -e "${YELLOW}[WARN] $1${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${CYAN}[INFO] $1${NC}"
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# CHECKS
|
||||
# =============================================================================
|
||||
|
||||
check_git_status() {
|
||||
print_step "Checking git status..."
|
||||
|
||||
# Check for uncommitted changes
|
||||
if ! git diff --quiet 2>/dev/null; then
|
||||
print_warn "You have unstaged changes"
|
||||
fi
|
||||
|
||||
# Check for untracked files
|
||||
local untracked
|
||||
untracked=$(git ls-files --others --exclude-standard 2>/dev/null | wc -l)
|
||||
if [[ "$untracked" -gt 0 ]]; then
|
||||
print_warn "You have $untracked untracked file(s)"
|
||||
fi
|
||||
|
||||
# Show current branch
|
||||
local branch
|
||||
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
|
||||
print_info "Current branch: $branch"
|
||||
}
|
||||
|
||||
check_dependencies() {
|
||||
print_step "Checking dependencies..."
|
||||
|
||||
local missing=0
|
||||
|
||||
# Check .NET
|
||||
if ! command -v dotnet &>/dev/null; then
|
||||
print_fail ".NET SDK not found"
|
||||
missing=1
|
||||
else
|
||||
local version
|
||||
version=$(dotnet --version)
|
||||
print_success ".NET SDK: $version"
|
||||
fi
|
||||
|
||||
# Check Docker
|
||||
if ! command -v docker &>/dev/null; then
|
||||
print_warn "Docker not found (some tests may fail)"
|
||||
else
|
||||
if docker info &>/dev/null; then
|
||||
print_success "Docker: running"
|
||||
else
|
||||
print_warn "Docker: not running"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check Git
|
||||
if ! command -v git &>/dev/null; then
|
||||
print_fail "Git not found"
|
||||
missing=1
|
||||
else
|
||||
print_success "Git: installed"
|
||||
fi
|
||||
|
||||
return $missing
|
||||
}
|
||||
|
||||
run_smoke_tests() {
|
||||
print_step "Running smoke tests..."
|
||||
|
||||
if "$SCRIPT_DIR/local-ci.sh" smoke; then
|
||||
print_success "Smoke tests passed"
|
||||
return 0
|
||||
else
|
||||
print_fail "Smoke tests failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_pr_tests() {
|
||||
print_step "Running PR-gating suite..."
|
||||
|
||||
if "$SCRIPT_DIR/local-ci.sh" pr; then
|
||||
print_success "PR-gating suite passed"
|
||||
return 0
|
||||
else
|
||||
print_fail "PR-gating suite failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_full_tests() {
|
||||
print_step "Running full test suite..."
|
||||
|
||||
if "$SCRIPT_DIR/local-ci.sh" full; then
|
||||
print_success "Full test suite passed"
|
||||
return 0
|
||||
else
|
||||
print_fail "Full test suite failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_module_tests() {
|
||||
print_step "Running module tests..."
|
||||
|
||||
if "$SCRIPT_DIR/local-ci.sh" module; then
|
||||
print_success "Module tests passed"
|
||||
return 0
|
||||
else
|
||||
print_fail "Module tests failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_helm() {
|
||||
if command -v helm &>/dev/null; then
|
||||
print_step "Validating Helm chart..."
|
||||
local chart="$REPO_ROOT/devops/helm/stellaops"
|
||||
if [[ -d "$chart" ]]; then
|
||||
if helm lint "$chart" &>/dev/null; then
|
||||
print_success "Helm chart valid"
|
||||
else
|
||||
print_warn "Helm chart has warnings"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
validate_compose() {
|
||||
print_step "Validating Docker Compose..."
|
||||
local compose="$REPO_ROOT/devops/compose/docker-compose.ci.yaml"
|
||||
if [[ -f "$compose" ]]; then
|
||||
if docker compose -f "$compose" config &>/dev/null; then
|
||||
print_success "Docker Compose valid"
|
||||
else
|
||||
print_warn "Docker Compose has issues"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# MAIN
|
||||
# =============================================================================
|
||||
|
||||
main() {
|
||||
print_header "Pre-Commit Validation"
|
||||
print_info "Level: $LEVEL"
|
||||
print_info "Repository: $REPO_ROOT"
|
||||
|
||||
local start_time
|
||||
start_time=$(date +%s)
|
||||
local failed=0
|
||||
|
||||
# Always run these checks
|
||||
check_git_status
|
||||
check_dependencies || failed=1
|
||||
|
||||
if [[ $failed -eq 1 ]]; then
|
||||
print_fail "Dependency check failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run appropriate test level
|
||||
case "$LEVEL" in
|
||||
quick|smoke)
|
||||
run_smoke_tests || failed=1
|
||||
;;
|
||||
pr|default)
|
||||
run_smoke_tests || failed=1
|
||||
if [[ $failed -eq 0 ]]; then
|
||||
run_module_tests || failed=1
|
||||
fi
|
||||
if [[ $failed -eq 0 ]]; then
|
||||
run_pr_tests || failed=1
|
||||
fi
|
||||
validate_helm
|
||||
validate_compose
|
||||
;;
|
||||
full|all)
|
||||
run_smoke_tests || failed=1
|
||||
if [[ $failed -eq 0 ]]; then
|
||||
run_full_tests || failed=1
|
||||
fi
|
||||
validate_helm
|
||||
validate_compose
|
||||
;;
|
||||
*)
|
||||
print_fail "Unknown level: $LEVEL"
|
||||
echo "Valid levels: quick, pr, full"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Calculate duration
|
||||
local end_time
|
||||
end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
local minutes=$((duration / 60))
|
||||
local seconds=$((duration % 60))
|
||||
|
||||
# Final summary
|
||||
print_header "Summary"
|
||||
print_info "Duration: ${minutes}m ${seconds}s"
|
||||
|
||||
if [[ $failed -eq 0 ]]; then
|
||||
echo ""
|
||||
echo -e "${GREEN}=============================================${NC}"
|
||||
echo -e "${GREEN} ALL CHECKS PASSED - Ready to commit!${NC}"
|
||||
echo -e "${GREEN}=============================================${NC}"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " git add -A"
|
||||
echo " git commit -m \"Your commit message\""
|
||||
echo ""
|
||||
exit 0
|
||||
else
|
||||
echo ""
|
||||
echo -e "${RED}=============================================${NC}"
|
||||
echo -e "${RED} VALIDATION FAILED - Do not commit!${NC}"
|
||||
echo -e "${RED}=============================================${NC}"
|
||||
echo ""
|
||||
echo "Check the logs in: out/local-ci/logs/"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Show usage if --help
|
||||
if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
|
||||
cat <<EOF
|
||||
Pre-Commit Validation Script
|
||||
|
||||
Usage: $(basename "$0") [level]
|
||||
|
||||
Levels:
|
||||
quick Smoke test only (~2 min)
|
||||
pr Full PR-gating suite (~15 min) [default]
|
||||
full All tests including extended (~45 min)
|
||||
|
||||
Examples:
|
||||
$(basename "$0") # Run PR-gating validation
|
||||
$(basename "$0") quick # Quick smoke test only
|
||||
$(basename "$0") full # Run everything
|
||||
|
||||
What each level validates:
|
||||
quick: Build + Unit tests
|
||||
pr: Build + Unit + Architecture + Contract + Integration + Security + Golden
|
||||
full: All PR-gating + Performance + Benchmark + AirGap + Chaos + Determinism
|
||||
EOF
|
||||
exit 0
|
||||
fi
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user