forked from numworks/epsilon
-
Notifications
You must be signed in to change notification settings - Fork 0
142 lines (135 loc) · 6.87 KB
/
code_coverage.yml
File metadata and controls
142 lines (135 loc) · 6.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
name: Code Coverage
on: workflow_call
jobs:
coverage:
timeout-minutes: 60
runs-on: ubuntu-latest
env:
MAKEFLAGS: -j2
COVERAGE_OUTPUT_DIR: 'output/debug/no_assert/linux/coverage'
steps:
- name: Fetch target branch and PR branch
uses: actions/checkout@v4
with:
fetch-depth: 200
- name: Find most recent ancestor of PR and target branch
id: common_ancestor
run: echo "commit_sha=$(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }})" >> $GITHUB_OUTPUT
- name: Build container and define DOCKER_RUN
uses: ./.github/actions/docker-builder
- name: Checkout to most recent ancestor
uses: actions/checkout@v4
with:
ref: ${{ steps.common_ancestor.outputs.commit_sha }}
- name: Create coverage output directory
run: mkdir -p ${{ env.COVERAGE_OUTPUT_DIR }}
- name: Build BASE coverage target
run: $DOCKER_RUN "touch ${{ env.COVERAGE_OUTPUT_DIR }}/base_summary.txt && make TOOLCHAIN=host-gcc PLATFORM=simulator DEBUG=1 ASSERTIONS=0 coverage | grep \"coverage rate:\" --text -A 4 > ${{ env.COVERAGE_OUTPUT_DIR }}/base_summary.txt"
- name: Rename base.info
run: mv ${{ env.COVERAGE_OUTPUT_DIR }}/code_coverage.info ${{ env.COVERAGE_OUTPUT_DIR }}/base.info
- name: Upload BASE coverage
uses: actions/upload-artifact@v4
with:
name: base.info
path: ${{ env.COVERAGE_OUTPUT_DIR }}/base.info
retention-days: 2
- name: Upload BASE coverage summary
uses: actions/upload-artifact@v4
with:
name: base_summary
path: ${{ env.COVERAGE_OUTPUT_DIR }}/base_summary.txt
retention-days: 2
- name: Checkout current branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Build HEAD coverage target
run: $DOCKER_RUN "make PLATFORM=simulator DEBUG=1 ASSERTIONS=0 coverage"
- name: Rename head.info
run: mv ${{ env.COVERAGE_OUTPUT_DIR }}/code_coverage.info ${{ env.COVERAGE_OUTPUT_DIR }}/head.info
- name: Upload HEAD coverage
uses: actions/upload-artifact@v4
with:
name: head.info
path: ${{ env.COVERAGE_OUTPUT_DIR }}/head.info
retention-days: 2
- name: Download BASE info # needed because the checkout action cleaned the "output" folder
uses: actions/download-artifact@v4
with:
name: base.info
path: ${{ env.COVERAGE_OUTPUT_DIR }}
- name: Download BASE coverage summary
uses: actions/download-artifact@v4
with:
name: base_summary
path: ${{ env.COVERAGE_OUTPUT_DIR }}
- name: Generate diff file
run: $DOCKER_RUN "touch ${{ env.COVERAGE_OUTPUT_DIR }}/diff.txt && /usr/local/share/lcov/support-scripts/gitdiff --prefix ${{ github.workspace }} ${{ steps.common_ancestor.outputs.commit_sha }} ${{ github.event.pull_request.head.sha }} > ${{ env.COVERAGE_OUTPUT_DIR }}/diff.txt"
- name: Upload diff file # useful for debug
id: diff
uses: actions/upload-artifact@v4
with:
name: diff
path: ${{ env.COVERAGE_OUTPUT_DIR }}/diff.txt
retention-days: 2
- name: Generate coverage report
run: $DOCKER_RUN "touch ${{ env.COVERAGE_OUTPUT_DIR }}/genhtml_output.txt && genhtml ${{ env.COVERAGE_OUTPUT_DIR }}/head.info -o ${{ env.COVERAGE_OUTPUT_DIR }}/report --baseline-file ${{ env.COVERAGE_OUTPUT_DIR }}/base.info --diff-file ${{ env.COVERAGE_OUTPUT_DIR }}/diff.txt --no-function-coverage --ignore-errors path | grep \"coverage rate:\" -A 40 > ${{ env.COVERAGE_OUTPUT_DIR }}/genhtml_output.txt"
- name: Upload report
id: report
uses: actions/upload-artifact@v4
with:
name: coverage_report
path: ${{ env.COVERAGE_OUTPUT_DIR }}/report
retention-days: 2
- name: Upload genhtml output # useful for debugging
uses: actions/upload-artifact@v4
with:
name: genhtml_output
path: ${{ env.COVERAGE_OUTPUT_DIR }}/genhtml_output.txt
retention-days: 2
# TODO: next steps should be in a separate workflow for safety reasons
- name: Format report into markdown tables
run: |
touch ${{ env.COVERAGE_OUTPUT_DIR }}/summary.md && $DOCKER_RUN "\$PYTHON build/metrics/coverage_report.py ${{ env.COVERAGE_OUTPUT_DIR }}/genhtml_output.txt --base_output ${{ env.COVERAGE_OUTPUT_DIR }}/base_summary.txt --summary" > ${{ env.COVERAGE_OUTPUT_DIR }}/summary.md
touch ${{ env.COVERAGE_OUTPUT_DIR }}/differential.md && $DOCKER_RUN "\$PYTHON build/metrics/coverage_report.py ${{ env.COVERAGE_OUTPUT_DIR }}/genhtml_output.txt --diff" > ${{ env.COVERAGE_OUTPUT_DIR }}/differential.md
- name: Shorten commit ids
id: shorten_commits
run: |
echo "head_sha=$(git rev-parse --short ${{ github.event.pull_request.head.sha }} )" >> $GITHUB_OUTPUT
echo "base_sha=$(git rev-parse --short ${{ steps.common_ancestor.outputs.commit_sha }} )" >> $GITHUB_OUTPUT
- name: Add comment
uses: actions/github-script@v7
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
var fs = require('fs');
var head_commit = "${{ steps.shorten_commits.outputs.head_sha }}";
var base_commit = "${{ steps.shorten_commits.outputs.base_sha }}";
var summary = fs.readFileSync('${{ env.COVERAGE_OUTPUT_DIR }}/summary.md');
var differential = fs.readFileSync('${{ env.COVERAGE_OUTPUT_DIR }}/differential.md');
var artifact_url = "${{ github.server_url }}/${{ github.repository }}//actions/runs/${{ github.run_id }}/artifacts/${{ steps.report.outputs.artifact-id }}"
const body = "### Coverage report (" + head_commit + ")\n\n" + summary + "#### Differences with base branch (" + base_commit + ")\n\n" + differential + "\n\nDownload full report: " + artifact_url
const pr_number = context.issue.number
const owner = context.repo.owner;
const repo = context.repo.repo;
const oldComments = await github.paginate(
github.rest.issues.listComments,
{
owner, repo,
issue_number: pr_number,
}
);
const commentToUpdate = oldComments.findLast(comment =>
comment.user.login === 'github-actions[bot]' && comment.body.startsWith(body.slice(0,10))
)
if (commentToUpdate) {
await github.rest.issues.updateComment({
owner, repo, body,
comment_id: commentToUpdate.id,
});
} else {
await github.rest.issues.createComment({
owner, repo, body,
issue_number: pr_number,
});
}