🎉 init: 小龙的工作空间
This commit is contained in:
Executable
+372
@@ -0,0 +1,372 @@
|
||||
#!/bin/bash
|
||||
# ====================================================
|
||||
# PR-D Production Check — OpenClaw Agent OS v2
|
||||
# ====================================================
|
||||
# One-shot safety gate: env → baseline → guard →
|
||||
# deprecation → smoke → report.
|
||||
# Every architecture PR must pass this gate first.
|
||||
# ====================================================
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m'
|
||||
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
# ─── Result state ───────────────────────────────────
|
||||
ENV_PASS=false
|
||||
BASELINE_PASS=false
|
||||
GUARD_PASS=false
|
||||
DEPRECATION_STATUS="PASS"
|
||||
SMOKE_PASS=false
|
||||
OVERALL_PASS=true
|
||||
|
||||
FAILED_STEP=""
|
||||
FAIL_REASON=""
|
||||
FAIL_FIX=""
|
||||
|
||||
BASELINE_COUNT=0
|
||||
BASELINE_DURATION=0
|
||||
BASELINE_LOG=""
|
||||
DEPRECATION_COUNT=0
|
||||
|
||||
# ─── Helpers ────────────────────────────────────────
|
||||
|
||||
fail_step() {
|
||||
local step="$1" reason="$2" fix="$3"
|
||||
FAILED_STEP="$step"
|
||||
FAIL_REASON="$reason"
|
||||
FAIL_FIX="$fix"
|
||||
OVERALL_PASS=false
|
||||
}
|
||||
|
||||
section() {
|
||||
echo ""
|
||||
echo -e "${CYAN}══════════════════════════════════════════════${NC}"
|
||||
echo -e "${CYAN} $1${NC}"
|
||||
echo -e "${CYAN}══════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────
|
||||
# Step 1: Environment Check
|
||||
# ─────────────────────────────────────────────────────
|
||||
section "Step 1: Environment Check"
|
||||
|
||||
check_ok() { echo -e " ${GREEN}✓${NC} $1"; }
|
||||
check_fail() { echo -e " ${RED}✗${NC} $1"; fail_step "Environment" "$1" "$2"; }
|
||||
|
||||
# Node.js version
|
||||
NODE_VERSION=$(node --version 2>/dev/null || echo "")
|
||||
if [ -z "$NODE_VERSION" ]; then
|
||||
check_fail "Node.js not found" "Install Node.js >= 18"
|
||||
else
|
||||
NODE_MAJOR=$(echo "$NODE_VERSION" | sed 's/v//' | cut -d. -f1)
|
||||
if [ "$NODE_MAJOR" -lt 18 ]; then
|
||||
check_fail "Node.js $NODE_VERSION too old (need >=18)" "Upgrade Node.js: nvm install 18"
|
||||
else
|
||||
check_ok "Node.js $NODE_VERSION"
|
||||
fi
|
||||
fi
|
||||
|
||||
# npm
|
||||
if command -v npm &>/dev/null; then
|
||||
NPM_VERSION=$(npm --version 2>/dev/null)
|
||||
check_ok "npm $NPM_VERSION"
|
||||
else
|
||||
check_fail "npm not found" "Install npm (bundled with Node.js)"
|
||||
fi
|
||||
|
||||
# openclaw CLI
|
||||
if command -v openclaw &>/dev/null; then
|
||||
OC_VERSION=$(openclaw --version 2>/dev/null || echo "unknown")
|
||||
check_ok "openclaw CLI ($OC_VERSION)"
|
||||
else
|
||||
check_fail "openclaw CLI not found" "Install openclaw: npm i -g openclaw"
|
||||
fi
|
||||
|
||||
# Working directory
|
||||
if [ -f "package.json" ]; then
|
||||
check_ok "Working directory: $ROOT_DIR"
|
||||
else
|
||||
check_fail "Not in workspace root (no package.json)" "cd to workspace root"
|
||||
fi
|
||||
|
||||
# Required directories
|
||||
for dir in "test/baseline" "test/architecture" "scripts"; do
|
||||
if [ -d "$dir" ]; then
|
||||
check_ok "Directory exists: $dir"
|
||||
else
|
||||
check_fail "Directory missing: $dir" "Create $dir before running"
|
||||
fi
|
||||
done
|
||||
|
||||
if $OVERALL_PASS; then
|
||||
ENV_PASS=true
|
||||
echo ""
|
||||
echo -e " ${GREEN}Environment: PASS${NC}"
|
||||
else
|
||||
ENV_PASS=false
|
||||
echo ""
|
||||
echo -e " ${RED}Environment: FAIL${NC}"
|
||||
fi
|
||||
|
||||
# ─────────────────────────────────────────────────────
|
||||
# Step 2: Baseline Tests
|
||||
# ─────────────────────────────────────────────────────
|
||||
section "Step 2: Baseline Tests"
|
||||
|
||||
BASELINE_START=$(date +%s)
|
||||
|
||||
# Run baseline tests directly (not via buggy test-baseline.sh which has wrong TEST_DIR)
|
||||
BASELINE_LOG=$(mktemp)
|
||||
BASELINE_FILES=$(ls test/baseline/test-*.test.mjs 2>/dev/null || echo "")
|
||||
BASELINE_TOTAL=$(echo "$BASELINE_FILES" | wc -w | tr -d ' ')
|
||||
|
||||
if [ -z "$BASELINE_FILES" ] || [ "$BASELINE_TOTAL" -eq 0 ]; then
|
||||
echo -e " ${RED}✗${NC} No baseline test files found"
|
||||
fail_step "Baseline Tests" "No test files in test/baseline/" "Ensure PR-A baseline tests exist"
|
||||
else
|
||||
echo " Running $BASELINE_TOTAL baseline test files..."
|
||||
echo ""
|
||||
|
||||
PASSED=0
|
||||
FAILED=0
|
||||
|
||||
for f in $BASELINE_FILES; do
|
||||
name=$(basename "$f" .test.mjs)
|
||||
echo -ne " [RUN ] $name ... "
|
||||
|
||||
if node --test "$f" >> "$BASELINE_LOG" 2>&1; then
|
||||
echo -e "${GREEN}PASS${NC}"
|
||||
PASSED=$((PASSED + 1))
|
||||
else
|
||||
echo -e "${RED}FAIL${NC}"
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo " ──────────────────────────────────────────"
|
||||
echo " Test files: $BASELINE_TOTAL"
|
||||
echo " Passed: $PASSED"
|
||||
echo " Failed: $FAILED"
|
||||
echo " Log: $BASELINE_LOG"
|
||||
|
||||
if [ "$FAILED" -gt 0 ]; then
|
||||
fail_step "Baseline Tests" "$FAILED/$BASELINE_TOTAL tests failed" "Check $BASELINE_LOG for details"
|
||||
BASELINE_PASS=false
|
||||
else
|
||||
BASELINE_PASS=true
|
||||
fi
|
||||
fi
|
||||
|
||||
BASELINE_END=$(date +%s)
|
||||
BASELINE_DURATION=$((BASELINE_END - BASELINE_START))
|
||||
BASELINE_COUNT=$BASELINE_TOTAL
|
||||
|
||||
echo ""
|
||||
echo -e " Duration: ${BASELINE_DURATION}s"
|
||||
if $BASELINE_PASS; then
|
||||
echo -e " ${GREEN}Baseline Tests: PASS${NC}"
|
||||
else
|
||||
echo -e " ${RED}Baseline Tests: FAIL${NC}"
|
||||
fi
|
||||
|
||||
# ─────────────────────────────────────────────────────
|
||||
# Step 3: Architecture Guards
|
||||
# ─────────────────────────────────────────────────────
|
||||
section "Step 3: Architecture Guards"
|
||||
|
||||
GUARD_SCRIPT="$SCRIPT_DIR/guard-all.sh"
|
||||
|
||||
if [ ! -f "$GUARD_SCRIPT" ]; then
|
||||
fail_step "Architecture Guard" "guard-all.sh not found at $GUARD_SCRIPT" "Ensure PR-B guard scripts exist"
|
||||
GUARD_PASS=false
|
||||
else
|
||||
echo " Running: bash $GUARD_SCRIPT"
|
||||
echo ""
|
||||
|
||||
# Run guard-all but capture exit code — we need to differentiate HARD vs SOFT
|
||||
# guard-all.sh exits 1 if any hard guard fails
|
||||
GUARD_OUTPUT=$(bash "$GUARD_SCRIPT" 2>&1) || GUARD_EXIT=$?
|
||||
|
||||
echo "$GUARD_OUTPUT"
|
||||
|
||||
# Parse guard-all output for individual guard statuses
|
||||
GUARD_TOTAL=6
|
||||
GUARD_PASSED=0
|
||||
GUARD_FAILED=0
|
||||
GUARD_WARNED=0
|
||||
|
||||
while IFS='|' read -r name result; do
|
||||
case "$result" in
|
||||
PASS) GUARD_PASSED=$((GUARD_PASSED + 1)) ;;
|
||||
FAIL) GUARD_FAILED=$((GUARD_FAILED + 1)) ;;
|
||||
WARN) GUARD_WARNED=$((GUARD_WARNED + 1)) ;;
|
||||
esac
|
||||
done < <(echo "$GUARD_OUTPUT" | grep -E '^\S+\|(PASS|FAIL|WARN)$' || true)
|
||||
|
||||
# HARD guard failure = production check failure
|
||||
# SOFT guard warning ≠ production check failure
|
||||
if [ "${GUARD_EXIT:-0}" -ne 0 ]; then
|
||||
fail_step "Architecture Guard" "$GUARD_FAILED HARD guard(s) failed" "Review guard output above and fix violations"
|
||||
GUARD_PASS=false
|
||||
else
|
||||
GUARD_PASS=true
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo " Guard status: $GUARD_PASSED pass | $GUARD_FAILED fail | $GUARD_WARNED warn"
|
||||
|
||||
if $GUARD_PASS; then
|
||||
echo -e " ${GREEN}Architecture Guard: PASS${NC}"
|
||||
else
|
||||
echo -e " ${RED}Architecture Guard: FAIL${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ─────────────────────────────────────────────────────
|
||||
# Step 4: Deprecation Check
|
||||
# ─────────────────────────────────────────────────────
|
||||
section "Step 4: Deprecation Check"
|
||||
|
||||
DEPRECATION_SCRIPT="$SCRIPT_DIR/check-deprecations.mjs"
|
||||
|
||||
if [ ! -f "$DEPRECATION_SCRIPT" ]; then
|
||||
DEPRECATION_STATUS="FAIL"
|
||||
fail_step "Deprecation Check" "check-deprecations.mjs not found" "Ensure PR-C deprecation check script exists"
|
||||
else
|
||||
echo " Running: node $DEPRECATION_SCRIPT"
|
||||
echo ""
|
||||
|
||||
# Deprecation check never fails on deprecation count, only on script crash
|
||||
DEPRECATION_OUTPUT=$(node "$DEPRECATION_SCRIPT" 2>&1) || DEP_EXIT=$?
|
||||
|
||||
echo "$DEPRECATION_OUTPUT"
|
||||
|
||||
# Extract deprecation count and list
|
||||
DEPRECATION_COUNT=$(echo "$DEPRECATION_OUTPUT" | grep "Total warnings:" | grep -oE '[0-9]+' || echo "0")
|
||||
|
||||
if [ "${DEP_EXIT:-0}" -ne 0 ]; then
|
||||
DEPRECATION_STATUS="FAIL"
|
||||
fail_step "Deprecation Check" "Script crashed (exit $DEP_EXIT)" "Check $DEPRECATION_SCRIPT for errors"
|
||||
elif [ "$DEPRECATION_COUNT" -gt 0 ]; then
|
||||
DEPRECATION_STATUS="WARN"
|
||||
else
|
||||
DEPRECATION_STATUS="PASS"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo " Deprecation items: $DEPRECATION_COUNT"
|
||||
|
||||
# Print deprecation list if any
|
||||
DEP_LIST=$(echo "$DEPRECATION_OUTPUT" | sed -n '/Deprecated modules:/,/^$/p' || true)
|
||||
if [ -n "$DEP_LIST" ]; then
|
||||
echo "$DEP_LIST"
|
||||
fi
|
||||
|
||||
case "$DEPRECATION_STATUS" in
|
||||
PASS) echo -e " ${GREEN}Deprecation Check: PASS${NC}" ;;
|
||||
WARN) echo -e " ${YELLOW}Deprecation Check: WARN${NC}" ;;
|
||||
FAIL) echo -e " ${RED}Deprecation Check: FAIL${NC}" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# ─────────────────────────────────────────────────────
|
||||
# Step 5: Smoke Test
|
||||
# ─────────────────────────────────────────────────────
|
||||
section "Step 5: Smoke Test"
|
||||
|
||||
SMOKE_SCRIPT="$SCRIPT_DIR/smoke-test.mjs"
|
||||
|
||||
if [ ! -f "$SMOKE_SCRIPT" ]; then
|
||||
fail_step "Smoke Test" "smoke-test.mjs not found at $SMOKE_SCRIPT" "Create scripts/smoke-test.mjs"
|
||||
SMOKE_PASS=false
|
||||
else
|
||||
echo " Running: node $SMOKE_SCRIPT"
|
||||
echo ""
|
||||
|
||||
SMOKE_OUTPUT=$(node "$SMOKE_SCRIPT" 2>&1) || SMOKE_EXIT=$?
|
||||
|
||||
echo "$SMOKE_OUTPUT"
|
||||
|
||||
if [ "${SMOKE_EXIT:-0}" -eq 0 ]; then
|
||||
SMOKE_PASS=true
|
||||
echo -e " ${GREEN}Smoke Test: PASS${NC}"
|
||||
else
|
||||
SMOKE_PASS=false
|
||||
fail_step "Smoke Test" "Smoke test failed (exit $SMOKE_EXIT)" "Check smoke test output above"
|
||||
echo -e " ${RED}Smoke Test: FAIL${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ─────────────────────────────────────────────────────
|
||||
# Step 6: Summary Report
|
||||
# ─────────────────────────────────────────────────────
|
||||
END_TIME=$(date +%s)
|
||||
TOTAL_DURATION=$((END_TIME - START_TIME))
|
||||
|
||||
section "Step 6: Summary Report"
|
||||
|
||||
echo ""
|
||||
echo -e " ${BOLD}OpenClaw Production Check Summary${NC}"
|
||||
echo -e " ────────────────────────────────"
|
||||
|
||||
# Print each step status
|
||||
print_status() {
|
||||
local label="$1" status="$2"
|
||||
case "$status" in
|
||||
PASS) echo -e " ${label}: ${GREEN}PASS${NC}" ;;
|
||||
FAIL) echo -e " ${label}: ${RED}FAIL${NC}" ;;
|
||||
WARN) echo -e " ${label}: ${YELLOW}WARN${NC}" ;;
|
||||
*) echo -e " ${label}: $status" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
ENV_STR=$($ENV_PASS && echo "PASS" || echo "FAIL")
|
||||
BASELINE_STR=$($BASELINE_PASS && echo "PASS" || echo "FAIL")
|
||||
GUARD_STR=$($GUARD_PASS && echo "PASS" || echo "FAIL")
|
||||
|
||||
print_status "Environment" "$ENV_STR"
|
||||
print_status "Baseline Tests" "$BASELINE_STR"
|
||||
print_status "Architecture Guard" "$GUARD_STR"
|
||||
print_status "Deprecation Check" "$DEPRECATION_STATUS"
|
||||
print_status "Smoke Test" "$($SMOKE_PASS && echo "PASS" || echo "FAIL")"
|
||||
|
||||
echo ""
|
||||
OVERALL_STR=$($OVERALL_PASS && echo "PASS" || echo "FAIL")
|
||||
echo -e " ${BOLD}Overall:${NC} $($OVERALL_PASS && echo -e "${GREEN}PASS${NC}" || echo -e "${RED}FAIL${NC}")"
|
||||
echo -e " ${BOLD}Duration:${NC} ${TOTAL_DURATION}s"
|
||||
|
||||
# Failure details
|
||||
if ! $OVERALL_PASS; then
|
||||
echo ""
|
||||
echo -e " ${RED}${BOLD}Failed Step:${NC} ${FAILED_STEP}"
|
||||
echo -e " ${RED}${BOLD}Reason:${NC} ${FAIL_REASON}"
|
||||
echo -e " ${YELLOW}${BOLD}Suggested Fix:${NC} ${FAIL_FIX}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}══════════════════════════════════════════════${NC}"
|
||||
|
||||
if $OVERALL_PASS; then
|
||||
echo -e "${GREEN} ✓ PRODUCTION CHECK PASSED — Safe to proceed${NC}"
|
||||
echo -e "${CYAN}══════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED} ✗ PRODUCTION CHECK FAILED — Fix before proceeding${NC}"
|
||||
echo -e "${CYAN}══════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user