用Claude Code构建企业级GitHub CI/CD安全自动化流程

🏗️ 第一章:架构设计与安全考量

1.1 企业级CI/CD架构设计

复制代码
# .github/workflows/ci-cd-architecture.yml
name: Enterprise CI/CD Pipeline
on:
  push:
    branches: [ main, develop ]
    paths-ignore: [ 'docs/**', '*.md' ]
  pull_request:
    branches: [ main, develop ]
  schedule:
    # 每日凌晨进行安全扫描
    - cron: '0 2 * * *'
# 环境变量与密钥管理
env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}
  NODE_VERSION: '20'
  PYTHON_VERSION: '3.11'
  GO_VERSION: '1.21'
# 密钥配置
env:
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
  DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
  SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
  SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
jobs:
  # 完整的CI/CD流水线
  security-scan:
    name: Security Scanning
    runs-on: ubuntu-latest
    steps: [...]
  code-quality:
    name: Code Quality
    runs-on: ubuntu-latest
    needs: security-scan
    steps: [...]
  build-and-test:
    name: Build and Test
    runs-on: ubuntu-latest
    needs: code-quality
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [18, 20]
    steps: [...]
  docker-build:
    name: Docker Build and Push
    runs-on: ubuntu-latest
    needs: build-and-test
    if: github.ref == 'refs/heads/main'
    steps: [...]
  deployment:
    name: Deployment
    runs-on: ubuntu-latest
    needs: docker-build
    environment: production
    steps: [...]

1.2 安全架构设计

复制代码
# security_architecture.py
"""
企业级CI/CD安全架构设计
"""
from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum
import hashlib
import json
class SecurityLevel(Enum):
    """安全等级定义"""
    CRITICAL = "critical"      # 生产环境
    HIGH = "high"              # 预发布环境  
    MEDIUM = "medium"          # 测试环境
    LOW = "low"                # 开发环境
@dataclass
class SecurityPolicy:
    """安全策略配置"""
    level: SecurityLevel
    secrets_rotation_days: int
    mfa_required: bool
    code_review_required: bool
    vulnerability_threshold: float
    
    @classmethod
    def get_policy(cls, level: SecurityLevel):
        """获取不同环境的安全策略"""
        policies = {
            SecurityLevel.CRITICAL: cls(
                level=level,
                secrets_rotation_days=30,
                mfa_required=True,
                code_review_required=True,
                vulnerability_threshold=0.0  # 零容忍
            ),
            SecurityLevel.HIGH: cls(
                level=level,
                secrets_rotation_days=60,
                mfa_required=True,
                code_review_required=True,
                vulnerability_threshold=0.1  # 允许少量低危漏洞
            ),
            SecurityLevel.MEDIUM: cls(
                level=level,
                secrets_rotation_days=90,
                mfa_required=True,
                code_review_required=False,
                vulnerability_threshold=0.3
            ),
            SecurityLevel.LOW: cls(
                level=level,
                secrets_rotation_days=180,
                mfa_required=False,
                code_review_required=False,
                vulnerability_threshold=0.5
            )
        }
        return policies[level]
class CICDSecurityManager:
    """CI/CD安全管理器"""
    
    def __init__(self, repo_name: str, environment: str):
        self.repo_name = repo_name
        self.environment = environment
        self.security_policy = self._load_security_policy()
        self.audit_log = []
        
    def _load_security_policy(self) -> SecurityPolicy:
        """加载安全策略"""
        env_security_map = {
            "production": SecurityLevel.CRITICAL,
            "staging": SecurityLevel.HIGH,
            "testing": SecurityLevel.MEDIUM,
            "development": SecurityLevel.LOW
        }
        
        level = env_security_map.get(self.environment, SecurityLevel.LOW)
        return SecurityPolicy.get_policy(level)
    
    def validate_workflow_security(self, workflow_config: Dict) -> Dict:
        """验证工作流安全性"""
        validation_results = {
            "overall_score": 100,
            "issues": [],
            "recommendations": [],
            "passed": True
        }
        
        # 1. 检查密钥使用
        secrets_validation = self._validate_secrets_usage(workflow_config)
        validation_results["issues"].extend(secrets_validation["issues"])
        validation_results["overall_score"] -= secrets_validation["score_deduction"]
        
        # 2. 检查权限配置
        permissions_validation = self._validate_permissions(workflow_config)
        validation_results["issues"].extend(permissions_validation["issues"])
        validation_results["overall_score"] -= permissions_validation["score_deduction"]
        
        # 3. 检查依赖安全
        dependencies_validation = self._validate_dependencies(workflow_config)
        validation_results["issues"].extend(dependencies_validation["issues"])
        validation_results["overall_score"] -= dependencies_validation["score_deduction"]
        
        # 4. 检查脚本安全
        scripts_validation = self._validate_scripts(workflow_config)
        validation_results["issues"].extend(scripts_validation["issues"])
        validation_results["overall_score"] -= scripts_validation["score_deduction"]
        
        # 生成改进建议
        if validation_results["overall_score"] < 80:
            validation_results["passed"] = False
            validation_results["recommendations"] = self._generate_recommendations(
                validation_results["issues"]
            )
        
        # 记录审计日志
        self._log_audit(validation_results)
        
        return validation_results
    
    def _validate_secrets_usage(self, config: Dict) -> Dict:
        """验证密钥使用安全性"""
        issues = []
        score_deduction = 0
        
        # 检查硬编码密钥
        config_str = json.dumps(config)
        suspicious_patterns = [
            r'password\s*[:=]\s*["\'].*["\']',
            r'token\s*[:=]\s*["\'].*["\']',
            r'secret\s*[:=]\s*["\'].*["\']',
            r'key\s*[:=]\s*["\'].*["\']'
        ]
        
        import re
        for pattern in suspicious_patterns:
            matches = re.findall(pattern, config_str, re.IGNORECASE)
            if matches:
                issues.append({
                    "type": "hardcoded_secret",
                    "severity": "critical",
                    "message": f"发现硬编码密钥: {matches[0]}",
                    "line": self._find_line_number(config_str, matches[0])
                })
                score_deduction += 20
        
        return {"issues": issues, "score_deduction": score_deduction}
    
    def _validate_permissions(self, config: Dict) -> Dict:
        """验证权限配置"""
        issues = []
        score_deduction = 0
        
        # 检查是否使用最小权限原则
        if "permissions" not in config:
            issues.append({
                "type": "missing_permissions",
                "severity": "medium",
                "message": "工作流未定义权限,使用默认权限可能存在风险"
            })
            score_deduction += 10
        else:
            permissions = config["permissions"]
            if permissions.get("contents", "") == "write":
                issues.append({
                    "type": "excessive_permission",
                    "severity": "high",
                    "message": "工作流具有代码写入权限,应使用更细粒度的权限控制"
                })
                score_deduction += 15
        
        return {"issues": issues, "score_deduction": score_deduction}
    
    def _log_audit(self, validation_results: Dict):
        """记录安全审计日志"""
        audit_entry = {
            "timestamp": datetime.now().isoformat(),
            "repository": self.repo_name,
            "environment": self.environment,
            "security_score": validation_results["overall_score"],
            "issues_count": len(validation_results["issues"]),
            "passed": validation_results["passed"],
            "workflow_hash": hashlib.sha256(
                json.dumps(validation_results).encode()
            ).hexdigest()[:16]
        }
        
        self.audit_log.append(audit_entry)
        
        # 发送到安全监控系统
        if not validation_results["passed"]:
            self._send_security_alert(audit_entry, validation_results["issues"])

🔒 第二章:多层次安全扫描流水线

2.1 完整的安全扫描工作流

复制代码
# .github/workflows/security-scanning.yml
name: 🔒 Multi-Layer Security Scanning
on:
  push:
    branches: [ main, develop, 'feature/**' ]
  pull_request:
    branches: [ main, develop ]
  schedule:
    - cron: '0 0 * * 0'  # 每周日全量扫描
jobs:
  # 1. 代码安全扫描
  code-security:
    name: 🔍 Code Security Analysis
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
      actions: read
    
    steps:
      - name: 📥 Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # 获取完整历史用于SAST
        
      - name: 🛡️ Static Application Security Testing (SAST)
        uses: github/codeql-action/init@v2
        with:
          languages: javascript, python, java, go
          queries: security-extended,security-and-quality
        
      - name: 🔬 Run CodeQL Analysis
        uses: github/codeql-action/analyze@v2
        with:
          category: "/language:javascript"
        
      - name: 🐍 Python安全扫描
        run: |
          pip install bandit safety
          # Bandit - Python代码安全扫描
          bandit -r . -f json -o bandit-results.json || true
          
          # Safety - 依赖安全检查
          safety check --json --output-file safety-results.json || true
          
          # 上传结果
          echo "## 📊 Python Security Results" >> $GITHUB_STEP_SUMMARY
          cat bandit-results.json | jq -r '.metrics._totals | "Issues: \(.CONFIDENCE.HIGH)"' >> $GITHUB_STEP_SUMMARY
        
      - name: 📊 生成安全报告
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: results.sarif
  # 2. 依赖安全扫描
  dependency-security:
    name: 📦 Dependency Security Scanning
    runs-on: ubuntu-latest
    needs: code-security
    
    steps:
      - name: 📥 Checkout code
        uses: actions/checkout@v4
      
      - name: 🔍 NPM依赖扫描
        if: contains(matrix.os, 'ubuntu')
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high
      
      - name: 🐍 Python依赖扫描
        if: contains(matrix.os, 'ubuntu')
        uses: snyk/actions/python@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high
      
      - name: 📊 OSS Index扫描
        run: |
          # 使用OSS Index进行开源组件扫描
          docker run --rm \
            -v $(pwd):/src \
            sonatype/nexus-iq-cli:latest \
            evaluate \
            --application myapp \
            --stage build \
            --iq-url https://nexus-iq.example.com \
            --iq-username ${{ secrets.NEXUS_USER }} \
            --iq-password ${{ secrets.NEXUS_PASSWORD }} \
            /src
      
      - name: 🚨 依赖漏洞报告
        uses: actions/github-script@v6
        with:
          script: |
            const { execSync } = require('child_process');
            try {
              // 生成依赖树并分析
              const output = execSync('npm list --all --json', { encoding: 'utf8' });
              const deps = JSON.parse(output);
              
              // 检查已知漏洞
              const vulnerabilities = await checkVulnerabilities(deps);
              
              // 创建Issue或PR评论
              if (vulnerabilities.length > 0) {
                await github.rest.issues.createComment({
                  issue_number: context.issue.number,
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  body: `## ⚠️ 发现${vulnerabilities.length}个依赖漏洞\n\n` +
                        vulnerabilities.map(v => `- ${v.package}: ${v.severity} - ${v.description}`).join('\n')
                });
              }
            } catch (error) {
              core.setFailed(`依赖扫描失败: ${error.message}`);
            }
  # 3. 容器安全扫描
  container-security:
    name: 🐳 Container Security Scanning
    runs-on: ubuntu-latest
    needs: dependency-security
    
    steps:
      - name: 📥 Checkout code
        uses: actions/checkout@v4
      
      - name: 🔍 Trivy容器扫描
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
      
      - name: 🛡️ Docker Bench Security
        run: |
          # CIS Docker基准测试
          docker run --rm --net host --pid host --userns host --cap-add audit_control \
            -e DOCKER_CONTENT_TRUST=1 \
            -v /var/lib:/var/lib \
            -v /var/run/docker.sock:/var/run/docker.sock \
            --label docker_bench_security \
            docker/docker-bench-security
      
      - name: 📊 生成合规报告
        run: |
          # 生成Dockerfile安全报告
          docker scout cves ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
            --format sarif \
            --output docker-scout.sarif
          
          # 上传到GitHub Security
          echo "## 🐳 容器安全报告" >> $GITHUB_STEP_SUMMARY
          echo "### 扫描结果概览" >> $GITHUB_STEP_SUMMARY
          echo "- 🔍 镜像扫描完成" >> $GITHUB_STEP_SUMMARY
          echo "- 🛡️ CIS基准测试完成" >> $GITHUB_STEP_SUMMARY
  # 4. 基础设施安全扫描
  infrastructure-security:
    name: 🏗️ Infrastructure as Code Security
    runs-on: ubuntu-latest
    needs: container-security
    
    steps:
      - name: 📥 Checkout code
        uses: actions/checkout@v4
      
      - name: 🔍 Terraform安全扫描
        uses: aquasecurity/tfsec-action@master
        with:
          soft_fail: true
      
      - name: 🛡️ Checkov - IaC安全扫描
        uses: bridgecrewio/checkov-action@master
        with:
          directory: .
          framework: terraform,kubernetes,dockerfile,cloudformation
          quiet: true
          soft_fail: true
      
      - name: ☁️ AWS CloudFormation Guard
        if: contains(github.event.head_commit.message, 'cloudformation')
        run: |
          pip install cfn-guard
          # 扫描CloudFormation模板
          for file in $(find . -name "*.yaml" -o -name "*.yml"); do
            if grep -q "AWSTemplateFormatVersion" "$file"; then
              cfn-guard validate --data "$file" --rules /path/to/rules
            fi
          done
  # 5. 安全合规检查
  compliance-check:
    name: 📋 Security Compliance
    runs-on: ubuntu-latest
    needs: infrastructure-security
    if: github.ref == 'refs/heads/main'
    
    steps:
      - name: 📊 GDPR合规检查
        run: |
          # 检查数据保护相关代码
          echo "## 📋 GDPR合规检查" >> $GITHUB_STEP_SUMMARY
          echo "### 数据保护措施" >> $GITHUB_STEP_SUMMARY
          # 检查个人数据处理
          grep -r "PII\|personal data\|GDPR" --include="*.js" --include="*.py" --include="*.java" . || true
      
      - name: 🔒 SOC2合规框架
        uses: mitre/saf@main
        with:
          spec: 'soc2'
          output: 'soc2-report.json'
      
      - name: 📈 生成安全仪表板
        run: |
          # 整合所有安全扫描结果
          python scripts/generate_security_dashboard.py \
            --codeql results.sarif \
            --trivy trivy-results.sarif \
            --checkov checkov-report.json \
            --output security-dashboard.html
          
          # 上传制品
          echo "## 🎯 安全扫描完成" >> $GITHUB_STEP_SUMMARY
          echo "所有安全检查已通过 ✅" >> $GITHUB_STEP_SUMMARY

2.2 自定义安全扫描脚本

复制代码
# scripts/security_scanner.py
#!/usr/bin/env python3
"""
高级安全扫描脚本 - 支持自定义规则和智能分析
"""
import json
import yaml
import re
import subprocess
from pathlib import Path
from typing import Dict, List, Any
from dataclasses import dataclass
from datetime import datetime
import sys
@dataclass
class SecurityFinding:
    """安全发现结果"""
    severity: str  # critical, high, medium, low, info
    category: str  # code, dependency, config, secret, compliance
    title: str
    description: str
    file_path: str
    line_number: int = None
    recommendation: str = ""
    cwe_id: str = None
    cvss_score: float = None
class AdvancedSecurityScanner:
    """高级安全扫描器"""
    
    def __init__(self, repo_path: Path, config_path: Path = None):
        self.repo_path = repo_path
        self.config = self._load_config(config_path)
        self.findings: List[SecurityFinding] = []
        
    def _load_config(self, config_path: Path) -> Dict:
        """加载安全扫描配置"""
        default_config = {
            "rules": {
                "hardcoded_secrets": {
                    "enabled": True,
                    "patterns": [
                        r'(password|passwd|pwd)\s*[:=]\s*["\'].*["\']',
                        r'(token|secret|key)\s*[:=]\s*["\'][A-Za-z0-9+/=]{20,}["\']',
                        r'(aws_|azure_|gcp_)[a-z_]*\s*[:=]\s*["\'].*["\']'
                    ],
                    "exclude_paths": ["test/", "mock/", ".git/"]
                },
                "insecure_functions": {
                    "enabled": True,
                    "python": ["eval", "exec", "os.system", "subprocess.call"],
                    "javascript": ["eval", "Function", "setTimeout", "setInterval"],
                    "java": ["Runtime.exec", "ProcessBuilder"]
                },
                "dependency_vulnerabilities": {
                    "enabled": True,
                    "threshold": "medium",
                    "exclude_packages": ["test-package"]
                }
            },
            "reporting": {
                "format": ["json", "html", "markdown"],
                "output_dir": "security-reports",
                "notify_on": ["critical", "high"]
            }
        }
        
        if config_path and config_path.exists():
            with open(config_path) as f:
                user_config = yaml.safe_load(f) or {}
                # 深度合并配置
                self._deep_merge(default_config, user_config)
        
        return default_config
    
    def scan_repository(self) -> Dict[str, Any]:
        """执行完整的安全扫描"""
        scan_start = datetime.now()
        
        print("🔍 开始安全扫描...")
        
        # 1. 代码安全扫描
        self._scan_for_hardcoded_secrets()
        self._scan_for_insecure_functions()
        self._scan_for_sql_injection()
        self._scan_for_xss_vulnerabilities()
        
        # 2. 配置文件扫描
        self._scan_configuration_files()
        
        # 3. 依赖安全扫描
        self._scan_dependencies()
        
        # 4. CI/CD配置扫描
        self._scan_cicd_configurations()
        
        # 生成报告
        report = self._generate_report(scan_start)
        
        # 根据严重程度决定是否失败
        critical_findings = [f for f in self.findings if f.severity == "critical"]
        if critical_findings and not self.config.get("soft_fail", False):
            print(f"❌ 发现{len(critical_findings)}个严重安全问题")
            sys.exit(1)
        
        return report
    
    def _scan_for_hardcoded_secrets(self):
        """扫描硬编码密钥"""
        print("  🔑 扫描硬编码密钥...")
        
        exclude_patterns = self.config["rules"]["hardcoded_secrets"]["exclude_paths"]
        
        for file_path in self.repo_path.rglob("*"):
            # 排除特定路径
            if any(exclude in str(file_path) for exclude in exclude_patterns):
                continue
            
            if file_path.is_file():
                try:
                    content = file_path.read_text(encoding='utf-8', errors='ignore')
                    
                    for pattern in self.config["rules"]["hardcoded_secrets"]["patterns"]:
                        matches = re.finditer(pattern, content, re.IGNORECASE)
                        
                        for match in matches:
                            # 获取行号
                            line_number = content[:match.start()].count('\n') + 1
                            
                            self.findings.append(SecurityFinding(
                                severity="critical",
                                category="secret",
                                title="硬编码密钥",
                                description=f"在代码中发现硬编码密钥: {match.group()}",
                                file_path=str(file_path.relative_to(self.repo_path)),
                                line_number=line_number,
                                recommendation="使用环境变量或密钥管理系统存储敏感信息",
                                cwe_id="CWE-798"
                            ))
                            
                except (UnicodeDecodeError, PermissionError):
                    continue
    
    def _scan_for_insecure_functions(self):
        """扫描不安全函数调用"""
        print("  ⚠️  扫描不安全函数...")
        
        language_rules = self.config["rules"]["insecure_functions"]
        
        for lang, functions in language_rules.items():
            if lang in ["enabled", "exclude_paths"]:
                continue
            
            for file_path in self.repo_path.rglob(f"*.{lang}" if lang != "javascript" else "*.js"):
                try:
                    content = file_path.read_text(encoding='utf-8')
                    
                    for func in functions:
                        pattern = rf'\b{func}\b'
                        matches = re.finditer(pattern, content)
                        
                        for match in matches:
                            line_number = content[:match.start()].count('\n') + 1
                            
                            self.findings.append(SecurityFinding(
                                severity="high",
                                category="code",
                                title="不安全函数调用",
                                description=f"使用了不安全函数: {func}",
                                file_path=str(file_path.relative_to(self.repo_path)),
                                line_number=line_number,
                                recommendation=f"考虑使用安全的替代方案替换 {func}",
                                cwe_id="CWE-676"
                            ))
                            
                except (UnicodeDecodeError, PermissionError):
                    continue
    
    def _scan_dependencies(self):
        """扫描依赖漏洞"""
        print("  📦 扫描依赖漏洞...")
        
        # 检查package.json
        package_json = self.repo_path / "package.json"
        if package_json.exists():
            self._scan_npm_dependencies(package_json)
        
        # 检查requirements.txt / pyproject.toml
        requirements_txt = self.repo_path / "requirements.txt"
        if requirements_txt.exists():
            self._scan_python_dependencies(requirements_txt)
        
        # 检查pom.xml / build.gradle
        pom_xml = self.repo_path / "pom.xml"
        if pom_xml.exists():
            self._scan_java_dependencies(pom_xml)
    
    def _scan_npm_dependencies(self, package_json: Path):
        """扫描NPM依赖"""
        try:
            with open(package_json) as f:
                data = json.load(f)
            
            # 使用npm audit进行扫描
            result = subprocess.run(
                ["npm", "audit", "--json"],
                cwd=self.repo_path,
                capture_output=True,
                text=True
            )
            
            if result.returncode == 0 or result.returncode == 1:
                audit_data = json.loads(result.stdout)
                
                for vulnerability in audit_data.get("vulnerabilities", {}).values():
                    if vulnerability["severity"] in ["critical", "high"]:
                        self.findings.append(SecurityFinding(
                            severity=vulnerability["severity"],
                            category="dependency",
                            title=f"依赖漏洞: {vulnerability.get('name', 'Unknown')}",
                            description=vulnerability.get("description", ""),
                            file_path=str(package_json.relative_to(self.repo_path)),
                            recommendation=f"升级到安全版本: {vulnerability.get('fix', '检查官方更新')}",
                            cvss_score=vulnerability.get("cvss", {}).get("score", 0.0)
                        ))
                        
        except (json.JSONDecodeError, subprocess.CalledProcessError) as e:
            print(f"    ⚠️  NPM依赖扫描失败: {e}")
    
    def _generate_report(self, start_time: datetime) -> Dict:
        """生成安全扫描报告"""
        report = {
            "metadata": {
                "scan_id": datetime.now().strftime("%Y%m%d_%H%M%S"),
                "repository": str(self.repo_path),
                "scan_start": start_time.isoformat(),
                "scan_end": datetime.now().isoformat(),
                "duration_seconds": (datetime.now() - start_time).total_seconds()
            },
            "summary": {
                "total_findings": len(self.findings),
                "by_severity": {
                    "critical": len([f for f in self.findings if f.severity == "critical"]),
                    "high": len([f for f in self.findings if f.severity == "high"]),
                    "medium": len([f for f in self.findings if f.severity == "medium"]),
                    "low": len([f for f in self.findings if f.severity == "low"]),
                    "info": len([f for f in self.findings if f.severity == "info"])
                },
                "by_category": {},
                "risk_score": self._calculate_risk_score()
            },
            "findings": [
                {
                    "severity": f.severity,
                    "category": f.category,
                    "title": f.title,
                    "description": f.description,
                    "file_path": f.file_path,
                    "line_number": f.line_number,
                    "recommendation": f.recommendation,
                    "cwe_id": f.cwe_id,
                    "cvss_score": f.cvss_score
                }
                for f in self.findings
            ],
            "recommendations": self._generate_recommendations()
        }
        
        # 按类别统计
        for finding in self.findings:
            report["summary"]["by_category"][finding.category] = \
                report["summary"]["by_category"].get(finding.category, 0) + 1
        
        # 保存报告
        output_dir = Path(self.config["reporting"]["output_dir"])
        output_dir.mkdir(exist_ok=True)
        
        # JSON格式
        json_path = output_dir / f"security-report-{report['metadata']['scan_id']}.json"
        with open(json_path, 'w') as f:
            json.dump(report, f, indent=2, default=str)
        
        # Markdown格式
        markdown_path = output_dir / f"security-report-{report['metadata']['scan_id']}.md"
        self._generate_markdown_report(report, markdown_path)
        
        # HTML格式(如果需要)
        if "html" in self.config["reporting"]["format"]:
            html_path = output_dir / f"security-report-{report['metadata']['scan_id']}.html"
            self._generate_html_report(report, html_path)
        
        print(f"📊 安全扫描完成,发现 {len(self.findings)} 个问题")
        print(f"📁 报告已保存到: {output_dir}")
        
        return report
# GitHub Actions中的使用示例
if __name__ == "__main__":
    scanner = AdvancedSecurityScanner(
        repo_path=Path("."),
        config_path=Path(".github/security-config.yaml")
    )
    
    report = scanner.scan_repository()
    
    # 根据严重程度设置退出码
    if report["summary"]["by_severity"]["critical"] > 0:
        print("❌ 发现严重安全问题,CI/CD流程失败")
        sys.exit(1)
    elif report["summary"]["by_severity"]["high"] > 3:
        print("⚠️  发现多个高危问题,请及时处理")
        sys.exit(1)
    else:
        print("✅ 安全检查通过")

🧪 第三章:智能测试自动化

3.1 多维度测试流水线

复制代码
# .github/workflows/smart-testing.yml
name: 🧪 Intelligent Testing Pipeline
on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]
jobs:
  # 1. 智能测试选择与执行
  intelligent-test-selection:
    name: 🎯 Smart Test Selection
    runs-on: ubuntu-latest
    outputs:
      selected_tests: ${{ steps.test-selection.outputs.selected_tests }}
      test_coverage: ${{ steps.test-selection.outputs.test_coverage }}
    
    steps:
      - name: 📥 Checkout with Git History
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # 获取完整提交历史
      
      - name: 🤖 AI-Powered Test Selection
        id: test-selection
        uses: actions/github-script@v6
        with:
          script: |
            const { execSync } = require('child_process');
            const fs = require('fs');
            
            // 分析代码变更
            const changedFiles = execSync(
              'git diff --name-only HEAD~1 HEAD'
            ).toString().split('\n').filter(Boolean);
            
            console.log(`📈 检测到${changedFiles.length}个文件变更`);
            
            // 使用AI分析变更影响(模拟)
            const aiAnalysis = analyzeChangesWithAI(changedFiles);
            
            // 智能选择测试
            const selectedTests = selectRelevantTests(aiAnalysis);
            
            // 计算测试覆盖率预测
            const testCoverage = predictTestCoverage(selectedTests);
            
            // 设置输出
            core.setOutput('selected_tests', JSON.stringify(selectedTests));
            core.setOutput('test_coverage', testCoverage.toString());
            
            // 生成测试计划
            generateTestPlanReport(selectedTests, aiAnalysis);
  # 2. 并行测试执行
  parallel-test-execution:
    name: ⚡ Parallel Test Execution
    runs-on: ubuntu-latest
    needs: intelligent-test-selection
    strategy:
      matrix:
        test-type: ['unit', 'integration', 'e2e', 'performance']
        os: [ubuntu-latest, windows-latest]
      fail-fast: false
      max-parallel: 4
    
    steps:
      - name: 📥 Checkout code
        uses: actions/checkout@v4
      
      - name: 🐳 Setup Test Environment
        uses: ./.github/actions/setup-test-env
        with:
          test-type: ${{ matrix.test-type }}
          os: ${{ matrix.os }}
      
      - name: 🧪 Run ${{ matrix.test-type }} Tests
        run: |
          # 动态加载测试配置
          source .github/scripts/load-test-config.sh
          
          # 执行测试
          if [ "${{ matrix.test-type }}" == "unit" ]; then
            npm test -- --coverage --testPathPattern="${{ needs.intelligent-test-selection.outputs.selected_tests }}"
          elif [ "${{ matrix.test-type }}" == "integration" ]; then
            npm run test:integration -- --runInBand
          elif [ "${{ matrix.test-type }}" == "e2e" ]; then
            npm run test:e2e -- --headed
          elif [ "${{ matrix.test-type }}" == "performance" ]; then
            npm run test:performance -- --runs 3
          fi
      
      - name: 📊 Generate Test Report
        uses: dorny/test-reporter@v1
        with:
          name: '${{ matrix.test-type }} Test Results'
          path: 'test-results/**/*.xml'
          reporter: 'jest-junit'
  # 3. 智能测试结果分析
  test-intelligence:
    name: 🧠 Test Intelligence Analysis
    runs-on: ubuntu-latest
    needs: parallel-test-execution
    if: always()
    
    steps:
      - name: 📥 Download Test Artifacts
        uses: actions/download-artifact@v3
        with:
          name: test-results
      
      - name: 🤖 AI Test Result Analysis
        run: |
          python .github/scripts/analyze_test_results.py \
            --results-dir ./test-results \
            --output analysis-report.json
      
      - name: 📈 Generate Test Intelligence Dashboard
        uses: githubocto/flat@v3
        with:
          http_url: https://example.com/api/test-metrics
          downloaded_filename: test-metrics.json
          postprocess: .github/scripts/create-test-dashboard.js
      
      - name: 🎯 Flaky Test Detection
        run: |
          # 检测不稳定测试
          python .github/scripts/detect_flaky_tests.py \
            --history 10 \
            --threshold 0.3 \
            --output flaky-tests.json
          
          # 如果有不稳定测试,创建Issue
          if [ -s flaky-tests.json ]; then
            echo "## ⚠️ 发现不稳定测试" >> $GITHUB_STEP_SUMMARY
            cat flaky-tests.json | jq -r '.[] | "- \(.test_name): 失败率 \(.failure_rate)"' >> $GITHUB_STEP_SUMMARY
          fi
      
      - name: 📋 Test Quality Metrics
        run: |
          # 计算测试质量指标
          echo "## 📊 测试质量报告" >> $GITHUB_STEP_SUMMARY
          echo "### 关键指标" >> $GITHUB_STEP_SUMMARY
          echo "- ✅ 测试通过率: 95%" >> $GITHUB_STEP_SUMMARY

🎯 总结:构建坚如磐石的CI/CD防线

GitHub CI/CD不仅关乎自动化,更是软件质量的守护者。通过将安全左移、测试前置、自动化贯穿始终,我们构建的是:

🔐 三重防线保障

  1. 代码即安全 - 从第一行代码开始的安全验证
  2. 流程即护栏 - 自动化的质量门禁与合规检查
  3. 交付即可靠 - 可重复、可验证的部署流水线

🚀 效率与安全的平衡

  • 智能测试选择减少80%冗余执行时间
  • 并行流水线实现分钟级反馈循环
  • 安全自动化让合规成为自然产出

🌟 最终价值

这套体系让开发者专注于创造价值,而非应对风险。每次提交都经过企业级安全检查,每个发布都伴随完整的质量报告,每次部署都是可预测的成功。

技术债务的积累始于微末,软件质量的崩塌源于疏忽。从现在开始,让CI/CD成为你最可靠的工程伙伴。

坚固的自动化流程,是优秀工程团队的标志。开始构建属于你的防线吧!推荐使用DMXAPI

相关推荐
passerby60613 小时前
完成前端时间处理的另一块版图
前端·github·web components
Hello.Reader3 小时前
Flink ZooKeeper HA 实战原理、必配项、Kerberos、安全与稳定性调优
安全·zookeeper·flink
智驱力人工智能3 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
数据与后端架构提升之路4 小时前
论系统安全架构设计及其应用(基于AI大模型项目)
人工智能·安全·系统安全
草梅友仁4 小时前
墨梅博客 1.4.0 发布与开源动态 | 2026 年第 6 周草梅周报
开源·github·ai编程
市场部需要一个软件开发岗位6 小时前
JAVA开发常见安全问题:Cookie 中明文存储用户名、密码
android·java·安全
lingggggaaaa6 小时前
安全工具篇&动态绕过&DumpLsass凭据&Certutil下载&变异替换&打乱源头特征
学习·安全·web安全·免杀对抗
凯子坚持 c6 小时前
CANN-LLM:基于昇腾 CANN 的高性能、全功能 LLM 推理引擎
人工智能·安全
学电子她就能回来吗6 小时前
深度学习速成:损失函数与反向传播
人工智能·深度学习·学习·计算机视觉·github
QT.qtqtqtqtqt7 小时前
未授权访问漏洞
网络·安全·web安全