214 lines
7.8 KiB
YAML
214 lines
7.8 KiB
YAML
---
|
|
# DESCRIPTION: Github actions config
|
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
|
|
|
name: Code coverage
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
schedule:
|
|
- cron: '0 0 * * 0' # weekly
|
|
pull_request:
|
|
types: [opened, synchronize, reopened, labeled, unlabeled]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
concurrency:
|
|
# At most 1 job per branch. Auto cancel all but scheduled jobs
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: ${{ github.event_name != 'schedule' }}
|
|
|
|
jobs:
|
|
|
|
build:
|
|
name: Build
|
|
# Only run scheduled jobs if explicitly enabled for that repo (e.g.: not on forks)
|
|
# Only run pull request jobs if labelled as needing an coverage run
|
|
# Always run workflow dispatch jobs
|
|
if: |
|
|
(github.event_name == 'schedule'
|
|
&& vars.ENABLE_SCHEDULED_JOBS == 'true') ||
|
|
(github.event_name == 'pull_request'
|
|
&& contains(github.event.pull_request.labels.*.name, 'pr: dev-coverage')) ||
|
|
(github.event_name == 'workflow_dispatch')
|
|
uses: ./.github/workflows/reusable-build.yml
|
|
with:
|
|
# For pull requests, build the head of the pull request branch, not the
|
|
# merge commit, otherwise patch coverage would include the changes
|
|
# between the root of the pull request and the target branch
|
|
sha: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
|
os: ubuntu-24.04
|
|
os-name: linux
|
|
cc: gcc
|
|
dev-asan: 0
|
|
dev-gcov: 1
|
|
|
|
test:
|
|
name: Test | ${{ matrix.test }}${{ matrix.num }}
|
|
needs: build
|
|
uses: ./.github/workflows/reusable-test.yml
|
|
with:
|
|
archive: ${{ needs.build.outputs.archive }}
|
|
os: ubuntu-24.04
|
|
cc: gcc
|
|
reloc: 0
|
|
suite: ${{ matrix.test }}${{ matrix.num }}
|
|
dev-gcov: 1
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
test: [coverage-vlt-, coverage-vltmt-]
|
|
num: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
include:
|
|
- {test: coverage-dist, num: ''}
|
|
|
|
publish-codecov:
|
|
name: Publish results to codecov.io
|
|
needs: test
|
|
if: ${{ contains(needs.*.result, 'success') && !cancelled() }}
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v5
|
|
|
|
- name: Download code coverage data
|
|
uses: actions/download-artifact@v6
|
|
with:
|
|
pattern: code-coverage-*
|
|
path: obj_coverage
|
|
merge-multiple: true
|
|
|
|
- name: List files
|
|
id: list-files
|
|
run: |
|
|
ls -lsha obj_coverage
|
|
find obj_coverage -type f | paste -sd, | sed "s/^/files=/" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Upload to codecov.io
|
|
uses: codecov/codecov-action@v5
|
|
with:
|
|
disable_file_fixes: true
|
|
disable_search: true
|
|
fail_ci_if_error: true
|
|
files: ${{ steps.list-files.outputs.files }}
|
|
plugins: noop
|
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
verbose: true
|
|
|
|
prepare-report:
|
|
name: Prepare HTML report
|
|
needs: [build, test]
|
|
if: ${{ contains(needs.*.result, 'success') && !cancelled() }}
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- name: Install dependencies
|
|
run: |
|
|
echo 'set man-db/auto-update false' | sudo debconf-communicate >/dev/null
|
|
sudo dpkg-reconfigure man-db
|
|
sudo apt install lcov
|
|
|
|
- name: Download repository archive
|
|
uses: actions/download-artifact@v6
|
|
with:
|
|
name: ${{ needs.build.outputs.archive }}
|
|
path: ${{ github.workspace }}
|
|
|
|
- name: Unpack repository archive
|
|
run: |
|
|
tar -x -z -f ${{ needs.build.outputs.archive }}
|
|
ls -lsha
|
|
|
|
- name: Download code coverage data
|
|
uses: actions/download-artifact@v6
|
|
with:
|
|
pattern: code-coverage-*
|
|
path: repo/obj_coverage
|
|
merge-multiple: true
|
|
|
|
- name: Create report
|
|
working-directory: repo
|
|
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
|
|
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
|
|
fi
|
|
# Remove data files
|
|
rm -f obj_coverage/verilator*.info
|
|
# Some extra work for PRs 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 "<pre>" >> notification/body.txt
|
|
grep -E "(lines|branches)\.*:" ${{ github.workspace }}/make-coverage-report.log | sed "s/\.*:/:/" >> notification/body.txt || true
|
|
echo "</pre>" >> 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
|
|
else
|
|
echo "Patch contains no code changes" >> notification/body.txt
|
|
fi
|
|
cat notification/body.txt
|
|
fi
|
|
|
|
- name: Upload report
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
path: repo/obj_coverage
|
|
name: coverage-report
|
|
|
|
- name: Upload notification
|
|
if: ${{ github.event_name == 'pull_request' }}
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
path: repo/notification
|
|
name: coverage-pr-notification
|
|
|
|
# Create GitHub issue for failed scheduled jobs
|
|
# This should always be the last job (we want an issue if anything breaks)
|
|
create-issue:
|
|
name: Create issue on failure
|
|
needs: [publish-codecov,prepare-report]
|
|
if: ${{ github.event_name == 'schedule' && github.repository == 'verilator/verilator' && github.run_attempt == 1 && failure() && !cancelled() }}
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
# Creating issues requires elevated privilege
|
|
- name: Generate access token
|
|
id: generate-token
|
|
uses: actions/create-github-app-token@v2.1.4
|
|
with:
|
|
app-id: ${{ vars.VERILATOR_CI_ID }}
|
|
private-key: ${{ secrets.VERILATOR_CI_KEY }}
|
|
owner: verilator
|
|
repositories: verilator
|
|
permission-issues: write
|
|
- name: Create issue
|
|
env:
|
|
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
|
run: |-
|
|
echo "This issue was created automatically by the GitHub Actions CI due to the failure of a scheduled Code coverage run." >> body.txt
|
|
echo "" >> body.txt
|
|
echo "Workflow status: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> body.txt
|
|
gh issue --repo ${{ github.repository }} create \
|
|
--title "Code coverage run #${{ github.run_number }} Failed" \
|
|
--body-file body.txt \
|
|
--label new \
|
|
--assignee gezalore,wsnyder
|