Skip to main content
Glama
run_quality_checks_on_files.sh8.33 kB
#!/bin/bash # scripts/pr/run_quality_checks_on_files.sh - Run quality checks on specific files # # Usage: bash scripts/pr/run_quality_checks_on_files.sh [FILE1] [FILE2] ... # bash scripts/pr/run_quality_checks_on_files.sh --files-from=changed_files.txt # git diff origin/main...HEAD --name-only | bash scripts/pr/run_quality_checks_on_files.sh --stdin # # This script is designed for GitHub Actions and CI/CD workflows where we have # a list of changed files but no PR number yet. # # Exit codes: # 0 - All checks passed # 1 - Warnings found (non-blocking) # 2 - Critical issues found (blocking) set -e # Determine LLM command (Groq primary, Gemini fallback) LLM_CMD="" if [ -n "$GROQ_API_KEY" ] && command -v groq &> /dev/null; then LLM_CMD="groq" echo "Using Groq API for quality checks (fast mode)" elif command -v gemini &> /dev/null; then LLM_CMD="gemini" echo "Using Gemini CLI for quality checks" else echo "Error: No LLM available (neither Groq API nor Gemini CLI found)" echo "Install Groq CLI or Gemini CLI to run quality checks" exit 1 fi # Parse input files files=() if [ "$1" = "--stdin" ]; then # Read from stdin while IFS= read -r line; do [ -n "$line" ] && files+=("$line") done elif [ "$1" = "--files-from" ]; then # Read from file files_list="${2#--files-from=}" if [ -z "$files_list" ]; then files_list="$2" fi if [ ! -f "$files_list" ]; then echo "Error: File list not found: $files_list" exit 1 fi while IFS= read -r line; do [ -n "$line" ] && files+=("$line") done < "$files_list" else # Files provided as arguments files=("$@") fi # Filter for Python files only python_files=() for file in "${files[@]}"; do if [[ "$file" == *.py ]]; then python_files+=("$file") fi done if [ ${#python_files[@]} -eq 0 ]; then echo "No Python files to check." echo "::notice title=Quality Gate::No Python files changed - skipping quality checks" exit 0 fi echo "=== Quality Gate: File-Based Checks ===" echo "" echo "Checking ${#python_files[@]} Python file(s):" for file in "${python_files[@]}"; do echo " - $file" done echo "" exit_code=0 warnings=() critical_issues=() complexity_issues=() security_issues=() # Check 1: Code Complexity echo "=== Check 1: Code Complexity ===" for file in "${python_files[@]}"; do if [ ! -f "$file" ]; then echo "::warning file=$file::File not found in working directory, skipping" continue fi echo "Analyzing: $file" # Use LLM to analyze complexity result=$($LLM_CMD "Analyze code complexity. Rate each function 1-10 (1=simple, 10=very complex). Report ONLY functions with score >7 in format 'FunctionName: Score X - Reason'. If no functions have score >7, respond with 'COMPLEXITY_OK'. File content: $(cat "$file")" 2>&1 || echo "COMPLEXITY_OK") # Check for high complexity if echo "$result" | grep -qi "score [89]\|score 10"; then # Extract function names and scores for GitHub Actions annotations while IFS= read -r line; do if echo "$line" | grep -qi "score [89]\|score 10"; then function_name=$(echo "$line" | cut -d':' -f1 | xargs) score=$(echo "$line" | grep -oP 'Score \K[0-9]+' || echo "?") # Add GitHub Actions warning annotation echo "::warning file=$file,title=High Complexity::$line" complexity_issues+=("$file: $line") # Block on complexity >8, warn on 7-8 if [ "$score" -gt 8 ] 2>/dev/null; then warnings+=("BLOCKING: High complexity ($score) in $file - $function_name") exit_code=1 else warnings+=("WARNING: Moderate complexity ($score) in $file - $function_name") if [ $exit_code -eq 0 ]; then exit_code=1 fi fi fi done <<< "$result" else echo " ✅ Complexity OK" fi done echo "" # Check 2: Security Vulnerabilities echo "=== Check 2: Security Vulnerabilities ===" for file in "${python_files[@]}"; do if [ ! -f "$file" ]; then continue fi echo "Scanning: $file" # Request machine-parseable output (same as quality_gate.sh) result=$($LLM_CMD "Security audit. Check for: SQL injection (raw SQL), XSS (unescaped HTML), command injection (os.system, subprocess with shell=True), path traversal, hardcoded secrets. IMPORTANT: Output format: - If ANY vulnerability found, start response with: VULNERABILITY_DETECTED: [type] - If NO vulnerabilities found, start response with: SECURITY_CLEAN - Then provide details File content: $(cat "$file")" 2>&1 || echo "SECURITY_CLEAN") # Check for machine-parseable vulnerability marker if echo "$result" | grep -q "^VULNERABILITY_DETECTED:"; then vuln_type=$(echo "$result" | grep "^VULNERABILITY_DETECTED:" | cut -d':' -f2- | xargs) # Add GitHub Actions error annotation echo "::error file=$file,title=Security Vulnerability::$vuln_type" critical_issues+=("🔴 SECURITY: $file - $vuln_type") security_issues+=("$file: $vuln_type") exit_code=2 else echo " ✅ Security OK" fi done echo "" # Generate GitHub Actions outputs echo "::group::Quality Gate Summary" echo "" if [ $exit_code -eq 0 ]; then echo "✅ ALL CHECKS PASSED" echo "" echo "Quality Gate Results:" echo "- Code complexity: ✅ OK" echo "- Security scan: ✅ OK" echo "" # Set GitHub Actions output echo "quality_check_passed=true" >> $GITHUB_OUTPUT 2>/dev/null || true echo "quality_check_status=passed" >> $GITHUB_OUTPUT 2>/dev/null || true echo "::notice title=Quality Gate::All checks passed - ready for PR creation" elif [ $exit_code -eq 2 ]; then echo "🔴 CRITICAL FAILURES - PR CREATION BLOCKED" echo "" echo "Security vulnerabilities detected:" for issue in "${security_issues[@]}"; do echo " - $issue" done echo "" # Set GitHub Actions output echo "quality_check_passed=false" >> $GITHUB_OUTPUT 2>/dev/null || true echo "quality_check_status=failed" >> $GITHUB_OUTPUT 2>/dev/null || true echo "quality_check_blocking=true" >> $GITHUB_OUTPUT 2>/dev/null || true # Create detailed error summary for GitHub Actions { echo "## 🔴 Quality Gate FAILED - Security Issues" echo "" echo "**Critical security vulnerabilities detected. PR creation is blocked.**" echo "" echo "### Security Issues:" for issue in "${security_issues[@]}"; do echo "- $issue" done echo "" echo "**Action Required:**" echo "Fix all security vulnerabilities before proceeding." } >> $GITHUB_STEP_SUMMARY 2>/dev/null || true echo "::error title=Quality Gate::Security vulnerabilities detected - PR creation blocked" else echo "⚠️ WARNINGS DETECTED - NON-BLOCKING" echo "" if [ ${#complexity_issues[@]} -gt 0 ]; then echo "Complexity issues:" for issue in "${complexity_issues[@]}"; do echo " - $issue" done echo "" fi # Set GitHub Actions output echo "quality_check_passed=false" >> $GITHUB_OUTPUT 2>/dev/null || true echo "quality_check_status=warnings" >> $GITHUB_OUTPUT 2>/dev/null || true echo "quality_check_blocking=false" >> $GITHUB_OUTPUT 2>/dev/null || true # Create detailed warning summary for GitHub Actions { echo "## ⚠️ Quality Gate WARNINGS" echo "" echo "**Some checks require attention (non-blocking).**" echo "" if [ ${#complexity_issues[@]} -gt 0 ]; then echo "### Complexity Issues:" for issue in "${complexity_issues[@]}"; do echo "- $issue" done echo "" fi echo "**Recommendation:**" echo "Consider addressing these issues to improve code quality." } >> $GITHUB_STEP_SUMMARY 2>/dev/null || true echo "::warning title=Quality Gate::Code quality warnings detected - consider addressing before PR creation" fi echo "::endgroup::" echo "" exit $exit_code

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/doobidoo/mcp-memory-service'

If you have feedback or need assistance with the MCP directory API, please join our Discord server