-
Notifications
You must be signed in to change notification settings - Fork 20
513 lines (463 loc) · 16.7 KB
/
roboanimals-workflow.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
on:
workflow_call:
inputs:
ref:
required: true
type: string
comment-id:
required: true
type: string
file:
required: true
type: string
network:
required: true
type: string
fn:
required: true
type: string
send:
required: true
type: string
pull_request_number:
required: true
type: string
delete-branch-after-send:
required: true
type: string
group_telegram_chat_id:
required: false
default: ''
type: string
announcement_telegram_chat_id:
required: false
default: false
type: string
failure_telegram_chat_id:
required: false
default: ''
type: string
runs_on:
required: true
type: string
compiler_cache_version:
required: false
default: 'v0.0.1'
type: string
brownie_cache_version:
required: false
type: string
default: 'v0.0.1'
close_pr:
required: false
default: 'false'
type: string
check_reviews:
required: false
default: 'false'
type: string
cached_runner:
required: false
default: 'false'
type: string
be:
required: false
default: 'false'
type: string
from_pr:
required: false
default: 'true'
type: string
job_description:
required: false
default: 'default cronjob description'
type: string
job_author:
required: false
type: string
default: 'no cron job author specified'
secrets:
COORDINAPE_BEARER_TOKEN:
required: false
TELEGRAM_TOKEN:
required: true
POLYGONSCAN_TOKEN:
required: true
FTMSCAN_TOKEN:
required: true
ETHERSCAN_TOKEN:
required: true
BSCSCAN_TOKEN:
required: true
ARBISCAN_TOKEN:
required: true
SNOWTRACE_TOKEN:
required: true
OPTISCAN_TOKEN:
required: false
BASESCAN_TOKEN:
required: false
YRPC_API_KEY:
required: false
YPRICEAPI_PASS:
required: false
YPRICEAPI_USER:
required: false
PRIVATE_KEY:
required: true
PAT:
required: true
jobs:
roboanimalsWorkflow:
runs-on: ${{ inputs.runs_on }}
concurrency:
group: ${{ inputs.send == 'true' && 'true' || github.run_id }}
timeout-minutes: 60
steps:
- uses: hmarr/debug-action@v2
- name: Create URL to the run output
id: vars
run: echo "run-url=https://github.com/${{github.repository}}/actions/runs/$GITHUB_RUN_ID" >> $GITHUB_OUTPUT
- name: Save runner name
id: runner_name
run: echo "runner_name=$RUNNER_NAME" >> $GITHUB_OUTPUT
- name: Edit comment with link to run
if: ${{ inputs.from_pr == 'true' }}
uses: peter-evans/[email protected]
with:
comment-id: ${{ inputs.comment-id }}
body: |
> 🚀 Agent ${{steps.runner_name.outputs.runner_name }} has picked up this request, follow progress [here](${{ steps.vars.outputs.run-url }})
>
- name: Checking out code
uses: actions/checkout@v1
with:
ref: ${{ inputs.ref }}
submodules: 'true'
- name: Get PR title
uses: actions/[email protected]
if: ${{ inputs.from_pr == 'true' }}
id: get-pr-title
with:
script: |
const {data: pull} = await github.rest.pulls.get({...context.repo, pull_number: ${{ inputs.pull_request_number }}});
if (!pull.title) {
return 'Empty Title 🤡';
}
return pull.title.replace(/\$/g, '💲');
- name: Get PR body
uses: actions/[email protected]
if: ${{ inputs.from_pr == 'true' }}
id: get-pr-body
with:
script: |
const {data: pull} = await github.rest.pulls.get({...context.repo, pull_number: ${{ inputs.pull_request_number }}});
if (!pull.body) {
return 'Empty Description 🤡';
}
return pull.body.replace(/\r\n/g, ' 🐶 ').replace(/\$/g, '💲');
- name: Get PR author
uses: actions/[email protected]
if: ${{ inputs.from_pr == 'true' }}
id: get-pr-author
with:
script: |
const {data: pull} = await github.rest.pulls.get({...context.repo, pull_number: ${{ inputs.pull_request_number }}});
if (pull.user.login === null) {
return 'Empty Author 🤡';
}
return pull.user.login;
- name: Pull down reviews
uses: actions/[email protected]
if: ${{ inputs.check_reviews == 'true' }}
id: get-pr
with:
script: |
const { data: reviews } = await github.rest.pulls.listReviews({
...context.repo,
pull_number: ${{ inputs.pull_request_number }},
})
const approvals = reviews.filter(review => review.state == 'APPROVED')
const reviews_filtered = approvals.filter(review => review.user.login != ${{ steps.get-pr-author.outputs.result }})
core.info(`List of reviews:\n ${JSON.stringify(reviews_filtered)}`)
return reviews_filtered.length
- name: Check Reviews
if: ${{ inputs.check_reviews == 'true' && inputs.send == 'true' && steps.get-pr.outputs.result < 1}}
run: exit 1
- name: Fail on no reviews
if: ${{ inputs.check_reviews == 'true' && failure() }}
uses: peter-evans/[email protected]
with:
comment-id: ${{ inputs.comment-id }}
body: |
> Review requirement failed. Get at least one approval before sending.
- name: Download Foundry
run: |
curl -L https://foundry.paradigm.xyz | bash
- name: Foundry Up
run: |
BASE_DIR=${XDG_CONFIG_HOME:-$HOME}
FOUNDRY_DIR=${FOUNDRY_DIR-"$BASE_DIR/.foundry"}
FOUNDRY_BIN_DIR="$FOUNDRY_DIR/bin"
$FOUNDRY_BIN_DIR/foundryup
- name: Add Anvil to Path
run: |
BASE_DIR=${XDG_CONFIG_HOME:-$HOME}
FOUNDRY_DIR=${FOUNDRY_DIR-"$BASE_DIR/.foundry"}
FOUNDRY_BIN_DIR="$FOUNDRY_DIR/bin"
echo $FOUNDRY_BIN_DIR >> $GITHUB_PATH
- name: Set up python 3.10
uses: actions/setup-python@main
with:
python-version: '3.10'
- name: Install python dependencies
run: |
pip install setuptools wheel
pip install "cython<3.0" "pyyaml>=5.4.1,<6" --no-build-isolation
pip install -r requirements-dev.txt
- name: Edit .env file
env:
YRPC_API_KEY: ${{ secrets.YRPC_API_KEY }}
run: |
touch .env
echo YRPC_API_KEY=${{ secrets.YRPC_API_KEY }} >> .env
- name: Add network config
timeout-minutes: 1
run: |
brownie networks list true
cp network-config.yaml ~/.brownie/
brownie networks list true
- name: Brownie compile
if: ${{ inputs.fn != 'hydate_compiler_cache' }}
run: |
brownie compile
- name: Run Function
id: fn
timeout-minutes: 45
env:
COORDINAPE_BEARER_TOKEN: ${{ secrets.COORDINAPE_BEARER_TOKEN }}
POLYGONSCAN_TOKEN: ${{ secrets.POLYGONSCAN_TOKEN }}
FTMSCAN_TOKEN: ${{ secrets.FTMSCAN_TOKEN }}
ETHERSCAN_TOKEN: ${{ secrets.ETHERSCAN_TOKEN }}
BSCSCAN_TOKEN: ${{ secrets.BSCSCAN_TOKEN }}
ARBISCAN_TOKEN: ${{ secrets.ARBISCAN_TOKEN }}
SNOWTRACE_TOKEN: ${{ secrets.SNOWTRACE_TOKEN }}
OPTIMISMSCAN_TOKEN: ${{ secrets.OPTISCAN_TOKEN }}
BASESCAN_TOKEN: ${{ secrets.BASESCAN_TOKEN }}
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
YRPC_API_KEY: ${{ secrets.YRPC_API_KEY }}
GITHUB_ACTION_SEND: ${{ inputs.send }}
YPRICEAPI_USER: ${{ secrets.YPRICEAPI_USER }}
YPRICEAPI_PASS: ${{ secrets.YPRICEAPI_PASS }}
BE: ${{ inputs.be }}
run: |
python3 -m multisig_ci brownie run -r ${{ inputs.file }} ${{ inputs.fn }} --network ${{ inputs.network }}-main-fork 1>output.txt 2>error.txt || EXIT_CODE=$?
echo "brownie-exit-code=$EXIT_CODE" >> $GITHUB_OUTPUT
echo "::group:: Output"
cat output.txt
echo "::endgroup::"
echo "::group:: Error"
cat error.txt
echo "::endgroup::"
exit 0
- name: Set timeout
if: failure()
id: timeout
run: |
echo "::group:: Output"
cat output.txt
echo "::endgroup::"
echo "::group:: Error"
cat error.txt
echo "::endgroup::"
echo "brownie-timeout=true" >> $GITHUB_OUTPUT
- name: Check failure
id: failcheck
run: |
echo "::group:: Output"
cat output.txt
echo "::endgroup::"
echo "::group:: Error"
cat error.txt
echo "::endgroup::"
exit ${{ steps.fn.outputs.brownie-exit-code}}
- name: Nonce fail check, add comment
if: inputs.send == 'true' && env.NONCE == ''
uses: peter-evans/[email protected]
with:
comment-id: ${{ inputs.comment-id }}
body: |
> Did not find nonce.txt. Did you run with send=true without actually posting the transaction at the end of your function? Use the @sign decorator above your function.
- name: New TX Telegram Alert - MultiSig Chat
env:
TELEGRAM_MESSAGE: "Oof, ${{ steps.get-pr-author.outputs.result }} just tried to send a transaction without putting the @sign decorator above the function... Please join me in shaming this 🤡"
if: inputs.send == 'true' && env.NONCE == ''
run: |
python3 -m multisig_ci send_and_pin_message ${{ secrets.TELEGRAM_TOKEN }} ${{ inputs.group_telegram_chat_id }}
continue-on-error: true
- name: Nonce fail check
if: inputs.send == 'true' && env.NONCE == ''
run: |
exit 1
- name: Safe url check, add comment
if: inputs.send == 'true' && env.SAFE_LINK == ''
uses: peter-evans/[email protected]
with:
comment-id: ${{ inputs.comment-id }}
body: |
> Fatal error. Did not find safe.txt.
- name: Safe fail check, add comment
if: inputs.send == 'true' && env.SAFE_LINK == ''
run: |
exit 1
- name: Fix ansi codes
if: always() && inputs.from_pr == 'true'
run: |
sed -i 's/\x1b\[[0-9;]*m//g' ./error.txt
sed -i 's/\x1b\[[0-9;]*m//g' ./output.txt
- name: Read error.txt
if: always() && inputs.from_pr == 'true'
id: read_error
uses: juliangruber/read-file-action@v1
with:
path: ./error.txt
- name: Read output.txt
if: always() && inputs.from_pr == 'true'
id: read_output
uses: juliangruber/read-file-action@v1
with:
path: ./output.txt
- name: Edit comment with error message
if: ${{ failure() && inputs.from_pr == 'true' }}
uses: peter-evans/[email protected]
with:
comment-id: ${{ inputs.comment-id }}
body: |
> ❌ Failure, check failure [logs](${{ steps.vars.outputs.run-url }}) below
Output:
```
${{ steps.read_output.outputs.content }}
```
Error:
```
${{ steps.read_error.outputs.content }}
```
- name: Edit comment with dry run message
if: ${{ inputs.send == 'false' && inputs.from_pr == 'true'}}
uses: peter-evans/[email protected]
with:
comment-id: ${{ inputs.comment-id }}
body: |
> ✅ Dry run success, see output [here](${{ steps.vars.outputs.run-url }})
> Rerun the command with send=true to publish the TX to the safe
Output:
```
${{ steps.read_output.outputs.content }}
```
continue-on-error: true
- name: Set PR url
if: ${{ inputs.from_pr == 'true' }}
id: pr-url
run: |
echo "pr-url=https://github.com/${{github.repository}}/pull/${{ inputs.pull_request_number }}/files" >> $GITHUB_OUTPUT
- name: Create Telegram message - from PR
if: ${{ inputs.send == 'true' && inputs.from_pr == 'true' }}
run: |
TELEGRAM_MESSAGE=$(cat << EOF
✍️ [${{ inputs.network}} #${{ env.NONCE }}](${{ env.SAFE_LINK }}) \`${{ steps.get-pr-title.outputs.result}}\`
Sender: ${{ steps.get-pr-author.outputs.result }}
Description: \`${{ steps.get-pr-body.outputs.result }}\`
Review [the code](${{ steps.pr-url.outputs.pr-url }}), verify [the output](${{ steps.vars.outputs.run-url }}), and [sign here](${{ env.SAFE_LINK }})
EOF
)
echo "TELEGRAM_MESSAGE<<EOF" >> $GITHUB_ENV
echo "$TELEGRAM_MESSAGE" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Create Telegram message - automated
if: ${{ inputs.send == 'true' && inputs.from_pr == 'false' }}
run: |
TELEGRAM_MESSAGE=$(cat << EOF
✍️ [${{ inputs.network}} #${{ env.NONCE }}](${{ env.SAFE_LINK }}) \`${{ steps.get-pr-title.outputs.result}}\`
Sender: ${{ inputs.job_author }} (via cronjob or manual trigger)
Description: ${{ inputs.job_description }}
Function ran: ${{ inputs.fn }} in ${{inputs.file}}.py
Verify [the output](${{ steps.vars.outputs.run-url }}), and [sign here](${{ env.SAFE_LINK }})
EOF
)
echo "TELEGRAM_MESSAGE<<EOF" >> $GITHUB_ENV
echo "$TELEGRAM_MESSAGE" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: New TX Telegram Alert - Robowoofy Alert Chat
if: ${{ inputs.send == 'true' }}
run: |
python3 -m multisig_ci send_and_pin_message ${{ secrets.TELEGRAM_TOKEN }} ${{ inputs.announcement_telegram_chat_id }}
continue-on-error: true
- name: New TX Telegram Alert - MultiSig Chat
if: ${{ inputs.send == 'true' }}
run: |
python3 -m multisig_ci send_and_pin_message ${{ secrets.TELEGRAM_TOKEN }} ${{ inputs.group_telegram_chat_id }}
continue-on-error: true
- name: Edit comment with full run message
if: ${{ inputs.send == 'true' && inputs.from_pr == 'true' }}
uses: peter-evans/[email protected]
with:
comment-id: ${{ inputs.comment-id }}
body: |
> ✅ TX with nonce ${{ env.NONCE }} successfully sent. Find output logs [here](${{ steps.vars.outputs.run-url }}).
> Find your queued TX on the [Gnosis UI](${{ env.SAFE_LINK }})
>
> Your PR has been labeled with tag ${{inputs.network}} ${{ env.NONCE }}, which you can find [here](https://github.com/yearn/strategist-ms/labels?q=${{ env.NONCE }}).
Output:
```
${{ steps.read_output.outputs.content }}
```
continue-on-error: true
- uses: actions/[email protected]
if: ${{ inputs.send == 'true' && inputs.from_pr == 'true' }}
with:
script: |
github.rest.issues.addLabels({
issue_number: ${{ inputs.pull_request_number }},
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['${{ inputs.network }} #${{ env.NONCE }}']
})
- name: Delete PRs head branches
if: ${{ inputs.delete-branch-after-send == 'true' && inputs.send == 'true' && inputs.from_pr == 'true'}}
uses: pinguinsquad/[email protected]
with:
github_token: ${{ secrets.PAT }}
numbers: ${{ inputs.pull_request_number }}
continue-on-error: true
- name: Add reaction
if: ${{ inputs.from_pr == 'true' }}
uses: peter-evans/[email protected]
with:
comment-id: ${{ inputs.comment-id }}
reaction-type: hooray
continue-on-error: true
- name: Telegram Alert On Infra Failure
if: ${{ failure() && steps.failcheck.outcome == 'success' }}
uses: appleboy/telegram-action@master
with:
disable_web_page_preview: true
to: ${{ inputs.failure_telegram_chat_id}}
token: ${{ secrets.TELEGRAM_TOKEN }}
message: |
Grrrr grrrrr grrrrr ${{ steps.vars.outputs.run-url }} pipeline failed even though the brownie function succeeded!
continue-on-error: true
- name: Telegram Alert On Brownie Timeout
if: ${{ failure() && steps.timeout.outputs.brownie-timeout == 'true' }}
uses: appleboy/telegram-action@master
with:
to: ${{ inputs.failure_telegram_chat_id }}
token: ${{ secrets.TELEGRAM_TOKEN }}
message: |
Grrrr grrrrr grrrrr ${{ steps.vars.outputs.run-url }} brownie timed out!
continue-on-error: true
- name: cleanup files
if: always()
run: |
rm -rf ~/.brownie/accounts
rm -f ~/alive.signal
continue-on-error: true