name: Code Quality on: push: branches: [ main, master ] pull_request: branches: [ main, master ] jobs: quality-gate: runs-on: ubuntu-latest container: dart:stable steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Flutter uses: subosito/flutter-action@v2 with: flutter-version: '3.19.0' channel: 'stable' - name: Cache dependencies uses: actions/cache@v4 with: path: | ~/.pub-cache **/.dart_tool key: ${{ runner.os }}-deps-${{ hashFiles('**/pubspec.lock') }} - name: Install all dependencies run: | find . -name "pubspec.yaml" -exec dirname {} \; | xargs -I {} sh -c 'cd {} && flutter pub get || dart pub get' - name: Run code generation run: | projects=("mnemo_cards_backend" "mnemo_cards_web_v2" "mnemo_cards") for project in "${projects[@]}"; do if [ -d "$project" ]; then cd $project flutter pub run build_runner build --delete-conflicting-outputs || true cd .. fi done - name: Lint all projects run: | projects=("mnemo_cards_backend" "mnemo_cards_web_v2" "mnemo_cards" "mnemo_cards_common" "mnemo_cards_common_backend" "mnemo_cards_frontend_common") for project in "${projects[@]}"; do if [ -d "$project" ]; then echo "Linting $project..." cd $project flutter analyze lib/ || dart analyze lib/ || echo "Analysis failed for $project" flutter format --set-exit-if-changed lib/ || echo "Format check failed for $project" cd .. fi done - name: Run tests with coverage run: | projects=("mnemo_cards_backend" "mnemo_cards_web_v2" "mnemo_cards") for project in "${projects[@]}"; do if [ -d "$project" ]; then echo "Testing $project..." cd $project flutter test --coverage || dart test --coverage || echo "Tests failed for $project" cd .. fi done - name: Upload coverage reports uses: codecov/codecov-action@v4 with: files: ./mnemo_cards_backend/coverage/lcov.info,./mnemo_cards_web_v2/coverage/lcov.info,./mnemo_cards/coverage/lcov.info flags: unittests name: codecov-umbrella - name: Quality gate check run: | # Check if coverage is above threshold if [ -f "coverage/coverage.json" ]; then COVERAGE=$(jq '.coverage' coverage/coverage.json 2>/dev/null || echo "0") if (( $(echo "$COVERAGE < 80" | bc -l) )); then echo "Coverage is below 80%: $COVERAGE%" exit 1 fi fi # Check for critical linting issues if grep -r "error:" .github/workflows/code-quality.log 2>/dev/null; then echo "Found critical linting errors" exit 1 fi echo "✅ Quality gate passed" security-scan: runs-on: ubuntu-latest container: dart:stable steps: - name: Checkout code uses: actions/checkout@v4 - name: Run security audit run: | # Check for known vulnerabilities in dependencies projects=("mnemo_cards_backend" "mnemo_cards_web_v2" "mnemo_cards" "mnemo_cards_common" "mnemo_cards_common_backend" "mnemo_cards_frontend_common") for project in "${projects[@]}"; do if [ -d "$project" ]; then cd $project echo "Auditing $project..." flutter pub audit || dart pub audit || echo "Audit failed for $project" cd .. fi done - name: Check for secrets run: | # Simple check for potential secrets if grep -r -i "password\|secret\|key\|token" --include="*.dart" --include="*.yaml" --include="*.json" . | grep -v "example\|test\|mock\|fake" | grep -v "pubspec"; then echo "⚠️ Potential secrets found in code" echo "Please review and ensure no real secrets are committed" else echo "✅ No obvious secrets found" fi