1
- from pathlib import Path
2
- import subprocess
3
- from pprint import pprint
4
- from collections import namedtuple
5
- from typing import Generator
6
-
1
+ import json
7
2
import logging
3
+ import os
4
+ import shlex
8
5
import shutil
6
+ import subprocess
9
7
import sys
10
8
import tempfile
11
- import shlex
12
- import os
9
+ from collections import namedtuple
10
+ from pathlib import Path , PosixPath
11
+ from typing import Generator , List
13
12
14
13
logging .basicConfig (stream = sys .stdout , level = logging .DEBUG )
15
14
18
17
'.ci' ,
19
18
'.git' ,
20
19
'.github' ,
20
+ 'archived' ,
21
21
'lightning' ,
22
- 'feeadjuster'
23
22
]
24
23
25
24
global_dependencies = [
@@ -50,13 +49,15 @@ def enumerate_plugins(basedir: Path) -> Generator[Plugin, None, None]:
50
49
pip_pytest = [
51
50
x for x in plugins if (x / Path ('requirements.txt' )).exists ()
52
51
]
52
+ print (f'Pip plugins: { ", " .join ([p .name for p in sorted (pip_pytest )])} ' )
53
53
54
54
poetry_pytest = [
55
55
x for x in plugins if (x / Path ("pyproject.toml" )).exists ()
56
56
]
57
- print (poetry_pytest )
57
+ print (f'Poetry plugins: { ", " . join ([ p . name for p in sorted ( poetry_pytest )]) } ' )
58
58
59
59
other_plugins = [x for x in plugins if x not in pip_pytest and x not in poetry_pytest ]
60
+ print (f'Other plugins: { ", " .join ([p .name for p in sorted (other_plugins )])} ' )
60
61
61
62
for p in sorted (pip_pytest ):
62
63
yield Plugin (
@@ -227,20 +228,24 @@ def install_pyln_testing(pip_path):
227
228
stderr = subprocess .STDOUT ,
228
229
)
229
230
230
- def run_one (p : Plugin ) -> bool :
231
- print ("Running tests on plugin {p.name}" .format (p = p ))
232
-
233
- testfiles = [
231
+ def get_testfiles (p : Plugin ) -> List [PosixPath ]:
232
+ return [
234
233
x for x in p .path .iterdir ()
235
234
if (x .is_dir () and x .name == 'tests' )
236
235
or (x .name .startswith ("test_" ) and x .name .endswith ('.py' ))
237
236
]
238
237
239
- if len (testfiles ) == 0 :
238
+ def has_testfiles (p : Plugin ) -> bool :
239
+ return len (get_testfiles (p )) > 0
240
+
241
+ def run_one (p : Plugin ) -> bool :
242
+ print ("Running tests on plugin {p.name}" .format (p = p ))
243
+
244
+ if not has_testfiles (p ):
240
245
print ("No test files found, skipping plugin {p.name}" .format (p = p ))
241
246
return True
242
247
243
- print ("Found {ctestfiles} test files, creating virtualenv and running tests" .format (ctestfiles = len (testfiles )))
248
+ print ("Found {ctestfiles} test files, creating virtualenv and running tests" .format (ctestfiles = len (get_testfiles ( p ) )))
244
249
print ("##[group]{p.name}" .format (p = p ))
245
250
246
251
# Create a virtual env
@@ -296,7 +301,7 @@ def run_one(p: Plugin) -> bool:
296
301
print ("##[endgroup]" )
297
302
298
303
299
- def run_all (args ):
304
+ def run_all (workflow , update_badges , plugin_names ):
300
305
root_path = subprocess .check_output ([
301
306
'git' ,
302
307
'rev-parse' ,
@@ -306,20 +311,82 @@ def run_all(args):
306
311
root = Path (root_path )
307
312
308
313
plugins = list (enumerate_plugins (root ))
309
- if args != []:
310
- plugins = [p for p in plugins if p .name in args ]
314
+ if plugin_names != []:
315
+ plugins = [p for p in plugins if p .name in plugin_names ]
311
316
print ("Testing the following plugins: {names}" .format (names = [p .name for p in plugins ]))
312
317
else :
313
318
print ("Testing all plugins in {root}" .format (root = root ))
314
319
315
320
results = [(p , run_one (p )) for p in plugins ]
316
321
success = all ([t [1 ] for t in results ])
317
322
323
+ if sys .version_info [0 :2 ] == (3 , 12 ) and update_badges :
324
+ push_badges_data (collect_badges_data (results , success ), workflow )
325
+
318
326
if not success :
319
327
print ("The following tests failed:" )
320
328
for t in filter (lambda t : not t [1 ], results ):
321
329
print (" - {p.name} ({p.path})" .format (p = t [0 ]))
322
330
sys .exit (1 )
331
+ else :
332
+ print ("All tests passed." )
333
+
334
+
335
+ def collect_badges_data (results , success ):
336
+ badges_data = {}
337
+ for t in results :
338
+ p = t [0 ]
339
+ if has_testfiles (p ):
340
+ if success or t [1 ]:
341
+ badges_data [p .name ] = True
342
+ else :
343
+ badges_data [p .name ] = False
344
+ return badges_data
345
+
346
+
347
+ def configure_git ():
348
+ subprocess .run (["git" , "config" , "--global" , "user.email" , '"lightningd@plugins.repo"' ])
349
+ subprocess .run (["git" , "config" , "--global" , "user.name" , '"lightningd"' ])
350
+
351
+
352
+ def update_and_commit_badge (plugin_name , passed , workflow ):
353
+ json_data = { "schemaVersion" : 1 , "label" : "" , "message" : " ✔ " , "color" : "green" }
354
+ if not passed :
355
+ json_data .update ({"message" : "✗" , "color" : "red" })
356
+
357
+ filename = os .path .join ("badges" , f"{ plugin_name } _{ workflow } .json" )
358
+ with open (filename , "w" ) as file :
359
+ file .write (json .dumps (json_data ))
360
+
361
+ output = subprocess .check_output (["git" , "add" , "-v" , filename ]).decode ("utf-8" )
362
+ if output != "" :
363
+ subprocess .run (["git" , "commit" , "-m" , f'Update { plugin_name } badge to { "passed" if passed else "failed" } ({ workflow } )' ])
364
+ return True
365
+ return False
366
+
367
+
368
+ def push_badges_data (data , workflow ):
369
+ print ("Pushing badge data..." )
370
+ configure_git ()
371
+ subprocess .run (["git" , "fetch" ])
372
+ subprocess .run (["git" , "checkout" , "badges" ])
373
+
374
+ any_changes = False
375
+ for plugin_name , passed in data .items ():
376
+ any_changes |= update_and_commit_badge (plugin_name , passed , workflow )
377
+
378
+ if any_changes :
379
+ subprocess .run (["git" , "push" , "origin" , "badges" ])
380
+ print ("Done." )
381
+
323
382
324
383
if __name__ == "__main__" :
325
- run_all (sys .argv [1 :])
384
+ import argparse
385
+
386
+ parser = argparse .ArgumentParser (description = 'Plugins test script' )
387
+ parser .add_argument ("workflow" , type = str , help = "Name of the GitHub workflow" )
388
+ parser .add_argument ("--update-badges" , action = 'store_true' , help = "Whether badges data should be updated" )
389
+ parser .add_argument ("plugins" , nargs = "*" , default = [], help = "List of plugins" )
390
+ args = parser .parse_args ()
391
+
392
+ run_all (args .workflow , args .update_badges , args .plugins )
0 commit comments