diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index cfe7865aa..b7ce9609a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -132,52 +132,35 @@ jobs: env: GH_TOKEN: ${{ github.token }} run: | - ls -lsha obj_coverage - # Combine reports from test jobs - nodist/fastcov.py -C obj_coverage/verilator-*.info --lcov -o obj_coverage/verilator.info - # For a PR, report patch coverage against the merge-base between the head of the PR and the target branch + ci/ci-coverage-report.bash \ + ${{ github.run_id }} \ + "${{ github.event_name == 'pull_request' && github.event.number || '' }}" \ + "${{ github.event.pull_request.base.sha }}" \ + "${{ github.event.pull_request.head.sha }}" + # Create the report artifact. Note there is no report if the patch is empty. + mkdir ../report-artifact + [ ! -d obj_coverage/report ] || mv obj_coverage/report ../report-artifact/ if [[ "${{ github.event_name }}" == "pull_request" ]]; then - COVERAGE_BASE=$(git rev-parse --short $(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }})) - make coverage-report COVERAGE_BASE=${COVERAGE_BASE} |& tee ${{ github.workspace }}/make-coverage-report.log - else - make coverage-report + echo ${{ github.event.number }} > ../report-artifact/pr-number.txt fi - # Remove data files - rm -f obj_coverage/verilator*.info - # Some extra work for PRs only + # Create the notification artifact, for pull requests only if [[ "${{ github.event_name }}" == "pull_request" ]]; then - # Save PR number in report - echo ${{ github.event.number }} > obj_coverage/pr-number.txt - # Generate notification comment content - mkdir -p notification - echo ${{ github.event.number }} > notification/pr-number.txt - NUM=$(gh run view ${{ github.run_id }} --json number --jq ".number") - URL=$(gh run view ${{ github.run_id }} --json url --jq ".url") - echo "Patch coverage from PR workflow [#$NUM]($URL) (code coverage of lines changed relative to ${COVERAGE_BASE}):" > notification/body.txt - if [[ ! -f obj_coverage/empty-patch ]]; then - echo "
" >> notification/body.txt
- grep -E "(lines|branches)\.*:" ${{ github.workspace }}/make-coverage-report.log | sed "s/\.*:/:/" >> notification/body.txt || true
- echo "" >> notification/body.txt
- echo "Report: [${{ github.run_id }}](https://${{ github.repository_owner }}.github.io/verilator/coverage-reports/${{ github.run_id }}/index.html)" >> notification/body.txt
- echo "" >> notification/body.txt
- echo "Please get to 100% line coverage, and understand all branches; see https://github.com/verilator/verilator/blob/master/docs/internals.rst#code-coverage-results" >> notification/body.txt
- else
- echo "Patch contains no code changes" >> notification/body.txt
- fi
- cat notification/body.txt
+ mkdir ../notification-artifact
+ mv obj_coverage/notification.txt ../notification-artifact/body.txt
+ echo ${{ github.event.number }} > ../notification-artifact/pr-number.txt
fi
- name: Upload report
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
- path: repo/obj_coverage
+ path: report-artifact
name: coverage-report
- name: Upload notification
if: ${{ github.event_name == 'pull_request' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
- path: repo/notification
+ path: notification-artifact
name: pr-notification
# Create GitHub issue for failed scheduled jobs
diff --git a/Makefile.in b/Makefile.in
index 60cb2c2f6..8ec594833 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -467,9 +467,11 @@ analyzer-include:
# Bash/sh files
BASH_FILES = \
+ ci/ci-coverage-report.bash \
ci/ci-install.bash \
ci/ci-pages-notify.bash \
ci/ci-pages.bash \
+ ci/ci-rtlmeter-report.bash \
ci/ci-script.bash \
ci/docker/run/hooks/post_push \
ci/docker/run/verilator-docker \
diff --git a/ci/ci-coverage-report.bash b/ci/ci-coverage-report.bash
new file mode 100755
index 000000000..60a9e67e0
--- /dev/null
+++ b/ci/ci-coverage-report.bash
@@ -0,0 +1,86 @@
+#!/usr/bin/env bash
+# DESCRIPTION: Verilator: CI script for 'coverage.yml' results
+#
+# SPDX-FileCopyrightText: 2026 Wilson Snyder
+# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
+
+# This script combines the code coverage data gathered by the test jobs into
+# the HTML report published on GitHub Pages, and for a pull request, builds the
+# content of the response comment posted on it.
+
+# Developer note: You should be able to run this script in your local checkout
+# if you have GitHub CLI (command 'gh') setup, authenticated ('gh auth login'),
+# and have set a default repository ('gh repo set-default').
+
+set -eo pipefail
+
+# Trace when running in the CI
+[ "$GITHUB_ACTIONS" != "true" ] || set -x
+
+# Arguments:
+# 1. run ID
+# 2. number of the pull request, or empty for a non-pull-request run
+# 3. base SHA of the pull request (pull requests only)
+# 4. head SHA of the pull request (pull requests only)
+RUN_ID=$1
+PR_NUMBER=$2
+PR_BASE_SHA=$3
+PR_HEAD_SHA=$4
+
+# Coverage data and report directory, uploaded as the 'coverage-report' artifact
+COVERAGE_DIR=obj_coverage
+ls -lsha ${COVERAGE_DIR}
+
+# Combine the reports from the test jobs
+nodist/fastcov.py -C ${COVERAGE_DIR}/verilator-*.info --lcov -o ${COVERAGE_DIR}/verilator.info
+
+# Create the report. For a pull request, report patch coverage against the
+# merge-base between the head of the pull request and the target branch. The
+# summary quoted in the notification below is only in the log of 'make'.
+MAKE_LOG=make-coverage-report.log
+if [ -n "${PR_NUMBER}" ]; then
+ COVERAGE_BASE=$(git rev-parse --short $(git merge-base ${PR_BASE_SHA} ${PR_HEAD_SHA}))
+ make coverage-report COVERAGE_BASE=${COVERAGE_BASE} |& tee ${MAKE_LOG}
+else
+ make coverage-report
+fi
+
+# Remove the data files, only the HTML report is published
+rm -f ${COVERAGE_DIR}/verilator*.info
+
+# The rest is for pull requests only
+if [ -z "${PR_NUMBER}" ]; then
+ exit 0
+fi
+
+# Get some metadata about the run
+RUN_NUM=$(gh run view ${RUN_ID} --json number --jq ".number")
+RUN_URL=$(gh run view ${RUN_ID} --json url --jq ".url")
+
+# Repository owner and name of the default repository, used to build the
+# GitHub Pages URL of the report. The owner is lowercased, as required for the
+# '