Compare commits
3133 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
05f0aba931 | ||
![]() |
462396174f | ||
![]() |
c19a7eb771 | ||
![]() |
c288441a7d | ||
![]() |
1d6ea46cac | ||
![]() |
02b41f5ff9 | ||
![]() |
b4a4dcabce | ||
![]() |
602aacf949 | ||
![]() |
51290e039a | ||
![]() |
b4badd8cce | ||
![]() |
652b4c06e8 | ||
![]() |
0b7a421316 | ||
![]() |
b26581aca1 | ||
![]() |
43e6b45c5d | ||
![]() |
fe1bc0e3d3 | ||
![]() |
d7917c6584 | ||
![]() |
3f646a3549 | ||
![]() |
6809677b7a | ||
![]() |
4edd678ac3 | ||
![]() |
f08255874b | ||
![]() |
92c02a00a1 | ||
![]() |
b70221184d | ||
![]() |
435fd74b2e | ||
![]() |
0626fa3ff3 | ||
![]() |
8817a797cb | ||
![]() |
54174910be | ||
![]() |
84ef162530 | ||
![]() |
b672a5115a | ||
![]() |
678cdc2808 | ||
![]() |
27b7bbb0ae | ||
![]() |
83610723bb | ||
![]() |
21acf46f4a | ||
![]() |
f356b3c86b | ||
![]() |
66275de060 | ||
![]() |
a16702bf7a | ||
![]() |
aa11897ec4 | ||
![]() |
6513fe1691 | ||
![]() |
45e0c78ac7 | ||
![]() |
a949a8338c | ||
![]() |
1f772e919b | ||
![]() |
684c5e6d94 | ||
![]() |
9d7201ded6 | ||
![]() |
f93ff33629 | ||
![]() |
729c70475c | ||
![]() |
2009d446ac | ||
![]() |
b693fc207f | ||
![]() |
0104c75ccc | ||
![]() |
4d0aab94b6 | ||
![]() |
df3e9932c4 | ||
![]() |
c3a1bb2c99 | ||
![]() |
27843f1667 | ||
![]() |
36d5b9dda5 | ||
![]() |
9d4f8fea58 | ||
![]() |
d0cf1645b7 | ||
![]() |
641e22af4a | ||
![]() |
8a4a9757b7 | ||
![]() |
6bfa9e7a9a | ||
![]() |
625dbd682e | ||
![]() |
1a71128b6a | ||
![]() |
c29c1d3dd0 | ||
![]() |
e753fb0a63 | ||
![]() |
e21f1a3077 | ||
![]() |
792230fced | ||
![]() |
4dbe54f96e | ||
![]() |
537f1c6318 | ||
![]() |
82587d8858 | ||
![]() |
eda64a62bd | ||
![]() |
4d5444c2c3 | ||
![]() |
c2e104be2f | ||
![]() |
eed685a419 | ||
![]() |
6f538bb83f | ||
![]() |
48d8f15b2a | ||
![]() |
f4e06529f1 | ||
![]() |
9b5f7d7ff5 | ||
![]() |
80dc58425e | ||
![]() |
f9216b6d97 | ||
![]() |
fef272dc40 | ||
![]() |
a236bf57ea | ||
![]() |
0cb58dec12 | ||
![]() |
44f3356296 | ||
![]() |
1d9fdda44c | ||
![]() |
ca746c1dbe | ||
![]() |
2414c5b001 | ||
![]() |
e73bb10d96 | ||
![]() |
c7114f61a1 | ||
![]() |
38cc85fd79 | ||
![]() |
834406f361 | ||
![]() |
5d8e41f17c | ||
![]() |
a78c1f5db4 | ||
![]() |
5977012387 | ||
![]() |
e9772d1404 | ||
![]() |
880354d0c6 | ||
![]() |
8d5497eb10 | ||
![]() |
696bea0add | ||
![]() |
bd7d572708 | ||
![]() |
305db886e7 | ||
![]() |
17107f43d7 | ||
![]() |
2d4c94f488 | ||
![]() |
bf02379775 | ||
![]() |
0d320382bc | ||
![]() |
40853de9f8 | ||
![]() |
94b94fea13 | ||
![]() |
f8034fbb84 | ||
![]() |
b4c0974161 | ||
![]() |
246859db91 | ||
![]() |
46a4c027a6 | ||
![]() |
525aabbe28 | ||
![]() |
25b256207d | ||
![]() |
257f12c17b | ||
![]() |
598b7212f2 | ||
![]() |
88201be733 | ||
![]() |
9b7ba7b107 | ||
![]() |
3ea85a1c0d | ||
![]() |
50693d8df5 | ||
![]() |
87d8f9488b | ||
![]() |
950331d47c | ||
![]() |
ed00b69562 | ||
![]() |
9d768c3d4e | ||
![]() |
6b79c79980 | ||
![]() |
99b60a2a91 | ||
![]() |
8ae850f052 | ||
![]() |
71038002e0 | ||
![]() |
03d95b07db | ||
![]() |
c65cd88342 | ||
![]() |
9f928e3005 | ||
![]() |
fb1b47b727 | ||
![]() |
a77ecbc238 | ||
![]() |
e4fe134b73 | ||
![]() |
f5a7145f2b | ||
![]() |
10471793b2 | ||
![]() |
28fd03b28d | ||
![]() |
4db04c76fa | ||
![]() |
f79274f27b | ||
![]() |
f1d2215d5d | ||
![]() |
6b2903bdce | ||
![]() |
dc82617b24 | ||
![]() |
1797e9a1ea | ||
![]() |
56b5e13a32 | ||
![]() |
9e63ef55ed | ||
![]() |
f1afcaced6 | ||
![]() |
e42a3d1b0a | ||
![]() |
f0eedff362 | ||
![]() |
f6d7b721fd | ||
![]() |
6f59461624 | ||
![]() |
443dcaf814 | ||
![]() |
6f8dfa84e8 | ||
![]() |
df7dd40375 | ||
![]() |
07a5a99344 | ||
![]() |
02a0746337 | ||
![]() |
75ed46d235 | ||
![]() |
c8c9e91b48 | ||
![]() |
8ead8a4214 | ||
![]() |
0f83d09356 | ||
![]() |
c3dcd3e758 | ||
![]() |
0e9a58eebf | ||
![]() |
2295558b65 | ||
![]() |
68447960ff | ||
![]() |
00518ab39d | ||
![]() |
2c2260e690 | ||
![]() |
9adb9156b8 | ||
![]() |
d1d479f03c | ||
![]() |
cc733854b1 | ||
![]() |
0b99ecfd4e | ||
![]() |
cc3bbb0c52 | ||
![]() |
373db58d9d | ||
![]() |
9161a8dcde | ||
![]() |
e13fb92d45 | ||
![]() |
7891350b8e | ||
![]() |
457e041909 | ||
![]() |
eaf854ef0c | ||
![]() |
681bf92506 | ||
![]() |
3ec883ad31 | ||
![]() |
e5740c1ffc | ||
![]() |
bbe7f7b544 | ||
![]() |
205913dc0c | ||
![]() |
dd73690e2e | ||
![]() |
c226cd45e5 | ||
![]() |
facb2785cd | ||
![]() |
4b558a92db | ||
![]() |
5f68aa8f2d | ||
![]() |
0da22a2fef | ||
![]() |
2972fe4d6b | ||
![]() |
57a81a39f3 | ||
![]() |
1d8732f877 | ||
![]() |
3de07763cf | ||
![]() |
b53f3b80e1 | ||
![]() |
4f8f7b39ce | ||
![]() |
ff86e79932 | ||
![]() |
14c7f454e7 | ||
![]() |
cda0f1d381 | ||
![]() |
d44c8e3205 | ||
![]() |
6b3dabec4c | ||
![]() |
bce8e36722 | ||
![]() |
b376795801 | ||
![]() |
d41df78c17 | ||
![]() |
4ae1154663 | ||
![]() |
60268df189 | ||
![]() |
f52993ba02 | ||
![]() |
3b13fed1b0 | ||
![]() |
338ea071b0 | ||
![]() |
25cb66210f | ||
![]() |
d6babd6899 | ||
![]() |
0a79e54e1f | ||
![]() |
9d06a2a6a9 | ||
![]() |
7e8e88bd35 | ||
![]() |
b510737b96 | ||
![]() |
2e70979353 | ||
![]() |
625929d27d | ||
![]() |
03334d095e | ||
![]() |
8a0655f075 | ||
![]() |
98e187efcd | ||
![]() |
96f65726ea | ||
![]() |
bf548e4af2 | ||
![]() |
8b07fd3b11 | ||
![]() |
d195e6e7c2 | ||
![]() |
1754cd4b9e | ||
![]() |
03c184259a | ||
![]() |
5f0139347a | ||
![]() |
58a98867a7 | ||
![]() |
9216b0cec2 | ||
![]() |
0e3a6c3e99 | ||
![]() |
e86678fe3a | ||
![]() |
35d5a4d79f | ||
![]() |
887f93673c | ||
![]() |
a29e8b5656 | ||
![]() |
5a127050b2 | ||
![]() |
581934340b | ||
![]() |
5587afbef7 | ||
![]() |
0f039f361b | ||
![]() |
6d4230d4f0 | ||
![]() |
1711887607 | ||
![]() |
c393672835 | ||
![]() |
396e5a51d5 | ||
![]() |
47a2d62412 | ||
![]() |
c73b12cc6d | ||
![]() |
41ce994be9 | ||
![]() |
192e174507 | ||
![]() |
5e85e31a01 | ||
![]() |
7871e848ad | ||
![]() |
15fa7fb955 | ||
![]() |
1c5b7dc5f4 | ||
![]() |
4765b9f775 | ||
![]() |
0c82494d63 | ||
![]() |
7d02310f6e | ||
![]() |
0df48f8409 | ||
![]() |
b76e23c88a | ||
![]() |
549c203ec2 | ||
![]() |
cee950d742 | ||
![]() |
44ce9f4341 | ||
![]() |
7b65c377b1 | ||
![]() |
532b66aa5c | ||
![]() |
d9384bba72 | ||
![]() |
461ea4f9bf | ||
![]() |
0874344d6e | ||
![]() |
9f8300f8b4 | ||
![]() |
a06b9e80ae | ||
![]() |
4c5f5d698f | ||
![]() |
07c64e5618 | ||
![]() |
5bd333239b | ||
![]() |
831e892562 | ||
![]() |
e052d30e1c | ||
![]() |
23a449039c | ||
![]() |
60e2739e15 | ||
![]() |
0f319d7425 | ||
![]() |
d477ae513d | ||
![]() |
5891cbdfd5 | ||
![]() |
c9eaa5c000 | ||
![]() |
fd91508dbb | ||
![]() |
e8a7e82269 | ||
![]() |
159b05372c | ||
![]() |
635f118699 | ||
![]() |
634b61511e | ||
![]() |
77fcf43160 | ||
![]() |
5f084a52a4 | ||
![]() |
ff2cb1b4f2 | ||
![]() |
5d5da31340 | ||
![]() |
29bc0d3fd9 | ||
![]() |
c9f9d5784e | ||
![]() |
a4fba0109c | ||
![]() |
8a6546164a | ||
![]() |
bad2eb6859 | ||
![]() |
b2dbd4264a | ||
![]() |
57d40e662d | ||
![]() |
185549c022 | ||
![]() |
f853fd0592 | ||
![]() |
cd3c6e6bbd | ||
![]() |
e5ce44a301 | ||
![]() |
ccdcd17ffd | ||
![]() |
e4b8dafc5d | ||
![]() |
2d756ea4c5 | ||
![]() |
ce497c39e9 | ||
![]() |
2d21bbb405 | ||
![]() |
90941b398f | ||
![]() |
2ca8dc42f6 | ||
![]() |
ee096d679e | ||
![]() |
4621617d4b | ||
![]() |
4bbd49b998 | ||
![]() |
c6557ed000 | ||
![]() |
f0e7702ccc | ||
![]() |
6354e6c542 | ||
![]() |
117616472f | ||
![]() |
4ff79362e5 | ||
![]() |
0713a11242 | ||
![]() |
064742427d | ||
![]() |
efe5e6c7a4 | ||
![]() |
01e9662a12 | ||
![]() |
20576b4b9e | ||
![]() |
077b23f6a6 | ||
![]() |
02768050b1 | ||
![]() |
427adf47f0 | ||
![]() |
5c6aa49478 | ||
![]() |
aa0b62a2d0 | ||
![]() |
0320702dd5 | ||
![]() |
38903688b4 | ||
![]() |
98a74d2cd6 | ||
![]() |
068000d9c6 | ||
![]() |
490ac3999e | ||
![]() |
2859a60726 | ||
![]() |
d03038e4e4 | ||
![]() |
77af4bed28 | ||
![]() |
a5cf6aa30c | ||
![]() |
15807c9c84 | ||
![]() |
dc458cf753 | ||
![]() |
92ca3eebd0 | ||
![]() |
f591d0c7f0 | ||
![]() |
35023362e2 | ||
![]() |
e436cb6d85 | ||
![]() |
257d47dfba | ||
![]() |
4918e11830 | ||
![]() |
aa08304bd4 | ||
![]() |
008ba8ceec | ||
![]() |
fe6c3ea0ca | ||
![]() |
7fc073d922 | ||
![]() |
7e4bfc2f1f | ||
![]() |
ef3a7f51d6 | ||
![]() |
a65c2f2100 | ||
![]() |
ea042d8095 | ||
![]() |
8293f8c984 | ||
![]() |
0ff732eeb3 | ||
![]() |
8df6fc260f | ||
![]() |
d516645658 | ||
![]() |
2c97e7ea24 | ||
![]() |
1c8e606958 | ||
![]() |
74605cb326 | ||
![]() |
aa15b58e8a | ||
![]() |
0a392e7438 | ||
![]() |
85efc7df8e | ||
![]() |
2a095d24c2 | ||
![]() |
ac3dc5e392 | ||
![]() |
dd7e9d3b17 | ||
![]() |
0647a31f54 | ||
![]() |
9d67dd3dbe | ||
![]() |
5acd7e3646 | ||
![]() |
9f4af73d05 | ||
![]() |
800a282599 | ||
![]() |
31c4d150e6 | ||
![]() |
2a2a5b6b9c | ||
![]() |
d8dcc13244 | ||
![]() |
639ce0e105 | ||
![]() |
9d447b9959 | ||
![]() |
83bfc72efa | ||
![]() |
879c8388c8 | ||
![]() |
bb7502bd15 | ||
![]() |
5c5539ced9 | ||
![]() |
c2039de114 | ||
![]() |
0cbc9bc448 | ||
![]() |
9ef20a69dd | ||
![]() |
a617853c0f | ||
![]() |
5c1bceb76c | ||
![]() |
3f54ebb830 | ||
![]() |
6f070cff38 | ||
![]() |
ec75ae5ab7 | ||
![]() |
4333ab5b20 | ||
![]() |
e3cac49049 | ||
![]() |
68bd4537bd | ||
![]() |
f0ce41b71c | ||
![]() |
ce451bf430 | ||
![]() |
7592e9e855 | ||
![]() |
999653c672 | ||
![]() |
6cf4c21fdf | ||
![]() |
09ee51bee3 | ||
![]() |
8eced8a5df | ||
![]() |
13fa1402a7 | ||
![]() |
07ac0ac168 | ||
![]() |
049d7fd639 | ||
![]() |
2e90fbb74b | ||
![]() |
2a9db54a6d | ||
![]() |
d0d5671ef7 | ||
![]() |
97120ff1f5 | ||
![]() |
b2d4e1b488 | ||
![]() |
9299962a59 | ||
![]() |
ea35f7ea00 | ||
![]() |
3399f8837f | ||
![]() |
ac897da4f1 | ||
![]() |
8e56bc097a | ||
![]() |
f6d3fe5179 | ||
![]() |
efa99ea361 | ||
![]() |
6d8f9bd379 | ||
![]() |
589fb70c81 | ||
![]() |
7daee9e7cf | ||
![]() |
99c80bdd47 | ||
![]() |
5e7cbf5fdb | ||
![]() |
b4d6d28988 | ||
![]() |
8370e6e6ef | ||
![]() |
aa31060851 | ||
![]() |
54c56103aa | ||
![]() |
e57fb1b8eb | ||
![]() |
926735a61e | ||
![]() |
d3ac2a064b | ||
![]() |
91df40b882 | ||
![]() |
28396e9658 | ||
![]() |
3a66e2a7e4 | ||
![]() |
35f3202fd5 | ||
![]() |
2b30af482a | ||
![]() |
a93bcf46e0 | ||
![]() |
6d4c555c7d | ||
![]() |
507a8c703d | ||
![]() |
3a7052c24a | ||
![]() |
782eb123a9 | ||
![]() |
9134dac8f6 | ||
![]() |
df12603b45 | ||
![]() |
bb9b5e8363 | ||
![]() |
31b9c0a541 | ||
![]() |
ba0a561b13 | ||
![]() |
8d35cbb00f | ||
![]() |
82dd6547dc | ||
![]() |
6d42539842 | ||
![]() |
08dedfb681 | ||
![]() |
f6d9fa10e0 | ||
![]() |
9eb0d763ae | ||
![]() |
51d2f88f07 | ||
![]() |
90a06d6ba9 | ||
![]() |
2cb2c9234e | ||
![]() |
ac21d93904 | ||
![]() |
a4637ea6e7 | ||
![]() |
fd9998cf5f | ||
![]() |
ea024b2d7f | ||
![]() |
db4e584844 | ||
![]() |
c6543c497a | ||
![]() |
88f9f3efbb | ||
![]() |
3af07c2040 | ||
![]() |
3680129aa2 | ||
![]() |
5d866cbe77 | ||
![]() |
346f237a17 | ||
![]() |
c037f1e7c5 | ||
![]() |
ae82ed4ae0 | ||
![]() |
cbd59070e8 | ||
![]() |
6c9dcea443 | ||
![]() |
79b060d445 | ||
![]() |
434b67ebc3 | ||
![]() |
cbda684547 | ||
![]() |
3f8189989b | ||
![]() |
67a1f54f6f | ||
![]() |
99248a4438 | ||
![]() |
878743189b | ||
![]() |
98d1d84e2f | ||
![]() |
a60bf3759e | ||
![]() |
bc46e4c422 | ||
![]() |
fba4067348 | ||
![]() |
e4b8674732 | ||
![]() |
bc2b5aef20 | ||
![]() |
63c36a563a | ||
![]() |
44b77505fe | ||
![]() |
62f4729b5d | ||
![]() |
e0579abf95 | ||
![]() |
8e0194b29b | ||
![]() |
3649d2842d | ||
![]() |
0ca1c07b47 | ||
![]() |
a57f4dcc81 | ||
![]() |
9c39b0b6e9 | ||
![]() |
8b141f3906 | ||
![]() |
17e07d8bc0 | ||
![]() |
13fa1c06fc | ||
![]() |
0deb29d192 | ||
![]() |
28267ee8b7 | ||
![]() |
094d3441f8 | ||
![]() |
aeec36b035 | ||
![]() |
2d0270c489 | ||
![]() |
0e0adfa0d3 | ||
![]() |
5313e6bbe3 | ||
![]() |
54789be3a1 | ||
![]() |
1675238cfd | ||
![]() |
3fbf5fb588 | ||
![]() |
95230678db | ||
![]() |
fdccafbb6e | ||
![]() |
0e8d796ee0 | ||
![]() |
0c6f2ac488 | ||
![]() |
1db97adba4 | ||
![]() |
fb8f6db383 | ||
![]() |
efd7ecef11 | ||
![]() |
4f8e12c098 | ||
![]() |
032add13e8 | ||
![]() |
0f0747e79d | ||
![]() |
0c2a758b81 | ||
![]() |
1b6d7b6fb6 | ||
![]() |
716b1e1304 | ||
![]() |
7aaf10d9ee | ||
![]() |
cc08e170f4 | ||
![]() |
6e79d6e3db | ||
![]() |
d13ac1942f | ||
![]() |
bb89f97963 | ||
![]() |
1864078d0a | ||
![]() |
f495a0321d | ||
![]() |
47371c50e9 | ||
![]() |
4f573fed06 | ||
![]() |
ff2f6e6b91 | ||
![]() |
0102c07446 | ||
![]() |
089842a7a8 | ||
![]() |
787db0612e | ||
![]() |
4ef6b56482 | ||
![]() |
f9480db177 | ||
![]() |
c9ae347dbb | ||
![]() |
56284d8081 | ||
![]() |
35ad6787f5 | ||
![]() |
ca0db0ea03 | ||
![]() |
03fcd0b3bb | ||
![]() |
35da2a2e01 | ||
![]() |
2329d9fb48 | ||
![]() |
154ca89d2e | ||
![]() |
449352f10e | ||
![]() |
7c1826332f | ||
![]() |
af2816c654 | ||
![]() |
88be287f56 | ||
![]() |
5513a5e205 | ||
![]() |
e7023fa1da | ||
![]() |
46550b6fd9 | ||
![]() |
9454999946 | ||
![]() |
7611ff348d | ||
![]() |
187cf1e88c | ||
![]() |
e1e532cff0 | ||
![]() |
dfecec4fb7 | ||
![]() |
c116f52a15 | ||
![]() |
0b0b6429e1 | ||
![]() |
f732c371a4 | ||
![]() |
04c00459a2 | ||
![]() |
5cee511ba5 | ||
![]() |
399525a994 | ||
![]() |
c075bd2719 | ||
![]() |
208b83f295 | ||
![]() |
ccb109a584 | ||
![]() |
2918913341 | ||
![]() |
a66176714d | ||
![]() |
95642a1ebb | ||
![]() |
726e06f8ef | ||
![]() |
d96fe5d997 | ||
![]() |
4ae611e5c5 | ||
![]() |
1c938490c8 | ||
![]() |
ba558db977 | ||
![]() |
bf19fa23a6 | ||
![]() |
66b77cbd0c | ||
![]() |
10bfa980b7 | ||
![]() |
9e46b4f7f7 | ||
![]() |
3bf6172534 | ||
![]() |
45581f0044 | ||
![]() |
9ebb48b57a | ||
![]() |
4e2dca3ba5 | ||
![]() |
af6bdde59a | ||
![]() |
fc1fb2b582 | ||
![]() |
883b4ccbdb | ||
![]() |
f91c9fe8b1 | ||
![]() |
3ca6b80013 | ||
![]() |
ee5ef758aa | ||
![]() |
42fe158594 | ||
![]() |
48427afe26 | ||
![]() |
5c74583cb3 | ||
![]() |
742ed362b6 | ||
![]() |
44d340e48c | ||
![]() |
2561448da0 | ||
![]() |
86cabf5ea2 | ||
![]() |
b5fc67a4f5 | ||
![]() |
0b22a52bff | ||
![]() |
da093c1609 | ||
![]() |
c634be959b | ||
![]() |
2139fa1b6f | ||
![]() |
6784c9e1ee | ||
![]() |
607d5ddbbf | ||
![]() |
d588360bfe | ||
![]() |
90f2c0c1b1 | ||
![]() |
0d6e9b7196 | ||
![]() |
8f90cc165a | ||
![]() |
75758bc65f | ||
![]() |
066e72a5fb | ||
![]() |
c23e564e67 | ||
![]() |
c0080255e3 | ||
![]() |
3a3d3a2b86 | ||
![]() |
79ef9d3fee | ||
![]() |
da4597ee22 | ||
![]() |
9f4ec1c14f | ||
![]() |
4da6e32cfe | ||
![]() |
7f1c4cb6db | ||
![]() |
939fbca781 | ||
![]() |
9ba175ae24 | ||
![]() |
f7779a6302 | ||
![]() |
05bdc91228 | ||
![]() |
6d07b6ee59 | ||
![]() |
1cf54bb5d3 | ||
![]() |
21b4a4bc7b | ||
![]() |
658f397297 | ||
![]() |
38a0c329bb | ||
![]() |
b0be21b8df | ||
![]() |
97825a1994 | ||
![]() |
13189f9e52 | ||
![]() |
2a9f067522 | ||
![]() |
ad01f6fdba | ||
![]() |
b082611680 | ||
![]() |
a36c479373 | ||
![]() |
90a4f2a326 | ||
![]() |
41ff1f2249 | ||
![]() |
b20ce84763 | ||
![]() |
875213d4a9 | ||
![]() |
71b57652f0 | ||
![]() |
834b86247e | ||
![]() |
d8d3669cb3 | ||
![]() |
940b170a31 | ||
![]() |
55b93d0734 | ||
![]() |
25ef3926d1 | ||
![]() |
4d33bd5f9c | ||
![]() |
f25e47258b | ||
![]() |
a3c4ccbde0 | ||
![]() |
b114534101 | ||
![]() |
303f064ba9 | ||
![]() |
e981e53b7f | ||
![]() |
d850ef91f7 | ||
![]() |
8701b586f3 | ||
![]() |
9b1ba9a603 | ||
![]() |
18c8a4eceb | ||
![]() |
892553a457 | ||
![]() |
50a9cc9b7b | ||
![]() |
c300d15dae | ||
![]() |
c076064636 | ||
![]() |
40526807ee | ||
![]() |
a59bf8ffcf | ||
![]() |
6821899764 | ||
![]() |
bfc49f4cff | ||
![]() |
7549e1e4b9 | ||
![]() |
2fc653d87d | ||
![]() |
273a7c1641 | ||
![]() |
905fcf74f4 | ||
![]() |
229fe310d2 | ||
![]() |
85073ea010 | ||
![]() |
e622bd9227 | ||
![]() |
003b42ec7f | ||
![]() |
0a5a862874 | ||
![]() |
1864dc5311 | ||
![]() |
1be6574035 | ||
![]() |
51bc7ab145 | ||
![]() |
b49b468c28 | ||
![]() |
8055b31e95 | ||
![]() |
c371c6f055 | ||
![]() |
7448ec4f69 | ||
![]() |
d1f3041043 | ||
![]() |
d0064d8549 | ||
![]() |
4270b9fd4b | ||
![]() |
cd07d32e58 | ||
![]() |
33ddc07d8b | ||
![]() |
1c7fbaba14 | ||
![]() |
af292f1e84 | ||
![]() |
2ddcb04986 | ||
![]() |
3ce5a2970f | ||
![]() |
d898dd09e4 | ||
![]() |
0e08afd95d | ||
![]() |
955cdc8d81 | ||
![]() |
e48cacbca5 | ||
![]() |
5aee572571 | ||
![]() |
c83cb31f5b | ||
![]() |
fea790cb66 | ||
![]() |
794c26fb9f | ||
![]() |
0f6525cd7d | ||
![]() |
28cf22057f | ||
![]() |
faedee1163 | ||
![]() |
4a7ca97de0 | ||
![]() |
cef68eee2e | ||
![]() |
40e81cc72b | ||
![]() |
4d1f5becef | ||
![]() |
c82b7e2992 | ||
![]() |
02eb5a78aa | ||
![]() |
2cee40ea93 | ||
![]() |
5b02f7c186 | ||
![]() |
2e7f228016 | ||
![]() |
8a78ebb29f | ||
![]() |
95690f9ece | ||
![]() |
97266423db | ||
![]() |
af4b210111 | ||
![]() |
2a10bef1b4 | ||
![]() |
5c45808ea0 | ||
![]() |
a82ffc67b3 | ||
![]() |
44225688bb | ||
![]() |
f144a9e6da | ||
![]() |
d08f64adf6 | ||
![]() |
2d0db8be9e | ||
![]() |
408093d9ff | ||
![]() |
a8fcc78511 | ||
![]() |
49e754c81d | ||
![]() |
3b9406ef82 | ||
![]() |
1d9d8f4a76 | ||
![]() |
6777efe3ca | ||
![]() |
2b4a057e15 | ||
![]() |
1e88b750d4 | ||
![]() |
57421690e0 | ||
![]() |
1c14cc7ff3 | ||
![]() |
54864d4c3b | ||
![]() |
8f6e85fcdf | ||
![]() |
6cd5b66101 | ||
![]() |
3729bf289f | ||
![]() |
db153baf73 | ||
![]() |
344b35fc53 | ||
![]() |
f318653745 | ||
![]() |
3415b43780 | ||
![]() |
15f38d6693 | ||
![]() |
2160c8e998 | ||
![]() |
39084f937a | ||
![]() |
22a6a7dedc | ||
![]() |
8f93691a81 | ||
![]() |
c5c7d8163f | ||
![]() |
e061de58da | ||
![]() |
6f90eecfe8 | ||
![]() |
4daaa8171d | ||
![]() |
cbff9146e3 | ||
![]() |
2d7c10954b | ||
![]() |
6e74c9dbbb | ||
![]() |
44827f39da | ||
![]() |
2ba385a5e1 | ||
![]() |
7d9358afc1 | ||
![]() |
cf03855076 | ||
![]() |
877b5ce98c | ||
![]() |
428220b7f4 | ||
![]() |
914e0223cf | ||
![]() |
b79cd45602 | ||
![]() |
19107de46c | ||
![]() |
29dd1b9c76 | ||
![]() |
dac82b0e15 | ||
![]() |
4595c4c56b | ||
![]() |
39000e536b | ||
![]() |
181ee9b66b | ||
![]() |
9053f9ea11 | ||
![]() |
8238a41032 | ||
![]() |
aaf4339aa1 | ||
![]() |
d2486b470f | ||
![]() |
e7fd9e59a4 | ||
![]() |
e3cc088a96 | ||
![]() |
72d7089b72 | ||
![]() |
e94da5a065 | ||
![]() |
a721d001dd | ||
![]() |
8af3110d4d | ||
![]() |
a351a301d2 | ||
![]() |
62a23f82b1 | ||
![]() |
ef42e5ad18 | ||
![]() |
cd1e384723 | ||
![]() |
a52f8621d2 | ||
![]() |
920856cfdd | ||
![]() |
08906b3254 | ||
![]() |
cd35eace22 | ||
![]() |
8296c33fd0 | ||
![]() |
0ad71b9855 | ||
![]() |
c98e6d20fc | ||
![]() |
2398551415 | ||
![]() |
060b3b9b03 | ||
![]() |
ff65504325 | ||
![]() |
543c1a25c6 | ||
![]() |
1be42003d7 | ||
![]() |
2325baada3 | ||
![]() |
e6ce728d79 | ||
![]() |
0b947ed818 | ||
![]() |
e8dbf6d670 | ||
![]() |
41c232aad8 | ||
![]() |
4196030939 | ||
![]() |
bbe796033e | ||
![]() |
159562dc02 | ||
![]() |
a21a533a0c | ||
![]() |
eeb169a9f9 | ||
![]() |
951140b94a | ||
![]() |
dbf0700c7a | ||
![]() |
dacbaebcaf | ||
![]() |
36ab2fe9c2 | ||
![]() |
7e3a4bac80 | ||
![]() |
dcbe9805f4 | ||
![]() |
fd73c1248c | ||
![]() |
8e79ba7ab9 | ||
![]() |
5db7b578d5 | ||
![]() |
a17e8c5252 | ||
![]() |
d1e9506b19 | ||
![]() |
1fdfe0928a | ||
![]() |
76c4d81a6a | ||
![]() |
d8904df6c5 | ||
![]() |
662c03ea61 | ||
![]() |
c8b7da7226 | ||
![]() |
249c1698c5 | ||
![]() |
17352b2176 | ||
![]() |
e8e6614779 | ||
![]() |
ad4b06d999 | ||
![]() |
b1a34eb336 | ||
![]() |
d9a6ccb099 | ||
![]() |
090eb05f17 | ||
![]() |
690bef673a | ||
![]() |
fb8d2c9c29 | ||
![]() |
bb3b39cd33 | ||
![]() |
001f56257c | ||
![]() |
57245a9721 | ||
![]() |
6ee9cdc581 | ||
![]() |
dc40835d4d | ||
![]() |
7e3122dc95 | ||
![]() |
073479583b | ||
![]() |
d76ddeeeaa | ||
![]() |
7cdc56dd7a | ||
![]() |
246636f5fa | ||
![]() |
fe0fb71961 | ||
![]() |
e60a7a9173 | ||
![]() |
81bb5d8954 | ||
![]() |
523e8b6f11 | ||
![]() |
4a0a3c4aa5 | ||
![]() |
9dfd3f686b | ||
![]() |
796ac2d08f | ||
![]() |
534262e0b2 | ||
![]() |
673189f77b | ||
![]() |
89cb9ea919 | ||
![]() |
7113206187 | ||
![]() |
926a3fd777 | ||
![]() |
de23f62d1e | ||
![]() |
afbabc4364 | ||
![]() |
eda0811ed2 | ||
![]() |
bda67fc879 | ||
![]() |
5a5d398e5f | ||
![]() |
f699bde5ad | ||
![]() |
48566bbcc2 | ||
![]() |
d68a6666be | ||
![]() |
07660d51a9 | ||
![]() |
632c84dcca | ||
![]() |
1aee3621b1 | ||
![]() |
8d335b7b7d | ||
![]() |
fd460fa3ba | ||
![]() |
5b84ed26a3 | ||
![]() |
e03c026bf4 | ||
![]() |
5704310356 | ||
![]() |
c922361eb2 | ||
![]() |
48576e6584 | ||
![]() |
79d644d1a2 | ||
![]() |
2f7246cb26 | ||
![]() |
8476756ae3 | ||
![]() |
d90c240f2a | ||
![]() |
3be651e99d | ||
![]() |
4fac98a656 | ||
![]() |
bed56b29b8 | ||
![]() |
2338e28eef | ||
![]() |
d4eb53db66 | ||
![]() |
8f777bbc0d | ||
![]() |
7d256b941a | ||
![]() |
c3ceccf9bc | ||
![]() |
c89928824f | ||
![]() |
047f654646 | ||
![]() |
0fc9663aa7 | ||
![]() |
50f623482f | ||
![]() |
2e0f79f8b6 | ||
![]() |
308cb3daf9 | ||
![]() |
f1b3c2fa8b | ||
![]() |
2f6d66af9d | ||
![]() |
ef21b84507 | ||
![]() |
c9dd6721cf | ||
![]() |
428519788b | ||
![]() |
522df62704 | ||
![]() |
d35b677f4b | ||
![]() |
b1c183b83c | ||
![]() |
7555f14f91 | ||
![]() |
bc2a793022 | ||
![]() |
a40e52b504 | ||
![]() |
c860b5c47f | ||
![]() |
2f8b80270f | ||
![]() |
d01e38ae60 | ||
![]() |
eed6844f8b | ||
![]() |
f6e73eb5b6 | ||
![]() |
3034ed7851 | ||
![]() |
34c9fcc96a | ||
![]() |
b7f1b7347f | ||
![]() |
fc4a224c47 | ||
![]() |
b86b5055c6 | ||
![]() |
c0d418d2f4 | ||
![]() |
2cd89433de | ||
![]() |
6cb2857ef0 | ||
![]() |
716bc48e21 | ||
![]() |
6afd248b18 | ||
![]() |
8e62bee92f | ||
![]() |
02ce009f42 | ||
![]() |
88a8df65a2 | ||
![]() |
5c42e98b8f | ||
![]() |
fd5abe1ac5 | ||
![]() |
088d89c918 | ||
![]() |
8299ae07ec | ||
![]() |
fd8ad0b934 | ||
![]() |
2fc6aa80df | ||
![]() |
1c26215f3f | ||
![]() |
7b1e1540e2 | ||
![]() |
02010edac3 | ||
![]() |
e4e76943d6 | ||
![]() |
569361586a | ||
![]() |
785218258b | ||
![]() |
0b45bc64c2 | ||
![]() |
17f3fec1ed | ||
![]() |
52dbf3e3cf | ||
![]() |
0a814e4372 | ||
![]() |
fc63326544 | ||
![]() |
18bacaab15 | ||
![]() |
e8f12786b4 | ||
![]() |
8789204f97 | ||
![]() |
819fb64520 | ||
![]() |
31003b45e6 | ||
![]() |
1f04b16682 | ||
![]() |
0a8b04e3e3 | ||
![]() |
f8b4039d96 | ||
![]() |
6da496e2f9 | ||
![]() |
68d38a3f16 | ||
![]() |
0e8eddfd8c | ||
![]() |
3645cf9fc3 | ||
![]() |
a0585ff990 | ||
![]() |
ec3a2a3b3b | ||
![]() |
24e2a6fb86 | ||
![]() |
1144bc6587 | ||
![]() |
fa84d9471e | ||
![]() |
71dfd0dc2e | ||
![]() |
b941520afb | ||
![]() |
be110124f6 | ||
![]() |
927363397d | ||
![]() |
9dc097cfe5 | ||
![]() |
e3b0c8a681 | ||
![]() |
a62be95af3 | ||
![]() |
a2e707696a | ||
![]() |
f267068b02 | ||
![]() |
7f0849be06 | ||
![]() |
87697c0dca | ||
![]() |
0acc1c308e | ||
![]() |
312a3d8003 | ||
![]() |
701bae514b | ||
![]() |
8bffb974e4 | ||
![]() |
d4e6e22e93 | ||
![]() |
1e9cd5f299 | ||
![]() |
29022e81a4 | ||
![]() |
6b028b6303 | ||
![]() |
f76208237d | ||
![]() |
b61db7817f | ||
![]() |
6a48a0a018 | ||
![]() |
3415802ae9 | ||
![]() |
20a19b977f | ||
![]() |
10228bf07b | ||
![]() |
24ac45c74e | ||
![]() |
85c8b8252f | ||
![]() |
948fd1aec0 | ||
![]() |
213a6fbf71 | ||
![]() |
c089e392a9 | ||
![]() |
387fa91a19 | ||
![]() |
bde04d3ec6 | ||
![]() |
ce7dceac93 | ||
![]() |
18832c2f0d | ||
![]() |
3fdcd6b1fa | ||
![]() |
2b564ea543 | ||
![]() |
6b62acfc40 | ||
![]() |
62411c0bbf | ||
![]() |
c10ebdc85f | ||
![]() |
1b00b76bc1 | ||
![]() |
8ffb34e4db | ||
![]() |
81ce706243 | ||
![]() |
a96679dfee | ||
![]() |
0c659577d4 | ||
![]() |
ea41e77287 | ||
![]() |
ca51c3f430 | ||
![]() |
5716c6246f | ||
![]() |
f6edf885b4 | ||
![]() |
4acaa728bb | ||
![]() |
331d2daf96 | ||
![]() |
174b246d44 | ||
![]() |
0bf83955a9 | ||
![]() |
69c6091ee4 | ||
![]() |
cf02ab960f | ||
![]() |
b50d1ab2d1 | ||
![]() |
ba9054e8d5 | ||
![]() |
7e9cc01c54 | ||
![]() |
0f52c861db | ||
![]() |
920e7b9ae1 | ||
![]() |
b8e577a274 | ||
![]() |
fc3c551a67 | ||
![]() |
797a722244 | ||
![]() |
44790ad9d8 | ||
![]() |
73d266fe29 | ||
![]() |
e1ddf02aff | ||
![]() |
66d62c97d5 | ||
![]() |
d44a61ef33 | ||
![]() |
ef59201f02 | ||
![]() |
f5439803c2 | ||
![]() |
a0a0be0376 | ||
![]() |
48ce5846c9 | ||
![]() |
de0eba3279 | ||
![]() |
bc262c2f61 | ||
![]() |
d4389f0f4f | ||
![]() |
79984462e1 | ||
![]() |
c6dcc2a013 | ||
![]() |
e6dde3c065 | ||
![]() |
39283171ce | ||
![]() |
33288d37e7 | ||
![]() |
b60277dde9 | ||
![]() |
68b429ddc6 | ||
![]() |
ec0b6d0e4c | ||
![]() |
e3ea6b7948 | ||
![]() |
8c8be234b2 | ||
![]() |
029d6cd6b8 | ||
![]() |
8fc95ea175 | ||
![]() |
3e2a2ce2d0 | ||
![]() |
4aebdafc0b | ||
![]() |
2aadab2297 | ||
![]() |
2a968ff601 | ||
![]() |
ef327f98b5 | ||
![]() |
5c1cab8429 | ||
![]() |
60e7ac7c28 | ||
![]() |
fe91ab72f6 | ||
![]() |
cc23ede837 | ||
![]() |
76dc7bcd3f | ||
![]() |
c7072f0969 | ||
![]() |
032079bf7f | ||
![]() |
21ccb43669 | ||
![]() |
038a51af80 | ||
![]() |
a5f4b54b5f | ||
![]() |
61e9ed7dab | ||
![]() |
c6c396f2fe | ||
![]() |
7f05b89187 | ||
![]() |
139cb86a77 | ||
![]() |
97365f6cd2 | ||
![]() |
1f20fb83f0 | ||
![]() |
51647add79 | ||
![]() |
6c6532459a | ||
![]() |
f53b75ef58 | ||
![]() |
732c1a14e7 | ||
![]() |
3ab0d43f2c | ||
![]() |
de17e6cdf2 | ||
![]() |
c7bb50a40c | ||
![]() |
fe12e8f13f | ||
![]() |
87e23c4c79 | ||
![]() |
2f49eb9ee1 | ||
![]() |
00b3d3d9e7 | ||
![]() |
19193bdb26 | ||
![]() |
d12b5fc2ab | ||
![]() |
338f354106 | ||
![]() |
626a6b7213 | ||
![]() |
090f90127a | ||
![]() |
598640f3be | ||
![]() |
7ee3290f25 | ||
![]() |
e9eccdd473 | ||
![]() |
6dc8c796c9 | ||
![]() |
d1028b2eb8 | ||
![]() |
0e24cebad0 | ||
![]() |
d8f8ad9a74 | ||
![]() |
47a703e935 | ||
![]() |
742b6417b4 | ||
![]() |
af9376f801 | ||
![]() |
adaff22ded | ||
![]() |
2cd4de3431 | ||
![]() |
b199521773 | ||
![]() |
aecc5ebeee | ||
![]() |
630aa37bbd | ||
![]() |
c060576a37 | ||
![]() |
54849deb96 | ||
![]() |
034e423c9c | ||
![]() |
89c31817b2 | ||
![]() |
e42f43b67b | ||
![]() |
6fdb8b53b3 | ||
![]() |
3323f78bb4 | ||
![]() |
fe20777b56 | ||
![]() |
89890d6f77 | ||
![]() |
927a8c5ba3 | ||
![]() |
5e7542fc4b | ||
![]() |
bb3376162b | ||
![]() |
6d350523ea | ||
![]() |
8838901b21 | ||
![]() |
eb59803836 | ||
![]() |
bdf73bf6ae | ||
![]() |
4cddd28d4b | ||
![]() |
89f014aed9 | ||
![]() |
4904bb2843 | ||
![]() |
13e016d7c4 | ||
![]() |
709c71af5f | ||
![]() |
8c58d60f5b | ||
![]() |
e6e128a1c4 | ||
![]() |
358ff4f347 | ||
![]() |
ec1e14cf27 | ||
![]() |
7d7c69556b | ||
![]() |
cb82bb7325 | ||
![]() |
07e161e47f | ||
![]() |
2106eb4457 | ||
![]() |
4afe0ab671 | ||
![]() |
5768dd7d22 | ||
![]() |
648f9c1aaf | ||
![]() |
e5efec47f6 | ||
![]() |
d6d7cb291e | ||
![]() |
5817a9efb0 | ||
![]() |
33d50af03f | ||
![]() |
a4cd522ee2 | ||
![]() |
a553a029f5 | ||
![]() |
faa5db4b1d | ||
![]() |
63f203d400 | ||
![]() |
fd5b3a411d | ||
![]() |
c4a394a9cf | ||
![]() |
50ae49b0e4 | ||
![]() |
588d46e858 | ||
![]() |
bdeaa9108c | ||
![]() |
4d8812d205 | ||
![]() |
668fd3a713 | ||
![]() |
b952f3beb3 | ||
![]() |
ce8bc5d49a | ||
![]() |
9ff3603359 | ||
![]() |
54479c37f5 | ||
![]() |
6d89069134 | ||
![]() |
3bbaba4ae7 | ||
![]() |
18c62c592a | ||
![]() |
c39b06f825 | ||
![]() |
4c2f8eda37 | ||
![]() |
2c8123e91e | ||
![]() |
e1754a427f | ||
![]() |
f573054697 | ||
![]() |
c3c3db7fee | ||
![]() |
480e87dd66 | ||
![]() |
7fcd53ac00 | ||
![]() |
749fe3bb28 | ||
![]() |
d7af20bab3 | ||
![]() |
690b721958 | ||
![]() |
77f9e6c7c6 | ||
![]() |
c82a34e7e5 | ||
![]() |
7a1c64e8b1 | ||
![]() |
71290f02ff | ||
![]() |
ecf455a884 | ||
![]() |
432e0c810c | ||
![]() |
fcdeb5b3d7 | ||
![]() |
01e83d6024 | ||
![]() |
c706c70eed | ||
![]() |
d4f86e9d16 | ||
![]() |
d9105a4631 | ||
![]() |
0621d936c0 | ||
![]() |
024cd58ac6 | ||
![]() |
c9a1c56f6d | ||
![]() |
54a8c99a03 | ||
![]() |
9bf09145c3 | ||
![]() |
c25c77a67a | ||
![]() |
ea90b5ced9 | ||
![]() |
d144c0c92d | ||
![]() |
341b80da8b | ||
![]() |
6cf9c8246e | ||
![]() |
955946132d | ||
![]() |
1f2cb3b00f | ||
![]() |
c9124514c3 | ||
![]() |
90ef0b1b22 | ||
![]() |
c648759d89 | ||
![]() |
b9ea510e42 | ||
![]() |
174a2a6360 | ||
![]() |
2d0b52f440 | ||
![]() |
d0e3a7c3aa | ||
![]() |
2c6893c21a | ||
![]() |
17ca5bb3e5 | ||
![]() |
61845c2b19 | ||
![]() |
417f924dea | ||
![]() |
c51a48d4f6 | ||
![]() |
a625ca325f | ||
![]() |
752970edd0 | ||
![]() |
7b64c76932 | ||
![]() |
6d9ee62035 | ||
![]() |
b27dcc252a | ||
![]() |
b60e479cea | ||
![]() |
ab8493166b | ||
![]() |
9333a5cf0c | ||
![]() |
8ec721eb3b | ||
![]() |
7d1d4d2cce | ||
![]() |
fb20f4d248 | ||
![]() |
b2a0ba40a4 | ||
![]() |
c467712045 | ||
![]() |
f41e41fa3f | ||
![]() |
f490eeaa59 | ||
![]() |
37e5be95e2 | ||
![]() |
e208eb429a | ||
![]() |
c784b6f1c4 | ||
![]() |
6dc4095801 | ||
![]() |
a522bdb715 | ||
![]() |
07e0177b72 | ||
![]() |
fee9327009 | ||
![]() |
f991633730 | ||
![]() |
1fc4377f03 | ||
![]() |
353ea22e6f | ||
![]() |
cdf9afcec8 | ||
![]() |
f58fe58af9 | ||
![]() |
9ab423063b | ||
![]() |
b8dd3a1a06 | ||
![]() |
6e4b6b77a3 | ||
![]() |
b13786805a | ||
![]() |
7c72320404 | ||
![]() |
763a7bfbb5 | ||
![]() |
c789aecfa6 | ||
![]() |
1aae16084a | ||
![]() |
a593948c90 | ||
![]() |
96134b7430 | ||
![]() |
5d2fcdb4cb | ||
![]() |
c0a8bcfa6a | ||
![]() |
4bc117de0c | ||
![]() |
47db5bd435 | ||
![]() |
eeb5a258f5 | ||
![]() |
5436326dcf | ||
![]() |
9ecc6e7fe2 | ||
![]() |
72cf8893fc | ||
![]() |
28d6f2964c | ||
![]() |
8c9ee56d01 | ||
![]() |
5978e5a2df | ||
![]() |
ab45871481 | ||
![]() |
17c3e9e98f | ||
![]() |
c9dcbc3147 | ||
![]() |
aa54931d1d | ||
![]() |
3f7b5c900b | ||
![]() |
161a189eb5 | ||
![]() |
a48618a94b | ||
![]() |
2bdfc0c60d | ||
![]() |
cf4fe8759a | ||
![]() |
58c7ce2add | ||
![]() |
61316fda76 | ||
![]() |
5d38ef5289 | ||
![]() |
51330c5719 | ||
![]() |
7b92155d7a | ||
![]() |
3127174fab | ||
![]() |
cfdaf8f14e | ||
![]() |
043929ee8f | ||
![]() |
96fd19710a | ||
![]() |
4e2535f2b3 | ||
![]() |
449a845ff2 | ||
![]() |
777b2b437a | ||
![]() |
2fafe0a734 | ||
![]() |
bc88d8bc95 | ||
![]() |
fd2b77dd74 | ||
![]() |
652648acb4 | ||
![]() |
8a36220d04 | ||
![]() |
04de9221b6 | ||
![]() |
9ad1a5b96a | ||
![]() |
88fb02bd31 | ||
![]() |
c798a4ea57 | ||
![]() |
e82d3911ce | ||
![]() |
de2b6e43f7 | ||
![]() |
25eaddf37a | ||
![]() |
77f872a759 | ||
![]() |
abef388dd9 | ||
![]() |
30e1bb07d4 | ||
![]() |
9fdfe4cf16 | ||
![]() |
024242fc77 | ||
![]() |
ecdfb9c92e | ||
![]() |
1c2673b763 | ||
![]() |
4e23a965c8 | ||
![]() |
53c377a374 | ||
![]() |
9d2dd83a01 | ||
![]() |
1cf8e0a600 | ||
![]() |
fd208a9313 | ||
![]() |
11b14aea27 | ||
![]() |
088aefc16a | ||
![]() |
be61785609 | ||
![]() |
413fd78918 | ||
![]() |
7bbc71bb94 | ||
![]() |
f569b77fb1 | ||
![]() |
c22c36bf00 | ||
![]() |
3c03080dbf | ||
![]() |
48979870c0 | ||
![]() |
32778a6046 | ||
![]() |
8873eb78c3 | ||
![]() |
82d64d32b4 | ||
![]() |
96d3f739bc | ||
![]() |
6d0aacb114 | ||
![]() |
8f25d07e2f | ||
![]() |
a16f162810 | ||
![]() |
5fce9894a2 | ||
![]() |
4ea8e08f69 | ||
![]() |
3fb71100b1 | ||
![]() |
b2d17f5124 | ||
![]() |
fede43944f | ||
![]() |
8f7c87ffda | ||
![]() |
4a0aac0d19 | ||
![]() |
a611c48932 | ||
![]() |
ce810b29b2 | ||
![]() |
4e5d0fad4d | ||
![]() |
fea1ca3c21 | ||
![]() |
df0c101b3f | ||
![]() |
7ecfc6730d | ||
![]() |
8b07761656 | ||
![]() |
e45cb98580 | ||
![]() |
87380821bf | ||
![]() |
b109d83a62 | ||
![]() |
b109d82bbf | ||
![]() |
5c78c9fe10 | ||
![]() |
2f5a1b0ae2 | ||
![]() |
0302ff21cd | ||
![]() |
79adacd43e | ||
![]() |
b3ee2eb875 | ||
![]() |
6e426e6495 | ||
![]() |
5e2d64b30d | ||
![]() |
3bac490b9e | ||
![]() |
3f253380d0 | ||
![]() |
ed3a233c12 | ||
![]() |
5e30988ccd | ||
![]() |
eca4cad8f9 | ||
![]() |
e085286c32 | ||
![]() |
ba19ff432d | ||
![]() |
469d60a2c7 | ||
![]() |
86476f23a6 | ||
![]() |
72539bec37 | ||
![]() |
123f9a4d0d | ||
![]() |
b77f2d8f69 | ||
![]() |
51fd453fbc | ||
![]() |
b5633a53cb | ||
![]() |
355089dca8 | ||
![]() |
6cda158eaa | ||
![]() |
08cde2a468 | ||
![]() |
e9b5807e92 | ||
![]() |
d372d0971f | ||
![]() |
db5dd7c176 | ||
![]() |
1e674fcfac | ||
![]() |
c3e1f46ee4 | ||
![]() |
be8e4c86e6 | ||
![]() |
bff90b7e3b | ||
![]() |
a95a008d18 | ||
![]() |
07f86bcdc4 | ||
![]() |
3a3ec498d8 | ||
![]() |
ee137444f0 | ||
![]() |
cda2902303 | ||
![]() |
986ad9c20c | ||
![]() |
c39d6d3f14 | ||
![]() |
71cf20e50d | ||
![]() |
ac6318196f | ||
![]() |
8d86a18fbc | ||
![]() |
3d6f7aa7fe | ||
![]() |
0bf905f9c5 | ||
![]() |
f973319839 | ||
![]() |
edebe24d1f | ||
![]() |
9328bab880 | ||
![]() |
ad99acc982 | ||
![]() |
8c92f21e68 | ||
![]() |
4bcd0bbcf8 | ||
![]() |
6b1da8ffbd | ||
![]() |
4e680e146a | ||
![]() |
c8fb92cb80 | ||
![]() |
32a737ef81 | ||
![]() |
03d80c561a | ||
![]() |
d5cbe0076a | ||
![]() |
e3cd18048c | ||
![]() |
1d1543af8c | ||
![]() |
172ae47338 | ||
![]() |
bd376fbcfa | ||
![]() |
93b782be1f | ||
![]() |
10b3f59625 | ||
![]() |
53acb3010e | ||
![]() |
3032ed1238 | ||
![]() |
84ed30e2f4 | ||
![]() |
6961203862 | ||
![]() |
1837ef5578 | ||
![]() |
74b06cafc9 | ||
![]() |
74b3be4bf5 | ||
![]() |
5ce975c602 | ||
![]() |
89c8821949 | ||
![]() |
bd5870c212 | ||
![]() |
570b202ee2 | ||
![]() |
7a453ffa2e | ||
![]() |
04124efe75 | ||
![]() |
6f22f2f9ba | ||
![]() |
3ee6abf610 | ||
![]() |
e26c03691d | ||
![]() |
fa4776dd71 | ||
![]() |
379de7170f | ||
![]() |
23ffa77dee | ||
![]() |
fdbd13bcad | ||
![]() |
23e3c4300c | ||
![]() |
063e674726 | ||
![]() |
62102d8eaa | ||
![]() |
5a331a4999 | ||
![]() |
89cf313699 | ||
![]() |
e0e0326cc5 | ||
![]() |
ca6650c514 | ||
![]() |
bda7fb2353 | ||
![]() |
74338865c1 | ||
![]() |
b477871310 | ||
![]() |
598d24527e | ||
![]() |
6498ab1ae4 | ||
![]() |
8aea4cfc19 | ||
![]() |
55362b9d1b | ||
![]() |
e47c489b15 | ||
![]() |
5e3c67ab60 | ||
![]() |
3253948ff2 | ||
![]() |
0e4863b3a2 | ||
![]() |
10999da6dc | ||
![]() |
07dba6b85d | ||
![]() |
ab710fb168 | ||
![]() |
cec01b8d1d | ||
![]() |
8efe373530 | ||
![]() |
123da80395 | ||
![]() |
ab5069cbb1 | ||
![]() |
eebd3f0a07 | ||
![]() |
a2ffc56365 | ||
![]() |
58afb05fef | ||
![]() |
fe5db36271 | ||
![]() |
5982c92676 | ||
![]() |
4d6ed243ff | ||
![]() |
adb9fa830d | ||
![]() |
73246a42b0 | ||
![]() |
65a49b917f | ||
![]() |
5e8b123b3d | ||
![]() |
6164e1cd7f | ||
![]() |
4dc0f1f904 | ||
![]() |
b4d152a6a5 | ||
![]() |
f0fc230482 | ||
![]() |
cb2d527650 | ||
![]() |
68f10de3ea | ||
![]() |
d5414fd30b | ||
![]() |
608b7f81de | ||
![]() |
a4b2b85206 | ||
![]() |
adde7bbfea | ||
![]() |
85bd8694a9 | ||
![]() |
4dce8843f8 | ||
![]() |
7f2aa19bdc | ||
![]() |
4ffc815953 | ||
![]() |
210cc839c2 | ||
![]() |
2c684aedfa | ||
![]() |
2703edcc41 | ||
![]() |
1a3ea1d324 | ||
![]() |
db3ea27a0c | ||
![]() |
fc6ac10d4c | ||
![]() |
08f351ba16 | ||
![]() |
aae4005247 | ||
![]() |
eb97e78971 | ||
![]() |
35d9bb6ce9 | ||
![]() |
ce8c198347 | ||
![]() |
1982157b6c | ||
![]() |
dddfbd694c | ||
![]() |
41ed98fdd5 | ||
![]() |
966bc5f420 | ||
![]() |
ddcadfd11d | ||
![]() |
299748b520 | ||
![]() |
57d9664f8e | ||
![]() |
653adcf614 | ||
![]() |
019dd18a51 | ||
![]() |
235067705e | ||
![]() |
f487fc6c7b | ||
![]() |
0953088baa | ||
![]() |
ddc065bac8 | ||
![]() |
82b26d6c01 | ||
![]() |
c54e638a31 | ||
![]() |
e7bcef0f0b | ||
![]() |
6f8a32e362 | ||
![]() |
0562b9f865 | ||
![]() |
be519638b0 | ||
![]() |
596fc641d0 | ||
![]() |
c0c2634976 | ||
![]() |
5ac4c9fe42 | ||
![]() |
93ae7c6b6a | ||
![]() |
ca8881ae34 | ||
![]() |
487675b843 | ||
![]() |
988322a381 | ||
![]() |
30649ae7e0 | ||
![]() |
52c733bd7b | ||
![]() |
e6a750f507 | ||
![]() |
b1a4c25c63 | ||
![]() |
15be594e99 | ||
![]() |
5af8560e3b | ||
![]() |
ef3b39a58e | ||
![]() |
a7850c2ddb | ||
![]() |
9a6dabf8d1 | ||
![]() |
4f9f822a4a | ||
![]() |
e5ceb2cea2 | ||
![]() |
238f44e1cf | ||
![]() |
dc4c7d50aa | ||
![]() |
ebf889a3b1 | ||
![]() |
45c8d9cb88 | ||
![]() |
19b584354a | ||
![]() |
7839ede089 | ||
![]() |
15cb0ce053 | ||
![]() |
c50c1e0f0c | ||
![]() |
b6c440bf6f | ||
![]() |
c2296c1b04 | ||
![]() |
bacda0ec4f | ||
![]() |
ea251d4d2f | ||
![]() |
41e8587ad1 | ||
![]() |
6159d43b91 | ||
![]() |
83eb7d0871 | ||
![]() |
e80b1c7e65 | ||
![]() |
4c09115926 | ||
![]() |
3f78288717 | ||
![]() |
1d1287f9fa | ||
![]() |
613e474ee0 | ||
![]() |
8125192be8 | ||
![]() |
d5d55864de | ||
![]() |
508ea1fe11 | ||
![]() |
dbfd5e10a7 | ||
![]() |
4ca6f666de | ||
![]() |
20abff4daa | ||
![]() |
011c918754 | ||
![]() |
71a44a5c8c | ||
![]() |
42b8312161 | ||
![]() |
99639db2ad | ||
![]() |
392359fc8c | ||
![]() |
b4afd867a1 | ||
![]() |
171fd357a8 | ||
![]() |
232c8a3b69 | ||
![]() |
8fb979df89 | ||
![]() |
7f33882a12 | ||
![]() |
8aef40ac80 | ||
![]() |
7fcaecbe85 | ||
![]() |
8bb2cb2854 | ||
![]() |
088336658d | ||
![]() |
57f3d32fad | ||
![]() |
d09f11f8d0 | ||
![]() |
7e8d87b891 | ||
![]() |
ee6a0bc6dc | ||
![]() |
1d8a2f9137 | ||
![]() |
8a5f6280e6 | ||
![]() |
61648e78ea | ||
![]() |
2693e63ae2 | ||
![]() |
ed82d95e3a | ||
![]() |
0626c3f940 | ||
![]() |
83952deb06 | ||
![]() |
c4bb28b25e | ||
![]() |
a2b1e5dbb9 | ||
![]() |
349b9cd596 | ||
![]() |
565ad867fa | ||
![]() |
d984765c3c | ||
![]() |
f25e6fe945 | ||
![]() |
110b9baa5f | ||
![]() |
d2f7657e17 | ||
![]() |
a5b3ab3adf | ||
![]() |
b04bee68cb | ||
![]() |
5a415cfa17 | ||
![]() |
dac1573a9f | ||
![]() |
2cb89c14f8 | ||
![]() |
0c11739343 | ||
![]() |
a8f275909b | ||
![]() |
78e918f749 | ||
![]() |
e20f763562 | ||
![]() |
aa677d9200 | ||
![]() |
c763fb03d9 | ||
![]() |
e92019659f | ||
![]() |
42fb35e835 | ||
![]() |
75ea265d3a | ||
![]() |
88a778c8d7 | ||
![]() |
2f66d3becc | ||
![]() |
9ca5762164 | ||
![]() |
4f51d4bdf2 | ||
![]() |
3599672c90 | ||
![]() |
2b31ed904d | ||
![]() |
5db646f3d5 | ||
![]() |
f1df99fa1d | ||
![]() |
e5cb100651 | ||
![]() |
5375720ffa | ||
![]() |
4311e06ffd | ||
![]() |
f8e9251aac | ||
![]() |
b1478017f4 | ||
![]() |
1a70916518 | ||
![]() |
1bfae76e44 | ||
![]() |
85368c0a27 | ||
![]() |
901681a010 | ||
![]() |
3787560a3d | ||
![]() |
a64becde5e | ||
![]() |
d6db5b61d1 | ||
![]() |
3d674ed245 | ||
![]() |
aa0a3c1ae1 | ||
![]() |
d5e31f6bc1 | ||
![]() |
211879e6d9 | ||
![]() |
b75f6c0571 | ||
![]() |
4f1ac0562f | ||
![]() |
f8f2961361 | ||
![]() |
ce4b8e3cba | ||
![]() |
ebdb5eac17 | ||
![]() |
a4150e3d36 | ||
![]() |
4f56809937 | ||
![]() |
a377d0ea43 | ||
![]() |
483c5e735d | ||
![]() |
ba522dd664 | ||
![]() |
10aaa531b8 | ||
![]() |
394fc25d46 | ||
![]() |
76855a1bbe | ||
![]() |
6758393645 | ||
![]() |
4837447a0b | ||
![]() |
78ac3f4d78 | ||
![]() |
c3ab8f3936 | ||
![]() |
e070e451a6 | ||
![]() |
f701d66cbd | ||
![]() |
acd99f22a7 | ||
![]() |
41bac1e2f7 | ||
![]() |
c1b58174f0 | ||
![]() |
160c1dacc6 | ||
![]() |
550a972358 | ||
![]() |
6114375387 | ||
![]() |
db14f52900 | ||
![]() |
7dd55804cf | ||
![]() |
e8733f64fa | ||
![]() |
2e7b724f9a | ||
![]() |
996300de86 | ||
![]() |
9bb7d28e70 | ||
![]() |
d574e2b818 | ||
![]() |
dccc349e98 | ||
![]() |
d4e4d24f9c | ||
![]() |
b78225f7de | ||
![]() |
6384aa7d7f | ||
![]() |
e034ba961f | ||
![]() |
40f3d5695f | ||
![]() |
8c727bef3c | ||
![]() |
7330323a2d | ||
![]() |
2b49b75dcb | ||
![]() |
a98e4d3169 | ||
![]() |
ca4840ce6a | ||
![]() |
0a3cc94baa | ||
![]() |
237b05158c | ||
![]() |
7f75cdb504 | ||
![]() |
4bf8a029f7 | ||
![]() |
4b6b8eb9e7 | ||
![]() |
fd3e44b556 | ||
![]() |
1d0bc9880c | ||
![]() |
9f3cd20ba2 | ||
![]() |
19e86cc60b | ||
![]() |
ca30b8500a | ||
![]() |
bdfc50c467 | ||
![]() |
aabcbcc882 | ||
![]() |
6cf9a958b7 | ||
![]() |
61361b9cde | ||
![]() |
4d1ed48b49 | ||
![]() |
58ffe6f792 | ||
![]() |
0dbccaa808 | ||
![]() |
f195837047 | ||
![]() |
bfbf803f41 | ||
![]() |
07a1f5a723 | ||
![]() |
427b9f931d | ||
![]() |
3472a62032 | ||
![]() |
f62204d4c7 | ||
![]() |
19ecae980a | ||
![]() |
8a2dbf5570 | ||
![]() |
1d0a36c98e | ||
![]() |
760335a2f5 | ||
![]() |
70d6677420 | ||
![]() |
c789451909 | ||
![]() |
6e62cd44dc | ||
![]() |
82d305f9fa | ||
![]() |
183a9ec343 | ||
![]() |
3b6c057cd8 | ||
![]() |
e2b21be3d2 | ||
![]() |
a7b70fa84d | ||
![]() |
7a06bb7247 | ||
![]() |
9dc80210cf | ||
![]() |
a1a2be24bd | ||
![]() |
bb675e1715 | ||
![]() |
9e0389c5ae | ||
![]() |
9b3a93a0c1 | ||
![]() |
a991e1d22a | ||
![]() |
0df8efd4d7 | ||
![]() |
4f64429e8b | ||
![]() |
a73691148f | ||
![]() |
cd8e421366 | ||
![]() |
32a46ba6ba | ||
![]() |
0e4974f191 | ||
![]() |
4f939f8e80 | ||
![]() |
2405ae6c59 | ||
![]() |
49ac42e025 | ||
![]() |
9cac2f8ea1 | ||
![]() |
6497e8ef99 | ||
![]() |
1ae6035162 | ||
![]() |
8b8c347ee9 | ||
![]() |
bd4ca4c445 | ||
![]() |
2a28c9bb7d | ||
![]() |
5f902276c1 | ||
![]() |
73401b8f0b | ||
![]() |
fa300c6aa4 | ||
![]() |
79fbc9646d | ||
![]() |
eaffc06f9c | ||
![]() |
d14a55854a | ||
![]() |
01588a88f3 | ||
![]() |
c3a1d0574b | ||
![]() |
0358232251 | ||
![]() |
5bc868d5b5 | ||
![]() |
a1893f84b3 | ||
![]() |
44d49bc228 | ||
![]() |
3f1e44af6c | ||
![]() |
d9be0ccb5e | ||
![]() |
ff10d2fbc5 | ||
![]() |
8fb90ed7f6 | ||
![]() |
474e3bd363 | ||
![]() |
b2902f40b3 | ||
![]() |
17ae17127c | ||
![]() |
65dc0e47e9 | ||
![]() |
ba5abef332 | ||
![]() |
84dcdf586d | ||
![]() |
74dc2e8a78 | ||
![]() |
a817eeece0 | ||
![]() |
b120be5d01 | ||
![]() |
626ad8da53 | ||
![]() |
8356a01788 | ||
![]() |
a84c8f54f9 | ||
![]() |
a4f296d02e | ||
![]() |
33eef1b0ed | ||
![]() |
ae2404f72e | ||
![]() |
3f045143ec | ||
![]() |
0707f1b441 | ||
![]() |
fbc9b61579 | ||
![]() |
ac602e39b8 | ||
![]() |
ef32360b2d | ||
![]() |
4b60d05705 | ||
![]() |
385d98db73 | ||
![]() |
8c766cffe7 | ||
![]() |
00cc8e59b9 | ||
![]() |
56a1ce212a | ||
![]() |
baaf598b46 | ||
![]() |
15519b6a6f | ||
![]() |
e9a054c870 | ||
![]() |
ed7adeaf22 | ||
![]() |
703a319222 | ||
![]() |
e6fbdde201 | ||
![]() |
860dc31320 | ||
![]() |
fd5d6c3a2d | ||
![]() |
77fbd5a18c | ||
![]() |
aba4e5712b | ||
![]() |
c3642c4a1c | ||
![]() |
0a207fd892 | ||
![]() |
2a74e5e5d4 | ||
![]() |
6e85a3501a | ||
![]() |
660db6c787 | ||
![]() |
a4d22acb20 | ||
![]() |
984b4ca567 | ||
![]() |
477b380579 | ||
![]() |
a699a3be4a | ||
![]() |
3a46c048f7 | ||
![]() |
d78a469ec7 | ||
![]() |
0d9ec12402 | ||
![]() |
7e929625a3 | ||
![]() |
c09cd8795d | ||
![]() |
67482da9c0 | ||
![]() |
ef8591de30 | ||
![]() |
f282e19e52 | ||
![]() |
a20b263d03 | ||
![]() |
69b90fbdbe | ||
![]() |
2cf3132a60 | ||
![]() |
dc7365b27b | ||
![]() |
d8b80b3b09 | ||
![]() |
33d8d67443 | ||
![]() |
9f74b8c9e2 | ||
![]() |
17ce62043e | ||
![]() |
896db63e40 | ||
![]() |
467f657e76 | ||
![]() |
efaec6dced | ||
![]() |
5adea4114e | ||
![]() |
02a5f95a79 | ||
![]() |
91e0894f3f | ||
![]() |
20cff0223e | ||
![]() |
8a4cc4fbd6 | ||
![]() |
d372997c45 | ||
![]() |
a0b9b1e5a9 | ||
![]() |
88defd04db | ||
![]() |
e428e21b89 | ||
![]() |
b383c47099 | ||
![]() |
a262e55d0d | ||
![]() |
637cb57c28 | ||
![]() |
65688ba5c8 | ||
![]() |
63f38f9f41 | ||
![]() |
3d46931839 | ||
![]() |
3840bc84e6 | ||
![]() |
1c9a614a4f | ||
![]() |
d127e35180 | ||
![]() |
386cb933d4 | ||
![]() |
54b7c1b8d2 | ||
![]() |
967c8a0609 | ||
![]() |
6093777a38 | ||
![]() |
bf3ca40593 | ||
![]() |
0951b64836 | ||
![]() |
32c707316b | ||
![]() |
f08344bfbc | ||
![]() |
bcd97d2870 | ||
![]() |
e54a2423a8 | ||
![]() |
3c938dc216 | ||
![]() |
80e364a5d0 | ||
![]() |
120c425db7 | ||
![]() |
df466ccd7d | ||
![]() |
0a5b7c6ec0 | ||
![]() |
08d0cedfea | ||
![]() |
5abef67e95 | ||
![]() |
ba788ed4ee | ||
![]() |
e883d3fc1b | ||
![]() |
7f3332eb99 | ||
![]() |
28638a0d9b | ||
![]() |
0686733297 | ||
![]() |
8a7336fb6f | ||
![]() |
bf097488b7 | ||
![]() |
fad01cd373 | ||
![]() |
5b0b92e859 | ||
![]() |
dc7e117725 | ||
![]() |
f4f55124a4 | ||
![]() |
b86dc28fcb | ||
![]() |
c6cd9a4c8b | ||
![]() |
62974b6c9c | ||
![]() |
f76843a802 | ||
![]() |
fb362d4f10 | ||
![]() |
3996bc3fde | ||
![]() |
7b68fcd082 | ||
![]() |
c8dc4b69b8 | ||
![]() |
0265ed819d | ||
![]() |
96ce8da4f6 | ||
![]() |
2ed48aa52f | ||
![]() |
434c3eaa98 | ||
![]() |
0efacabbb5 | ||
![]() |
61fac4da4b | ||
![]() |
6ea66cc129 | ||
![]() |
30b9252953 | ||
![]() |
3b10cebd3d | ||
![]() |
171e4353ac | ||
![]() |
1882e2f481 | ||
![]() |
0c4c0c47b8 | ||
![]() |
fe3a37012f | ||
![]() |
fe47f7dc4c | ||
![]() |
61e93c8aeb | ||
![]() |
73e225f69c | ||
![]() |
ef0a29048c | ||
![]() |
e447432ead | ||
![]() |
4203489288 | ||
![]() |
e7e332ee69 | ||
![]() |
1bf2487713 | ||
![]() |
07952792bb | ||
![]() |
3e827ae4d1 | ||
![]() |
839d5701db | ||
![]() |
3ebdc42d8b | ||
![]() |
747f9e656c | ||
![]() |
9d429cc7ac | ||
![]() |
b04424611d | ||
![]() |
4f5723a9fe | ||
![]() |
d362fea453 | ||
![]() |
22ede94fe5 | ||
![]() |
94e6fba8d8 | ||
![]() |
61fb39f691 | ||
![]() |
9478e36442 | ||
![]() |
e6bd87aabe | ||
![]() |
443b6c32e7 | ||
![]() |
56a01f8a9e | ||
![]() |
2e4e636392 | ||
![]() |
c21087a6bb | ||
![]() |
ac07453ae9 | ||
![]() |
43835a2749 | ||
![]() |
36f5714273 | ||
![]() |
d48d7b71f5 | ||
![]() |
b82208d0c1 | ||
![]() |
9f7a99a9af | ||
![]() |
a37f1b1575 | ||
![]() |
3dbb79f467 | ||
![]() |
44220f8c89 | ||
![]() |
e43adb629b | ||
![]() |
3c0e266bd5 | ||
![]() |
67230d6de5 | ||
![]() |
6a9cc33099 | ||
![]() |
4b4f463907 | ||
![]() |
991e8b3aae | ||
![]() |
420a7792d0 | ||
![]() |
e062ae86aa | ||
![]() |
6326c61a70 | ||
![]() |
eea929be22 | ||
![]() |
9962dc418e | ||
![]() |
77f03d2bb5 | ||
![]() |
a236f54cc9 | ||
![]() |
de6d1ed419 | ||
![]() |
5345fb6b0e | ||
![]() |
72d3bb8b33 | ||
![]() |
d908ddd2ef | ||
![]() |
8dc46ae460 | ||
![]() |
1218e11f1e | ||
![]() |
18ddeeb8bc | ||
![]() |
3b614c0cfa | ||
![]() |
5f89dc7d6e | ||
![]() |
2d251d6924 | ||
![]() |
c46761fdcd | ||
![]() |
321490c60a | ||
![]() |
dc88c3a0c5 | ||
![]() |
2125c059c3 | ||
![]() |
f6e319ef2e | ||
![]() |
3d1f14f079 | ||
![]() |
1abc7bec79 | ||
![]() |
18dfe0dd4e | ||
![]() |
c94657a1d8 | ||
![]() |
c755692dde | ||
![]() |
1e46f60599 | ||
![]() |
f009ea4a47 | ||
![]() |
7cdc68de58 | ||
![]() |
734bb168e3 | ||
![]() |
6e227a5e76 | ||
![]() |
307c11527a | ||
![]() |
5621d09ed1 | ||
![]() |
8c4057e25f | ||
![]() |
8f47019836 | ||
![]() |
7a799a583e | ||
![]() |
ae54c380bb | ||
![]() |
738ce05a6a | ||
![]() |
b4f323482c | ||
![]() |
e957501bc3 | ||
![]() |
f38b70aee3 | ||
![]() |
62aa9ed8ce | ||
![]() |
eada3203b5 | ||
![]() |
e2d72e213a | ||
![]() |
664f1245dd | ||
![]() |
d41a74b958 | ||
![]() |
d2e030b6ed | ||
![]() |
1b73c818fe | ||
![]() |
a2913c1b3d | ||
![]() |
95f386689b | ||
![]() |
6ba3c59bc6 | ||
![]() |
e65822d31a | ||
![]() |
866ffdf84d | ||
![]() |
338a11e8c5 | ||
![]() |
6a0f4e7f4d | ||
![]() |
dee73a71be | ||
![]() |
9b079a7363 | ||
![]() |
ac593b977e | ||
![]() |
5b43f91839 | ||
![]() |
ece8e1f566 | ||
![]() |
cfbf2ee2ea | ||
![]() |
6042b819eb | ||
![]() |
367c547d7d | ||
![]() |
6ac1087775 | ||
![]() |
2982c7c1d0 | ||
![]() |
a3a62da413 | ||
![]() |
958d453c5d | ||
![]() |
0f09389954 | ||
![]() |
dc104b5c83 | ||
![]() |
97e67238ea | ||
![]() |
ac72938f3a | ||
![]() |
133f857c90 | ||
![]() |
3e8708a684 | ||
![]() |
90a4d2a19b | ||
![]() |
251c03879a | ||
![]() |
ae5f032774 | ||
![]() |
dd6f3c9e10 | ||
![]() |
84396edc7e | ||
![]() |
6079b26874 | ||
![]() |
b94eca1419 | ||
![]() |
a14ccf053e | ||
![]() |
1fd624717d | ||
![]() |
dca71d6aaa | ||
![]() |
441dd9f254 | ||
![]() |
6e95ff3cd5 | ||
![]() |
a4d7180f07 | ||
![]() |
8890344e49 | ||
![]() |
d3f15b49f1 | ||
![]() |
8227e3155d | ||
![]() |
d0e44775cd | ||
![]() |
5f73da34f8 | ||
![]() |
ed9a8c623c | ||
![]() |
ad3a3e02a7 | ||
![]() |
08509d9a42 | ||
![]() |
99d1026ab8 | ||
![]() |
a471e65bf2 | ||
![]() |
807520bd14 | ||
![]() |
68efb13b02 | ||
![]() |
3351aa00b2 | ||
![]() |
b4b4b40c03 | ||
![]() |
bfe077bfb6 | ||
![]() |
62aef87f39 | ||
![]() |
a8965747f2 | ||
![]() |
6a28d55cbf | ||
![]() |
902daca592 | ||
![]() |
b8094dc31e | ||
![]() |
e2bb33a278 | ||
![]() |
0cf7a23785 | ||
![]() |
984ab2b4b8 | ||
![]() |
99b636b6a7 | ||
![]() |
22c9314c52 | ||
![]() |
d96e4cfa30 | ||
![]() |
f390b8d769 | ||
![]() |
764c279509 | ||
![]() |
bf1b284c20 | ||
![]() |
c50a04d832 | ||
![]() |
f8d4b5c286 | ||
![]() |
31d24d6654 | ||
![]() |
8fb8d46593 | ||
![]() |
7b3e6ed2f5 | ||
![]() |
06d1e2d093 | ||
![]() |
7d0716889b | ||
![]() |
be35464a0e | ||
![]() |
b2e6ecea09 | ||
![]() |
fea3b5eab8 | ||
![]() |
e15fb07855 | ||
![]() |
e712ee7e3d | ||
![]() |
10de0c5e4e | ||
![]() |
08fb627a3d | ||
![]() |
61651ceaa9 | ||
![]() |
4034cb97bc | ||
![]() |
de59412f4b | ||
![]() |
13809e0a15 | ||
![]() |
c715985c07 | ||
![]() |
32c930e9ab | ||
![]() |
f1febd43b2 | ||
![]() |
b9fcfc65d8 | ||
![]() |
19ffb8fde5 | ||
![]() |
420c851349 | ||
![]() |
75a97e3f7b | ||
![]() |
61af1b57e4 | ||
![]() |
4703a0ce80 | ||
![]() |
4054514874 | ||
![]() |
b969806a43 | ||
![]() |
b9e70f7821 | ||
![]() |
2a5aadbf48 | ||
![]() |
0f0e558289 | ||
![]() |
7cdc1871c1 | ||
![]() |
12633630ab | ||
![]() |
0643dfe61b | ||
![]() |
d66098e3dd | ||
![]() |
3fa5a82cb1 | ||
![]() |
58b52f3bf8 | ||
![]() |
368551a133 | ||
![]() |
2aafb8f8d0 | ||
![]() |
9c4736bb17 | ||
![]() |
71840771e9 | ||
![]() |
a4cabf6b61 | ||
![]() |
ce98483800 | ||
![]() |
ed67b9caa4 | ||
![]() |
cbfb0fda5a | ||
![]() |
edd790e0a8 | ||
![]() |
f1bc8b0892 | ||
![]() |
bc3236f035 | ||
![]() |
e92598caeb | ||
![]() |
c295a8af70 | ||
![]() |
ae1ce4eb54 | ||
![]() |
23c0e1a9b3 | ||
![]() |
57168941b2 | ||
![]() |
dedb6325a8 | ||
![]() |
b65bd345ef | ||
![]() |
d3cd1f406f | ||
![]() |
986dcdd054 | ||
![]() |
c2547e29dd | ||
![]() |
cebc3a1072 | ||
![]() |
932dad3197 | ||
![]() |
c0fcba572d | ||
![]() |
5dee4bc718 | ||
![]() |
66521ab1de | ||
![]() |
7ce52e88c0 | ||
![]() |
795015c1e8 | ||
![]() |
65b4f04d50 | ||
![]() |
f94d252cea | ||
![]() |
3c4becd315 | ||
![]() |
a5be4ddc74 | ||
![]() |
e793a5d902 | ||
![]() |
1e6b143073 | ||
![]() |
983dfd764c | ||
![]() |
bcba9b1fee | ||
![]() |
39518769ff | ||
![]() |
3e2fd5f6b3 | ||
![]() |
bb9443782b | ||
![]() |
a5eb308eb7 | ||
![]() |
6e32c65ce4 | ||
![]() |
d24b4c4320 | ||
![]() |
68d7ab12b2 | ||
![]() |
1a90f7b69c | ||
![]() |
c2c004776f | ||
![]() |
9f289689bb | ||
![]() |
3a08ee3d66 | ||
![]() |
3f90c29b0d | ||
![]() |
8cfc822887 | ||
![]() |
786dd821bc | ||
![]() |
98989f19ee | ||
![]() |
28a044aa26 | ||
![]() |
a8c8155e8e | ||
![]() |
fcedc1dc3f | ||
![]() |
c1cc30c8d4 | ||
![]() |
79704e5d8f | ||
![]() |
c276f6ff7e | ||
![]() |
096d3eabcd | ||
![]() |
252a35e796 | ||
![]() |
7f68648067 | ||
![]() |
ada5b187c7 | ||
![]() |
286e016e0e | ||
![]() |
855a023c51 | ||
![]() |
fd0e5587fa | ||
![]() |
fdc57a15f6 | ||
![]() |
4bf3bdf2d8 | ||
![]() |
e843160dcb | ||
![]() |
01870df0a9 | ||
![]() |
1b8d7e81b0 | ||
![]() |
77121bc77b | ||
![]() |
6ae1152eea | ||
![]() |
335f001567 | ||
![]() |
ff59751b3c | ||
![]() |
bb9c177485 | ||
![]() |
68f89922d6 | ||
![]() |
450406efbc | ||
![]() |
bc752d6087 | ||
![]() |
c4d29bf5b2 | ||
![]() |
995ead5584 | ||
![]() |
af3b754ee2 | ||
![]() |
5c9ad7fce6 | ||
![]() |
4b455d3d83 | ||
![]() |
941c21b681 | ||
![]() |
cfc8494f3b | ||
![]() |
fe56d428c0 | ||
![]() |
f10717dc73 | ||
![]() |
e4decfd4bd | ||
![]() |
aa52cfcd81 | ||
![]() |
d1fb3092ba | ||
![]() |
b4938889d4 | ||
![]() |
9403c911ce | ||
![]() |
50142ba7af | ||
![]() |
711eaef9ea | ||
![]() |
b670630c81 | ||
![]() |
3b998fdc54 | ||
![]() |
dd5ec50e4b | ||
![]() |
627dfaf069 | ||
![]() |
ca3088a08d | ||
![]() |
63725ea32d | ||
![]() |
8e3e2f13a8 | ||
![]() |
262238adca | ||
![]() |
4e8b111da1 | ||
![]() |
27c18b1c64 | ||
![]() |
2d0a396d46 | ||
![]() |
cdbd6e5e85 | ||
![]() |
f6fb7cb101 | ||
![]() |
4b2a818159 | ||
![]() |
0b2cecdaae | ||
![]() |
a6a95f098b | ||
![]() |
17a9fac9ca | ||
![]() |
413d837155 | ||
![]() |
ad363667e1 | ||
![]() |
eb136c70d4 | ||
![]() |
1ce0241964 | ||
![]() |
a2673955a0 | ||
![]() |
1d6e210c97 | ||
![]() |
f36f89daeb | ||
![]() |
210f4edecf | ||
![]() |
a558487ee0 | ||
![]() |
b45fdcf650 | ||
![]() |
baf172ed6a | ||
![]() |
e64110acb1 | ||
![]() |
d8ae75228d | ||
![]() |
61ed208946 | ||
![]() |
4f38efcb15 | ||
![]() |
62c6729ad3 | ||
![]() |
fd0ee42a4d | ||
![]() |
d46fe4c5c6 | ||
![]() |
307e695c51 | ||
![]() |
b3d763dd5c | ||
![]() |
f0555f4cd6 | ||
![]() |
8953e851a1 | ||
![]() |
09ae9e21b6 | ||
![]() |
982d4d0dea | ||
![]() |
724c3d91d5 | ||
![]() |
759895012f | ||
![]() |
48f056c336 | ||
![]() |
7e7cfb8175 | ||
![]() |
d8275c3c60 | ||
![]() |
7c854716df | ||
![]() |
efc6ca5073 | ||
![]() |
ff1033d6d9 | ||
![]() |
8de562e931 | ||
![]() |
291d397b90 | ||
![]() |
1ced186070 | ||
![]() |
dd9210256d | ||
![]() |
846166ffa0 | ||
![]() |
4e8b0a81f6 | ||
![]() |
be3cb7b5aa | ||
![]() |
81520789a6 | ||
![]() |
bea18ddafc | ||
![]() |
b14b0a186c | ||
![]() |
8c6e3fef17 | ||
![]() |
62690928c6 | ||
![]() |
ec96351509 | ||
![]() |
5c8fbbaf20 | ||
![]() |
bc00134c62 | ||
![]() |
7ed7f59ca2 | ||
![]() |
5cd49f8c2d | ||
![]() |
2740f4ff1f | ||
![]() |
5b1a2fe1bf | ||
![]() |
a0f6ff42fa | ||
![]() |
316681cafb | ||
![]() |
6d2a5c29e8 | ||
![]() |
3750c5302c | ||
![]() |
a299058164 | ||
![]() |
235f02844b | ||
![]() |
a866c7c45e | ||
![]() |
c8b8b3cadf | ||
![]() |
2610be7bb8 | ||
![]() |
7c640bd299 | ||
![]() |
0604c7fd87 | ||
![]() |
e4574f5e38 | ||
![]() |
2e272d0ec7 | ||
![]() |
270645280a | ||
![]() |
a8b258a5a2 | ||
![]() |
d3148ec5e5 | ||
![]() |
0190fb3dbc | ||
![]() |
f0f52523e7 | ||
![]() |
9461844917 | ||
![]() |
03730a35b9 | ||
![]() |
bfda1ec9d1 | ||
![]() |
17ab284b9d | ||
![]() |
f51c3c4c5f | ||
![]() |
c742851bbf | ||
![]() |
9f56ba29e4 | ||
![]() |
10a315a997 | ||
![]() |
dd7c81416d | ||
![]() |
677536fd32 | ||
![]() |
a86508a71e | ||
![]() |
f3f3a8e0a0 | ||
![]() |
f588e17a5b | ||
![]() |
8b5e11a2b1 | ||
![]() |
de63afb341 | ||
![]() |
a43858e60f | ||
![]() |
4dd77eb4d6 | ||
![]() |
234951f19b | ||
![]() |
02c995141e | ||
![]() |
dc786e7809 | ||
![]() |
e73ff65381 | ||
![]() |
6a459d285a | ||
![]() |
3751de29e9 | ||
![]() |
29b8f500c2 | ||
![]() |
5a03253d72 | ||
![]() |
b90d0ab136 | ||
![]() |
2b7a7f90b7 | ||
![]() |
8f03b98162 | ||
![]() |
9b5d88e0d0 | ||
![]() |
b4b7e995cd | ||
![]() |
528984a4f8 | ||
![]() |
1b438493cf | ||
![]() |
3b54ee8a34 | ||
![]() |
ffddd5941d | ||
![]() |
6313c343d4 | ||
![]() |
75af1a47c4 | ||
![]() |
b50afacfed | ||
![]() |
7de6088904 | ||
![]() |
8281b8ad57 | ||
![]() |
d82ceda8a1 | ||
![]() |
bff472661c | ||
![]() |
5184a750a6 | ||
![]() |
f60f9d4d6b | ||
![]() |
9d736a1803 | ||
![]() |
d77ab55ce1 | ||
![]() |
13c0052761 | ||
![]() |
bc7fa5e550 | ||
![]() |
3d7cff9835 | ||
![]() |
cc6619bd58 | ||
![]() |
4cd2d9f19e | ||
![]() |
69d9410ad3 | ||
![]() |
f038bbbed9 | ||
![]() |
05f9744e41 | ||
![]() |
ef1134dca7 | ||
![]() |
de772eb038 | ||
![]() |
5485a02af8 | ||
![]() |
2c4c729f2a | ||
![]() |
b6b72a44c8 | ||
![]() |
0ec94592d4 | ||
![]() |
068970bff8 | ||
![]() |
26361016d9 | ||
![]() |
1f907ee3bb | ||
![]() |
fc8e4597a7 | ||
![]() |
08dfcc4c04 | ||
![]() |
8cbcb5bd41 | ||
![]() |
865fd6e79a | ||
![]() |
769bb7f140 | ||
![]() |
ca2731c4b9 | ||
![]() |
2bbb2f249d | ||
![]() |
bb03b8754a | ||
![]() |
3e3de07034 | ||
![]() |
402f3827f0 | ||
![]() |
8e3ce84d94 | ||
![]() |
8e99cd3206 | ||
![]() |
9fdf62af89 | ||
![]() |
1bc25030ee | ||
![]() |
69cb60a7bb | ||
![]() |
7939ced35e | ||
![]() |
0144a27348 | ||
![]() |
27dd522957 | ||
![]() |
fa9e2ce8bf | ||
![]() |
6a02815615 | ||
![]() |
fa5d3d59a3 | ||
![]() |
723b5d3f7d | ||
![]() |
a2e52d663f | ||
![]() |
99444e8f79 | ||
![]() |
024cd9adae | ||
![]() |
f7a56405a8 | ||
![]() |
a6b6d5ba9a | ||
![]() |
ab92e76dc8 | ||
![]() |
c87fbfdc3b | ||
![]() |
8356556044 | ||
![]() |
0bdc1cda4e | ||
![]() |
fa269949dd | ||
![]() |
1060db9be7 | ||
![]() |
df4dacaa89 | ||
![]() |
ee96eba261 | ||
![]() |
172663c1a0 | ||
![]() |
f2e68be9bb | ||
![]() |
242ef530a8 | ||
![]() |
22a9e7512b | ||
![]() |
41562df308 | ||
![]() |
4e7053cfd8 | ||
![]() |
42f7377ae0 | ||
![]() |
086ffa020e | ||
![]() |
38731065db | ||
![]() |
602081b5d9 | ||
![]() |
15c8c40ba8 | ||
![]() |
b0bd577697 | ||
![]() |
86eef8cdff | ||
![]() |
437049ca22 | ||
![]() |
6e12407521 | ||
![]() |
8fcb602161 | ||
![]() |
51af91599b | ||
![]() |
c5c9b6ff9e | ||
![]() |
e3b5eb746a | ||
![]() |
cc8c5e7787 | ||
![]() |
4717fbffaa | ||
![]() |
d552acdbfc | ||
![]() |
c28e2996d2 | ||
![]() |
ad33a235d2 | ||
![]() |
ba0dd99ea1 | ||
![]() |
840016d287 | ||
![]() |
0c9b5d5c37 | ||
![]() |
4f7185fe00 | ||
![]() |
095002c917 | ||
![]() |
83322c2e9c | ||
![]() |
03ef174aec | ||
![]() |
c41b715259 | ||
![]() |
d0e5182f78 | ||
![]() |
17ea45322d | ||
![]() |
7b0c3d7790 | ||
![]() |
9461e99923 | ||
![]() |
b4c0efad44 | ||
![]() |
98d07d49b8 | ||
![]() |
bbc26e5efa | ||
![]() |
01d9c79ad2 | ||
![]() |
48326e19ea | ||
![]() |
bf534010c8 | ||
![]() |
be849d1612 | ||
![]() |
3da07e5b14 | ||
![]() |
4ad3c84be0 | ||
![]() |
5cd280e718 | ||
![]() |
9a417daee7 | ||
![]() |
60f4aabced | ||
![]() |
5dd27b18ae | ||
![]() |
6ffc0e26e3 | ||
![]() |
dcd088713a | ||
![]() |
3a8cb18589 | ||
![]() |
16e8ea38da | ||
![]() |
618e703768 | ||
![]() |
1faa996b87 | ||
![]() |
0f7f451225 | ||
![]() |
4472745cf1 | ||
![]() |
52a83d3ef3 | ||
![]() |
cb433740f0 | ||
![]() |
3f5b196783 | ||
![]() |
c6b48fe911 | ||
![]() |
e0bd90b74a | ||
![]() |
82edb42dc4 | ||
![]() |
cbcaf86272 | ||
![]() |
30ac0d5e30 | ||
![]() |
62f3ac4728 | ||
![]() |
3491f60cd2 | ||
![]() |
da64026a59 | ||
![]() |
06f041ee63 | ||
![]() |
18edda7475 | ||
![]() |
0268ea521b | ||
![]() |
841d7d379c | ||
![]() |
b12ac5bdd5 | ||
![]() |
967b5466c0 | ||
![]() |
559d530325 | ||
![]() |
b1929916fa | ||
![]() |
646144ddf8 | ||
![]() |
1bf658c5ba | ||
![]() |
659d5814cd | ||
![]() |
6aa0ae3b2c | ||
![]() |
a9c3a8135d | ||
![]() |
baedfec11a | ||
![]() |
bec82ebb34 | ||
![]() |
88f751a23c | ||
![]() |
17288cdb41 | ||
![]() |
98c01d6558 | ||
![]() |
4ae6f80c0f | ||
![]() |
22920e8d5d | ||
![]() |
5c03d2895c | ||
![]() |
e185973ea9 | ||
![]() |
e75dfc6354 | ||
![]() |
28ac672424 | ||
![]() |
d3225fe87b | ||
![]() |
602cf94057 | ||
![]() |
620fa099ad | ||
![]() |
ee1ab68105 | ||
![]() |
8a141f1b25 | ||
![]() |
7f4d2ba1d7 | ||
![]() |
312a368eff | ||
![]() |
492c7bf391 | ||
![]() |
7179d77efe | ||
![]() |
8d5c4478e2 | ||
![]() |
bfc4426d68 | ||
![]() |
0e8d0f1209 | ||
![]() |
2b777af8b0 | ||
![]() |
5e56dcabdd | ||
![]() |
257f37d700 | ||
![]() |
09e93879a7 | ||
![]() |
3789f95625 | ||
![]() |
31c22e9e94 | ||
![]() |
58ae566dc6 | ||
![]() |
8cd034b5cd | ||
![]() |
7394701157 | ||
![]() |
234423e82b | ||
![]() |
f834a938f2 | ||
![]() |
d2bf1ba9cd | ||
![]() |
8ec2566464 | ||
![]() |
7dd9711c64 | ||
![]() |
0c7f7d1ce7 | ||
![]() |
abfa34ddb6 | ||
![]() |
6d5cf3f952 | ||
![]() |
5f910fc7e7 | ||
![]() |
dd75630a57 | ||
![]() |
9014219205 | ||
![]() |
36e65a1165 | ||
![]() |
4ef34fc5f4 | ||
![]() |
95e9882404 | ||
![]() |
b977bc8ddc | ||
![]() |
bf6ddb7db6 | ||
![]() |
50a1854730 | ||
![]() |
4c536a7182 | ||
![]() |
fb62fbd197 | ||
![]() |
3020c439b0 | ||
![]() |
6c44eb8294 | ||
![]() |
ce1dc8468b | ||
![]() |
c07b7603d6 | ||
![]() |
22dc9741b8 | ||
![]() |
b2ee165d6b | ||
![]() |
8acdf5acdf | ||
![]() |
fcfb36863a | ||
![]() |
e2e05ab7f8 | ||
![]() |
665f0cd35c | ||
![]() |
5eb9d8c131 | ||
![]() |
7d9d8dbed9 | ||
![]() |
736c95931c | ||
![]() |
8f98569b2a | ||
![]() |
34a865a2b2 | ||
![]() |
3df9c18651 | ||
![]() |
3fac642ac6 | ||
![]() |
38cf4def05 | ||
![]() |
0d740caef8 | ||
![]() |
d9101bf951 | ||
![]() |
4d9c041938 | ||
![]() |
ad2f98ecee | ||
![]() |
d95d0359a5 | ||
![]() |
4221d49190 | ||
![]() |
6a63d1e1bf | ||
![]() |
fb1fe28aa9 | ||
![]() |
d39be7dab1 | ||
![]() |
0906711ee2 | ||
![]() |
4cbef76b5d | ||
![]() |
cf50530aad | ||
![]() |
6a872c41f9 | ||
![]() |
b417139777 | ||
![]() |
be340ec1ef | ||
![]() |
af9b0d1b66 | ||
![]() |
6a97f0189b | ||
![]() |
ae90a0b602 | ||
![]() |
3538a9c448 | ||
![]() |
3ea81e414c | ||
![]() |
bc1dc8f54d | ||
![]() |
51ab26a070 | ||
![]() |
3de1f9a283 | ||
![]() |
87d61bba41 | ||
![]() |
9716e7993f | ||
![]() |
666680491a | ||
![]() |
58a81c5c4c | ||
![]() |
6b8ef3323f | ||
![]() |
1c997727c9 | ||
![]() |
0edfedf16d | ||
![]() |
42d4eb324d | ||
![]() |
205450238e | ||
![]() |
c3c25d12b0 | ||
![]() |
b77c43beb0 | ||
![]() |
8373ec9091 | ||
![]() |
944a8b8909 | ||
![]() |
a78216810d | ||
![]() |
69a29db2d7 | ||
![]() |
e4fdf56472 | ||
![]() |
582ce2283c | ||
![]() |
43886cd0c3 | ||
![]() |
581eef0495 | ||
![]() |
9e1cda0fb7 | ||
![]() |
20b6ac540d | ||
![]() |
f0da059036 | ||
![]() |
0e1a7180e5 | ||
![]() |
e55f7fb99e | ||
![]() |
9151ce890a | ||
![]() |
225875592f | ||
![]() |
4a7ed1cd68 | ||
![]() |
0a05f634b6 | ||
![]() |
939ae1be50 | ||
![]() |
1abdcf81f3 | ||
![]() |
4b7f83fb7a | ||
![]() |
c815c5df17 | ||
![]() |
74d37f129f | ||
![]() |
8138d89db1 | ||
![]() |
5b5e575c4c | ||
![]() |
423833260b | ||
![]() |
fbb03cca84 | ||
![]() |
02c29677a6 | ||
![]() |
09ca4109ad | ||
![]() |
b1873d4919 | ||
![]() |
7f7bafe37a | ||
![]() |
9dcecf749d | ||
![]() |
23cf07c0bc | ||
![]() |
fd30e95c05 | ||
![]() |
67e0fe5e75 | ||
![]() |
3e205d23e0 | ||
![]() |
b4def97a99 | ||
![]() |
ed9e4befd6 | ||
![]() |
cce5bff7c0 | ||
![]() |
b6d9173b6b | ||
![]() |
07b38ce1a1 | ||
![]() |
7a19e1f563 | ||
![]() |
ce04a71447 | ||
![]() |
f96d468a04 | ||
![]() |
6655125c37 | ||
![]() |
4f723c8a08 | ||
![]() |
33a8d4202a | ||
![]() |
915804c250 | ||
![]() |
4523c1be3d | ||
![]() |
8ee5785691 | ||
![]() |
7d223a4638 | ||
![]() |
c632bba0e4 | ||
![]() |
ac7e9e7409 | ||
![]() |
8567a10991 | ||
![]() |
1b9b564b1b | ||
![]() |
c91875f5c7 | ||
![]() |
c65a184a68 | ||
![]() |
9ee57c0871 | ||
![]() |
a47fe7c043 | ||
![]() |
f1a01ff091 | ||
![]() |
0093196671 | ||
![]() |
3baba75579 | ||
![]() |
c69f784c4f | ||
![]() |
b60efcf625 | ||
![]() |
044773f27a | ||
![]() |
e42d2fcf77 | ||
![]() |
a968e74116 | ||
![]() |
b711f8d3a4 | ||
![]() |
fe238e608d | ||
![]() |
4d042152e5 | ||
![]() |
d1c0ee4e67 | ||
![]() |
12bb701066 | ||
![]() |
a8e851942c | ||
![]() |
724e1a1fea | ||
![]() |
fdd4ec0d74 | ||
![]() |
020ae6440a | ||
![]() |
815b8a6dbc | ||
![]() |
070aa8aaf9 | ||
![]() |
5f40fac43c | ||
![]() |
86a97221c8 | ||
![]() |
562c86f382 | ||
![]() |
c004907b76 | ||
![]() |
1e1e79beb1 | ||
![]() |
931aafa079 | ||
![]() |
1d44b6d930 | ||
![]() |
d26252004a | ||
![]() |
62c26bf6f0 | ||
![]() |
fb18af2532 | ||
![]() |
3aa2cc8b70 | ||
![]() |
f301f0f948 | ||
![]() |
11f586bd88 | ||
![]() |
679a1f78bd | ||
![]() |
a6d456f542 | ||
![]() |
059617dc0d | ||
![]() |
b7c4b5161d | ||
![]() |
55d7ed5032 | ||
![]() |
9d6a865b9e | ||
![]() |
b94562c2d4 | ||
![]() |
ef211120a5 | ||
![]() |
8a0500a5cb | ||
![]() |
295aabe028 | ||
![]() |
a59f800cbb | ||
![]() |
5cf6e7a5be | ||
![]() |
576594102a | ||
![]() |
f4d8dc543f | ||
![]() |
a2f1692a6f | ||
![]() |
969e5d8dad | ||
![]() |
a6c69ab0ca | ||
![]() |
98112b163c | ||
![]() |
a6cc85b4b6 | ||
![]() |
6c238a972b | ||
![]() |
72aab29255 | ||
![]() |
6402474c46 | ||
![]() |
469cc2b708 | ||
![]() |
fdfc2d648c | ||
![]() |
d7212b2954 | ||
![]() |
513bb9920a | ||
![]() |
f465da83c9 | ||
![]() |
554fae61a8 | ||
![]() |
7dfd007898 | ||
![]() |
c12a6f5538 | ||
![]() |
e35d0afdc1 | ||
![]() |
842e57c994 | ||
![]() |
909b045c81 | ||
![]() |
9ed666d189 | ||
![]() |
081ee9cc54 | ||
![]() |
f6c1fe1c6c | ||
![]() |
ec018be115 | ||
![]() |
041d24051d | ||
![]() |
1f30bd2085 | ||
![]() |
9125e4d5da | ||
![]() |
227e314ad8 | ||
![]() |
2bf9c4d198 | ||
![]() |
0f808a8de4 | ||
![]() |
82b7c17c09 | ||
![]() |
b476eb5054 | ||
![]() |
ffd30e8dd8 | ||
![]() |
a7dc1531cb | ||
![]() |
c5eec21596 | ||
![]() |
17f2c309ac | ||
![]() |
7b71b4999e | ||
![]() |
5ef40d7166 | ||
![]() |
34a29cb8a6 | ||
![]() |
f5a8de7d36 | ||
![]() |
abb8062519 | ||
![]() |
2702dd241c | ||
![]() |
c7b6b5068a | ||
![]() |
32778b637f | ||
![]() |
eeb5dfb252 | ||
![]() |
44a759c065 | ||
![]() |
a2a827260c | ||
![]() |
a8daea7bf1 | ||
![]() |
53dd0e017f | ||
![]() |
0bc7d4006f | ||
![]() |
b224e37625 | ||
![]() |
a53d74f700 | ||
![]() |
f5d5eb9133 | ||
![]() |
985c5e91f6 | ||
![]() |
2f3f1438bb | ||
![]() |
ed90466495 | ||
![]() |
af93c64cfb | ||
![]() |
a7b11ecaab | ||
![]() |
239c560880 | ||
![]() |
8683cf7a6d | ||
![]() |
393dac5ef4 | ||
![]() |
832540c0bd | ||
![]() |
933541631c | ||
![]() |
83f33bd403 | ||
![]() |
9c7f90a508 | ||
![]() |
37b9df5bd8 | ||
![]() |
fe0a8cd3ae | ||
![]() |
1c11902f89 | ||
![]() |
f51ab66afb | ||
![]() |
de8d1bc003 | ||
![]() |
e867a0c365 | ||
![]() |
4b0508d51e | ||
![]() |
1eb4363a4b | ||
![]() |
1eabd2fb82 | ||
![]() |
4daffbaee1 | ||
![]() |
32d6fb28f0 | ||
![]() |
4b1f26aed5 | ||
![]() |
92456281bc | ||
![]() |
6113e26177 | ||
![]() |
42712950f2 | ||
![]() |
0b33274468 | ||
![]() |
9d43e5cb33 | ||
![]() |
da7249a7da | ||
![]() |
8185763b47 | ||
![]() |
b58b0de3c2 | ||
![]() |
b539612242 | ||
![]() |
a17a4c2841 | ||
![]() |
1663a841cf | ||
![]() |
8cb0f24d1b | ||
![]() |
b3b79dbb9c | ||
![]() |
c284d64019 | ||
![]() |
d27c1154d5 | ||
![]() |
acb1d7db82 | ||
![]() |
690deb84ea | ||
![]() |
a83b3d3943 | ||
![]() |
8e79a7232f | ||
![]() |
aaf26005c3 | ||
![]() |
618324f5d3 | ||
![]() |
3520c15609 | ||
![]() |
fad8491fc9 | ||
![]() |
3eda4784bb | ||
![]() |
b719970c0b | ||
![]() |
68651bf651 | ||
![]() |
d4982767f9 | ||
![]() |
aa6e536bdb | ||
![]() |
515a44abdb | ||
![]() |
bbda4a813a | ||
![]() |
a81ed2173e | ||
![]() |
e3e15baf50 | ||
![]() |
225624ef26 | ||
![]() |
7d60fe14e4 | ||
![]() |
357d0e1dee | ||
![]() |
2c5f9483f5 | ||
![]() |
2e4c654d24 | ||
![]() |
c4a2357a3c | ||
![]() |
0b72380497 | ||
![]() |
21bd727d6c | ||
![]() |
18dea8572d | ||
![]() |
e7d271c9e1 | ||
![]() |
cc2d4600d8 | ||
![]() |
830658002d | ||
![]() |
b06e69da6c | ||
![]() |
2d12c2d5c8 | ||
![]() |
711d42d763 | ||
![]() |
5acfa350b7 | ||
![]() |
fa18b2cf05 | ||
![]() |
fd7c70d42d | ||
![]() |
be3bd2810f | ||
![]() |
52cb7100f2 | ||
![]() |
5b338faafa | ||
![]() |
b73d4f8d3f | ||
![]() |
9d48b7acf4 | ||
![]() |
2458fea93e | ||
![]() |
539c9b2f0c | ||
![]() |
1bf2f9775d | ||
![]() |
6be19fd726 | ||
![]() |
445bbefc90 | ||
![]() |
e9f69ac719 | ||
![]() |
416c6348f8 | ||
![]() |
75f52eeda4 | ||
![]() |
20f6f68d34 | ||
![]() |
b94745bfeb | ||
![]() |
00cfbecfee | ||
![]() |
092bd2feb9 | ||
![]() |
738523bd5f | ||
![]() |
910453353b | ||
![]() |
13328439bc | ||
![]() |
7fe764fa81 | ||
![]() |
204ed812d0 | ||
![]() |
7dfde9f9fe | ||
![]() |
269e6c2a15 | ||
![]() |
80cb5a3de4 | ||
![]() |
61ee456a9d | ||
![]() |
b6dd719334 | ||
![]() |
40292bd765 | ||
![]() |
64580b3060 | ||
![]() |
e5db4109e0 | ||
![]() |
98bf782e42 | ||
![]() |
e77fe6304b | ||
![]() |
d0d33c82a2 | ||
![]() |
4ea1cf7500 | ||
![]() |
835db067d1 | ||
![]() |
281391b987 | ||
![]() |
e458dee210 | ||
![]() |
c4d765fc77 | ||
![]() |
283e1f384e | ||
![]() |
c204bb533c | ||
![]() |
3f66a14524 | ||
![]() |
b7e12d640e | ||
![]() |
c1d40aa45b | ||
![]() |
4e8540cc23 | ||
![]() |
9b119a28a5 | ||
![]() |
ff749ea95a | ||
![]() |
775240461c | ||
![]() |
642651fe29 | ||
![]() |
c029ed4f59 | ||
![]() |
2f20ef2c6b | ||
![]() |
686b672b03 | ||
![]() |
59233a5db9 | ||
![]() |
00f80efd45 | ||
![]() |
000d3cff5a | ||
![]() |
c1644a1f17 | ||
![]() |
af9f912974 | ||
![]() |
f56e736bed | ||
![]() |
0d89cb5d73 | ||
![]() |
ef4467c8b8 | ||
![]() |
16f1061f41 | ||
![]() |
ee22dfaf73 | ||
![]() |
38982dbe41 | ||
![]() |
064d858f63 | ||
![]() |
31bc57ef04 | ||
![]() |
9c1a181e67 | ||
![]() |
b160683938 | ||
![]() |
78b8e06a07 | ||
![]() |
8ddde738a5 | ||
![]() |
019a09d36e | ||
![]() |
c78c155cf0 | ||
![]() |
20765a994f | ||
![]() |
8a6f638464 | ||
![]() |
c4ea3ea9f8 | ||
![]() |
243fa32395 | ||
![]() |
3c15e7e4d4 | ||
![]() |
3bd96ae803 | ||
![]() |
3b638a9708 | ||
![]() |
188487d180 | ||
![]() |
922308f3c8 | ||
![]() |
f2bbfc138b | ||
![]() |
b42f932be5 | ||
![]() |
30988915fa | ||
![]() |
f4ece4ed57 | ||
![]() |
b1b88f09a2 | ||
![]() |
66714ebcad | ||
![]() |
3ef3d14e6d | ||
![]() |
0a8c804187 | ||
![]() |
fb46697b26 | ||
![]() |
243b81766a | ||
![]() |
e71d15e5da | ||
![]() |
a3d0fc798e | ||
![]() |
cb2ab79827 | ||
![]() |
5515da09bf | ||
![]() |
1622678cd7 | ||
![]() |
400b2ce7f5 | ||
![]() |
9046b77400 | ||
![]() |
98695e35af | ||
![]() |
248a1050a8 | ||
![]() |
8dfe0ee3f4 | ||
![]() |
467d26c8b7 | ||
![]() |
bb40edd264 | ||
![]() |
c6de787438 | ||
![]() |
45f1e8fb92 | ||
![]() |
ff85b03c27 | ||
![]() |
bc42b5f993 | ||
![]() |
aae164d51b | ||
![]() |
d9eb683b30 | ||
![]() |
3f78450f6c | ||
![]() |
b84b6ca11b | ||
![]() |
fa48a435b3 | ||
![]() |
2a91a6204f | ||
![]() |
a6d5b37cba | ||
![]() |
3ebf0a6369 | ||
![]() |
ddc5ed8372 | ||
![]() |
8bf07a8b5d | ||
![]() |
09a879748c | ||
![]() |
71afc9f3b8 | ||
![]() |
bb5d1a8f64 | ||
![]() |
23b35e63df | ||
![]() |
12ed49be65 | ||
![]() |
b54a7ae725 | ||
![]() |
71583c0a06 | ||
![]() |
e11c6b4fe2 | ||
![]() |
d924fccc1e | ||
![]() |
9e2f491e3f | ||
![]() |
902e607379 | ||
![]() |
29558f2ca4 | ||
![]() |
2b51570d5f | ||
![]() |
227fb65ec9 | ||
![]() |
3b3a421bef | ||
![]() |
5de15f855c | ||
![]() |
040111b367 | ||
![]() |
104afac892 | ||
![]() |
b6f4c3cf16 | ||
![]() |
ac426cd439 | ||
![]() |
3ee41f13e6 | ||
![]() |
6213a65ebe | ||
![]() |
576ad18ead | ||
![]() |
4e6de625a6 | ||
![]() |
d6475671fe | ||
![]() |
4645f6c955 | ||
![]() |
0b9d12b01a | ||
![]() |
4aa85cfb22 | ||
![]() |
1d307bb4de | ||
![]() |
5bb1b050f3 | ||
![]() |
724314caa1 | ||
![]() |
be5a16dacc | ||
![]() |
fb30d37bcb | ||
![]() |
9f3e75368c | ||
![]() |
66115b7173 | ||
![]() |
4f72533e45 | ||
![]() |
33a99b6c97 | ||
![]() |
e1796d73e4 | ||
![]() |
3e1f47b193 | ||
![]() |
3451eadc87 | ||
![]() |
520368d3a1 | ||
![]() |
3d6d917b49 | ||
![]() |
1d34e69895 | ||
![]() |
d0d71572ef | ||
![]() |
69451b63b8 | ||
![]() |
4cef38cbce | ||
![]() |
f1be45b9ab | ||
![]() |
b86b537e2b | ||
![]() |
5cb4d14be7 | ||
![]() |
7bae8cf0e8 | ||
![]() |
02612a5e97 | ||
![]() |
98b231f5af | ||
![]() |
8a129181d9 | ||
![]() |
4787cce9c3 | ||
![]() |
8e7cc77ab9 | ||
![]() |
5a6b6bb1c3 | ||
![]() |
1f37ab54c8 | ||
![]() |
6757c5e650 | ||
![]() |
be5c441f0d | ||
![]() |
343bc3cc2f | ||
![]() |
1a59b03b8b | ||
![]() |
1ac83f052b | ||
![]() |
3b5a8e6656 | ||
![]() |
223c35895d | ||
![]() |
13c082a4b3 | ||
![]() |
966bf442ea | ||
![]() |
32f883f2c8 | ||
![]() |
61622b6c0a | ||
![]() |
4ed079e554 | ||
![]() |
d18cfbea8d | ||
![]() |
81ad4b8744 | ||
![]() |
cfcb385d2b | ||
![]() |
5e2a2f1923 | ||
![]() |
81037a4f7b | ||
![]() |
3eeb3186dd | ||
![]() |
6f8181a0ea | ||
![]() |
368be5bbf0 | ||
![]() |
9cc7563ef7 | ||
![]() |
847613ee23 | ||
![]() |
1af9ab3830 | ||
![]() |
4c0811d6d3 | ||
![]() |
bfe33aff05 | ||
![]() |
55a857d66a | ||
![]() |
684c3a8487 | ||
![]() |
9d6b2c32e8 | ||
![]() |
e6c1b2487a | ||
![]() |
506cc732d4 | ||
![]() |
62a9200adf | ||
![]() |
1126e5084e | ||
![]() |
e47f6a420a | ||
![]() |
19eb759935 | ||
![]() |
03274db805 | ||
![]() |
1d51af8e6a | ||
![]() |
00d592baeb | ||
![]() |
79f5fc819f | ||
![]() |
8a41500fbe | ||
![]() |
fcd69a6202 | ||
![]() |
005b4f86af | ||
![]() |
4d091f8b2c | ||
![]() |
c035ac4746 | ||
![]() |
733250a98f | ||
![]() |
d807308d1c | ||
![]() |
083bed6459 | ||
![]() |
b80d9cca04 | ||
![]() |
2f8c46f9d7 | ||
![]() |
2a771ad30d | ||
![]() |
11048977f0 | ||
![]() |
b5198a4764 | ||
![]() |
75933dc40b | ||
![]() |
dc688ad0b2 | ||
![]() |
5cab6c42e2 | ||
![]() |
cc5b16fc9d | ||
![]() |
ba01a24d10 | ||
![]() |
a48d12ad38 | ||
![]() |
dfe8a2779d | ||
![]() |
2c0d12b627 | ||
![]() |
3a01bb540d | ||
![]() |
fba57fd3c6 | ||
![]() |
7abdbc94e9 | ||
![]() |
4f76fe6a8e | ||
![]() |
1d1f2dec19 | ||
![]() |
01fb130d1e | ||
![]() |
031c7ba276 | ||
![]() |
304c203f25 | ||
![]() |
2e02d49f78 | ||
![]() |
677631125b | ||
![]() |
675ab58887 | ||
![]() |
21a9d525da | ||
![]() |
5a860fa1ae | ||
![]() |
1b6483d0e7 | ||
![]() |
8c6f276ea5 | ||
![]() |
cb4914b39a | ||
![]() |
d825b1f709 | ||
![]() |
ca4eaaf129 | ||
![]() |
4530127b24 | ||
![]() |
a22f734463 | ||
![]() |
43ddf0c457 | ||
![]() |
2096ed00f7 | ||
![]() |
20681a5b4f | ||
![]() |
0bd70b7aec | ||
![]() |
377d0bb796 | ||
![]() |
bd55e90a0a | ||
![]() |
256e64f4cc | ||
![]() |
202fce939f | ||
![]() |
410c5bd269 | ||
![]() |
0bdbb6ef89 | ||
![]() |
7d8b8c4fb3 | ||
![]() |
0fe67a1f15 | ||
![]() |
53a29f98f5 | ||
![]() |
53afe7a5b5 | ||
![]() |
b4b0cdd1b5 | ||
![]() |
25bc48dc22 | ||
![]() |
5b842506f3 | ||
![]() |
d037d57af6 | ||
![]() |
6124995d9d | ||
![]() |
8dd8e28f8a | ||
![]() |
708c43a168 | ||
![]() |
828fe99e14 | ||
![]() |
0f979ea79a | ||
![]() |
8b48200c3e | ||
![]() |
5011643f10 | ||
![]() |
cb1c256b21 | ||
![]() |
19748dbf75 | ||
![]() |
0813144c8a | ||
![]() |
d880b079d2 | ||
![]() |
13f88ce2f7 | ||
![]() |
1116e7318e | ||
![]() |
f0eb196cb1 | ||
![]() |
28cd30a219 | ||
![]() |
f71e36d38d | ||
![]() |
7bfa539f0d | ||
![]() |
4db62cd596 | ||
![]() |
654e9a041e | ||
![]() |
9af8ec1a72 | ||
![]() |
d679de9200 | ||
![]() |
e5890a16d1 | ||
![]() |
76699419e3 | ||
![]() |
1e10ed4950 | ||
![]() |
d8a3837b58 | ||
![]() |
812f1ba385 | ||
![]() |
b8ad14b306 | ||
![]() |
b18824c9f0 | ||
![]() |
1da043e160 | ||
![]() |
f9f0a46798 | ||
![]() |
51a1c2074d | ||
![]() |
3772657346 | ||
![]() |
67831ca117 | ||
![]() |
0754fdabe3 | ||
![]() |
d290bdd91e | ||
![]() |
73f135c7fa | ||
![]() |
d5520e1e13 | ||
![]() |
58d2c2ff31 | ||
![]() |
b93fc4e17e | ||
![]() |
8f01cb5faa | ||
![]() |
a9723f45ea | ||
![]() |
b658cd4874 | ||
![]() |
48397d4073 | ||
![]() |
c41bb1b973 | ||
![]() |
58d63b3769 | ||
![]() |
6254a409a7 | ||
![]() |
dc711ae840 | ||
![]() |
274863210e | ||
![]() |
5a4a0bb928 | ||
![]() |
7e6d51ee5b | ||
![]() |
4da8ecd620 | ||
![]() |
d967a177e2 | ||
![]() |
1937b56341 | ||
![]() |
9c41fbbf3a | ||
![]() |
15b1769fc5 | ||
![]() |
f32b39dc36 | ||
![]() |
4960867083 | ||
![]() |
969f2cba67 | ||
![]() |
a0682a8245 | ||
![]() |
11eb1ff90c | ||
![]() |
ed6c88af0a | ||
![]() |
00503bc68b | ||
![]() |
8b6518fd1d | ||
![]() |
2402e035c5 | ||
![]() |
737a5e230f | ||
![]() |
fbbf180f25 | ||
![]() |
3db7129dbc | ||
![]() |
8c4ef03028 | ||
![]() |
c804430756 | ||
![]() |
a4ea86e71f | ||
![]() |
c4acb795c5 | ||
![]() |
67bbc48934 | ||
![]() |
c7b18dbe14 | ||
![]() |
b5b22b1a9f | ||
![]() |
2ecd06deb6 | ||
![]() |
ba98ceed2d | ||
![]() |
518dba3e05 | ||
![]() |
0389470572 | ||
![]() |
8f723a129d | ||
![]() |
5fe8e4d604 | ||
![]() |
d093818ffe | ||
![]() |
7de38c4c75 | ||
![]() |
c2b58adcbd | ||
![]() |
933ad04651 | ||
![]() |
bc50a219c9 | ||
![]() |
fa61b8872b | ||
![]() |
14f6eca8a5 | ||
![]() |
ca530b2cc6 | ||
![]() |
d6a0e35f63 | ||
![]() |
83365da33e | ||
![]() |
4a37137ae0 | ||
![]() |
391126c25c | ||
![]() |
fe86615f16 | ||
![]() |
1c561c0270 | ||
![]() |
51d97e3330 | ||
![]() |
49e4a65bc2 | ||
![]() |
3f4565907d | ||
![]() |
060d09a82f | ||
![]() |
550d248e17 | ||
![]() |
03b96b1ee4 | ||
![]() |
7c66aa285d | ||
![]() |
8fac2f4376 | ||
![]() |
fb196bcc0b | ||
![]() |
a35dac8406 | ||
![]() |
338eaa4eac | ||
![]() |
ac8a08a71b | ||
![]() |
1c8bd519b4 | ||
![]() |
745cc73fef | ||
![]() |
a0089a8516 | ||
![]() |
277a3bc1fc | ||
![]() |
2640644727 | ||
![]() |
557228b7f1 | ||
![]() |
9f7f868dd0 | ||
![]() |
1f4d9f16e1 | ||
![]() |
16dd720838 | ||
![]() |
afa4cd137b | ||
![]() |
47c1f9d2a2 | ||
![]() |
e95bba87d2 | ||
![]() |
c100db569a | ||
![]() |
e203fd51b1 | ||
![]() |
7c4db0c506 | ||
![]() |
95552d2a29 | ||
![]() |
da947a8087 | ||
![]() |
abde5f3ab5 | ||
![]() |
37a7be0dd3 | ||
![]() |
d183729cfc | ||
![]() |
9dbc29a0f2 | ||
![]() |
6b13d1de24 | ||
![]() |
41a918a6d0 | ||
![]() |
8a0216cea1 | ||
![]() |
edd01e091f | ||
![]() |
7852058eee | ||
![]() |
a5b0000bd1 | ||
![]() |
b49c7a478a | ||
![]() |
d7ab28fff8 | ||
![]() |
ee67c3ebe9 | ||
![]() |
1046f8a4de | ||
![]() |
b6e5d26963 | ||
![]() |
5f050e0b7a | ||
![]() |
5b2a45c658 | ||
![]() |
ca62688ed8 | ||
![]() |
a6145b548a | ||
![]() |
88db9d9fcc | ||
![]() |
8239cbf938 | ||
![]() |
81f32e2402 | ||
![]() |
93ab2f259e | ||
![]() |
05fe5a1454 | ||
![]() |
e2bd4f229f | ||
![]() |
5c76029233 | ||
![]() |
9d404b88a1 | ||
![]() |
0e956bb09e | ||
![]() |
b25acb4ce7 | ||
![]() |
0312146842 | ||
![]() |
78879f7581 | ||
![]() |
18496eb7e4 | ||
![]() |
b2c601819d | ||
![]() |
78b9b2d0f1 | ||
![]() |
f863cedeea | ||
![]() |
c92504a11b | ||
![]() |
6007361a95 | ||
![]() |
bf8e076d73 | ||
![]() |
6a4e739596 | ||
![]() |
1772038cde | ||
![]() |
81657dc060 | ||
![]() |
300e935beb | ||
![]() |
d188a8e7a1 | ||
![]() |
5653483733 | ||
![]() |
bdd3bf886a | ||
![]() |
a0301e7e4d | ||
![]() |
23c8cafe35 | ||
![]() |
8a7dfe02e7 | ||
![]() |
c7eb6e4282 | ||
![]() |
40dc6382c6 | ||
![]() |
fd5dd8e5ad | ||
![]() |
d6f3673f2e | ||
![]() |
9864173ab1 | ||
![]() |
2bcefe21d5 |
267
.all-contributorsrc
Normal file
267
.all-contributorsrc
Normal file
@ -0,0 +1,267 @@
|
||||
{
|
||||
"files": [
|
||||
"README.md"
|
||||
],
|
||||
"imageSize": 100,
|
||||
"commit": false,
|
||||
"contributors": [
|
||||
{
|
||||
"login": "jsoref",
|
||||
"name": "Josh Soref",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2119212?v=4",
|
||||
"profile": "https://github.com/jsoref",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "monoxgas",
|
||||
"name": "Nick Landers",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1223016?v=4",
|
||||
"profile": "https://github.com/monoxgas",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Kras4ooo",
|
||||
"name": "Krasimir Nikolov",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1948054?v=4",
|
||||
"profile": "https://github.com/Kras4ooo",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "IvanPizhenko",
|
||||
"name": "Ivan Pizhenko",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/11859904?v=4",
|
||||
"profile": "https://github.com/IvanPizhenko",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "talva-tr",
|
||||
"name": "talva-tr",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/82046981?v=4",
|
||||
"profile": "https://github.com/talva-tr",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "eltociear",
|
||||
"name": "Ikko Ashimine",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/22633385?v=4",
|
||||
"profile": "https://bandism.net/",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Zamiell",
|
||||
"name": "James",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/5511220?v=4",
|
||||
"profile": "https://github.com/Zamiell",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "wushujames",
|
||||
"name": "James Cheng",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/677529?v=4",
|
||||
"profile": "https://github.com/wushujames",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "massongit",
|
||||
"name": "Masaya Suzuki",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/15100604?v=4",
|
||||
"profile": "https://qiita.com/SUZUKI_Masaya",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "fagai",
|
||||
"name": "fagai",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1772112?v=4",
|
||||
"profile": "https://fagai.net",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "pkit",
|
||||
"name": "Constantine Peresypkin",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/805654?v=4",
|
||||
"profile": "https://github.com/pkit",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "deronnax",
|
||||
"name": "Mathieu Dupuy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/439279?v=4",
|
||||
"profile": "https://github.com/deronnax",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "JoeOvo",
|
||||
"name": "Joe Moggridge",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/100686542?v=4",
|
||||
"profile": "https://github.com/JoeOvo",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "thyarles",
|
||||
"name": "Charles Santos",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1340046?v=4",
|
||||
"profile": "https://www.credly.com/users/thyarles/badges",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "kostiantyn-korniienko-aurea",
|
||||
"name": "Kostiantyn Korniienko",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/37180625?v=4",
|
||||
"profile": "https://github.com/kostiantyn-korniienko-aurea",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lpulley",
|
||||
"name": "Logan Pulley",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/7193187?v=4",
|
||||
"profile": "https://github.com/lpulley",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "kenji-miyake",
|
||||
"name": "Kenji Miyake",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/31987104?v=4",
|
||||
"profile": "https://www.linkedin.com/in/kenji-miyake/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "adonisgarciac",
|
||||
"name": "adonisgarciac",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/71078987?v=4",
|
||||
"profile": "https://github.com/adonisgarciac",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "cfernhout",
|
||||
"name": "Chiel Fernhout",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/22294606?v=4",
|
||||
"profile": "https://github.com/cfernhout",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "albertoperdomo2",
|
||||
"name": "Alberto Perdomo",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/62241095?v=4",
|
||||
"profile": "https://github.com/albertoperdomo2",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "V0lantis",
|
||||
"name": "Arthur",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/37664438?v=4",
|
||||
"profile": "https://arthurvolant.com",
|
||||
"contributions": [
|
||||
"bug",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "rodrigorfk",
|
||||
"name": "Rodrigo Fior Kuntzer",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1995033?v=4",
|
||||
"profile": "https://github.com/rodrigorfk",
|
||||
"contributions": [
|
||||
"code",
|
||||
"test",
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "levenleven",
|
||||
"name": "Aleksey Levenstein",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6463364?v=4",
|
||||
"profile": "https://github.com/levenleven",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "dan-hill2802",
|
||||
"name": "Daniel Hill",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/5046322?v=4",
|
||||
"profile": "https://github.com/dan-hill2802",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "KeisukeYamashita",
|
||||
"name": "KeisukeYamashita",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/23056537?v=4",
|
||||
"profile": "https://keisukeyamashita.com",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "codesculpture",
|
||||
"name": "Aravind",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/63452117?v=4",
|
||||
"profile": "https://github.com/codesculpture",
|
||||
"contributions": [
|
||||
"code",
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Whadup",
|
||||
"name": "Lukas Pfahler",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2308119?v=4",
|
||||
"profile": "https://lukaspfahler.de",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
"projectName": "changed-files",
|
||||
"projectOwner": "tj-actions",
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
"skipCi": true,
|
||||
"commitConvention": "angular",
|
||||
"commitType": "docs"
|
||||
}
|
4
.codacy.yml
Normal file
4
.codacy.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
exclude_paths:
|
||||
- "*.md"
|
||||
- "dist/**"
|
5
.eslintignore
Normal file
5
.eslintignore
Normal file
@ -0,0 +1,5 @@
|
||||
dist/
|
||||
lib/
|
||||
node_modules/
|
||||
jest.config.js
|
||||
coverage/
|
85
.eslintrc.json
Normal file
85
.eslintrc.json
Normal file
@ -0,0 +1,85 @@
|
||||
{
|
||||
"plugins": [
|
||||
"jest",
|
||||
"@typescript-eslint",
|
||||
"github"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:github/recommended",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 9,
|
||||
"sourceType": "module",
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"rules": {
|
||||
"i18n-text/no-en": "off",
|
||||
"eslint-comments/no-use": "off",
|
||||
"import/no-namespace": "off",
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": "error",
|
||||
"@typescript-eslint/explicit-member-accessibility": [
|
||||
"error",
|
||||
{
|
||||
"accessibility": "no-public"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-require-imports": "error",
|
||||
"@typescript-eslint/array-type": "error",
|
||||
"@typescript-eslint/await-thenable": "error",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"camelcase": "off",
|
||||
"@typescript-eslint/consistent-type-assertions": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
"allowExpressions": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/func-call-spacing": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"@typescript-eslint/no-array-constructor": "error",
|
||||
"@typescript-eslint/no-empty-interface": "error",
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"@typescript-eslint/no-extraneous-class": "error",
|
||||
"@typescript-eslint/no-for-in-array": "error",
|
||||
"@typescript-eslint/no-inferrable-types": "error",
|
||||
"@typescript-eslint/no-misused-new": "error",
|
||||
"@typescript-eslint/no-namespace": "error",
|
||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
||||
"@typescript-eslint/no-useless-constructor": "error",
|
||||
"@typescript-eslint/no-var-requires": "error",
|
||||
"@typescript-eslint/prefer-for-of": "warn",
|
||||
"@typescript-eslint/prefer-function-type": "warn",
|
||||
"@typescript-eslint/prefer-includes": "error",
|
||||
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
||||
"@typescript-eslint/promise-function-async": "error",
|
||||
"@typescript-eslint/require-array-sort-compare": "error",
|
||||
"@typescript-eslint/restrict-plus-operands": "error",
|
||||
"no-shadow": "off",
|
||||
"@typescript-eslint/no-shadow": "error",
|
||||
"semi": "off",
|
||||
"filenames/match-regex": [
|
||||
"error",
|
||||
"^[a-zA-Z0-9\\-.]+$",
|
||||
true
|
||||
],
|
||||
"@typescript-eslint/semi": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"@typescript-eslint/type-annotation-spacing": "error",
|
||||
"@typescript-eslint/unbound-method": "error"
|
||||
},
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true,
|
||||
"jest/globals": true
|
||||
}
|
||||
}
|
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
dist/** -diff linguist-generated=true
|
12
.github/FUNDING.yml
vendored
12
.github/FUNDING.yml
vendored
@ -1,12 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: jackton1
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: tj-actions
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: []
|
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,32 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[BUG]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
17
.github/dependabot.yml
vendored
17
.github/dependabot.yml
vendored
@ -1,7 +1,24 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
versioning-strategy: widen
|
||||
labels:
|
||||
- "merge when passing"
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- "merge when passing"
|
||||
- package-ecosystem: gitsubmodule
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- "merge when passing"
|
||||
|
23
.github/workflows/auto-approve.yml
vendored
23
.github/workflows/auto-approve.yml
vendored
@ -1,23 +0,0 @@
|
||||
name: Auto approve
|
||||
|
||||
on:
|
||||
pull_request_target
|
||||
|
||||
jobs:
|
||||
auto-approve:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: hmarr/auto-approve-action@v2
|
||||
if: |
|
||||
github.actor == 'dependabot[bot]' ||
|
||||
github.actor == 'dependabot' ||
|
||||
github.actor == 'dependabot-preview[bot]' ||
|
||||
github.actor == 'dependabot-preview' ||
|
||||
github.actor == 'renovate[bot]' ||
|
||||
github.actor == 'renovate' ||
|
||||
github.actor == 'pyup-bot' ||
|
||||
github.actor == 'github-actions[bot]' ||
|
||||
github.actor == 'pre-commit-ci' ||
|
||||
github.actor == 'pre-commit-ci[bot]'
|
||||
with:
|
||||
github-token: ${{ secrets.PAT_TOKEN }}
|
56
.github/workflows/codacy-analysis.yml
vendored
Normal file
56
.github/workflows/codacy-analysis.yml
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
# This workflow checks out code, performs a Codacy security scan
|
||||
# and integrates the results with the
|
||||
# GitHub Advanced Security code scanning feature. For more information on
|
||||
# the Codacy security scan action usage and parameters, see
|
||||
# https://github.com/codacy/codacy-analysis-cli-action.
|
||||
# For more information on Codacy Analysis CLI in general, see
|
||||
# https://github.com/codacy/codacy-analysis-cli.
|
||||
|
||||
name: Codacy Security Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
- cron: '15 16 * * 2'
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
codacy-security-scan:
|
||||
name: Codacy Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Checkout the repository to the GitHub Actions runner
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
|
||||
- name: Run Codacy Analysis CLI
|
||||
continue-on-error: true
|
||||
uses: codacy/codacy-analysis-cli-action@v4.4.5
|
||||
with:
|
||||
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
|
||||
# You can also omit the token and run the tools that support default configurations
|
||||
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
verbose: true
|
||||
output: results.sarif
|
||||
format: sarif
|
||||
# Adjust severity of non-security issues
|
||||
gh-code-scanning-compat: true
|
||||
# Force 0 exit code to allow SARIF file generation
|
||||
# This will hand over control about PR rejection to the GitHub side
|
||||
max-allowed-issues: 2147483647
|
||||
|
||||
# Upload the SARIF file generated in the previous step
|
||||
- name: Upload SARIF results file
|
||||
continue-on-error: true
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: results.sarif
|
79
.github/workflows/codeql.yml
vendored
Normal file
79
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "main" ]
|
||||
schedule:
|
||||
- cron: '44 20 * * 0'
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
18
.github/workflows/greetings.yml
vendored
Normal file
18
.github/workflows/greetings.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
name: Greetings
|
||||
|
||||
on: [pull_request_target, issues]
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
greeting:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/first-interaction@v1
|
||||
continue-on-error: true
|
||||
with:
|
||||
repo-token: ${{ secrets.PAT_TOKEN }}
|
||||
issue-message: "Thanks for reporting this issue, don't forget to star this project if you haven't already to help us reach a wider audience."
|
||||
pr-message: "Thanks for implementing a fix, could you ensure that the test covers your changes if applicable."
|
178
.github/workflows/issue-comment-job-example.yml
vendored
Normal file
178
.github/workflows/issue-comment-job-example.yml
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
name: Issue Comment Job Example
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
|
||||
jobs:
|
||||
pr_commented:
|
||||
# This job only runs for pull request comments
|
||||
name: PR comment
|
||||
if: ${{ github.event.issue.pull_request }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: |
|
||||
echo A comment on PR $NUMBER
|
||||
env:
|
||||
NUMBER: ${{ github.event.issue.number }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
|
||||
- name: Run changed-files with defaults
|
||||
id: changed-files
|
||||
uses: ./
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo '${{ toJSON(steps.changed-files.outputs) }}'
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Run changed-files for old new filenames test rename
|
||||
id: changed-files-all-old-new-renamed-files
|
||||
uses: ./
|
||||
with:
|
||||
base_sha: d1c0ee4
|
||||
sha: 4d04215
|
||||
fetch_depth: 60000
|
||||
include_all_old_new_renamed_files: true
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo '${{ toJSON(steps.changed-files-all-old-new-renamed-files.outputs) }}'
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo '${{ toJSON(steps.changed-files-all-old-new-renamed-files.outputs) }}'
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Check all_old_new_renamed_files output on non windows platform
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files.outputs.all_old_new_renamed_files, 'test/test rename 1.txt,test/test rename-1.txt') && runner.os != 'Windows'"
|
||||
run: |
|
||||
echo "Invalid output: Expected to include (test/test rename 1.txt,test/test rename-1.txt) got (${{ steps.changed-files-all-old-new-renamed-files.outputs.all_old_new_renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Check all_old_new_renamed_files output on windows platform
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files.outputs.all_old_new_renamed_files, 'test\\test rename 1.txt,test\\test rename-1.txt') && runner.os == 'Windows'"
|
||||
run: |
|
||||
echo "Invalid output: Expected to not include (test\\test rename 1.txt,test\\test rename-1.txt) got (${{ steps.changed-files-all-old-new-renamed-files.outputs.all_old_new_renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Check the renamed_files output on non windows platform
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files.outputs.renamed_files, 'test/test rename-1.txt') && runner.os != 'Windows'"
|
||||
run: |
|
||||
echo "Invalid output: Expected to include (test/test rename-1.txt) got (${{ steps.changed-files-all-old-new-renamed-files.outputs.renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Check the renamed_files output on windows platform
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files.outputs.renamed_files, 'test\\test rename-1.txt') && runner.os == 'Windows'"
|
||||
run: |
|
||||
echo "Invalid output: Expected to not include (test\\test rename-1.txt) got (${{ steps.changed-files-all-old-new-renamed-files.outputs.renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
|
||||
issue_commented:
|
||||
# This job only runs for issue comments
|
||||
name: Issue comment
|
||||
if: ${{ !github.event.issue.pull_request }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: |
|
||||
echo A comment on issue $NUMBER
|
||||
env:
|
||||
NUMBER: ${{ github.event.issue.number }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
|
||||
- name: Run changed-files with defaults
|
||||
id: changed-files
|
||||
uses: ./
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo '${{ toJSON(steps.changed-files.outputs) }}'
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Run changed-files for old new filenames test rename
|
||||
id: changed-files-all-old-new-renamed-files
|
||||
uses: ./
|
||||
with:
|
||||
base_sha: d1c0ee4
|
||||
sha: 4d04215
|
||||
fetch_depth: 60000
|
||||
include_all_old_new_renamed_files: true
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo '${{ toJSON(steps.changed-files-all-old-new-renamed-files.outputs) }}'
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo '${{ toJSON(steps.changed-files-all-old-new-renamed-files.outputs) }}'
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Check all_old_new_renamed_files output on non windows platform
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files.outputs.all_old_new_renamed_files, 'test/test rename 1.txt,test/test rename-1.txt') && runner.os != 'Windows'"
|
||||
run: |
|
||||
echo "Invalid output: Expected to include (test/test rename 1.txt,test/test rename-1.txt) got (${{ steps.changed-files-all-old-new-renamed-files.outputs.all_old_new_renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Check all_old_new_renamed_files output on windows platform
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files.outputs.all_old_new_renamed_files, 'test\\test rename 1.txt,test\\test rename-1.txt') && runner.os == 'Windows'"
|
||||
run: |
|
||||
echo "Invalid output: Expected to not include (test\\test rename 1.txt,test\\test rename-1.txt) got (${{ steps.changed-files-all-old-new-renamed-files.outputs.all_old_new_renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Check the renamed_files output on non windows platform
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files.outputs.renamed_files, 'test/test rename-1.txt') && runner.os != 'Windows'"
|
||||
run: |
|
||||
echo "Invalid output: Expected to include (test/test rename-1.txt) got (${{ steps.changed-files-all-old-new-renamed-files.outputs.renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
||||
|
||||
- name: Check the renamed_files output on windows platform
|
||||
if: "!contains(steps.changed-files-all-old-new-renamed-files.outputs.renamed_files, 'test\\test rename-1.txt') && runner.os == 'Windows'"
|
||||
run: |
|
||||
echo "Invalid output: Expected to not include (test\\test rename-1.txt) got (${{ steps.changed-files-all-old-new-renamed-files.outputs.renamed_files }})"
|
||||
exit 1
|
||||
shell:
|
||||
bash
|
19
.github/workflows/label-conflict.yml
vendored
19
.github/workflows/label-conflict.yml
vendored
@ -1,19 +0,0 @@
|
||||
name: "Maintenance"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
types: [synchronize]
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: check if prs are dirty
|
||||
uses: eps1lon/actions-label-merge-conflict@releases/2.x
|
||||
with:
|
||||
dirtyLabel: "PR: needs rebase"
|
||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||
commentOnDirty: "This pull request has conflicts, please resolve those before we can evaluate the pull request."
|
||||
commentOnClean: "Conflicts have been resolved."
|
55
.github/workflows/manual-triggered-job-example.yml
vendored
Normal file
55
.github/workflows/manual-triggered-job-example.yml
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
name: Manual Triggered Job Example
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test changed-files
|
||||
runs-on: ${{ matrix.platform }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 7
|
||||
matrix:
|
||||
platform: [ubuntu-latest, windows-latest, macos-latest]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Run changed-files with defaults
|
||||
id: changed-files
|
||||
uses: ./
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo '${{ toJSON(steps.changed-files.outputs) }}'
|
||||
|
||||
- name: Run changed-files with glob filtering
|
||||
id: changed-files-glob
|
||||
uses: ./
|
||||
with:
|
||||
files: |
|
||||
test/*.txt
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo '${{ toJSON(steps.changed-files-glob.outputs) }}'
|
||||
|
||||
- name: Run changed-files with glob filtering and all_old_new_renamed_files
|
||||
id: changed-files-glob-all-old-new-renamed-files
|
||||
uses: ./
|
||||
with:
|
||||
include_all_old_new_renamed_files: true
|
||||
files: |
|
||||
test/*.txt
|
||||
|
||||
- name: Show output
|
||||
run: |
|
||||
echo '${{ toJSON(steps.changed-files-glob-all-old-new-renamed-files.outputs) }}'
|
45
.github/workflows/matrix-example.yml
vendored
Normal file
45
.github/workflows/matrix-example.yml
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
name: Matrix Example
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
changed-files:
|
||||
name: Get changed files
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: ./
|
||||
with:
|
||||
matrix: true
|
||||
- name: List all changed files
|
||||
run: echo '${{ steps.changed-files.outputs.all_changed_files }}'
|
||||
|
||||
matrix-job:
|
||||
name: Run Matrix Job
|
||||
runs-on: ubuntu-latest
|
||||
needs: [changed-files]
|
||||
strategy:
|
||||
matrix:
|
||||
files: ${{ fromJSON(needs.changed-files.outputs.matrix) }}
|
||||
max-parallel: 4
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Test
|
||||
run: |
|
||||
echo ${{ matrix.files }}
|
67
.github/workflows/multi-job-example.yml
vendored
Normal file
67
.github/workflows/multi-job-example.yml
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
name: Multi Job Example
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
pull_request:
|
||||
branches:
|
||||
- "**"
|
||||
|
||||
jobs:
|
||||
changed-files:
|
||||
name: Get changed files
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
all_changed_files: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: ./
|
||||
- name: List all changed files
|
||||
run: echo '${{ steps.changed-files.outputs.all_changed_files }}'
|
||||
|
||||
view-changed-files:
|
||||
name: View all changed files
|
||||
runs-on: ubuntu-latest
|
||||
needs: [changed-files]
|
||||
steps:
|
||||
- name: List all changed files
|
||||
run: |
|
||||
echo '${{ needs.changed-files.outputs.all_changed_files }}'
|
||||
|
||||
|
||||
changed-files-rest-api:
|
||||
name: Get changed files using REST API
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
all_changed_files: ${{ steps.changed-files.outputs.all_changed_files }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
continue-on-error: ${{ github.event_name == 'push' }}
|
||||
uses: ./
|
||||
with:
|
||||
use_rest_api: true
|
||||
- name: List all changed files
|
||||
run: echo '${{ steps.changed-files.outputs.all_changed_files }}'
|
||||
|
||||
view-changed-files-rest-api:
|
||||
name: View all changed files using REST API
|
||||
runs-on: ubuntu-latest
|
||||
needs: [changed-files-rest-api]
|
||||
steps:
|
||||
- name: List all changed files
|
||||
run: |
|
||||
echo '${{ needs.changed-files-rest-api.outputs.all_changed_files }}'
|
18
.github/workflows/rebase.yml
vendored
18
.github/workflows/rebase.yml
vendored
@ -1,18 +0,0 @@
|
||||
name: Automatic Rebase
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
jobs:
|
||||
rebase:
|
||||
name: Rebase
|
||||
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.PAT_TOKEN }}
|
||||
fetch-depth: 0 # otherwise, you will failed to push refs to dest repo
|
||||
- name: Automatic Rebase
|
||||
uses: cirrus-actions/rebase@1.4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
|
29
.github/workflows/sync-release-version.yml
vendored
29
.github/workflows/sync-release-version.yml
vendored
@ -1,4 +1,9 @@
|
||||
name: Update release version.
|
||||
name: Update release version
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
@ -8,24 +13,34 @@ jobs:
|
||||
update-version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Run release-tagger
|
||||
uses: tj-actions/release-tagger@v4
|
||||
- name: Sync release version.
|
||||
uses: tj-actions/sync-release-version@v8.5
|
||||
uses: tj-actions/sync-release-version@v13
|
||||
id: sync-release-version
|
||||
with:
|
||||
pattern: '${{ github.repository }}@'
|
||||
only_major: true
|
||||
paths: |
|
||||
README.md
|
||||
- name: Generate CHANGELOG
|
||||
uses: tj-actions/github-changelog-generator@v1.6
|
||||
- name: Sync release package version.
|
||||
uses: tj-actions/sync-release-version@v13
|
||||
id: sync-release-package-version
|
||||
with:
|
||||
output: 'HISTORY.md'
|
||||
pattern: '"version": "'
|
||||
strip_prefix: "v"
|
||||
paths: |
|
||||
package.json
|
||||
- name: Run git-cliff
|
||||
uses: tj-actions/git-cliff@v1
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
uses: peter-evans/create-pull-request@v7.0.5
|
||||
with:
|
||||
base: "main"
|
||||
labels: "merge when passing"
|
||||
title: "Upgraded to ${{ steps.sync-release-version.outputs.new_version }}"
|
||||
branch: "upgrade-to-${{ steps.sync-release-version.outputs.new_version }}"
|
||||
commit-message: "Upgraded from ${{ steps.sync-release-version.outputs.old_version }} -> ${{ steps.sync-release-version.outputs.new_version }}"
|
||||
|
2200
.github/workflows/test.yml
vendored
2200
.github/workflows/test.yml
vendored
File diff suppressed because it is too large
Load Diff
52
.github/workflows/update-readme.yml
vendored
Normal file
52
.github/workflows/update-readme.yml
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
name: Format README.md
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
sync-assets:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Run auto-doc
|
||||
uses: tj-actions/auto-doc@v3
|
||||
with:
|
||||
use_code_blocks: true
|
||||
use_major_version: true
|
||||
|
||||
- name: Run remark
|
||||
uses: tj-actions/remark@v3
|
||||
|
||||
- name: Verify Changed files
|
||||
uses: tj-actions/verify-changed-files@v20
|
||||
id: verify_changed_files
|
||||
with:
|
||||
files: |
|
||||
README.md
|
||||
|
||||
- name: README.md changed
|
||||
if: steps.verify_changed_files.outputs.files_changed == 'true'
|
||||
run: |
|
||||
echo "README.md has uncommitted changes"
|
||||
exit 1
|
||||
|
||||
- name: Create Pull Request
|
||||
if: failure()
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
with:
|
||||
base: "main"
|
||||
labels: "merge when passing"
|
||||
title: "Updated README.md"
|
||||
branch: "chore/update-readme"
|
||||
commit-message: "Updated README.md"
|
||||
body: "Updated README.md"
|
||||
token: ${{ secrets.PAT_TOKEN }}
|
41
.github/workflows/workflow-run-example.yml
vendored
Normal file
41
.github/workflows/workflow-run-example.yml
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
name: Workflow Run Example
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Matrix Example]
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
on-success:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: ./
|
||||
|
||||
- name: Echo list of changed files on success
|
||||
run: |
|
||||
echo "Changed files on success:"
|
||||
echo "${{ steps.changed-files.outputs.all_changed_files }}"
|
||||
|
||||
on-failure:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: ./
|
||||
|
||||
- name: Echo list of changed files on failure
|
||||
run: |
|
||||
echo "Changed files on failure:"
|
||||
echo "${{ steps.changed-files.outputs.all_changed_files }}"
|
107
.gitignore
vendored
107
.gitignore
vendored
@ -1,2 +1,107 @@
|
||||
# Dependency directory
|
||||
node_modules
|
||||
|
||||
# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
./.env
|
||||
.env/../.env
|
||||
./.env.local
|
||||
./.env/../.env.local
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# OS metadata
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Ignore built ts files
|
||||
__tests__/runner/*
|
||||
lib/**/*
|
||||
|
||||
# IDEA
|
||||
.idea/
|
||||
.envrc
|
||||
|
||||
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "test/demo"]
|
||||
path = test/demo
|
||||
url = git@github.com:tj-actions/demo.git
|
3
.prettierignore
Normal file
3
.prettierignore
Normal file
@ -0,0 +1,3 @@
|
||||
dist/
|
||||
lib/
|
||||
node_modules/
|
10
.prettierrc.json
Normal file
10
.prettierrc.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": false,
|
||||
"arrowParens": "avoid"
|
||||
}
|
12
.whitesource
Normal file
12
.whitesource
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"scanSettings": {
|
||||
"baseBranches": []
|
||||
},
|
||||
"checkRunSettings": {
|
||||
"vulnerableCheckRunConclusionLevel": "failure",
|
||||
"displayMode": "diff"
|
||||
},
|
||||
"issueSettings": {
|
||||
"minSeverityLevel": "LOW"
|
||||
}
|
||||
}
|
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,128 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
jtonye@ymail.com.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
9357
HISTORY.md
9357
HISTORY.md
File diff suppressed because it is too large
Load Diff
32
SECURITY.md
Normal file
32
SECURITY.md
Normal file
@ -0,0 +1,32 @@
|
||||
# Security Policy
|
||||
|
||||
## Proactive Security Measures
|
||||
|
||||
To proactively detect and address security vulnerabilities, we utilize several robust tools and processes:
|
||||
|
||||
- **Dependency Updates:** We use [Renovate](https://renovatebot.com) and [Dependabot](https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/about-dependabot-security-updates) to keep our dependencies updated and promptly patch detected vulnerabilities through automated PRs.
|
||||
- **[GitHub's Security Features](https://github.com/features/security):** Our repository and dependencies are continuously monitored via GitHub's security features, which include:
|
||||
- **Code Scanning:** Using GitHub's CodeQL, all pull requests are scanned to identify potential vulnerabilities in our source code.
|
||||
- **Automated Alerts:** Dependabot identifies vulnerabilities based on the GitHub Advisory Database and opens PRs with patches, while automated [secret scanning](https://docs.github.com/en/enterprise-cloud@latest/code-security/secret-scanning/about-secret-scanning#about-secret-scanning-for-partner-patterns) provides alerts for detected secrets.
|
||||
- **[GitGuardian Security Checks](https://www.gitguardian.com/):** We employ GitGuardian to ensure security checks are performed on the codebase, enhancing the overall security of our project.
|
||||
- **Code Analysis and Security Scanning:** With the help of [Codacy Static Code Analysis](https://www.codacy.com/) and [Codacy Security Scan](https://security.codacy.com/), we conduct thorough analyses and scans of our code for potential security risks.
|
||||
|
||||
## Reporting Security Vulnerabilities
|
||||
|
||||
Despite our best efforts to deliver secure software, we acknowledge the invaluable role of the community in identifying security breaches.
|
||||
|
||||
### Private Vulnerability Disclosures
|
||||
|
||||
We request all suspected vulnerabilities to be responsibly and privately disclosed by sending an email to [support@tj-actions.online](mailto:support@tj-actions.online).
|
||||
|
||||
### Public Vulnerability Disclosures
|
||||
|
||||
For publicly disclosed security vulnerabilities, please **IMMEDIATELY** email [support@tj-actions.online](mailto:support@tj-actions.online) with the details for prompt action.
|
||||
|
||||
Upon confirmation of a breach, reporters will receive full credit and recognition for their contribution. Please note, that we do not offer monetary compensation for reporting vulnerabilities.
|
||||
|
||||
## Communication of Security Breaches
|
||||
|
||||
We will utilize the [GitHub Security Advisory](https://github.com/tj-actions/changed-files/security/advisories) to communicate any security breaches. The advisory will be made public once a patch has been released to rectify the issue.
|
||||
|
||||
We appreciate your cooperation and contribution to maintaining the security of our software. Remember, a secure community is a strong community.
|
441
action.yml
441
action.yml
@ -1,156 +1,331 @@
|
||||
name: Changed files
|
||||
description: Get all changed files
|
||||
name: Changed Files
|
||||
description: Get all Added, Copied, Modified, Deleted, Renamed, Type changed, Unmerged, and Unknown files.
|
||||
author: tj-actions
|
||||
|
||||
inputs:
|
||||
separator:
|
||||
description: 'Split character for array output'
|
||||
required: true
|
||||
description: "Split character for output strings."
|
||||
required: false
|
||||
default: " "
|
||||
include_all_old_new_renamed_files:
|
||||
description: "Include `all_old_new_renamed_files` output. Note this can generate a large output See: #501."
|
||||
required: false
|
||||
default: "false"
|
||||
old_new_separator:
|
||||
description: "Split character for old and new filename pairs."
|
||||
required: false
|
||||
default: ","
|
||||
old_new_files_separator:
|
||||
description: "Split character for old and new renamed filename pairs."
|
||||
required: false
|
||||
default: " "
|
||||
files_from_source_file:
|
||||
description: "Source file(s) used to populate the `files` input."
|
||||
required: false
|
||||
default: ""
|
||||
files_from_source_file_separator:
|
||||
description: "Separator used to split the `files_from_source_file` input."
|
||||
default: "\n"
|
||||
required: false
|
||||
files:
|
||||
description: 'Check for file changes for all files listed (Defaults to the entire repo)'
|
||||
description: |
|
||||
File and directory patterns used to detect changes (Defaults to the entire repo if unset).
|
||||
NOTE: Multiline file/directory patterns should not include quotes.
|
||||
required: false
|
||||
default: ""
|
||||
files_separator:
|
||||
description: "Separator used to split the `files` input"
|
||||
default: "\n"
|
||||
required: false
|
||||
files_yaml:
|
||||
description: "YAML used to define a set of file patterns to detect changes"
|
||||
required: false
|
||||
default: ""
|
||||
files_yaml_from_source_file:
|
||||
description: "Source file(s) used to populate the `files_yaml` input. Example: https://github.com/tj-actions/changed-files/blob/main/test/changed-files.yml"
|
||||
required: false
|
||||
default: ""
|
||||
files_yaml_from_source_file_separator:
|
||||
description: 'Separator used to split the `files_yaml_from_source_file` input'
|
||||
default: "\n"
|
||||
required: false
|
||||
files_ignore_yaml:
|
||||
description: "YAML used to define a set of file patterns to ignore changes"
|
||||
required: false
|
||||
default: ""
|
||||
files_ignore_yaml_from_source_file:
|
||||
description: "Source file(s) used to populate the `files_ignore_yaml` input. Example: https://github.com/tj-actions/changed-files/blob/main/test/changed-files.yml"
|
||||
required: false
|
||||
default: ""
|
||||
files_ignore_yaml_from_source_file_separator:
|
||||
description: 'Separator used to split the `files_ignore_yaml_from_source_file` input'
|
||||
default: "\n"
|
||||
required: false
|
||||
files_ignore:
|
||||
description: "Ignore changes to these file(s). NOTE: Multiline file/directory patterns should not include quotes."
|
||||
required: false
|
||||
default: ""
|
||||
files_ignore_separator:
|
||||
description: "Separator used to split the `files_ignore` input"
|
||||
default: "\n"
|
||||
required: false
|
||||
files_ignore_from_source_file:
|
||||
description: "Source file(s) used to populate the `files_ignore` input"
|
||||
required: false
|
||||
default: ""
|
||||
files_ignore_from_source_file_separator:
|
||||
description: 'Separator used to split the `files_ignore_from_source_file` input'
|
||||
default: "\n"
|
||||
required: false
|
||||
sha:
|
||||
description: "Specify a different commit SHA or branch used for comparing changes"
|
||||
required: false
|
||||
base_sha:
|
||||
description: "Specify a different base commit SHA or branch used for comparing changes"
|
||||
required: false
|
||||
since:
|
||||
description: "Get changed files for commits whose timestamp is older than the given time."
|
||||
required: false
|
||||
default: ""
|
||||
until:
|
||||
description: "Get changed files for commits whose timestamp is earlier than the given time."
|
||||
required: false
|
||||
default: ""
|
||||
path:
|
||||
description: "Specify a relative path under `$GITHUB_WORKSPACE` to locate the repository."
|
||||
required: false
|
||||
default: "."
|
||||
quotepath:
|
||||
description: "Use non-ASCII characters to match files and output the filenames completely verbatim by setting this to `false`"
|
||||
default: "true"
|
||||
required: false
|
||||
diff_relative:
|
||||
description: "Exclude changes outside the current directory and show path names relative to it. NOTE: This requires you to specify the top-level directory via the `path` input."
|
||||
required: false
|
||||
default: "true"
|
||||
dir_names:
|
||||
default: "false"
|
||||
description: "Output unique changed directories instead of filenames. NOTE: This returns `.` for changed files located in the current working directory which defaults to `$GITHUB_WORKSPACE`."
|
||||
required: false
|
||||
dir_names_max_depth:
|
||||
description: "Limit the directory output to a maximum depth e.g `test/test1/test2` with max depth of `2` returns `test/test1`."
|
||||
required: false
|
||||
dir_names_exclude_current_dir:
|
||||
description: "Exclude the current directory represented by `.` from the output when `dir_names` is set to `true`."
|
||||
required: false
|
||||
default: "false"
|
||||
dir_names_include_files:
|
||||
description: "File and directory patterns to include in the output when `dir_names` is set to `true`. NOTE: This returns only the matching files and also the directory names."
|
||||
required: false
|
||||
default: ""
|
||||
dir_names_include_files_separator:
|
||||
description: "Separator used to split the `dir_names_include_files` input"
|
||||
default: "\n"
|
||||
required: false
|
||||
dir_names_deleted_files_include_only_deleted_dirs:
|
||||
description: "Include only directories that have been deleted as opposed to directory names of files that have been deleted in the `deleted_files` output when `dir_names` is set to `true`."
|
||||
required: false
|
||||
default: "false"
|
||||
json:
|
||||
description: "Output list of changed files in a JSON formatted string which can be used for matrix jobs. Example: https://github.com/tj-actions/changed-files/blob/main/.github/workflows/matrix-example.yml"
|
||||
required: false
|
||||
default: "false"
|
||||
escape_json:
|
||||
description: "Escape JSON output."
|
||||
required: false
|
||||
default: "true"
|
||||
safe_output:
|
||||
description: "Apply sanitization to output filenames before being set as output."
|
||||
required: false
|
||||
default: "true"
|
||||
fetch_depth:
|
||||
description: "Depth of additional branch history fetched. NOTE: This can be adjusted to resolve errors with insufficient history."
|
||||
required: false
|
||||
default: "25"
|
||||
skip_initial_fetch:
|
||||
description: |
|
||||
Skip initially fetching additional history to improve performance for shallow repositories.
|
||||
NOTE: This could lead to errors with missing history. It's intended to be used when you've fetched all necessary history to perform the diff.
|
||||
required: false
|
||||
default: "false"
|
||||
fetch_additional_submodule_history:
|
||||
description: "Fetch additional history for submodules."
|
||||
required: false
|
||||
default: "false"
|
||||
since_last_remote_commit:
|
||||
description: "Use the last commit on the remote branch as the `base_sha`. Defaults to the last non-merge commit on the target branch for pull request events and the previous remote commit of the current branch for push events."
|
||||
required: false
|
||||
default: "false"
|
||||
write_output_files:
|
||||
description: "Write outputs to the `output_dir` defaults to `.github/outputs` folder. NOTE: This creates a `.txt` file by default and a `.json` file if `json` is set to `true`."
|
||||
required: false
|
||||
default: "false"
|
||||
output_dir:
|
||||
description: "Directory to store output files."
|
||||
required: false
|
||||
default: ".github/outputs"
|
||||
output_renamed_files_as_deleted_and_added:
|
||||
description: "Output renamed files as deleted and added files."
|
||||
required: false
|
||||
default: "false"
|
||||
recover_deleted_files:
|
||||
description: "Recover deleted files."
|
||||
required: false
|
||||
default: "false"
|
||||
recover_deleted_files_to_destination:
|
||||
description: "Recover deleted files to a new destination directory, defaults to the original location."
|
||||
required: false
|
||||
default: ""
|
||||
recover_files:
|
||||
description: |
|
||||
File and directory patterns used to recover deleted files,
|
||||
defaults to the patterns provided via the `files`, `files_from_source_file`, `files_ignore` and `files_ignore_from_source_file` inputs
|
||||
or all deleted files if no patterns are provided.
|
||||
required: false
|
||||
default: ""
|
||||
recover_files_separator:
|
||||
description: "Separator used to split the `recover_files` input"
|
||||
default: "\n"
|
||||
required: false
|
||||
recover_files_ignore:
|
||||
description: "File and directory patterns to ignore when recovering deleted files."
|
||||
required: false
|
||||
default: ""
|
||||
recover_files_ignore_separator:
|
||||
description: "Separator used to split the `recover_files_ignore` input"
|
||||
default: "\n"
|
||||
required: false
|
||||
token:
|
||||
description: "GitHub token used to fetch changed files from Github's API."
|
||||
required: false
|
||||
default: ${{ github.token }}
|
||||
api_url:
|
||||
description: "Github API URL."
|
||||
required: false
|
||||
default: ${{ github.api_url }}
|
||||
use_rest_api:
|
||||
description: "Force the use of Github's REST API even when a local copy of the repository exists"
|
||||
required: false
|
||||
default: "false"
|
||||
fail_on_initial_diff_error:
|
||||
description: "Fail when the initial diff fails."
|
||||
required: false
|
||||
default: "false"
|
||||
fail_on_submodule_diff_error:
|
||||
description: "Fail when the submodule diff fails."
|
||||
required: false
|
||||
default: "false"
|
||||
negation_patterns_first:
|
||||
description: "Apply the negation patterns first. NOTE: This affects how changed files are matched."
|
||||
required: false
|
||||
default: "false"
|
||||
matrix:
|
||||
description: "Output changed files in a format that can be used for matrix jobs. Alias for setting inputs `json` to `true` and `escape_json` to `false`."
|
||||
required: false
|
||||
default: "false"
|
||||
exclude_submodules:
|
||||
description: "Exclude changes to submodules."
|
||||
required: false
|
||||
default: "false"
|
||||
fetch_missing_history_max_retries:
|
||||
description: "Maximum number of retries to fetch missing history."
|
||||
required: false
|
||||
default: "20"
|
||||
use_posix_path_separator:
|
||||
description: "Use POSIX path separator `/` for output file paths on Windows."
|
||||
required: false
|
||||
default: "false"
|
||||
tags_pattern:
|
||||
description: "Tags pattern to include."
|
||||
required: false
|
||||
default: "*"
|
||||
tags_ignore_pattern:
|
||||
description: "Tags pattern to ignore."
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
|
||||
outputs:
|
||||
added_files:
|
||||
description: List of added files.
|
||||
value: ${{ steps.changed_files.outputs.added_files }}
|
||||
description: "Returns only files that are Added (A)."
|
||||
added_files_count:
|
||||
description: "Returns the number of `added_files`"
|
||||
copied_files:
|
||||
description: List of copied files.
|
||||
value: ${{ steps.changed_files.outputs.copied_files }}
|
||||
description: "Returns only files that are Copied (C)."
|
||||
copied_files_count:
|
||||
description: "Returns the number of `copied_files`"
|
||||
deleted_files:
|
||||
description: List of deleted files.
|
||||
value: ${{ steps.changed_files.outputs.deleted_files }}
|
||||
description: "Returns only files that are Deleted (D)."
|
||||
deleted_files_count:
|
||||
description: "Returns the number of `deleted_files`"
|
||||
modified_files:
|
||||
description: List of modified files.
|
||||
value: ${{ steps.changed_files.outputs.modified_files }}
|
||||
description: "Returns only files that are Modified (M)."
|
||||
modified_files_count:
|
||||
description: "Returns the number of `modified_files`"
|
||||
renamed_files:
|
||||
description: List of renamed files.
|
||||
value: ${{ steps.changed_files.outputs.renamed_files }}
|
||||
changed_files:
|
||||
description: List of changed files.
|
||||
value: ${{ steps.changed_files.outputs.changed_files }}
|
||||
description: "Returns only files that are Renamed (R)."
|
||||
renamed_files_count:
|
||||
description: "Returns the number of `renamed_files`"
|
||||
all_old_new_renamed_files:
|
||||
description: "Returns only files that are Renamed and lists their old and new names. **NOTE:** This requires setting `include_all_old_new_renamed_files` to `true`. Also, keep in mind that this output is global and wouldn't be nested in outputs generated when the `*_yaml_*` input is used. (R)"
|
||||
all_old_new_renamed_files_count:
|
||||
description: "Returns the number of `all_old_new_renamed_files`"
|
||||
type_changed_files:
|
||||
description: "Returns only files that have their file type changed (T)."
|
||||
type_changed_files_count:
|
||||
description: "Returns the number of `type_changed_files`"
|
||||
unmerged_files:
|
||||
description: List of unmerged files.
|
||||
value: ${{ steps.changed_files.outputs.unmerged_files }}
|
||||
description: "Returns only files that are Unmerged (U)."
|
||||
unmerged_files_count:
|
||||
description: "Returns the number of `unmerged_files`"
|
||||
unknown_files:
|
||||
description: List of unknown files.
|
||||
value: ${{ steps.changed_files.outputs.unknown_files }}
|
||||
description: "Returns only files that are Unknown (X)."
|
||||
unknown_files_count:
|
||||
description: "Returns the number of `unknown_files`"
|
||||
all_changed_and_modified_files:
|
||||
description: "Returns all changed and modified files i.e. a combination of (ACMRDTUX)"
|
||||
all_changed_and_modified_files_count:
|
||||
description: "Returns the number of `all_changed_and_modified_files`"
|
||||
all_changed_files:
|
||||
description: List of all changed files.
|
||||
value: ${{ steps.changed_files.outputs.all_changed_files }}
|
||||
description: "Returns all changed files i.e. a combination of all added, copied, modified and renamed files (ACMR)"
|
||||
all_changed_files_count:
|
||||
description: "Returns the number of `all_changed_files`"
|
||||
any_changed:
|
||||
description: "Returns `true` when any of the filenames provided using the `files*` or `files_ignore*` inputs have changed. This defaults to `true` when no patterns are specified. i.e. *includes a combination of all added, copied, modified and renamed files (ACMR)*."
|
||||
only_changed:
|
||||
description: "Returns `true` when only files provided using the `files*` or `files_ignore*` inputs have changed. i.e. *includes a combination of all added, copied, modified and renamed files (ACMR)*."
|
||||
other_changed_files:
|
||||
description: "Returns all other changed files not listed in the files input i.e. includes a combination of all added, copied, modified and renamed files (ACMR)."
|
||||
other_changed_files_count:
|
||||
description: "Returns the number of `other_changed_files`"
|
||||
all_modified_files:
|
||||
description: List of all copied modified and added files
|
||||
value: ${{ steps.changed_files.outputs.all_modified_files }}
|
||||
has_changed:
|
||||
description: Return true only when all files provided using the files input have all changed.
|
||||
value: ${{ steps.changed_files.outputs.has_changed }}
|
||||
description: "Returns all changed files i.e. a combination of all added, copied, modified, renamed and deleted files (ACMRD)."
|
||||
all_modified_files_count:
|
||||
description: "Returns the number of `all_modified_files`"
|
||||
any_modified:
|
||||
description: "Returns `true` when any of the filenames provided using the `files*` or `files_ignore*` inputs have been modified. This defaults to `true` when no patterns are specified. i.e. *includes a combination of all added, copied, modified, renamed, and deleted files (ACMRD)*."
|
||||
only_modified:
|
||||
description: "Returns `true` when only files provided using the `files*` or `files_ignore*` inputs have been modified. (ACMRD)."
|
||||
other_modified_files:
|
||||
description: "Returns all other modified files not listed in the files input i.e. a combination of all added, copied, modified, and deleted files (ACMRD)"
|
||||
other_modified_files_count:
|
||||
description: "Returns the number of `other_modified_files`"
|
||||
any_deleted:
|
||||
description: "Returns `true` when any of the filenames provided using the `files*` or `files_ignore*` inputs have been deleted. This defaults to `true` when no patterns are specified. (D)"
|
||||
only_deleted:
|
||||
description: "Returns `true` when only files provided using the `files*` or `files_ignore*` inputs have been deleted. (D)"
|
||||
other_deleted_files:
|
||||
description: "Returns all other deleted files not listed in the files input i.e. a combination of all deleted files (D)"
|
||||
other_deleted_files_count:
|
||||
description: "Returns the number of `other_deleted_files`"
|
||||
modified_keys:
|
||||
description: "Returns all modified YAML keys when the `files_yaml` input is used. i.e. key that contains any path that has either been added, copied, modified, and deleted (ACMRD)"
|
||||
changed_keys:
|
||||
description: "Returns all changed YAML keys when the `files_yaml` input is used. i.e. key that contains any path that has either been added, copied, modified, and renamed (ACMR)"
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- id: changed_files
|
||||
run: |
|
||||
echo "Getting head sha..."
|
||||
|
||||
if [[ -z $GITHUB_BASE_REF ]]; then
|
||||
HEAD_SHA=$(git rev-parse HEAD^1 || true)
|
||||
else
|
||||
TARGET_BRANCH=${GITHUB_BASE_REF}
|
||||
git fetch --depth=1 origin ${TARGET_BRANCH}:${TARGET_BRANCH}
|
||||
HEAD_SHA=$(git rev-parse ${TARGET_BRANCH} || true)
|
||||
fi
|
||||
|
||||
INPUT_FILES="${{ inputs.files }}"
|
||||
|
||||
if [[ -z "$INPUT_FILES" ]]; then
|
||||
|
||||
echo "Getting diff..."
|
||||
|
||||
ADDED=$(git diff --diff-filter=A --name-only "$HEAD_SHA" | tr "\n" "${{ inputs.separator }}" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
COPIED=$(git diff --diff-filter=C --name-only "$HEAD_SHA" | tr "\n" "${{ inputs.separator }}" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
DELETED=$(git diff --diff-filter=D --name-only "$HEAD_SHA" | tr "\n" "${{ inputs.separator }}" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
MODIFIED=$(git diff --diff-filter=M --name-only "$HEAD_SHA" | tr "\n" "${{ inputs.separator }}" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
RENAMED=$(git diff --diff-filter=R --name-only "$HEAD_SHA" | tr "\n" "${{ inputs.separator }}" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
CHANGED=$(git diff --diff-filter=T --name-only "$HEAD_SHA" | tr "\n" "${{ inputs.separator }}" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
UNMERGED=$(git diff --diff-filter=U --name-only "$HEAD_SHA" | tr "\n" "${{ inputs.separator }}" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
UNKNOWN=$(git diff --diff-filter=X --name-only "$HEAD_SHA" | tr "\n" "${{ inputs.separator }}" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
ALL_CHANGED=$(git diff --diff-filter='*ACDMRTUX' --name-only "$HEAD_SHA" | tr "\n" "${{ inputs.separator }}" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
ALL_MODIFIED_FILES=$(git diff --diff-filter='ACM' --name-only "$HEAD_SHA" | tr "\n" "${{ inputs.separator }}" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
|
||||
echo "::set-output name=added_files::$ADDED"
|
||||
echo "::set-output name=copied_files::$COPIED"
|
||||
echo "::set-output name=deleted_files::$DELETED"
|
||||
echo "::set-output name=modified_files::$MODIFIED"
|
||||
echo "::set-output name=renamed_files::$RENAMED"
|
||||
echo "::set-output name=changed_files::$CHANGED"
|
||||
echo "::set-output name=unmerged_files::$UNMERGED"
|
||||
echo "::set-output name=unknown_files::$UNKNOWN"
|
||||
echo "::set-output name=all_changed_files::$ALL_CHANGED"
|
||||
echo "::set-output name=all_modified_files::$ALL_MODIFIED_FILES"
|
||||
|
||||
else
|
||||
ADDED=()
|
||||
COPIED=()
|
||||
DELETED=()
|
||||
MODIFIED=()
|
||||
RENAMED=()
|
||||
CHANGED=()
|
||||
UNMERGED=()
|
||||
UNKNOWN=()
|
||||
ALL_CHANGED=()
|
||||
ALL_MODIFIED_FILES=()
|
||||
|
||||
for path in ${INPUT_FILES}
|
||||
do
|
||||
echo "Checking for file changes: \"${path}\"..."
|
||||
ADDED+=$(git diff --diff-filter=A --name-only "$HEAD_SHA" | grep -E "(${path})" | xargs printf "%s${{ inputs.separator }}" || true)
|
||||
COPIED+=$(git diff --diff-filter=C --name-only "$HEAD_SHA" | grep -E "(${path})" | xargs printf "%s${{ inputs.separator }}" || true)
|
||||
DELETED+=$(git diff --diff-filter=D --name-only "$HEAD_SHA" | grep -E "(${path})" | xargs printf "%s${{ inputs.separator }}" || true)
|
||||
MODIFIED+=$(git diff --diff-filter=M --name-only "$HEAD_SHA" | grep -E "(${path})" | xargs printf "%s${{ inputs.separator }}" || true)
|
||||
RENAMED+=$(git diff --diff-filter=R --name-only "$HEAD_SHA" | grep -E "(${path})" | xargs printf "%s${{ inputs.separator }}" || true)
|
||||
CHANGED+=$(git diff --diff-filter=T --name-only "$HEAD_SHA" | grep -E "(${path})" | xargs printf "%s${{ inputs.separator }}" || true)
|
||||
UNMERGED+=$(git diff --diff-filter=U --name-only "$HEAD_SHA" | grep -E "(${path})" | xargs printf "%s${{ inputs.separator }}" || true)
|
||||
UNKNOWN+=$(git diff --diff-filter=X --name-only "$HEAD_SHA" | grep -E "(${path})" | xargs printf "%s${{ inputs.separator }}" || true)
|
||||
ALL_CHANGED+=$(git diff --diff-filter='*ACDMRTUX' --name-only "$HEAD_SHA" | grep -E "(${path})" | xargs printf "%s${{ inputs.separator }}" || true)
|
||||
ALL_MODIFIED_FILES+=$(git diff --diff-filter='ACM' --name-only "$HEAD_SHA" | grep -E "(${path})" | xargs printf "%s${{ inputs.separator }}" || true)
|
||||
done
|
||||
|
||||
ADDED=$(echo "$ADDED" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
COPIED=$(echo $COPIED | sed -E 's/(${{ inputs.separator }})$//')
|
||||
DELETED=$(echo "$DELETED" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
MODIFIED=$(echo "$MODIFIED" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
RENAMED=$(echo "$RENAMED" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
CHANGED=$(echo "$CHANGED" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
UNMERGED=$(echo "$UNMERGED" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
UNKNOWN=$(echo "$UNKNOWN" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
ALL_CHANGED=$(echo "$ALL_CHANGED" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
ALL_MODIFIED_FILES=$(echo "$ALL_MODIFIED_FILES" | sed -E 's/(${{ inputs.separator }})$//')
|
||||
|
||||
OUTPUT_ALL_MODIFIED_FILES=$(echo $ALL_MODIFIED_FILES | sed "s/${{ inputs.separator }}/ /g")
|
||||
ALL_INPUT_FILES=$(echo $INPUT_FILES | sed "s/\n/ /g")
|
||||
|
||||
IFS=$'\n' SORTED_INPUT_FILES=($(sort <<<"${ALL_INPUT_FILES[*]}"))
|
||||
IFS=$'\n' SORTED_OUTPUT_ALL_MODIFIED_FILES=($(sort <<<"${OUTPUT_ALL_MODIFIED_FILES[*]}"))
|
||||
|
||||
if [[ "${SORTED_INPUT_FILES[*]}" == "${SORTED_OUTPUT_ALL_MODIFIED_FILES[*]}" ]]; then
|
||||
echo "::set-output name=has_changed::true"
|
||||
else
|
||||
echo "::set-output name=has_changed::false"
|
||||
fi
|
||||
|
||||
echo "::set-output name=added_files::$ADDED"
|
||||
echo "::set-output name=copied_files::$COPIED"
|
||||
echo "::set-output name=deleted_files::$DELETED"
|
||||
echo "::set-output name=modified_files::$MODIFIED"
|
||||
echo "::set-output name=renamed_files::$RENAMED"
|
||||
echo "::set-output name=changed_files::$CHANGED"
|
||||
echo "::set-output name=unmerged_files::$UNMERGED"
|
||||
echo "::set-output name=unknown_files::$UNKNOWN"
|
||||
echo "::set-output name=all_changed_files::$ALL_CHANGED"
|
||||
echo "::set-output name=all_modified_files::$ALL_MODIFIED_FILES"
|
||||
fi
|
||||
shell: bash
|
||||
using: 'node20'
|
||||
main: 'dist/index.js'
|
||||
|
||||
branding:
|
||||
icon: file-text
|
||||
|
71049
dist/index.js
generated
vendored
Normal file
71049
dist/index.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/index.js.map
generated
vendored
Normal file
1
dist/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
6055
dist/licenses.txt
generated
vendored
Normal file
6055
dist/licenses.txt
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
dist/sourcemap-register.js
generated
vendored
Normal file
1
dist/sourcemap-register.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
13
jest.config.js
Normal file
13
jest.config.js
Normal file
@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
moduleFileExtensions: ['js', 'ts'],
|
||||
testMatch: ['**/*.test.ts'],
|
||||
transform: {
|
||||
'^.+\\.ts$': 'ts-jest'
|
||||
},
|
||||
verbose: true,
|
||||
testTimeout: 10000,
|
||||
setupFiles: [
|
||||
"<rootDir>/jest/setupEnv.cjs"
|
||||
]
|
||||
};
|
8
jest/setupEnv.cjs
Normal file
8
jest/setupEnv.cjs
Normal file
@ -0,0 +1,8 @@
|
||||
const path = require('path')
|
||||
|
||||
process.env.GITHUB_WORKSPACE = path.join(
|
||||
path.resolve(__dirname, '..'), '.'
|
||||
)
|
||||
process.env.GITHUB_ACTION_PATH = path.join(
|
||||
path.resolve(__dirname, '..'), '.'
|
||||
)
|
64
package.json
Normal file
64
package.json
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "@tj-actions/changed-files",
|
||||
"version": "45.0.4",
|
||||
"description": "Github action to retrieve all (added, copied, modified, deleted, renamed, type changed, unmerged, unknown) files and directories.",
|
||||
"main": "lib/main.js",
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"format": "prettier --write src/*.ts src/**/*.ts",
|
||||
"format-check": "prettier --check src/*.ts src/**/*.ts",
|
||||
"lint": "eslint src/*.ts src/**/*.ts --max-warnings 0",
|
||||
"lint:fix": "eslint --fix src/*.ts src/**/*.ts",
|
||||
"package": "ncc build lib/main.js --source-map --license licenses.txt",
|
||||
"test": "jest --coverage",
|
||||
"update-snapshot": "jest -u",
|
||||
"all": "yarn build && yarn format && yarn lint && yarn package && yarn test"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/tj-actions/changed-files.git"
|
||||
},
|
||||
"keywords": [
|
||||
"actions",
|
||||
"glob",
|
||||
"github-actions"
|
||||
],
|
||||
"author": "Tonye Jack",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/tj-actions/changed-files/issues"
|
||||
},
|
||||
"homepage": "https://github.com/tj-actions/changed-files#readme",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/github": "^6.0.0",
|
||||
"@octokit/rest": "^21.0.0",
|
||||
"@stdlib/utils-convert-path": "^0.2.1",
|
||||
"lodash": "^4.17.21",
|
||||
"micromatch": "^4.0.5",
|
||||
"yaml": "^2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/lodash": "^4.14.195",
|
||||
"@types/micromatch": "^4.0.2",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
||||
"@typescript-eslint/parser": "^7.0.0",
|
||||
"@vercel/ncc": "^0.38.0",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-github": "^5.0.0",
|
||||
"eslint-plugin-jest": "^28.0.0",
|
||||
"eslint-plugin-prettier": "^5.0.0-alpha.2",
|
||||
"jest": "^29.5.0",
|
||||
"prettier": "^3.0.0",
|
||||
"ts-jest": "^29.1.0",
|
||||
"typescript": "^5.1.3"
|
||||
}
|
||||
}
|
@ -7,7 +7,8 @@
|
||||
"prConcurrentLimit": 5,
|
||||
"rebaseWhen": "behind-base-branch",
|
||||
"addLabels": [
|
||||
"dependencies"
|
||||
"dependencies",
|
||||
"merge when passing"
|
||||
],
|
||||
"assignees": [
|
||||
"jackton1"
|
||||
@ -19,13 +20,21 @@
|
||||
"enabled": true,
|
||||
"automerge": true
|
||||
},
|
||||
"nvm": {
|
||||
"enabled": false
|
||||
},
|
||||
"packageRules": [
|
||||
{
|
||||
"matchUpdateTypes": ["major", "minor", "patch", "pin", "digest"],
|
||||
"matchUpdateTypes": [
|
||||
"minor",
|
||||
"patch",
|
||||
"pin",
|
||||
"digest"
|
||||
],
|
||||
"automerge": true,
|
||||
"rebaseWhen": "behind-base-branch",
|
||||
"addLabels": [
|
||||
"automerge"
|
||||
"merge when passing"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -33,10 +42,15 @@
|
||||
"matchLanguages": [
|
||||
"docker"
|
||||
],
|
||||
"matchUpdateTypes": ["major", "minor", "patch", "pin", "digest"],
|
||||
"matchUpdateTypes": [
|
||||
"minor",
|
||||
"patch",
|
||||
"pin",
|
||||
"digest"
|
||||
],
|
||||
"rebaseWhen": "behind-base-branch",
|
||||
"addLabels": [
|
||||
"automerge"
|
||||
"merge when passing"
|
||||
],
|
||||
"automerge": true
|
||||
}
|
||||
|
373
src/__tests__/__snapshots__/inputs.test.ts.snap
Normal file
373
src/__tests__/__snapshots__/inputs.test.ts.snap
Normal file
@ -0,0 +1,373 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`getInputs should correctly parse boolean inputs 1`] = `
|
||||
{
|
||||
"apiUrl": "",
|
||||
"baseSha": "",
|
||||
"diffRelative": "false",
|
||||
"dirNames": "false",
|
||||
"dirNamesDeletedFilesIncludeOnlyDeletedDirs": "false",
|
||||
"dirNamesExcludeCurrentDir": "false",
|
||||
"dirNamesIncludeFiles": "",
|
||||
"dirNamesIncludeFilesSeparator": "",
|
||||
"escapeJson": false,
|
||||
"excludeSubmodules": "false",
|
||||
"failOnInitialDiffError": "false",
|
||||
"failOnSubmoduleDiffError": "false",
|
||||
"fetchAdditionalSubmoduleHistory": "false",
|
||||
"fetchMissingHistoryMaxRetries": 20,
|
||||
"files": "",
|
||||
"filesFromSourceFile": "",
|
||||
"filesFromSourceFileSeparator": "",
|
||||
"filesIgnore": "",
|
||||
"filesIgnoreFromSourceFile": "",
|
||||
"filesIgnoreFromSourceFileSeparator": "",
|
||||
"filesIgnoreSeparator": "",
|
||||
"filesIgnoreYaml": "",
|
||||
"filesIgnoreYamlFromSourceFile": "",
|
||||
"filesIgnoreYamlFromSourceFileSeparator": "",
|
||||
"filesSeparator": "",
|
||||
"filesYaml": "",
|
||||
"filesYamlFromSourceFile": "",
|
||||
"filesYamlFromSourceFileSeparator": "",
|
||||
"includeAllOldNewRenamedFiles": "false",
|
||||
"json": true,
|
||||
"negationPatternsFirst": "false",
|
||||
"oldNewFilesSeparator": " ",
|
||||
"oldNewSeparator": ",",
|
||||
"outputDir": "",
|
||||
"outputRenamedFilesAsDeletedAndAdded": "false",
|
||||
"path": ".",
|
||||
"quotepath": "false",
|
||||
"recoverDeletedFiles": "false",
|
||||
"recoverDeletedFilesToDestination": "",
|
||||
"recoverFiles": "",
|
||||
"recoverFilesIgnore": "",
|
||||
"recoverFilesIgnoreSeparator": "
|
||||
",
|
||||
"recoverFilesSeparator": "
|
||||
",
|
||||
"safeOutput": "false",
|
||||
"separator": "",
|
||||
"sha": "",
|
||||
"since": "",
|
||||
"sinceLastRemoteCommit": "false",
|
||||
"skipInitialFetch": "true",
|
||||
"tagsIgnorePattern": "",
|
||||
"tagsPattern": "*",
|
||||
"token": "",
|
||||
"until": "",
|
||||
"usePosixPathSeparator": "false",
|
||||
"useRestApi": "false",
|
||||
"writeOutputFiles": "false",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`getInputs should correctly parse numeric inputs 1`] = `
|
||||
{
|
||||
"apiUrl": "",
|
||||
"baseSha": "",
|
||||
"diffRelative": true,
|
||||
"dirNames": false,
|
||||
"dirNamesDeletedFilesIncludeOnlyDeletedDirs": false,
|
||||
"dirNamesExcludeCurrentDir": false,
|
||||
"dirNamesIncludeFiles": "",
|
||||
"dirNamesIncludeFilesSeparator": "",
|
||||
"dirNamesMaxDepth": 2,
|
||||
"escapeJson": false,
|
||||
"excludeSubmodules": false,
|
||||
"failOnInitialDiffError": false,
|
||||
"failOnSubmoduleDiffError": false,
|
||||
"fetchAdditionalSubmoduleHistory": false,
|
||||
"fetchDepth": 5,
|
||||
"files": "",
|
||||
"filesFromSourceFile": "",
|
||||
"filesFromSourceFileSeparator": "",
|
||||
"filesIgnore": "",
|
||||
"filesIgnoreFromSourceFile": "",
|
||||
"filesIgnoreFromSourceFileSeparator": "",
|
||||
"filesIgnoreSeparator": "",
|
||||
"filesIgnoreYaml": "",
|
||||
"filesIgnoreYamlFromSourceFile": "",
|
||||
"filesIgnoreYamlFromSourceFileSeparator": "",
|
||||
"filesSeparator": "",
|
||||
"filesYaml": "",
|
||||
"filesYamlFromSourceFile": "",
|
||||
"filesYamlFromSourceFileSeparator": "",
|
||||
"includeAllOldNewRenamedFiles": false,
|
||||
"json": false,
|
||||
"negationPatternsFirst": false,
|
||||
"oldNewFilesSeparator": "",
|
||||
"oldNewSeparator": "",
|
||||
"outputDir": "",
|
||||
"outputRenamedFilesAsDeletedAndAdded": false,
|
||||
"path": "",
|
||||
"quotepath": true,
|
||||
"recoverDeletedFiles": false,
|
||||
"recoverDeletedFilesToDestination": "",
|
||||
"recoverFiles": "",
|
||||
"recoverFilesIgnore": "",
|
||||
"recoverFilesIgnoreSeparator": "",
|
||||
"recoverFilesSeparator": "",
|
||||
"safeOutput": false,
|
||||
"separator": "",
|
||||
"sha": "",
|
||||
"since": "",
|
||||
"sinceLastRemoteCommit": false,
|
||||
"skipInitialFetch": false,
|
||||
"tagsIgnorePattern": "",
|
||||
"tagsPattern": "",
|
||||
"token": "",
|
||||
"until": "",
|
||||
"usePosixPathSeparator": false,
|
||||
"useRestApi": false,
|
||||
"writeOutputFiles": false,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`getInputs should correctly parse string inputs 1`] = `
|
||||
{
|
||||
"apiUrl": "https://api.github.com",
|
||||
"baseSha": "",
|
||||
"diffRelative": true,
|
||||
"dirNames": false,
|
||||
"dirNamesDeletedFilesIncludeOnlyDeletedDirs": false,
|
||||
"dirNamesExcludeCurrentDir": false,
|
||||
"dirNamesIncludeFiles": "",
|
||||
"dirNamesIncludeFilesSeparator": "",
|
||||
"escapeJson": false,
|
||||
"excludeSubmodules": false,
|
||||
"failOnInitialDiffError": false,
|
||||
"failOnSubmoduleDiffError": false,
|
||||
"fetchAdditionalSubmoduleHistory": false,
|
||||
"files": "",
|
||||
"filesFromSourceFile": "",
|
||||
"filesFromSourceFileSeparator": "",
|
||||
"filesIgnore": "",
|
||||
"filesIgnoreFromSourceFile": "",
|
||||
"filesIgnoreFromSourceFileSeparator": "",
|
||||
"filesIgnoreSeparator": "",
|
||||
"filesIgnoreYaml": "",
|
||||
"filesIgnoreYamlFromSourceFile": "",
|
||||
"filesIgnoreYamlFromSourceFileSeparator": "",
|
||||
"filesSeparator": "",
|
||||
"filesYaml": "",
|
||||
"filesYamlFromSourceFile": "",
|
||||
"filesYamlFromSourceFileSeparator": "",
|
||||
"includeAllOldNewRenamedFiles": false,
|
||||
"json": false,
|
||||
"negationPatternsFirst": false,
|
||||
"oldNewFilesSeparator": "",
|
||||
"oldNewSeparator": "",
|
||||
"outputDir": "",
|
||||
"outputRenamedFilesAsDeletedAndAdded": false,
|
||||
"path": "",
|
||||
"quotepath": true,
|
||||
"recoverDeletedFiles": false,
|
||||
"recoverDeletedFilesToDestination": "",
|
||||
"recoverFiles": "",
|
||||
"recoverFilesIgnore": "",
|
||||
"recoverFilesIgnoreSeparator": "",
|
||||
"recoverFilesSeparator": "",
|
||||
"safeOutput": false,
|
||||
"separator": "",
|
||||
"sha": "",
|
||||
"since": "",
|
||||
"sinceLastRemoteCommit": false,
|
||||
"skipInitialFetch": false,
|
||||
"tagsIgnorePattern": "",
|
||||
"tagsPattern": "",
|
||||
"token": "token",
|
||||
"until": "",
|
||||
"usePosixPathSeparator": false,
|
||||
"useRestApi": false,
|
||||
"writeOutputFiles": false,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`getInputs should handle invalid numeric inputs correctly 1`] = `
|
||||
{
|
||||
"apiUrl": "",
|
||||
"baseSha": "",
|
||||
"diffRelative": true,
|
||||
"dirNames": false,
|
||||
"dirNamesDeletedFilesIncludeOnlyDeletedDirs": false,
|
||||
"dirNamesExcludeCurrentDir": false,
|
||||
"dirNamesIncludeFiles": "",
|
||||
"dirNamesIncludeFilesSeparator": "",
|
||||
"dirNamesMaxDepth": 2,
|
||||
"escapeJson": false,
|
||||
"excludeSubmodules": false,
|
||||
"failOnInitialDiffError": false,
|
||||
"failOnSubmoduleDiffError": false,
|
||||
"fetchAdditionalSubmoduleHistory": false,
|
||||
"fetchDepth": NaN,
|
||||
"files": "",
|
||||
"filesFromSourceFile": "",
|
||||
"filesFromSourceFileSeparator": "",
|
||||
"filesIgnore": "",
|
||||
"filesIgnoreFromSourceFile": "",
|
||||
"filesIgnoreFromSourceFileSeparator": "",
|
||||
"filesIgnoreSeparator": "",
|
||||
"filesIgnoreYaml": "",
|
||||
"filesIgnoreYamlFromSourceFile": "",
|
||||
"filesIgnoreYamlFromSourceFileSeparator": "",
|
||||
"filesSeparator": "",
|
||||
"filesYaml": "",
|
||||
"filesYamlFromSourceFile": "",
|
||||
"filesYamlFromSourceFileSeparator": "",
|
||||
"includeAllOldNewRenamedFiles": false,
|
||||
"json": false,
|
||||
"negationPatternsFirst": false,
|
||||
"oldNewFilesSeparator": "",
|
||||
"oldNewSeparator": "",
|
||||
"outputDir": "",
|
||||
"outputRenamedFilesAsDeletedAndAdded": false,
|
||||
"path": "",
|
||||
"quotepath": true,
|
||||
"recoverDeletedFiles": false,
|
||||
"recoverDeletedFilesToDestination": "",
|
||||
"recoverFiles": "",
|
||||
"recoverFilesIgnore": "",
|
||||
"recoverFilesIgnoreSeparator": "",
|
||||
"recoverFilesSeparator": "",
|
||||
"safeOutput": false,
|
||||
"separator": "",
|
||||
"sha": "",
|
||||
"since": "",
|
||||
"sinceLastRemoteCommit": false,
|
||||
"skipInitialFetch": false,
|
||||
"tagsIgnorePattern": "",
|
||||
"tagsPattern": "",
|
||||
"token": "",
|
||||
"until": "",
|
||||
"usePosixPathSeparator": false,
|
||||
"useRestApi": false,
|
||||
"writeOutputFiles": false,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`getInputs should handle negative numeric inputs correctly 1`] = `
|
||||
{
|
||||
"apiUrl": "",
|
||||
"baseSha": "",
|
||||
"diffRelative": true,
|
||||
"dirNames": false,
|
||||
"dirNamesDeletedFilesIncludeOnlyDeletedDirs": false,
|
||||
"dirNamesExcludeCurrentDir": false,
|
||||
"dirNamesIncludeFiles": "",
|
||||
"dirNamesIncludeFilesSeparator": "",
|
||||
"dirNamesMaxDepth": -2,
|
||||
"escapeJson": false,
|
||||
"excludeSubmodules": false,
|
||||
"failOnInitialDiffError": false,
|
||||
"failOnSubmoduleDiffError": false,
|
||||
"fetchAdditionalSubmoduleHistory": false,
|
||||
"fetchDepth": 2,
|
||||
"files": "",
|
||||
"filesFromSourceFile": "",
|
||||
"filesFromSourceFileSeparator": "",
|
||||
"filesIgnore": "",
|
||||
"filesIgnoreFromSourceFile": "",
|
||||
"filesIgnoreFromSourceFileSeparator": "",
|
||||
"filesIgnoreSeparator": "",
|
||||
"filesIgnoreYaml": "",
|
||||
"filesIgnoreYamlFromSourceFile": "",
|
||||
"filesIgnoreYamlFromSourceFileSeparator": "",
|
||||
"filesSeparator": "",
|
||||
"filesYaml": "",
|
||||
"filesYamlFromSourceFile": "",
|
||||
"filesYamlFromSourceFileSeparator": "",
|
||||
"includeAllOldNewRenamedFiles": false,
|
||||
"json": false,
|
||||
"negationPatternsFirst": false,
|
||||
"oldNewFilesSeparator": "",
|
||||
"oldNewSeparator": "",
|
||||
"outputDir": "",
|
||||
"outputRenamedFilesAsDeletedAndAdded": false,
|
||||
"path": "",
|
||||
"quotepath": true,
|
||||
"recoverDeletedFiles": false,
|
||||
"recoverDeletedFilesToDestination": "",
|
||||
"recoverFiles": "",
|
||||
"recoverFilesIgnore": "",
|
||||
"recoverFilesIgnoreSeparator": "",
|
||||
"recoverFilesSeparator": "",
|
||||
"safeOutput": false,
|
||||
"separator": "",
|
||||
"sha": "",
|
||||
"since": "",
|
||||
"sinceLastRemoteCommit": false,
|
||||
"skipInitialFetch": false,
|
||||
"tagsIgnorePattern": "",
|
||||
"tagsPattern": "",
|
||||
"token": "",
|
||||
"until": "",
|
||||
"usePosixPathSeparator": false,
|
||||
"useRestApi": false,
|
||||
"writeOutputFiles": false,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`getInputs should return default values when no inputs are provided 1`] = `
|
||||
{
|
||||
"apiUrl": "",
|
||||
"baseSha": "",
|
||||
"diffRelative": true,
|
||||
"dirNames": false,
|
||||
"dirNamesDeletedFilesIncludeOnlyDeletedDirs": false,
|
||||
"dirNamesExcludeCurrentDir": false,
|
||||
"dirNamesIncludeFiles": "",
|
||||
"dirNamesIncludeFilesSeparator": "",
|
||||
"escapeJson": false,
|
||||
"excludeSubmodules": false,
|
||||
"failOnInitialDiffError": false,
|
||||
"failOnSubmoduleDiffError": false,
|
||||
"fetchAdditionalSubmoduleHistory": false,
|
||||
"fetchMissingHistoryMaxRetries": 20,
|
||||
"files": "",
|
||||
"filesFromSourceFile": "",
|
||||
"filesFromSourceFileSeparator": "",
|
||||
"filesIgnore": "",
|
||||
"filesIgnoreFromSourceFile": "",
|
||||
"filesIgnoreFromSourceFileSeparator": "",
|
||||
"filesIgnoreSeparator": "",
|
||||
"filesIgnoreYaml": "",
|
||||
"filesIgnoreYamlFromSourceFile": "",
|
||||
"filesIgnoreYamlFromSourceFileSeparator": "",
|
||||
"filesSeparator": "",
|
||||
"filesYaml": "",
|
||||
"filesYamlFromSourceFile": "",
|
||||
"filesYamlFromSourceFileSeparator": "",
|
||||
"includeAllOldNewRenamedFiles": false,
|
||||
"json": false,
|
||||
"negationPatternsFirst": false,
|
||||
"oldNewFilesSeparator": " ",
|
||||
"oldNewSeparator": ",",
|
||||
"outputDir": "",
|
||||
"outputRenamedFilesAsDeletedAndAdded": false,
|
||||
"path": ".",
|
||||
"quotepath": true,
|
||||
"recoverDeletedFiles": false,
|
||||
"recoverDeletedFilesToDestination": "",
|
||||
"recoverFiles": "",
|
||||
"recoverFilesIgnore": "",
|
||||
"recoverFilesIgnoreSeparator": "
|
||||
",
|
||||
"recoverFilesSeparator": "
|
||||
",
|
||||
"safeOutput": false,
|
||||
"separator": "",
|
||||
"sha": "",
|
||||
"since": "",
|
||||
"sinceLastRemoteCommit": false,
|
||||
"skipInitialFetch": false,
|
||||
"tagsIgnorePattern": "",
|
||||
"tagsPattern": "*",
|
||||
"token": "",
|
||||
"until": "",
|
||||
"usePosixPathSeparator": false,
|
||||
"useRestApi": false,
|
||||
"writeOutputFiles": false,
|
||||
}
|
||||
`;
|
153
src/__tests__/inputs.test.ts
Normal file
153
src/__tests__/inputs.test.ts
Normal file
@ -0,0 +1,153 @@
|
||||
import * as core from '@actions/core'
|
||||
import {getInputs, Inputs} from '../inputs'
|
||||
import {DEFAULT_VALUES_OF_UNSUPPORTED_API_INPUTS} from '../constant'
|
||||
|
||||
jest.mock('@actions/core')
|
||||
|
||||
describe('getInputs', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
test('should return default values when no inputs are provided', () => {
|
||||
;(core.getInput as jest.Mock).mockImplementation(name => {
|
||||
const camelCaseName = name.replace(/_([a-z])/g, (g: string[]) => {
|
||||
return g[1].toUpperCase()
|
||||
}) as keyof Inputs
|
||||
|
||||
return (DEFAULT_VALUES_OF_UNSUPPORTED_API_INPUTS[camelCaseName] ||
|
||||
'') as string
|
||||
})
|
||||
;(core.getBooleanInput as jest.Mock).mockImplementation(name => {
|
||||
const camelCaseName = name.replace(/_([a-z])/g, (g: string[]) => {
|
||||
return g[1].toUpperCase()
|
||||
}) as keyof Inputs
|
||||
|
||||
return (DEFAULT_VALUES_OF_UNSUPPORTED_API_INPUTS[camelCaseName] ||
|
||||
false) as boolean
|
||||
})
|
||||
expect(getInputs()).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('should correctly parse boolean inputs', () => {
|
||||
;(core.getInput as jest.Mock).mockImplementation(name => {
|
||||
const camelCaseName = name.replace(/_([a-z])/g, (g: string[]) => {
|
||||
return g[1].toUpperCase()
|
||||
}) as keyof Inputs
|
||||
|
||||
return (DEFAULT_VALUES_OF_UNSUPPORTED_API_INPUTS[camelCaseName] ||
|
||||
'') as string
|
||||
})
|
||||
;(core.getBooleanInput as jest.Mock).mockImplementation(name => {
|
||||
switch (name) {
|
||||
case 'matrix':
|
||||
return 'true'
|
||||
case 'skip_initial_fetch':
|
||||
return 'true'
|
||||
default:
|
||||
return 'false'
|
||||
}
|
||||
})
|
||||
expect(getInputs()).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('should handle matrix alias correctly', () => {
|
||||
;(core.getBooleanInput as jest.Mock).mockImplementation(name => {
|
||||
return name === 'matrix' ? 'true' : 'false'
|
||||
})
|
||||
|
||||
const inputs = getInputs()
|
||||
expect(inputs).toHaveProperty('json', true)
|
||||
expect(inputs).toHaveProperty('escapeJson', false)
|
||||
})
|
||||
|
||||
test('should correctly parse string inputs', () => {
|
||||
;(core.getInput as jest.Mock).mockImplementation(name => {
|
||||
switch (name) {
|
||||
case 'token':
|
||||
return 'token'
|
||||
case 'api_url':
|
||||
return 'https://api.github.com'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
})
|
||||
;(core.getBooleanInput as jest.Mock).mockImplementation(name => {
|
||||
const camelCaseName = name.replace(/_([a-z])/g, (g: string[]) => {
|
||||
return g[1].toUpperCase()
|
||||
}) as keyof Inputs
|
||||
|
||||
return (DEFAULT_VALUES_OF_UNSUPPORTED_API_INPUTS[camelCaseName] ||
|
||||
false) as boolean
|
||||
})
|
||||
expect(getInputs()).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('should correctly parse numeric inputs', () => {
|
||||
;(core.getInput as jest.Mock).mockImplementation(name => {
|
||||
switch (name) {
|
||||
case 'fetch_depth':
|
||||
return '5'
|
||||
case 'dir_names_max_depth':
|
||||
return '2'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
})
|
||||
;(core.getBooleanInput as jest.Mock).mockImplementation(name => {
|
||||
const camelCaseName = name.replace(/_([a-z])/g, (g: string[]) => {
|
||||
return g[1].toUpperCase()
|
||||
}) as keyof Inputs
|
||||
|
||||
return (DEFAULT_VALUES_OF_UNSUPPORTED_API_INPUTS[camelCaseName] ||
|
||||
false) as boolean
|
||||
})
|
||||
expect(getInputs()).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('should handle invalid numeric inputs correctly', () => {
|
||||
;(core.getInput as jest.Mock).mockImplementation(name => {
|
||||
// TODO: Add validation for invalid numbers which should result in an error instead of NaN
|
||||
switch (name) {
|
||||
case 'fetch_depth':
|
||||
return 'invalid'
|
||||
case 'dir_names_max_depth':
|
||||
return '2'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
})
|
||||
;(core.getBooleanInput as jest.Mock).mockImplementation(name => {
|
||||
const camelCaseName = name.replace(/_([a-z])/g, (g: string[]) => {
|
||||
return g[1].toUpperCase()
|
||||
}) as keyof Inputs
|
||||
|
||||
return (DEFAULT_VALUES_OF_UNSUPPORTED_API_INPUTS[camelCaseName] ||
|
||||
false) as boolean
|
||||
})
|
||||
expect(getInputs()).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('should handle negative numeric inputs correctly', () => {
|
||||
;(core.getInput as jest.Mock).mockImplementation(name => {
|
||||
// TODO: Add validation for negative numbers which should result in an error
|
||||
switch (name) {
|
||||
case 'fetch_depth':
|
||||
return '-5'
|
||||
case 'dir_names_max_depth':
|
||||
return '-2'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
})
|
||||
;(core.getBooleanInput as jest.Mock).mockImplementation(name => {
|
||||
const camelCaseName = name.replace(/_([a-z])/g, (g: string[]) => {
|
||||
return g[1].toUpperCase()
|
||||
}) as keyof Inputs
|
||||
|
||||
return (DEFAULT_VALUES_OF_UNSUPPORTED_API_INPUTS[camelCaseName] ||
|
||||
false) as boolean
|
||||
})
|
||||
expect(getInputs()).toMatchSnapshot()
|
||||
})
|
||||
})
|
761
src/__tests__/utils.test.ts
Normal file
761
src/__tests__/utils.test.ts
Normal file
@ -0,0 +1,761 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import {ChangeTypeEnum} from '../changedFiles'
|
||||
import {Inputs} from '../inputs'
|
||||
import {
|
||||
getDirname,
|
||||
getDirnameMaxDepth,
|
||||
getFilteredChangedFiles,
|
||||
getPreviousGitTag,
|
||||
normalizeSeparators,
|
||||
warnUnsupportedRESTAPIInputs
|
||||
} from '../utils'
|
||||
|
||||
const originalPlatform = process.platform
|
||||
|
||||
function mockedPlatform(platform: string): void {
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: platform
|
||||
})
|
||||
}
|
||||
|
||||
describe('utils test', () => {
|
||||
afterEach(() => {
|
||||
Object.defineProperty(process, 'platform', {
|
||||
value: originalPlatform
|
||||
})
|
||||
})
|
||||
|
||||
describe('getDirnameMaxDepth_function', () => {
|
||||
// Tests that the function returns the correct dirname when the relative path has multiple directories
|
||||
it('test_multiple_directories', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: 'path/to/some/file',
|
||||
dirNamesMaxDepth: 2,
|
||||
excludeCurrentDir: false
|
||||
})
|
||||
expect(result).toEqual('path/to')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname when the relative path has only one directory
|
||||
it('test_single_directory', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: 'path/to',
|
||||
dirNamesMaxDepth: 1,
|
||||
excludeCurrentDir: false
|
||||
})
|
||||
expect(result).toEqual('path')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname when the relative path has no directories
|
||||
it('test_no_directories', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: 'file.txt',
|
||||
dirNamesMaxDepth: 1,
|
||||
excludeCurrentDir: false
|
||||
})
|
||||
expect(result).toEqual('.')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname when dirNamesMaxDepth is set to a value less than the number of directories in the relative path
|
||||
it('test_dirnames_max_depth_less_than_num_directories', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: 'path/to/some/file',
|
||||
dirNamesMaxDepth: 1,
|
||||
excludeCurrentDir: false
|
||||
})
|
||||
expect(result).toEqual('path')
|
||||
})
|
||||
|
||||
// Tests that the function returns an empty string when excludeCurrentDir is true and the output is '.'
|
||||
it('test_exclude_current_dir_is_true_and_output_is_dot', () => {
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: '.',
|
||||
dirNamesMaxDepth: 1,
|
||||
excludeCurrentDir: true
|
||||
})
|
||||
expect(result).toEqual('')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname when the relative path is a Windows drive root and excludeCurrentDir is true
|
||||
it('test_windows_drive_root_and_exclude_current_dir_is_true', () => {
|
||||
mockedPlatform('win32')
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath: 'C:\\',
|
||||
dirNamesMaxDepth: 1,
|
||||
excludeCurrentDir: true
|
||||
})
|
||||
expect(result).toEqual('')
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth handles a relative path with a trailing separator correctly
|
||||
it('test_trailing_separator', () => {
|
||||
const input = {
|
||||
relativePath: 'path/to/dir/',
|
||||
dirNamesMaxDepth: 2,
|
||||
excludeCurrentDir: true
|
||||
}
|
||||
const expectedOutput = 'path/to'
|
||||
const actualOutput = getDirnameMaxDepth(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth returns an empty string when excludeCurrentDir is true and the output is '.'
|
||||
it('test_trailing_separator_exclude_current_dir', () => {
|
||||
const input = {
|
||||
relativePath: 'file',
|
||||
excludeCurrentDir: true
|
||||
}
|
||||
const expectedOutput = ''
|
||||
const actualOutput = getDirnameMaxDepth(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth returns the correct output for a Windows UNC root path
|
||||
it('test_windows_unc_root', () => {
|
||||
mockedPlatform('win32')
|
||||
const input = {
|
||||
relativePath: '\\hello',
|
||||
dirNamesMaxDepth: 2,
|
||||
excludeCurrentDir: true
|
||||
}
|
||||
const expectedOutput = ''
|
||||
expect(getDirnameMaxDepth(input)).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth returns an empty string when given a Windows UNC root and excludeCurrentDir is true
|
||||
it('test_windows_unc_root_exclude_current_dir', () => {
|
||||
mockedPlatform('win32')
|
||||
const relativePath = '\\hello'
|
||||
const result = getDirnameMaxDepth({
|
||||
relativePath,
|
||||
excludeCurrentDir: true
|
||||
})
|
||||
expect(result).toEqual('')
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth returns the correct dirname with a relative path that contains both forward and backward slashes
|
||||
it('test_relative_path_with_slashes', () => {
|
||||
const relativePath = 'path/to\file'
|
||||
const expectedOutput = 'path'
|
||||
const actualOutput = getDirnameMaxDepth({relativePath})
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that getDirnameMaxDepth returns the correct dirname for a relative path that contains special characters
|
||||
it('test_special_characters', () => {
|
||||
const relativePath =
|
||||
'path/with/special/characters/!@#$%^&*()_+{}|:<>?[];,./'
|
||||
const expectedDirname = 'path/with/special/characters'
|
||||
const actualDirname = getDirnameMaxDepth({relativePath})
|
||||
expect(actualDirname).toEqual(expectedDirname)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getDirname_function', () => {
|
||||
// Tests that the function returns the correct dirname for a valid path
|
||||
it('test valid path', () => {
|
||||
expect(getDirname('/path/to/file')).toEqual('/path/to')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname for a valid Windows UNC root path
|
||||
it('test windows unc root path', () => {
|
||||
mockedPlatform('win32')
|
||||
expect(getDirname('\\helloworld')).toEqual('.')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname for a path with a trailing slash
|
||||
it('test path with trailing slash', () => {
|
||||
expect(getDirname('/path/to/file/')).toEqual('/path/to')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname for a Windows UNC root path with a trailing slash
|
||||
it('test windows unc root path with trailing slash', () => {
|
||||
mockedPlatform('win32')
|
||||
expect(getDirname('\\hello\\world\\')).toEqual('.')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname for a path with multiple slashes
|
||||
it('test path with multiple slashes', () => {
|
||||
expect(getDirname('/path//to/file')).toEqual('/path/to')
|
||||
})
|
||||
|
||||
// Tests that the function returns the correct dirname for a Windows UNC root path with multiple slashes
|
||||
it('test windows unc root path with multiple slashes', () => {
|
||||
mockedPlatform('win32')
|
||||
expect(getDirname('\\hello\\world')).toEqual('.')
|
||||
})
|
||||
})
|
||||
|
||||
describe('normalizeSeparators_function', () => {
|
||||
// Tests that forward slashes are normalized on Linux
|
||||
it('test forward slashes linux', () => {
|
||||
const input = 'path/to/file'
|
||||
const expectedOutput = 'path/to/file'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that backslashes are normalized on Windows
|
||||
it('test backslashes windows', () => {
|
||||
mockedPlatform('win32')
|
||||
const input = 'path\\to\\file'
|
||||
const expectedOutput = 'path\\to\\file'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that forward slashes are normalized on Windows
|
||||
it('test mixed slashes windows', () => {
|
||||
mockedPlatform('win32')
|
||||
const input = 'path/to/file'
|
||||
const expectedOutput = 'path\\to\\file'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that mixed slashes are normalized on Windows
|
||||
it('test mixed slashes windows', () => {
|
||||
mockedPlatform('win32')
|
||||
const input = 'path\\to/file'
|
||||
const expectedOutput = 'path\\to\\file'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that an empty string returns an empty string
|
||||
it('test empty string', () => {
|
||||
const input = ''
|
||||
const expectedOutput = ''
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that multiple consecutive slashes are removed
|
||||
it('test multiple consecutive slashes', () => {
|
||||
const input = 'path//to//file'
|
||||
const expectedOutput = 'path/to/file'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that UNC format is preserved on Windows
|
||||
it('test unc format windows', () => {
|
||||
mockedPlatform('win32')
|
||||
const input = '\\\\hello\\world'
|
||||
const expectedOutput = '\\\\hello\\world'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
|
||||
// Tests that a drive root is preserved on Windows
|
||||
it('test drive root windows', () => {
|
||||
mockedPlatform('win32')
|
||||
const input = 'C:\\'
|
||||
const expectedOutput = 'C:\\'
|
||||
const actualOutput = normalizeSeparators(input)
|
||||
expect(actualOutput).toEqual(expectedOutput)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getFilteredChangedFiles', () => {
|
||||
// Tests that the function returns an empty object when allDiffFiles and filePatterns are empty
|
||||
it('should return an empty object when allDiffFiles and filePatterns are empty', async () => {
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles: {
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
},
|
||||
filePatterns: []
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function returns allDiffFiles when filePatterns is empty
|
||||
it('should return allDiffFiles when filePatterns is empty', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: ['file1.txt'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: []
|
||||
})
|
||||
expect(result).toEqual(allDiffFiles)
|
||||
})
|
||||
|
||||
// Tests that the function returns an empty object when allDiffFiles is empty
|
||||
it('should return an empty object when allDiffFiles is empty', async () => {
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles: {
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
},
|
||||
filePatterns: ['*.txt']
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function returns only the files that match the file patterns on non windows platforms
|
||||
it('should return only the files that match the file patterns', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: [
|
||||
'file1.txt',
|
||||
'file2.md',
|
||||
'file3.txt',
|
||||
'test/dir/file4.txt',
|
||||
'test/dir/file5.txt',
|
||||
'dir/file6.md'
|
||||
],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: ['*.txt']
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: ['file1.txt', 'file3.txt'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function returns only the files that match the file patterns on windows
|
||||
it('should return only the files that match the file patterns on windows', async () => {
|
||||
mockedPlatform('win32')
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: [
|
||||
'file1.txt',
|
||||
'file2.md',
|
||||
'file3.txt',
|
||||
'test\\dir\\file4.txt',
|
||||
'test\\dir\\file5.txt',
|
||||
'dir\\file6.md'
|
||||
],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: ['*.txt']
|
||||
})
|
||||
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: ['file1.txt', 'file3.txt'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function returns only the files that match the file patterns with globstar on non windows platforms
|
||||
it('should return only the files that match the file patterns with globstar', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: [
|
||||
'file1.txt',
|
||||
'file2.md',
|
||||
'file3.txt',
|
||||
'test/dir/file4.txt',
|
||||
'test/dir/file5.txt',
|
||||
'dir/file6.md'
|
||||
],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: ['**.txt']
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: [
|
||||
'file1.txt',
|
||||
'file3.txt',
|
||||
'test/dir/file4.txt',
|
||||
'test/dir/file5.txt'
|
||||
],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function returns only the files that match the file patterns with globstar on windows
|
||||
it('should return only the files that match the file patterns with globstar on windows', async () => {
|
||||
mockedPlatform('win32')
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: ['test\\test rename-1.txt'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: ['test/**']
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: ['test\\test rename-1.txt'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function returns an empty object when there are no files that match the file patterns
|
||||
it('should return an empty object when there are no files that match the file patterns', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: ['file1.md', 'file2.md', 'file3.md'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: ['*.txt']
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that the function can handle file names with special characters
|
||||
it('should handle file names with special characters', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: [
|
||||
'file1.txt',
|
||||
'file2 with spaces.txt',
|
||||
'file3$$.txt'
|
||||
],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const result = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: ['file2*.txt']
|
||||
})
|
||||
expect(result).toEqual({
|
||||
[ChangeTypeEnum.Added]: ['file2 with spaces.txt'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
})
|
||||
})
|
||||
|
||||
// Tests that getFilteredChangedFiles correctly filters files using glob patterns
|
||||
it('should filter files using glob patterns', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: ['test/migrations/test.sql'],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const filePatterns = ['test/migrations/**']
|
||||
const filteredFiles = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns
|
||||
})
|
||||
expect(filteredFiles[ChangeTypeEnum.Added]).toEqual([
|
||||
'test/migrations/test.sql'
|
||||
])
|
||||
})
|
||||
|
||||
// Tests that getFilteredChangedFiles correctly filters files using ignore glob patterns
|
||||
it('should filter files using ignore glob patterns', async () => {
|
||||
const allDiffFiles = {
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [
|
||||
'assets/scripts/configure-minikube-linux.sh'
|
||||
],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
const filePatterns = [
|
||||
'assets/scripts/**.sh',
|
||||
'!assets/scripts/configure-minikube-linux.sh'
|
||||
]
|
||||
const filteredFiles = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns
|
||||
})
|
||||
expect(filteredFiles[ChangeTypeEnum.Modified]).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('warnUnsupportedRESTAPIInputs', () => {
|
||||
// Warns about unsupported inputs when using the REST API.
|
||||
it('should warn about unsupported inputs when all inputs are supported', async () => {
|
||||
const inputs: Inputs = {
|
||||
files: '',
|
||||
filesSeparator: '\n',
|
||||
filesFromSourceFile: '',
|
||||
filesFromSourceFileSeparator: '\n',
|
||||
filesYaml: '',
|
||||
filesYamlFromSourceFile: '',
|
||||
filesYamlFromSourceFileSeparator: '\n',
|
||||
filesIgnore: '',
|
||||
filesIgnoreSeparator: '\n',
|
||||
filesIgnoreFromSourceFile: '',
|
||||
filesIgnoreFromSourceFileSeparator: '\n',
|
||||
filesIgnoreYaml: '',
|
||||
filesIgnoreYamlFromSourceFile: '',
|
||||
filesIgnoreYamlFromSourceFileSeparator: '\n',
|
||||
separator: ' ',
|
||||
includeAllOldNewRenamedFiles: false,
|
||||
oldNewSeparator: ',',
|
||||
oldNewFilesSeparator: ' ',
|
||||
sha: '1313123',
|
||||
baseSha: '',
|
||||
since: '',
|
||||
until: '',
|
||||
path: '.',
|
||||
quotepath: true,
|
||||
diffRelative: true,
|
||||
dirNames: false,
|
||||
dirNamesMaxDepth: undefined,
|
||||
dirNamesExcludeCurrentDir: false,
|
||||
dirNamesIncludeFiles: '',
|
||||
dirNamesIncludeFilesSeparator: '\n',
|
||||
dirNamesDeletedFilesIncludeOnlyDeletedDirs: false,
|
||||
json: false,
|
||||
escapeJson: true,
|
||||
safeOutput: true,
|
||||
fetchDepth: 50,
|
||||
fetchAdditionalSubmoduleHistory: false,
|
||||
sinceLastRemoteCommit: false,
|
||||
writeOutputFiles: false,
|
||||
outputDir: '.github/outputs',
|
||||
outputRenamedFilesAsDeletedAndAdded: false,
|
||||
recoverDeletedFiles: false,
|
||||
recoverDeletedFilesToDestination: '',
|
||||
recoverFiles: '',
|
||||
recoverFilesSeparator: '\n',
|
||||
recoverFilesIgnore: '',
|
||||
recoverFilesIgnoreSeparator: '\n',
|
||||
token: '${{ github.token }}',
|
||||
apiUrl: '${{ github.api_url }}',
|
||||
skipInitialFetch: false,
|
||||
failOnInitialDiffError: false,
|
||||
failOnSubmoduleDiffError: false,
|
||||
negationPatternsFirst: false,
|
||||
useRestApi: false,
|
||||
excludeSubmodules: false,
|
||||
fetchMissingHistoryMaxRetries: 20,
|
||||
usePosixPathSeparator: false,
|
||||
tagsPattern: '*',
|
||||
tagsIgnorePattern: ''
|
||||
}
|
||||
|
||||
const coreWarningSpy = jest.spyOn(core, 'warning')
|
||||
|
||||
await warnUnsupportedRESTAPIInputs({
|
||||
inputs
|
||||
})
|
||||
|
||||
expect(coreWarningSpy).toHaveBeenCalledWith(
|
||||
'Input "sha" is not supported when using GitHub\'s REST API to get changed files'
|
||||
)
|
||||
|
||||
expect(coreWarningSpy).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
describe('getPreviousGitTag', () => {
|
||||
// Check if the environment variable GITHUB_REPOSITORY_OWNER is 'tj-actions'
|
||||
const shouldSkip = !!process.env.GITHUB_EVENT_PULL_REQUEST_HEAD_REPO_FORK
|
||||
// Function returns the second-latest tag and its SHA
|
||||
it('should return the second latest tag and its SHA when multiple tags are present', async () => {
|
||||
if (shouldSkip) {
|
||||
return
|
||||
}
|
||||
const result = await getPreviousGitTag({
|
||||
cwd: '.',
|
||||
tagsPattern: '*',
|
||||
tagsIgnorePattern: '',
|
||||
currentBranch: 'v1.0.1'
|
||||
})
|
||||
expect(result).toEqual({
|
||||
tag: 'v1.0.0',
|
||||
sha: 'f0751de6af436d4e79016e2041cf6400e0833653'
|
||||
})
|
||||
})
|
||||
// Tags are filtered by a specified pattern when 'tagsPattern' is provided
|
||||
it('should filter tags by the specified pattern', async () => {
|
||||
if (shouldSkip) {
|
||||
return
|
||||
}
|
||||
const result = await getPreviousGitTag({
|
||||
cwd: '.',
|
||||
tagsPattern: 'v1.*',
|
||||
tagsIgnorePattern: '',
|
||||
currentBranch: 'v1.0.1'
|
||||
})
|
||||
expect(result).toEqual({
|
||||
tag: 'v1.0.0',
|
||||
sha: 'f0751de6af436d4e79016e2041cf6400e0833653'
|
||||
})
|
||||
})
|
||||
// Tags are excluded by a specified ignore pattern when 'tagsIgnorePattern' is provided
|
||||
it('should exclude tags by the specified ignore pattern', async () => {
|
||||
if (shouldSkip) {
|
||||
return
|
||||
}
|
||||
const result = await getPreviousGitTag({
|
||||
cwd: '.',
|
||||
tagsPattern: '*',
|
||||
tagsIgnorePattern: 'v0.*.*',
|
||||
currentBranch: 'v1.0.1'
|
||||
})
|
||||
expect(result).toEqual({
|
||||
tag: 'v1.0.0',
|
||||
sha: 'f0751de6af436d4e79016e2041cf6400e0833653'
|
||||
})
|
||||
})
|
||||
|
||||
// No tags are available in the repository
|
||||
it('should return empty values when no tags are available in the repository', async () => {
|
||||
jest.spyOn(exec, 'getExecOutput').mockResolvedValueOnce({
|
||||
stdout: '',
|
||||
stderr: '',
|
||||
exitCode: 0
|
||||
})
|
||||
const result = await getPreviousGitTag({
|
||||
cwd: '.',
|
||||
tagsPattern: '*',
|
||||
tagsIgnorePattern: '',
|
||||
currentBranch: ''
|
||||
})
|
||||
expect(result).toEqual({tag: '', sha: ''})
|
||||
})
|
||||
|
||||
// Only one tag is available, making it impossible to find a previous tag
|
||||
it('should return empty values when only one tag is available', async () => {
|
||||
jest.spyOn(exec, 'getExecOutput').mockResolvedValueOnce({
|
||||
stdout:
|
||||
'v1.0.1|f0751de6af436d4e79016e2041cf6400e0833653|2021-01-01T00:00:00Z',
|
||||
stderr: '',
|
||||
exitCode: 0
|
||||
})
|
||||
const result = await getPreviousGitTag({
|
||||
cwd: '.',
|
||||
tagsPattern: '*',
|
||||
tagsIgnorePattern: '',
|
||||
currentBranch: 'v1.0.1'
|
||||
})
|
||||
expect(result).toEqual({tag: '', sha: ''})
|
||||
})
|
||||
|
||||
// Git commands fail and throw errors
|
||||
it('should throw an error when git commands fail', async () => {
|
||||
jest
|
||||
.spyOn(exec, 'getExecOutput')
|
||||
.mockRejectedValue(new Error('git command failed'))
|
||||
await expect(
|
||||
getPreviousGitTag({
|
||||
cwd: '.',
|
||||
tagsPattern: '*',
|
||||
tagsIgnorePattern: '',
|
||||
currentBranch: 'v1.0.1'
|
||||
})
|
||||
).rejects.toThrow('git command failed')
|
||||
})
|
||||
})
|
||||
})
|
498
src/changedFiles.ts
Normal file
498
src/changedFiles.ts
Normal file
@ -0,0 +1,498 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as github from '@actions/github'
|
||||
import type {RestEndpointMethodTypes} from '@octokit/rest'
|
||||
import flatten from 'lodash/flatten'
|
||||
import convertPath from '@stdlib/utils-convert-path'
|
||||
import mm from 'micromatch'
|
||||
import * as path from 'path'
|
||||
import {setOutputsAndGetModifiedAndChangedFilesStatus} from './changedFilesOutput'
|
||||
import {DiffResult} from './commitSha'
|
||||
import {Inputs} from './inputs'
|
||||
import {
|
||||
canDiffCommits,
|
||||
getAllChangedFiles,
|
||||
getDirnameMaxDepth,
|
||||
getDirNamesIncludeFilesPattern,
|
||||
getFilteredChangedFiles,
|
||||
gitRenamedFiles,
|
||||
gitSubmoduleDiffSHA,
|
||||
isWindows,
|
||||
jsonOutput,
|
||||
setArrayOutput
|
||||
} from './utils'
|
||||
|
||||
export const processChangedFiles = async ({
|
||||
filePatterns,
|
||||
allDiffFiles,
|
||||
inputs,
|
||||
yamlFilePatterns,
|
||||
workingDirectory
|
||||
}: {
|
||||
filePatterns: string[]
|
||||
allDiffFiles: ChangedFiles
|
||||
inputs: Inputs
|
||||
yamlFilePatterns: Record<string, string[]>
|
||||
workingDirectory?: string
|
||||
}): Promise<void> => {
|
||||
if (filePatterns.length > 0) {
|
||||
core.startGroup('changed-files-patterns')
|
||||
const allFilteredDiffFiles = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns
|
||||
})
|
||||
core.debug(
|
||||
`All filtered diff files: ${JSON.stringify(allFilteredDiffFiles)}`
|
||||
)
|
||||
await setOutputsAndGetModifiedAndChangedFilesStatus({
|
||||
allDiffFiles,
|
||||
allFilteredDiffFiles,
|
||||
inputs,
|
||||
filePatterns,
|
||||
workingDirectory
|
||||
})
|
||||
core.info('All Done!')
|
||||
core.endGroup()
|
||||
}
|
||||
|
||||
if (Object.keys(yamlFilePatterns).length > 0) {
|
||||
const modifiedKeys: string[] = []
|
||||
const changedKeys: string[] = []
|
||||
|
||||
for (const key of Object.keys(yamlFilePatterns)) {
|
||||
core.startGroup(`changed-files-yaml-${key}`)
|
||||
const allFilteredDiffFiles = await getFilteredChangedFiles({
|
||||
allDiffFiles,
|
||||
filePatterns: yamlFilePatterns[key]
|
||||
})
|
||||
core.debug(
|
||||
`All filtered diff files for ${key}: ${JSON.stringify(
|
||||
allFilteredDiffFiles
|
||||
)}`
|
||||
)
|
||||
const {anyChanged, anyModified} =
|
||||
await setOutputsAndGetModifiedAndChangedFilesStatus({
|
||||
allDiffFiles,
|
||||
allFilteredDiffFiles,
|
||||
inputs,
|
||||
filePatterns: yamlFilePatterns[key],
|
||||
outputPrefix: key,
|
||||
workingDirectory
|
||||
})
|
||||
if (anyModified) {
|
||||
modifiedKeys.push(key)
|
||||
}
|
||||
if (anyChanged) {
|
||||
changedKeys.push(key)
|
||||
}
|
||||
|
||||
core.info('All Done!')
|
||||
core.endGroup()
|
||||
}
|
||||
|
||||
if (modifiedKeys.length > 0) {
|
||||
await setArrayOutput({
|
||||
key: 'modified_keys',
|
||||
inputs,
|
||||
value: modifiedKeys
|
||||
})
|
||||
}
|
||||
|
||||
if (changedKeys.length > 0) {
|
||||
await setArrayOutput({
|
||||
key: 'changed_keys',
|
||||
inputs,
|
||||
value: changedKeys
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (filePatterns.length === 0 && Object.keys(yamlFilePatterns).length === 0) {
|
||||
core.startGroup('changed-files-all')
|
||||
await setOutputsAndGetModifiedAndChangedFilesStatus({
|
||||
allDiffFiles,
|
||||
allFilteredDiffFiles: allDiffFiles,
|
||||
inputs,
|
||||
workingDirectory
|
||||
})
|
||||
core.info('All Done!')
|
||||
core.endGroup()
|
||||
}
|
||||
}
|
||||
|
||||
export const getRenamedFiles = async ({
|
||||
inputs,
|
||||
workingDirectory,
|
||||
diffSubmodule,
|
||||
diffResult,
|
||||
submodulePaths
|
||||
}: {
|
||||
inputs: Inputs
|
||||
workingDirectory: string
|
||||
diffSubmodule: boolean
|
||||
diffResult: DiffResult
|
||||
submodulePaths: string[]
|
||||
}): Promise<{paths: string; count: string}> => {
|
||||
const renamedFiles = await gitRenamedFiles({
|
||||
cwd: workingDirectory,
|
||||
sha1: diffResult.previousSha,
|
||||
sha2: diffResult.currentSha,
|
||||
diff: diffResult.diff,
|
||||
oldNewSeparator: inputs.oldNewSeparator
|
||||
})
|
||||
|
||||
if (diffSubmodule) {
|
||||
for (const submodulePath of submodulePaths) {
|
||||
const submoduleShaResult = await gitSubmoduleDiffSHA({
|
||||
cwd: workingDirectory,
|
||||
parentSha1: diffResult.previousSha,
|
||||
parentSha2: diffResult.currentSha,
|
||||
submodulePath,
|
||||
diff: diffResult.diff
|
||||
})
|
||||
|
||||
const submoduleWorkingDirectory = path.join(
|
||||
workingDirectory,
|
||||
submodulePath
|
||||
)
|
||||
|
||||
if (submoduleShaResult.currentSha && submoduleShaResult.previousSha) {
|
||||
let diff = '...'
|
||||
|
||||
if (
|
||||
!(await canDiffCommits({
|
||||
cwd: submoduleWorkingDirectory,
|
||||
sha1: submoduleShaResult.previousSha,
|
||||
sha2: submoduleShaResult.currentSha,
|
||||
diff
|
||||
}))
|
||||
) {
|
||||
let message = `Unable to use three dot diff for: ${submodulePath} submodule. Falling back to two dot diff. You can set 'fetch_additional_submodule_history: true' to fetch additional submodule history in order to use three dot diff`
|
||||
if (inputs.fetchAdditionalSubmoduleHistory) {
|
||||
message = `To fetch additional submodule history for: ${submodulePath} you can increase history depth using 'fetch_depth' input`
|
||||
}
|
||||
core.info(message)
|
||||
diff = '..'
|
||||
}
|
||||
|
||||
const submoduleRenamedFiles = await gitRenamedFiles({
|
||||
cwd: submoduleWorkingDirectory,
|
||||
sha1: submoduleShaResult.previousSha,
|
||||
sha2: submoduleShaResult.currentSha,
|
||||
diff,
|
||||
oldNewSeparator: inputs.oldNewSeparator,
|
||||
isSubmodule: true,
|
||||
parentDir: submodulePath
|
||||
})
|
||||
renamedFiles.push(...submoduleRenamedFiles)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inputs.json) {
|
||||
return {
|
||||
paths: jsonOutput({value: renamedFiles, shouldEscape: inputs.escapeJson}),
|
||||
count: renamedFiles.length.toString()
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
paths: renamedFiles.join(inputs.oldNewFilesSeparator),
|
||||
count: renamedFiles.length.toString()
|
||||
}
|
||||
}
|
||||
|
||||
export enum ChangeTypeEnum {
|
||||
Added = 'A',
|
||||
Copied = 'C',
|
||||
Deleted = 'D',
|
||||
Modified = 'M',
|
||||
Renamed = 'R',
|
||||
TypeChanged = 'T',
|
||||
Unmerged = 'U',
|
||||
Unknown = 'X'
|
||||
}
|
||||
|
||||
export type ChangedFiles = {
|
||||
[key in ChangeTypeEnum]: string[]
|
||||
}
|
||||
|
||||
export const getAllDiffFiles = async ({
|
||||
workingDirectory,
|
||||
diffSubmodule,
|
||||
diffResult,
|
||||
submodulePaths,
|
||||
outputRenamedFilesAsDeletedAndAdded,
|
||||
fetchAdditionalSubmoduleHistory,
|
||||
failOnInitialDiffError,
|
||||
failOnSubmoduleDiffError
|
||||
}: {
|
||||
workingDirectory: string
|
||||
diffSubmodule: boolean
|
||||
diffResult: DiffResult
|
||||
submodulePaths: string[]
|
||||
outputRenamedFilesAsDeletedAndAdded: boolean
|
||||
fetchAdditionalSubmoduleHistory: boolean
|
||||
failOnInitialDiffError: boolean
|
||||
failOnSubmoduleDiffError: boolean
|
||||
}): Promise<ChangedFiles> => {
|
||||
const files = await getAllChangedFiles({
|
||||
cwd: workingDirectory,
|
||||
sha1: diffResult.previousSha,
|
||||
sha2: diffResult.currentSha,
|
||||
diff: diffResult.diff,
|
||||
outputRenamedFilesAsDeletedAndAdded,
|
||||
failOnInitialDiffError
|
||||
})
|
||||
|
||||
if (diffSubmodule) {
|
||||
for (const submodulePath of submodulePaths) {
|
||||
const submoduleShaResult = await gitSubmoduleDiffSHA({
|
||||
cwd: workingDirectory,
|
||||
parentSha1: diffResult.previousSha,
|
||||
parentSha2: diffResult.currentSha,
|
||||
submodulePath,
|
||||
diff: diffResult.diff
|
||||
})
|
||||
|
||||
const submoduleWorkingDirectory = path.join(
|
||||
workingDirectory,
|
||||
submodulePath
|
||||
)
|
||||
|
||||
if (submoduleShaResult.currentSha && submoduleShaResult.previousSha) {
|
||||
let diff = '...'
|
||||
|
||||
if (
|
||||
!(await canDiffCommits({
|
||||
cwd: submoduleWorkingDirectory,
|
||||
sha1: submoduleShaResult.previousSha,
|
||||
sha2: submoduleShaResult.currentSha,
|
||||
diff
|
||||
}))
|
||||
) {
|
||||
let message = `Set 'fetch_additional_submodule_history: true' to fetch additional submodule history for: ${submodulePath}`
|
||||
if (fetchAdditionalSubmoduleHistory) {
|
||||
message = `To fetch additional submodule history for: ${submodulePath} you can increase history depth using 'fetch_depth' input`
|
||||
}
|
||||
core.warning(message)
|
||||
diff = '..'
|
||||
}
|
||||
|
||||
const submoduleFiles = await getAllChangedFiles({
|
||||
cwd: submoduleWorkingDirectory,
|
||||
sha1: submoduleShaResult.previousSha,
|
||||
sha2: submoduleShaResult.currentSha,
|
||||
diff,
|
||||
isSubmodule: true,
|
||||
parentDir: submodulePath,
|
||||
outputRenamedFilesAsDeletedAndAdded,
|
||||
failOnSubmoduleDiffError
|
||||
})
|
||||
|
||||
for (const changeType of Object.keys(
|
||||
submoduleFiles
|
||||
) as ChangeTypeEnum[]) {
|
||||
if (!files[changeType]) {
|
||||
files[changeType] = []
|
||||
}
|
||||
files[changeType].push(...submoduleFiles[changeType])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return files
|
||||
}
|
||||
|
||||
function* getFilePaths({
|
||||
inputs,
|
||||
filePaths,
|
||||
dirNamesIncludeFilePatterns
|
||||
}: {
|
||||
inputs: Inputs
|
||||
filePaths: string[]
|
||||
dirNamesIncludeFilePatterns: string[]
|
||||
}): Generator<string> {
|
||||
for (const filePath of filePaths) {
|
||||
if (inputs.dirNames) {
|
||||
if (dirNamesIncludeFilePatterns.length > 0) {
|
||||
const isWin = isWindows()
|
||||
const matchOptions = {dot: true, windows: isWin, noext: true}
|
||||
if (mm.isMatch(filePath, dirNamesIncludeFilePatterns, matchOptions)) {
|
||||
yield filePath
|
||||
}
|
||||
}
|
||||
yield getDirnameMaxDepth({
|
||||
relativePath: filePath,
|
||||
dirNamesMaxDepth: inputs.dirNamesMaxDepth,
|
||||
excludeCurrentDir: inputs.dirNamesExcludeCurrentDir
|
||||
})
|
||||
} else {
|
||||
yield filePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function* getChangeTypeFilesGenerator({
|
||||
inputs,
|
||||
changedFiles,
|
||||
changeTypes
|
||||
}: {
|
||||
inputs: Inputs
|
||||
changedFiles: ChangedFiles
|
||||
changeTypes: ChangeTypeEnum[]
|
||||
}): Generator<string> {
|
||||
const dirNamesIncludeFilePatterns = getDirNamesIncludeFilesPattern({inputs})
|
||||
core.debug(
|
||||
`Dir names include file patterns: ${JSON.stringify(
|
||||
dirNamesIncludeFilePatterns
|
||||
)}`
|
||||
)
|
||||
|
||||
for (const changeType of changeTypes) {
|
||||
const filePaths = changedFiles[changeType] || []
|
||||
for (const filePath of getFilePaths({
|
||||
inputs,
|
||||
filePaths,
|
||||
dirNamesIncludeFilePatterns
|
||||
})) {
|
||||
if (isWindows() && inputs.usePosixPathSeparator) {
|
||||
yield convertPath(filePath, 'mixed')
|
||||
} else {
|
||||
yield filePath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const getChangeTypeFiles = async ({
|
||||
inputs,
|
||||
changedFiles,
|
||||
changeTypes
|
||||
}: {
|
||||
inputs: Inputs
|
||||
changedFiles: ChangedFiles
|
||||
changeTypes: ChangeTypeEnum[]
|
||||
}): Promise<{paths: string[] | string; count: string}> => {
|
||||
const files = [
|
||||
...new Set(getChangeTypeFilesGenerator({inputs, changedFiles, changeTypes}))
|
||||
].filter(Boolean)
|
||||
|
||||
const paths = inputs.json ? files : files.join(inputs.separator)
|
||||
|
||||
return {
|
||||
paths,
|
||||
count: files.length.toString()
|
||||
}
|
||||
}
|
||||
|
||||
function* getAllChangeTypeFilesGenerator({
|
||||
inputs,
|
||||
changedFiles
|
||||
}: {
|
||||
inputs: Inputs
|
||||
changedFiles: ChangedFiles
|
||||
}): Generator<string> {
|
||||
const dirNamesIncludeFilePatterns = getDirNamesIncludeFilesPattern({inputs})
|
||||
core.debug(
|
||||
`Dir names include file patterns: ${JSON.stringify(
|
||||
dirNamesIncludeFilePatterns
|
||||
)}`
|
||||
)
|
||||
|
||||
const filePaths = flatten(Object.values(changedFiles))
|
||||
|
||||
for (const filePath of getFilePaths({
|
||||
inputs,
|
||||
filePaths,
|
||||
dirNamesIncludeFilePatterns
|
||||
})) {
|
||||
if (isWindows() && inputs.usePosixPathSeparator) {
|
||||
yield convertPath(filePath, 'mixed')
|
||||
} else {
|
||||
yield filePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const getAllChangeTypeFiles = async ({
|
||||
inputs,
|
||||
changedFiles
|
||||
}: {
|
||||
inputs: Inputs
|
||||
changedFiles: ChangedFiles
|
||||
}): Promise<{paths: string[] | string; count: string}> => {
|
||||
const files = [
|
||||
...new Set(getAllChangeTypeFilesGenerator({inputs, changedFiles}))
|
||||
].filter(Boolean)
|
||||
|
||||
const paths = inputs.json ? files : files.join(inputs.separator)
|
||||
|
||||
return {
|
||||
paths,
|
||||
count: files.length.toString()
|
||||
}
|
||||
}
|
||||
|
||||
export const getChangedFilesFromGithubAPI = async ({
|
||||
inputs
|
||||
}: {
|
||||
inputs: Inputs
|
||||
}): Promise<ChangedFiles> => {
|
||||
const octokit = github.getOctokit(inputs.token, {
|
||||
baseUrl: inputs.apiUrl
|
||||
})
|
||||
const changedFiles: ChangedFiles = {
|
||||
[ChangeTypeEnum.Added]: [],
|
||||
[ChangeTypeEnum.Copied]: [],
|
||||
[ChangeTypeEnum.Deleted]: [],
|
||||
[ChangeTypeEnum.Modified]: [],
|
||||
[ChangeTypeEnum.Renamed]: [],
|
||||
[ChangeTypeEnum.TypeChanged]: [],
|
||||
[ChangeTypeEnum.Unmerged]: [],
|
||||
[ChangeTypeEnum.Unknown]: []
|
||||
}
|
||||
|
||||
core.info('Getting changed files from GitHub API...')
|
||||
|
||||
const options = octokit.rest.pulls.listFiles.endpoint.merge({
|
||||
owner: github.context.repo.owner,
|
||||
repo: github.context.repo.repo,
|
||||
pull_number: github.context.payload.pull_request?.number,
|
||||
per_page: 100
|
||||
})
|
||||
|
||||
const paginatedResponse =
|
||||
await octokit.paginate<
|
||||
RestEndpointMethodTypes['pulls']['listFiles']['response']['data'][0]
|
||||
>(options)
|
||||
|
||||
core.info(`Found ${paginatedResponse.length} changed files from GitHub API`)
|
||||
const statusMap: Record<string, ChangeTypeEnum> = {
|
||||
added: ChangeTypeEnum.Added,
|
||||
removed: ChangeTypeEnum.Deleted,
|
||||
modified: ChangeTypeEnum.Modified,
|
||||
renamed: ChangeTypeEnum.Renamed,
|
||||
copied: ChangeTypeEnum.Copied,
|
||||
changed: ChangeTypeEnum.TypeChanged,
|
||||
unchanged: ChangeTypeEnum.Unmerged
|
||||
}
|
||||
|
||||
for await (const item of paginatedResponse) {
|
||||
const changeType: ChangeTypeEnum =
|
||||
statusMap[item.status] || ChangeTypeEnum.Unknown
|
||||
|
||||
if (changeType === ChangeTypeEnum.Renamed) {
|
||||
if (inputs.outputRenamedFilesAsDeletedAndAdded) {
|
||||
changedFiles[ChangeTypeEnum.Deleted].push(item.previous_filename || '')
|
||||
changedFiles[ChangeTypeEnum.Added].push(item.filename)
|
||||
} else {
|
||||
changedFiles[ChangeTypeEnum.Renamed].push(item.filename)
|
||||
}
|
||||
} else {
|
||||
changedFiles[changeType].push(item.filename)
|
||||
}
|
||||
}
|
||||
|
||||
return changedFiles
|
||||
}
|
502
src/changedFilesOutput.ts
Normal file
502
src/changedFilesOutput.ts
Normal file
@ -0,0 +1,502 @@
|
||||
import * as core from '@actions/core'
|
||||
import path from 'path'
|
||||
import {
|
||||
ChangedFiles,
|
||||
ChangeTypeEnum,
|
||||
getAllChangeTypeFiles,
|
||||
getChangeTypeFiles
|
||||
} from './changedFiles'
|
||||
import {Inputs} from './inputs'
|
||||
import {getOutputKey, setArrayOutput, setOutput, exists} from './utils'
|
||||
|
||||
const getArrayFromPaths = (
|
||||
paths: string | string[],
|
||||
inputs: Inputs
|
||||
): string[] => {
|
||||
return Array.isArray(paths) ? paths : paths.split(inputs.separator)
|
||||
}
|
||||
|
||||
export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
|
||||
allDiffFiles,
|
||||
allFilteredDiffFiles,
|
||||
inputs,
|
||||
filePatterns = [],
|
||||
outputPrefix = '',
|
||||
workingDirectory
|
||||
}: {
|
||||
allDiffFiles: ChangedFiles
|
||||
allFilteredDiffFiles: ChangedFiles
|
||||
inputs: Inputs
|
||||
filePatterns?: string[]
|
||||
outputPrefix?: string
|
||||
workingDirectory?: string
|
||||
}): Promise<{anyModified: boolean; anyChanged: boolean}> => {
|
||||
const addedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Added]
|
||||
})
|
||||
core.debug(`Added files: ${JSON.stringify(addedFiles)}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('added_files', outputPrefix),
|
||||
value: addedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
await setOutput({
|
||||
key: getOutputKey('added_files_count', outputPrefix),
|
||||
value: addedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
const copiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Copied]
|
||||
})
|
||||
core.debug(`Copied files: ${JSON.stringify(copiedFiles)}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('copied_files', outputPrefix),
|
||||
value: copiedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('copied_files_count', outputPrefix),
|
||||
value: copiedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
const modifiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Modified]
|
||||
})
|
||||
core.debug(`Modified files: ${JSON.stringify(modifiedFiles)}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('modified_files', outputPrefix),
|
||||
value: modifiedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('modified_files_count', outputPrefix),
|
||||
value: modifiedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
const renamedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Renamed]
|
||||
})
|
||||
core.debug(`Renamed files: ${JSON.stringify(renamedFiles)}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('renamed_files', outputPrefix),
|
||||
value: renamedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('renamed_files_count', outputPrefix),
|
||||
value: renamedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
const typeChangedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.TypeChanged]
|
||||
})
|
||||
core.debug(`Type changed files: ${JSON.stringify(typeChangedFiles)}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('type_changed_files', outputPrefix),
|
||||
value: typeChangedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('type_changed_files_count', outputPrefix),
|
||||
value: typeChangedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
const unmergedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Unmerged]
|
||||
})
|
||||
core.debug(`Unmerged files: ${JSON.stringify(unmergedFiles)}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('unmerged_files', outputPrefix),
|
||||
value: unmergedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('unmerged_files_count', outputPrefix),
|
||||
value: unmergedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
const unknownFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Unknown]
|
||||
})
|
||||
core.debug(`Unknown files: ${JSON.stringify(unknownFiles)}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('unknown_files', outputPrefix),
|
||||
value: unknownFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('unknown_files_count', outputPrefix),
|
||||
value: unknownFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
const allChangedAndModifiedFiles = await getAllChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles
|
||||
})
|
||||
core.debug(
|
||||
`All changed and modified files: ${JSON.stringify(
|
||||
allChangedAndModifiedFiles
|
||||
)}`
|
||||
)
|
||||
await setOutput({
|
||||
key: getOutputKey('all_changed_and_modified_files', outputPrefix),
|
||||
value: allChangedAndModifiedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('all_changed_and_modified_files_count', outputPrefix),
|
||||
value: allChangedAndModifiedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
const allChangedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed
|
||||
]
|
||||
})
|
||||
core.debug(`All changed files: ${JSON.stringify(allChangedFiles)}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('all_changed_files', outputPrefix),
|
||||
value: allChangedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('all_changed_files_count', outputPrefix),
|
||||
value: allChangedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('any_changed', outputPrefix),
|
||||
value: allChangedFiles.paths.length > 0,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json
|
||||
})
|
||||
|
||||
const allOtherChangedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed
|
||||
]
|
||||
})
|
||||
core.debug(`All other changed files: ${JSON.stringify(allOtherChangedFiles)}`)
|
||||
|
||||
const allOtherChangedFilesPaths: string[] = getArrayFromPaths(
|
||||
allOtherChangedFiles.paths,
|
||||
inputs
|
||||
)
|
||||
const allChangedFilesPaths: string[] = getArrayFromPaths(
|
||||
allChangedFiles.paths,
|
||||
inputs
|
||||
)
|
||||
|
||||
const otherChangedFiles = allOtherChangedFilesPaths.filter(
|
||||
(filePath: string) => !allChangedFilesPaths.includes(filePath)
|
||||
)
|
||||
|
||||
const onlyChanged =
|
||||
otherChangedFiles.length === 0 &&
|
||||
allChangedFiles.paths.length > 0 &&
|
||||
filePatterns.length > 0
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('only_changed', outputPrefix),
|
||||
value: onlyChanged,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json
|
||||
})
|
||||
|
||||
await setArrayOutput({
|
||||
key: 'other_changed_files',
|
||||
inputs,
|
||||
value: otherChangedFiles,
|
||||
outputPrefix
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('other_changed_files_count', outputPrefix),
|
||||
value: otherChangedFiles.length.toString(),
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
const allModifiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed,
|
||||
ChangeTypeEnum.Deleted
|
||||
]
|
||||
})
|
||||
core.debug(`All modified files: ${JSON.stringify(allModifiedFiles)}`)
|
||||
await setOutput({
|
||||
key: getOutputKey('all_modified_files', outputPrefix),
|
||||
value: allModifiedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('all_modified_files_count', outputPrefix),
|
||||
value: allModifiedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('any_modified', outputPrefix),
|
||||
value: allModifiedFiles.paths.length > 0,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json
|
||||
})
|
||||
|
||||
const allOtherModifiedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allDiffFiles,
|
||||
changeTypes: [
|
||||
ChangeTypeEnum.Added,
|
||||
ChangeTypeEnum.Copied,
|
||||
ChangeTypeEnum.Modified,
|
||||
ChangeTypeEnum.Renamed,
|
||||
ChangeTypeEnum.Deleted
|
||||
]
|
||||
})
|
||||
|
||||
const allOtherModifiedFilesPaths: string[] = getArrayFromPaths(
|
||||
allOtherModifiedFiles.paths,
|
||||
inputs
|
||||
)
|
||||
|
||||
const allModifiedFilesPaths: string[] = getArrayFromPaths(
|
||||
allModifiedFiles.paths,
|
||||
inputs
|
||||
)
|
||||
|
||||
const otherModifiedFiles = allOtherModifiedFilesPaths.filter(
|
||||
(filePath: string) => !allModifiedFilesPaths.includes(filePath)
|
||||
)
|
||||
|
||||
const onlyModified =
|
||||
otherModifiedFiles.length === 0 &&
|
||||
allModifiedFiles.paths.length > 0 &&
|
||||
filePatterns.length > 0
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('only_modified', outputPrefix),
|
||||
value: onlyModified,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json
|
||||
})
|
||||
|
||||
await setArrayOutput({
|
||||
key: 'other_modified_files',
|
||||
inputs,
|
||||
value: otherModifiedFiles,
|
||||
outputPrefix
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('other_modified_files_count', outputPrefix),
|
||||
value: otherModifiedFiles.length.toString(),
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
const deletedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allFilteredDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Deleted]
|
||||
})
|
||||
core.debug(`Deleted files: ${JSON.stringify(deletedFiles)}`)
|
||||
|
||||
if (
|
||||
inputs.dirNamesDeletedFilesIncludeOnlyDeletedDirs &&
|
||||
inputs.dirNames &&
|
||||
workingDirectory
|
||||
) {
|
||||
const newDeletedFilesPaths: string[] = []
|
||||
for (const deletedPath of getArrayFromPaths(deletedFiles.paths, inputs)) {
|
||||
const dirPath = path.join(workingDirectory, deletedPath)
|
||||
core.debug(`Checking if directory exists: ${dirPath}`)
|
||||
if (!(await exists(dirPath))) {
|
||||
core.debug(`Directory not found: ${dirPath}`)
|
||||
newDeletedFilesPaths.push(deletedPath)
|
||||
}
|
||||
}
|
||||
deletedFiles.paths = inputs.json
|
||||
? newDeletedFilesPaths
|
||||
: newDeletedFilesPaths.join(inputs.separator)
|
||||
deletedFiles.count = newDeletedFilesPaths.length.toString()
|
||||
core.debug(`New deleted files: ${JSON.stringify(deletedFiles)}`)
|
||||
}
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('deleted_files', outputPrefix),
|
||||
value: deletedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
shouldEscape: inputs.escapeJson,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('deleted_files_count', outputPrefix),
|
||||
value: deletedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('any_deleted', outputPrefix),
|
||||
value: deletedFiles.paths.length > 0,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json
|
||||
})
|
||||
|
||||
const allOtherDeletedFiles = await getChangeTypeFiles({
|
||||
inputs,
|
||||
changedFiles: allDiffFiles,
|
||||
changeTypes: [ChangeTypeEnum.Deleted]
|
||||
})
|
||||
|
||||
const allOtherDeletedFilesPaths: string[] = getArrayFromPaths(
|
||||
allOtherDeletedFiles.paths,
|
||||
inputs
|
||||
)
|
||||
|
||||
const deletedFilesPaths: string[] = getArrayFromPaths(
|
||||
deletedFiles.paths,
|
||||
inputs
|
||||
)
|
||||
|
||||
const otherDeletedFiles = allOtherDeletedFilesPaths.filter(
|
||||
filePath => !deletedFilesPaths.includes(filePath)
|
||||
)
|
||||
|
||||
const onlyDeleted =
|
||||
otherDeletedFiles.length === 0 &&
|
||||
deletedFiles.paths.length > 0 &&
|
||||
filePatterns.length > 0
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('only_deleted', outputPrefix),
|
||||
value: onlyDeleted,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json
|
||||
})
|
||||
|
||||
await setArrayOutput({
|
||||
key: 'other_deleted_files',
|
||||
inputs,
|
||||
value: otherDeletedFiles,
|
||||
outputPrefix
|
||||
})
|
||||
|
||||
await setOutput({
|
||||
key: getOutputKey('other_deleted_files_count', outputPrefix),
|
||||
value: otherDeletedFiles.length.toString(),
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir
|
||||
})
|
||||
|
||||
return {
|
||||
anyModified: allModifiedFiles.paths.length > 0,
|
||||
anyChanged: allChangedFiles.paths.length > 0
|
||||
}
|
||||
}
|
644
src/commitSha.ts
Normal file
644
src/commitSha.ts
Normal file
@ -0,0 +1,644 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as github from '@actions/github'
|
||||
|
||||
import {Env} from './env'
|
||||
import {Inputs} from './inputs'
|
||||
import {
|
||||
canDiffCommits,
|
||||
cleanShaInput,
|
||||
getCurrentBranchName,
|
||||
getHeadSha,
|
||||
getParentSha,
|
||||
getPreviousGitTag,
|
||||
getRemoteBranchHeadSha,
|
||||
gitFetch,
|
||||
gitFetchSubmodules,
|
||||
gitLog,
|
||||
verifyCommitSha
|
||||
} from './utils'
|
||||
|
||||
const getCurrentSHA = async ({
|
||||
inputs,
|
||||
workingDirectory
|
||||
}: {
|
||||
inputs: Inputs
|
||||
workingDirectory: string
|
||||
}): Promise<string> => {
|
||||
let currentSha = await cleanShaInput({
|
||||
sha: inputs.sha,
|
||||
cwd: workingDirectory,
|
||||
token: inputs.token
|
||||
})
|
||||
core.debug('Getting current SHA...')
|
||||
|
||||
if (inputs.until) {
|
||||
core.debug(`Getting base SHA for '${inputs.until}'...`)
|
||||
try {
|
||||
currentSha = await gitLog({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
'--format=%H',
|
||||
'-n',
|
||||
'1',
|
||||
'--date',
|
||||
'local',
|
||||
'--until',
|
||||
inputs.until
|
||||
]
|
||||
})
|
||||
} catch (error) {
|
||||
core.error(
|
||||
`Invalid until date: ${inputs.until}. ${(error as Error).message}`
|
||||
)
|
||||
throw error
|
||||
}
|
||||
} else {
|
||||
if (!currentSha) {
|
||||
if (
|
||||
github.context.payload.pull_request?.head?.sha &&
|
||||
(await verifyCommitSha({
|
||||
sha: github.context.payload.pull_request?.head?.sha,
|
||||
cwd: workingDirectory,
|
||||
showAsErrorMessage: false
|
||||
})) === 0
|
||||
) {
|
||||
currentSha = github.context.payload.pull_request?.head?.sha
|
||||
} else if (github.context.eventName === 'merge_group') {
|
||||
currentSha = github.context.payload.merge_group?.head_sha
|
||||
} else {
|
||||
currentSha = await getHeadSha({cwd: workingDirectory})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await verifyCommitSha({sha: currentSha, cwd: workingDirectory})
|
||||
core.debug(`Current SHA: ${currentSha}`)
|
||||
|
||||
return currentSha
|
||||
}
|
||||
|
||||
export interface DiffResult {
|
||||
previousSha: string
|
||||
currentSha: string
|
||||
currentBranch: string
|
||||
targetBranch: string
|
||||
diff: string
|
||||
initialCommit?: boolean
|
||||
}
|
||||
|
||||
interface SHAForNonPullRequestEvent {
|
||||
inputs: Inputs
|
||||
env: Env
|
||||
workingDirectory: string
|
||||
isShallow: boolean
|
||||
diffSubmodule: boolean
|
||||
gitFetchExtraArgs: string[]
|
||||
isTag: boolean
|
||||
remoteName: string
|
||||
}
|
||||
|
||||
export const getSHAForNonPullRequestEvent = async ({
|
||||
inputs,
|
||||
env,
|
||||
workingDirectory,
|
||||
isShallow,
|
||||
diffSubmodule,
|
||||
gitFetchExtraArgs,
|
||||
isTag,
|
||||
remoteName
|
||||
}: SHAForNonPullRequestEvent): Promise<DiffResult> => {
|
||||
let targetBranch = env.GITHUB_REF_NAME
|
||||
let currentBranch = targetBranch
|
||||
let initialCommit = false
|
||||
|
||||
if (!inputs.skipInitialFetch) {
|
||||
if (isShallow) {
|
||||
core.info('Repository is shallow, fetching more history...')
|
||||
|
||||
if (isTag) {
|
||||
let sourceBranch = ''
|
||||
|
||||
if (github.context.payload.base_ref) {
|
||||
sourceBranch = github.context.payload.base_ref.replace(
|
||||
'refs/heads/',
|
||||
''
|
||||
)
|
||||
} else if (github.context.payload.release?.target_commitish) {
|
||||
sourceBranch = github.context.payload.release?.target_commitish
|
||||
}
|
||||
|
||||
await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`,
|
||||
remoteName,
|
||||
`+refs/heads/${sourceBranch}:refs/remotes/${remoteName}/${sourceBranch}`
|
||||
]
|
||||
})
|
||||
} else {
|
||||
await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`,
|
||||
remoteName,
|
||||
`+refs/heads/${targetBranch}:refs/remotes/${remoteName}/${targetBranch}`
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
if (diffSubmodule) {
|
||||
await gitFetchSubmodules({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`
|
||||
]
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (diffSubmodule && inputs.fetchAdditionalSubmoduleHistory) {
|
||||
await gitFetchSubmodules({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const currentSha = await getCurrentSHA({inputs, workingDirectory})
|
||||
let previousSha = await cleanShaInput({
|
||||
sha: inputs.baseSha,
|
||||
cwd: workingDirectory,
|
||||
token: inputs.token
|
||||
})
|
||||
const diff = '..'
|
||||
const currentBranchName = await getCurrentBranchName({cwd: workingDirectory})
|
||||
|
||||
if (
|
||||
currentBranchName &&
|
||||
currentBranchName !== 'HEAD' &&
|
||||
(currentBranchName !== targetBranch || currentBranchName !== currentBranch)
|
||||
) {
|
||||
targetBranch = currentBranchName
|
||||
currentBranch = currentBranchName
|
||||
}
|
||||
|
||||
if (inputs.baseSha && inputs.sha && currentBranch && targetBranch) {
|
||||
if (previousSha === currentSha) {
|
||||
core.error(
|
||||
`Similar commit hashes detected: previous sha: ${previousSha} is equivalent to the current sha: ${currentSha}.`
|
||||
)
|
||||
core.error(
|
||||
`Please verify that both commits are valid, and increase the fetch_depth to a number higher than ${inputs.fetchDepth}.`
|
||||
)
|
||||
throw new Error('Similar commit hashes detected.')
|
||||
}
|
||||
|
||||
core.debug(`Previous SHA: ${previousSha}`)
|
||||
|
||||
return {
|
||||
previousSha,
|
||||
currentSha,
|
||||
currentBranch,
|
||||
targetBranch,
|
||||
diff
|
||||
}
|
||||
}
|
||||
|
||||
if (!previousSha || previousSha === currentSha) {
|
||||
core.debug('Getting previous SHA...')
|
||||
if (inputs.since) {
|
||||
core.debug(`Getting base SHA for '${inputs.since}'...`)
|
||||
try {
|
||||
const allCommitsFrom = await gitLog({
|
||||
cwd: workingDirectory,
|
||||
args: ['--format=%H', '--date', 'local', '--since', inputs.since]
|
||||
})
|
||||
|
||||
if (allCommitsFrom) {
|
||||
const allCommitsFromArray = allCommitsFrom.split('\n')
|
||||
previousSha = allCommitsFromArray[allCommitsFromArray.length - 1]
|
||||
}
|
||||
} catch (error) {
|
||||
core.error(
|
||||
`Invalid since date: ${inputs.since}. ${(error as Error).message}`
|
||||
)
|
||||
throw error
|
||||
}
|
||||
} else if (isTag) {
|
||||
core.debug('Getting previous SHA for tag...')
|
||||
const {sha, tag} = await getPreviousGitTag({
|
||||
cwd: workingDirectory,
|
||||
tagsPattern: inputs.tagsPattern,
|
||||
tagsIgnorePattern: inputs.tagsIgnorePattern,
|
||||
currentBranch
|
||||
})
|
||||
previousSha = sha
|
||||
targetBranch = tag
|
||||
} else {
|
||||
if (github.context.eventName === 'merge_group') {
|
||||
core.debug('Getting previous SHA for merge group...')
|
||||
previousSha = github.context.payload.merge_group?.base_sha
|
||||
} else {
|
||||
core.debug('Getting previous SHA for last remote commit...')
|
||||
if (
|
||||
github.context.payload.forced === 'false' ||
|
||||
!github.context.payload.forced
|
||||
) {
|
||||
previousSha = github.context.payload.before
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!previousSha ||
|
||||
previousSha === '0000000000000000000000000000000000000000'
|
||||
) {
|
||||
previousSha = await getParentSha({
|
||||
cwd: workingDirectory
|
||||
})
|
||||
} else if (
|
||||
(await verifyCommitSha({
|
||||
sha: previousSha,
|
||||
cwd: workingDirectory,
|
||||
showAsErrorMessage: false
|
||||
})) !== 0
|
||||
) {
|
||||
core.warning(
|
||||
`Previous commit ${previousSha} is not valid. Using parent commit.`
|
||||
)
|
||||
previousSha = await getParentSha({
|
||||
cwd: workingDirectory
|
||||
})
|
||||
}
|
||||
|
||||
if (!previousSha || previousSha === currentSha) {
|
||||
previousSha = await getParentSha({
|
||||
cwd: workingDirectory
|
||||
})
|
||||
|
||||
if (!previousSha) {
|
||||
core.warning('Initial commit detected no previous commit found.')
|
||||
initialCommit = true
|
||||
previousSha = currentSha
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await verifyCommitSha({sha: previousSha, cwd: workingDirectory})
|
||||
core.debug(`Previous SHA: ${previousSha}`)
|
||||
|
||||
core.debug(`Target branch: ${targetBranch}`)
|
||||
core.debug(`Current branch: ${currentBranch}`)
|
||||
|
||||
if (!initialCommit && previousSha === currentSha) {
|
||||
core.error(
|
||||
`Similar commit hashes detected: previous sha: ${previousSha} is equivalent to the current sha: ${currentSha}.`
|
||||
)
|
||||
core.error(
|
||||
`Please verify that both commits are valid, and increase the fetch_depth to a number higher than ${inputs.fetchDepth}.`
|
||||
)
|
||||
throw new Error('Similar commit hashes detected.')
|
||||
}
|
||||
|
||||
return {
|
||||
previousSha,
|
||||
currentSha,
|
||||
currentBranch,
|
||||
targetBranch,
|
||||
diff,
|
||||
initialCommit
|
||||
}
|
||||
}
|
||||
|
||||
interface SHAForPullRequestEvent {
|
||||
inputs: Inputs
|
||||
workingDirectory: string
|
||||
isShallow: boolean
|
||||
diffSubmodule: boolean
|
||||
gitFetchExtraArgs: string[]
|
||||
remoteName: string
|
||||
}
|
||||
|
||||
export const getSHAForPullRequestEvent = async ({
|
||||
inputs,
|
||||
workingDirectory,
|
||||
isShallow,
|
||||
diffSubmodule,
|
||||
gitFetchExtraArgs,
|
||||
remoteName
|
||||
}: SHAForPullRequestEvent): Promise<DiffResult> => {
|
||||
let targetBranch = github.context.payload.pull_request?.base?.ref
|
||||
const currentBranch = github.context.payload.pull_request?.head?.ref
|
||||
if (inputs.sinceLastRemoteCommit) {
|
||||
targetBranch = currentBranch
|
||||
}
|
||||
|
||||
if (!inputs.skipInitialFetch) {
|
||||
core.info('Repository is shallow, fetching more history...')
|
||||
if (isShallow) {
|
||||
let prFetchExitCode = await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
remoteName,
|
||||
`pull/${github.context.payload.pull_request?.number}/head:${currentBranch}`
|
||||
]
|
||||
})
|
||||
|
||||
if (prFetchExitCode !== 0) {
|
||||
prFetchExitCode = await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`,
|
||||
remoteName,
|
||||
`+refs/heads/${currentBranch}*:refs/remotes/${remoteName}/${currentBranch}*`
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
if (prFetchExitCode !== 0) {
|
||||
throw new Error(
|
||||
'Failed to fetch pull request branch. Please ensure "persist-credentials" is set to "true" when checking out the repository. See: https://github.com/actions/checkout#usage'
|
||||
)
|
||||
}
|
||||
core.debug('Fetching target branch...')
|
||||
await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`,
|
||||
remoteName,
|
||||
`+refs/heads/${github.context.payload.pull_request?.base?.ref}:refs/remotes/${remoteName}/${github.context.payload.pull_request?.base?.ref}`
|
||||
]
|
||||
})
|
||||
|
||||
if (diffSubmodule) {
|
||||
await gitFetchSubmodules({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`
|
||||
]
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (diffSubmodule && inputs.fetchAdditionalSubmoduleHistory) {
|
||||
await gitFetchSubmodules({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
core.info('Completed fetching more history.')
|
||||
}
|
||||
|
||||
const currentSha = await getCurrentSHA({inputs, workingDirectory})
|
||||
let previousSha = await cleanShaInput({
|
||||
sha: inputs.baseSha,
|
||||
cwd: workingDirectory,
|
||||
token: inputs.token
|
||||
})
|
||||
let diff = '...'
|
||||
|
||||
if (inputs.baseSha && inputs.sha && currentBranch && targetBranch) {
|
||||
if (previousSha === currentSha) {
|
||||
core.error(
|
||||
`Similar commit hashes detected: previous sha: ${previousSha} is equivalent to the current sha: ${currentSha}.`
|
||||
)
|
||||
core.error(
|
||||
`Please verify that both commits are valid, and increase the fetch_depth to a number higher than ${inputs.fetchDepth}.`
|
||||
)
|
||||
throw new Error('Similar commit hashes detected.')
|
||||
}
|
||||
|
||||
core.debug(`Previous SHA: ${previousSha}`)
|
||||
|
||||
return {
|
||||
previousSha,
|
||||
currentSha,
|
||||
currentBranch,
|
||||
targetBranch,
|
||||
diff
|
||||
}
|
||||
}
|
||||
|
||||
if (!github.context.payload.pull_request?.base?.ref) {
|
||||
diff = '..'
|
||||
}
|
||||
|
||||
if (!previousSha || previousSha === currentSha) {
|
||||
if (inputs.sinceLastRemoteCommit) {
|
||||
previousSha = github.context.payload.before
|
||||
|
||||
if (
|
||||
!previousSha ||
|
||||
(previousSha &&
|
||||
(await verifyCommitSha({
|
||||
sha: previousSha,
|
||||
cwd: workingDirectory,
|
||||
showAsErrorMessage: false
|
||||
})) !== 0)
|
||||
) {
|
||||
core.info(
|
||||
`Unable to locate the previous commit in the local history for ${github.context.eventName} (${github.context.payload.action}) event. Falling back to the previous commit in the local history.`
|
||||
)
|
||||
|
||||
previousSha = await getParentSha({
|
||||
cwd: workingDirectory
|
||||
})
|
||||
|
||||
if (
|
||||
github.context.payload.action &&
|
||||
github.context.payload.action === 'synchronize' &&
|
||||
previousSha &&
|
||||
(!previousSha ||
|
||||
(previousSha &&
|
||||
(await verifyCommitSha({
|
||||
sha: previousSha,
|
||||
cwd: workingDirectory,
|
||||
showAsErrorMessage: false
|
||||
})) !== 0))
|
||||
) {
|
||||
throw new Error(
|
||||
'Unable to locate the previous commit in the local history. Please ensure to checkout pull request HEAD commit instead of the merge commit. See: https://github.com/actions/checkout/blob/main/README.md#checkout-pull-request-head-commit-instead-of-merge-commit'
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
!previousSha ||
|
||||
(previousSha &&
|
||||
(await verifyCommitSha({
|
||||
sha: previousSha,
|
||||
cwd: workingDirectory,
|
||||
showAsErrorMessage: false
|
||||
})) !== 0)
|
||||
) {
|
||||
throw new Error(
|
||||
'Unable to locate the previous commit in the local history. Please ensure to checkout pull request HEAD commit instead of the merge commit. See: https://github.com/actions/checkout/blob/main/README.md#checkout-pull-request-head-commit-instead-of-merge-commit'
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
previousSha = github.context.payload.pull_request?.base?.sha
|
||||
|
||||
if (!previousSha) {
|
||||
previousSha = await getRemoteBranchHeadSha({
|
||||
cwd: workingDirectory,
|
||||
remoteName,
|
||||
branch: targetBranch
|
||||
})
|
||||
}
|
||||
|
||||
if (isShallow) {
|
||||
if (
|
||||
!(await canDiffCommits({
|
||||
cwd: workingDirectory,
|
||||
sha1: previousSha,
|
||||
sha2: currentSha,
|
||||
diff
|
||||
}))
|
||||
) {
|
||||
core.info(
|
||||
'Merge base is not in the local history, fetching remote target branch...'
|
||||
)
|
||||
|
||||
for (
|
||||
let i = 1;
|
||||
i <= (inputs.fetchMissingHistoryMaxRetries || 10);
|
||||
i++
|
||||
) {
|
||||
await gitFetch({
|
||||
cwd: workingDirectory,
|
||||
args: [
|
||||
...gitFetchExtraArgs,
|
||||
'-u',
|
||||
'--progress',
|
||||
`--deepen=${inputs.fetchDepth}`,
|
||||
remoteName,
|
||||
`+refs/heads/${targetBranch}:refs/remotes/${remoteName}/${targetBranch}`
|
||||
]
|
||||
})
|
||||
|
||||
if (
|
||||
await canDiffCommits({
|
||||
cwd: workingDirectory,
|
||||
sha1: previousSha,
|
||||
sha2: currentSha,
|
||||
diff
|
||||
})
|
||||
) {
|
||||
break
|
||||
}
|
||||
|
||||
core.info(
|
||||
'Merge base is not in the local history, fetching remote target branch again...'
|
||||
)
|
||||
core.info(`Attempt ${i}/10`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!previousSha || previousSha === currentSha) {
|
||||
previousSha = github.context.payload.pull_request?.base?.sha
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!(await canDiffCommits({
|
||||
cwd: workingDirectory,
|
||||
sha1: previousSha,
|
||||
sha2: currentSha,
|
||||
diff
|
||||
}))
|
||||
) {
|
||||
diff = '..'
|
||||
}
|
||||
|
||||
await verifyCommitSha({sha: previousSha, cwd: workingDirectory})
|
||||
core.debug(`Previous SHA: ${previousSha}`)
|
||||
|
||||
if (
|
||||
!(await canDiffCommits({
|
||||
cwd: workingDirectory,
|
||||
sha1: previousSha,
|
||||
sha2: currentSha,
|
||||
diff
|
||||
}))
|
||||
) {
|
||||
core.warning(
|
||||
'If this pull request is from a forked repository, please set the checkout action `repository` input to the same repository as the pull request.'
|
||||
)
|
||||
core.warning(
|
||||
'This can be done by setting actions/checkout `repository` to ${{ github.event.pull_request.head.repo.full_name }}'
|
||||
)
|
||||
throw new Error(
|
||||
`Unable to determine a difference between ${previousSha}${diff}${currentSha}`
|
||||
)
|
||||
}
|
||||
|
||||
if (previousSha === currentSha) {
|
||||
core.error(
|
||||
`Similar commit hashes detected: previous sha: ${previousSha} is equivalent to the current sha: ${currentSha}.`
|
||||
)
|
||||
// This occurs if a PR is created from a forked repository and the event is pull_request_target.
|
||||
// - name: Checkout to branch
|
||||
// uses: actions/checkout@v3
|
||||
// Without setting the repository to use the same repository as the pull request will cause the previousSha
|
||||
// to be the same as the currentSha since the currentSha cannot be found in the local history.
|
||||
// The solution is to use:
|
||||
// - name: Checkout to branch
|
||||
// uses: actions/checkout@v3
|
||||
// with:
|
||||
// repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
if (github.context.eventName === 'pull_request_target') {
|
||||
core.warning(
|
||||
'If this pull request is from a forked repository, please set the checkout action `repository` input to the same repository as the pull request.'
|
||||
)
|
||||
core.warning(
|
||||
'This can be done by setting actions/checkout `repository` to ${{ github.event.pull_request.head.repo.full_name }}'
|
||||
)
|
||||
} else {
|
||||
core.error(
|
||||
`Please verify that both commits are valid, and increase the fetch_depth to a number higher than ${inputs.fetchDepth}.`
|
||||
)
|
||||
}
|
||||
throw new Error('Similar commit hashes detected.')
|
||||
}
|
||||
|
||||
return {
|
||||
previousSha,
|
||||
currentSha,
|
||||
currentBranch,
|
||||
targetBranch,
|
||||
diff
|
||||
}
|
||||
}
|
29
src/constant.ts
Normal file
29
src/constant.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import {Inputs} from './inputs'
|
||||
|
||||
export const DEFAULT_VALUES_OF_UNSUPPORTED_API_INPUTS: Partial<Inputs> = {
|
||||
sha: '',
|
||||
baseSha: '',
|
||||
since: '',
|
||||
until: '',
|
||||
path: '.',
|
||||
quotepath: true,
|
||||
diffRelative: true,
|
||||
sinceLastRemoteCommit: false,
|
||||
recoverDeletedFiles: false,
|
||||
recoverDeletedFilesToDestination: '',
|
||||
recoverFiles: '',
|
||||
recoverFilesSeparator: '\n',
|
||||
recoverFilesIgnore: '',
|
||||
recoverFilesIgnoreSeparator: '\n',
|
||||
includeAllOldNewRenamedFiles: false,
|
||||
oldNewSeparator: ',',
|
||||
oldNewFilesSeparator: ' ',
|
||||
skipInitialFetch: false,
|
||||
fetchAdditionalSubmoduleHistory: false,
|
||||
dirNamesDeletedFilesIncludeOnlyDeletedDirs: false,
|
||||
excludeSubmodules: false,
|
||||
fetchMissingHistoryMaxRetries: 20,
|
||||
usePosixPathSeparator: false,
|
||||
tagsPattern: '*',
|
||||
tagsIgnorePattern: ''
|
||||
}
|
13
src/env.ts
Normal file
13
src/env.ts
Normal file
@ -0,0 +1,13 @@
|
||||
export type Env = {
|
||||
GITHUB_REF_NAME: string
|
||||
GITHUB_REF: string
|
||||
GITHUB_WORKSPACE: string
|
||||
}
|
||||
|
||||
export const getEnv = async (): Promise<Env> => {
|
||||
return {
|
||||
GITHUB_REF_NAME: process.env.GITHUB_REF_NAME || '',
|
||||
GITHUB_REF: process.env.GITHUB_REF || '',
|
||||
GITHUB_WORKSPACE: process.env.GITHUB_WORKSPACE || ''
|
||||
}
|
||||
}
|
351
src/inputs.ts
Normal file
351
src/inputs.ts
Normal file
@ -0,0 +1,351 @@
|
||||
import * as core from '@actions/core'
|
||||
|
||||
export type Inputs = {
|
||||
files: string
|
||||
filesSeparator: string
|
||||
filesFromSourceFile: string
|
||||
filesFromSourceFileSeparator: string
|
||||
filesYaml: string
|
||||
filesYamlFromSourceFile: string
|
||||
filesYamlFromSourceFileSeparator: string
|
||||
filesIgnore: string
|
||||
filesIgnoreSeparator: string
|
||||
filesIgnoreFromSourceFile: string
|
||||
filesIgnoreFromSourceFileSeparator: string
|
||||
filesIgnoreYaml: string
|
||||
filesIgnoreYamlFromSourceFile: string
|
||||
filesIgnoreYamlFromSourceFileSeparator: string
|
||||
separator: string
|
||||
includeAllOldNewRenamedFiles: boolean
|
||||
oldNewSeparator: string
|
||||
oldNewFilesSeparator: string
|
||||
sha: string
|
||||
baseSha: string
|
||||
since: string
|
||||
until: string
|
||||
path: string
|
||||
quotepath: boolean
|
||||
diffRelative: boolean
|
||||
dirNames: boolean
|
||||
dirNamesMaxDepth?: number
|
||||
dirNamesExcludeCurrentDir: boolean
|
||||
dirNamesIncludeFiles: string
|
||||
dirNamesIncludeFilesSeparator: string
|
||||
dirNamesDeletedFilesIncludeOnlyDeletedDirs: boolean
|
||||
json: boolean
|
||||
escapeJson: boolean
|
||||
safeOutput: boolean
|
||||
fetchDepth?: number
|
||||
fetchAdditionalSubmoduleHistory: boolean
|
||||
sinceLastRemoteCommit: boolean
|
||||
writeOutputFiles: boolean
|
||||
outputDir: string
|
||||
outputRenamedFilesAsDeletedAndAdded: boolean
|
||||
recoverDeletedFiles: boolean
|
||||
recoverDeletedFilesToDestination: string
|
||||
recoverFiles: string
|
||||
recoverFilesSeparator: string
|
||||
recoverFilesIgnore: string
|
||||
recoverFilesIgnoreSeparator: string
|
||||
token: string
|
||||
apiUrl: string
|
||||
skipInitialFetch: boolean
|
||||
failOnInitialDiffError: boolean
|
||||
failOnSubmoduleDiffError: boolean
|
||||
negationPatternsFirst: boolean
|
||||
useRestApi: boolean
|
||||
excludeSubmodules: boolean
|
||||
fetchMissingHistoryMaxRetries?: number
|
||||
usePosixPathSeparator: boolean
|
||||
tagsPattern: string
|
||||
tagsIgnorePattern?: string
|
||||
}
|
||||
|
||||
export const getInputs = (): Inputs => {
|
||||
const files = core.getInput('files', {required: false})
|
||||
const filesSeparator = core.getInput('files_separator', {
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
})
|
||||
const filesIgnore = core.getInput('files_ignore', {required: false})
|
||||
const filesIgnoreSeparator = core.getInput('files_ignore_separator', {
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
})
|
||||
const filesFromSourceFile = core.getInput('files_from_source_file', {
|
||||
required: false
|
||||
})
|
||||
const filesFromSourceFileSeparator = core.getInput(
|
||||
'files_from_source_file_separator',
|
||||
{
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
const filesYaml = core.getInput('files_yaml', {required: false})
|
||||
const filesYamlFromSourceFile = core.getInput('files_yaml_from_source_file', {
|
||||
required: false
|
||||
})
|
||||
const filesYamlFromSourceFileSeparator = core.getInput(
|
||||
'files_yaml_from_source_file_separator',
|
||||
{
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
const filesIgnoreFromSourceFile = core.getInput(
|
||||
'files_ignore_from_source_file',
|
||||
{required: false}
|
||||
)
|
||||
const filesIgnoreFromSourceFileSeparator = core.getInput(
|
||||
'files_ignore_from_source_file_separator',
|
||||
{
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
const filesIgnoreYaml = core.getInput('files_ignore_yaml', {required: false})
|
||||
const filesIgnoreYamlFromSourceFile = core.getInput(
|
||||
'files_ignore_yaml_from_source_file',
|
||||
{required: false}
|
||||
)
|
||||
const filesIgnoreYamlFromSourceFileSeparator = core.getInput(
|
||||
'files_ignore_yaml_from_source_file_separator',
|
||||
{
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
const separator = core.getInput('separator', {
|
||||
required: true,
|
||||
trimWhitespace: false
|
||||
})
|
||||
const includeAllOldNewRenamedFiles = core.getBooleanInput(
|
||||
'include_all_old_new_renamed_files',
|
||||
{required: false}
|
||||
)
|
||||
const oldNewSeparator = core.getInput('old_new_separator', {
|
||||
required: true,
|
||||
trimWhitespace: false
|
||||
})
|
||||
const oldNewFilesSeparator = core.getInput('old_new_files_separator', {
|
||||
required: true,
|
||||
trimWhitespace: false
|
||||
})
|
||||
const sha = core.getInput('sha', {required: false})
|
||||
const baseSha = core.getInput('base_sha', {required: false})
|
||||
const since = core.getInput('since', {required: false})
|
||||
const until = core.getInput('until', {required: false})
|
||||
const path = core.getInput('path', {required: false})
|
||||
const quotepath = core.getBooleanInput('quotepath', {required: false})
|
||||
const diffRelative = core.getBooleanInput('diff_relative', {required: false})
|
||||
const dirNames = core.getBooleanInput('dir_names', {required: false})
|
||||
const dirNamesMaxDepth = core.getInput('dir_names_max_depth', {
|
||||
required: false
|
||||
})
|
||||
const dirNamesExcludeCurrentDir = core.getBooleanInput(
|
||||
'dir_names_exclude_current_dir',
|
||||
{
|
||||
required: false
|
||||
}
|
||||
)
|
||||
const dirNamesIncludeFiles = core.getInput('dir_names_include_files', {
|
||||
required: false
|
||||
})
|
||||
const dirNamesIncludeFilesSeparator = core.getInput(
|
||||
'dir_names_include_files_separator',
|
||||
{
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
let json = core.getBooleanInput('json', {required: false})
|
||||
let escapeJson = core.getBooleanInput('escape_json', {required: false})
|
||||
const matrix = core.getBooleanInput('matrix', {required: false})
|
||||
|
||||
if (matrix) {
|
||||
json = true
|
||||
escapeJson = false
|
||||
}
|
||||
|
||||
const safeOutput = core.getBooleanInput('safe_output', {required: false})
|
||||
const fetchDepth = core.getInput('fetch_depth', {required: false})
|
||||
const sinceLastRemoteCommit = core.getBooleanInput(
|
||||
'since_last_remote_commit',
|
||||
{required: false}
|
||||
)
|
||||
const writeOutputFiles = core.getBooleanInput('write_output_files', {
|
||||
required: false
|
||||
})
|
||||
const outputDir = core.getInput('output_dir', {required: false})
|
||||
const outputRenamedFilesAsDeletedAndAdded = core.getBooleanInput(
|
||||
'output_renamed_files_as_deleted_and_added',
|
||||
{required: false}
|
||||
)
|
||||
const recoverDeletedFiles = core.getBooleanInput('recover_deleted_files', {
|
||||
required: false
|
||||
})
|
||||
const recoverDeletedFilesToDestination = core.getInput(
|
||||
'recover_deleted_files_to_destination',
|
||||
{required: false}
|
||||
)
|
||||
const recoverFiles = core.getInput('recover_files', {required: false})
|
||||
const recoverFilesSeparator = core.getInput('recover_files_separator', {
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
})
|
||||
const recoverFilesIgnore = core.getInput('recover_files_ignore', {
|
||||
required: false
|
||||
})
|
||||
const recoverFilesIgnoreSeparator = core.getInput(
|
||||
'recover_files_ignore_separator',
|
||||
{
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
}
|
||||
)
|
||||
const token = core.getInput('token', {required: false})
|
||||
const apiUrl = core.getInput('api_url', {required: false})
|
||||
const skipInitialFetch = core.getBooleanInput('skip_initial_fetch', {
|
||||
required: false
|
||||
})
|
||||
const fetchAdditionalSubmoduleHistory = core.getBooleanInput(
|
||||
'fetch_additional_submodule_history',
|
||||
{
|
||||
required: false
|
||||
}
|
||||
)
|
||||
const failOnInitialDiffError = core.getBooleanInput(
|
||||
'fail_on_initial_diff_error',
|
||||
{
|
||||
required: false
|
||||
}
|
||||
)
|
||||
const failOnSubmoduleDiffError = core.getBooleanInput(
|
||||
'fail_on_submodule_diff_error',
|
||||
{
|
||||
required: false
|
||||
}
|
||||
)
|
||||
const dirNamesDeletedFilesIncludeOnlyDeletedDirs = core.getBooleanInput(
|
||||
'dir_names_deleted_files_include_only_deleted_dirs',
|
||||
{
|
||||
required: false
|
||||
}
|
||||
)
|
||||
|
||||
const negationPatternsFirst = core.getBooleanInput(
|
||||
'negation_patterns_first',
|
||||
{
|
||||
required: false
|
||||
}
|
||||
)
|
||||
|
||||
const useRestApi = core.getBooleanInput('use_rest_api', {
|
||||
required: false
|
||||
})
|
||||
|
||||
const excludeSubmodules = core.getBooleanInput('exclude_submodules', {
|
||||
required: false
|
||||
})
|
||||
|
||||
const fetchMissingHistoryMaxRetries = core.getInput(
|
||||
'fetch_missing_history_max_retries',
|
||||
{required: false}
|
||||
)
|
||||
|
||||
const usePosixPathSeparator = core.getBooleanInput(
|
||||
'use_posix_path_separator',
|
||||
{
|
||||
required: false
|
||||
}
|
||||
)
|
||||
|
||||
const tagsPattern = core.getInput('tags_pattern', {
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
})
|
||||
const tagsIgnorePattern = core.getInput('tags_ignore_pattern', {
|
||||
required: false,
|
||||
trimWhitespace: false
|
||||
})
|
||||
|
||||
const inputs: Inputs = {
|
||||
files,
|
||||
filesSeparator,
|
||||
filesFromSourceFile,
|
||||
filesFromSourceFileSeparator,
|
||||
filesYaml,
|
||||
filesYamlFromSourceFile,
|
||||
filesYamlFromSourceFileSeparator,
|
||||
filesIgnore,
|
||||
filesIgnoreSeparator,
|
||||
filesIgnoreFromSourceFile,
|
||||
filesIgnoreFromSourceFileSeparator,
|
||||
filesIgnoreYaml,
|
||||
filesIgnoreYamlFromSourceFile,
|
||||
filesIgnoreYamlFromSourceFileSeparator,
|
||||
failOnInitialDiffError,
|
||||
failOnSubmoduleDiffError,
|
||||
separator,
|
||||
// Not Supported via REST API
|
||||
sha,
|
||||
baseSha,
|
||||
since,
|
||||
until,
|
||||
path,
|
||||
quotepath,
|
||||
diffRelative,
|
||||
sinceLastRemoteCommit,
|
||||
recoverDeletedFiles,
|
||||
recoverDeletedFilesToDestination,
|
||||
recoverFiles,
|
||||
recoverFilesSeparator,
|
||||
recoverFilesIgnore,
|
||||
recoverFilesIgnoreSeparator,
|
||||
includeAllOldNewRenamedFiles,
|
||||
oldNewSeparator,
|
||||
oldNewFilesSeparator,
|
||||
skipInitialFetch,
|
||||
fetchAdditionalSubmoduleHistory,
|
||||
dirNamesDeletedFilesIncludeOnlyDeletedDirs,
|
||||
excludeSubmodules,
|
||||
usePosixPathSeparator,
|
||||
tagsPattern,
|
||||
tagsIgnorePattern,
|
||||
// End Not Supported via REST API
|
||||
dirNames,
|
||||
dirNamesExcludeCurrentDir,
|
||||
dirNamesIncludeFiles,
|
||||
dirNamesIncludeFilesSeparator,
|
||||
json,
|
||||
escapeJson,
|
||||
safeOutput,
|
||||
writeOutputFiles,
|
||||
outputDir,
|
||||
outputRenamedFilesAsDeletedAndAdded,
|
||||
token,
|
||||
apiUrl,
|
||||
negationPatternsFirst,
|
||||
useRestApi
|
||||
}
|
||||
|
||||
if (fetchDepth) {
|
||||
// Fallback to at least 2 if the fetch_depth is less than 2
|
||||
inputs.fetchDepth = Math.max(parseInt(fetchDepth, 10), 2)
|
||||
}
|
||||
|
||||
if (dirNamesMaxDepth) {
|
||||
inputs.dirNamesMaxDepth = parseInt(dirNamesMaxDepth, 10)
|
||||
}
|
||||
|
||||
if (fetchMissingHistoryMaxRetries) {
|
||||
// Fallback to at least 1 if the fetch_missing_history_max_retries is less than 1
|
||||
inputs.fetchMissingHistoryMaxRetries = Math.max(
|
||||
parseInt(fetchMissingHistoryMaxRetries, 10),
|
||||
1
|
||||
)
|
||||
}
|
||||
|
||||
return inputs
|
||||
}
|
298
src/main.ts
Normal file
298
src/main.ts
Normal file
@ -0,0 +1,298 @@
|
||||
import * as core from '@actions/core'
|
||||
import * as github from '@actions/github'
|
||||
import path from 'path'
|
||||
import {
|
||||
processChangedFiles,
|
||||
ChangeTypeEnum,
|
||||
getAllDiffFiles,
|
||||
getChangedFilesFromGithubAPI,
|
||||
getRenamedFiles
|
||||
} from './changedFiles'
|
||||
import {
|
||||
DiffResult,
|
||||
getSHAForNonPullRequestEvent,
|
||||
getSHAForPullRequestEvent
|
||||
} from './commitSha'
|
||||
import {Env, getEnv} from './env'
|
||||
import {getInputs, Inputs} from './inputs'
|
||||
import {
|
||||
getFilePatterns,
|
||||
getRecoverFilePatterns,
|
||||
getSubmodulePath,
|
||||
getYamlFilePatterns,
|
||||
hasLocalGitDirectory,
|
||||
isRepoShallow,
|
||||
recoverDeletedFiles,
|
||||
setOutput,
|
||||
submoduleExists,
|
||||
updateGitGlobalConfig,
|
||||
verifyMinimumGitVersion,
|
||||
warnUnsupportedRESTAPIInputs
|
||||
} from './utils'
|
||||
|
||||
const getChangedFilesFromLocalGitHistory = async ({
|
||||
inputs,
|
||||
env,
|
||||
workingDirectory,
|
||||
filePatterns,
|
||||
yamlFilePatterns
|
||||
}: {
|
||||
inputs: Inputs
|
||||
env: Env
|
||||
workingDirectory: string
|
||||
filePatterns: string[]
|
||||
yamlFilePatterns: Record<string, string[]>
|
||||
}): Promise<void> => {
|
||||
await verifyMinimumGitVersion()
|
||||
|
||||
let quotepathValue = 'on'
|
||||
|
||||
if (!inputs.quotepath) {
|
||||
quotepathValue = 'off'
|
||||
}
|
||||
|
||||
await updateGitGlobalConfig({
|
||||
name: 'core.quotepath',
|
||||
value: quotepathValue
|
||||
})
|
||||
|
||||
if (inputs.diffRelative) {
|
||||
await updateGitGlobalConfig({
|
||||
name: 'diff.relative',
|
||||
value: 'true'
|
||||
})
|
||||
}
|
||||
|
||||
const isShallow = await isRepoShallow({cwd: workingDirectory})
|
||||
let diffSubmodule = false
|
||||
let gitFetchExtraArgs = ['--no-tags', '--prune']
|
||||
|
||||
if (inputs.excludeSubmodules) {
|
||||
core.info('Excluding submodules from the diff')
|
||||
} else {
|
||||
diffSubmodule = await submoduleExists({cwd: workingDirectory})
|
||||
}
|
||||
|
||||
if (diffSubmodule) {
|
||||
gitFetchExtraArgs.push('--recurse-submodules')
|
||||
}
|
||||
|
||||
const isTag = env.GITHUB_REF?.startsWith('refs/tags/')
|
||||
const remoteName = 'origin'
|
||||
const outputRenamedFilesAsDeletedAndAdded =
|
||||
inputs.outputRenamedFilesAsDeletedAndAdded
|
||||
let submodulePaths: string[] = []
|
||||
|
||||
if (diffSubmodule) {
|
||||
submodulePaths = await getSubmodulePath({cwd: workingDirectory})
|
||||
}
|
||||
|
||||
if (isTag) {
|
||||
gitFetchExtraArgs = ['--prune', '--no-recurse-submodules']
|
||||
}
|
||||
|
||||
let diffResult: DiffResult
|
||||
|
||||
if (!github.context.payload.pull_request?.base?.ref) {
|
||||
core.info(`Running on a ${github.context.eventName || 'push'} event...`)
|
||||
diffResult = await getSHAForNonPullRequestEvent({
|
||||
inputs,
|
||||
env,
|
||||
workingDirectory,
|
||||
isShallow,
|
||||
diffSubmodule,
|
||||
gitFetchExtraArgs,
|
||||
isTag,
|
||||
remoteName
|
||||
})
|
||||
} else {
|
||||
core.info(
|
||||
`Running on a ${github.context.eventName || 'pull_request'} (${
|
||||
github.context.payload.action
|
||||
}) event...`
|
||||
)
|
||||
diffResult = await getSHAForPullRequestEvent({
|
||||
inputs,
|
||||
workingDirectory,
|
||||
isShallow,
|
||||
diffSubmodule,
|
||||
gitFetchExtraArgs,
|
||||
remoteName
|
||||
})
|
||||
}
|
||||
|
||||
if (diffResult.initialCommit) {
|
||||
core.info('This is the first commit for this repository; exiting...')
|
||||
core.endGroup()
|
||||
return
|
||||
}
|
||||
|
||||
core.info(
|
||||
`Retrieving changes between ${diffResult.previousSha} (${diffResult.targetBranch}) → ${diffResult.currentSha} (${diffResult.currentBranch})`
|
||||
)
|
||||
|
||||
const allDiffFiles = await getAllDiffFiles({
|
||||
workingDirectory,
|
||||
diffSubmodule,
|
||||
diffResult,
|
||||
submodulePaths,
|
||||
outputRenamedFilesAsDeletedAndAdded,
|
||||
fetchAdditionalSubmoduleHistory: inputs.fetchAdditionalSubmoduleHistory,
|
||||
failOnInitialDiffError: inputs.failOnInitialDiffError,
|
||||
failOnSubmoduleDiffError: inputs.failOnSubmoduleDiffError
|
||||
})
|
||||
core.debug(`All diff files: ${JSON.stringify(allDiffFiles)}`)
|
||||
core.info('All Done!')
|
||||
core.endGroup()
|
||||
|
||||
if (inputs.recoverDeletedFiles) {
|
||||
let recoverPatterns = getRecoverFilePatterns({inputs})
|
||||
|
||||
if (recoverPatterns.length > 0 && filePatterns.length > 0) {
|
||||
core.info('No recover patterns found; defaulting to file patterns')
|
||||
recoverPatterns = filePatterns
|
||||
}
|
||||
|
||||
await recoverDeletedFiles({
|
||||
inputs,
|
||||
workingDirectory,
|
||||
deletedFiles: allDiffFiles[ChangeTypeEnum.Deleted],
|
||||
recoverPatterns,
|
||||
diffResult,
|
||||
diffSubmodule,
|
||||
submodulePaths
|
||||
})
|
||||
}
|
||||
|
||||
await processChangedFiles({
|
||||
filePatterns,
|
||||
allDiffFiles,
|
||||
inputs,
|
||||
yamlFilePatterns,
|
||||
workingDirectory
|
||||
})
|
||||
|
||||
if (inputs.includeAllOldNewRenamedFiles) {
|
||||
core.startGroup('changed-files-all-old-new-renamed-files')
|
||||
const allOldNewRenamedFiles = await getRenamedFiles({
|
||||
inputs,
|
||||
workingDirectory,
|
||||
diffSubmodule,
|
||||
diffResult,
|
||||
submodulePaths
|
||||
})
|
||||
core.debug(`All old new renamed files: ${allOldNewRenamedFiles}`)
|
||||
await setOutput({
|
||||
key: 'all_old_new_renamed_files',
|
||||
value: allOldNewRenamedFiles.paths,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json,
|
||||
safeOutput: inputs.safeOutput
|
||||
})
|
||||
await setOutput({
|
||||
key: 'all_old_new_renamed_files_count',
|
||||
value: allOldNewRenamedFiles.count,
|
||||
writeOutputFiles: inputs.writeOutputFiles,
|
||||
outputDir: inputs.outputDir,
|
||||
json: inputs.json
|
||||
})
|
||||
core.info('All Done!')
|
||||
core.endGroup()
|
||||
}
|
||||
}
|
||||
|
||||
const getChangedFilesFromRESTAPI = async ({
|
||||
inputs,
|
||||
filePatterns,
|
||||
yamlFilePatterns
|
||||
}: {
|
||||
inputs: Inputs
|
||||
filePatterns: string[]
|
||||
yamlFilePatterns: Record<string, string[]>
|
||||
}): Promise<void> => {
|
||||
const allDiffFiles = await getChangedFilesFromGithubAPI({
|
||||
inputs
|
||||
})
|
||||
core.debug(`All diff files: ${JSON.stringify(allDiffFiles)}`)
|
||||
core.info('All Done!')
|
||||
|
||||
await processChangedFiles({
|
||||
filePatterns,
|
||||
allDiffFiles,
|
||||
inputs,
|
||||
yamlFilePatterns
|
||||
})
|
||||
}
|
||||
|
||||
export async function run(): Promise<void> {
|
||||
core.startGroup('changed-files')
|
||||
|
||||
const env = await getEnv()
|
||||
core.debug(`Env: ${JSON.stringify(env, null, 2)}`)
|
||||
|
||||
const inputs = getInputs()
|
||||
core.debug(`Inputs: ${JSON.stringify(inputs, null, 2)}`)
|
||||
|
||||
const workingDirectory = path.resolve(
|
||||
env.GITHUB_WORKSPACE || process.cwd(),
|
||||
inputs.useRestApi ? '.' : inputs.path
|
||||
)
|
||||
core.debug(`Working directory: ${workingDirectory}`)
|
||||
|
||||
const hasGitDirectory = await hasLocalGitDirectory({workingDirectory})
|
||||
core.debug(`Has git directory: ${hasGitDirectory}`)
|
||||
|
||||
const filePatterns = await getFilePatterns({
|
||||
inputs,
|
||||
workingDirectory
|
||||
})
|
||||
core.debug(`File patterns: ${filePatterns}`)
|
||||
|
||||
const yamlFilePatterns = await getYamlFilePatterns({
|
||||
inputs,
|
||||
workingDirectory
|
||||
})
|
||||
core.debug(`Yaml file patterns: ${JSON.stringify(yamlFilePatterns)}`)
|
||||
|
||||
if (inputs.useRestApi && !github.context.payload.pull_request?.number) {
|
||||
throw new Error(
|
||||
"Only pull_request* events are supported when using GitHub's REST API."
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
inputs.token &&
|
||||
github.context.payload.pull_request?.number &&
|
||||
(!hasGitDirectory || inputs.useRestApi)
|
||||
) {
|
||||
core.info("Using GitHub's REST API to get changed files")
|
||||
await warnUnsupportedRESTAPIInputs({inputs})
|
||||
await getChangedFilesFromRESTAPI({
|
||||
inputs,
|
||||
filePatterns,
|
||||
yamlFilePatterns
|
||||
})
|
||||
} else {
|
||||
if (!hasGitDirectory) {
|
||||
throw new Error(
|
||||
`Unable to locate the git repository in the given path: ${workingDirectory}.\n Please run actions/checkout before this action (Make sure the 'path' input is correct).\n If you intend to use Github's REST API note that only pull_request* events are supported. Current event is "${github.context.eventName}".`
|
||||
)
|
||||
}
|
||||
|
||||
core.info('Using local .git directory')
|
||||
await getChangedFilesFromLocalGitHistory({
|
||||
inputs,
|
||||
env,
|
||||
workingDirectory,
|
||||
filePatterns,
|
||||
yamlFilePatterns
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line github/no-then
|
||||
run().catch(e => {
|
||||
core.setFailed(e.message || e)
|
||||
process.exit(1)
|
||||
})
|
1583
src/utils.ts
Normal file
1583
src/utils.ts
Normal file
File diff suppressed because it is too large
Load Diff
1
test/[test new].txt
Normal file
1
test/[test new].txt
Normal file
@ -0,0 +1 @@
|
||||
This is a test file
|
7
test/changed-files-list.txt
Normal file
7
test/changed-files-list.txt
Normal file
@ -0,0 +1,7 @@
|
||||
.github/workflows/test.yml
|
||||
action.yml
|
||||
action.yml
|
||||
action.yml
|
||||
**/test.txt
|
||||
!test/test/test.txt
|
||||
[test new].txt
|
16
test/changed-files.yml
Normal file
16
test/changed-files.yml
Normal file
@ -0,0 +1,16 @@
|
||||
test:
|
||||
- test/**.txt
|
||||
src:
|
||||
- src/*.ts
|
||||
- '!src/__tests__/**'
|
||||
dist:
|
||||
- dist/**
|
||||
shared: &shared
|
||||
- .github/**
|
||||
common:
|
||||
- *shared
|
||||
- .gitignore
|
||||
multiline: |
|
||||
test/**
|
||||
src/*.ts
|
||||
.github/**
|
1
test/demo
Submodule
1
test/demo
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 5dfac2e9a7dc53ca33bc4682355193672c97437c
|
1
test/new.md
Normal file
1
test/new.md
Normal file
@ -0,0 +1 @@
|
||||
This is a test markdown file
|
1
test/test new 1.txt
Normal file
1
test/test new 1.txt
Normal file
@ -0,0 +1 @@
|
||||
This is a test file
|
1
test/test new.txt
Normal file
1
test/test new.txt
Normal file
@ -0,0 +1 @@
|
||||
This is a test file.
|
1
test/test rename 2.txt
Normal file
1
test/test rename 2.txt
Normal file
@ -0,0 +1 @@
|
||||
This is test file 2.
|
1
test/test rename-1.txt
Normal file
1
test/test rename-1.txt
Normal file
@ -0,0 +1 @@
|
||||
This is a test file 1.
|
1
test/test-è.txt
Normal file
1
test/test-è.txt
Normal file
@ -0,0 +1 @@
|
||||
This is a test file with non ASCII character in the filename.
|
1
test/test.txt
Normal file
1
test/test.txt
Normal file
@ -0,0 +1 @@
|
||||
This is a test file...
|
1
test/test/test.txt
Normal file
1
test/test/test.txt
Normal file
@ -0,0 +1 @@
|
||||
This is a test file.
|
1
test/test2/test.txt
Normal file
1
test/test2/test.txt
Normal file
@ -0,0 +1 @@
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
1
test/test2/test3/new.txt
Normal file
1
test/test2/test3/new.txt
Normal file
@ -0,0 +1 @@
|
||||
Test file.
|
1
test/test2/test3/test4/test.txt
Normal file
1
test/test2/test3/test4/test.txt
Normal file
@ -0,0 +1 @@
|
||||
Test file.
|
12
tsconfig.json
Normal file
12
tsconfig.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||
"outDir": "./lib", /* Redirect output structure to the directory. */
|
||||
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
},
|
||||
"exclude": ["node_modules", "jest/setEnvVars.cjs"]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user