-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve test coverage action [@coderabbit ignore] #790
Changes from all commits
e4c5947
797e772
48b9703
9795b16
745c5c7
e186436
143d4c2
779bd8b
f36a67e
48de477
d119ca9
484c918
f582cbc
9785369
4cd03e0
f18dab6
0eaa7c8
a3e6f5d
cfd1977
db2f0ff
e7395b2
8364ac7
5d772b0
2f8e953
3d39c31
af38e51
056a8c2
1755f86
17e5da3
476ba04
10b6204
f5f566d
be50801
e40f49a
2202a50
6f86400
1aa3287
c75b982
b27f938
26fa4ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ name: Enforce Min Test Coverage | |
|
||
on: | ||
pull_request: | ||
types: [opened, synchronize, reopened] | ||
types: [opened, synchronize, reopened, ready_for_review] | ||
|
||
jobs: | ||
enforce-min-test-coverage: | ||
|
@@ -27,6 +27,8 @@ jobs: | |
MIN_TEST_COVERAGE: 74 # = 74% line coverage | ||
steps: | ||
- uses: actions/[email protected] | ||
with: | ||
fetch-depth: 0 ##### Fetch all history for all branches | ||
|
||
- name: Set up Node.js | ||
uses: actions/setup-node@v4 | ||
|
@@ -54,12 +56,20 @@ jobs: | |
|
||
echo "Coverage report successfully filtered" | ||
|
||
- name: Generate Coverage Summary | ||
# Step to get modified or added files in the src/ folder | ||
- name: Get Modified Files | ||
id: get_modified_files | ||
run: | | ||
# Get list of modified or added files in src directory | ||
MODIFIED_FILES=$(git diff --name-only --diff-filter=AM origin/main | grep '^src/.*\.sol$') | ||
echo "modified_files=$MODIFIED_FILES" >> "$GITHUB_ENV" | ||
|
||
- name: Generate Coverage Summary | ||
run: | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Address shellcheck warnings in the script. Static analysis has flagged several issues:
These issues can lead to unexpected behavior and should be corrected. - MODIFIED_FILES=(${MODIFIED_FILES})
+ read -r -a MODIFIED_FILES <<< "$MODIFIED_FILES"
- if [[ " ${MODIFIED_FILES[@]} " =~ "$FILE_NAME" ]]; then
+ if [[ " ${MODIFIED_FILES[*]} " =~ $FILE_NAME ]]; then
Toolsactionlint
|
||
|
||
# Path to the lcov info file | ||
LCOV_FILE="lcov-filtered.info" | ||
MODIFIED_FILES=(${MODIFIED_FILES}) | ||
|
||
# Initialize counters | ||
TOTAL_LINES_FOUND=0 | ||
|
@@ -69,14 +79,23 @@ jobs: | |
TOTAL_BRANCHES_FOUND=0 | ||
TOTAL_BRANCHES_HIT=0 | ||
|
||
# Clear the per-file coverage report file | ||
echo "" > per_file_coverage_report.txt | ||
|
||
# Read through the lcov file | ||
while IFS= read -r line; do | ||
case $line in | ||
SF:*) | ||
CURRENT_FILE=${line#SF:} | ||
FILE_NAME=$(basename "$CURRENT_FILE") | ||
;; | ||
LF:*) | ||
TOTAL_LINES_FOUND=$((TOTAL_LINES_FOUND + ${line#LF:})) | ||
FILE_LINES_FOUND=${line#LF:} | ||
;; | ||
LH:*) | ||
TOTAL_LINES_HIT=$((TOTAL_LINES_HIT + ${line#LH:})) | ||
FILE_LINES_HIT=${line#LH:} | ||
;; | ||
FNF:*) | ||
TOTAL_FUNCTIONS_FOUND=$((TOTAL_FUNCTIONS_FOUND + ${line#FNF:})) | ||
|
@@ -91,6 +110,16 @@ jobs: | |
TOTAL_BRANCHES_HIT=$((TOTAL_BRANCHES_HIT + ${line#BRH:})) | ||
;; | ||
esac | ||
|
||
# Check if the file is in the list of modified files | ||
if [[ " ${MODIFIED_FILES[@]} " =~ " $FILE_NAME " ]]; then | ||
# Calculate line coverage percentage for the current file | ||
LINE_COVERAGE_PERCENTAGE=$(echo "scale=2; $FILE_LINES_HIT / $FILE_LINES_FOUND * 100" | bc) | ||
|
||
# Append the per-file coverage to the report file | ||
echo "File: $FILE_NAME - Line Coverage: $LINE_COVERAGE_PERCENTAGE% ($FILE_LINES_HIT / $FILE_LINES_FOUND)" >> per_file_coverage_report.txt | ||
fi | ||
|
||
done < "$LCOV_FILE" | ||
|
||
# Calculate percentages with high precision | ||
|
@@ -118,7 +147,7 @@ jobs: | |
exit 1 | ||
fi | ||
|
||
# Output result_COVERAGE_REPORTs | ||
# Output results | ||
echo "$LINE_COVERAGE_REPORT" | ||
echo "$FUNCTION_COVERAGE_REPORT" | ||
echo "$BRANCH_COVERAGE_REPORT" | ||
|
@@ -131,14 +160,3 @@ jobs: | |
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 }} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"mainnet": "0x000000000022D473030F116dDEE9F6B43aC78BA3", | ||
"arbitrum": "0x000000000022D473030F116dDEE9F6B43aC78BA3", | ||
"aurora": "", | ||
"avalanche": "0x000000000022D473030F116dDEE9F6B43aC78BA3", | ||
"base": "0x000000000022D473030F116dDEE9F6B43aC78BA3", | ||
"blast": "0x000000000022d473030f116ddee9f6b43ac78ba3", | ||
"boba": "", | ||
"bsc": "0x000000000022D473030F116dDEE9F6B43aC78BA3", | ||
"celo": "0x000000000022D473030F116dDEE9F6B43aC78BA3", | ||
"fantom": "", | ||
"fraxtal": "", | ||
"fuse": "", | ||
"gnosis": "", | ||
"gravity": "", | ||
"immutablezkevm": "", | ||
"linea": "", | ||
"mantle": "", | ||
"metis": "", | ||
"mode": "", | ||
"moonbeam": "", | ||
"moonriver": "", | ||
"optimism": "0x000000000022D473030F116dDEE9F6B43aC78BA3", | ||
"polygon": "0x000000000022D473030F116dDEE9F6B43aC78BA3", | ||
"polygonzkevm": "", | ||
"rootstock": "", | ||
"scroll": "", | ||
"sei": "", | ||
"taiko": "", | ||
"zksync": "0x0000000000225e31d15943971f47ad3022f714fa" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
# Permit2 Proxy | ||
|
||
## Description | ||
|
||
Periphery contract which enables gasless and semi-gasless transaction flows | ||
enabled through ERC20 Permit and Uniswap's Permit2 | ||
|
||
## How To Use | ||
|
||
The contract has a number of methods for making gasless and semi-gasless calls | ||
as well as a few helpful utility methods. | ||
|
||
The following methods are available: | ||
|
||
This method is used to execute a transaction where the approval is granted | ||
using an ERC20 Permit signature. It can only be called by the signer in order | ||
to prevent front-running attacks. | ||
|
||
```solidity | ||
/// @notice Allows to bridge tokens through a LI.FI diamond contract using | ||
/// an EIP2612 gasless permit (only works with tokenAddresses that | ||
/// implement EIP2612) (in contrast to Permit2, calldata and diamondAddress | ||
/// are not signed by the user and could therefore be replaced by the user) | ||
/// Can only be called by the permit signer to prevent front-running. | ||
/// @param tokenAddress Address of the token to be bridged | ||
/// @param amount Amount of tokens to be bridged | ||
/// @param deadline Transaction must be completed before this timestamp | ||
/// @param v User signature (recovery ID) | ||
/// @param r User signature (ECDSA output) | ||
/// @param s User signature (ECDSA output) | ||
/// @param diamondCalldata Address of the token to be bridged | ||
function callDiamondWithEIP2612Signature( | ||
address tokenAddress, | ||
uint256 amount, | ||
uint256 deadline, | ||
uint8 v, | ||
bytes32 r, | ||
bytes32 s, | ||
bytes calldata diamondCalldata | ||
) public payable | ||
```` | ||
|
||
This method is used to execute a transaction where the approval is granted via | ||
Uniswap's Permit2 contract. It can only be called by the signer in order to | ||
prevent front-running attacks. | ||
|
||
```solidity | ||
/// @notice Allows to bridge tokens of one type through a LI.FI diamond | ||
/// contract using Uniswap's Permit2 contract and a user signature | ||
/// that verifies allowance. The calldata can be changed by the | ||
/// user. Can only be called by the permit signer to prevent | ||
/// front-running. | ||
/// @param _diamondCalldata the calldata to execute | ||
/// @param _permit the Uniswap Permit2 parameters | ||
/// @param _signature the signature giving approval to transfer tokens | ||
function callDiamondWithPermit2( | ||
bytes calldata _diamondCalldata, | ||
ISignatureTransfer.PermitTransferFrom calldata _permit, | ||
bytes calldata _signature | ||
) external payable | ||
``` | ||
|
||
This method enables a gasless flow by allowing a user to sign a Uniswap Permit2 | ||
message hash which includes a "witness" type. This extra type restricts which | ||
calldata can be called during execution and cannot be changed. Anyone with the | ||
signature can execute the transaction on behalf of the signer. | ||
|
||
```solidity | ||
/// @notice Allows to bridge tokens of one type through a LI.FI diamond | ||
/// contract using Uniswap's Permit2 contract and a user signature | ||
/// that verifies allowance, diamondAddress and diamondCalldata | ||
/// @param _diamondCalldata the calldata to execute | ||
/// @param _signer the signer giving permission to transfer tokens | ||
/// @param _permit the Uniswap Permit2 parameters | ||
/// @param _signature the signature giving approval to transfer tokens | ||
function callDiamondWithPermit2Witness( | ||
bytes calldata _diamondCalldata, | ||
address _signer, | ||
ISignatureTransfer.PermitTransferFrom calldata _permit, | ||
bytes calldata _signature | ||
) external payable | ||
``` | ||
|
||
There are a few utility methods to make it easier to generate the necessary | ||
signature for the gasless flow. | ||
|
||
Calling this method will return a valid message hash that can then be signed | ||
in order to be executed later by another wallet. | ||
|
||
```solidity | ||
/// @notice utitlity method for constructing a valid Permit2 message hash | ||
/// @param _diamondCalldata the calldata to execute | ||
/// @param _assetId the address of the token to approve | ||
/// @param _amount amount of tokens to approve | ||
/// @param _nonce the nonce to use | ||
/// @param _deadline the expiration deadline | ||
function getPermit2MsgHash( | ||
bytes calldata _diamondCalldata, | ||
address _assetId, | ||
uint256 _amount, | ||
uint256 _nonce, | ||
uint256 _deadline | ||
) external view returns (bytes32 msgHash) | ||
``` | ||
|
||
Permit2 nonces are non-sequential and are a bit complicated to work with. The | ||
following utility methods allow you to fetch the next valid nonce or sequence | ||
of nonces for use when generating Permit2 signatures. | ||
|
||
```solidity | ||
/// @notice Finds the next valid nonce for a user, starting from 0. | ||
/// @param owner The owner of the nonces | ||
/// @return nonce The first valid nonce starting from 0 | ||
function nextNonce(address owner) external view returns (uint256 nonce) | ||
|
||
/// @notice Finds the next valid nonce for a user, after from a given nonce. | ||
/// @dev This can be helpful if you're signing multiple nonces in a row and | ||
/// need the next nonce to sign but the start one is still valid. | ||
/// @param owner The owner of the nonces | ||
/// @param start The nonce to start from | ||
/// @return nonce The first valid nonce after the given nonce | ||
function nextNonceAfter( | ||
address owner, | ||
uint256 start | ||
) external view returns (uint256 nonce) | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve the script for fetching modified files.
The script uses
git diff
to fetch modified or added Solidity files. However, it's crucial to ensure that the base branch (origin/main
) is up-to-date to avoid missing any recent changes. Consider adding agit fetch
step before this to ensure accuracy.+ git fetch origin main MODIFIED_FILES=$(git diff --name-only --diff-filter=AM origin/main | grep '^src/.*\.sol$')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are checking out the repo in an earlier step in the same file, is it not automatically ensured that we have the latest version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@0xDEnYO, the
actions/checkout
step does indeed clone the repository, but it doesn't automatically fetch the latest changes from the remote base branch (origin/main
). By default, it only fetches the latest commit of the branch being checked out. Therefore, to ensure that thegit diff
command compares against the most up-to-date version oforigin/main
, it's recommended to add agit fetch
step before running thegit diff
command. This will ensure that any recent changes toorigin/main
are included in the comparison.Let me know if you need further clarification!