Files
ComfyUI_frontend/.github/workflows/ci-tests-e2e-coverage.yaml
ShihChi Huang 64253de713 fix: e2e coverage html report asset failures (#13127)
## Summary

Harden E2E coverage HTML generation against non-renderable LCOV source
entries so public assets and stale sourcemap paths no longer abort the
report.

## Changes

- **What**: Removes `assets/images/*` entries from merged E2E LCOV
before upload/report generation.
- **What**: Lets `genhtml` ignore range warnings and synthesize missing
source files when LCOV references stale paths.
- **Dependencies**: None.

## Review Focus

Root cause: Playwright/Monocart can emit LCOV `SF:` records that
`genhtml` cannot read from the checkout. The failed run stopped first on
public assets like `assets/images/hf-logo.svg`; replaying the same
artifact also exposed stale source paths after those assets were
removed.

The filter is intentionally `assets/images/*`, not `assets/*`, because
real `lcov` matching would also remove legitimate source coverage under
`src/platform/assets/...`.

## Validation

- `yamllint --config-file .yamllint
.github/workflows/ci-tests-e2e-coverage.yaml`
- Replayed failed run `28138018468` merged LCOV:
  - `assets/images/*` strip leaves `0` `SF:assets/...` entries
  - preserves `68` `SF:src/platform/assets/...` entries
- `genhtml` exits `0` with `--ignore-errors source,unmapped,range
--synthesize-missing`
- Commit hook: `oxfmt`, `oxlint`, `eslint`, `pnpm typecheck`
- Push hook: `knip --cache`

## Screenshots (if applicable)

N/A, CI workflow-only.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Changes are limited to the E2E coverage GitHub Actions workflow; no
application runtime or security paths are touched.
> 
> **Overview**
> Fixes E2E coverage HTML generation failing when merged LCOV references
paths **genhtml** cannot read (public static assets and stale sourcemap
paths from Playwright/Monocart).
> 
> The **Strip non-source entries** step now also drops `assets/images/*`
via `lcov --remove`, scoped narrowly so real source under
`src/platform/assets/...` stays in the report. **Generate HTML coverage
report** passes `--ignore-errors source,unmapped,range` and
`--synthesize-missing` so remaining unmapped or missing sources do not
abort the job.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ede5556644. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: huang47 <157390+huang47@users.noreply.github.com>
2026-06-26 23:05:13 +00:00

163 lines
5.8 KiB
YAML

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 repository
uses: actions/checkout@v6
- name: Setup frontend
uses: ./.github/actions/setup-frontend
- 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: 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@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3
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,range \
--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@v7
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