deps(deps-dev): bump jest and @types/jest #733
Workflow file for this run
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: Coverage | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| jobs: | |
| coverage: | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_USER: test_user | |
| POSTGRES_PASSWORD: test_password | |
| POSTGRES_DB: test_db | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| redis: | |
| image: redis:7-alpine | |
| ports: | |
| - 6379:6379 | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| - name: Verify package-lock.json exists | |
| run: | | |
| if [ ! -f package-lock.json ]; then | |
| npm install --package-lock-only | |
| fi | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run database migrations | |
| run: npm run migrate:up | |
| continue-on-error: true | |
| env: | |
| DATABASE_URL: postgresql://test_user:test_password@localhost:5432/test_db | |
| - name: Run tests with coverage | |
| id: coverage | |
| run: | | |
| npm run test:coverage -- --coverageReporters=json-summary --coverageReporters=text --coverageReporters=lcov 2>&1 | tee coverage-output.txt | |
| EXIT_CODE=${PIPESTATUS[0]} | |
| echo "exit_code=$EXIT_CODE" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| env: | |
| DATABASE_URL: postgresql://test_user:test_password@localhost:5432/test_db | |
| REDIS_URL: redis://localhost:6379 | |
| NODE_ENV: test | |
| - name: Extract coverage metrics | |
| id: metrics | |
| run: | | |
| if [ -f coverage/coverage-summary.json ]; then | |
| STMTS=$(node -e "const c=require('./coverage/coverage-summary.json');console.log(c.total.statements.pct)") | |
| BRANCHES=$(node -e "const c=require('./coverage/coverage-summary.json');console.log(c.total.branches.pct)") | |
| FUNCS=$(node -e "const c=require('./coverage/coverage-summary.json');console.log(c.total.functions.pct)") | |
| LINES=$(node -e "const c=require('./coverage/coverage-summary.json');console.log(c.total.lines.pct)") | |
| else | |
| STMTS="N/A" | |
| BRANCHES="N/A" | |
| FUNCS="N/A" | |
| LINES="N/A" | |
| fi | |
| echo "statements=$STMTS" >> "$GITHUB_OUTPUT" | |
| echo "branches=$BRANCHES" >> "$GITHUB_OUTPUT" | |
| echo "functions=$FUNCS" >> "$GITHUB_OUTPUT" | |
| echo "lines=$LINES" >> "$GITHUB_OUTPUT" | |
| # Thresholds — keep in sync with jest.config.js | |
| THRESHOLD_STMTS=20 | |
| THRESHOLD_BRANCHES=15 | |
| THRESHOLD_FUNCS=25 | |
| THRESHOLD_LINES=20 | |
| PASSED=true | |
| if [ "$STMTS" != "N/A" ]; then | |
| node -e "process.exit(($STMTS < $THRESHOLD_STMTS) ? 1 : 0)" || PASSED=false | |
| node -e "process.exit(($BRANCHES < $THRESHOLD_BRANCHES) ? 1 : 0)" || PASSED=false | |
| node -e "process.exit(($FUNCS < $THRESHOLD_FUNCS) ? 1 : 0)" || PASSED=false | |
| node -e "process.exit(($LINES < $THRESHOLD_LINES) ? 1 : 0)" || PASSED=false | |
| fi | |
| echo "passed=$PASSED" >> "$GITHUB_OUTPUT" | |
| echo "threshold_stmts=$THRESHOLD_STMTS" >> "$GITHUB_OUTPUT" | |
| echo "threshold_branches=$THRESHOLD_BRANCHES" >> "$GITHUB_OUTPUT" | |
| echo "threshold_funcs=$THRESHOLD_FUNCS" >> "$GITHUB_OUTPUT" | |
| echo "threshold_lines=$THRESHOLD_LINES" >> "$GITHUB_OUTPUT" | |
| - name: Comment coverage on PR | |
| if: github.event_name == 'pull_request' | |
| continue-on-error: true | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const stmts = '${{ steps.metrics.outputs.statements }}'; | |
| const branches = '${{ steps.metrics.outputs.branches }}'; | |
| const funcs = '${{ steps.metrics.outputs.functions }}'; | |
| const lines = '${{ steps.metrics.outputs.lines }}'; | |
| const passed = '${{ steps.metrics.outputs.passed }}' === 'true'; | |
| const thStmts = '${{ steps.metrics.outputs.threshold_stmts }}'; | |
| const thBranches = '${{ steps.metrics.outputs.threshold_branches }}'; | |
| const thFuncs = '${{ steps.metrics.outputs.threshold_funcs }}'; | |
| const thLines = '${{ steps.metrics.outputs.threshold_lines }}'; | |
| const icon = (val, threshold) => parseFloat(val) >= parseFloat(threshold) ? '✅' : '❌'; | |
| const status = passed ? '✅ Coverage thresholds met' : '❌ Coverage below thresholds'; | |
| const body = `## 📊 Coverage Report | |
| ${status} | |
| | Metric | Current | Threshold | Status | | |
| |--------|---------|-----------|--------| | |
| | Statements | ${stmts}% | ${thStmts}% | ${icon(stmts, thStmts)} | | |
| | Branches | ${branches}% | ${thBranches}% | ${icon(branches, thBranches)} | | |
| | Functions | ${funcs}% | ${thFuncs}% | ${icon(funcs, thFuncs)} | | |
| | Lines | ${lines}% | ${thLines}% | ${icon(lines, thLines)} | | |
| > Coverage enforcement is configured in \`jest.config.js\`. Thresholds only go up — never down. | |
| `.replace(/^ +/gm, ''); | |
| // Find and update existing comment or create new | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| }); | |
| const existing = comments.find(c => c.body.includes('📊 Coverage Report')); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body, | |
| }); | |
| } | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v6 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./coverage/lcov.info | |
| flags: unittests | |
| name: codecov-umbrella | |
| fail_ci_if_error: false | |
| verbose: true | |
| - name: Enforce coverage thresholds | |
| if: steps.metrics.outputs.passed == 'false' | |
| run: | | |
| echo "❌ Coverage is below the required thresholds." | |
| echo "" | |
| echo " Statements: ${{ steps.metrics.outputs.statements }}% (need ${{ steps.metrics.outputs.threshold_stmts }}%)" | |
| echo " Branches: ${{ steps.metrics.outputs.branches }}% (need ${{ steps.metrics.outputs.threshold_branches }}%)" | |
| echo " Functions: ${{ steps.metrics.outputs.functions }}% (need ${{ steps.metrics.outputs.threshold_funcs }}%)" | |
| echo " Lines: ${{ steps.metrics.outputs.lines }}% (need ${{ steps.metrics.outputs.threshold_lines }}%)" | |
| echo "" | |
| echo "Please add tests to cover the untested code." | |
| exit 1 |