name: App Expo Quality on: pull_request: paths: - "app-expo/**" - ".github/workflows/app-expo-quality.yml" push: branches: - main - master - develop paths: - "app-expo/**" - ".github/workflows/app-expo-quality.yml" workflow_dispatch: concurrency: group: app-expo-quality-${{ github.ref }} cancel-in-progress: true jobs: verify: name: Verify app-expo runs-on: ubuntu-latest permissions: contents: read issues: write defaults: run: working-directory: app-expo steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: npm cache-dependency-path: app-expo/package-lock.json - name: Install dependencies run: npm ci - name: Check formatting run: npm run format:check - name: Run linter run: npm run lint - name: Run Jest in CI mode run: npm run test:ci - name: Build coverage summary if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository id: coverage_summary run: | node <<'EOF' const fs = require('fs'); const summaryPath = 'coverage/jest/coverage-summary.json'; const summary = JSON.parse(fs.readFileSync(summaryPath, 'utf8')).total; const metrics = [ ['Lines', summary.lines], ['Statements', summary.statements], ['Functions', summary.functions], ['Branches', summary.branches], ]; const body = [ '## app-expo Jest Coverage', '', '| Metric | Percent | Covered / Total |', '| --- | ---: | ---: |', ...metrics.map( ([name, metric]) => `| ${name} | ${metric.pct}% | ${metric.covered}/${metric.total} |` ), '', '_Generated by App Expo Quality._', ].join('\n'); fs.appendFileSync(process.env.GITHUB_OUTPUT, `body< comment.user?.login === 'github-actions[bot]' && comment.body?.includes(marker) ); if (existing) { await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body, }); } else { await github.rest.issues.createComment({ owner, repo, issue_number, body, }); } - name: Upload Jest coverage if: always() uses: actions/upload-artifact@v4 with: name: app-expo-jest-coverage path: app-expo/coverage/jest retention-days: 14