feat: Enhance project configuration and add new features #2
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 Analysis | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| schedule: | |
| # Run weekly on Sundays at 2 AM UTC | |
| - cron: '0 2 * * 0' | |
| workflow_dispatch: | |
| env: | |
| DOTNET_VERSION: '9.0.x' | |
| NODE_VERSION: '20.x' | |
| jobs: | |
| # ============================================================================ | |
| # Frontend Code Quality | |
| # ============================================================================ | |
| frontend-quality: | |
| name: π¨ Frontend Code Quality | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: π₯ Checkout Code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: π¦ Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| cache-dependency-path: 'web/package-lock.json' | |
| - name: π Install Dependencies | |
| working-directory: ./web | |
| run: npm ci --prefer-offline --no-audit | |
| - name: π ESLint Analysis | |
| working-directory: ./web | |
| run: | | |
| npm run lint -- --format json --output-file eslint-report.json || true | |
| npm run lint -- --format unix || echo "ESLint found issues" | |
| - name: π― TypeScript Type Check | |
| working-directory: ./web | |
| run: npm run type-check || echo "Type checking found issues" | |
| - name: π Bundle Size Analysis | |
| working-directory: ./web | |
| run: | | |
| npm run build | |
| echo "## π¦ Bundle Size Analysis" >> $GITHUB_STEP_SUMMARY | |
| echo "| File | Size | Gzipped |" >> $GITHUB_STEP_SUMMARY | |
| echo "|------|------|---------|" >> $GITHUB_STEP_SUMMARY | |
| cd dist/assets | |
| for file in *.js *.css; do | |
| if [ -f "$file" ]; then | |
| original_size=$(stat -c%s "$file" | numfmt --to=iec) | |
| gzip_size=$(gzip -c "$file" | wc -c | numfmt --to=iec) | |
| echo "| $file | $original_size | $gzip_size |" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| done | |
| - name: π§ͺ Test Coverage | |
| working-directory: ./web | |
| run: | | |
| npm run test:coverage || echo "Test coverage analysis completed" | |
| - name: π€ Upload Coverage Reports | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| directory: ./web/coverage | |
| flags: frontend | |
| name: frontend-coverage | |
| continue-on-error: true | |
| - name: π€ Upload ESLint Report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: eslint-report | |
| path: web/eslint-report.json | |
| continue-on-error: true | |
| # ============================================================================ | |
| # Backend Code Quality | |
| # ============================================================================ | |
| backend-quality: | |
| name: π§ Backend Code Quality | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: π₯ Checkout Code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: π¦ Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: π Restore Dependencies | |
| run: dotnet restore | |
| - name: π§ Build Project | |
| run: dotnet build --no-restore --configuration Release | |
| - name: π§ͺ Run Tests with Coverage | |
| run: | | |
| dotnet test --no-build --configuration Release \ | |
| --collect:"XPlat Code Coverage" \ | |
| --results-directory ./coverage \ | |
| --logger trx \ | |
| --verbosity normal | |
| - name: π Code Coverage Report | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| directory: ./coverage | |
| flags: backend | |
| name: backend-coverage | |
| continue-on-error: true | |
| - name: π Security Analysis | |
| run: | | |
| echo "## π Security Analysis" >> $GITHUB_STEP_SUMMARY | |
| echo "### Vulnerable Packages" >> $GITHUB_STEP_SUMMARY | |
| if dotnet list package --vulnerable --include-transitive > vulnerable-packages.txt 2>&1; then | |
| if grep -q "no vulnerable packages" vulnerable-packages.txt; then | |
| echo "β No vulnerable packages found" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "β οΈ Vulnerable packages detected:" >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| cat vulnerable-packages.txt >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| else | |
| echo "β Security scan failed" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: π Code Metrics | |
| run: | | |
| echo "## π Code Metrics" >> $GITHUB_STEP_SUMMARY | |
| echo "### Lines of Code" >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| find src -name "*.cs" -exec wc -l {} + | tail -1 >> $GITHUB_STEP_SUMMARY | |
| echo "\`\`\`" >> $GITHUB_STEP_SUMMARY | |
| echo "### File Count by Type" >> $GITHUB_STEP_SUMMARY | |
| echo "| Type | Count |" >> $GITHUB_STEP_SUMMARY | |
| echo "|------|-------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| C# Files | $(find src -name "*.cs" | wc -l) |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Project Files | $(find src -name "*.csproj" | wc -l) |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Test Files | $(find src -name "*Test*.cs" -o -name "*Tests*.cs" | wc -l) |" >> $GITHUB_STEP_SUMMARY | |
| # ============================================================================ | |
| # SonarCloud Analysis (Optional) | |
| # ============================================================================ | |
| sonarcloud: | |
| name: π SonarCloud Analysis | |
| runs-on: ubuntu-latest | |
| if: github.event_name != 'schedule' | |
| steps: | |
| - name: π₯ Checkout Code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: π¦ Setup Java | |
| uses: actions/setup-java@v3 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: π¦ Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: π Cache SonarCloud packages | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.sonar/cache | |
| key: ${{ runner.os }}-sonar | |
| restore-keys: ${{ runner.os }}-sonar | |
| - name: π Cache SonarCloud scanner | |
| id: cache-sonar-scanner | |
| uses: actions/cache@v3 | |
| with: | |
| path: ./.sonar/scanner | |
| key: ${{ runner.os }}-sonar-scanner | |
| restore-keys: ${{ runner.os }}-sonar-scanner | |
| - name: π¦ Install SonarCloud scanner | |
| if: steps.cache-sonar-scanner.outputs.cache-hit != 'true' | |
| run: | | |
| mkdir -p ./.sonar/scanner | |
| dotnet tool update dotnet-sonarscanner --tool-path ./.sonar/scanner | |
| - name: π Build and analyze | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| run: | | |
| if [ -z "$SONAR_TOKEN" ]; then | |
| echo "β οΈ SONAR_TOKEN not configured, skipping SonarCloud analysis" | |
| exit 0 | |
| fi | |
| ./.sonar/scanner/dotnet-sonarscanner begin \ | |
| /k:"ClaudeCodeProxy" \ | |
| /o:"your-org" \ | |
| /d:sonar.token="${SONAR_TOKEN}" \ | |
| /d:sonar.host.url="https://sonarcloud.io" \ | |
| /d:sonar.cs.vscoveragexml.reportsPaths=coverage/**/*.xml | |
| dotnet build --configuration Release | |
| dotnet test --configuration Release \ | |
| --collect:"Code Coverage" \ | |
| --results-directory ./coverage | |
| ./.sonar/scanner/dotnet-sonarscanner end /d:sonar.token="${SONAR_TOKEN}" | |
| continue-on-error: true | |
| # ============================================================================ | |
| # Dependency Review | |
| # ============================================================================ | |
| dependency-review: | |
| name: π Dependency Review | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: π₯ Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: π Dependency Review | |
| uses: actions/dependency-review-action@v3 | |
| with: | |
| fail-on-severity: moderate | |
| allow-licenses: MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC | |
| # ============================================================================ | |
| # CodeQL Analysis | |
| # ============================================================================ | |
| codeql: | |
| name: π CodeQL Analysis | |
| runs-on: ubuntu-latest | |
| permissions: | |
| actions: read | |
| contents: read | |
| security-events: write | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| language: [ 'csharp', 'javascript' ] | |
| steps: | |
| - name: π₯ Checkout Code | |
| uses: actions/checkout@v4 | |
| - name: π Initialize CodeQL | |
| uses: github/codeql-action/init@v3 | |
| with: | |
| languages: ${{ matrix.language }} | |
| - name: π¦ Setup .NET (for C#) | |
| if: matrix.language == 'csharp' | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: ${{ env.DOTNET_VERSION }} | |
| - name: π§ Build .NET Project | |
| if: matrix.language == 'csharp' | |
| run: | | |
| dotnet restore | |
| dotnet build --no-restore --configuration Release | |
| - name: π¦ Setup Node.js (for JavaScript) | |
| if: matrix.language == 'javascript' | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| cache-dependency-path: 'web/package-lock.json' | |
| - name: π§ Build Frontend | |
| if: matrix.language == 'javascript' | |
| working-directory: ./web | |
| run: | | |
| npm ci --prefer-offline --no-audit | |
| npm run build | |
| - name: π Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@v3 | |
| # ============================================================================ | |
| # Quality Summary | |
| # ============================================================================ | |
| quality-summary: | |
| name: π Quality Summary | |
| runs-on: ubuntu-latest | |
| needs: [frontend-quality, backend-quality, codeql] | |
| if: always() | |
| steps: | |
| - name: π Generate Summary | |
| run: | | |
| echo "## π Code Quality Analysis Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Check job results | |
| frontend_result="${{ needs.frontend-quality.result }}" | |
| backend_result="${{ needs.backend-quality.result }}" | |
| codeql_result="${{ needs.codeql.result }}" | |
| echo "| Component | Status | Details |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-----------|--------|---------|" >> $GITHUB_STEP_SUMMARY | |
| if [ "$frontend_result" == "success" ]; then | |
| echo "| π¨ Frontend Quality | β Passed | Linting, type checking, and tests completed |" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "| π¨ Frontend Quality | β Failed | Issues found in frontend analysis |" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| if [ "$backend_result" == "success" ]; then | |
| echo "| π§ Backend Quality | β Passed | Build, tests, and security scan completed |" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "| π§ Backend Quality | β Failed | Issues found in backend analysis |" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| if [ "$codeql_result" == "success" ]; then | |
| echo "| π CodeQL Security | β Passed | No security vulnerabilities detected |" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "| π CodeQL Security | β Failed | Security issues detected |" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### π Recommendations" >> $GITHUB_STEP_SUMMARY | |
| echo "- Review any failed checks above" >> $GITHUB_STEP_SUMMARY | |
| echo "- Check coverage reports for areas needing more tests" >> $GITHUB_STEP_SUMMARY | |
| echo "- Address any security vulnerabilities found" >> $GITHUB_STEP_SUMMARY | |
| echo "- Consider refactoring code with high complexity" >> $GITHUB_STEP_SUMMARY |