Code Quality #506
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Code Quality | |
| # Comprehensive code quality checks | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| schedule: | |
| # Run quality checks daily at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| permissions: | |
| contents: read | |
| security-events: write | |
| actions: read | |
| env: | |
| DOTNET_VERSION: '9.0.x' | |
| DOTNET_NOLOGO: true | |
| DOTNET_CLI_TELEMETRY_OPTOUT: true | |
| jobs: | |
| code-analysis: | |
| name: 🔍 Code Analysis | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 📥 Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: 🔧 Setup Complete Environment | |
| uses: ./.github/actions/setup-environment | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| enable-nuget-cache: true | |
| - name: 🔨 Build and Test with Coverage | |
| uses: ./.github/actions/build-and-test | |
| with: | |
| configuration: 'Release' | |
| enable-coverage: true | |
| - name: 📊 Upload coverage to Codecov | |
| if: always() | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| directory: artifacts/coverage/ | |
| fail_ci_if_error: false | |
| verbose: false | |
| continue-on-error: true | |
| - name: 📤 Upload test results | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: code-analysis-results | |
| path: | | |
| artifacts/test-results/ | |
| artifacts/coverage/ | |
| if-no-files-found: warn | |
| retention-days: 30 | |
| security-scan: | |
| name: 🔒 Security Scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 📥 Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - name: 🔧 Setup Complete Environment | |
| uses: ./.github/actions/setup-environment | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| enable-nuget-cache: true | |
| - name: 🔍 Initialize CodeQL | |
| uses: github/codeql-action/init@v3 | |
| with: | |
| languages: csharp | |
| - name: 🔨 Build for Analysis | |
| uses: ./.github/actions/build-and-test | |
| with: | |
| configuration: 'Release' | |
| enable-coverage: false | |
| skip-tests: true | |
| - name: 🔬 Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@v3 | |
| - name: 🛡️ Run security audit | |
| shell: pwsh | |
| run: | | |
| # Explicitly target the primary solution to avoid ambiguity when multiple .sln files exist | |
| $sln = "AGI.Kapster.sln" | |
| # Check for known vulnerabilities in NuGet packages | |
| dotnet list $sln package --vulnerable --include-transitive 2>&1 | Tee-Object -FilePath "security-audit.log" | |
| # Check for outdated packages | |
| dotnet list $sln package --outdated 2>&1 | Tee-Object -FilePath "outdated-packages.log" | |
| - name: 📄 Upload security reports | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: security-reports | |
| path: | | |
| security-audit.log | |
| outdated-packages.log | |
| if-no-files-found: warn | |
| retention-days: 30 | |
| # TODO: Re-enable performance tests when needed for complex performance-critical features | |
| # performance-test: | |
| # name: ⚡ Performance Test | |
| # runs-on: ubuntu-latest | |
| # if: github.event_name != 'schedule' # Skip on scheduled runs | |
| # | |
| # steps: | |
| # - name: 📥 Checkout repository | |
| # uses: actions/checkout@v4 | |
| # with: | |
| # fetch-depth: 1 | |
| # | |
| # - name: 🔧 Setup Complete Environment | |
| # uses: ./.github/actions/setup-environment | |
| # with: | |
| # dotnet-version: ${{ env.DOTNET_VERSION }} | |
| # enable-nuget-cache: true | |
| # | |
| # - name: 🔨 Build for Performance Testing | |
| # uses: ./.github/actions/build-and-test | |
| # with: | |
| # configuration: 'Release' | |
| # enable-coverage: false | |
| # skip-tests: false | |
| # cache-key-suffix: '-perf' | |
| # | |
| # - name: ⚡ Run performance tests | |
| # shell: pwsh | |
| # run: | | |
| # if (Test-Path "tests/") { | |
| # ./build.ps1 Test --configuration Release --test-filter "Category=Performance" | |
| # } else { | |
| # Write-Host "⚠️ No performance tests found, skipping..." | |
| # } | |
| # | |
| # - name: 📊 Generate performance report | |
| # shell: pwsh | |
| # run: | | |
| # # Basic performance metrics | |
| # Write-Host "📊 Build Performance Metrics" | Tee-Object -FilePath "performance-report.md" | |
| # Write-Host "=============================" | Tee-Object -Append -FilePath "performance-report.md" | |
| # Write-Host "" | Tee-Object -Append -FilePath "performance-report.md" | |
| # | |
| # # Check assembly sizes | |
| # Write-Host "## Assembly Sizes" | Tee-Object -Append -FilePath "performance-report.md" | |
| # if (Test-Path "artifacts/publish") { | |
| # Get-ChildItem "artifacts/publish" -Recurse -Filter "*.dll" | | |
| # Sort-Object Length -Descending | | |
| # Select-Object Name, @{Name="Size(MB)";Expression={[math]::Round($_.Length/1MB,2)}} | | |
| # Format-Table | Out-String | Tee-Object -Append -FilePath "performance-report.md" | |
| # } else { | |
| # Write-Host "No publish artifacts found for analysis." | Tee-Object -Append -FilePath "performance-report.md" | |
| # } | |
| # | |
| # # Build timing (if available) | |
| # Write-Host "## Build Performance" | Tee-Object -Append -FilePath "performance-report.md" | |
| # Write-Host "Build completed at: $(Get-Date)" | Tee-Object -Append -FilePath "performance-report.md" | |
| # | |
| # # Ensure file exists | |
| # if (-not (Test-Path "performance-report.md")) { | |
| # Write-Host "Creating fallback performance report..." | |
| # "Performance report generated at $(Get-Date)" | Out-File -FilePath "performance-report.md" | |
| # } | |
| # | |
| # - name: 📊 Upload performance report | |
| # uses: actions/upload-artifact@v4 | |
| # if: always() | |
| # with: | |
| # name: performance-report | |
| # path: performance-report.md | |
| # if-no-files-found: warn | |
| # retention-days: 30 | |
| quality-gate: | |
| name: 🎯 Quality Gate | |
| runs-on: ubuntu-latest | |
| needs: [code-analysis, security-scan] | |
| if: always() | |
| steps: | |
| - name: 📊 Evaluate quality metrics | |
| shell: pwsh | |
| run: | | |
| Write-Host "🎯 Quality Gate Evaluation" | |
| Write-Host "==========================" | |
| $codeAnalysisResult = "${{ needs.code-analysis.result }}" | |
| $securityScanResult = "${{ needs.security-scan.result }}" | |
| Write-Host "Code Analysis: $codeAnalysisResult" | |
| Write-Host "Security Scan: $securityScanResult" | |
| Write-Host "Dependency Check: SKIPPED (requires GitHub Advanced Security)" | |
| $allPassed = ($codeAnalysisResult -eq "success") -and | |
| ($securityScanResult -eq "success") | |
| if ($allPassed) { | |
| Write-Host "✅ Quality gate PASSED - All checks successful!" | |
| } else { | |
| Write-Host "❌ Quality gate FAILED - Some checks failed!" | |
| if ($env:GITHUB_EVENT_NAME -eq "pull_request") { | |
| Write-Host "::error::Quality gate failed. Please address the issues before merging." | |
| exit 1 | |
| } | |
| } |