# 测试流水线脚本 # 用途: 执行完整的代码质量检查流程 # 包括: Linting -> Build -> Test -> Coverage -> Cleanup param( [switch]$SkipLint, [switch]$SkipBuild, [switch]$SkipTest, [switch]$Verbose ) $ErrorActionPreference = "Stop" $Script:FailureCount = 0 # 颜色输出函数 function Write-Success { param($Message) Write-Host "✓ $Message" -ForegroundColor Green } function Write-Failure { param($Message) Write-Host "✗ $Message" -ForegroundColor Red; $Script:FailureCount++ } function Write-Info { param($Message) Write-Host "→ $Message" -ForegroundColor Cyan } function Write-Section { param($Message) Write-Host "`n=== $Message ===" -ForegroundColor Yellow } # 清理函数 function Cleanup { Write-Section "Cleanup" # 删除构建产物 $artifacts = @("*.exe", "*.test", "coverage.out", "coverage.html") foreach ($pattern in $artifacts) { Get-ChildItem -Path . -Filter $pattern -Recurse -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue } # 清理测试生成的临时文件 Get-ChildItem -Path . -Filter ".env.test" -Recurse -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue Write-Success "Cleanup completed" } # Linting function Run-Linting { Write-Section "Code Linting" try { # 先运行 go fmt Write-Info "Formatting code..." $fmtOutput = go fmt ./... 2>&1 if ($fmtOutput) { Write-Info "Formatted files:" $fmtOutput | ForEach-Object { Write-Host " $_" -ForegroundColor Gray } } Write-Info "Running golangci-lint..." # 检查 golangci-lint 是否安装 $lintPath = Get-Command golangci-lint -ErrorAction SilentlyContinue if (-not $lintPath) { Write-Failure "golangci-lint not found. Please install it first." return $false } # 运行 linter $output = & golangci-lint run --config .golangci.yml ./... 2>&1 if ($LASTEXITCODE -eq 0) { Write-Success "Linting passed" return $true } else { Write-Failure "Linting failed" Write-Host $output -ForegroundColor Red return $false } } catch { Write-Failure "Linting error: $_" return $false } } # Build function Run-Build { Write-Section "Build" try { Write-Info "Building project..." # 使用 NUL 设备作为输出(Windows 的 /dev/null) $env:GOOS = "" $env:GOARCH = "" # 构建但不保存二进制文件 $output = go build -o NUL . 2>&1 if ($LASTEXITCODE -eq 0) { Write-Success "Build successful" return $true } else { Write-Failure "Build failed" if ($Verbose) { Write-Host $output -ForegroundColor Red } return $false } } catch { Write-Failure "Build error: $_" return $false } } # Tests function Run-Tests { Write-Section "Tests" try { Write-Info "Running unit tests..." # 运行短测试(跳过集成测试) # 注意: Windows 下不启用 race detector (需要 cgo) # PowerShell 需要使用引号包裹带等号的参数 $testOutput = go test -v -short "-coverprofile=coverage.out" ./... 2>&1 if ($LASTEXITCODE -eq 0) { Write-Success "All tests passed" # 显示覆盖率摘要 Write-Info "Coverage summary:" $coverageOutput = go tool cover -func coverage.out 2>&1 $totalLine = $coverageOutput | Select-String "total:" if ($totalLine) { Write-Host " $totalLine" -ForegroundColor White } # 可选:生成 HTML 覆盖率报告 if ($Verbose) { go tool cover -html=coverage.out -o coverage.html Write-Success "Coverage report generated: coverage.html" } return $true } else { Write-Failure "Tests failed" if ($Verbose) { Write-Host $output -ForegroundColor Red } return $false } } catch { Write-Failure "Test error: $_" return $false } } # 主流程 function Main { Write-Host @" ╔════════════════════════════════════════╗ ║ ES-Demo Test Pipeline v1.0 ║ ╚════════════════════════════════════════╝ "@ -ForegroundColor Magenta $startTime = Get-Date # 执行流水线步骤 $results = @{ Lint = $true Build = $true Test = $true } if (-not $SkipLint) { $results.Lint = Run-Linting } else { Write-Info "Skipping linting" } if (-not $SkipBuild) { $results.Build = Run-Build } else { Write-Info "Skipping build" } if (-not $SkipTest) { $results.Test = Run-Tests } else { Write-Info "Skipping tests" } # 清理 Cleanup # 结果汇总 $endTime = Get-Date $duration = $endTime - $startTime Write-Section "Summary" Write-Host "Lint: " -NoNewline if ($results.Lint) { Write-Success "PASS" } else { Write-Failure "FAIL" } Write-Host "Build: " -NoNewline if ($results.Build) { Write-Success "PASS" } else { Write-Failure "FAIL" } Write-Host "Test: " -NoNewline if ($results.Test) { Write-Success "PASS" } else { Write-Failure "FAIL" } Write-Host "`nTotal time: $($duration.TotalSeconds) seconds" -ForegroundColor Cyan # 返回退出码 if ($Script:FailureCount -gt 0) { Write-Host "`n❌ Pipeline FAILED with $Script:FailureCount error(s)" -ForegroundColor Red exit 1 } else { Write-Host "`n✅ Pipeline PASSED" -ForegroundColor Green exit 0 } } # 运行主流程 Main