diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 51f072e2..e8288ddb 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -47,15 +47,94 @@ jobs: coverage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v3 with: node-version: 24 - registry-url: 'https://registry.npmjs.org' - cache: 'npm' - - run: npm ci - - run: npm run coverage - - uses: actions/upload-artifact@v4 + + - name: Checkout Main + uses: actions/checkout@v4 with: - name: coverage-report - path: coverage + ref: main + + - name: Install & Test (Main) + run: | + npm ci + npm run coverage + mv coverage/coverage-summary.json ${{ runner.temp }}/coverage-main-summary.json + + - name: Checkout PR Branch + uses: actions/checkout@v4 + with: + clean: true + + - name: Install & Test (PR) + run: | + npm ci + npm run coverage + + - name: Report Coverage Delta + uses: actions/github-script@v6 + with: + script: | + const fs = require('fs'); + + const loadSummary = (path) => { + return JSON.parse(fs.readFileSync(path, 'utf8')); + }; + + let markdown = `### 🧪 Code Coverage Delta\n\n`; + markdown += `| Metric | Main | PR | Delta |\n`; + markdown += `| :--- | :---: | :---: | :---: |\n`; + + const metrics = ['lines', 'statements', 'functions', 'branches']; + const getPct = (summary, metric) => summary.total[metric].pct; + + const mainSummary = loadSummary('${{ runner.temp }}/coverage-main-summary.json'); + const prSummary = loadSummary('./coverage/coverage-summary.json'); + + metrics.forEach(metric => { + const oldPct = getPct(mainSummary, metric); + const newPct = getPct(prSummary, metric); + const diff = (newPct - oldPct).toFixed(2); + + let icon = ''; + if (diff > 0) icon = '🟢'; + else if (diff < 0) icon = '🔴'; + else icon = '⚪️'; + + const diffStr = diff > 0 ? `+${diff}%` : `${diff}%`; + + markdown += `| **${metric}** | ${oldPct}% | ${newPct}% | ${icon} ${diffStr} |\n`; + }); + + markdown += `\n_Generated by [unit-tests.yml](https://github.com/a2aproject/a2a-js/actions/workflows/unit-tests.yml)_`; + + const { owner, repo } = context.repo; + const issue_number = context.issue.number; + + const comments = await github.rest.issues.listComments({ + owner, + repo, + issue_number, + }); + + const existingComment = comments.data.find(c => + c.body.includes('Generated by [unit-tests.yml]') && + c.user.type === 'Bot' + ); + + if (existingComment) { + await github.rest.issues.updateComment({ + owner, + repo, + comment_id: existingComment.id, + body: markdown + }); + } else { + await github.rest.issues.createComment({ + owner, + repo, + issue_number, + body: markdown + }); + }