diff options
| -rw-r--r-- | .github/actions/post-coverage-comment/action.yml | 102 | ||||
| -rw-r--r-- | .github/workflows/ci.yml | 39 | ||||
| -rw-r--r-- | package.json | 2 | ||||
| -rw-r--r-- | packages/cli/package.json | 3 | ||||
| -rw-r--r-- | packages/cli/vitest.config.ts | 18 | ||||
| -rw-r--r-- | packages/server/package.json | 3 | ||||
| -rw-r--r-- | packages/server/vitest.config.ts | 28 |
7 files changed, 184 insertions, 11 deletions
diff --git a/.github/actions/post-coverage-comment/action.yml b/.github/actions/post-coverage-comment/action.yml new file mode 100644 index 00000000..9a78b945 --- /dev/null +++ b/.github/actions/post-coverage-comment/action.yml @@ -0,0 +1,102 @@ +name: 'Post Coverage Comment Action' +description: 'Prepares and posts a code coverage comment to a PR.' + +inputs: + cli_json_file: + description: 'Path to CLI coverage-summary.json' + required: true + server_json_file: + description: 'Path to Server coverage-summary.json' + required: true + cli_full_text_summary_file: + description: 'Path to CLI full-text-summary.txt' + required: true + server_full_text_summary_file: + description: 'Path to Server full-text-summary.txt' + required: true + node_version: + description: 'Node.js version for context in messages' + required: true + github_token: + description: 'GitHub token for posting comments' + required: true + +runs: + using: 'composite' + steps: + - name: Prepare Coverage Comment + id: prep_coverage_comment + shell: bash + run: | + cli_json_file="${{ inputs.cli_json_file }}" + server_json_file="${{ inputs.server_json_file }}" + cli_full_text_summary_file="${{ inputs.cli_full_text_summary_file }}" + server_full_text_summary_file="${{ inputs.server_full_text_summary_file }}" + comment_file="coverage-comment.md" + + # Extract percentages using jq for the main table + if [ -f "$cli_json_file" ]; then + cli_lines_pct=$(jq -r '.total.lines.pct' "$cli_json_file") + cli_statements_pct=$(jq -r '.total.statements.pct' "$cli_json_file") + cli_functions_pct=$(jq -r '.total.functions.pct' "$cli_json_file") + cli_branches_pct=$(jq -r '.total.branches.pct' "$cli_json_file") + else + cli_lines_pct="N/A"; cli_statements_pct="N/A"; cli_functions_pct="N/A"; cli_branches_pct="N/A" + echo "CLI coverage-summary.json not found at: $cli_json_file" >&2 # Error to stderr + fi + + if [ -f "$server_json_file" ]; then + server_lines_pct=$(jq -r '.total.lines.pct' "$server_json_file") + server_statements_pct=$(jq -r '.total.statements.pct' "$server_json_file") + server_functions_pct=$(jq -r '.total.functions.pct' "$server_json_file") + server_branches_pct=$(jq -r '.total.branches.pct' "$server_json_file") + else + server_lines_pct="N/A"; server_statements_pct="N/A"; server_functions_pct="N/A"; server_branches_pct="N/A" + echo "Server coverage-summary.json not found at: $server_json_file" >&2 # Error to stderr + fi + + echo "## Code Coverage Summary" > "$comment_file" + echo "" >> "$comment_file" + echo "| Package | Lines | Statements | Functions | Branches |" >> "$comment_file" + echo "|---|---|---|---|---|" >> "$comment_file" + echo "| CLI | ${cli_lines_pct}% | ${cli_statements_pct}% | ${cli_functions_pct}% | ${cli_branches_pct}% |" >> "$comment_file" + echo "| Server | ${server_lines_pct}% | ${server_statements_pct}% | ${server_functions_pct}% | ${server_branches_pct}% |" >> "$comment_file" + echo "" >> "$comment_file" + + # CLI Package - Collapsible Section (with full text summary from file) + echo "<details>" >> "$comment_file" + echo "<summary>CLI Package - Full Text Report</summary>" >> "$comment_file" + echo "" >> "$comment_file" + echo '```text' >> "$comment_file" + if [ -f "$cli_full_text_summary_file" ]; then + cat "$cli_full_text_summary_file" >> "$comment_file" + else + echo "CLI full-text-summary.txt not found at: $cli_full_text_summary_file" >> "$comment_file" + fi + echo '```' >> "$comment_file" + echo "</details>" >> "$comment_file" + echo "" >> "$comment_file" + + # Server Package - Collapsible Section (with full text summary from file) + echo "<details>" >> "$comment_file" + echo "<summary>Server Package - Full Text Report</summary>" >> "$comment_file" + echo "" >> "$comment_file" + echo '```text' >> "$comment_file" + if [ -f "$server_full_text_summary_file" ]; then + cat "$server_full_text_summary_file" >> "$comment_file" + else + echo "Server full-text-summary.txt not found at: $server_full_text_summary_file" >> "$comment_file" + fi + echo '```' >> "$comment_file" + echo "</details>" >> "$comment_file" + echo "" >> "$comment_file" + + echo "_For detailed HTML reports, please see the 'coverage-reports-${{ inputs.node_version }}' artifact from the main CI run._" >> "$comment_file" + + - name: Post Coverage Comment + uses: thollander/actions-comment-pull-request@v3 + if: always() + with: + file-path: coverage-comment.md # Use the generated file directly + comment-tag: code-coverage-summary + github-token: ${{ inputs.github_token }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e2f63ab..09ee5078 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -87,11 +87,8 @@ jobs: - name: Install dependencies for testing run: npm ci # Install fresh dependencies using the downloaded package-lock.json - - name: Run tests (generate JUnit XML) - run: npm run test:ci --workspaces --if-present - - - name: Collect coverage - run: npm run coverage # This will run tests again, but also generate coverage + - name: Run tests and generate reports + run: NO_COLOR=true npm run test:ci - name: Publish Test Report uses: dorny/test-reporter@v1 @@ -108,3 +105,35 @@ jobs: with: name: coverage-reports-${{ matrix.node-version }} path: packages/*/coverage + + post_coverage_comment: + name: Post Coverage Comment + runs-on: ubuntu-latest + needs: test + if: always() + continue-on-error: true + permissions: + contents: read # For checkout + pull-requests: write # For commenting + strategy: + matrix: + node-version: [20.x] # Should match the test job's matrix + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download coverage reports artifact + uses: actions/download-artifact@v4 + with: + name: coverage-reports-${{ matrix.node-version }} + path: coverage_artifact # Download to a specific directory + + - name: Post Coverage Comment using Composite Action + uses: ./.github/actions/post-coverage-comment # Path to the composite action directory + with: + cli_json_file: coverage_artifact/cli/coverage/coverage-summary.json + server_json_file: coverage_artifact/server/coverage/coverage-summary.json + cli_full_text_summary_file: coverage_artifact/cli/coverage/full-text-summary.txt + server_full_text_summary_file: coverage_artifact/server/coverage/full-text-summary.txt + node_version: ${{ matrix.node-version }} + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index 82d18391..46ec34be 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "clean": "scripts/clean.sh", "prepare": "npm run bundle", "test": "npm run test --workspaces", - "coverage": "npm run coverage --workspaces --if-present", + "test:ci": "npm run test:ci --workspaces --if-present", "start": "NODE_ENV=development scripts/start.sh", "debug": "NODE_ENV=development DEBUG=1 scripts/start.sh", "lint:fix": "eslint . --fix", diff --git a/packages/cli/package.json b/packages/cli/package.json index d038c195..6ae1bd40 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -18,8 +18,7 @@ "lint": "eslint . --ext .ts,.tsx", "format": "prettier --write .", "test": "vitest run", - "test:ci": "vitest run --reporter=junit --outputFile=junit.xml", - "coverage": "vitest run --coverage", + "test:ci": "vitest run --coverage", "typecheck": "tsc --noEmit", "prerelease:version": "node ../../scripts/bind_package_version.js", "prerelease:deps": "node ../../scripts/bind_package_dependencies.js", diff --git a/packages/cli/vitest.config.ts b/packages/cli/vitest.config.ts index aac3ddb3..a7548310 100644 --- a/packages/cli/vitest.config.ts +++ b/packages/cli/vitest.config.ts @@ -10,6 +10,22 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { environment: 'jsdom', - globals: true, // Optional: enables global APIs like describe, it, expect + globals: true, + reporters: ['default', 'junit'], + outputFile: { + junit: 'junit.xml', + }, + coverage: { + provider: 'v8', + reportsDirectory: './coverage', + reporter: [ + ['text', { file: 'full-text-summary.txt' }], + 'html', + 'json', + 'lcov', + 'cobertura', + ['json-summary', { outputFile: 'coverage-summary.json' }], + ], + }, }, }); diff --git a/packages/server/package.json b/packages/server/package.json index 8e654c88..abb679cc 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -11,8 +11,7 @@ "lint": "eslint . --ext .ts,.tsx", "format": "prettier --write .", "test": "vitest run", - "test:ci": "vitest run --reporter=junit --outputFile=junit.xml", - "coverage": "vitest run --coverage", + "test:ci": "vitest run --coverage", "typecheck": "tsc --noEmit", "prerelease:version": "node ../../scripts/bind_package_version.js", "prerelease:deps": "node ../../scripts/bind_package_dependencies.js", diff --git a/packages/server/vitest.config.ts b/packages/server/vitest.config.ts new file mode 100644 index 00000000..17defb41 --- /dev/null +++ b/packages/server/vitest.config.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + reporters: ['default', 'junit'], + outputFile: { + junit: 'junit.xml', + }, + coverage: { + provider: 'v8', + reportsDirectory: './coverage', + reporter: [ + ['text', { file: 'full-text-summary.txt' }], + 'html', + 'json', + 'lcov', + 'cobertura', + ['json-summary', { outputFile: 'coverage-summary.json' }], + ], + }, + }, +}); |
