446 lines
13 KiB
Bash
446 lines
13 KiB
Bash
#!/bin/bash
|
|
|
|
# ci-hooks.sh - Continuous integration hooks for .agents
|
|
# Part of LCBP3-DMS Phase 3 enhancements
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Base directory
|
|
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
AGENTS_DIR="$BASE_DIR/.agents"
|
|
|
|
# CI configuration
|
|
CI_LOG_DIR="$AGENTS_DIR/logs/ci"
|
|
CI_REPORT_DIR="$AGENTS_DIR/reports/ci"
|
|
|
|
# Ensure directories exist
|
|
mkdir -p "$CI_LOG_DIR" "$CI_REPORT_DIR"
|
|
|
|
# Logging function
|
|
ci_log() {
|
|
local level="$1"
|
|
local message="$2"
|
|
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
local log_file="$CI_LOG_DIR/ci-$(date '+%Y-%m-%d').log"
|
|
|
|
echo "[$timestamp] [$level] $message" | tee -a "$log_file"
|
|
|
|
# Console output with colors
|
|
case "$level" in
|
|
"INFO") echo -e "${BLUE}$message${NC}" ;;
|
|
"PASS") echo -e "${GREEN}$message${NC}" ;;
|
|
"WARN") echo -e "${YELLOW}$message${NC}" ;;
|
|
"FAIL") echo -e "${RED}$message${NC}" ;;
|
|
*) echo "$message" ;;
|
|
esac
|
|
}
|
|
|
|
# Pre-commit hook
|
|
pre_commit_hook() {
|
|
ci_log "INFO" "Running pre-commit validation..."
|
|
|
|
local exit_code=0
|
|
|
|
# 1. Run version validation
|
|
ci_log "INFO" "Checking version consistency..."
|
|
if "$AGENTS_DIR/scripts/bash/validate-versions.sh" >> "$CI_LOG_DIR/pre-commit-versions.log" 2>&1; then
|
|
ci_log "PASS" "Version validation passed"
|
|
else
|
|
ci_log "FAIL" "Version validation failed"
|
|
exit_code=1
|
|
fi
|
|
|
|
# 2. Run skill audit
|
|
ci_log "INFO" "Auditing skills..."
|
|
if "$AGENTS_DIR/scripts/bash/audit-skills.sh" >> "$CI_LOG_DIR/pre-commit-skills.log" 2>&1; then
|
|
ci_log "PASS" "Skill audit passed"
|
|
else
|
|
ci_log "FAIL" "Skill audit failed"
|
|
exit_code=1
|
|
fi
|
|
|
|
# 3. Run integration tests (if Node.js available)
|
|
if command -v node >/dev/null 2>&1; then
|
|
ci_log "INFO" "Running integration tests..."
|
|
if node "$AGENTS_DIR/tests/skill-integration.test.js" >> "$CI_LOG_DIR/pre-commit-tests.log" 2>&1; then
|
|
ci_log "PASS" "Integration tests passed"
|
|
else
|
|
ci_log "WARN" "Integration tests failed (non-blocking)"
|
|
fi
|
|
else
|
|
ci_log "WARN" "Node.js not available, skipping integration tests"
|
|
fi
|
|
|
|
# 4. Check for forbidden patterns
|
|
ci_log "INFO" "Checking for forbidden patterns..."
|
|
local forbidden_patterns=("TODO" "FIXME" "XXX" "HACK")
|
|
local found_forbidden=false
|
|
|
|
for pattern in "${forbidden_patterns[@]}"; do
|
|
if grep -r "$pattern" "$AGENTS_DIR/skills" --include="*.md" >/dev/null 2>&1; then
|
|
ci_log "WARN" "Found forbidden pattern: $pattern"
|
|
found_forbidden=true
|
|
fi
|
|
done
|
|
|
|
if [ "$found_forbidden" = false ]; then
|
|
ci_log "PASS" "No forbidden patterns found"
|
|
fi
|
|
|
|
# Generate pre-commit report
|
|
local report_file="$CI_REPORT_DIR/pre-commit-$(date '+%Y%m%d-%H%M%S').json"
|
|
cat > "$report_file" << EOF
|
|
{
|
|
"timestamp": "$(date -Iseconds)",
|
|
"hook_type": "pre-commit",
|
|
"exit_code": $exit_code,
|
|
"checks_performed": [
|
|
"version_validation",
|
|
"skill_audit",
|
|
"integration_tests",
|
|
"forbidden_patterns"
|
|
],
|
|
"log_files": [
|
|
"pre-commit-versions.log",
|
|
"pre-commit-skills.log",
|
|
"pre-commit-tests.log"
|
|
]
|
|
}
|
|
EOF
|
|
|
|
ci_log "INFO" "Pre-commit report saved to: $report_file"
|
|
|
|
if [ $exit_code -eq 0 ]; then
|
|
ci_log "PASS" "Pre-commit validation completed successfully"
|
|
else
|
|
ci_log "FAIL" "Pre-commit validation failed"
|
|
fi
|
|
|
|
return $exit_code
|
|
}
|
|
|
|
# Pre-push hook
|
|
pre_push_hook() {
|
|
ci_log "INFO" "Running pre-push validation..."
|
|
|
|
local exit_code=0
|
|
|
|
# 1. Full health check
|
|
ci_log "INFO" "Running full health check..."
|
|
if command -v node >/dev/null 2>&1; then
|
|
if node "$AGENTS_DIR/scripts/health-monitor.js" >> "$CI_LOG_DIR/pre-push-health.log" 2>&1; then
|
|
ci_log "PASS" "Health check passed"
|
|
else
|
|
ci_log "FAIL" "Health check failed"
|
|
exit_code=1
|
|
fi
|
|
else
|
|
ci_log "WARN" "Node.js not available, using basic health check"
|
|
if "$AGENTS_DIR/scripts/bash/audit-skills.sh" >> "$CI_LOG_DIR/pre-push-basic.log" 2>&1; then
|
|
ci_log "PASS" "Basic health check passed"
|
|
else
|
|
ci_log "FAIL" "Basic health check failed"
|
|
exit_code=1
|
|
fi
|
|
fi
|
|
|
|
# 2. Advanced validation (if available)
|
|
if command -v node >/dev/null 2>&1 && [ -f "$AGENTS_DIR/scripts/advanced-validator.js" ]; then
|
|
ci_log "INFO" "Running advanced validation..."
|
|
if node "$AGENTS_DIR/scripts/advanced-validator.js" >> "$CI_LOG_DIR/pre-push-advanced.log" 2>&1; then
|
|
ci_log "PASS" "Advanced validation passed"
|
|
else
|
|
ci_log "WARN" "Advanced validation found issues (non-blocking)"
|
|
fi
|
|
fi
|
|
|
|
# 3. Dependency validation
|
|
if command -v node >/dev/null 2>&1 && [ -f "$AGENTS_DIR/scripts/dependency-validator.js" ]; then
|
|
ci_log "INFO" "Running dependency validation..."
|
|
if node "$AGENTS_DIR/scripts/dependency-validator.js" >> "$CI_LOG_DIR/pre-push-dependencies.log" 2>&1; then
|
|
ci_log "PASS" "Dependency validation passed"
|
|
else
|
|
ci_log "WARN" "Dependency validation found issues (non-blocking)"
|
|
fi
|
|
fi
|
|
|
|
# 4. Performance monitoring
|
|
if command -v node >/dev/null 2>&1 && [ -f "$AGENTS_DIR/scripts/performance-monitor.js" ]; then
|
|
ci_log "INFO" "Running performance monitoring..."
|
|
if node "$AGENTS_DIR/scripts/performance-monitor.js" >> "$CI_LOG_DIR/pre-push-performance.log" 2>&1; then
|
|
ci_log "PASS" "Performance monitoring passed"
|
|
else
|
|
ci_log "WARN" "Performance monitoring found issues (non-blocking)"
|
|
fi
|
|
fi
|
|
|
|
# Generate pre-push report
|
|
local report_file="$CI_REPORT_DIR/pre-push-$(date '+%Y%m%d-%H%M%S').json"
|
|
cat > "$report_file" << EOF
|
|
{
|
|
"timestamp": "$(date -Iseconds)",
|
|
"hook_type": "pre-push",
|
|
"exit_code": $exit_code,
|
|
"checks_performed": [
|
|
"health_check",
|
|
"advanced_validation",
|
|
"dependency_validation",
|
|
"performance_monitoring"
|
|
],
|
|
"log_files": [
|
|
"pre-push-health.log",
|
|
"pre-push-advanced.log",
|
|
"pre-push-dependencies.log",
|
|
"pre-push-performance.log"
|
|
]
|
|
}
|
|
EOF
|
|
|
|
ci_log "INFO" "Pre-push report saved to: $report_file"
|
|
|
|
if [ $exit_code -eq 0 ]; then
|
|
ci_log "PASS" "Pre-push validation completed successfully"
|
|
else
|
|
ci_log "FAIL" "Pre-push validation failed"
|
|
fi
|
|
|
|
return $exit_code
|
|
}
|
|
|
|
# CI pipeline hook
|
|
ci_pipeline_hook() {
|
|
ci_log "INFO" "Running CI pipeline validation..."
|
|
|
|
local exit_code=0
|
|
local pipeline_start=$(date +%s)
|
|
|
|
# Create pipeline workspace
|
|
local workspace="$CI_REPORT_DIR/pipeline-$(date '+%Y%m%d-%H%M%S')"
|
|
mkdir -p "$workspace"
|
|
|
|
# 1. Environment validation
|
|
ci_log "INFO" "Validating CI environment..."
|
|
|
|
# Check required tools
|
|
local required_tools=("node" "npm")
|
|
for tool in "${required_tools[@]}"; do
|
|
if command -v "$tool" >/dev/null 2>&1; then
|
|
ci_log "PASS" "Tool available: $tool"
|
|
else
|
|
ci_log "FAIL" "Tool missing: $tool"
|
|
exit_code=1
|
|
fi
|
|
done
|
|
|
|
# Check Node.js modules
|
|
if [ -f "$AGENTS_DIR/package.json" ]; then
|
|
cd "$AGENTS_DIR"
|
|
if npm list --depth=0 >/dev/null 2>&1; then
|
|
ci_log "PASS" "Node.js dependencies installed"
|
|
else
|
|
ci_log "WARN" "Installing Node.js dependencies..."
|
|
npm install >> "$workspace/npm-install.log" 2>&1 || {
|
|
ci_log "FAIL" "Failed to install Node.js dependencies"
|
|
exit_code=1
|
|
}
|
|
fi
|
|
cd "$BASE_DIR"
|
|
fi
|
|
|
|
# 2. Full test suite
|
|
ci_log "INFO" "Running full test suite..."
|
|
|
|
# Integration tests
|
|
if node "$AGENTS_DIR/tests/skill-integration.test.js" >> "$workspace/integration-tests.log" 2>&1; then
|
|
ci_log "PASS" "Integration tests passed"
|
|
else
|
|
ci_log "FAIL" "Integration tests failed"
|
|
exit_code=1
|
|
fi
|
|
|
|
# Workflow validation tests
|
|
if node "$AGENTS_DIR/tests/workflow-validation.test.js" >> "$workspace/workflow-tests.log" 2>&1; then
|
|
ci_log "PASS" "Workflow validation tests passed"
|
|
else
|
|
ci_log "FAIL" "Workflow validation tests failed"
|
|
exit_code=1
|
|
fi
|
|
|
|
# 3. Comprehensive validation
|
|
ci_log "INFO" "Running comprehensive validation..."
|
|
|
|
# Health monitoring
|
|
if node "$AGENTS_DIR/scripts/health-monitor.js" >> "$workspace/health-check.log" 2>&1; then
|
|
ci_log "PASS" "Health monitoring passed"
|
|
else
|
|
ci_log "FAIL" "Health monitoring failed"
|
|
exit_code=1
|
|
fi
|
|
|
|
# Advanced validation
|
|
if node "$AGENTS_DIR/scripts/advanced-validator.js" >> "$workspace/advanced-validation.log" 2>&1; then
|
|
ci_log "PASS" "Advanced validation passed"
|
|
else
|
|
ci_log "WARN" "Advanced validation found issues"
|
|
fi
|
|
|
|
# Dependency validation
|
|
if node "$AGENTS_DIR/scripts/dependency-validator.js" >> "$workspace/dependency-validation.log" 2>&1; then
|
|
ci_log "PASS" "Dependency validation passed"
|
|
else
|
|
ci_log "WARN" "Dependency validation found issues"
|
|
fi
|
|
|
|
# Performance monitoring
|
|
if node "$AGENTS_DIR/scripts/performance-monitor.js" >> "$workspace/performance-monitor.log" 2>&1; then
|
|
ci_log "PASS" "Performance monitoring passed"
|
|
else
|
|
ci_log "WARN" "Performance monitoring found issues"
|
|
fi
|
|
|
|
# 4. Generate artifacts
|
|
ci_log "INFO" "Generating CI artifacts..."
|
|
|
|
local pipeline_end=$(date +%s)
|
|
local duration=$((pipeline_end - pipeline_start))
|
|
|
|
# Consolidated report
|
|
local report_file="$workspace/ci-pipeline-report.json"
|
|
cat > "$report_file" << EOF
|
|
{
|
|
"timestamp": "$(date -Iseconds)",
|
|
"pipeline_type": "full_ci",
|
|
"duration_seconds": $duration,
|
|
"exit_code": $exit_code,
|
|
"environment": {
|
|
"node_version": "$(node --version)",
|
|
"platform": "$(uname -s)",
|
|
"working_directory": "$BASE_DIR"
|
|
},
|
|
"checks_performed": [
|
|
"environment_validation",
|
|
"integration_tests",
|
|
"workflow_validation_tests",
|
|
"health_monitoring",
|
|
"advanced_validation",
|
|
"dependency_validation",
|
|
"performance_monitoring"
|
|
],
|
|
"artifacts": [
|
|
"integration-tests.log",
|
|
"workflow-tests.log",
|
|
"health-check.log",
|
|
"advanced-validation.log",
|
|
"dependency-validation.log",
|
|
"performance-monitor.log",
|
|
"npm-install.log"
|
|
],
|
|
"workspace": "$workspace"
|
|
}
|
|
EOF
|
|
|
|
ci_log "INFO" "CI pipeline report saved to: $report_file"
|
|
ci_log "INFO" "CI artifacts saved to: $workspace"
|
|
ci_log "INFO" "Pipeline duration: ${duration}s"
|
|
|
|
if [ $exit_code -eq 0 ]; then
|
|
ci_log "PASS" "CI pipeline completed successfully"
|
|
else
|
|
ci_log "FAIL" "CI pipeline failed"
|
|
fi
|
|
|
|
return $exit_code
|
|
}
|
|
|
|
# Install Git hooks
|
|
install_git_hooks() {
|
|
ci_log "INFO" "Installing Git hooks..."
|
|
|
|
local hooks_dir="$BASE_DIR/.git/hooks"
|
|
local agents_hooks_dir="$AGENTS_DIR/scripts/git-hooks"
|
|
|
|
# Create git-hooks directory
|
|
mkdir -p "$agents_hooks_dir"
|
|
|
|
# Create pre-commit hook
|
|
cat > "$agents_hooks_dir/pre-commit" << 'EOF'
|
|
#!/bin/bash
|
|
# Pre-commit hook for .agents validation
|
|
echo "Running .agents pre-commit validation..."
|
|
if bash .agents/scripts/ci-hooks.sh pre-commit; then
|
|
echo "Pre-commit validation passed"
|
|
exit 0
|
|
else
|
|
echo "Pre-commit validation failed"
|
|
exit 1
|
|
fi
|
|
EOF
|
|
|
|
# Create pre-push hook
|
|
cat > "$agents_hooks_dir/pre-push" << 'EOF'
|
|
#!/bin/bash
|
|
# Pre-push hook for .agents validation
|
|
echo "Running .agents pre-push validation..."
|
|
if bash .agents/scripts/ci-hooks.sh pre-push; then
|
|
echo "Pre-push validation passed"
|
|
exit 0
|
|
else
|
|
echo "Pre-push validation failed"
|
|
exit 1
|
|
fi
|
|
EOF
|
|
|
|
# Make hooks executable
|
|
chmod +x "$agents_hooks_dir/pre-commit"
|
|
chmod +x "$agents_hooks_dir/pre-push"
|
|
|
|
# Install hooks if .git directory exists
|
|
if [ -d "$hooks_dir" ]; then
|
|
cp "$agents_hooks_dir/pre-commit" "$hooks_dir/"
|
|
cp "$agents_hooks_dir/pre-push" "$hooks_dir/"
|
|
ci_log "PASS" "Git hooks installed successfully"
|
|
else
|
|
ci_log "WARN" "Git repository not found, hooks copied to .agents/scripts/git-hooks"
|
|
fi
|
|
}
|
|
|
|
# Main function
|
|
main() {
|
|
local command="${1:-help}"
|
|
|
|
case "$command" in
|
|
"pre-commit")
|
|
pre_commit_hook
|
|
;;
|
|
"pre-push")
|
|
pre_push_hook
|
|
;;
|
|
"ci-pipeline")
|
|
ci_pipeline_hook
|
|
;;
|
|
"install-hooks")
|
|
install_git_hooks
|
|
;;
|
|
"help"|*)
|
|
echo "Usage: $0 {pre-commit|pre-push|ci-pipeline|install-hooks|help}"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " pre-commit - Run pre-commit validation"
|
|
echo " pre-push - Run pre-push validation"
|
|
echo " ci-pipeline - Run full CI pipeline"
|
|
echo " install-hooks - Install Git hooks"
|
|
echo " help - Show this help"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Run main function with all arguments
|
|
main "$@"
|