-
Notifications
You must be signed in to change notification settings - Fork 47
144 lines (120 loc) · 5.79 KB
/
enforceTestCoverage.yml
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
143
144
name: Enforce Min Test Coverage
# - will make sure that (Foundry) unit test coverage is above min threshold
# - we start with 74% (status today), planning to increase to 100% until EOY 2024
# - Only the 'lines' coverage counts as 'branch' coverage is not reliable
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
jobs:
enforce-min-test-coverage:
runs-on: ubuntu-latest
# will only run once the PR is in "Ready for Review" state
if: ${{ github.event.pull_request.draft == false }}
permissions:
pull-requests: write
contents: read
env:
ETH_NODE_URI_MAINNET: ${{ secrets.ETH_NODE_URI_MAINNET }}
ETH_NODE_URI_POLYGON: ${{ secrets.ETH_NODE_URI_POLYGON }}
ETH_NODE_URI_GOERLI: ${{ secrets.ETH_NODE_URI_GOERLI }}
ETH_NODE_URI_ARBITRUM: ${{ secrets.ETH_NODE_URI_ARBITRUM }}
ETH_NODE_URI_BSC: ${{ secrets.ETH_NODE_URI_BSC }}
ETH_NODE_URI_GNOSIS: ${{ secrets.ETH_NODE_URI_GNOSIS }}
MIN_TEST_COVERAGE: ${{ secrets.MIN_TEST_COVERAGE }}
steps:
- uses: actions/[email protected]
- name: Set up Node.js
uses: actions/[email protected]
with:
node-version: '20'
- name: Install dev dependencies
run: yarn install
- name: Install Foundry
uses: foundry-rs/[email protected]
with:
version: nightly
- name: Install Dependencies
run: forge install
- name: Generate Coverage Report
run: |
forge coverage --report lcov --force --evm-version 'shanghai' --ir-minimum
echo "Filtering coverage report to only contain coverage info for 'src/'' folder now"
npx ts-node script/utils/filter_lcov.ts lcov.info lcov-filtered.info 'test/' 'script/'
echo "Coverage report successfully filtered"
- name: Generate Coverage Summary
run: |
# Path to the lcov info file
LCOV_FILE="lcov-filtered.info"
# Initialize counters
TOTAL_LINES_FOUND=0
TOTAL_LINES_HIT=0
TOTAL_FUNCTIONS_FOUND=0
TOTAL_FUNCTIONS_HIT=0
TOTAL_BRANCHES_FOUND=0
TOTAL_BRANCHES_HIT=0
# Read through the lcov file
while IFS= read -r line; do
case $line in
LF:*)
TOTAL_LINES_FOUND=$((TOTAL_LINES_FOUND + ${line#LF:}))
;;
LH:*)
TOTAL_LINES_HIT=$((TOTAL_LINES_HIT + ${line#LH:}))
;;
FNF:*)
TOTAL_FUNCTIONS_FOUND=$((TOTAL_FUNCTIONS_FOUND + ${line#FNF:}))
;;
FNH:*)
TOTAL_FUNCTIONS_HIT=$((TOTAL_FUNCTIONS_HIT + ${line#FNH:}))
;;
BRF:*)
TOTAL_BRANCHES_FOUND=$((TOTAL_BRANCHES_FOUND + ${line#BRF:}))
;;
BRH:*)
TOTAL_BRANCHES_HIT=$((TOTAL_BRANCHES_HIT + ${line#BRH:}))
;;
esac
done < "$LCOV_FILE"
# Calculate percentages with high precision
LINE_COVERAGE_PERCENTAGE=$(echo "scale=4; $TOTAL_LINES_HIT / $TOTAL_LINES_FOUND * 100" | bc)
FUNCTION_COVERAGE_PERCENTAGE=$(echo "scale=4; $TOTAL_FUNCTIONS_HIT / $TOTAL_FUNCTIONS_FOUND * 100" | bc)
BRANCH_COVERAGE_PERCENTAGE=$(echo "scale=4; $TOTAL_BRANCHES_HIT / $TOTAL_BRANCHES_FOUND * 100" | bc)
# Format results with two decimal places and alignment
LINE_COVERAGE_PERCENTAGE=$(printf "%.2f" "$LINE_COVERAGE_PERCENTAGE")
FUNCTION_COVERAGE_PERCENTAGE=$(printf "%.2f" "$FUNCTION_COVERAGE_PERCENTAGE")
BRANCH_COVERAGE_PERCENTAGE=$(printf "%.2f" "$BRANCH_COVERAGE_PERCENTAGE")
# Prepare aligned output
LINE_COVERAGE_REPORT=$(printf "Line Coverage: %6s%% (%4d / %4d lines)" "$LINE_COVERAGE_PERCENTAGE" "$TOTAL_LINES_HIT" "$TOTAL_LINES_FOUND")
FUNCTION_COVERAGE_REPORT=$(printf "Function Coverage: %6s%% (%4d / %4d functions)" "$FUNCTION_COVERAGE_PERCENTAGE" "$TOTAL_FUNCTIONS_HIT" "$TOTAL_FUNCTIONS_FOUND")
BRANCH_COVERAGE_REPORT=$(printf "Branch Coverage: %6s%% (%4d / %4d branches)" "$BRANCH_COVERAGE_PERCENTAGE" "$TOTAL_BRANCHES_HIT" "$TOTAL_BRANCHES_FOUND")
# Check against minimum threshold
if (( $(echo "$LINE_COVERAGE_PERCENTAGE >= $MIN_TEST_COVERAGE" | bc -l) )); then
RESULT_COVERAGE_REPORT="Test coverage ($LINE_COVERAGE_PERCENTAGE%) is above min threshold ($MIN_TEST_COVERAGE%). Check passed."
echo -e "\033[32m$RESULT_COVERAGE_REPORT\033[0m"
else
RESULT_COVERAGE_REPORT="Test coverage ($LINE_COVERAGE_PERCENTAGE%) is below min threshold ($MIN_TEST_COVERAGE%). Check failed."
echo -e "\033[31m$RESULT_COVERAGE_REPORT\033[0m"
exit 1
fi
# Output result_COVERAGE_REPORTs
echo "$LINE_COVERAGE_REPORT"
echo "$FUNCTION_COVERAGE_REPORT"
echo "$BRANCH_COVERAGE_REPORT"
echo "$RESULT_COVERAGE_REPORT"
# Store in GitHub environment variables
{
echo "LINE_COVERAGE_REPORT=$LINE_COVERAGE_REPORT"
echo "FUNCTION_COVERAGE_REPORT=$FUNCTION_COVERAGE_REPORT"
echo "BRANCH_COVERAGE_REPORT=$BRANCH_COVERAGE_REPORT"
echo "RESULT_COVERAGE_REPORT=$RESULT_COVERAGE_REPORT"
} >> "$GITHUB_ENV"
- name: Comment with Coverage Summary in PR
uses: mshick/[email protected]
with:
repo-token: ${{ secrets.GIT_ACTIONS_BOT_PAT_CLASSIC }}
message: |
## Test Coverage Report
${{ env.LINE_COVERAGE_REPORT }}
${{ env.FUNCTION_COVERAGE_REPORT }}
${{ env.BRANCH_COVERAGE_REPORT }}
${{ env.RESULT_COVERAGE_REPORT }}