CI: E2E Coverage #64
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: E2E Coverage' | |
| on: | |
| workflow_run: | |
| workflows: ['CI: Tests E2E'] | |
| types: | |
| - completed | |
| concurrency: | |
| group: e2e-coverage-${{ github.event.workflow_run.head_sha }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| merge: | |
| if: > | |
| github.repository == 'Comfy-Org/ComfyUI_frontend' && | |
| github.event.workflow_run.conclusion == 'success' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| outputs: | |
| has-coverage: ${{ steps.coverage-shards.outputs.has-coverage }} | |
| steps: | |
| - name: Checkout sources for genhtml | |
| uses: actions/checkout@v7 | |
| with: | |
| sparse-checkout: | | |
| src | |
| packages | |
| - name: Download all shard coverage data | |
| uses: dawidd6/action-download-artifact@0bd50d53a6d7fb5cb921e607957e9cc12b4ce392 # v12 | |
| with: | |
| run_id: ${{ github.event.workflow_run.id }} | |
| name: e2e-coverage-shard-.* | |
| name_is_regexp: true | |
| path: temp/coverage-shards | |
| if_no_artifact_found: warn | |
| - name: Detect shard coverage data | |
| id: coverage-shards | |
| run: | | |
| if [ -d temp/coverage-shards ] && find temp/coverage-shards -name 'coverage.lcov' -type f | grep -q .; then | |
| echo "has-coverage=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "has-coverage=false" >> "$GITHUB_OUTPUT" | |
| echo "No E2E coverage shard artifacts found; treating this run as skipped." >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| - name: Install lcov | |
| if: steps.coverage-shards.outputs.has-coverage == 'true' | |
| run: sudo apt-get install -y -qq lcov | |
| - name: Merge shard coverage into single LCOV | |
| if: steps.coverage-shards.outputs.has-coverage == 'true' | |
| run: | | |
| mkdir -p coverage/playwright | |
| LCOV_FILES=$(find temp/coverage-shards -name 'coverage.lcov' -type f) | |
| ADD_ARGS="" | |
| for f in $LCOV_FILES; do ADD_ARGS="$ADD_ARGS -a $f"; done | |
| lcov $ADD_ARGS -o coverage/playwright/coverage.lcov | |
| wc -l coverage/playwright/coverage.lcov | |
| - name: Validate merged coverage | |
| if: steps.coverage-shards.outputs.has-coverage == 'true' | |
| run: | | |
| MERGED_SF=$(grep -c '^SF:' coverage/playwright/coverage.lcov || echo 0) | |
| MERGED_LH=$(awk -F: '/^LH:/{s+=$2}END{print s+0}' coverage/playwright/coverage.lcov) | |
| MERGED_LF=$(awk -F: '/^LF:/{s+=$2}END{print s+0}' coverage/playwright/coverage.lcov) | |
| echo "### Merged coverage" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- **$MERGED_SF** source files" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- **$MERGED_LH / $MERGED_LF** lines hit" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo "| Shard | Files | Lines Hit |" >> "$GITHUB_STEP_SUMMARY" | |
| echo "|-------|-------|-----------|" >> "$GITHUB_STEP_SUMMARY" | |
| for f in $(find temp/coverage-shards -name 'coverage.lcov' -type f | sort); do | |
| SHARD=$(basename "$(dirname "$f")") | |
| SHARD_SF=$(grep -c '^SF:' "$f" || echo 0) | |
| SHARD_LH=$(awk -F: '/^LH:/{s+=$2}END{print s+0}' "$f") | |
| echo "| $SHARD | $SHARD_SF | $SHARD_LH |" >> "$GITHUB_STEP_SUMMARY" | |
| if [ "$MERGED_LH" -lt "$SHARD_LH" ]; then | |
| echo "::error::Merged LH ($MERGED_LH) < shard LH ($SHARD_LH) in $SHARD — possible data loss" | |
| fi | |
| done | |
| - name: Assert coverage was mapped back to source | |
| if: steps.coverage-shards.outputs.has-coverage == 'true' | |
| run: | | |
| MAPPED_SF=$(grep -cE '^SF:(src|packages)/' coverage/playwright/coverage.lcov || true) | |
| echo "Source-mapped files: $MAPPED_SF" >> "$GITHUB_STEP_SUMMARY" | |
| if [ "${MAPPED_SF:-0}" -lt 100 ]; then | |
| echo "::error::Only $MAPPED_SF files under src/ or packages/ in the merged tracefile. Observed paths: $(grep -m 5 '^SF:' coverage/playwright/coverage.lcov | tr '\n' ' '). Served bundle paths mean the E2E build dropped its '//# sourceMappingURL=' comment — check it ran with COLLECT_COVERAGE=true (vite.config.mts build.sourcemap)." | |
| exit 1 | |
| fi | |
| - name: Strip non-source entries from coverage | |
| if: steps.coverage-shards.outputs.has-coverage == 'true' | |
| run: | | |
| lcov --remove coverage/playwright/coverage.lcov \ | |
| '*localhost-8188*' \ | |
| 'assets/images/*' \ | |
| -o coverage/playwright/coverage.lcov \ | |
| --ignore-errors unused | |
| wc -l coverage/playwright/coverage.lcov | |
| - name: Upload merged coverage data | |
| if: steps.coverage-shards.outputs.has-coverage == 'true' | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: e2e-coverage | |
| path: coverage/playwright/ | |
| retention-days: 30 | |
| if-no-files-found: warn | |
| - name: Upload E2E coverage to Codecov | |
| if: steps.coverage-shards.outputs.has-coverage == 'true' | |
| uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 | |
| with: | |
| files: coverage/playwright/coverage.lcov | |
| flags: e2e | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| fail_ci_if_error: false | |
| - name: Generate HTML coverage report | |
| if: steps.coverage-shards.outputs.has-coverage == 'true' | |
| run: | | |
| genhtml coverage/playwright/coverage.lcov \ | |
| -o coverage/html \ | |
| --title "ComfyUI E2E Coverage" \ | |
| --no-function-coverage \ | |
| --precision 1 \ | |
| --ignore-errors source,unmapped \ | |
| --synthesize-missing | |
| - name: Upload HTML report artifact | |
| if: steps.coverage-shards.outputs.has-coverage == 'true' | |
| uses: actions/upload-artifact@v6 | |
| with: | |
| name: e2e-coverage-html | |
| path: coverage/html/ | |
| retention-days: 30 | |
| deploy: | |
| needs: merge | |
| if: > | |
| github.event.workflow_run.head_branch == 'main' && | |
| needs.merge.outputs.has-coverage == 'true' && | |
| github.event.workflow_run.event == 'push' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pages: write | |
| id-token: write | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| steps: | |
| - name: Download HTML report | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: e2e-coverage-html | |
| path: coverage/html | |
| - name: Upload to GitHub Pages | |
| uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1 | |
| with: | |
| path: coverage/html | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 |