Fix quality check workflow to not fail on outdated dependencies (#24) #41
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: CI | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| - dev | |
| push: | |
| branches: | |
| - main | |
| - dev | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| jobs: | |
| analyze: | |
| name: Analyze & Format Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.head_ref }} | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.27.0' | |
| channel: 'stable' | |
| cache: true | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Format code | |
| run: dart format . | |
| - name: Check for formatting changes | |
| id: verify_diff | |
| run: | | |
| if ! git diff --quiet --exit-code; then | |
| echo "formatted=true" >> $GITHUB_OUTPUT | |
| echo "✨ Code was auto-formatted" | |
| else | |
| echo "formatted=false" >> $GITHUB_OUTPUT | |
| echo "✅ Code is already properly formatted" | |
| fi | |
| - name: Commit formatted code | |
| if: steps.verify_diff.outputs.formatted == 'true' && github.event_name == 'pull_request' | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add -A | |
| git commit -m "style: auto-format code with dart format [skip ci]" | |
| git push | |
| - name: Analyze project source | |
| run: flutter analyze --no-fatal-infos | |
| - name: Check for outdated dependencies | |
| run: flutter pub outdated | |
| test: | |
| name: Run Tests | |
| runs-on: ubuntu-latest | |
| needs: analyze | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.27.0' | |
| channel: 'stable' | |
| cache: true | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Run tests | |
| run: flutter test --coverage | |
| - name: Generate coverage report | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| dart pub global activate coverage | |
| dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --report-on=lib | |
| - name: Generate coverage summary | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| # Install lcov if not available | |
| sudo apt-get update | |
| sudo apt-get install -y lcov | |
| # Generate summary | |
| lcov --summary coverage/lcov.info > coverage_summary.txt 2>&1 || true | |
| # Parse coverage percentage | |
| COVERAGE=$(grep -oP 'lines......: \K[0-9.]+' coverage_summary.txt || echo "0") | |
| # Create a detailed report | |
| echo "## 📊 Test Coverage Report" > coverage_report.md | |
| echo "" >> coverage_report.md | |
| echo "### Overall Coverage: **${COVERAGE}%**" >> coverage_report.md | |
| echo "" >> coverage_report.md | |
| # Add coverage badge | |
| if (( $(echo "$COVERAGE >= 80" | bc -l) )); then | |
| echo "" >> coverage_report.md | |
| elif (( $(echo "$COVERAGE >= 60" | bc -l) )); then | |
| echo "" >> coverage_report.md | |
| else | |
| echo "" >> coverage_report.md | |
| fi | |
| echo "" >> coverage_report.md | |
| echo "### Details" >> coverage_report.md | |
| echo "\`\`\`" >> coverage_report.md | |
| cat coverage_summary.txt >> coverage_report.md | |
| echo "\`\`\`" >> coverage_report.md | |
| # Generate per-file coverage if available | |
| echo "" >> coverage_report.md | |
| echo "### File Coverage" >> coverage_report.md | |
| echo "\`\`\`" >> coverage_report.md | |
| lcov --list coverage/lcov.info >> coverage_report.md 2>&1 || echo "Detailed file coverage not available" >> coverage_report.md | |
| echo "\`\`\`" >> coverage_report.md | |
| - name: Comment PR with coverage | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const report = fs.readFileSync('coverage_report.md', 'utf8'); | |
| // Find existing coverage comment | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| }); | |
| const botComment = comments.find(comment => | |
| comment.user.type === 'Bot' && | |
| comment.body.includes('📊 Test Coverage Report') | |
| ); | |
| const commentBody = `${report}\n\n---\n*Updated: ${new Date().toUTCString()}*`; | |
| if (botComment) { | |
| // Update existing comment | |
| await github.rest.issues.updateComment({ | |
| comment_id: botComment.id, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: commentBody | |
| }); | |
| } else { | |
| // Create new comment | |
| await github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: commentBody | |
| }); | |
| } | |
| - name: Upload coverage artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report | |
| path: | | |
| coverage/ | |
| coverage_report.md | |
| retention-days: 30 | |
| package-analysis: | |
| name: Package Analysis | |
| runs-on: ubuntu-latest | |
| needs: analyze | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.27.0' | |
| channel: 'stable' | |
| cache: true | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Run package analysis | |
| run: | | |
| dart pub global activate pana | |
| pana --no-warning --exit-code-threshold 0 | |
| - name: Dry run pub publish | |
| run: flutter pub publish --dry-run | |
| build-example: | |
| name: Build Example App | |
| runs-on: ${{ matrix.os }} | |
| needs: test | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| include: | |
| - os: ubuntu-latest | |
| build-command: flutter build web | |
| platform: web | |
| - os: macos-latest | |
| build-command: flutter build ios --no-codesign | |
| platform: ios | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.27.0' | |
| channel: 'stable' | |
| cache: true | |
| - name: Get dependencies (example) | |
| working-directory: ./example | |
| run: flutter pub get | |
| - name: Build ${{ matrix.platform }} | |
| working-directory: ./example | |
| run: ${{ matrix.build-command }} | |
| security-scan: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.27.0' | |
| channel: 'stable' | |
| cache: true | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Check for known security issues | |
| run: | | |
| dart pub global activate dependency_validator | |
| # Ignore references in documentation (README, example mentions) | |
| dependency_validator --ignore=example,file_picker || true | |
| # Check for actual security vulnerabilities | |
| flutter pub outdated --show-all 2>&1 | grep -i "security\|vulnerability" || echo "No known security issues found" | |
| lint-report: | |
| name: Generate Lint Report | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.27.0' | |
| channel: 'stable' | |
| cache: true | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Run analyzer and save output | |
| run: | | |
| flutter analyze > analyze_report.txt 2>&1 || true | |
| # Create formatted report | |
| echo "## 🔍 Static Analysis Report" > lint_report.md | |
| echo "" >> lint_report.md | |
| echo "\`\`\`" >> lint_report.md | |
| cat analyze_report.txt >> lint_report.md | |
| echo "\`\`\`" >> lint_report.md | |
| - name: Comment PR with analysis results | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const report = fs.readFileSync('lint_report.md', 'utf8'); | |
| // Find existing lint comment | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| }); | |
| const botComment = comments.find(comment => | |
| comment.user.type === 'Bot' && | |
| comment.body.includes('🔍 Static Analysis Report') | |
| ); | |
| const commentBody = `${report}\n\n---\n*Updated: ${new Date().toUTCString()}*`; | |
| if (botComment) { | |
| // Update existing comment | |
| await github.rest.issues.updateComment({ | |
| comment_id: botComment.id, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: commentBody | |
| }); | |
| } else { | |
| // Create new comment | |
| await github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: commentBody | |
| }); | |
| } |