Skip to content

Commit 9f37a1c

Browse files
committed
feat: add CI output comparison between branches
Run assertion monitor on both target and PR branches, diff the alert output, and post results to PR comments. - Uses config.ci.json with public RPCs for CI runs - Posts GitHub-style diff showing only alert changes - Uses built-in GITHUB_TOKEN (no additional secrets needed)
1 parent eb2cb08 commit 9f37a1c

File tree

2 files changed

+147
-4
lines changed

2 files changed

+147
-4
lines changed

.github/workflows/ci.yml

Lines changed: 126 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,20 +125,142 @@ jobs:
125125

126126
steps:
127127
- uses: actions/checkout@v4
128-
128+
129129
- name: Use Node.js ${{ matrix.node-version }}
130130
uses: actions/setup-node@v4
131131
with:
132132
node-version: ${{ matrix.node-version }}
133133
cache: 'yarn'
134-
134+
135135
- name: Install dependencies
136136
run: yarn install --frozen-lockfile
137-
137+
138138
- name: Run lint
139139
run: |
140140
if [ -f "package.json" ] && grep -q '"lint"' package.json; then
141141
yarn lint
142142
else
143143
echo "No lint script found at root level"
144-
fi
144+
fi
145+
146+
# Output comparison - compares monitoring output between target branch and PR branch
147+
output-comparison:
148+
runs-on: ubuntu-latest
149+
if: github.event_name == 'pull_request'
150+
151+
steps:
152+
- name: Checkout PR branch
153+
uses: actions/checkout@v4
154+
with:
155+
ref: ${{ github.head_ref }}
156+
path: pr-branch
157+
158+
- name: Checkout target branch
159+
uses: actions/checkout@v4
160+
with:
161+
ref: ${{ github.base_ref }}
162+
path: target-branch
163+
164+
- name: Use Node.js 18.x
165+
uses: actions/setup-node@v4
166+
with:
167+
node-version: 18.x
168+
169+
- name: Run monitoring on target branch
170+
id: target
171+
run: |
172+
cd target-branch
173+
yarn install --frozen-lockfile
174+
yarn workspace assertion-monitor build
175+
# Run monitoring with CI config and extract alert summary
176+
timeout 180s yarn workspace assertion-monitor dev --configPath=../../config.ci.json 2>&1 | tee output.txt || true
177+
# Extract alerts section
178+
sed -n '/Alert Summary/,$ p' output.txt > ../target-alerts.txt || echo "No alerts" > ../target-alerts.txt
179+
continue-on-error: true
180+
181+
- name: Run monitoring on PR branch
182+
id: pr
183+
run: |
184+
cd pr-branch
185+
yarn install --frozen-lockfile
186+
yarn workspace assertion-monitor build
187+
# Run monitoring with CI config and extract alert summary
188+
timeout 180s yarn workspace assertion-monitor dev --configPath=../../config.ci.json 2>&1 | tee output.txt || true
189+
# Extract alerts section
190+
sed -n '/Alert Summary/,$ p' output.txt > ../pr-alerts.txt || echo "No alerts" > ../pr-alerts.txt
191+
continue-on-error: true
192+
193+
- name: Generate diff and post comment
194+
uses: actions/github-script@v7
195+
with:
196+
script: |
197+
const fs = require('fs');
198+
199+
const targetAlerts = fs.existsSync('target-alerts.txt')
200+
? fs.readFileSync('target-alerts.txt', 'utf8').trim()
201+
: '';
202+
const prAlerts = fs.existsSync('pr-alerts.txt')
203+
? fs.readFileSync('pr-alerts.txt', 'utf8').trim()
204+
: '';
205+
206+
const hasChanges = targetAlerts !== prAlerts;
207+
208+
let body = '';
209+
if (hasChanges) {
210+
body = `### ⚠️ Alert Output Changes
211+
212+
\`\`\`diff
213+
${generateDiff(targetAlerts, prAlerts)}
214+
\`\`\`
215+
`;
216+
} else {
217+
body = `### ✅ Alert Output: No Changes`;
218+
}
219+
220+
// Simple line-by-line diff
221+
function generateDiff(oldText, newText) {
222+
const oldLines = oldText.split('\n');
223+
const newLines = newText.split('\n');
224+
const diff = [];
225+
226+
const maxLen = Math.max(oldLines.length, newLines.length);
227+
for (let i = 0; i < maxLen; i++) {
228+
const oldLine = oldLines[i] || '';
229+
const newLine = newLines[i] || '';
230+
if (oldLine !== newLine) {
231+
if (oldLine) diff.push('- ' + oldLine);
232+
if (newLine) diff.push('+ ' + newLine);
233+
} else if (oldLine) {
234+
diff.push(' ' + oldLine);
235+
}
236+
}
237+
return diff.join('\n');
238+
}
239+
240+
// Find existing comment
241+
const { data: comments } = await github.rest.issues.listComments({
242+
owner: context.repo.owner,
243+
repo: context.repo.repo,
244+
issue_number: context.issue.number,
245+
});
246+
247+
const botComment = comments.find(comment =>
248+
comment.user.type === 'Bot' &&
249+
comment.body.includes('Alert Output')
250+
);
251+
252+
if (botComment) {
253+
await github.rest.issues.updateComment({
254+
owner: context.repo.owner,
255+
repo: context.repo.repo,
256+
comment_id: botComment.id,
257+
body: body
258+
});
259+
} else {
260+
await github.rest.issues.createComment({
261+
owner: context.repo.owner,
262+
repo: context.repo.repo,
263+
issue_number: context.issue.number,
264+
body: body
265+
});
266+
}

config.ci.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"childChains": [
3+
{
4+
"name": "Arbitrum Sepolia",
5+
"chainId": 421614,
6+
"parentChainId": 11155111,
7+
"confirmPeriodBlocks": 45818,
8+
"parentRpcUrl": "https://sepolia.drpc.org",
9+
"orbitRpcUrl": "https://sepolia-rollup.arbitrum.io/rpc",
10+
"explorerUrl": "https://sepolia.arbiscan.io",
11+
"parentExplorerUrl": "https://sepolia.etherscan.io",
12+
"ethBridge": {
13+
"bridge": "0x38f918D0E9F1b721EDaA41302E399fa1B79333a9",
14+
"inbox": "0xaAe29B0366299461418F5324a79Afc425BE5ae21",
15+
"outbox": "0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F",
16+
"rollup": "0x042b2e6c5e99d4c521bd49beed5e99651d9b0cf4",
17+
"sequencerInbox": "0x6c97864CE4bE1C2C8bB6aFe3A115E6D7Dca82E71"
18+
}
19+
}
20+
]
21+
}

0 commit comments

Comments
 (0)