-
Notifications
You must be signed in to change notification settings - Fork 51
157 lines (138 loc) · 5.75 KB
/
run-forge-tests.yaml
File metadata and controls
157 lines (138 loc) · 5.75 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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
name: Run Forge Tests
on:
pull_request:
branches:
- staging-2.5
- master
workflow_dispatch:
jobs:
check:
name: Foundry project
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # Required to comment on PRs
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Run tests
run: forge test -vvv
env:
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
SCROLL_RPC_URL: ${{ secrets.SCROLL_RPC_URL }}
HISTORICAL_PROOF_812_WITHDRAWAL_RPC_URL: ${{ secrets.HISTORICAL_PROOF_812_WITHDRAWAL_RPC_URL }}
HISTORICAL_PROOF_RPC_URL: ${{ secrets.HISTORICAL_PROOF_RPC_URL }}
- name: Generate coverage report
if: always()
shell: bash
run: |
# Capture full output; || true so the step always continues
forge coverage --report summary \
--no-match-coverage '(script/|test/|src/helpers/|src/interfaces/|src/eigenlayer|src/libraries/|src/archive/)' \
--color never > full_output.txt 2>&1 || true
# Extract coverage table lines
grep -E '^\|' full_output.txt > coverage.txt || true
if [ -s coverage.txt ]; then
echo "" >> coverage.txt
echo "---" >> coverage.txt
grep -E "^(Ran|Suite result:|Test result:)" full_output.txt >> coverage.txt || true
else
echo "Coverage report could not be generated. Check workflow logs for details." > coverage.txt
fi
env:
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
SCROLL_RPC_URL: ${{ secrets.SCROLL_RPC_URL }}
HISTORICAL_PROOF_812_WITHDRAWAL_RPC_URL: ${{ secrets.HISTORICAL_PROOF_812_WITHDRAWAL_RPC_URL }}
HISTORICAL_PROOF_RPC_URL: ${{ secrets.HISTORICAL_PROOF_RPC_URL }}
- name: Upload coverage artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: forge-coverage
path: coverage.txt
- name: Post coverage comment on PR
if: always() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
// Hidden marker for reliable comment detection (emojis can have encoding issues)
const COMMENT_MARKER = '<!-- forge-coverage-report -->';
// Get PR number - context.issue.number may be undefined on some event types
const prNumber = context.payload.pull_request?.number || context.issue?.number;
if (!prNumber) {
console.log('Could not determine PR number, skipping comment');
return;
}
console.log(`PR number: ${prNumber}`);
// Read coverage file
let coverage;
try {
coverage = fs.readFileSync('coverage.txt', 'utf8');
console.log(`Coverage file read successfully (${coverage.length} chars)`);
} catch (err) {
console.log(`Failed to read coverage.txt: ${err.message}`);
return;
}
// Build the Markdown with no leading indentation (YAML indentation would break fenced code blocks).
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
const body = [
COMMENT_MARKER,
'## 📊 Forge Coverage Report',
'',
'```',
coverage.trimEnd(),
'```',
'',
`<sub>Generated by workflow run [#${context.runNumber}](${runUrl})</sub>`
].join('\n');
try {
// Find existing comment to update (avoids spam on multiple pushes). Fetch ALL comments with pagination
const comments = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const { data: pageComments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
per_page: 100,
page: page
});
comments.push(...pageComments);
hasMore = pageComments.length === 100;
page++;
}
// Search by hidden marker (more reliable than emoji-based search)
const botComment = comments.find(c =>
c.body?.includes(COMMENT_MARKER)
);
console.log(`Found ${comments.length} total comments`);
if (botComment) {
console.log(`Updating existing comment (id: ${botComment.id})`);
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: body
});
console.log('Comment updated successfully');
} else {
console.log('No existing comment found, creating new one');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: body
});
console.log('Comment created successfully');
}
} catch (err) {
console.error(`GitHub API error: ${err.message}`);
throw err; // Re-throw to fail the step visibly
}