Compare commits
672 Commits
v0.1.0-bet
...
v0.26.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5205f4197c | ||
|
|
c76674dd4a | ||
|
|
8471422135 | ||
|
|
e266e3e984 | ||
|
|
1b7201d572 | ||
|
|
6983a397f4 | ||
|
|
81e959d041 | ||
|
|
475cefa34e | ||
|
|
c14688a151 | ||
|
|
dde9860104 | ||
|
|
ee6e7bbd95 | ||
|
|
fe58cc26f5 | ||
|
|
1bf4b58db1 | ||
|
|
82d10009f7 | ||
|
|
bf985d0056 | ||
|
|
129955ee04 | ||
|
|
6d74aad91b | ||
|
|
24546185f6 | ||
|
|
1b5c574732 | ||
|
|
2ace0cd1f7 | ||
|
|
33d4b448ac | ||
|
|
ee91773603 | ||
|
|
5186ba6fdf | ||
|
|
1309d2023e | ||
|
|
6a4479ebc2 | ||
|
|
cd9f97a8c5 | ||
|
|
65f5b77696 | ||
|
|
9ba5af418c | ||
|
|
93ae2ded04 | ||
|
|
15788e8b93 | ||
|
|
92053e1988 | ||
|
|
6d856fd53e | ||
|
|
e67313ac6d | ||
|
|
881230f4b0 | ||
|
|
6fb52d2a23 | ||
|
|
2941f52b66 | ||
|
|
760d0c2369 | ||
|
|
d344961874 | ||
|
|
5958c823ef | ||
|
|
a033bb70cd | ||
|
|
8f8c0bb7ec | ||
|
|
0903e498a4 | ||
|
|
1e903f84b6 | ||
|
|
3a2e4a89a6 | ||
|
|
b3dc87c0e0 | ||
|
|
bd1955c564 | ||
|
|
956acbf3c6 | ||
|
|
ea36deec7f | ||
|
|
9d829e4f4a | ||
|
|
66c00b9bbd | ||
|
|
448f9ac218 | ||
|
|
624e16fb7c | ||
|
|
ee84f2ac79 | ||
|
|
7eb10a1871 | ||
|
|
27a4b44e2c | ||
|
|
75c874dd62 | ||
|
|
c94131a9e9 | ||
|
|
ec0a6e279b | ||
|
|
e0dd35a21c | ||
|
|
b25aadfb15 | ||
|
|
70f40871ae | ||
|
|
61d2e66416 | ||
|
|
c425c1b90c | ||
|
|
4a832ddb12 | ||
|
|
adf692bdc3 | ||
|
|
022c68391f | ||
|
|
eea3ac78bc | ||
|
|
76526d71ff | ||
|
|
4078ffc721 | ||
|
|
ffa2fadd58 | ||
|
|
53d4eba877 | ||
|
|
2c7c8d2118 | ||
|
|
4e56c9c296 | ||
|
|
ae20b6fb50 | ||
|
|
a99525f2f1 | ||
|
|
5820a0ba86 | ||
|
|
62e3923775 | ||
|
|
a459c7c911 | ||
|
|
4c3e9b6acf | ||
|
|
139c4c71de | ||
|
|
4383056550 | ||
|
|
40802f0aa9 | ||
|
|
8f9d3a3d14 | ||
|
|
e41efdd2aa | ||
|
|
33688c4ac8 | ||
|
|
f549f7954e | ||
|
|
5bbaf90158 | ||
|
|
00abdc0e59 | ||
|
|
0f39343265 | ||
|
|
97b80719d2 | ||
|
|
e03b1899b0 | ||
|
|
aece826a8c | ||
|
|
e6bbe6fe93 | ||
|
|
7621606be3 | ||
|
|
4ebe781891 | ||
|
|
a783f79a57 | ||
|
|
8d18a4a3a8 | ||
|
|
045a9c213c | ||
|
|
db0a36131e | ||
|
|
8d4d79eeb7 | ||
|
|
d44748420a | ||
|
|
b4e58da038 | ||
|
|
db6f070033 | ||
|
|
f35cc699c5 | ||
|
|
be6d9ea002 | ||
|
|
579376516d | ||
|
|
3c3a909fe3 | ||
|
|
53bcd3e6fe | ||
|
|
c6f16e945f | ||
|
|
06acacde0e | ||
|
|
2bba1c12c1 | ||
|
|
ad54dd379e | ||
|
|
a40fd9420f | ||
|
|
4d8bd68c1c | ||
|
|
43d331f793 | ||
|
|
fc4dae47b6 | ||
|
|
aa0228d826 | ||
|
|
02007009cc | ||
|
|
329c1c75cf | ||
|
|
056cded622 | ||
|
|
c47291c3a8 | ||
|
|
b73c694210 | ||
|
|
84b6763d80 | ||
|
|
10b5647a43 | ||
|
|
18e4452bac | ||
|
|
eb5663273f | ||
|
|
0bd3773680 | ||
|
|
f6cafdfce1 | ||
|
|
416c2914df | ||
|
|
341bae465f | ||
|
|
264a0eec2a | ||
|
|
545f7cd6ea | ||
|
|
de2888af87 | ||
|
|
43f61228ec | ||
|
|
8d1d731562 | ||
|
|
5706b95a7f | ||
|
|
5d8b7b4828 | ||
|
|
48e339fd34 | ||
|
|
41cae83741 | ||
|
|
d58f77be10 | ||
|
|
a24f5c12ca | ||
|
|
e73765a5ce | ||
|
|
cd14c5b580 | ||
|
|
9b446bf084 | ||
|
|
cbcf885731 | ||
|
|
5fba0d0374 | ||
|
|
d0e492964d | ||
|
|
e1fa386cb5 | ||
|
|
3401826b29 | ||
|
|
90c8d29f29 | ||
|
|
22e390c8ba | ||
|
|
70d3d9ae67 | ||
|
|
9436c6ca61 | ||
|
|
225d61b701 | ||
|
|
5dacef0ba8 | ||
|
|
26887092dc | ||
|
|
8dc7edb368 | ||
|
|
5879437e96 | ||
|
|
1c0d7a58fd | ||
|
|
e6c7da2fcd | ||
|
|
a98aa046a8 | ||
|
|
63adf44466 | ||
|
|
7fb507050a | ||
|
|
8e9a04559b | ||
|
|
224d7ab315 | ||
|
|
755c685d84 | ||
|
|
7d8b4dc669 | ||
|
|
cae64f370a | ||
|
|
7ed7bac5eb | ||
|
|
d86f59520c | ||
|
|
e1439ff231 | ||
|
|
cbb7546c52 | ||
|
|
05a9e511a8 | ||
|
|
8125540486 | ||
|
|
aff5040515 | ||
|
|
30cd573d15 | ||
|
|
3653f3bca9 | ||
|
|
250b2120b4 | ||
|
|
7ea6ed7dab | ||
|
|
3344f7b1c8 | ||
|
|
619687375a | ||
|
|
cbc244c2f4 | ||
|
|
f1c76199be | ||
|
|
b0d1226bb6 | ||
|
|
039e7f9c6e | ||
|
|
048d6c3fbe | ||
|
|
59a3548fbb | ||
|
|
c1429fefa4 | ||
|
|
1274cd2848 | ||
|
|
48394d7948 | ||
|
|
aebb2a6f58 | ||
|
|
dff5cd7e88 | ||
|
|
7e4d49d3be | ||
|
|
dee5356ab8 | ||
|
|
2267dad53e | ||
|
|
666b19e915 | ||
|
|
a5975adf41 | ||
|
|
3f7d7f75b5 | ||
|
|
299d4131fa | ||
|
|
ab1052f7e0 | ||
|
|
bf4bc3c036 | ||
|
|
49a22f7a3e | ||
|
|
03b8464ee3 | ||
|
|
0a1d2c2307 | ||
|
|
0adac517e3 | ||
|
|
012b121eb5 | ||
|
|
11cc7c697d | ||
|
|
0721cb2aa9 | ||
|
|
26949f5f39 | ||
|
|
32b78e4566 | ||
|
|
2d240ca0fc | ||
|
|
8c09071628 | ||
|
|
a9fec88f7a | ||
|
|
066518ecec | ||
|
|
d63347f68f | ||
|
|
9282d3e13b | ||
|
|
d240b3146a | ||
|
|
7063f758ae | ||
|
|
ad2fe8539c | ||
|
|
5d0a08a448 | ||
|
|
66f17c25e3 | ||
|
|
bf9adbe540 | ||
|
|
f2a56cda90 | ||
|
|
a60fe56754 | ||
|
|
9c42213ecc | ||
|
|
2e9fde295e | ||
|
|
942777afdc | ||
|
|
d468250481 | ||
|
|
8854de97ed | ||
|
|
666e090b82 | ||
|
|
f04fa19563 | ||
|
|
f8b8b5b18d | ||
|
|
f92cc3db0b | ||
|
|
032e16cf73 | ||
|
|
a6a71daf88 | ||
|
|
e298150fd7 | ||
|
|
a99fb34091 | ||
|
|
3a20771080 | ||
|
|
5430d017a5 | ||
|
|
e3bdf20325 | ||
|
|
f8ca396f63 | ||
|
|
603112bbed | ||
|
|
31a5828eff | ||
|
|
b3bb7713d9 | ||
|
|
6273173795 | ||
|
|
5fd725469f | ||
|
|
7929028d80 | ||
|
|
4995997eed | ||
|
|
348446a8d6 | ||
|
|
c8a1b7a531 | ||
|
|
911d146f5f | ||
|
|
0cc3169aa7 | ||
|
|
1de2911b5e | ||
|
|
9e9fc490d2 | ||
|
|
a45afd3161 | ||
|
|
7d829c430b | ||
|
|
ddc04994d9 | ||
|
|
b613f395b8 | ||
|
|
9e405d775a | ||
|
|
248fc44d7e | ||
|
|
e907622be4 | ||
|
|
5bc270dc53 | ||
|
|
c1ecc4b621 | ||
|
|
0a04d5661f | ||
|
|
252cfd570c | ||
|
|
2f97829cfc | ||
|
|
ea541ecec7 | ||
|
|
64a550a5dc | ||
|
|
73bb35d328 | ||
|
|
97573bff9a | ||
|
|
cef4c16170 | ||
|
|
3281ef2a12 | ||
|
|
03b93c3aee | ||
|
|
f8909e3265 | ||
|
|
624fee6e10 | ||
|
|
e927ebb09c | ||
|
|
5250fc63c3 | ||
|
|
77c591b46c | ||
|
|
602235dcce | ||
|
|
3ca52c06b2 | ||
|
|
7c2659dc5d | ||
|
|
307731cacb | ||
|
|
81355687c2 | ||
|
|
cca99038ee | ||
|
|
24a9fd8152 | ||
|
|
53e9f24dd0 | ||
|
|
b525cd9de8 | ||
|
|
21a7def1e9 | ||
|
|
243e746a8d | ||
|
|
b212b3b35e | ||
|
|
191def3857 | ||
|
|
0e5f8a766a | ||
|
|
a625c7487f | ||
|
|
e8569c2d9b | ||
|
|
7b1a9e4e34 | ||
|
|
8b3ff1beb0 | ||
|
|
35555f7a24 | ||
|
|
5562309585 | ||
|
|
2848275bb4 | ||
|
|
48c7d682b4 | ||
|
|
04d1940f48 | ||
|
|
6af9ce25af | ||
|
|
1e2ed9bcf1 | ||
|
|
3e8e9fc046 | ||
|
|
663d108e8d | ||
|
|
2629338e09 | ||
|
|
7a01b3e2a4 | ||
|
|
c363216f0d | ||
|
|
0ebe5d1c2f | ||
|
|
6d03d1708d | ||
|
|
d6753812df | ||
|
|
3f7939e71c | ||
|
|
584493d659 | ||
|
|
dd4311c75e | ||
|
|
b91698741e | ||
|
|
36e5638636 | ||
|
|
d852953482 | ||
|
|
9bb2a9fe23 | ||
|
|
f4fdb6a9f8 | ||
|
|
558d76d017 | ||
|
|
f3dd07df13 | ||
|
|
0455460f6f | ||
|
|
f5c9bb7acd | ||
|
|
9d75f8f839 | ||
|
|
b86f723512 | ||
|
|
d3d7271f87 | ||
|
|
fddef161c1 | ||
|
|
e75930a3a6 | ||
|
|
bd5e1d1bab | ||
|
|
354737b4fc | ||
|
|
eea8c07dcc | ||
|
|
f08154f2c4 | ||
|
|
aae835e4b4 | ||
|
|
6f9aedec5e | ||
|
|
78cfd0384b | ||
|
|
d5f67f772e | ||
|
|
cb4777c2a5 | ||
|
|
80845a187b | ||
|
|
66e22ce5a5 | ||
|
|
7b63a1220d | ||
|
|
59715cf565 | ||
|
|
e8cb844045 | ||
|
|
a00c49179b | ||
|
|
dc2c313f17 | ||
|
|
c73f530a0e | ||
|
|
66fff011ac | ||
|
|
c4085cc810 | ||
|
|
79d8877773 | ||
|
|
95ac6338f1 | ||
|
|
7b72d5977b | ||
|
|
2ad0e2331e | ||
|
|
f2d14e7769 | ||
|
|
33dc7b6ecb | ||
|
|
6bf3dcef73 | ||
|
|
31d5e42cc0 | ||
|
|
32e2a6bf6f | ||
|
|
c8d666e020 | ||
|
|
49ed594253 | ||
|
|
144df6eecc | ||
|
|
c3e31dcc03 | ||
|
|
0f8ae202d6 | ||
|
|
c674e727ec | ||
|
|
a72977ca69 | ||
|
|
a6558f6584 | ||
|
|
6a8f167e10 | ||
|
|
19f5e39cc1 | ||
|
|
945af30d0c | ||
|
|
24a56dbe42 | ||
|
|
4e8d894523 | ||
|
|
5b15c952e9 | ||
|
|
9822f1ac09 | ||
|
|
b9121242ac | ||
|
|
c759388ee4 | ||
|
|
dfcd13e51e | ||
|
|
2be3d9389c | ||
|
|
541f8784ed | ||
|
|
4abccc4c6a | ||
|
|
fcc92b092b | ||
|
|
6e043aee71 | ||
|
|
7a37a260aa | ||
|
|
1534dfad1b | ||
|
|
08e669e7d5 | ||
|
|
83d366eb65 | ||
|
|
5b760c8b3a | ||
|
|
674ee4994a | ||
|
|
a56ca8f880 | ||
|
|
b833243795 | ||
|
|
823d1cfce9 | ||
|
|
97bc88d30b | ||
|
|
ed4441e704 | ||
|
|
7a4b2122b2 | ||
|
|
959fb2fd2e | ||
|
|
2c0d9d0c4e | ||
|
|
3199bce461 | ||
|
|
f1593e3aa2 | ||
|
|
db5c712dec | ||
|
|
fd97af130e | ||
|
|
ec700a3813 | ||
|
|
324e807d2e | ||
|
|
8e45354f0c | ||
|
|
906aacf7ff | ||
|
|
1d9f94872d | ||
|
|
b99f9ec3ef | ||
|
|
8d02bad9a9 | ||
|
|
c1edd0b5e3 | ||
|
|
70c0e12f74 | ||
|
|
ddcd63c92a | ||
|
|
0e5fc3661a | ||
|
|
3d49d98580 | ||
|
|
ca519e1aa8 | ||
|
|
b13ef76b5e | ||
|
|
2043356c92 | ||
|
|
84371bb189 | ||
|
|
ad6e71b881 | ||
|
|
e47142d45b | ||
|
|
e79f79bcd9 | ||
|
|
ab02f62089 | ||
|
|
8cef70fefb | ||
|
|
321a028303 | ||
|
|
80eaf0972b | ||
|
|
101a44b0a7 | ||
|
|
22cc0b6c27 | ||
|
|
21fdfc52c4 | ||
|
|
eebb677d5a | ||
|
|
495c96b050 | ||
|
|
b1e0aeed50 | ||
|
|
d0ee813215 | ||
|
|
b2a51dd6b4 | ||
|
|
acd3c9df19 | ||
|
|
8ad595b445 | ||
|
|
9450a454a7 | ||
|
|
a7221012c8 | ||
|
|
6fc5565c73 | ||
|
|
7492c7193a | ||
|
|
f05a598a08 | ||
|
|
fc85cef9e1 | ||
|
|
a5b683b46e | ||
|
|
0b166c63ef | ||
|
|
e072607266 | ||
|
|
a1ffbe9606 | ||
|
|
fdd740da2d | ||
|
|
8a9577d5e2 | ||
|
|
ca7a29d2d7 | ||
|
|
d39585b339 | ||
|
|
2e3ba6678f | ||
|
|
337a7240a5 | ||
|
|
728fcdbea9 | ||
|
|
dfa1a320c4 | ||
|
|
4ff86b974f | ||
|
|
181782ba21 | ||
|
|
dd977d3597 | ||
|
|
776422c908 | ||
|
|
d86a125551 | ||
|
|
633f41191f | ||
|
|
79def6b218 | ||
|
|
31e5d12fd9 | ||
|
|
1eda4b6a6c | ||
|
|
c71f3fe1ba | ||
|
|
8c8294806e | ||
|
|
ec382328c4 | ||
|
|
051c91700a | ||
|
|
471068fc6f | ||
|
|
60feaf2f84 | ||
|
|
ec33a95de8 | ||
|
|
b45f7f151f | ||
|
|
0ad6a34d2a | ||
|
|
4445b1e4fc | ||
|
|
9cca84f1d8 | ||
|
|
cf39a26d01 | ||
|
|
3ebf172e37 | ||
|
|
dba2a69f61 | ||
|
|
dd07d9ea06 | ||
|
|
0af70ae7cf | ||
|
|
0f6ebcb798 | ||
|
|
3f543accc6 | ||
|
|
16bbae82de | ||
|
|
8b597ca8bc | ||
|
|
dc9c9bc2b7 | ||
|
|
63659873d5 | ||
|
|
6327a9b5dc | ||
|
|
50b16df20c | ||
|
|
0b1e18cfc2 | ||
|
|
741d2e1319 | ||
|
|
9e10ac6818 | ||
|
|
65f12dcfd0 | ||
|
|
46da20f01d | ||
|
|
0af3fda4f0 | ||
|
|
6179a5a445 | ||
|
|
26d9901f07 | ||
|
|
462c95e83d | ||
|
|
e185293749 | ||
|
|
2d1ce9a223 | ||
|
|
2d105f7337 | ||
|
|
5df47fe964 | ||
|
|
61527248dd | ||
|
|
210b7421e4 | ||
|
|
e9aa8365e3 | ||
|
|
85557d0e0d | ||
|
|
a7448298e0 | ||
|
|
d0929eeb16 | ||
|
|
da9600bbef | ||
|
|
70fba4e078 | ||
|
|
a89868cdc5 | ||
|
|
49bde5a54a | ||
|
|
4fcbf75fc4 | ||
|
|
314f8f431e | ||
|
|
7fb0476dc8 | ||
|
|
9b9ff70b75 | ||
|
|
e7eee6e401 | ||
|
|
b2fd32e0ef | ||
|
|
417136db1e | ||
|
|
e033e82024 | ||
|
|
b3328f5ec4 | ||
|
|
b0518231d0 | ||
|
|
c0da63f810 | ||
|
|
041d9693ab | ||
|
|
39158d8047 | ||
|
|
a6c94b5167 | ||
|
|
a5943234fd | ||
|
|
03977693c1 | ||
|
|
d6d770f303 | ||
|
|
8df8cee02f | ||
|
|
94febd1da7 | ||
|
|
b7cdc617ce | ||
|
|
75c0c7fac0 | ||
|
|
e9cfd63e16 | ||
|
|
ac61bd8949 | ||
|
|
7b50104faa | ||
|
|
d7735e9ddf | ||
|
|
dd1544e1be | ||
|
|
32af66cb28 | ||
|
|
2090433c0d | ||
|
|
50c11e6dce | ||
|
|
0f9cc7c29f | ||
|
|
dfc72fd31c | ||
|
|
317ef51ab5 | ||
|
|
3a30337d24 | ||
|
|
fc16ecda91 | ||
|
|
48cefc1da0 | ||
|
|
fda3be9699 | ||
|
|
53ca96fcc4 | ||
|
|
70390c899b | ||
|
|
ac9d9d9a1b | ||
|
|
3c2fe5ddb2 | ||
|
|
adad1e3786 | ||
|
|
3a0f4db686 | ||
|
|
2201fc1194 | ||
|
|
6210eb507a | ||
|
|
3b532d1b91 | ||
|
|
93fa96f54f | ||
|
|
3ec6f00f46 | ||
|
|
4d66b2fa08 | ||
|
|
964381b7e9 | ||
|
|
f78f708678 | ||
|
|
6fe7d54029 | ||
|
|
8a69d6cb01 | ||
|
|
1cc5fc87fb | ||
|
|
97e647fdd0 | ||
|
|
e08fc168a1 | ||
|
|
9128f56258 | ||
|
|
2e59ae7030 | ||
|
|
99487d6986 | ||
|
|
3d9ec9f02d | ||
|
|
f2b1224b00 | ||
|
|
1383a2bcaf | ||
|
|
1acd6c2fc0 | ||
|
|
d153cfaf3c | ||
|
|
d09114e0c5 | ||
|
|
c3aa7f205d | ||
|
|
62f8c6bef6 | ||
|
|
a9ce06b57e | ||
|
|
cb6ca3829f | ||
|
|
1098847fe7 | ||
|
|
35a8193474 | ||
|
|
2915834633 | ||
|
|
a0e8f0bf18 | ||
|
|
580aee99c0 | ||
|
|
89ecd37681 | ||
|
|
139fb39ab0 | ||
|
|
67957d8c7a | ||
|
|
768df5fbf4 | ||
|
|
e9db81b6a1 | ||
|
|
cd825ae548 | ||
|
|
28c11a1819 | ||
|
|
ed087e5b0d | ||
|
|
2038d87306 | ||
|
|
252c717cc3 | ||
|
|
9b338b58a7 | ||
|
|
abe37ab72b | ||
|
|
b3a30a9e32 | ||
|
|
31e915c017 | ||
|
|
05bbe49fe1 | ||
|
|
c80fedbbae | ||
|
|
2c60cad840 | ||
|
|
847887b312 | ||
|
|
d9984214c9 | ||
|
|
33b4390bc2 | ||
|
|
5e8f679709 | ||
|
|
f288f4f7ea | ||
|
|
cb9121174a | ||
|
|
464dfbe1ec | ||
|
|
5695c0049b | ||
|
|
44b1545abd | ||
|
|
4d9d62d542 | ||
|
|
aa3c8ef106 | ||
|
|
259abb56df | ||
|
|
76e5a25cff | ||
|
|
bb8a659d9e | ||
|
|
6ab0483b34 | ||
|
|
d7dbf54456 | ||
|
|
496d7e2c9d | ||
|
|
094239d9eb | ||
|
|
c8a13a2352 | ||
|
|
875c6c9e95 | ||
|
|
12e3bd7469 | ||
|
|
2abe456e6b | ||
|
|
80dc124c6b | ||
|
|
6ac2b2eb02 | ||
|
|
8cb1698b20 | ||
|
|
b13d2bd668 | ||
|
|
c2dfc9dae8 | ||
|
|
beff1d58b7 | ||
|
|
01219141e4 | ||
|
|
ec7bb99421 | ||
|
|
b223e0a42b | ||
|
|
5e365b5a48 | ||
|
|
392903fad6 | ||
|
|
406e440bcb | ||
|
|
64c6f33406 | ||
|
|
f0f0b76920 | ||
|
|
5e3916dce6 | ||
|
|
815affc0ed | ||
|
|
96ad2a52f8 | ||
|
|
556fff451f | ||
|
|
d1181e8a16 | ||
|
|
11bdb1082a | ||
|
|
fdfeb2486a | ||
|
|
7a9a28cd90 | ||
|
|
3e2548a8ed | ||
|
|
ad59af8cf2 | ||
|
|
40e9a15129 | ||
|
|
7d5ed416da | ||
|
|
87a4161671 | ||
|
|
63427f8ff1 | ||
|
|
77bb494420 | ||
|
|
48addf39b6 | ||
|
|
efe21e504c | ||
|
|
7fb4112dd4 | ||
|
|
a14339c1d2 | ||
|
|
c8e980fc49 | ||
|
|
3f81bea2c1 | ||
|
|
d21d31d108 | ||
|
|
765b23685c | ||
|
|
c89aa60986 | ||
|
|
3150492079 | ||
|
|
b193ec6e9e | ||
|
|
257dd09431 | ||
|
|
e47d166c4f | ||
|
|
98e69d9e72 | ||
|
|
81d78d2ce7 | ||
|
|
fe8b21ecf5 | ||
|
|
dea2294b93 | ||
|
|
cc48ecede1 | ||
|
|
388280c282 | ||
|
|
c11b80183c | ||
|
|
ae3911e977 | ||
|
|
535aedce51 | ||
|
|
104c7babf8 | ||
|
|
c617b15f70 | ||
|
|
17f9c80d9c | ||
|
|
ffdd47b148 | ||
|
|
eca9342d11 |
4
.eslintignore
Normal file
4
.eslintignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/.yarn/**
|
||||||
|
/lib/**
|
||||||
|
/coverage/**
|
||||||
|
/node_modules/**
|
||||||
@@ -1,23 +1,36 @@
|
|||||||
{
|
{
|
||||||
"env": {
|
"env": {
|
||||||
"node": true,
|
"node": true,
|
||||||
"es2021": true,
|
"es6": true,
|
||||||
"jest/globals": true
|
"mocha": true,
|
||||||
|
"jest": true
|
||||||
},
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
"eslint:recommended",
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/eslint-recommended",
|
||||||
"plugin:@typescript-eslint/recommended",
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:import/errors",
|
||||||
|
"plugin:import/typescript", // this is needed to allow importing typescript files from JS
|
||||||
|
"plugin:import/warnings",
|
||||||
"plugin:jest/recommended",
|
"plugin:jest/recommended",
|
||||||
"plugin:prettier/recommended"
|
"plugin:prettier/recommended"
|
||||||
],
|
],
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": "latest",
|
"ecmaVersion": 2023,
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"@typescript-eslint",
|
"@typescript-eslint",
|
||||||
"jest",
|
"jest",
|
||||||
"prettier"
|
"prettier"
|
||||||
]
|
],
|
||||||
|
"rules": {
|
||||||
|
"import/no-unresolved": [
|
||||||
|
"error", {
|
||||||
|
"ignore": ["csv-parse/sync", "@octokit/openapi-types"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"jest/no-disabled-tests": 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,2 +1,3 @@
|
|||||||
/.yarn/releases/** binary
|
/.yarn/releases/** binary
|
||||||
/.yarn/plugins/** binary
|
/.yarn/plugins/** binary
|
||||||
|
/__tests__/fixtures/oci-archive/** binary
|
||||||
|
|||||||
453
.github/buildx-lab-releases.json
vendored
Normal file
453
.github/buildx-lab-releases.json
vendored
Normal file
@@ -0,0 +1,453 @@
|
|||||||
|
{
|
||||||
|
"latest": {
|
||||||
|
"id": 157588052,
|
||||||
|
"tag_name": "v0.14.1-desktop.1",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.14.1-desktop.1",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/checksums.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"v0.14.1-desktop.1": {
|
||||||
|
"id": 157588052,
|
||||||
|
"tag_name": "v0.14.1-desktop.1",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.14.1-desktop.1",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/buildx-v0.14.1-desktop.1.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.1-desktop.1/checksums.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"v0.14.0-desktop.1": {
|
||||||
|
"id": 155523887,
|
||||||
|
"tag_name": "v0.14.0-desktop.1",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.14.0-desktop.1",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/buildx-v0.14.0-desktop.1.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.14.0-desktop.1/checksums.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"v0.13.1-desktop-preview.2": {
|
||||||
|
"id": 151417247,
|
||||||
|
"tag_name": "v0.13.1-desktop-preview.2",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.13.1-desktop-preview.2",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/buildx-v0.13.1-desktop-preview.2.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.13.1-desktop-preview.2/checksums.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"v0.12.1-desktop.4": {
|
||||||
|
"id": 137689487,
|
||||||
|
"tag_name": "v0.12.1-desktop.4",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.12.1-desktop.4",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/buildx-v0.12.1-desktop.4.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.4/checksums.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"v0.12.1-desktop.3": {
|
||||||
|
"id": 137560191,
|
||||||
|
"tag_name": "v0.12.1-desktop.3",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.12.1-desktop.3",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/buildx-v0.12.1-desktop.3.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.1-desktop.3/checksums.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"v0.12.0-desktop.2": {
|
||||||
|
"id": 132264953,
|
||||||
|
"tag_name": "v0.12.0-desktop.2",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.12.0-desktop.2",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/buildx-v0.12.0-desktop.2.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.2/checksums.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"v0.12.0-desktop.1": {
|
||||||
|
"id": 130699107,
|
||||||
|
"tag_name": "v0.12.0-desktop.1",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.12.0-desktop.1",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/buildx-v0.12.0-desktop.1.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.12.0-desktop.1/checksums.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"v0.11.2-desktop.5": {
|
||||||
|
"id": 123496811,
|
||||||
|
"tag_name": "v0.11.2-desktop.5",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.11.2-desktop.5",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/buildx-v0.11.2-desktop.5.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.5/checksums.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"v0.11.2-desktop.4": {
|
||||||
|
"id": 119399782,
|
||||||
|
"tag_name": "v0.11.2-desktop.4",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.11.2-desktop.4",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/buildx-v0.11.2-desktop.4.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.4/checksums.txt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"v0.11.2-desktop.2": {
|
||||||
|
"id": 118213369,
|
||||||
|
"tag_name": "v0.11.2-desktop.2",
|
||||||
|
"html_url": "https://github.com/docker/buildx-desktop/releases/tag/v0.11.2-desktop.2",
|
||||||
|
"assets": [
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.darwin-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.darwin-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.darwin-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.darwin-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.darwin-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.darwin-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-amd64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-arm-v6",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-arm-v6.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-arm-v6.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-arm-v7",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-arm-v7.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-arm-v7.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-arm64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-ppc64le",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-ppc64le.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-ppc64le.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-riscv64",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-riscv64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-riscv64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-s390x",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-s390x.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.linux-s390x.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.windows-amd64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.windows-amd64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.windows-amd64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.windows-arm64.exe",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.windows-arm64.provenance.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/buildx-v0.11.2-desktop.2.windows-arm64.sbom.json",
|
||||||
|
"https://github.com/docker/buildx-desktop/releases/download/v0.11.2-desktop.2/checksums.txt"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
1678
.github/buildx-releases.json
vendored
Normal file
1678
.github/buildx-releases.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
@@ -11,8 +11,13 @@ updates:
|
|||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
|
versioning-strategy: "increase"
|
||||||
allow:
|
allow:
|
||||||
- dependency-type: "production"
|
- dependency-type: "production"
|
||||||
|
ignore:
|
||||||
|
- # we want to match the same version as the one used by @actions/artifact
|
||||||
|
# https://github.com/actions/toolkit/blob/ae38557bb0dba824cdda26ce787bd6b66cf07a83/packages/artifact/package.json#L46
|
||||||
|
dependency-name: "@azure/storage-blob"
|
||||||
labels:
|
labels:
|
||||||
- "dependencies"
|
- "dependencies"
|
||||||
- "bot"
|
- "bot"
|
||||||
|
|||||||
1058
.github/docker-releases.json
vendored
Normal file
1058
.github/docker-releases.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
26
.github/workflows/build.yml
vendored
Normal file
26
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: build
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/*-releases.json'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Build
|
||||||
|
uses: docker/bake-action@v4
|
||||||
|
with:
|
||||||
|
targets: build
|
||||||
58
.github/workflows/buildx-lab-releases-json.yml
vendored
Normal file
58
.github/workflows/buildx-lab-releases-json.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
name: buildx-lab-releases-json
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 */12 * * *'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/*-releases.json'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generate:
|
||||||
|
uses: crazy-max/.github/.github/workflows/releases-json.yml@fa6141aedf23596fb8bdcceab9cce8dadaa31bd9
|
||||||
|
with:
|
||||||
|
repository: docker/buildx-desktop
|
||||||
|
artifact_name: buildx-lab-releases-json
|
||||||
|
filename: buildx-lab-releases.json
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
open-pr:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
needs:
|
||||||
|
- generate
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Download
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: buildx-lab-releases-json
|
||||||
|
path: .github
|
||||||
|
-
|
||||||
|
name: Commit changes
|
||||||
|
run: |
|
||||||
|
git add -A .
|
||||||
|
-
|
||||||
|
name: Create PR
|
||||||
|
uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5
|
||||||
|
with:
|
||||||
|
base: main
|
||||||
|
branch: bot/buildx-lab-releases-json
|
||||||
|
commit-message: "github: update .github/buildx-lab-releases.json"
|
||||||
|
signoff: true
|
||||||
|
delete-branch: true
|
||||||
|
title: "Update `.github/buildx-lab-releases.json`"
|
||||||
|
body: |
|
||||||
|
Update `.github/buildx-lab-releases.json` to keep in sync with [https://github.com/docker/buildx-desktop](https://github.com/docker/buildx-desktop).
|
||||||
|
draft: false
|
||||||
69
.github/workflows/buildx-releases-json.yml
vendored
69
.github/workflows/buildx-releases-json.yml
vendored
@@ -13,47 +13,46 @@ on:
|
|||||||
- 'main'
|
- 'main'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '.github/buildx-releases.json'
|
- '.github/*-releases.json'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
generate:
|
generate:
|
||||||
uses: crazy-max/.github/.github/workflows/releases-json.yml@2a596c917a8ad3e6203ae99b777148525a2e00d5
|
uses: crazy-max/.github/.github/workflows/releases-json.yml@fa6141aedf23596fb8bdcceab9cce8dadaa31bd9
|
||||||
with:
|
with:
|
||||||
repository: docker/buildx
|
repository: docker/buildx
|
||||||
artifact_name: buildx-releases-json
|
artifact_name: buildx-releases-json
|
||||||
filename: buildx-releases.json
|
filename: buildx-releases.json
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
# FIXME: Uncomment when repo public
|
open-pr:
|
||||||
# open-pr:
|
runs-on: ubuntu-22.04
|
||||||
# runs-on: ubuntu-22.04
|
if: github.event_name != 'pull_request'
|
||||||
# if: github.event_name != 'pull_request'
|
needs:
|
||||||
# needs:
|
- generate
|
||||||
# - generate
|
steps:
|
||||||
# steps:
|
-
|
||||||
# -
|
name: Checkout
|
||||||
# name: Checkout
|
uses: actions/checkout@v4
|
||||||
# uses: actions/checkout@v3
|
-
|
||||||
# -
|
name: Download
|
||||||
# name: Download
|
uses: actions/download-artifact@v4
|
||||||
# uses: actions/download-artifact@v3
|
with:
|
||||||
# with:
|
name: buildx-releases-json
|
||||||
# name: buildx-releases-json
|
path: .github
|
||||||
# path: .github
|
-
|
||||||
# -
|
name: Commit changes
|
||||||
# name: Commit changes
|
run: |
|
||||||
# run: |
|
git add -A .
|
||||||
# git add -A .
|
-
|
||||||
# -
|
name: Create PR
|
||||||
# name: Create PR
|
uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5
|
||||||
# uses: peter-evans/create-pull-request@2b011faafdcbc9ceb11414d64d0573f37c774b04
|
with:
|
||||||
# with:
|
base: main
|
||||||
# base: master
|
branch: bot/buildx-releases-json
|
||||||
# branch: bot/buildx-releases-json
|
commit-message: "github: update .github/buildx-releases.json"
|
||||||
# commit-message: "github: update .github/buildx-releases.json"
|
signoff: true
|
||||||
# signoff: true
|
delete-branch: true
|
||||||
# delete-branch: true
|
title: "Update `.github/buildx-releases.json`"
|
||||||
# title: "Update `.github/buildx-releases.json`"
|
body: |
|
||||||
# body: |
|
Update `.github/buildx-releases.json` to keep in sync with [https://github.com/docker/buildx](https://github.com/docker/buildx).
|
||||||
# Update `.github/buildx-releases.json` to keep in sync with [https://github.com/docker/buildx](https://github.com/docker/buildx).
|
draft: false
|
||||||
# draft: false
|
|
||||||
|
|||||||
46
.github/workflows/codeql.yml
vendored
Normal file
46
.github/workflows/codeql.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: codeql
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_VERSION: 20
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Enable corepack
|
||||||
|
run: |
|
||||||
|
corepack enable
|
||||||
|
yarn --version
|
||||||
|
-
|
||||||
|
name: Set up Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
|
-
|
||||||
|
name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v3
|
||||||
|
with:
|
||||||
|
languages: javascript-typescript
|
||||||
|
-
|
||||||
|
name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v3
|
||||||
|
-
|
||||||
|
name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v3
|
||||||
|
with:
|
||||||
|
category: "/language:javascript-typescript"
|
||||||
58
.github/workflows/docker-releases-json.yml
vendored
Normal file
58
.github/workflows/docker-releases-json.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
name: docker-releases-json
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 */12 * * *'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/*-releases.json'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generate:
|
||||||
|
uses: crazy-max/.github/.github/workflows/releases-json.yml@fa6141aedf23596fb8bdcceab9cce8dadaa31bd9
|
||||||
|
with:
|
||||||
|
repository: moby/moby
|
||||||
|
artifact_name: docker-releases-json
|
||||||
|
filename: docker-releases.json
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
open-pr:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
needs:
|
||||||
|
- generate
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Download
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: docker-releases-json
|
||||||
|
path: .github
|
||||||
|
-
|
||||||
|
name: Commit changes
|
||||||
|
run: |
|
||||||
|
git add -A .
|
||||||
|
-
|
||||||
|
name: Create PR
|
||||||
|
uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5
|
||||||
|
with:
|
||||||
|
base: main
|
||||||
|
branch: bot/docker-releases-json
|
||||||
|
commit-message: "github: update .github/docker-releases.json"
|
||||||
|
signoff: true
|
||||||
|
delete-branch: true
|
||||||
|
title: "Update `.github/docker-releases.json`"
|
||||||
|
body: |
|
||||||
|
Update `.github/docker-releases.json` to keep in sync with [https://github.com/moby/moby](https://github.com/moby/moby).
|
||||||
|
draft: false
|
||||||
10
.github/workflows/publish.yml
vendored
10
.github/workflows/publish.yml
vendored
@@ -1,5 +1,9 @@
|
|||||||
name: publish
|
name: publish
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
@@ -11,13 +15,13 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
-
|
-
|
||||||
name: Set up Docker Buildx
|
name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v3
|
||||||
-
|
-
|
||||||
name: Publish
|
name: Publish
|
||||||
uses: docker/bake-action@v2
|
uses: docker/bake-action@v4
|
||||||
with:
|
with:
|
||||||
targets: publish
|
targets: publish
|
||||||
env:
|
env:
|
||||||
|
|||||||
174
.github/workflows/test.yml
vendored
174
.github/workflows/test.yml
vendored
@@ -1,48 +1,168 @@
|
|||||||
name: test
|
name: test
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'main'
|
- 'main'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '.github/buildx-releases.json'
|
- '.github/*-releases.json'
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_VERSION: "20"
|
||||||
|
BUILDX_VERSION: "v0.15.0"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
validate:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
target:
|
|
||||||
- lint
|
|
||||||
- vendor-validate
|
|
||||||
- license-validate
|
|
||||||
steps:
|
|
||||||
-
|
|
||||||
name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
-
|
|
||||||
name: Validate
|
|
||||||
uses: docker/bake-action@v2
|
|
||||||
with:
|
|
||||||
targets: ${{ matrix.target }}
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: Checkout
|
name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
-
|
-
|
||||||
name: Test
|
name: Test
|
||||||
uses: docker/bake-action@v2
|
uses: docker/bake-action@v4
|
||||||
with:
|
with:
|
||||||
targets: test-coverage
|
targets: test-coverage
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
# -
|
-
|
||||||
# name: Upload coverage
|
name: Check coverage
|
||||||
# uses: codecov/codecov-action@v3
|
run: |
|
||||||
# with:
|
if [ -f ./coverage/clover.xml ] && [ ! -f ./coverage/allSkipped.txt ]; then
|
||||||
# file: ./coverage/clover.xml
|
echo "RUN_CODECOV=true" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "RUN_CODECOV=false" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
shell: bash
|
||||||
|
-
|
||||||
|
name: Upload coverage
|
||||||
|
uses: codecov/codecov-action@v4
|
||||||
|
if: env.RUN_CODECOV == 'true'
|
||||||
|
with:
|
||||||
|
file: ./coverage/clover.xml
|
||||||
|
flags: unit
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|
||||||
|
prepare-itg:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
matrix: ${{ steps.tests.outputs.matrix }}
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Enable corepack
|
||||||
|
run: |
|
||||||
|
corepack enable
|
||||||
|
yarn --version
|
||||||
|
-
|
||||||
|
name: Setup Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
|
cache: 'yarn'
|
||||||
|
-
|
||||||
|
name: Install
|
||||||
|
run: yarn install
|
||||||
|
-
|
||||||
|
name: Create matrix
|
||||||
|
id: tests
|
||||||
|
run: |
|
||||||
|
declare -a tests
|
||||||
|
for test in $(yarn run test:itg-list); do
|
||||||
|
tests+=("${test#$(pwd)/__tests__/}")
|
||||||
|
done
|
||||||
|
echo "matrix=$(echo ${tests[@]} | jq -cR 'split(" ")')" >>${GITHUB_OUTPUT}
|
||||||
|
-
|
||||||
|
name: Show matrix
|
||||||
|
run: |
|
||||||
|
echo ${{ steps.tests.outputs.matrix }}
|
||||||
|
|
||||||
|
test-itg:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
needs:
|
||||||
|
- prepare-itg
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
test: ${{ fromJson(needs.prepare-itg.outputs.matrix) }}
|
||||||
|
os:
|
||||||
|
- ubuntu-latest
|
||||||
|
#- macos-14 # no virt: https://github.com/docker/actions-toolkit/issues/317
|
||||||
|
- macos-13
|
||||||
|
- macos-12
|
||||||
|
- windows-latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Expose GitHub Runtime
|
||||||
|
uses: crazy-max/ghaction-github-runtime@v3
|
||||||
|
-
|
||||||
|
# FIXME: Needs to setup node twice on Windows due to a bug with runner
|
||||||
|
name: Setup Node
|
||||||
|
if: startsWith(matrix.os, 'windows')
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
|
-
|
||||||
|
name: Enable corepack
|
||||||
|
run: |
|
||||||
|
corepack enable
|
||||||
|
yarn --version
|
||||||
|
-
|
||||||
|
name: Setup Node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
|
cache: 'yarn'
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
if: startsWith(matrix.os, 'ubuntu')
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.BUILDX_VERSION }}
|
||||||
|
driver: docker
|
||||||
|
-
|
||||||
|
name: Set up container builder
|
||||||
|
if: startsWith(matrix.os, 'ubuntu')
|
||||||
|
id: builder
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
version: ${{ env.BUILDX_VERSION }}
|
||||||
|
use: false
|
||||||
|
-
|
||||||
|
name: Install
|
||||||
|
run: yarn install
|
||||||
|
-
|
||||||
|
name: Test
|
||||||
|
run: |
|
||||||
|
yarn test:itg-coverage --runTestsByPath __tests__/${{ matrix.test }} --coverageDirectory=./coverage
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
CTN_BUILDER_NAME: ${{ steps.builder.outputs.name }}
|
||||||
|
-
|
||||||
|
name: Check coverage
|
||||||
|
run: |
|
||||||
|
if [ -f ./coverage/clover.xml ] && [ ! -f ./coverage/allSkipped.txt ]; then
|
||||||
|
echo "RUN_CODECOV=true" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "RUN_CODECOV=false" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
shell: bash
|
||||||
|
-
|
||||||
|
name: Upload coverage
|
||||||
|
uses: codecov/codecov-action@v4
|
||||||
|
if: env.RUN_CODECOV == 'true'
|
||||||
|
with:
|
||||||
|
file: ./coverage/clover.xml
|
||||||
|
flags: itg
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
|||||||
47
.github/workflows/validate.yml
vendored
Normal file
47
.github/workflows/validate.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
name: validate
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/*-releases.json'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
prepare:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
outputs:
|
||||||
|
targets: ${{ steps.targets.outputs.matrix }}
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Matrix
|
||||||
|
id: targets
|
||||||
|
run: |
|
||||||
|
echo "matrix=$(docker buildx bake validate --print | jq -cr '.group.validate.targets')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
validate:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- prepare
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
target: ${{ fromJson(needs.prepare.outputs.targets) }}
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
-
|
||||||
|
name: Validate
|
||||||
|
uses: docker/bake-action@v4
|
||||||
|
with:
|
||||||
|
targets: ${{ matrix.target }}
|
||||||
6
.github/workflows/virtual-env.yml
vendored
6
.github/workflows/virtual-env.yml
vendored
@@ -21,9 +21,9 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
os:
|
os:
|
||||||
- ubuntu-latest
|
- ubuntu-latest
|
||||||
|
- ubuntu-24.04
|
||||||
- ubuntu-22.04
|
- ubuntu-22.04
|
||||||
- ubuntu-20.04
|
- ubuntu-20.04
|
||||||
- ubuntu-18.04
|
|
||||||
steps:
|
steps:
|
||||||
-
|
-
|
||||||
name: File system
|
name: File system
|
||||||
@@ -43,7 +43,7 @@ jobs:
|
|||||||
-
|
-
|
||||||
name: Docker daemon conf
|
name: Docker daemon conf
|
||||||
run: |
|
run: |
|
||||||
cat /etc/docker/daemon.json
|
cat /etc/docker/daemon.json || true
|
||||||
-
|
-
|
||||||
name: Docker info
|
name: Docker info
|
||||||
run: docker info
|
run: docker info
|
||||||
@@ -67,4 +67,4 @@ jobs:
|
|||||||
-
|
-
|
||||||
name: Dump context
|
name: Dump context
|
||||||
if: always()
|
if: always()
|
||||||
uses: crazy-max/ghaction-dump-context@v1
|
uses: crazy-max/ghaction-dump-context@v2
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
# Dependency directories
|
# Dependency directories
|
||||||
node_modules/
|
/node_modules/**
|
||||||
jspm_packages/
|
/jspm_packages/**
|
||||||
|
|
||||||
# yarn v2
|
# yarn v2
|
||||||
.yarn/
|
/.yarn/**
|
||||||
|
|
||||||
|
# build
|
||||||
|
/lib/**
|
||||||
|
|||||||
222
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
222
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
File diff suppressed because one or more lines are too long
823
.yarn/releases/yarn-3.3.1.cjs
vendored
823
.yarn/releases/yarn-3.3.1.cjs
vendored
File diff suppressed because one or more lines are too long
12
.yarnrc.yml
12
.yarnrc.yml
@@ -1,7 +1,15 @@
|
|||||||
|
logFilters:
|
||||||
|
- code: YN0013
|
||||||
|
level: discard
|
||||||
|
- code: YN0019
|
||||||
|
level: discard
|
||||||
|
- code: YN0076
|
||||||
|
level: discard
|
||||||
|
|
||||||
nodeLinker: node-modules
|
nodeLinker: node-modules
|
||||||
|
|
||||||
|
npmAuthToken: "${NODE_AUTH_TOKEN:-fallback}"
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||||
spec: "@yarnpkg/plugin-interactive-tools"
|
spec: "@yarnpkg/plugin-interactive-tools"
|
||||||
|
|
||||||
yarnPath: .yarn/releases/yarn-3.3.1.cjs
|
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
[](https://www.npmjs.com/package/@docker/actions-toolkit)
|
||||||
|
[](https://www.npmjs.com/package/@docker/actions-toolkit)
|
||||||
|
[](https://github.com/docker/actions-toolkit/actions?workflow=build)
|
||||||
|
[](https://github.com/docker/actions-toolkit/actions?workflow=test)
|
||||||
|
[](https://github.com/docker/actions-toolkit/actions?workflow=validate)
|
||||||
|
[](https://codecov.io/gh/docker/actions-toolkit)
|
||||||
|
|
||||||
# Actions Toolkit
|
# Actions Toolkit
|
||||||
|
|
||||||
Toolkit for Docker (GitHub) Actions.
|
Toolkit for Docker (GitHub) Actions.
|
||||||
@@ -34,7 +41,7 @@ $ npm install @docker/actions-toolkit
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const { Toolkit } = require('@docker/actions-toolkit')
|
const { Toolkit } = require('@docker/actions-toolkit/lib/toolkit')
|
||||||
const toolkit = new Toolkit()
|
const toolkit = new Toolkit()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ export const context = {
|
|||||||
repo: 'actions-toolkit'
|
repo: 'actions-toolkit'
|
||||||
},
|
},
|
||||||
ref: 'refs/heads/master',
|
ref: 'refs/heads/master',
|
||||||
runId: 123,
|
runId: 2188748038,
|
||||||
|
runNumber: 15,
|
||||||
payload: {
|
payload: {
|
||||||
after: '860c1904a1ce19322e91ac35af1ab07466440c37',
|
after: '860c1904a1ce19322e91ac35af1ab07466440c37',
|
||||||
base_ref: null,
|
base_ref: null,
|
||||||
|
|||||||
@@ -1,201 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2023 actions-toolkit authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {beforeEach, describe, expect, it, jest, test} from '@jest/globals';
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
|
|
||||||
import {Builder, BuilderInfo} from '../src/builder';
|
|
||||||
import {Context} from '../src/context';
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise<BuilderInfo> => {
|
|
||||||
return {
|
|
||||||
name: 'builder2',
|
|
||||||
driver: 'docker-container',
|
|
||||||
lastActivity: new Date('2023-01-16 09:45:23 +0000 UTC'),
|
|
||||||
nodes: [
|
|
||||||
{
|
|
||||||
buildkitVersion: 'v0.11.0',
|
|
||||||
buildkitdFlags: '--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host',
|
|
||||||
driverOpts: ['BUILDKIT_STEP_LOG_MAX_SIZE=10485760', 'BUILDKIT_STEP_LOG_MAX_SPEED=10485760', 'JAEGER_TRACE=localhost:6831', 'image=moby/buildkit:latest', 'network=host'],
|
|
||||||
endpoint: 'unix:///var/run/docker.sock',
|
|
||||||
name: 'builder20',
|
|
||||||
platforms: 'linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6',
|
|
||||||
status: 'running'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('inspect', () => {
|
|
||||||
it('valid', async () => {
|
|
||||||
const builder = new Builder({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const builderInfo = await builder.inspect('');
|
|
||||||
expect(builderInfo).not.toBeUndefined();
|
|
||||||
expect(builderInfo.name).not.toEqual('');
|
|
||||||
expect(builderInfo.driver).not.toEqual('');
|
|
||||||
expect(builderInfo.nodes).not.toEqual({});
|
|
||||||
}, 100000);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('parseInspect', () => {
|
|
||||||
// prettier-ignore
|
|
||||||
test.each([
|
|
||||||
[
|
|
||||||
'inspect1.txt',
|
|
||||||
{
|
|
||||||
"name": "builder-5cb467f7-0940-47e1-b94b-d51f54054d62",
|
|
||||||
"driver": "docker-container",
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"name": "builder-5cb467f7-0940-47e1-b94b-d51f54054d620",
|
|
||||||
"endpoint": "unix:///var/run/docker.sock",
|
|
||||||
"status": "running",
|
|
||||||
"buildkitdFlags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
|
||||||
"buildkitVersion": "v0.10.4",
|
|
||||||
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/arm64,linux/riscv64,linux/386,linux/arm/v7,linux/arm/v6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'inspect2.txt',
|
|
||||||
{
|
|
||||||
"name": "builder-5f449644-ff29-48af-8344-abb0292d0673",
|
|
||||||
"driver": "docker-container",
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"name": "builder-5f449644-ff29-48af-8344-abb0292d06730",
|
|
||||||
"endpoint": "unix:///var/run/docker.sock",
|
|
||||||
"driverOpts": [
|
|
||||||
"image=moby/buildkit:latest"
|
|
||||||
],
|
|
||||||
"status": "running",
|
|
||||||
"buildkitdFlags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
|
||||||
"buildkitVersion": "v0.10.4",
|
|
||||||
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'inspect3.txt',
|
|
||||||
{
|
|
||||||
"name": "builder-9929e463-7954-4dc3-89cd-514cca29ff80",
|
|
||||||
"driver": "docker-container",
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"name": "builder-9929e463-7954-4dc3-89cd-514cca29ff800",
|
|
||||||
"endpoint": "unix:///var/run/docker.sock",
|
|
||||||
"driverOpts": [
|
|
||||||
"image=moby/buildkit:master",
|
|
||||||
"network=host"
|
|
||||||
],
|
|
||||||
"status": "running",
|
|
||||||
"buildkitdFlags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
|
||||||
"buildkitVersion": "3fab389",
|
|
||||||
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'inspect4.txt',
|
|
||||||
{
|
|
||||||
"name": "default",
|
|
||||||
"driver": "docker",
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"name": "default",
|
|
||||||
"endpoint": "default",
|
|
||||||
"status": "running",
|
|
||||||
"buildkitVersion": "20.10.17",
|
|
||||||
"platforms": "linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'inspect5.txt',
|
|
||||||
{
|
|
||||||
"name": "remote-builder",
|
|
||||||
"driver": "remote",
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"name": "aws_graviton2",
|
|
||||||
"endpoint": "tcp://1.23.45.67:1234",
|
|
||||||
"driverOpts": [
|
|
||||||
"cert=/home/user/.certs/aws_graviton2/cert.pem",
|
|
||||||
"key=/home/user/.certs/aws_graviton2/key.pem",
|
|
||||||
"cacert=/home/user/.certs/aws_graviton2/ca.pem"
|
|
||||||
],
|
|
||||||
"status": "running",
|
|
||||||
"platforms": "darwin/arm64,linux/arm64,linux/arm/v5,linux/arm/v6,linux/arm/v7,windows/arm64"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'inspect6.txt',
|
|
||||||
{
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"name": "builder-17cfff01-48d9-4c3d-9332-9992e308a5100",
|
|
||||||
"endpoint": "unix:///var/run/docker.sock",
|
|
||||||
"status": "running",
|
|
||||||
"buildkitdFlags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
|
||||||
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/386"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "builder-17cfff01-48d9-4c3d-9332-9992e308a510",
|
|
||||||
"driver": "docker-container"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'inspect7.txt',
|
|
||||||
{
|
|
||||||
"name": "builder2",
|
|
||||||
"driver": "docker-container",
|
|
||||||
"lastActivity": new Date("2023-01-16T09:45:23.000Z"),
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"buildkitVersion": "v0.11.0",
|
|
||||||
"buildkitdFlags": "--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
|
||||||
"driverOpts": [
|
|
||||||
"BUILDKIT_STEP_LOG_MAX_SIZE=10485760",
|
|
||||||
"BUILDKIT_STEP_LOG_MAX_SPEED=10485760",
|
|
||||||
"JAEGER_TRACE=localhost:6831",
|
|
||||||
"image=moby/buildkit:latest",
|
|
||||||
"network=host"
|
|
||||||
],
|
|
||||||
"endpoint": "unix:///var/run/docker.sock",
|
|
||||||
"name": "builder20",
|
|
||||||
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6",
|
|
||||||
"status": "running"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
])('given %p', async (inspectFile, expected) => {
|
|
||||||
expect(await Builder.parseInspect(fs.readFileSync(path.join(__dirname, 'fixtures', inspectFile)).toString())).toEqual(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2023 actions-toolkit authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {describe, expect, it, jest, test, beforeEach, afterEach} from '@jest/globals';
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
import rimraf from 'rimraf';
|
|
||||||
import * as semver from 'semver';
|
|
||||||
|
|
||||||
import {BuildKit} from '../src/buildkit';
|
|
||||||
import {Builder, BuilderInfo} from '../src/builder';
|
|
||||||
import {Context} from '../src/context';
|
|
||||||
|
|
||||||
const tmpDir = path.join('/tmp/.docker-actions-toolkit-jest').split(path.sep).join(path.posix.sep);
|
|
||||||
const tmpName = path.join(tmpDir, '.tmpname-jest').split(path.sep).join(path.posix.sep);
|
|
||||||
|
|
||||||
jest.spyOn(Context.prototype as any, 'tmpDir').mockImplementation((): string => {
|
|
||||||
if (!fs.existsSync(tmpDir)) {
|
|
||||||
fs.mkdirSync(tmpDir, {recursive: true});
|
|
||||||
}
|
|
||||||
return tmpDir;
|
|
||||||
});
|
|
||||||
jest.spyOn(Context.prototype as any, 'tmpName').mockImplementation((): string => {
|
|
||||||
return tmpName;
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
rimraf.sync(tmpDir);
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise<BuilderInfo> => {
|
|
||||||
return {
|
|
||||||
name: 'builder2',
|
|
||||||
driver: 'docker-container',
|
|
||||||
lastActivity: new Date('2023-01-16 09:45:23 +0000 UTC'),
|
|
||||||
nodes: [
|
|
||||||
{
|
|
||||||
buildkitVersion: 'v0.11.0',
|
|
||||||
buildkitdFlags: '--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host',
|
|
||||||
driverOpts: ['BUILDKIT_STEP_LOG_MAX_SIZE=10485760', 'BUILDKIT_STEP_LOG_MAX_SPEED=10485760', 'JAEGER_TRACE=localhost:6831', 'image=moby/buildkit:latest', 'network=host'],
|
|
||||||
endpoint: 'unix:///var/run/docker.sock',
|
|
||||||
name: 'builder20',
|
|
||||||
platforms: 'linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6',
|
|
||||||
status: 'running'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getVersion', () => {
|
|
||||||
it('valid', async () => {
|
|
||||||
const buildkit = new BuildKit({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const version = await buildkit.getVersion('builder2');
|
|
||||||
expect(semver.valid(version)).not.toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('satisfies', () => {
|
|
||||||
test.each([
|
|
||||||
['builder2', '>=0.10.0', true],
|
|
||||||
['builder2', '>0.11.0', false]
|
|
||||||
])('given %p', async (builderName, range, expected) => {
|
|
||||||
const buildkit = new BuildKit({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
expect(await buildkit.versionSatisfies(builderName, range)).toBe(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('generateConfig', () => {
|
|
||||||
test.each([
|
|
||||||
['debug = true', false, 'debug = true', null],
|
|
||||||
[`notfound.toml`, true, '', new Error('config file notfound.toml not found')],
|
|
||||||
[
|
|
||||||
`${path.join(__dirname, 'fixtures', 'buildkitd.toml').split(path.sep).join(path.posix.sep)}`,
|
|
||||||
true,
|
|
||||||
`debug = true
|
|
||||||
[registry."docker.io"]
|
|
||||||
mirrors = ["mirror.gcr.io"]
|
|
||||||
`,
|
|
||||||
null
|
|
||||||
]
|
|
||||||
])('given %p config', async (val, file, exValue, error: Error) => {
|
|
||||||
try {
|
|
||||||
const buildkit = new BuildKit({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
let config: string;
|
|
||||||
if (file) {
|
|
||||||
config = buildkit.generateConfigFile(val);
|
|
||||||
} else {
|
|
||||||
config = buildkit.generateConfigInline(val);
|
|
||||||
}
|
|
||||||
expect(config).toEqual(tmpName);
|
|
||||||
const configValue = fs.readFileSync(tmpName, 'utf-8');
|
|
||||||
expect(configValue).toEqual(exValue);
|
|
||||||
} catch (e) {
|
|
||||||
// eslint-disable-next-line jest/no-conditional-expect
|
|
||||||
expect(e.message).toEqual(error?.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
65
__tests__/buildkit/buildkit.test.ts
Normal file
65
__tests__/buildkit/buildkit.test.ts
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {beforeEach, describe, expect, it, jest, test} from '@jest/globals';
|
||||||
|
|
||||||
|
import {BuildKit} from '../../src/buildkit/buildkit';
|
||||||
|
import {Builder} from '../../src/buildx/builder';
|
||||||
|
|
||||||
|
import {BuilderInfo} from '../../src/types/buildx/builder';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise<BuilderInfo> => {
|
||||||
|
return {
|
||||||
|
name: 'builder2',
|
||||||
|
driver: 'docker-container',
|
||||||
|
lastActivity: new Date('2023-01-16 09:45:23 +0000 UTC'),
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
buildkit: 'v0.11.0',
|
||||||
|
'buildkitd-flags': '--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host',
|
||||||
|
'driver-opts': ['BUILDKIT_STEP_LOG_MAX_SIZE=10485760', 'BUILDKIT_STEP_LOG_MAX_SPEED=10485760', 'JAEGER_TRACE=localhost:6831', 'image=moby/buildkit:latest', 'network=host'],
|
||||||
|
endpoint: 'unix:///var/run/docker.sock',
|
||||||
|
name: 'builder20',
|
||||||
|
platforms: 'linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6',
|
||||||
|
status: 'running'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getVersion', () => {
|
||||||
|
it('valid', async () => {
|
||||||
|
const builder = new Builder();
|
||||||
|
const builderInfo = await builder.inspect('builder2');
|
||||||
|
const buildkit = new BuildKit();
|
||||||
|
const version = await buildkit.getVersion(builderInfo.nodes[0]);
|
||||||
|
expect(version).toBe('v0.11.0');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('satisfies', () => {
|
||||||
|
test.each([
|
||||||
|
['builder2', '>=0.10.0', true],
|
||||||
|
['builder2', '>0.11.0', false]
|
||||||
|
])('given %p', async (builderName, range, expected) => {
|
||||||
|
const buildkit = new BuildKit();
|
||||||
|
expect(await buildkit.versionSatisfies(builderName, range)).toBe(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
79
__tests__/buildkit/config.test.ts
Normal file
79
__tests__/buildkit/config.test.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {describe, expect, jest, test, beforeEach, afterEach} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as rimraf from 'rimraf';
|
||||||
|
|
||||||
|
import {BuildKit} from '../../src/buildkit/buildkit';
|
||||||
|
import {Context} from '../../src/context';
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildkit-config-jest');
|
||||||
|
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
||||||
|
|
||||||
|
jest.spyOn(Context, 'tmpDir').mockImplementation((): string => {
|
||||||
|
if (!fs.existsSync(tmpDir)) {
|
||||||
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
|
}
|
||||||
|
return tmpDir;
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(Context, 'tmpName').mockImplementation((): string => {
|
||||||
|
return tmpName;
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
rimraf.sync(tmpDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolve', () => {
|
||||||
|
test.each([
|
||||||
|
['debug = true', false, 'debug = true', null],
|
||||||
|
[`notfound.toml`, true, '', new Error('config file notfound.toml not found')],
|
||||||
|
[
|
||||||
|
`${path.join(fixturesDir, 'buildkitd.toml')}`,
|
||||||
|
true,
|
||||||
|
`debug = true
|
||||||
|
[registry."docker.io"]
|
||||||
|
mirrors = ["mirror.gcr.io"]
|
||||||
|
`,
|
||||||
|
null
|
||||||
|
]
|
||||||
|
])('given %p config', async (val: string, file: boolean, exValue: string, error: Error | null) => {
|
||||||
|
try {
|
||||||
|
const buildkit = new BuildKit();
|
||||||
|
let config: string;
|
||||||
|
if (file) {
|
||||||
|
config = buildkit.config.resolveFromFile(val);
|
||||||
|
} else {
|
||||||
|
config = buildkit.config.resolveFromString(val);
|
||||||
|
}
|
||||||
|
expect(config).toEqual(tmpName);
|
||||||
|
const configValue = fs.readFileSync(tmpName, 'utf-8');
|
||||||
|
expect(configValue).toEqual(exValue);
|
||||||
|
} catch (e) {
|
||||||
|
// eslint-disable-next-line jest/no-conditional-expect
|
||||||
|
expect(e.message).toEqual(error?.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,399 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2023 actions-toolkit authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {describe, expect, it, jest, test, beforeEach, afterEach} from '@jest/globals';
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
import rimraf from 'rimraf';
|
|
||||||
import * as semver from 'semver';
|
|
||||||
import * as exec from '@actions/exec';
|
|
||||||
|
|
||||||
import {Buildx} from '../src/buildx';
|
|
||||||
import {Context} from '../src/context';
|
|
||||||
|
|
||||||
const tmpDir = path.join('/tmp/.docker-actions-toolkit-jest').split(path.sep).join(path.posix.sep);
|
|
||||||
const tmpName = path.join(tmpDir, '.tmpname-jest').split(path.sep).join(path.posix.sep);
|
|
||||||
const metadata = `{
|
|
||||||
"containerimage.config.digest": "sha256:059b68a595b22564a1cbc167af369349fdc2ecc1f7bc092c2235cbf601a795fd",
|
|
||||||
"containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c"
|
|
||||||
}`;
|
|
||||||
|
|
||||||
jest.spyOn(Context.prototype as any, 'tmpDir').mockImplementation((): string => {
|
|
||||||
if (!fs.existsSync(tmpDir)) {
|
|
||||||
fs.mkdirSync(tmpDir, {recursive: true});
|
|
||||||
}
|
|
||||||
return tmpDir;
|
|
||||||
});
|
|
||||||
jest.spyOn(Context.prototype as any, 'tmpName').mockImplementation((): string => {
|
|
||||||
return tmpName;
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
rimraf.sync(tmpDir);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isAvailable', () => {
|
|
||||||
it('docker cli', async () => {
|
|
||||||
const execSpy = jest.spyOn(exec, 'getExecOutput');
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context(),
|
|
||||||
standalone: false
|
|
||||||
});
|
|
||||||
buildx.isAvailable().catch(() => {
|
|
||||||
// noop
|
|
||||||
});
|
|
||||||
// eslint-disable-next-line jest/no-standalone-expect
|
|
||||||
expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], {
|
|
||||||
silent: true,
|
|
||||||
ignoreReturnCode: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('standalone', async () => {
|
|
||||||
const execSpy = jest.spyOn(exec, 'getExecOutput');
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context(),
|
|
||||||
standalone: true
|
|
||||||
});
|
|
||||||
buildx.isAvailable().catch(() => {
|
|
||||||
// noop
|
|
||||||
});
|
|
||||||
// eslint-disable-next-line jest/no-standalone-expect
|
|
||||||
expect(execSpy).toHaveBeenCalledWith(`buildx`, [], {
|
|
||||||
silent: true,
|
|
||||||
ignoreReturnCode: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('printInspect', () => {
|
|
||||||
it('prints builder2 instance', () => {
|
|
||||||
const execSpy = jest.spyOn(exec, 'exec');
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context(),
|
|
||||||
standalone: true
|
|
||||||
});
|
|
||||||
buildx.printInspect('builder2').catch(() => {
|
|
||||||
// noop
|
|
||||||
});
|
|
||||||
expect(execSpy).toHaveBeenCalledWith(`buildx`, ['inspect', 'builder2'], {
|
|
||||||
failOnStdErr: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('printVersion', () => {
|
|
||||||
it('docker cli', () => {
|
|
||||||
const execSpy = jest.spyOn(exec, 'exec');
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context(),
|
|
||||||
standalone: false
|
|
||||||
});
|
|
||||||
buildx.printVersion();
|
|
||||||
expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx', 'version'], {
|
|
||||||
failOnStdErr: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('standalone', () => {
|
|
||||||
const execSpy = jest.spyOn(exec, 'exec');
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context(),
|
|
||||||
standalone: true
|
|
||||||
});
|
|
||||||
buildx.printVersion();
|
|
||||||
expect(execSpy).toHaveBeenCalledWith(`buildx`, ['version'], {
|
|
||||||
failOnStdErr: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('version', () => {
|
|
||||||
it('valid', async () => {
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
expect(semver.valid(await buildx.version)).not.toBeUndefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('parseVersion', () => {
|
|
||||||
test.each([
|
|
||||||
['github.com/docker/buildx 0.4.1+azure bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'],
|
|
||||||
['github.com/docker/buildx v0.4.1 bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'],
|
|
||||||
['github.com/docker/buildx v0.4.2 fb7b670b764764dc4716df3eba07ffdae4cc47b2', '0.4.2'],
|
|
||||||
['github.com/docker/buildx f117971 f11797113e5a9b86bd976329c5dbb8a8bfdfadfa', 'f117971']
|
|
||||||
])('given %p', async (stdout, expected) => {
|
|
||||||
expect(Buildx.parseVersion(stdout)).toEqual(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('versionSatisfies', () => {
|
|
||||||
test.each([
|
|
||||||
['0.4.1', '>=0.3.2', true],
|
|
||||||
['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false],
|
|
||||||
['f117971', '>0.6.0', true]
|
|
||||||
])('given %p', async (version, range, expected) => {
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
expect(await buildx.versionSatisfies(range, version)).toBe(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getBuildImageID', () => {
|
|
||||||
it('matches', async () => {
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
|
|
||||||
const imageIDFile = buildx.getBuildImageIDFilePath();
|
|
||||||
await fs.writeFileSync(imageIDFile, imageID);
|
|
||||||
const expected = buildx.getBuildImageID();
|
|
||||||
expect(expected).toEqual(imageID);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getBuildMetadata', () => {
|
|
||||||
it('matches', async () => {
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const metadataFile = buildx.getBuildMetadataFilePath();
|
|
||||||
await fs.writeFileSync(metadataFile, metadata);
|
|
||||||
const expected = buildx.getBuildMetadata();
|
|
||||||
expect(expected).toEqual(metadata);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getDigest', () => {
|
|
||||||
it('matches', async () => {
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
const metadataFile = buildx.getBuildMetadataFilePath();
|
|
||||||
await fs.writeFileSync(metadataFile, metadata);
|
|
||||||
const expected = buildx.getDigest();
|
|
||||||
expect(expected).toEqual('sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getProvenanceInput', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
process.env = Object.keys(process.env).reduce((object, key) => {
|
|
||||||
if (!key.startsWith('INPUT_')) {
|
|
||||||
object[key] = process.env[key];
|
|
||||||
}
|
|
||||||
return object;
|
|
||||||
}, {});
|
|
||||||
});
|
|
||||||
|
|
||||||
// prettier-ignore
|
|
||||||
test.each([
|
|
||||||
[
|
|
||||||
'true',
|
|
||||||
'builder-id=https://github.com/docker/actions-toolkit/actions/runs/123'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'false',
|
|
||||||
'false'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'mode=min',
|
|
||||||
'mode=min,builder-id=https://github.com/docker/actions-toolkit/actions/runs/123'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'mode=max',
|
|
||||||
'mode=max,builder-id=https://github.com/docker/actions-toolkit/actions/runs/123'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'builder-id=foo',
|
|
||||||
'builder-id=foo'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'mode=max,builder-id=foo',
|
|
||||||
'mode=max,builder-id=foo'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'',
|
|
||||||
''
|
|
||||||
],
|
|
||||||
])('given input %p', async (input: string, expected: string) => {
|
|
||||||
await setInput('provenance', input);
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
expect(buildx.getProvenanceInput('provenance')).toEqual(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getProvenanceAttrs', () => {
|
|
||||||
// prettier-ignore
|
|
||||||
test.each([
|
|
||||||
[
|
|
||||||
'mode=min',
|
|
||||||
'mode=min,builder-id=https://github.com/docker/actions-toolkit/actions/runs/123'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'mode=max',
|
|
||||||
'mode=max,builder-id=https://github.com/docker/actions-toolkit/actions/runs/123'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'builder-id=foo',
|
|
||||||
'builder-id=foo'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'mode=max,builder-id=foo',
|
|
||||||
'mode=max,builder-id=foo'
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'',
|
|
||||||
'builder-id=https://github.com/docker/actions-toolkit/actions/runs/123'
|
|
||||||
],
|
|
||||||
])('given %p', async (input: string, expected: string) => {
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
expect(buildx.getProvenanceAttrs(input)).toEqual(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getRelease', () => {
|
|
||||||
it('returns latest buildx GitHub release', async () => {
|
|
||||||
const release = await Buildx.getRelease('latest');
|
|
||||||
expect(release).not.toBeNull();
|
|
||||||
expect(release?.tag_name).not.toEqual('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns v0.10.1 buildx GitHub release', async () => {
|
|
||||||
const release = await Buildx.getRelease('v0.10.1');
|
|
||||||
expect(release).not.toBeNull();
|
|
||||||
expect(release?.id).toEqual(90346950);
|
|
||||||
expect(release?.tag_name).toEqual('v0.10.1');
|
|
||||||
expect(release?.html_url).toEqual('https://github.com/docker/buildx/releases/tag/v0.10.1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns v0.2.2 buildx GitHub release', async () => {
|
|
||||||
const release = await Buildx.getRelease('v0.2.2');
|
|
||||||
expect(release).not.toBeNull();
|
|
||||||
expect(release?.id).toEqual(17671545);
|
|
||||||
expect(release?.tag_name).toEqual('v0.2.2');
|
|
||||||
expect(release?.html_url).toEqual('https://github.com/docker/buildx/releases/tag/v0.2.2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('unknown release', async () => {
|
|
||||||
await expect(Buildx.getRelease('foo')).rejects.toThrowError(new Error('Cannot find Buildx release foo in https://raw.githubusercontent.com/docker/buildx/master/.github/releases.json'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('generateBuildSecret', () => {
|
|
||||||
test.each([
|
|
||||||
['A_SECRET=abcdef0123456789', false, 'A_SECRET', 'abcdef0123456789', null],
|
|
||||||
['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789', false, 'GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789', null],
|
|
||||||
['MY_KEY=c3RyaW5nLXdpdGgtZXF1YWxzCg==', false, 'MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==', null],
|
|
||||||
['aaaaaaaa', false, '', '', new Error('aaaaaaaa is not a valid secret')],
|
|
||||||
['aaaaaaaa=', false, '', '', new Error('aaaaaaaa= is not a valid secret')],
|
|
||||||
['=bbbbbbb', false, '', '', new Error('=bbbbbbb is not a valid secret')],
|
|
||||||
[`foo=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`, true, 'foo', 'bar', null],
|
|
||||||
[`notfound=secret`, true, '', '', new Error('secret file secret not found')]
|
|
||||||
])('given %p key and %p secret', async (kvp: string, file: boolean, exKey: string, exValue: string, error: Error) => {
|
|
||||||
try {
|
|
||||||
const buildx = new Buildx({
|
|
||||||
context: new Context()
|
|
||||||
});
|
|
||||||
let secret: string;
|
|
||||||
if (file) {
|
|
||||||
secret = buildx.generateBuildSecretFile(kvp);
|
|
||||||
} else {
|
|
||||||
secret = buildx.generateBuildSecretString(kvp);
|
|
||||||
}
|
|
||||||
expect(secret).toEqual(`id=${exKey},src=${tmpName}`);
|
|
||||||
expect(fs.readFileSync(tmpName, 'utf-8')).toEqual(exValue);
|
|
||||||
} catch (e) {
|
|
||||||
// eslint-disable-next-line jest/no-conditional-expect
|
|
||||||
expect(e.message).toEqual(error?.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('hasLocalExporter', () => {
|
|
||||||
// prettier-ignore
|
|
||||||
test.each([
|
|
||||||
[['type=registry,ref=user/app'], false],
|
|
||||||
[['type=docker'], false],
|
|
||||||
[['type=local,dest=./release-out'], true],
|
|
||||||
[['type=tar,dest=/tmp/image.tar'], false],
|
|
||||||
[['type=docker', 'type=tar,dest=/tmp/image.tar'], false],
|
|
||||||
[['"type=tar","dest=/tmp/image.tar"'], false],
|
|
||||||
[['" type= local" , dest=./release-out'], true],
|
|
||||||
[['.'], true]
|
|
||||||
])('given %p returns %p', async (exporters: Array<string>, expected: boolean) => {
|
|
||||||
expect(Buildx.hasLocalExporter(exporters)).toEqual(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('hasTarExporter', () => {
|
|
||||||
// prettier-ignore
|
|
||||||
test.each([
|
|
||||||
[['type=registry,ref=user/app'], false],
|
|
||||||
[['type=docker'], false],
|
|
||||||
[['type=local,dest=./release-out'], false],
|
|
||||||
[['type=tar,dest=/tmp/image.tar'], true],
|
|
||||||
[['type=docker', 'type=tar,dest=/tmp/image.tar'], true],
|
|
||||||
[['"type=tar","dest=/tmp/image.tar"'], true],
|
|
||||||
[['" type= local" , dest=./release-out'], false],
|
|
||||||
[['.'], false]
|
|
||||||
])('given %p returns %p', async (exporters: Array<string>, expected: boolean) => {
|
|
||||||
expect(Buildx.hasTarExporter(exporters)).toEqual(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('hasDockerExporter', () => {
|
|
||||||
// prettier-ignore
|
|
||||||
test.each([
|
|
||||||
[['type=registry,ref=user/app'], false, undefined],
|
|
||||||
[['type=docker'], true, undefined],
|
|
||||||
[['type=local,dest=./release-out'], false, undefined],
|
|
||||||
[['type=tar,dest=/tmp/image.tar'], false, undefined],
|
|
||||||
[['type=docker', 'type=tar,dest=/tmp/image.tar'], true, undefined],
|
|
||||||
[['"type=tar","dest=/tmp/image.tar"'], false, undefined],
|
|
||||||
[['" type= local" , dest=./release-out'], false, undefined],
|
|
||||||
[['.'], true, true],
|
|
||||||
])('given %p returns %p', async (exporters: Array<string>, expected: boolean, load: boolean | undefined) => {
|
|
||||||
expect(Buildx.hasDockerExporter(exporters, load)).toEqual(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('hasGitAuthTokenSecret', () => {
|
|
||||||
// prettier-ignore
|
|
||||||
test.each([
|
|
||||||
[['A_SECRET=abcdef0123456789'], false],
|
|
||||||
[['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789'], true],
|
|
||||||
])('given %p secret', async (kvp: Array<string>, expected: boolean) => {
|
|
||||||
expect(Buildx.hasGitAuthTokenSecret(kvp)).toBe(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// See: https://github.com/actions/toolkit/blob/a1b068ec31a042ff1e10a522d8fdf0b8869d53ca/packages/core/src/core.ts#L89
|
|
||||||
function getInputName(name: string): string {
|
|
||||||
return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setInput(name: string, value: string): void {
|
|
||||||
process.env[getInputName(name)] = value;
|
|
||||||
}
|
|
||||||
62
__tests__/buildx/bake.test.itg.ts
Normal file
62
__tests__/buildx/bake.test.itg.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {beforeEach, describe, expect, jest, test} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
import {Bake} from '../../src/buildx/bake';
|
||||||
|
import {BakeDefinition} from '../../src/types/buildx/bake';
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
||||||
|
|
||||||
|
const maybe = !process.env.GITHUB_ACTIONS || (process.env.GITHUB_ACTIONS === 'true' && process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) ? describe : describe.skip;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
maybe('getDefinition', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
'https://github.com/docker/buildx.git#v0.10.4',
|
||||||
|
['binaries-cross'],
|
||||||
|
path.join(fixturesDir, 'bake-buildx-0.10.4-binaries-cross.json'),
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
// TODO: uncomment this test case when we have access to the private repo using an access token
|
||||||
|
// [
|
||||||
|
// 'https://github.com/docker/test-docker-action.git#remote-private',
|
||||||
|
// ['default'],
|
||||||
|
// path.join(fixturesDir, 'bake-test-docker-action-remote-private.json'),
|
||||||
|
// true,
|
||||||
|
// ]
|
||||||
|
])('given %p', async (source: string, targets: string[], out: string, auth) => {
|
||||||
|
const gitAuthToken = process.env.GITHUB_TOKEN || '';
|
||||||
|
if (auth && !gitAuthToken) {
|
||||||
|
console.log(`Git auth token not available, skipping test`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const bake = new Bake();
|
||||||
|
const expectedDef = <BakeDefinition>JSON.parse(fs.readFileSync(out, {encoding: 'utf-8'}).trim())
|
||||||
|
expect(await bake.getDefinition({
|
||||||
|
source: source,
|
||||||
|
targets: targets,
|
||||||
|
githubToken: gitAuthToken,
|
||||||
|
})).toEqual(expectedDef);
|
||||||
|
});
|
||||||
|
});
|
||||||
483
__tests__/buildx/bake.test.ts
Normal file
483
__tests__/buildx/bake.test.ts
Normal file
@@ -0,0 +1,483 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {afterEach, beforeEach, describe, expect, it, jest, test} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as rimraf from 'rimraf';
|
||||||
|
|
||||||
|
import {Bake} from '../../src/buildx/bake';
|
||||||
|
import {Context} from '../../src/context';
|
||||||
|
|
||||||
|
import {ExecOptions} from '@actions/exec';
|
||||||
|
import {BakeDefinition, BakeMetadata} from '../../src/types/buildx/bake';
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-inputs-jest');
|
||||||
|
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
||||||
|
const metadata: BakeMetadata = {
|
||||||
|
app: {
|
||||||
|
'buildx.build.ref': 'default/default/7frbdw1fmfozgtqavghowsepk'
|
||||||
|
},
|
||||||
|
db: {
|
||||||
|
'buildx.build.ref': 'default/default/onic7g2axylf56rxetob7qruy'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.spyOn(Context, 'tmpDir').mockImplementation((): string => {
|
||||||
|
if (!fs.existsSync(tmpDir)) {
|
||||||
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
|
}
|
||||||
|
return tmpDir;
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(Context, 'tmpName').mockImplementation((): string => {
|
||||||
|
return tmpName;
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
rimraf.sync(tmpDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveMetadata', () => {
|
||||||
|
it('matches', async () => {
|
||||||
|
const bake = new Bake();
|
||||||
|
fs.writeFileSync(bake.getMetadataFilePath(), JSON.stringify(metadata));
|
||||||
|
expect(bake.resolveMetadata()).toEqual(metadata as BakeMetadata);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveRefs', () => {
|
||||||
|
it('matches', async () => {
|
||||||
|
const bake = new Bake();
|
||||||
|
fs.writeFileSync(bake.getMetadataFilePath(), JSON.stringify(metadata));
|
||||||
|
expect(bake.resolveRefs()).toEqual(['default/default/7frbdw1fmfozgtqavghowsepk', 'default/default/onic7g2axylf56rxetob7qruy']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getDefinition', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
[path.join(fixturesDir, 'bake-01.hcl')],
|
||||||
|
['validate'],
|
||||||
|
[],
|
||||||
|
{silent: true},
|
||||||
|
path.join(fixturesDir, 'bake-01-validate.json')
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[path.join(fixturesDir, 'bake-02.hcl')],
|
||||||
|
['build'],
|
||||||
|
[],
|
||||||
|
undefined,
|
||||||
|
path.join(fixturesDir, 'bake-02-build.json')
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[path.join(fixturesDir, 'bake-01.hcl')],
|
||||||
|
['image'],
|
||||||
|
['*.output=type=docker', '*.platform=linux/amd64'],
|
||||||
|
undefined,
|
||||||
|
path.join(fixturesDir, 'bake-01-overrides.json')
|
||||||
|
]
|
||||||
|
])('given %p', async (files: string[], targets: string[], overrides: string[], execOptions: ExecOptions | undefined, out: string) => {
|
||||||
|
const bake = new Bake();
|
||||||
|
const expectedDef = <BakeDefinition>JSON.parse(fs.readFileSync(out, {encoding: 'utf-8'}).trim())
|
||||||
|
expect(await bake.getDefinition({
|
||||||
|
files: files,
|
||||||
|
targets: targets,
|
||||||
|
overrides: overrides
|
||||||
|
}, execOptions)).toEqual(expectedDef);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasLocalExporter', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"build": {
|
||||||
|
"output": [
|
||||||
|
"type=docker"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"build": {
|
||||||
|
"target": "build"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"local": {
|
||||||
|
"output": [
|
||||||
|
"type=local,dest=./release-out"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"tar": {
|
||||||
|
"output": [
|
||||||
|
"type=tar,dest=/tmp/image.tar"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"tar": {
|
||||||
|
"output": [
|
||||||
|
'"type=tar","dest=/tmp/image.tar"',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"local": {
|
||||||
|
"output": [
|
||||||
|
'" type= local" , dest=./release-out',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"local": {
|
||||||
|
"output": [
|
||||||
|
".",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true
|
||||||
|
]
|
||||||
|
])('given %o returns %p', async (def: BakeDefinition, expected: boolean) => {
|
||||||
|
expect(Bake.hasLocalExporter(def)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasTarExporter', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"reg": {
|
||||||
|
"output": [
|
||||||
|
"type=registry,ref=user/app"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"build": {
|
||||||
|
"output": [
|
||||||
|
"type=docker"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"local": {
|
||||||
|
"output": [
|
||||||
|
"type=local,dest=./release-out"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"tar": {
|
||||||
|
"output": [
|
||||||
|
"type=tar,dest=/tmp/image.tar"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"multi": {
|
||||||
|
"output": [
|
||||||
|
"type=docker",
|
||||||
|
"type=tar,dest=/tmp/image.tar"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"tar": {
|
||||||
|
"output": [
|
||||||
|
'"type=tar","dest=/tmp/image.tar"',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"local": {
|
||||||
|
"output": [
|
||||||
|
'" type= local" , dest=./release-out',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"local": {
|
||||||
|
"output": [
|
||||||
|
".",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
])('given %o returns %p', async (def: BakeDefinition, expected: boolean) => {
|
||||||
|
expect(Bake.hasTarExporter(def)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasDockerExporter', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"reg": {
|
||||||
|
"output": [
|
||||||
|
"type=registry,ref=user/app"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"build": {
|
||||||
|
"output": [
|
||||||
|
"type=docker"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"multi": {
|
||||||
|
"output": [
|
||||||
|
"type=docker",
|
||||||
|
"type=tar,dest=/tmp/image.tar"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"local": {
|
||||||
|
"output": [
|
||||||
|
'" type= local" , dest=./release-out'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"local": {
|
||||||
|
"output": [
|
||||||
|
"type=local,dest=./release-out"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"tar": {
|
||||||
|
"output": [
|
||||||
|
"type=tar,dest=/tmp/image.tar"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"multi": {
|
||||||
|
"output": [
|
||||||
|
"type=docker",
|
||||||
|
"type=tar,dest=/tmp/image.tar"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"tar": {
|
||||||
|
"output": [
|
||||||
|
'"type=tar","dest=/tmp/image.tar"'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"tar": {
|
||||||
|
"output": [
|
||||||
|
'"type=tar","dest=/tmp/image.tar"'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"local": {
|
||||||
|
"output": [
|
||||||
|
'" type= local" , dest=./release-out'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
false,
|
||||||
|
undefined
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"build": {
|
||||||
|
"output": [
|
||||||
|
"type=docker"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"build": {
|
||||||
|
"output": [
|
||||||
|
"type=docker"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"build": {
|
||||||
|
"output": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} as unknown as BakeDefinition,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
])('given %o and load:%p returns %p', async (def: BakeDefinition, expected: boolean, load: boolean | undefined) => {
|
||||||
|
expect(Bake.hasDockerExporter(def, load)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
361
__tests__/buildx/build.test.ts
Normal file
361
__tests__/buildx/build.test.ts
Normal file
@@ -0,0 +1,361 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {afterEach, beforeEach, describe, expect, it, jest, test} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as rimraf from 'rimraf';
|
||||||
|
|
||||||
|
import {Context} from '../../src/context';
|
||||||
|
import {Build} from '../../src/buildx/build';
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-inputs-jest');
|
||||||
|
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
||||||
|
const metadata = JSON.parse(fs.readFileSync(path.join(fixturesDir, 'metadata.json'), 'utf-8'));
|
||||||
|
|
||||||
|
jest.spyOn(Context, 'tmpDir').mockImplementation((): string => {
|
||||||
|
if (!fs.existsSync(tmpDir)) {
|
||||||
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
|
}
|
||||||
|
return tmpDir;
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(Context, 'tmpName').mockImplementation((): string => {
|
||||||
|
return tmpName;
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
rimraf.sync(tmpDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveImageID', () => {
|
||||||
|
it('matches', async () => {
|
||||||
|
const imageID = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
|
||||||
|
const build = new Build();
|
||||||
|
fs.writeFileSync(build.getImageIDFilePath(), imageID);
|
||||||
|
expect(build.resolveImageID()).toEqual(imageID);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveMetadata', () => {
|
||||||
|
it('matches', async () => {
|
||||||
|
const build = new Build();
|
||||||
|
fs.writeFileSync(build.getMetadataFilePath(), JSON.stringify(metadata));
|
||||||
|
expect(build.resolveMetadata()).toEqual(metadata);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveRef', () => {
|
||||||
|
it('matches', async () => {
|
||||||
|
const build = new Build();
|
||||||
|
fs.writeFileSync(build.getMetadataFilePath(), JSON.stringify(metadata));
|
||||||
|
expect(build.resolveRef()).toEqual('default/default/n6ibcp9b2pw108rrz7ywdznvo');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveProvenance', () => {
|
||||||
|
it('matches', async () => {
|
||||||
|
const build = new Build();
|
||||||
|
fs.writeFileSync(build.getMetadataFilePath(), JSON.stringify(metadata));
|
||||||
|
const provenance = build.resolveProvenance();
|
||||||
|
expect(provenance).toBeDefined();
|
||||||
|
expect(provenance?.buildType).toEqual('https://mobyproject.org/buildkit@v1');
|
||||||
|
expect(provenance?.materials).toBeDefined();
|
||||||
|
expect(provenance?.materials?.length).toEqual(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveDigest', () => {
|
||||||
|
it('matches', async () => {
|
||||||
|
const build = new Build();
|
||||||
|
fs.writeFileSync(build.getMetadataFilePath(), JSON.stringify(metadata));
|
||||||
|
expect(build.resolveDigest()).toEqual('sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getProvenanceInput', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env = Object.keys(process.env).reduce((object, key) => {
|
||||||
|
if (!key.startsWith('INPUT_')) {
|
||||||
|
object[key] = process.env[key];
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}, {});
|
||||||
|
});
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
'true',
|
||||||
|
'builder-id=https://github.com/docker/actions-toolkit/actions/runs/2188748038/attempts/2'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'false',
|
||||||
|
'false'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'mode=min',
|
||||||
|
'mode=min,builder-id=https://github.com/docker/actions-toolkit/actions/runs/2188748038/attempts/2'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'mode=max',
|
||||||
|
'mode=max,builder-id=https://github.com/docker/actions-toolkit/actions/runs/2188748038/attempts/2'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'builder-id=foo',
|
||||||
|
'builder-id=foo'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'mode=max,builder-id=foo',
|
||||||
|
'mode=max,builder-id=foo'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'',
|
||||||
|
''
|
||||||
|
],
|
||||||
|
])('given input %p', async (input: string, expected: string) => {
|
||||||
|
setInput('provenance', input);
|
||||||
|
expect(Build.getProvenanceInput('provenance')).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveProvenanceAttrs', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
'mode=min',
|
||||||
|
'mode=min,builder-id=https://github.com/docker/actions-toolkit/actions/runs/2188748038/attempts/2'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'mode=max',
|
||||||
|
'mode=max,builder-id=https://github.com/docker/actions-toolkit/actions/runs/2188748038/attempts/2'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'builder-id=foo',
|
||||||
|
'builder-id=foo'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'mode=max,builder-id=foo',
|
||||||
|
'mode=max,builder-id=foo'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'',
|
||||||
|
'builder-id=https://github.com/docker/actions-toolkit/actions/runs/2188748038/attempts/2'
|
||||||
|
],
|
||||||
|
])('given %p', async (input: string, expected: string) => {
|
||||||
|
expect(Build.resolveProvenanceAttrs(input)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveSecret', () => {
|
||||||
|
test.each([
|
||||||
|
['A_SECRET=abcdef0123456789', false, 'A_SECRET', 'abcdef0123456789', null],
|
||||||
|
['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789', false, 'GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789', null],
|
||||||
|
['MY_KEY=c3RyaW5nLXdpdGgtZXF1YWxzCg==', false, 'MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==', null],
|
||||||
|
['aaaaaaaa', false, '', '', new Error('aaaaaaaa is not a valid secret')],
|
||||||
|
['aaaaaaaa=', false, '', '', new Error('aaaaaaaa= is not a valid secret')],
|
||||||
|
['=bbbbbbb', false, '', '', new Error('=bbbbbbb is not a valid secret')],
|
||||||
|
[`foo=${path.join(fixturesDir, 'secret.txt')}`, true, 'foo', 'bar', null],
|
||||||
|
[`notfound=secret`, true, '', '', new Error('secret file secret not found')]
|
||||||
|
])('given %p key and %p secret', async (kvp: string, file: boolean, exKey: string, exValue: string, error: Error | null) => {
|
||||||
|
try {
|
||||||
|
let secret: string;
|
||||||
|
if (file) {
|
||||||
|
secret = Build.resolveSecretFile(kvp);
|
||||||
|
} else {
|
||||||
|
secret = Build.resolveSecretString(kvp);
|
||||||
|
}
|
||||||
|
expect(secret).toEqual(`id=${exKey},src=${tmpName}`);
|
||||||
|
expect(fs.readFileSync(tmpName, 'utf-8')).toEqual(exValue);
|
||||||
|
} catch (e) {
|
||||||
|
// eslint-disable-next-line jest/no-conditional-expect
|
||||||
|
expect(e.message).toEqual(error?.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test.each([
|
||||||
|
['FOO=bar', 'FOO', 'bar', null],
|
||||||
|
['FOO=', 'FOO', '', new Error('FOO= is not a valid secret')],
|
||||||
|
['=bar', '', '', new Error('=bar is not a valid secret')],
|
||||||
|
['FOO=bar=baz', 'FOO', 'bar=baz', null]
|
||||||
|
])('given %p key and %p env', async (kvp: string, exKey: string, exValue: string, error: Error | null) => {
|
||||||
|
try {
|
||||||
|
const secret = Build.resolveSecretEnv(kvp);
|
||||||
|
expect(secret).toEqual(`id=${exKey},env=${exValue}`);
|
||||||
|
} catch (e) {
|
||||||
|
// eslint-disable-next-line jest/no-conditional-expect
|
||||||
|
expect(e.message).toEqual(error?.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveCacheToAttrs', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
'',
|
||||||
|
undefined,
|
||||||
|
''
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'user/app:cache',
|
||||||
|
undefined,
|
||||||
|
'user/app:cache'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type=inline',
|
||||||
|
undefined,
|
||||||
|
'type=inline'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type=gha',
|
||||||
|
undefined,
|
||||||
|
'type=gha,repository=docker/actions-toolkit',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type=gha,mode=max',
|
||||||
|
undefined,
|
||||||
|
'type=gha,mode=max,repository=docker/actions-toolkit',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type=gha,mode=max',
|
||||||
|
'abcd1234',
|
||||||
|
'type=gha,mode=max,repository=docker/actions-toolkit,ghtoken=abcd1234',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type=gha,repository=foo/bar,mode=max',
|
||||||
|
undefined,
|
||||||
|
'type=gha,repository=foo/bar,mode=max',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type=gha,repository=foo/bar,mode=max',
|
||||||
|
'abcd1234',
|
||||||
|
'type=gha,repository=foo/bar,mode=max,ghtoken=abcd1234',
|
||||||
|
],
|
||||||
|
])('given %p', async (input: string, githubToken: string | undefined, expected: string) => {
|
||||||
|
expect(Build.resolveCacheToAttrs(input, githubToken)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasLocalExporter', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[['type=registry,ref=user/app'], false],
|
||||||
|
[['type=docker'], false],
|
||||||
|
[['type=local,dest=./release-out'], true],
|
||||||
|
[['type=tar,dest=/tmp/image.tar'], false],
|
||||||
|
[['type=docker', 'type=tar,dest=/tmp/image.tar'], false],
|
||||||
|
[['"type=tar","dest=/tmp/image.tar"'], false],
|
||||||
|
[['" type= local" , dest=./release-out'], true],
|
||||||
|
[['.'], true]
|
||||||
|
])('given %p returns %p', async (exporters: Array<string>, expected: boolean) => {
|
||||||
|
expect(Build.hasLocalExporter(exporters)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasTarExporter', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[['type=registry,ref=user/app'], false],
|
||||||
|
[['type=docker'], false],
|
||||||
|
[['type=local,dest=./release-out'], false],
|
||||||
|
[['type=tar,dest=/tmp/image.tar'], true],
|
||||||
|
[['type=docker', 'type=tar,dest=/tmp/image.tar'], true],
|
||||||
|
[['"type=tar","dest=/tmp/image.tar"'], true],
|
||||||
|
[['" type= local" , dest=./release-out'], false],
|
||||||
|
[['.'], false]
|
||||||
|
])('given %p returns %p', async (exporters: Array<string>, expected: boolean) => {
|
||||||
|
expect(Build.hasTarExporter(exporters)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasDockerExporter', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[['type=registry,ref=user/app'], false, undefined],
|
||||||
|
[['type=docker'], true, undefined],
|
||||||
|
[['type=local,dest=./release-out'], false, undefined],
|
||||||
|
[['type=tar,dest=/tmp/image.tar'], false, undefined],
|
||||||
|
[['type=docker', 'type=tar,dest=/tmp/image.tar'], true, undefined],
|
||||||
|
[['"type=tar","dest=/tmp/image.tar"'], false, undefined],
|
||||||
|
[['" type= local" , dest=./release-out'], false, undefined],
|
||||||
|
[['type=docker'], true, false],
|
||||||
|
[['type=docker'], true, true],
|
||||||
|
[['.'], true, true],
|
||||||
|
])('given %p returns %p', async (exporters: Array<string>, expected: boolean, load: boolean | undefined) => {
|
||||||
|
expect(Build.hasDockerExporter(exporters, load)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasAttestationType', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
['type=provenance,mode=min', 'provenance', true],
|
||||||
|
['type=sbom,true', 'sbom', true],
|
||||||
|
['type=foo,bar', 'provenance', false],
|
||||||
|
])('given %p for %p returns %p', async (attrs: string, name: string, expected: boolean) => {
|
||||||
|
expect(Build.hasAttestationType(name, attrs)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveAttestationAttrs', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
'type=provenance,mode=min',
|
||||||
|
'type=provenance,mode=min'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type=provenance,true',
|
||||||
|
'type=provenance,disabled=false'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type=provenance,false',
|
||||||
|
'type=provenance,disabled=true'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'',
|
||||||
|
''
|
||||||
|
],
|
||||||
|
])('given %p', async (input: string, expected: string) => {
|
||||||
|
expect(Build.resolveAttestationAttrs(input)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hasGitAuthTokenSecret', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[['A_SECRET=abcdef0123456789'], false],
|
||||||
|
[['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789'], true],
|
||||||
|
])('given %p secret', async (kvp: Array<string>, expected: boolean) => {
|
||||||
|
expect(Build.hasGitAuthTokenSecret(kvp)).toBe(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/actions/toolkit/blob/a1b068ec31a042ff1e10a522d8fdf0b8869d53ca/packages/core/src/core.ts#L89
|
||||||
|
function getInputName(name: string): string {
|
||||||
|
return `INPUT_${name.replace(/ /g, '_').toUpperCase()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setInput(name: string, value: string): void {
|
||||||
|
process.env[getInputName(name)] = value;
|
||||||
|
}
|
||||||
464
__tests__/buildx/builder.test.ts
Normal file
464
__tests__/buildx/builder.test.ts
Normal file
@@ -0,0 +1,464 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {beforeEach, describe, expect, it, jest, test} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
import {Builder} from '../../src/buildx/builder';
|
||||||
|
import {Exec} from '../../src/exec';
|
||||||
|
|
||||||
|
import {BuilderInfo} from '../../src/types/buildx/builder';
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise<BuilderInfo> => {
|
||||||
|
return {
|
||||||
|
name: 'builder2',
|
||||||
|
driver: 'docker-container',
|
||||||
|
lastActivity: new Date('2023-01-16 09:45:23 +0000 UTC'),
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
buildkit: 'v0.11.0',
|
||||||
|
'buildkitd-flags': '--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host',
|
||||||
|
'driver-opts': ['BUILDKIT_STEP_LOG_MAX_SIZE=10485760', 'BUILDKIT_STEP_LOG_MAX_SPEED=10485760', 'JAEGER_TRACE=localhost:6831', 'image=moby/buildkit:latest', 'network=host', 'qemu.install=true'],
|
||||||
|
endpoint: 'unix:///var/run/docker.sock',
|
||||||
|
name: 'builder20',
|
||||||
|
platforms: 'linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6',
|
||||||
|
status: 'running'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('exists', () => {
|
||||||
|
it('valid', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'getExecOutput');
|
||||||
|
const builder = new Builder();
|
||||||
|
await builder.exists('foo');
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx', 'inspect', 'foo'], {
|
||||||
|
silent: true,
|
||||||
|
ignoreReturnCode: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('inspect', () => {
|
||||||
|
it('valid', async () => {
|
||||||
|
const builder = new Builder();
|
||||||
|
const builderInfo = await builder.inspect('');
|
||||||
|
expect(builderInfo).not.toBeUndefined();
|
||||||
|
expect(builderInfo.name).not.toEqual('');
|
||||||
|
expect(builderInfo.driver).not.toEqual('');
|
||||||
|
expect(builderInfo.nodes).not.toEqual({});
|
||||||
|
}, 100000);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('parseInspect', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
'inspect1.txt',
|
||||||
|
{
|
||||||
|
"name": "builder-5cb467f7-0940-47e1-b94b-d51f54054d62",
|
||||||
|
"driver": "docker-container",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"name": "builder-5cb467f7-0940-47e1-b94b-d51f54054d620",
|
||||||
|
"endpoint": "unix:///var/run/docker.sock",
|
||||||
|
"status": "running",
|
||||||
|
"buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
||||||
|
"buildkit": "v0.10.4",
|
||||||
|
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/arm64,linux/riscv64,linux/386,linux/arm/v7,linux/arm/v6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'inspect2.txt',
|
||||||
|
{
|
||||||
|
"name": "builder-5f449644-ff29-48af-8344-abb0292d0673",
|
||||||
|
"driver": "docker-container",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"name": "builder-5f449644-ff29-48af-8344-abb0292d06730",
|
||||||
|
"endpoint": "unix:///var/run/docker.sock",
|
||||||
|
"driver-opts": [
|
||||||
|
"image=moby/buildkit:latest"
|
||||||
|
],
|
||||||
|
"status": "running",
|
||||||
|
"buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
||||||
|
"buildkit": "v0.10.4",
|
||||||
|
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'inspect3.txt',
|
||||||
|
{
|
||||||
|
"name": "builder-9929e463-7954-4dc3-89cd-514cca29ff80",
|
||||||
|
"driver": "docker-container",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"name": "builder-9929e463-7954-4dc3-89cd-514cca29ff800",
|
||||||
|
"endpoint": "unix:///var/run/docker.sock",
|
||||||
|
"driver-opts": [
|
||||||
|
"image=moby/buildkit:master",
|
||||||
|
"network=host"
|
||||||
|
],
|
||||||
|
"status": "running",
|
||||||
|
"buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
||||||
|
"buildkit": "3fab389",
|
||||||
|
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/386"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'inspect4.txt',
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"driver": "docker",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"endpoint": "default",
|
||||||
|
"status": "running",
|
||||||
|
"buildkit": "20.10.17",
|
||||||
|
"platforms": "linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'inspect5.txt',
|
||||||
|
{
|
||||||
|
"name": "remote-builder",
|
||||||
|
"driver": "remote",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"name": "aws_graviton2",
|
||||||
|
"endpoint": "tcp://1.23.45.67:1234",
|
||||||
|
"driver-opts": [
|
||||||
|
"cert=/home/user/.certs/aws_graviton2/cert.pem",
|
||||||
|
"key=/home/user/.certs/aws_graviton2/key.pem",
|
||||||
|
"cacert=/home/user/.certs/aws_graviton2/ca.pem"
|
||||||
|
],
|
||||||
|
"status": "running",
|
||||||
|
"platforms": "darwin/arm64,linux/arm64,linux/arm/v5,linux/arm/v6,linux/arm/v7,windows/arm64"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'inspect6.txt',
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"name": "builder-17cfff01-48d9-4c3d-9332-9992e308a5100",
|
||||||
|
"endpoint": "unix:///var/run/docker.sock",
|
||||||
|
"status": "running",
|
||||||
|
"buildkitd-flags": "--allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
||||||
|
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/386"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "builder-17cfff01-48d9-4c3d-9332-9992e308a510",
|
||||||
|
"driver": "docker-container"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'inspect7.txt',
|
||||||
|
{
|
||||||
|
"name": "builder2",
|
||||||
|
"driver": "docker-container",
|
||||||
|
"lastActivity": new Date("2023-01-16T09:45:23.000Z"),
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"buildkit": "v0.11.0",
|
||||||
|
"buildkitd-flags": "--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
||||||
|
"driver-opts": [
|
||||||
|
"env.BUILDKIT_STEP_LOG_MAX_SIZE=10485760",
|
||||||
|
"env.BUILDKIT_STEP_LOG_MAX_SPEED=10485760",
|
||||||
|
"env.JAEGER_TRACE=localhost:6831",
|
||||||
|
"image=moby/buildkit:latest",
|
||||||
|
"network=host",
|
||||||
|
"qemu.install=true"
|
||||||
|
],
|
||||||
|
"endpoint": "unix:///var/run/docker.sock",
|
||||||
|
"name": "builder20",
|
||||||
|
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6",
|
||||||
|
"status": "running"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'inspect8.txt',
|
||||||
|
{
|
||||||
|
"name": "builder-52aa0611-faf0-42ac-a940-461e4e287d68",
|
||||||
|
"driver": "docker-container",
|
||||||
|
"lastActivity": new Date("2023-06-13T13:52:31.000Z"),
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"buildkit": "v0.11.6",
|
||||||
|
"buildkitd-flags": "--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host",
|
||||||
|
"driver-opts": [
|
||||||
|
"image=moby/buildkit:buildx-stable-1",
|
||||||
|
"network=host",
|
||||||
|
],
|
||||||
|
"endpoint": "unix:///var/run/docker.sock",
|
||||||
|
"name": "builder-52aa0611-faf0-42ac-a940-461e4e287d680",
|
||||||
|
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/amd64/v4,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6",
|
||||||
|
"status": "running",
|
||||||
|
"labels": {
|
||||||
|
"org.mobyproject.buildkit.worker.executor": "oci",
|
||||||
|
"org.mobyproject.buildkit.worker.hostname": "fv-az572-38",
|
||||||
|
"org.mobyproject.buildkit.worker.network": "host",
|
||||||
|
"org.mobyproject.buildkit.worker.oci.process-mode": "sandbox",
|
||||||
|
"org.mobyproject.buildkit.worker.selinux.enabled": "false",
|
||||||
|
"org.mobyproject.buildkit.worker.snapshotter": "overlayfs",
|
||||||
|
},
|
||||||
|
"gcPolicy": [
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"filter": [
|
||||||
|
"type==source.local",
|
||||||
|
"type==exec.cachemount",
|
||||||
|
"type==source.git.checkout"
|
||||||
|
],
|
||||||
|
"keepDuration": "48h0m0s",
|
||||||
|
"keepBytes": "488.3MiB",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"keepDuration": "1440h0m0s",
|
||||||
|
"keepBytes": "8.382GiB",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"keepBytes": "8.382GiB",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": true,
|
||||||
|
"keepBytes": "8.382GiB",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'inspect9.txt',
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"driver": "docker",
|
||||||
|
"lastActivity": new Date("2023-06-13T18:13:43.000Z"),
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"buildkit": "v0.11.7-0.20230525183624-798ad6b0ce9f",
|
||||||
|
"endpoint": "default",
|
||||||
|
"name": "default",
|
||||||
|
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6",
|
||||||
|
"status": "running",
|
||||||
|
"gcPolicy": [
|
||||||
|
{
|
||||||
|
"all": true,
|
||||||
|
"keepBytes": "100GiB",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'inspect10.txt',
|
||||||
|
{
|
||||||
|
"name": "remote-builder",
|
||||||
|
"driver": "remote",
|
||||||
|
"lastActivity": new Date("2023-04-20T12:47:49.000Z"),
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"name": "remote-builder0",
|
||||||
|
"endpoint": "docker-container://buildx_buildkit_dk-remote-builder0",
|
||||||
|
"status": "inactive"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aws_graviton2",
|
||||||
|
"endpoint": "tcp://10.0.0.1:1234",
|
||||||
|
"driver-opts": [
|
||||||
|
"cacert=/home/user/.certs/aws_graviton2/ca.pem",
|
||||||
|
"cert=/home/user/.certs/aws_graviton2/cert.pem",
|
||||||
|
"key=/home/user/.certs/aws_graviton2/key.pem"
|
||||||
|
],
|
||||||
|
"status": "running",
|
||||||
|
"buildkit": "v0.11.6",
|
||||||
|
"platforms": "darwin/arm64,linux/arm64,linux/arm/v5,linux/arm/v6,linux/arm/v7,windows/arm64",
|
||||||
|
"labels": {
|
||||||
|
"org.mobyproject.buildkit.worker.executor": "oci",
|
||||||
|
"org.mobyproject.buildkit.worker.hostname": "77ebc22e2d82",
|
||||||
|
"org.mobyproject.buildkit.worker.network": "host",
|
||||||
|
"org.mobyproject.buildkit.worker.oci.process-mode": "sandbox",
|
||||||
|
"org.mobyproject.buildkit.worker.selinux.enabled": "false",
|
||||||
|
"org.mobyproject.buildkit.worker.snapshotter": "overlayfs"
|
||||||
|
},
|
||||||
|
"gcPolicy": [
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"filter": [
|
||||||
|
"type==source.local",
|
||||||
|
"type==exec.cachemount",
|
||||||
|
"type==source.git.checkout"
|
||||||
|
],
|
||||||
|
"keepDuration": "48h0m0s",
|
||||||
|
"keepBytes": "488.3MiB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"keepDuration": "1440h0m0s",
|
||||||
|
"keepBytes": "23.28GiB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"keepBytes": "23.28GiB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": true,
|
||||||
|
"keepBytes": "23.28GiB"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "linuxone_s390x",
|
||||||
|
"endpoint": "tcp://10.0.0.2:1234",
|
||||||
|
"driver-opts": [
|
||||||
|
"cacert=/home/user/.certs/linuxone_s390x/ca.pem",
|
||||||
|
"cert=/home/user/.certs/linuxone_s390x/cert.pem",
|
||||||
|
"key=/home/user/.certs/linuxone_s390x/key.pem"
|
||||||
|
],
|
||||||
|
"status": "running",
|
||||||
|
"buildkit": "v0.11.6",
|
||||||
|
"platforms": "linux/s390x",
|
||||||
|
"labels": {
|
||||||
|
"org.mobyproject.buildkit.worker.executor": "oci",
|
||||||
|
"org.mobyproject.buildkit.worker.hostname": "9d0d62a96818",
|
||||||
|
"org.mobyproject.buildkit.worker.network": "host",
|
||||||
|
"org.mobyproject.buildkit.worker.oci.process-mode": "sandbox",
|
||||||
|
"org.mobyproject.buildkit.worker.selinux.enabled": "false",
|
||||||
|
"org.mobyproject.buildkit.worker.snapshotter": "overlayfs"
|
||||||
|
},
|
||||||
|
"gcPolicy": [
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"keepBytes": "488.3MiB",
|
||||||
|
"filter": [
|
||||||
|
"type==source.local",
|
||||||
|
"type==exec.cachemount",
|
||||||
|
"type==source.git.checkout"
|
||||||
|
],
|
||||||
|
"keepDuration": "48h0m0s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"keepDuration": "1440h0m0s",
|
||||||
|
"keepBytes": "9.313GiB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"keepBytes": "9.313GiB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": true,
|
||||||
|
"keepBytes": "9.313GiB"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'inspect11.txt',
|
||||||
|
{
|
||||||
|
"name": "builder",
|
||||||
|
"driver": "docker-container",
|
||||||
|
"lastActivity": new Date("2024-03-01T14:25:03.000Z"),
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"buildkit": "37657a1",
|
||||||
|
"buildkitd-flags": "--debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host --allow-insecure-entitlement=network.host",
|
||||||
|
"driver-opts": [
|
||||||
|
"env.JAEGER_TRACE=localhost:6831",
|
||||||
|
"image=moby/buildkit:master",
|
||||||
|
"network=host",
|
||||||
|
"env.BUILDKIT_STEP_LOG_MAX_SIZE=10485760",
|
||||||
|
"env.BUILDKIT_STEP_LOG_MAX_SPEED=10485760",
|
||||||
|
],
|
||||||
|
"endpoint": "unix:///var/run/docker.sock",
|
||||||
|
"name": "builder0",
|
||||||
|
"platforms": "linux/amd64,linux/amd64/v2,linux/amd64/v3,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6",
|
||||||
|
"status": "running",
|
||||||
|
"features": {
|
||||||
|
"Cache export": true,
|
||||||
|
"Docker exporter": true,
|
||||||
|
"Multi-platform build": true,
|
||||||
|
"OCI exporter": true,
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"org.mobyproject.buildkit.worker.executor": "oci",
|
||||||
|
"org.mobyproject.buildkit.worker.hostname": "docker-desktop",
|
||||||
|
"org.mobyproject.buildkit.worker.network": "host",
|
||||||
|
"org.mobyproject.buildkit.worker.oci.process-mode": "sandbox",
|
||||||
|
"org.mobyproject.buildkit.worker.selinux.enabled": "false",
|
||||||
|
"org.mobyproject.buildkit.worker.snapshotter": "overlayfs",
|
||||||
|
},
|
||||||
|
"gcPolicy": [
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"filter": [
|
||||||
|
"type==source.local",
|
||||||
|
"type==exec.cachemount",
|
||||||
|
"type==source.git.checkout"
|
||||||
|
],
|
||||||
|
"keepDuration": "48h0m0s",
|
||||||
|
"keepBytes": "488.3MiB",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"keepDuration": "1440h0m0s",
|
||||||
|
"keepBytes": "94.06GiB",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": false,
|
||||||
|
"keepBytes": "94.06GiB",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"all": true,
|
||||||
|
"keepBytes": "94.06GiB",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
])('given %p', async (inspectFile, expected) => {
|
||||||
|
expect(await Builder.parseInspect(fs.readFileSync(path.join(fixturesDir, inspectFile)).toString())).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
290
__tests__/buildx/buildx.test.ts
Normal file
290
__tests__/buildx/buildx.test.ts
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {describe, expect, it, jest, test, beforeEach, afterEach} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as rimraf from 'rimraf';
|
||||||
|
import * as semver from 'semver';
|
||||||
|
|
||||||
|
import {Buildx} from '../../src/buildx/buildx';
|
||||||
|
import {Context} from '../../src/context';
|
||||||
|
import {Exec} from '../../src/exec';
|
||||||
|
|
||||||
|
import {Cert} from '../../src/types/buildx/buildx';
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-jest');
|
||||||
|
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
||||||
|
|
||||||
|
jest.spyOn(Context, 'tmpDir').mockImplementation((): string => {
|
||||||
|
if (!fs.existsSync(tmpDir)) {
|
||||||
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
|
}
|
||||||
|
return tmpDir;
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.spyOn(Context, 'tmpName').mockImplementation((): string => {
|
||||||
|
return tmpName;
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
rimraf.sync(tmpDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('configDir', () => {
|
||||||
|
const originalEnv = process.env;
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
BUILDX_CONFIG: '/var/docker/buildx',
|
||||||
|
DOCKER_CONFIG: '/var/docker/config'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = originalEnv;
|
||||||
|
});
|
||||||
|
it('returns default', async () => {
|
||||||
|
process.env.BUILDX_CONFIG = '';
|
||||||
|
expect(Buildx.configDir).toEqual(path.join('/var/docker/config', 'buildx'));
|
||||||
|
});
|
||||||
|
it('returns from env', async () => {
|
||||||
|
expect(Buildx.configDir).toEqual('/var/docker/buildx');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('certsDir', () => {
|
||||||
|
const originalEnv = process.env;
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
BUILDX_CONFIG: '/var/docker/buildx'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = originalEnv;
|
||||||
|
});
|
||||||
|
it('returns default', async () => {
|
||||||
|
process.env.BUILDX_CONFIG = '/var/docker/buildx';
|
||||||
|
expect(Buildx.certsDir).toEqual(path.join('/var/docker/buildx', 'certs'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isAvailable', () => {
|
||||||
|
it('docker cli', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'getExecOutput');
|
||||||
|
const buildx = new Buildx({
|
||||||
|
standalone: false
|
||||||
|
});
|
||||||
|
await buildx.isAvailable();
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx'], {
|
||||||
|
silent: true,
|
||||||
|
ignoreReturnCode: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('standalone', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'getExecOutput');
|
||||||
|
const buildx = new Buildx({
|
||||||
|
standalone: true
|
||||||
|
});
|
||||||
|
await buildx.isAvailable();
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`buildx`, [], {
|
||||||
|
silent: true,
|
||||||
|
ignoreReturnCode: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('printVersion', () => {
|
||||||
|
it('docker cli', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'exec');
|
||||||
|
const buildx = new Buildx({
|
||||||
|
standalone: false
|
||||||
|
});
|
||||||
|
await buildx.printVersion();
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`docker`, ['buildx', 'version'], {
|
||||||
|
failOnStdErr: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('standalone', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'exec');
|
||||||
|
const buildx = new Buildx({
|
||||||
|
standalone: true
|
||||||
|
});
|
||||||
|
await buildx.printVersion();
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`buildx`, ['version'], {
|
||||||
|
failOnStdErr: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('version', () => {
|
||||||
|
it('valid', async () => {
|
||||||
|
const buildx = new Buildx();
|
||||||
|
expect(semver.valid(await buildx.version())).not.toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('parseVersion', () => {
|
||||||
|
test.each([
|
||||||
|
['github.com/docker/buildx 0.4.1+azure bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'],
|
||||||
|
['github.com/docker/buildx v0.4.1 bda4882a65349ca359216b135896bddc1d92461c', '0.4.1'],
|
||||||
|
['github.com/docker/buildx v0.4.2 fb7b670b764764dc4716df3eba07ffdae4cc47b2', '0.4.2'],
|
||||||
|
['github.com/docker/buildx f117971 f11797113e5a9b86bd976329c5dbb8a8bfdfadfa', 'f117971']
|
||||||
|
])('given %p', async (stdout, expected) => {
|
||||||
|
expect(Buildx.parseVersion(stdout)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('versionSatisfies', () => {
|
||||||
|
test.each([
|
||||||
|
['0.4.1', '>=0.3.2', true],
|
||||||
|
['bda4882a65349ca359216b135896bddc1d92461c', '>0.1.0', false],
|
||||||
|
['f117971', '>0.6.0', true]
|
||||||
|
])('given %p', async (version, range, expected) => {
|
||||||
|
const buildx = new Buildx();
|
||||||
|
expect(await buildx.versionSatisfies(range, version)).toBe(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('resolveCertsDriverOpts', () => {
|
||||||
|
const originalEnv = process.env;
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
BUILDX_CONFIG: path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx')
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = originalEnv;
|
||||||
|
rimraf.sync(path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx'));
|
||||||
|
});
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
'mycontext',
|
||||||
|
'docker-container',
|
||||||
|
{},
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
'docker-container://mycontainer',
|
||||||
|
'docker-container',
|
||||||
|
{},
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
3,
|
||||||
|
'tcp://graviton2:1234',
|
||||||
|
'remote',
|
||||||
|
{},
|
||||||
|
[],
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
4,
|
||||||
|
'tcp://graviton2:1234',
|
||||||
|
'remote',
|
||||||
|
{
|
||||||
|
cacert: 'foo',
|
||||||
|
cert: 'foo',
|
||||||
|
key: 'foo',
|
||||||
|
} as Cert,
|
||||||
|
[
|
||||||
|
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cacert_graviton2-1234.pem'),
|
||||||
|
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cert_graviton2-1234.pem'),
|
||||||
|
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'key_graviton2-1234.pem')
|
||||||
|
],
|
||||||
|
[
|
||||||
|
`cacert=${path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cacert_graviton2-1234.pem')}`,
|
||||||
|
`cert=${path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cert_graviton2-1234.pem')}`,
|
||||||
|
`key=${path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'key_graviton2-1234.pem')}`
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
5,
|
||||||
|
'tcp://mybuilder:1234',
|
||||||
|
'docker-container',
|
||||||
|
{
|
||||||
|
cacert: 'foo',
|
||||||
|
cert: 'foo',
|
||||||
|
key: 'foo',
|
||||||
|
} as Cert,
|
||||||
|
[
|
||||||
|
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cacert_mybuilder-1234.pem'),
|
||||||
|
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'cert_mybuilder-1234.pem'),
|
||||||
|
path.join(tmpDir, 'resolveCertsDriverOpts', 'buildx', 'certs', 'key_mybuilder-1234.pem')
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
])('%p. given %p endpoint, %p driver', async (id: number, endpoint: string, driver: string, cert: Cert, expectedFiles: Array<string>, expectedOpts: Array<string>) => {
|
||||||
|
fs.mkdirSync(Buildx.certsDir, {recursive: true});
|
||||||
|
expect(Buildx.resolveCertsDriverOpts(driver, endpoint, cert)).toEqual(expectedOpts);
|
||||||
|
for (const k in expectedFiles) {
|
||||||
|
const file = expectedFiles[k];
|
||||||
|
expect(fs.existsSync(file)).toBe(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('refs', () => {
|
||||||
|
it('returns all refs', async () => {
|
||||||
|
const refs = Buildx.refs({
|
||||||
|
dir: path.join(fixturesDir, 'buildx-refs')
|
||||||
|
});
|
||||||
|
expect(Object.keys(refs).length).toEqual(11);
|
||||||
|
});
|
||||||
|
it('returns default builder refs', async () => {
|
||||||
|
const refs = Buildx.refs({
|
||||||
|
dir: path.join(fixturesDir, 'buildx-refs'),
|
||||||
|
builderName: 'default'
|
||||||
|
});
|
||||||
|
expect(Object.keys(refs).length).toEqual(8);
|
||||||
|
});
|
||||||
|
it('returns foo builder refs', async () => {
|
||||||
|
const refs = Buildx.refs({
|
||||||
|
dir: path.join(fixturesDir, 'buildx-refs'),
|
||||||
|
builderName: 'foo'
|
||||||
|
});
|
||||||
|
expect(Object.keys(refs).length).toEqual(3);
|
||||||
|
});
|
||||||
|
it('returns default builder refs since', async () => {
|
||||||
|
const mdate = new Date('2023-09-05T00:00:00Z');
|
||||||
|
fs.utimesSync(path.join(fixturesDir, 'buildx-refs', 'default', 'default', '36dix0eiv9evr61vrwzn32w7q'), mdate, mdate);
|
||||||
|
fs.utimesSync(path.join(fixturesDir, 'buildx-refs', 'default', 'default', '49p5r8und2konke5pmlyzqp3n'), mdate, mdate);
|
||||||
|
fs.utimesSync(path.join(fixturesDir, 'buildx-refs', 'default', 'default', 'a8zqzhhv5yiazm396jobsgdw2'), mdate, mdate);
|
||||||
|
const refs = Buildx.refs({
|
||||||
|
dir: path.join(fixturesDir, 'buildx-refs'),
|
||||||
|
builderName: 'default',
|
||||||
|
since: new Date('2024-01-10T00:00:00Z')
|
||||||
|
});
|
||||||
|
expect(Object.keys(refs).length).toEqual(5);
|
||||||
|
});
|
||||||
|
});
|
||||||
153
__tests__/buildx/history.test.itg.ts
Normal file
153
__tests__/buildx/history.test.itg.ts
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2024 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {beforeEach, describe, expect, jest, test} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
import {Buildx} from '../../src/buildx/buildx';
|
||||||
|
import {Bake} from '../../src/buildx/bake';
|
||||||
|
import {Build} from '../../src/buildx/build';
|
||||||
|
import {History} from '../../src/buildx/history';
|
||||||
|
import {Exec} from '../../src/exec';
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-history-jest');
|
||||||
|
|
||||||
|
const maybe = !process.env.GITHUB_ACTIONS || (process.env.GITHUB_ACTIONS === 'true' && process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) ? describe : describe.skip;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
maybe('exportBuild', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
'single',
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'-f', path.join(fixturesDir, 'hello.Dockerfile'),
|
||||||
|
fixturesDir
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'multi-platform',
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'-f', path.join(fixturesDir, 'hello.Dockerfile'),
|
||||||
|
'--platform', 'linux/amd64,linux/arm64',
|
||||||
|
fixturesDir
|
||||||
|
],
|
||||||
|
]
|
||||||
|
])('export build %p', async (_, bargs) => {
|
||||||
|
const buildx = new Buildx();
|
||||||
|
const build = new Build({buildx: buildx});
|
||||||
|
|
||||||
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
|
await expect(
|
||||||
|
(async () => {
|
||||||
|
// prettier-ignore
|
||||||
|
const buildCmd = await buildx.getCommand([
|
||||||
|
'--builder', process.env.CTN_BUILDER_NAME ?? 'default',
|
||||||
|
...bargs,
|
||||||
|
'--metadata-file', build.getMetadataFilePath()
|
||||||
|
]);
|
||||||
|
await Exec.exec(buildCmd.command, buildCmd.args);
|
||||||
|
})()
|
||||||
|
).resolves.not.toThrow();
|
||||||
|
|
||||||
|
const metadata = build.resolveMetadata();
|
||||||
|
expect(metadata).toBeDefined();
|
||||||
|
const buildRef = build.resolveRef(metadata);
|
||||||
|
expect(buildRef).toBeDefined();
|
||||||
|
|
||||||
|
const history = new History({buildx: buildx});
|
||||||
|
const exportRes = await history.export({
|
||||||
|
refs: [buildRef ?? '']
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(exportRes).toBeDefined();
|
||||||
|
expect(exportRes?.dockerbuildFilename).toBeDefined();
|
||||||
|
expect(exportRes?.dockerbuildSize).toBeDefined();
|
||||||
|
expect(fs.existsSync(exportRes?.dockerbuildFilename)).toBe(true);
|
||||||
|
expect(exportRes?.summaries).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
'single',
|
||||||
|
[
|
||||||
|
'bake',
|
||||||
|
'-f', path.join(fixturesDir, 'hello-bake.hcl'),
|
||||||
|
'hello'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'group',
|
||||||
|
[
|
||||||
|
'bake',
|
||||||
|
'-f', path.join(fixturesDir, 'hello-bake.hcl'),
|
||||||
|
'hello-all'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'matrix',
|
||||||
|
[
|
||||||
|
'bake',
|
||||||
|
'-f', path.join(fixturesDir, 'hello-bake.hcl'),
|
||||||
|
'hello-matrix'
|
||||||
|
],
|
||||||
|
]
|
||||||
|
])('export bake build %p', async (_, bargs) => {
|
||||||
|
const buildx = new Buildx();
|
||||||
|
const bake = new Bake({buildx: buildx});
|
||||||
|
|
||||||
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
|
await expect(
|
||||||
|
(async () => {
|
||||||
|
// prettier-ignore
|
||||||
|
const buildCmd = await buildx.getCommand([
|
||||||
|
'--builder', process.env.CTN_BUILDER_NAME ?? 'default',
|
||||||
|
...bargs,
|
||||||
|
'--metadata-file', bake.getMetadataFilePath()
|
||||||
|
]);
|
||||||
|
await Exec.exec(buildCmd.command, buildCmd.args, {
|
||||||
|
cwd: fixturesDir
|
||||||
|
});
|
||||||
|
})()
|
||||||
|
).resolves.not.toThrow();
|
||||||
|
|
||||||
|
const metadata = bake.resolveMetadata();
|
||||||
|
expect(metadata).toBeDefined();
|
||||||
|
const buildRefs = bake.resolveRefs(metadata);
|
||||||
|
expect(buildRefs).toBeDefined();
|
||||||
|
|
||||||
|
const history = new History({buildx: buildx});
|
||||||
|
const exportRes = await history.export({
|
||||||
|
refs: buildRefs ?? []
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(exportRes).toBeDefined();
|
||||||
|
expect(exportRes?.dockerbuildFilename).toBeDefined();
|
||||||
|
expect(exportRes?.dockerbuildSize).toBeDefined();
|
||||||
|
expect(fs.existsSync(exportRes?.dockerbuildFilename)).toBe(true);
|
||||||
|
expect(exportRes?.summaries).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
42
__tests__/buildx/install.test.itg.ts
Normal file
42
__tests__/buildx/install.test.itg.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {describe, expect, test} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
import {Install} from '../../src/buildx/install';
|
||||||
|
|
||||||
|
const maybe = !process.env.GITHUB_ACTIONS || (process.env.GITHUB_ACTIONS === 'true' && process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) ? describe : describe.skip;
|
||||||
|
|
||||||
|
maybe('download', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each(['latest'])(
|
||||||
|
'install docker %s', async (version) => {
|
||||||
|
await expect((async () => {
|
||||||
|
const install = new Install({
|
||||||
|
standalone: true
|
||||||
|
});
|
||||||
|
const toolPath = await install.download(version);
|
||||||
|
if (!fs.existsSync(toolPath)) {
|
||||||
|
throw new Error('toolPath does not exist');
|
||||||
|
}
|
||||||
|
const binPath = await install.installStandalone(toolPath);
|
||||||
|
if (!fs.existsSync(binPath)) {
|
||||||
|
throw new Error('binPath does not exist');
|
||||||
|
}
|
||||||
|
})()).resolves.not.toThrow();
|
||||||
|
}, 60000);
|
||||||
|
});
|
||||||
192
__tests__/buildx/install.test.ts
Normal file
192
__tests__/buildx/install.test.ts
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {describe, expect, it, jest, test, beforeEach, afterEach} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as rimraf from 'rimraf';
|
||||||
|
import osm = require('os');
|
||||||
|
|
||||||
|
import {Install} from '../../src/buildx/install';
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'buildx-jest');
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
rimraf.sync(tmpDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('download', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
['v0.9.0', false],
|
||||||
|
['v0.10.5', true],
|
||||||
|
['latest', true]
|
||||||
|
])(
|
||||||
|
'acquires %p of buildx (standalone: %p)', async (version, standalone) => {
|
||||||
|
const install = new Install({standalone: standalone});
|
||||||
|
const toolPath = await install.download(version);
|
||||||
|
expect(fs.existsSync(toolPath)).toBe(true);
|
||||||
|
let buildxBin: string;
|
||||||
|
if (standalone) {
|
||||||
|
buildxBin = await install.installStandalone(toolPath, tmpDir);
|
||||||
|
} else {
|
||||||
|
buildxBin = await install.installPlugin(toolPath, tmpDir);
|
||||||
|
}
|
||||||
|
expect(fs.existsSync(buildxBin)).toBe(true);
|
||||||
|
},
|
||||||
|
100000
|
||||||
|
);
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
// following versions are already cached to htc from previous test cases
|
||||||
|
['v0.9.0'],
|
||||||
|
['v0.10.5'],
|
||||||
|
])(
|
||||||
|
'acquires %p of buildx with cache', async (version) => {
|
||||||
|
const install = new Install({standalone: false});
|
||||||
|
const toolPath = await install.download(version);
|
||||||
|
expect(fs.existsSync(toolPath)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
['v0.11.2'],
|
||||||
|
['v0.12.0'],
|
||||||
|
])(
|
||||||
|
'acquires %p of buildx without cache', async (version) => {
|
||||||
|
const install = new Install({standalone: false});
|
||||||
|
const toolPath = await install.download(version, true);
|
||||||
|
expect(fs.existsSync(toolPath)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: add tests for arm
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
['win32', 'x64'],
|
||||||
|
['win32', 'arm64'],
|
||||||
|
['darwin', 'x64'],
|
||||||
|
['darwin', 'arm64'],
|
||||||
|
['linux', 'x64'],
|
||||||
|
['linux', 'arm64'],
|
||||||
|
['linux', 'ppc64'],
|
||||||
|
['linux', 's390x'],
|
||||||
|
])(
|
||||||
|
'acquires buildx for %s/%s', async (os, arch) => {
|
||||||
|
jest.spyOn(osm, 'platform').mockImplementation(() => os as NodeJS.Platform);
|
||||||
|
jest.spyOn(osm, 'arch').mockImplementation(() => arch);
|
||||||
|
const install = new Install();
|
||||||
|
const buildxBin = await install.download('latest');
|
||||||
|
expect(fs.existsSync(buildxBin)).toBe(true);
|
||||||
|
},
|
||||||
|
100000
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('build', () => {
|
||||||
|
// eslint-disable-next-line jest/no-disabled-tests
|
||||||
|
it.skip('builds refs/pull/648/head', async () => {
|
||||||
|
const install = new Install();
|
||||||
|
const toolPath = await install.build('https://github.com/docker/buildx.git#refs/pull/648/head');
|
||||||
|
expect(fs.existsSync(toolPath)).toBe(true);
|
||||||
|
const buildxBin = await install.installStandalone(toolPath, tmpDir);
|
||||||
|
expect(fs.existsSync(buildxBin)).toBe(true);
|
||||||
|
}, 100000);
|
||||||
|
|
||||||
|
// eslint-disable-next-line jest/no-disabled-tests
|
||||||
|
it.skip('builds 67bd6f4dc82a9cd96f34133dab3f6f7af803bb14', async () => {
|
||||||
|
const install = new Install();
|
||||||
|
const toolPath = await install.build('https://github.com/docker/buildx.git#67bd6f4dc82a9cd96f34133dab3f6f7af803bb14');
|
||||||
|
expect(fs.existsSync(toolPath)).toBe(true);
|
||||||
|
const buildxBin = await install.installPlugin(toolPath, tmpDir);
|
||||||
|
expect(fs.existsSync(buildxBin)).toBe(true);
|
||||||
|
}, 100000);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getDownloadVersion', () => {
|
||||||
|
it('returns official latest download version', async () => {
|
||||||
|
const version = await Install.getDownloadVersion('latest');
|
||||||
|
expect(version.key).toEqual('official');
|
||||||
|
expect(version.version).toEqual('latest');
|
||||||
|
expect(version.downloadURL).toEqual('https://github.com/docker/buildx/releases/download/v%s/%s');
|
||||||
|
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns official v0.10.1 download version', async () => {
|
||||||
|
const version = await Install.getDownloadVersion('v0.10.1');
|
||||||
|
expect(version.key).toEqual('official');
|
||||||
|
expect(version.version).toEqual('v0.10.1');
|
||||||
|
expect(version.downloadURL).toEqual('https://github.com/docker/buildx/releases/download/v%s/%s');
|
||||||
|
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns lab latest download version', async () => {
|
||||||
|
const version = await Install.getDownloadVersion('lab:latest');
|
||||||
|
expect(version.key).toEqual('lab');
|
||||||
|
expect(version.version).toEqual('latest');
|
||||||
|
expect(version.downloadURL).toEqual('https://github.com/docker/buildx-desktop/releases/download/v%s/%s');
|
||||||
|
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-lab-releases.json');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns lab v0.11.2-desktop.2 download version', async () => {
|
||||||
|
const version = await Install.getDownloadVersion('lab:v0.11.2-desktop.2');
|
||||||
|
expect(version.key).toEqual('lab');
|
||||||
|
expect(version.version).toEqual('v0.11.2-desktop.2');
|
||||||
|
expect(version.downloadURL).toEqual('https://github.com/docker/buildx-desktop/releases/download/v%s/%s');
|
||||||
|
expect(version.releasesURL).toEqual('https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-lab-releases.json');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('unknown repo', async () => {
|
||||||
|
await expect(Install.getDownloadVersion('foo:bar')).rejects.toThrow(new Error('Cannot find buildx version for foo:bar'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getRelease', () => {
|
||||||
|
it('returns latest official GitHub release', async () => {
|
||||||
|
const version = await Install.getDownloadVersion('latest');
|
||||||
|
const release = await Install.getRelease(version);
|
||||||
|
expect(release).not.toBeNull();
|
||||||
|
expect(release?.tag_name).not.toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns v0.10.1 official GitHub release', async () => {
|
||||||
|
const version = await Install.getDownloadVersion('v0.10.1');
|
||||||
|
const release = await Install.getRelease(version);
|
||||||
|
expect(release).not.toBeNull();
|
||||||
|
expect(release?.id).toEqual(90346950);
|
||||||
|
expect(release?.tag_name).toEqual('v0.10.1');
|
||||||
|
expect(release?.html_url).toEqual('https://github.com/docker/buildx/releases/tag/v0.10.1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns v0.11.2-desktop.2 lab GitHub release', async () => {
|
||||||
|
const version = await Install.getDownloadVersion('lab:v0.11.2-desktop.2');
|
||||||
|
const release = await Install.getRelease(version);
|
||||||
|
expect(release).not.toBeNull();
|
||||||
|
expect(release?.id).toEqual(118213369);
|
||||||
|
expect(release?.tag_name).toEqual('v0.11.2-desktop.2');
|
||||||
|
expect(release?.html_url).toEqual('https://github.com/docker/buildx-desktop/releases/tag/v0.11.2-desktop.2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('unknown release', async () => {
|
||||||
|
const version = await Install.getDownloadVersion('foo');
|
||||||
|
await expect(Install.getRelease(version)).rejects.toThrow(new Error('Cannot find Buildx release foo in https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/buildx-releases.json'));
|
||||||
|
});
|
||||||
|
});
|
||||||
40
__tests__/cache.test.itg.ts
Normal file
40
__tests__/cache.test.itg.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2024 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import path from 'path';
|
||||||
|
import {describe, expect, it} from '@jest/globals';
|
||||||
|
|
||||||
|
import {Cache} from '../src/cache';
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'cache-jest');
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, 'fixtures');
|
||||||
|
|
||||||
|
describe('cache', () => {
|
||||||
|
it('github-repo', async () => {
|
||||||
|
const r = (Math.random() + 1).toString(36).substring(7);
|
||||||
|
const htcName = `cache-test-github-repo-${r}`;
|
||||||
|
const c = new Cache({
|
||||||
|
htcName: htcName,
|
||||||
|
htcVersion: `v1.0.0+${r}`,
|
||||||
|
baseCacheDir: path.join(tmpDir, '.cache-test'),
|
||||||
|
cacheFile: 'github-repo.json'
|
||||||
|
});
|
||||||
|
expect(await c.save(path.join(fixturesDir, 'github-repo.json'))).not.toEqual('');
|
||||||
|
expect(await c.find()).not.toEqual('');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -14,23 +14,25 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import path from 'path';
|
import * as path from 'path';
|
||||||
import rimraf from 'rimraf';
|
import * as rimraf from 'rimraf';
|
||||||
import {describe, expect, jest, it, beforeEach, afterEach} from '@jest/globals';
|
import {describe, expect, jest, it, beforeEach, afterEach} from '@jest/globals';
|
||||||
|
|
||||||
import {Context} from '../src/context';
|
import {Context} from '../src/context';
|
||||||
|
|
||||||
const tmpDir = path.join('/tmp/.docker-actions-toolkit-jest').split(path.sep).join(path.posix.sep);
|
// prettier-ignore
|
||||||
const tmpName = path.join(tmpDir, '.tmpname-jest').split(path.sep).join(path.posix.sep);
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'context-jest');
|
||||||
|
const tmpName = path.join(tmpDir, '.tmpname-jest');
|
||||||
|
|
||||||
jest.spyOn(Context.prototype, 'tmpDir').mockImplementation((): string => {
|
jest.spyOn(Context, 'tmpDir').mockImplementation((): string => {
|
||||||
if (!fs.existsSync(tmpDir)) {
|
if (!fs.existsSync(tmpDir)) {
|
||||||
fs.mkdirSync(tmpDir, {recursive: true});
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
}
|
}
|
||||||
return tmpDir;
|
return tmpDir;
|
||||||
});
|
});
|
||||||
jest.spyOn(Context.prototype, 'tmpName').mockImplementation((): string => {
|
|
||||||
|
jest.spyOn(Context, 'tmpName').mockImplementation((): string => {
|
||||||
return tmpName;
|
return tmpName;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -42,16 +44,14 @@ afterEach(() => {
|
|||||||
rimraf.sync(tmpDir);
|
rimraf.sync(tmpDir);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('gitContext', () => {
|
describe('gitRef', () => {
|
||||||
it('returns refs/heads/master', async () => {
|
it('returns refs/heads/master', async () => {
|
||||||
const context = new Context();
|
expect(Context.gitRef()).toEqual('refs/heads/master');
|
||||||
expect(context.buildGitContext).toEqual('https://github.com/docker/actions-toolkit.git#refs/heads/master');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('provenanceBuilderID', () => {
|
describe('gitContext', () => {
|
||||||
it('returns 123', async () => {
|
it('returns refs/heads/master', async () => {
|
||||||
const context = new Context();
|
expect(Context.gitContext()).toEqual('https://github.com/docker/actions-toolkit.git#refs/heads/master');
|
||||||
expect(context.provenanceBuilderID).toEqual('https://github.com/docker/actions-toolkit/actions/runs/123');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2023 actions-toolkit authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {beforeEach, describe, expect, it, jest} from '@jest/globals';
|
|
||||||
import * as exec from '@actions/exec';
|
|
||||||
|
|
||||||
import {Docker} from '../src/docker';
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isAvailable', () => {
|
|
||||||
it('cli', () => {
|
|
||||||
const execSpy = jest.spyOn(exec, 'getExecOutput');
|
|
||||||
Docker.isAvailable();
|
|
||||||
// eslint-disable-next-line jest/no-standalone-expect
|
|
||||||
expect(execSpy).toHaveBeenCalledWith(`docker`, undefined, {
|
|
||||||
silent: true,
|
|
||||||
ignoreReturnCode: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('printVersion', () => {
|
|
||||||
it('docker cli', () => {
|
|
||||||
const execSpy = jest.spyOn(exec, 'exec');
|
|
||||||
Docker.printVersion(false).catch(() => {
|
|
||||||
// noop
|
|
||||||
});
|
|
||||||
expect(execSpy).toHaveBeenCalledWith(`docker`, ['version'], {
|
|
||||||
failOnStdErr: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('standalone', () => {
|
|
||||||
const execSpy = jest.spyOn(exec, 'exec');
|
|
||||||
Docker.printVersion(true).catch(() => {
|
|
||||||
// noop
|
|
||||||
});
|
|
||||||
expect(execSpy).not.toHaveBeenCalledWith(`docker`, ['version'], {
|
|
||||||
failOnStdErr: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('printInfo', () => {
|
|
||||||
it('docker cli', () => {
|
|
||||||
const execSpy = jest.spyOn(exec, 'exec');
|
|
||||||
Docker.printInfo(false).catch(() => {
|
|
||||||
// noop
|
|
||||||
});
|
|
||||||
expect(execSpy).toHaveBeenCalledWith(`docker`, ['info'], {
|
|
||||||
failOnStdErr: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('standalone', () => {
|
|
||||||
const execSpy = jest.spyOn(exec, 'exec');
|
|
||||||
Docker.printInfo(true).catch(() => {
|
|
||||||
// noop
|
|
||||||
});
|
|
||||||
expect(execSpy).not.toHaveBeenCalledWith(`docker`, ['info'], {
|
|
||||||
failOnStdErr: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
56
__tests__/docker/docker.test.itg.ts
Normal file
56
__tests__/docker/docker.test.itg.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2024 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {describe, expect, test} from '@jest/globals';
|
||||||
|
|
||||||
|
import {Docker} from '../../src/docker/docker';
|
||||||
|
|
||||||
|
const maybe = !process.env.GITHUB_ACTIONS || (process.env.GITHUB_ACTIONS === 'true' && process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) ? describe : describe.skip;
|
||||||
|
|
||||||
|
maybe('pull', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
'busybox',
|
||||||
|
undefined,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'busybox:1.36',
|
||||||
|
undefined,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'busybox@sha256:7ae8447f3a7f5bccaa765926f25fc038e425cf1b2be6748727bbea9a13102094',
|
||||||
|
undefined,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'doesnotexist:foo',
|
||||||
|
`pull access denied for doesnotexist`,
|
||||||
|
],
|
||||||
|
])('pulling %p', async (image: string, err: string | undefined) => {
|
||||||
|
try {
|
||||||
|
await Docker.pull(image, true);
|
||||||
|
if (err !== undefined) {
|
||||||
|
throw new Error('Expected an error to be thrown');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (err === undefined) {
|
||||||
|
throw new Error(`Expected no error, but got: ${e.message}`);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line jest/no-conditional-expect
|
||||||
|
expect(e.message).toContain(err);
|
||||||
|
}
|
||||||
|
}, 600000);
|
||||||
|
});
|
||||||
143
__tests__/docker/docker.test.ts
Normal file
143
__tests__/docker/docker.test.ts
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {afterEach, beforeEach, describe, expect, it, jest} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import * as io from '@actions/io';
|
||||||
|
import osm = require('os');
|
||||||
|
import * as rimraf from 'rimraf';
|
||||||
|
|
||||||
|
import {Docker} from '../../src/docker/docker';
|
||||||
|
import {Exec} from '../../src/exec';
|
||||||
|
|
||||||
|
import {ConfigFile} from '../../src/types/docker/docker';
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'docker-jest');
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
rimraf.sync(tmpDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('configDir', () => {
|
||||||
|
const originalEnv = process.env;
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
DOCKER_CONFIG: '/var/docker/config'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = originalEnv;
|
||||||
|
});
|
||||||
|
it('returns default', async () => {
|
||||||
|
process.env.DOCKER_CONFIG = '';
|
||||||
|
jest.spyOn(osm, 'homedir').mockImplementation(() => path.join('/tmp', 'home'));
|
||||||
|
expect(Docker.configDir).toEqual(path.join('/tmp', 'home', '.docker'));
|
||||||
|
});
|
||||||
|
it('returns from env', async () => {
|
||||||
|
expect(Docker.configDir).toEqual('/var/docker/config');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('configFile', () => {
|
||||||
|
const originalEnv = process.env;
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
if (!fs.existsSync(tmpDir)) {
|
||||||
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
|
}
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
DOCKER_CONFIG: tmpDir
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = originalEnv;
|
||||||
|
});
|
||||||
|
it('auths', async () => {
|
||||||
|
fs.copyFileSync(path.join(fixturesDir, 'docker-config-auths.json'), path.join(tmpDir, 'config.json'));
|
||||||
|
expect(Docker.configFile()).toEqual({
|
||||||
|
auths: {
|
||||||
|
'https://index.docker.io/v1/': {
|
||||||
|
auth: 'am9lam9lOmhlbGxv',
|
||||||
|
email: 'user@example.com'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as unknown as ConfigFile);
|
||||||
|
});
|
||||||
|
it('proxies', async () => {
|
||||||
|
fs.copyFileSync(path.join(fixturesDir, 'docker-config-proxies.json'), path.join(tmpDir, 'config.json'));
|
||||||
|
expect(Docker.configFile()).toEqual({
|
||||||
|
proxies: {
|
||||||
|
default: {
|
||||||
|
httpProxy: 'http://127.0.0.1:3128',
|
||||||
|
httpsProxy: 'http://127.0.0.1:3128'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as unknown as ConfigFile);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isAvailable', () => {
|
||||||
|
it('cli', async () => {
|
||||||
|
const ioWhichSpy = jest.spyOn(io, 'which');
|
||||||
|
await Docker.isAvailable();
|
||||||
|
expect(ioWhichSpy).toHaveBeenCalledTimes(1);
|
||||||
|
expect(ioWhichSpy).toHaveBeenCalledWith('docker', true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('context', () => {
|
||||||
|
it('call docker context show', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'getExecOutput');
|
||||||
|
await Docker.context().catch(() => {
|
||||||
|
// noop
|
||||||
|
});
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`docker`, ['context', 'inspect', '--format', '{{.Name}}'], {
|
||||||
|
ignoreReturnCode: true,
|
||||||
|
silent: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('printVersion', () => {
|
||||||
|
it('call docker version', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'exec');
|
||||||
|
await Docker.printVersion().catch(() => {
|
||||||
|
// noop
|
||||||
|
});
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`docker`, ['version']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('printInfo', () => {
|
||||||
|
it('call docker info', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'exec');
|
||||||
|
await Docker.printInfo().catch(() => {
|
||||||
|
// noop
|
||||||
|
});
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`docker`, ['info']);
|
||||||
|
});
|
||||||
|
});
|
||||||
69
__tests__/docker/install.test.itg.ts
Normal file
69
__tests__/docker/install.test.itg.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import path from 'path';
|
||||||
|
import {jest, describe, expect, test, beforeEach, afterEach} from '@jest/globals';
|
||||||
|
|
||||||
|
import {Install} from '../../src/docker/install';
|
||||||
|
import {Docker} from '../../src/docker/docker';
|
||||||
|
import {Exec} from '../../src/exec';
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'docker-install-jest');
|
||||||
|
|
||||||
|
describe('install', () => {
|
||||||
|
const originalEnv = process.env;
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
LIMA_START_ARGS: '--cpus 4 --memory 8',
|
||||||
|
LIMA_IMAGES: `x86_64:https://cloud.debian.org/images/cloud/bookworm/20231013-1532/debian-12-genericcloud-amd64-20231013-1532.qcow2@sha512:6b55e88b027c14da1b55c85a25a9f7069d4560a8fdb2d948c986a585db469728a06d2c528303e34bb62d8b2984def38fd9ddfc00965846ff6e05b01d6e883bfe
|
||||||
|
aarch64:https://cloud.debian.org/images/cloud/bookworm/20231013-1532/debian-12-genericcloud-arm64-20231013-1532.qcow2`
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = originalEnv;
|
||||||
|
});
|
||||||
|
// prettier-ignore
|
||||||
|
test.each(['v26.1.4'])(
|
||||||
|
'install docker %s', async (version) => {
|
||||||
|
if (process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) {
|
||||||
|
// Remove containerd first on ubuntu runners to make sure it takes
|
||||||
|
// ones packaged with docker
|
||||||
|
await Exec.exec('sudo', ['apt-get', 'remove', '-y', 'containerd.io'], {
|
||||||
|
env: Object.assign({}, process.env, {
|
||||||
|
DEBIAN_FRONTEND: 'noninteractive'
|
||||||
|
}) as {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await expect((async () => {
|
||||||
|
const install = new Install({
|
||||||
|
version: version,
|
||||||
|
runDir: tmpDir,
|
||||||
|
contextName: 'foo',
|
||||||
|
daemonConfig: `{"debug":true,"features":{"containerd-snapshotter":true}}`
|
||||||
|
});
|
||||||
|
await install.download();
|
||||||
|
await install.install();
|
||||||
|
await Docker.printVersion();
|
||||||
|
await Docker.printInfo();
|
||||||
|
await install.tearDown();
|
||||||
|
})()).resolves.not.toThrow();
|
||||||
|
}, 1200000);
|
||||||
|
});
|
||||||
102
__tests__/docker/install.test.ts
Normal file
102
__tests__/docker/install.test.ts
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {describe, expect, jest, test, beforeEach, afterEach, it} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as rimraf from 'rimraf';
|
||||||
|
import osm = require('os');
|
||||||
|
|
||||||
|
import {Install} from '../../src/docker/install';
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'docker-install-jest');
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
rimraf.sync(tmpDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('download', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
['v19.03.14', 'linux'],
|
||||||
|
['v20.10.22', 'linux'],
|
||||||
|
['v20.10.22', 'darwin'],
|
||||||
|
['v20.10.22', 'win32'],
|
||||||
|
])(
|
||||||
|
'acquires %p of docker (%s)', async (version, platformOS) => {
|
||||||
|
jest.spyOn(osm, 'platform').mockImplementation(() => platformOS as NodeJS.Platform);
|
||||||
|
const install = new Install({
|
||||||
|
version: version,
|
||||||
|
runDir: tmpDir,
|
||||||
|
});
|
||||||
|
const toolPath = await install.download();
|
||||||
|
expect(fs.existsSync(toolPath)).toBe(true);
|
||||||
|
}, 100000);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getRelease', () => {
|
||||||
|
it('returns latest docker GitHub release', async () => {
|
||||||
|
const release = await Install.getRelease('latest');
|
||||||
|
expect(release).not.toBeNull();
|
||||||
|
expect(release?.tag_name).not.toEqual('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns v23.0.0 buildx GitHub release', async () => {
|
||||||
|
const release = await Install.getRelease('v23.0.0');
|
||||||
|
expect(release).not.toBeNull();
|
||||||
|
expect(release?.id).toEqual(91109643);
|
||||||
|
expect(release?.tag_name).toEqual('v23.0.0');
|
||||||
|
expect(release?.html_url).toEqual('https://github.com/moby/moby/releases/tag/v23.0.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('unknown release', async () => {
|
||||||
|
await expect(Install.getRelease('foo')).rejects.toThrow(new Error('Cannot find Docker release foo in https://raw.githubusercontent.com/docker/actions-toolkit/main/.github/docker-releases.json'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('limaImage', () => {
|
||||||
|
const originalEnv = process.env;
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
LIMA_IMAGES: `x86_64:https://cloud-images.ubuntu.com/releases/23.10/release-20231011/ubuntu-23.10-server-cloudimg-amd64.img@sha256:f6529be56da3429a56e4f5ef202bf4958201bc63f8541e478caa6e8eb712e635
|
||||||
|
aarch64:https://cloud-images.ubuntu.com/releases/23.10/release-20231011/ubuntu-23.10-server-cloudimg-arm64.img`
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = originalEnv;
|
||||||
|
});
|
||||||
|
it('returns custom images', async () => {
|
||||||
|
expect(Install.limaCustomImages()).toEqual([
|
||||||
|
{
|
||||||
|
location: 'https://cloud-images.ubuntu.com/releases/23.10/release-20231011/ubuntu-23.10-server-cloudimg-amd64.img',
|
||||||
|
arch: 'x86_64',
|
||||||
|
digest: 'sha256:f6529be56da3429a56e4f5ef202bf4958201bc63f8541e478caa6e8eb712e635'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
location: 'https://cloud-images.ubuntu.com/releases/23.10/release-20231011/ubuntu-23.10-server-cloudimg-arm64.img',
|
||||||
|
arch: 'aarch64',
|
||||||
|
digest: ''
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
121
__tests__/dockerhub.test.ts
Normal file
121
__tests__/dockerhub.test.ts
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {describe, expect, jest, it, beforeEach} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
import {DockerHub} from '../src/dockerhub';
|
||||||
|
import {RepositoryResponse, RepositoryTagsResponse} from '../src/types/dockerhub';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
import repoInfoFixture from './fixtures/dockerhub-repoinfo.json';
|
||||||
|
import repoTagsFixture from './fixtures/dockerhub-repotags.json';
|
||||||
|
import repoAllTagsFixture from './fixtures/dockerhub-repoalltags.json';
|
||||||
|
|
||||||
|
describe('getRepository', () => {
|
||||||
|
it('returns repo info', async () => {
|
||||||
|
jest.spyOn(DockerHub.prototype, 'getRepository').mockImplementation((): Promise<RepositoryResponse> => {
|
||||||
|
return <Promise<RepositoryResponse>>(repoInfoFixture as unknown);
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
jest.spyOn(DockerHub as any, 'login').mockReturnValue('jwt_token');
|
||||||
|
const dockerhub = await DockerHub.build({
|
||||||
|
credentials: {
|
||||||
|
username: 'foo',
|
||||||
|
password: '0123456-7890-0000-1111-222222222'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const repoinfo = await dockerhub.getRepository({
|
||||||
|
namespace: 'foo',
|
||||||
|
name: 'bar'
|
||||||
|
});
|
||||||
|
expect(repoinfo.namespace).toEqual('foo');
|
||||||
|
expect(repoinfo.name).toEqual('bar');
|
||||||
|
expect(repoinfo.repository_type).toEqual('image');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getRepositoryTags', () => {
|
||||||
|
it('return repo tags', async () => {
|
||||||
|
jest.spyOn(DockerHub.prototype, 'getRepositoryTags').mockImplementation((): Promise<RepositoryTagsResponse> => {
|
||||||
|
return <Promise<RepositoryTagsResponse>>(repoTagsFixture as unknown);
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
jest.spyOn(DockerHub as any, 'login').mockReturnValue('jwt_token');
|
||||||
|
const dockerhub = await DockerHub.build({
|
||||||
|
credentials: {
|
||||||
|
username: 'foo',
|
||||||
|
password: '0123456-7890-0000-1111-222222222'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const resp = await dockerhub.getRepositoryTags({
|
||||||
|
namespace: 'crazymax',
|
||||||
|
name: 'diun'
|
||||||
|
});
|
||||||
|
expect(resp.count).toBeGreaterThan(0);
|
||||||
|
expect(resp.next).not.toBeNull();
|
||||||
|
expect(resp.results.length).toBeGreaterThan(0);
|
||||||
|
expect(resp.results[0].last_updater_username).toEqual('crazymax');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getRepositoryAllTags', () => {
|
||||||
|
it('return repo all tags', async () => {
|
||||||
|
jest.spyOn(DockerHub.prototype, 'getRepositoryAllTags').mockImplementation((): Promise<RepositoryTagsResponse> => {
|
||||||
|
return <Promise<RepositoryTagsResponse>>(repoAllTagsFixture as unknown);
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
jest.spyOn(DockerHub as any, 'login').mockReturnValue('jwt_token');
|
||||||
|
const dockerhub = await DockerHub.build({
|
||||||
|
credentials: {
|
||||||
|
username: 'foo',
|
||||||
|
password: '0123456-7890-0000-1111-222222222'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const resp = await dockerhub.getRepositoryAllTags({
|
||||||
|
namespace: 'crazymax',
|
||||||
|
name: 'diun'
|
||||||
|
});
|
||||||
|
expect(resp.count).toBeGreaterThan(0);
|
||||||
|
expect(resp.next).toBeNull();
|
||||||
|
expect(resp.results.length).toBeGreaterThan(0);
|
||||||
|
expect(resp.results[0].last_updater_username).toEqual('crazymax');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updateRepoDescription', () => {
|
||||||
|
it.skip('set repo description', async () => {
|
||||||
|
const dockerhub = await DockerHub.build({
|
||||||
|
credentials: {
|
||||||
|
username: 'foo',
|
||||||
|
password: 'bar'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const resp = await dockerhub.updateRepoDescription({
|
||||||
|
namespace: 'crazymax',
|
||||||
|
name: 'test-toolkit',
|
||||||
|
description: 'Hello-World',
|
||||||
|
full_description: fs.readFileSync(path.join(__dirname, '..', 'README.md'), 'utf-8')
|
||||||
|
});
|
||||||
|
expect(resp.namespace).toEqual('foo');
|
||||||
|
expect(resp.name).toEqual('bar');
|
||||||
|
expect(resp.description).toEqual('Hello-World');
|
||||||
|
});
|
||||||
|
});
|
||||||
51
__tests__/exec.test.ts
Normal file
51
__tests__/exec.test.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {beforeEach, describe, expect, it, jest} from '@jest/globals';
|
||||||
|
|
||||||
|
import {Exec} from '../src/exec';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('exec', () => {
|
||||||
|
it('returns docker version', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'exec');
|
||||||
|
await Exec.exec('docker', ['version'], {
|
||||||
|
ignoreReturnCode: true,
|
||||||
|
silent: true
|
||||||
|
});
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`docker`, ['version'], {
|
||||||
|
ignoreReturnCode: true,
|
||||||
|
silent: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getExecOutput', () => {
|
||||||
|
it('returns docker version', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'getExecOutput');
|
||||||
|
await Exec.getExecOutput('docker', ['version'], {
|
||||||
|
ignoreReturnCode: true,
|
||||||
|
silent: true
|
||||||
|
});
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`docker`, ['version'], {
|
||||||
|
ignoreReturnCode: true,
|
||||||
|
silent: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
29
__tests__/fixtures/bake-01-overrides.json
Normal file
29
__tests__/fixtures/bake-01-overrides.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"group": {
|
||||||
|
"default": {
|
||||||
|
"targets": [
|
||||||
|
"image"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"image": {
|
||||||
|
"context": ".",
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"args": {
|
||||||
|
"BUILDKIT_CONTEXT_KEEP_GIT_DIR": "1",
|
||||||
|
"GO_VERSION": "1.20"
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"docker/buildx-bin:local"
|
||||||
|
],
|
||||||
|
"target": "binaries",
|
||||||
|
"platforms": [
|
||||||
|
"linux/amd64"
|
||||||
|
],
|
||||||
|
"output": [
|
||||||
|
"type=docker"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
55
__tests__/fixtures/bake-01-validate.json
Normal file
55
__tests__/fixtures/bake-01-validate.json
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"group": {
|
||||||
|
"default": {
|
||||||
|
"targets": [
|
||||||
|
"validate"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"validate": {
|
||||||
|
"targets": [
|
||||||
|
"lint",
|
||||||
|
"validate-vendor",
|
||||||
|
"validate-docs"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"lint": {
|
||||||
|
"context": ".",
|
||||||
|
"dockerfile": "./hack/dockerfiles/lint.Dockerfile",
|
||||||
|
"args": {
|
||||||
|
"BUILDKIT_CONTEXT_KEEP_GIT_DIR": "1",
|
||||||
|
"GO_VERSION": "1.20"
|
||||||
|
},
|
||||||
|
"output": [
|
||||||
|
"type=cacheonly"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"validate-docs": {
|
||||||
|
"context": ".",
|
||||||
|
"dockerfile": "./hack/dockerfiles/docs.Dockerfile",
|
||||||
|
"args": {
|
||||||
|
"BUILDKIT_CONTEXT_KEEP_GIT_DIR": "1",
|
||||||
|
"BUILDX_EXPERIMENTAL": "1",
|
||||||
|
"FORMATS": "md",
|
||||||
|
"GO_VERSION": "1.20"
|
||||||
|
},
|
||||||
|
"target": "validate",
|
||||||
|
"output": [
|
||||||
|
"type=cacheonly"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"validate-vendor": {
|
||||||
|
"context": ".",
|
||||||
|
"dockerfile": "./hack/dockerfiles/vendor.Dockerfile",
|
||||||
|
"args": {
|
||||||
|
"BUILDKIT_CONTEXT_KEEP_GIT_DIR": "1",
|
||||||
|
"GO_VERSION": "1.20"
|
||||||
|
},
|
||||||
|
"target": "validate",
|
||||||
|
"output": [
|
||||||
|
"type=cacheonly"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
172
__tests__/fixtures/bake-01.hcl
Normal file
172
__tests__/fixtures/bake-01.hcl
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
// Copyright 2023 actions-toolkit authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
variable "GO_VERSION" {
|
||||||
|
default = "1.20"
|
||||||
|
}
|
||||||
|
variable "DOCS_FORMATS" {
|
||||||
|
default = "md"
|
||||||
|
}
|
||||||
|
variable "DESTDIR" {
|
||||||
|
default = "./bin"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Special target: https://github.com/docker/metadata-action#bake-definition
|
||||||
|
target "meta-helper" {
|
||||||
|
tags = ["docker/buildx-bin:local"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "_common" {
|
||||||
|
args = {
|
||||||
|
GO_VERSION = GO_VERSION
|
||||||
|
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group "default" {
|
||||||
|
targets = ["binaries"]
|
||||||
|
}
|
||||||
|
|
||||||
|
group "validate" {
|
||||||
|
targets = ["lint", "validate-vendor", "validate-docs"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "lint" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
dockerfile = "./hack/dockerfiles/lint.Dockerfile"
|
||||||
|
output = ["type=cacheonly"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "validate-vendor" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
|
||||||
|
target = "validate"
|
||||||
|
output = ["type=cacheonly"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "validate-docs" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
args = {
|
||||||
|
FORMATS = DOCS_FORMATS
|
||||||
|
BUILDX_EXPERIMENTAL = 1 // enables experimental cmds/flags for docs generation
|
||||||
|
}
|
||||||
|
dockerfile = "./hack/dockerfiles/docs.Dockerfile"
|
||||||
|
target = "validate"
|
||||||
|
output = ["type=cacheonly"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "validate-authors" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
dockerfile = "./hack/dockerfiles/authors.Dockerfile"
|
||||||
|
target = "validate"
|
||||||
|
output = ["type=cacheonly"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "validate-generated-files" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
dockerfile = "./hack/dockerfiles/generated-files.Dockerfile"
|
||||||
|
target = "validate"
|
||||||
|
output = ["type=cacheonly"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "update-vendor" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
|
||||||
|
target = "update"
|
||||||
|
output = ["."]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "update-docs" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
args = {
|
||||||
|
FORMATS = DOCS_FORMATS
|
||||||
|
BUILDX_EXPERIMENTAL = 1 // enables experimental cmds/flags for docs generation
|
||||||
|
}
|
||||||
|
dockerfile = "./hack/dockerfiles/docs.Dockerfile"
|
||||||
|
target = "update"
|
||||||
|
output = ["./docs/reference"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "update-authors" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
dockerfile = "./hack/dockerfiles/authors.Dockerfile"
|
||||||
|
target = "update"
|
||||||
|
output = ["."]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "update-generated-files" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
dockerfile = "./hack/dockerfiles/generated-files.Dockerfile"
|
||||||
|
target = "update"
|
||||||
|
output = ["."]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "mod-outdated" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
|
||||||
|
target = "outdated"
|
||||||
|
no-cache-filter = ["outdated"]
|
||||||
|
output = ["type=cacheonly"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "test" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
target = "test-coverage"
|
||||||
|
output = ["${DESTDIR}/coverage"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "binaries" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
target = "binaries"
|
||||||
|
output = ["${DESTDIR}/build"]
|
||||||
|
platforms = ["local"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "binaries-cross" {
|
||||||
|
inherits = ["binaries"]
|
||||||
|
platforms = [
|
||||||
|
"darwin/amd64",
|
||||||
|
"darwin/arm64",
|
||||||
|
"linux/amd64",
|
||||||
|
"linux/arm/v6",
|
||||||
|
"linux/arm/v7",
|
||||||
|
"linux/arm64",
|
||||||
|
"linux/ppc64le",
|
||||||
|
"linux/riscv64",
|
||||||
|
"linux/s390x",
|
||||||
|
"windows/amd64",
|
||||||
|
"windows/arm64"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "release" {
|
||||||
|
inherits = ["binaries-cross"]
|
||||||
|
target = "release"
|
||||||
|
output = ["${DESTDIR}/release"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "image" {
|
||||||
|
inherits = ["meta-helper", "binaries"]
|
||||||
|
output = ["type=image"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "image-cross" {
|
||||||
|
inherits = ["meta-helper", "binaries-cross"]
|
||||||
|
output = ["type=image"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "image-local" {
|
||||||
|
inherits = ["image"]
|
||||||
|
output = ["type=docker"]
|
||||||
|
}
|
||||||
20
__tests__/fixtures/bake-02-build.json
Normal file
20
__tests__/fixtures/bake-02-build.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"group": {
|
||||||
|
"default": {
|
||||||
|
"targets": [
|
||||||
|
"build"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"build": {
|
||||||
|
"context": ".",
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"args": {
|
||||||
|
"BUILDKIT_CONTEXT_KEEP_GIT_DIR": "1",
|
||||||
|
"GO_VERSION": "1.20"
|
||||||
|
},
|
||||||
|
"target": "build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
__tests__/fixtures/bake-02.hcl
Normal file
33
__tests__/fixtures/bake-02.hcl
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2023 actions-toolkit authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
variable "GO_VERSION" {
|
||||||
|
default = "1.20"
|
||||||
|
}
|
||||||
|
|
||||||
|
target "_common" {
|
||||||
|
args = {
|
||||||
|
GO_VERSION = GO_VERSION
|
||||||
|
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group "default" {
|
||||||
|
targets = ["build"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "build" {
|
||||||
|
inherits = ["_common"]
|
||||||
|
target = "build"
|
||||||
|
}
|
||||||
36
__tests__/fixtures/bake-buildx-0.10.4-binaries-cross.json
Normal file
36
__tests__/fixtures/bake-buildx-0.10.4-binaries-cross.json
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"group": {
|
||||||
|
"default": {
|
||||||
|
"targets": [
|
||||||
|
"binaries-cross"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"binaries-cross": {
|
||||||
|
"context": "https://github.com/docker/buildx.git#v0.10.4",
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"args": {
|
||||||
|
"BUILDKIT_CONTEXT_KEEP_GIT_DIR": "1",
|
||||||
|
"GO_VERSION": "1.19"
|
||||||
|
},
|
||||||
|
"target": "binaries",
|
||||||
|
"platforms": [
|
||||||
|
"darwin/amd64",
|
||||||
|
"darwin/arm64",
|
||||||
|
"linux/amd64",
|
||||||
|
"linux/arm/v6",
|
||||||
|
"linux/arm/v7",
|
||||||
|
"linux/arm64",
|
||||||
|
"linux/ppc64le",
|
||||||
|
"linux/riscv64",
|
||||||
|
"linux/s390x",
|
||||||
|
"windows/amd64",
|
||||||
|
"windows/arm64"
|
||||||
|
],
|
||||||
|
"output": [
|
||||||
|
"./bin/build"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"target": {
|
||||||
|
"default": {
|
||||||
|
"context": "https://github.com/docker/test-docker-action.git#remote-private",
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"tags": [
|
||||||
|
"foo"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"Definition":"eyJncm91cCI6eyJkZWZhdWx0Ijp7InRhcmdldHMiOlsiZGV2Il19fSwidGFyZ2V0Ijp7ImRldiI6eyJjb250ZXh0IjoiLiIsImRvY2tlcmZpbGUiOiJEb2NrZXJmaWxlIiwiYXJncyI6eyJCVUlMREtJVF9DT05URVhUX0tFRVBfR0lUX0RJUiI6IjEiLCJERUZBVUxUX1BST0RVQ1RfTElDRU5TRSI6IiIsIkRPQ0tFUl9CVUlMRFRBR1MiOiIiLCJET0NLRVJfREVCVUciOiIiLCJET0NLRVJfTERGTEFHUyI6IiIsIkRPQ0tFUl9TVEFUSUMiOiIxIiwiUEFDS0FHRVJfTkFNRSI6IiIsIlBMQVRGT1JNIjoiIiwiUFJPRFVDVCI6IiIsIlNZU1RFTUQiOiJmYWxzZSIsIlZFUlNJT04iOiIifSwidGFncyI6WyJkb2NrZXItZGV2Il0sInRhcmdldCI6ImRldiIsIm91dHB1dCI6WyJ0eXBlPWRvY2tlciJdfX19","Targets":["dev"],"Refs":["vzxn0jxr44khtq7hc8drtzwjv"]}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"LocalPath":"/home/crazymax/github/docker/docker-alpine-s6","DockerfilePath":""}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":""}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":"/home/crazymax/github/docker_org/buildx/Dockerfile"}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":"/home/crazymax/github/docker_org/buildx/Dockerfile"}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":""}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":"/home/crazymax/github/docker_org/buildx/Dockerfile"}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"LocalPath":"/home/crazymax/github/docker_org/buildx","DockerfilePath":""}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"Target":"dev","LocalPath":"/home/crazymax/github/docker_org/docker","DockerfilePath":"/home/crazymax/github/docker_org/docker/Dockerfile","GroupRef":"1fugf958r4peyg86h6scim5t5"}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"Target":"default","LocalPath":"/home/crazymax/github/docker_org/compose/.dev/47231","DockerfilePath":"/home/crazymax/github/docker_org/compose/.dev/47231/bad/Dockerfile"}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"Target":"default","LocalPath":"/home/crazymax/github/docker_org/compose/.dev/47231","DockerfilePath":"/home/crazymax/github/docker_org/compose/.dev/47231/bad/Dockerfile"}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"Target":"default","LocalPath":"/home/crazymax/github/docker_org/compose/.dev/47231","DockerfilePath":"/home/crazymax/github/docker_org/compose/.dev/47231/bad/Dockerfile"}
|
||||||
8
__tests__/fixtures/docker-config-auths.json
Normal file
8
__tests__/fixtures/docker-config-auths.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"auths": {
|
||||||
|
"https://index.docker.io/v1/": {
|
||||||
|
"auth": "am9lam9lOmhlbGxv",
|
||||||
|
"email": "user@example.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
__tests__/fixtures/docker-config-proxies.json
Normal file
8
__tests__/fixtures/docker-config-proxies.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"proxies": {
|
||||||
|
"default": {
|
||||||
|
"httpProxy": "http://127.0.0.1:3128",
|
||||||
|
"httpsProxy": "http://127.0.0.1:3128"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7131
__tests__/fixtures/dockerhub-repoalltags.json
Normal file
7131
__tests__/fixtures/dockerhub-repoalltags.json
Normal file
File diff suppressed because it is too large
Load Diff
34
__tests__/fixtures/dockerhub-repoinfo.json
Normal file
34
__tests__/fixtures/dockerhub-repoinfo.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"user": "foo",
|
||||||
|
"name": "bar",
|
||||||
|
"namespace": "foo",
|
||||||
|
"repository_type": "image",
|
||||||
|
"status": 1,
|
||||||
|
"status_description": "active",
|
||||||
|
"description": "Bar",
|
||||||
|
"is_private": false,
|
||||||
|
"is_automated": false,
|
||||||
|
"can_edit": true,
|
||||||
|
"star_count": 68,
|
||||||
|
"pull_count": 178255909,
|
||||||
|
"last_updated": "2023-02-02T14:22:31.184404Z",
|
||||||
|
"date_registered": "2019-06-04T20:08:57.306333Z",
|
||||||
|
"collaborator_count": 0,
|
||||||
|
"affiliation": "owner",
|
||||||
|
"hub_user": "foo",
|
||||||
|
"has_starred": false,
|
||||||
|
"full_description": "This is the full description of the repo.",
|
||||||
|
"permissions": {
|
||||||
|
"read": true,
|
||||||
|
"write": true,
|
||||||
|
"admin": true
|
||||||
|
},
|
||||||
|
"media_types": [
|
||||||
|
"application/vnd.docker.container.image.v1+json",
|
||||||
|
"application/vnd.docker.distribution.manifest.list.v2+json",
|
||||||
|
"application/vnd.oci.image.index.v1+json"
|
||||||
|
],
|
||||||
|
"content_types": [
|
||||||
|
"image"
|
||||||
|
]
|
||||||
|
}
|
||||||
1053
__tests__/fixtures/dockerhub-repotags.json
Normal file
1053
__tests__/fixtures/dockerhub-repotags.json
Normal file
File diff suppressed because it is too large
Load Diff
39
__tests__/fixtures/hello-bake.hcl
Normal file
39
__tests__/fixtures/hello-bake.hcl
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2024 actions-toolkit authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
target "hello" {
|
||||||
|
dockerfile = "hello.Dockerfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
target "hello-bar" {
|
||||||
|
dockerfile = "hello.Dockerfile"
|
||||||
|
args = {
|
||||||
|
NAME = "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group "hello-all" {
|
||||||
|
targets = ["hello", "hello-bar"]
|
||||||
|
}
|
||||||
|
|
||||||
|
target "hello-matrix" {
|
||||||
|
name = "matrix-${name}"
|
||||||
|
matrix = {
|
||||||
|
name = ["bar", "baz", "boo", "far", "faz", "foo", "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj"]
|
||||||
|
}
|
||||||
|
dockerfile = "hello.Dockerfile"
|
||||||
|
args = {
|
||||||
|
NAME = name
|
||||||
|
}
|
||||||
|
}
|
||||||
23
__tests__/fixtures/hello.Dockerfile
Normal file
23
__tests__/fixtures/hello.Dockerfile
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
# Copyright 2024 actions-toolkit authors
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
FROM busybox AS build
|
||||||
|
ARG NAME=foo
|
||||||
|
ARG TARGETPLATFORM
|
||||||
|
RUN echo "Hello $NAME from $TARGETPLATFORM" > foo
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
COPY --from=build /foo /
|
||||||
67
__tests__/fixtures/inspect10.txt
Normal file
67
__tests__/fixtures/inspect10.txt
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
Name: remote-builder
|
||||||
|
Driver: remote
|
||||||
|
Last Activity: 2023-04-20 12:47:49 +0000 UTC
|
||||||
|
|
||||||
|
Nodes:
|
||||||
|
Name: remote-builder0
|
||||||
|
Endpoint: docker-container://buildx_buildkit_dk-remote-builder0
|
||||||
|
Status: inactive
|
||||||
|
Platforms:
|
||||||
|
|
||||||
|
Name: aws_graviton2
|
||||||
|
Endpoint: tcp://10.0.0.1:1234
|
||||||
|
Driver Options: cacert="/home/user/.certs/aws_graviton2/ca.pem" cert="/home/user/.certs/aws_graviton2/cert.pem" key="/home/user/.certs/aws_graviton2/key.pem"
|
||||||
|
Status: running
|
||||||
|
Buildkit: v0.11.6
|
||||||
|
Platforms: darwin/arm64*, linux/arm64*, linux/arm/v5*, linux/arm/v6*, linux/arm/v7*, windows/arm64*
|
||||||
|
Labels:
|
||||||
|
org.mobyproject.buildkit.worker.executor: oci
|
||||||
|
org.mobyproject.buildkit.worker.hostname: 77ebc22e2d82
|
||||||
|
org.mobyproject.buildkit.worker.network: host
|
||||||
|
org.mobyproject.buildkit.worker.oci.process-mode: sandbox
|
||||||
|
org.mobyproject.buildkit.worker.selinux.enabled: false
|
||||||
|
org.mobyproject.buildkit.worker.snapshotter: overlayfs
|
||||||
|
GC Policy rule#0:
|
||||||
|
All: false
|
||||||
|
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
|
||||||
|
Keep Duration: 48h0m0s
|
||||||
|
Keep Bytes: 488.3MiB
|
||||||
|
GC Policy rule#1:
|
||||||
|
All: false
|
||||||
|
Keep Duration: 1440h0m0s
|
||||||
|
Keep Bytes: 23.28GiB
|
||||||
|
GC Policy rule#2:
|
||||||
|
All: false
|
||||||
|
Keep Bytes: 23.28GiB
|
||||||
|
GC Policy rule#3:
|
||||||
|
All: true
|
||||||
|
Keep Bytes: 23.28GiB
|
||||||
|
|
||||||
|
Name: linuxone_s390x
|
||||||
|
Endpoint: tcp://10.0.0.2:1234
|
||||||
|
Driver Options: cacert="/home/user/.certs/linuxone_s390x/ca.pem" cert="/home/user/.certs/linuxone_s390x/cert.pem" key="/home/user/.certs/linuxone_s390x/key.pem"
|
||||||
|
Status: running
|
||||||
|
Buildkit: v0.11.6
|
||||||
|
Platforms: linux/s390x*
|
||||||
|
Labels:
|
||||||
|
org.mobyproject.buildkit.worker.executor: oci
|
||||||
|
org.mobyproject.buildkit.worker.hostname: 9d0d62a96818
|
||||||
|
org.mobyproject.buildkit.worker.network: host
|
||||||
|
org.mobyproject.buildkit.worker.oci.process-mode: sandbox
|
||||||
|
org.mobyproject.buildkit.worker.selinux.enabled: false
|
||||||
|
org.mobyproject.buildkit.worker.snapshotter: overlayfs
|
||||||
|
GC Policy rule#0:
|
||||||
|
All: false
|
||||||
|
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
|
||||||
|
Keep Duration: 48h0m0s
|
||||||
|
Keep Bytes: 488.3MiB
|
||||||
|
GC Policy rule#1:
|
||||||
|
All: false
|
||||||
|
Keep Duration: 1440h0m0s
|
||||||
|
Keep Bytes: 9.313GiB
|
||||||
|
GC Policy rule#2:
|
||||||
|
All: false
|
||||||
|
Keep Bytes: 9.313GiB
|
||||||
|
GC Policy rule#3:
|
||||||
|
All: true
|
||||||
|
Keep Bytes: 9.313GiB
|
||||||
39
__tests__/fixtures/inspect11.txt
Normal file
39
__tests__/fixtures/inspect11.txt
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
Name: builder
|
||||||
|
Driver: docker-container
|
||||||
|
Last Activity: 2024-03-01 14:25:03 +0000 UTC
|
||||||
|
|
||||||
|
Nodes:
|
||||||
|
Name: builder0
|
||||||
|
Endpoint: unix:///var/run/docker.sock
|
||||||
|
Driver Options: env.JAEGER_TRACE="localhost:6831" image="moby/buildkit:master" network="host" env.BUILDKIT_STEP_LOG_MAX_SIZE="10485760" env.BUILDKIT_STEP_LOG_MAX_SPEED="10485760"
|
||||||
|
Status: running
|
||||||
|
BuildKit daemon flags: --debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host --allow-insecure-entitlement=network.host
|
||||||
|
BuildKit version: 37657a1
|
||||||
|
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
|
||||||
|
Features:
|
||||||
|
Cache export: true
|
||||||
|
Docker exporter: true
|
||||||
|
Multi-platform build: true
|
||||||
|
OCI exporter: true
|
||||||
|
Labels:
|
||||||
|
org.mobyproject.buildkit.worker.executor: oci
|
||||||
|
org.mobyproject.buildkit.worker.hostname: docker-desktop
|
||||||
|
org.mobyproject.buildkit.worker.network: host
|
||||||
|
org.mobyproject.buildkit.worker.oci.process-mode: sandbox
|
||||||
|
org.mobyproject.buildkit.worker.selinux.enabled: false
|
||||||
|
org.mobyproject.buildkit.worker.snapshotter: overlayfs
|
||||||
|
GC Policy rule#0:
|
||||||
|
All: false
|
||||||
|
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
|
||||||
|
Keep Duration: 48h0m0s
|
||||||
|
Keep Bytes: 488.3MiB
|
||||||
|
GC Policy rule#1:
|
||||||
|
All: false
|
||||||
|
Keep Duration: 1440h0m0s
|
||||||
|
Keep Bytes: 94.06GiB
|
||||||
|
GC Policy rule#2:
|
||||||
|
All: false
|
||||||
|
Keep Bytes: 94.06GiB
|
||||||
|
GC Policy rule#3:
|
||||||
|
All: true
|
||||||
|
Keep Bytes: 94.06GiB
|
||||||
@@ -5,7 +5,7 @@ Last Activity: 2023-01-16 09:45:23 +0000 UTC
|
|||||||
Nodes:
|
Nodes:
|
||||||
Name: builder20
|
Name: builder20
|
||||||
Endpoint: unix:///var/run/docker.sock
|
Endpoint: unix:///var/run/docker.sock
|
||||||
Driver Options: env.BUILDKIT_STEP_LOG_MAX_SIZE="10485760" env.BUILDKIT_STEP_LOG_MAX_SPEED="10485760" env.JAEGER_TRACE="localhost:6831" image="moby/buildkit:latest" network="host"
|
Driver Options: env.BUILDKIT_STEP_LOG_MAX_SIZE="10485760" env.BUILDKIT_STEP_LOG_MAX_SPEED="10485760" env.JAEGER_TRACE="localhost:6831" image="moby/buildkit:latest" network="host" qemu.install="true"
|
||||||
Status: running
|
Status: running
|
||||||
Flags: --debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
|
Flags: --debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
|
||||||
Buildkit: v0.11.0
|
Buildkit: v0.11.0
|
||||||
|
|||||||
34
__tests__/fixtures/inspect8.txt
Normal file
34
__tests__/fixtures/inspect8.txt
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
Name: builder-52aa0611-faf0-42ac-a940-461e4e287d68
|
||||||
|
Driver: docker-container
|
||||||
|
Last Activity: 2023-06-13 13:52:31 +0000 UTC
|
||||||
|
|
||||||
|
Nodes:
|
||||||
|
Name: builder-52aa0611-faf0-42ac-a940-461e4e287d680
|
||||||
|
Endpoint: unix:///var/run/docker.sock
|
||||||
|
Driver Options: image="moby/buildkit:buildx-stable-1" network="host"
|
||||||
|
Status: running
|
||||||
|
Flags: --debug --allow-insecure-entitlement security.insecure --allow-insecure-entitlement network.host
|
||||||
|
Buildkit: v0.11.6
|
||||||
|
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
|
||||||
|
Labels:
|
||||||
|
org.mobyproject.buildkit.worker.executor: oci
|
||||||
|
org.mobyproject.buildkit.worker.hostname: fv-az572-38
|
||||||
|
org.mobyproject.buildkit.worker.network: host
|
||||||
|
org.mobyproject.buildkit.worker.oci.process-mode: sandbox
|
||||||
|
org.mobyproject.buildkit.worker.selinux.enabled: false
|
||||||
|
org.mobyproject.buildkit.worker.snapshotter: overlayfs
|
||||||
|
GC Policy rule#0:
|
||||||
|
All: false
|
||||||
|
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
|
||||||
|
Keep Duration: 48h0m0s
|
||||||
|
Keep Bytes: 488.3MiB
|
||||||
|
GC Policy rule#1:
|
||||||
|
All: false
|
||||||
|
Keep Duration: 1440h0m0s
|
||||||
|
Keep Bytes: 8.382GiB
|
||||||
|
GC Policy rule#2:
|
||||||
|
All: false
|
||||||
|
Keep Bytes: 8.382GiB
|
||||||
|
GC Policy rule#3:
|
||||||
|
All: true
|
||||||
|
Keep Bytes: 8.382GiB
|
||||||
14
__tests__/fixtures/inspect9.txt
Normal file
14
__tests__/fixtures/inspect9.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
Name: default
|
||||||
|
Driver: docker
|
||||||
|
Last Activity: 2023-06-13 18:13:43 +0000 UTC
|
||||||
|
|
||||||
|
Nodes:
|
||||||
|
Name: default
|
||||||
|
Endpoint: default
|
||||||
|
Status: running
|
||||||
|
Buildkit: v0.11.7-0.20230525183624-798ad6b0ce9f
|
||||||
|
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
|
||||||
|
GC Policy rule#0:
|
||||||
|
All: true
|
||||||
|
Filters:
|
||||||
|
Keep Bytes: 100GiB
|
||||||
45
__tests__/fixtures/metadata.json
Normal file
45
__tests__/fixtures/metadata.json
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"buildx.build.provenance": {
|
||||||
|
"buildType": "https://mobyproject.org/buildkit@v1",
|
||||||
|
"materials": [
|
||||||
|
{
|
||||||
|
"uri": "pkg:docker/docker/dockerfile-upstream@master",
|
||||||
|
"digest": {
|
||||||
|
"sha256": "70433342168dafa34d11bd7236c3c3fcf448b90539733281711050808f32e835"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri": "pkg:docker/busybox@latest?platform=linux%2Famd64",
|
||||||
|
"digest": {
|
||||||
|
"sha256": "9ae97d36d26566ff84e8893c64a6dc4fe8ca6d1144bf5b87b2b85a32def253c7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"invocation": {
|
||||||
|
"configSource": {
|
||||||
|
"entryPoint": "Dockerfile"
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"frontend": "gateway.v0",
|
||||||
|
"args": {
|
||||||
|
"cmdline": "docker/dockerfile-upstream:master",
|
||||||
|
"source": "docker/dockerfile-upstream:master"
|
||||||
|
},
|
||||||
|
"locals": [
|
||||||
|
{
|
||||||
|
"name": "context"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dockerfile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"platform": "linux/amd64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buildx.build.ref": "default/default/n6ibcp9b2pw108rrz7ywdznvo",
|
||||||
|
"containerimage.config.digest": "sha256:059b68a595b22564a1cbc167f369349fdc2ecc1f7bc092c2235cbf601a795fd",
|
||||||
|
"containerimage.digest": "sha256:b09b9482c72371486bb2c1d2c2a2633ed1d0b8389e12c8d52b9e052725c0c83c"
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
__tests__/fixtures/oci-archive/hello-oci-gzip.tar
Normal file
BIN
__tests__/fixtures/oci-archive/hello-oci-gzip.tar
Normal file
Binary file not shown.
BIN
__tests__/fixtures/oci-archive/hello-oci-multiplatform-gzip.tar
Normal file
BIN
__tests__/fixtures/oci-archive/hello-oci-multiplatform-gzip.tar
Normal file
Binary file not shown.
BIN
__tests__/fixtures/oci-archive/hello-oci-uncompressed.tar
Normal file
BIN
__tests__/fixtures/oci-archive/hello-oci-uncompressed.tar
Normal file
Binary file not shown.
BIN
__tests__/fixtures/oci-archive/hello-oci-zstd.tar
Normal file
BIN
__tests__/fixtures/oci-archive/hello-oci-zstd.tar
Normal file
Binary file not shown.
BIN
__tests__/fixtures/oci-archive/moby~buildkit~LWDOW6.dockerbuild
Normal file
BIN
__tests__/fixtures/oci-archive/moby~buildkit~LWDOW6.dockerbuild
Normal file
Binary file not shown.
@@ -17,18 +17,266 @@
|
|||||||
import {beforeEach, describe, expect, it, jest} from '@jest/globals';
|
import {beforeEach, describe, expect, it, jest} from '@jest/globals';
|
||||||
|
|
||||||
import {Git} from '../src/git';
|
import {Git} from '../src/git';
|
||||||
|
import {Exec} from '../src/exec';
|
||||||
|
import {ExecOutput} from '@actions/exec';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
jest.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('git', () => {
|
describe('context', () => {
|
||||||
it('returns git remote ref', async () => {
|
it('returns mocked ref and sha', async () => {
|
||||||
try {
|
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
|
||||||
expect(await Git.getRemoteSha('https://github.com/docker/buildx.git', 'refs/pull/648/head')).toEqual('f11797113e5a9b86bd976329c5dbb8a8bfdfadfa');
|
const fullCmd = `${cmd} ${args?.join(' ')}`;
|
||||||
} catch (e) {
|
let result = '';
|
||||||
// eslint-disable-next-line jest/no-conditional-expect
|
switch (fullCmd) {
|
||||||
expect(e).toEqual(null);
|
case 'git show --format=%H HEAD --quiet --':
|
||||||
}
|
result = 'test-sha';
|
||||||
|
break;
|
||||||
|
case 'git branch --show-current':
|
||||||
|
result = 'test';
|
||||||
|
break;
|
||||||
|
case 'git symbolic-ref HEAD':
|
||||||
|
result = 'refs/heads/test';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
stdout: result,
|
||||||
|
stderr: '',
|
||||||
|
exitCode: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const ctx = await Git.context();
|
||||||
|
expect(ctx.ref).toEqual('refs/heads/test');
|
||||||
|
expect(ctx.sha).toEqual('test-sha');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isInsideWorkTree', () => {
|
||||||
|
it('have been called', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'getExecOutput');
|
||||||
|
try {
|
||||||
|
await Git.isInsideWorkTree();
|
||||||
|
} catch (err) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`git`, ['rev-parse', '--is-inside-work-tree'], {
|
||||||
|
silent: true,
|
||||||
|
ignoreReturnCode: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('remoteSha', () => {
|
||||||
|
it('returns sha using git ls-remote', async () => {
|
||||||
|
expect(await Git.remoteSha('https://github.com/docker/buildx.git', 'refs/pull/648/head')).toEqual('f11797113e5a9b86bd976329c5dbb8a8bfdfadfa');
|
||||||
|
});
|
||||||
|
it('returns sha using github api', async () => {
|
||||||
|
expect(await Git.remoteSha('https://github.com/docker/buildx.git', 'refs/pull/648/head', process.env.GITHUB_TOKEN)).toEqual('f11797113e5a9b86bd976329c5dbb8a8bfdfadfa');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('remoteURL', () => {
|
||||||
|
it('have been called', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'getExecOutput');
|
||||||
|
try {
|
||||||
|
await Git.remoteURL();
|
||||||
|
} catch (err) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`git`, ['remote', 'get-url', 'origin'], {
|
||||||
|
silent: true,
|
||||||
|
ignoreReturnCode: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ref', () => {
|
||||||
|
it('returns mocked ref', async () => {
|
||||||
|
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
|
||||||
|
const fullCmd = `${cmd} ${args?.join(' ')}`;
|
||||||
|
let result = '';
|
||||||
|
switch (fullCmd) {
|
||||||
|
case 'git branch --show-current':
|
||||||
|
result = 'test';
|
||||||
|
break;
|
||||||
|
case 'git symbolic-ref HEAD':
|
||||||
|
result = 'refs/heads/test';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
stdout: result,
|
||||||
|
stderr: '',
|
||||||
|
exitCode: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const ref = await Git.ref();
|
||||||
|
|
||||||
|
expect(ref).toEqual('refs/heads/test');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns mocked detached tag ref', async () => {
|
||||||
|
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
|
||||||
|
const fullCmd = `${cmd} ${args?.join(' ')}`;
|
||||||
|
let result = '';
|
||||||
|
switch (fullCmd) {
|
||||||
|
case 'git branch --show-current':
|
||||||
|
result = '';
|
||||||
|
break;
|
||||||
|
case 'git show -s --pretty=%D':
|
||||||
|
result = 'HEAD, tag: 8.0.0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
stdout: result,
|
||||||
|
stderr: '',
|
||||||
|
exitCode: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const ref = await Git.ref();
|
||||||
|
|
||||||
|
expect(ref).toEqual('refs/tags/8.0.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns mocked detached tag ref (shallow clone)', async () => {
|
||||||
|
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
|
||||||
|
const fullCmd = `${cmd} ${args?.join(' ')}`;
|
||||||
|
let result = '';
|
||||||
|
switch (fullCmd) {
|
||||||
|
case 'git branch --show-current':
|
||||||
|
result = '';
|
||||||
|
break;
|
||||||
|
case 'git show -s --pretty=%D':
|
||||||
|
result = 'grafted, HEAD, tag: 8.0.0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
stdout: result,
|
||||||
|
stderr: '',
|
||||||
|
exitCode: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const ref = await Git.ref();
|
||||||
|
|
||||||
|
expect(ref).toEqual('refs/tags/8.0.0');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns mocked detached pull request merge ref (shallow clone)', async () => {
|
||||||
|
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
|
||||||
|
const fullCmd = `${cmd} ${args?.join(' ')}`;
|
||||||
|
let result = '';
|
||||||
|
switch (fullCmd) {
|
||||||
|
case 'git branch --show-current':
|
||||||
|
result = '';
|
||||||
|
break;
|
||||||
|
case 'git show -s --pretty=%D':
|
||||||
|
result = 'grafted, HEAD, pull/221/merge';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
stdout: result,
|
||||||
|
stderr: '',
|
||||||
|
exitCode: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const ref = await Git.ref();
|
||||||
|
|
||||||
|
expect(ref).toEqual('refs/pull/221/merge');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throws an error when detached HEAD ref is not supported', async () => {
|
||||||
|
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
|
||||||
|
const fullCmd = `${cmd} ${args?.join(' ')}`;
|
||||||
|
let result = '';
|
||||||
|
switch (fullCmd) {
|
||||||
|
case 'git branch --show-current':
|
||||||
|
result = '';
|
||||||
|
break;
|
||||||
|
case 'git show -s --pretty=%D':
|
||||||
|
result = 'wrong, HEAD, tag: 8.0.0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
stdout: result,
|
||||||
|
stderr: '',
|
||||||
|
exitCode: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(Git.ref()).rejects.toThrow('Cannot find detached HEAD ref in "wrong, HEAD, tag: 8.0.0"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns mocked detached branch ref', async () => {
|
||||||
|
jest.spyOn(Exec, 'getExecOutput').mockImplementation((cmd, args): Promise<ExecOutput> => {
|
||||||
|
const fullCmd = `${cmd} ${args?.join(' ')}`;
|
||||||
|
let result = '';
|
||||||
|
switch (fullCmd) {
|
||||||
|
case 'git branch --show-current':
|
||||||
|
result = '';
|
||||||
|
break;
|
||||||
|
case 'git show -s --pretty=%D':
|
||||||
|
result = 'HEAD, origin/test, test';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
stdout: result,
|
||||||
|
stderr: '',
|
||||||
|
exitCode: 0
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const ref = await Git.ref();
|
||||||
|
|
||||||
|
expect(ref).toEqual('refs/heads/test');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('fullCommit', () => {
|
||||||
|
it('have been called', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'getExecOutput');
|
||||||
|
try {
|
||||||
|
await Git.fullCommit();
|
||||||
|
} catch (err) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`git`, ['show', '--format=%H', 'HEAD', '--quiet', '--'], {
|
||||||
|
silent: true,
|
||||||
|
ignoreReturnCode: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('shortCommit', () => {
|
||||||
|
it('have been called', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'getExecOutput');
|
||||||
|
try {
|
||||||
|
await Git.shortCommit();
|
||||||
|
} catch (err) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`git`, ['show', '--format=%h', 'HEAD', '--quiet', '--'], {
|
||||||
|
silent: true,
|
||||||
|
ignoreReturnCode: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('tag', () => {
|
||||||
|
it('have been called', async () => {
|
||||||
|
const execSpy = jest.spyOn(Exec, 'getExecOutput');
|
||||||
|
try {
|
||||||
|
await Git.tag();
|
||||||
|
} catch (err) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
expect(execSpy).toHaveBeenCalledWith(`git`, ['tag', '--points-at', 'HEAD', '--sort', '-version:creatordate'], {
|
||||||
|
silent: true,
|
||||||
|
ignoreReturnCode: true
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
196
__tests__/github.test.itg.ts
Normal file
196
__tests__/github.test.itg.ts
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2024 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {beforeEach, describe, expect, it, jest, test} from '@jest/globals';
|
||||||
|
import fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
|
import {Buildx} from '../src/buildx/buildx';
|
||||||
|
import {Bake} from '../src/buildx/bake';
|
||||||
|
import {Build} from '../src/buildx/build';
|
||||||
|
import {Exec} from '../src/exec';
|
||||||
|
import {GitHub} from '../src/github';
|
||||||
|
import {History} from '../src/buildx/history';
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, 'fixtures');
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'github-jest');
|
||||||
|
|
||||||
|
const maybe = !process.env.GITHUB_ACTIONS || (process.env.GITHUB_ACTIONS === 'true' && process.env.ImageOS && process.env.ImageOS.startsWith('ubuntu')) ? describe : describe.skip;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
maybe('uploadArtifact', () => {
|
||||||
|
it('uploads an artifact', async () => {
|
||||||
|
const res = await GitHub.uploadArtifact({
|
||||||
|
filename: path.join(fixturesDir, 'github-repo.json'),
|
||||||
|
mimeType: 'application/json',
|
||||||
|
retentionDays: 1
|
||||||
|
});
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
console.log('uploadArtifactResponse', res);
|
||||||
|
expect(res?.url).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
maybe('writeBuildSummary', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
"single",
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'-f', path.join(fixturesDir, 'hello.Dockerfile'),
|
||||||
|
fixturesDir
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"multiplatform",
|
||||||
|
[
|
||||||
|
'build',
|
||||||
|
'-f', path.join(fixturesDir, 'hello.Dockerfile'),
|
||||||
|
'--platform', 'linux/amd64,linux/arm64',
|
||||||
|
fixturesDir
|
||||||
|
],
|
||||||
|
]
|
||||||
|
])('write build summary %p', async (_, bargs) => {
|
||||||
|
const buildx = new Buildx();
|
||||||
|
const build = new Build({buildx: buildx});
|
||||||
|
|
||||||
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
|
await expect(
|
||||||
|
(async () => {
|
||||||
|
// prettier-ignore
|
||||||
|
const buildCmd = await buildx.getCommand([
|
||||||
|
'--builder', process.env.CTN_BUILDER_NAME ?? 'default',
|
||||||
|
...bargs,
|
||||||
|
'--metadata-file', build.getMetadataFilePath()
|
||||||
|
]);
|
||||||
|
await Exec.exec(buildCmd.command, buildCmd.args);
|
||||||
|
})()
|
||||||
|
).resolves.not.toThrow();
|
||||||
|
|
||||||
|
const metadata = build.resolveMetadata();
|
||||||
|
expect(metadata).toBeDefined();
|
||||||
|
const buildRef = build.resolveRef(metadata);
|
||||||
|
expect(buildRef).toBeDefined();
|
||||||
|
|
||||||
|
const history = new History({buildx: buildx});
|
||||||
|
const exportRes = await history.export({
|
||||||
|
refs: [buildRef ?? '']
|
||||||
|
});
|
||||||
|
expect(exportRes).toBeDefined();
|
||||||
|
expect(exportRes?.dockerbuildFilename).toBeDefined();
|
||||||
|
expect(exportRes?.dockerbuildSize).toBeDefined();
|
||||||
|
expect(exportRes?.summaries).toBeDefined();
|
||||||
|
|
||||||
|
const uploadRes = await GitHub.uploadArtifact({
|
||||||
|
filename: exportRes?.dockerbuildFilename,
|
||||||
|
mimeType: 'application/gzip',
|
||||||
|
retentionDays: 1
|
||||||
|
});
|
||||||
|
expect(uploadRes).toBeDefined();
|
||||||
|
expect(uploadRes?.url).toBeDefined();
|
||||||
|
|
||||||
|
await GitHub.writeBuildSummary({
|
||||||
|
exportRes: exportRes,
|
||||||
|
uploadRes: uploadRes,
|
||||||
|
inputs: {
|
||||||
|
context: fixturesDir,
|
||||||
|
file: path.join(fixturesDir, 'hello.Dockerfile')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
test.each([
|
||||||
|
[
|
||||||
|
'single',
|
||||||
|
[
|
||||||
|
'bake',
|
||||||
|
'-f', path.join(fixturesDir, 'hello-bake.hcl'),
|
||||||
|
'hello'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'group',
|
||||||
|
[
|
||||||
|
'bake',
|
||||||
|
'-f', path.join(fixturesDir, 'hello-bake.hcl'),
|
||||||
|
'hello-all'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'matrix',
|
||||||
|
[
|
||||||
|
'bake',
|
||||||
|
'-f', path.join(fixturesDir, 'hello-bake.hcl'),
|
||||||
|
'hello-matrix'
|
||||||
|
],
|
||||||
|
]
|
||||||
|
])('write bake summary %p', async (_, bargs) => {
|
||||||
|
const buildx = new Buildx();
|
||||||
|
const bake = new Bake({buildx: buildx});
|
||||||
|
|
||||||
|
fs.mkdirSync(tmpDir, {recursive: true});
|
||||||
|
await expect(
|
||||||
|
(async () => {
|
||||||
|
// prettier-ignore
|
||||||
|
const buildCmd = await buildx.getCommand([
|
||||||
|
'--builder', process.env.CTN_BUILDER_NAME ?? 'default',
|
||||||
|
...bargs,
|
||||||
|
'--metadata-file', bake.getMetadataFilePath()
|
||||||
|
]);
|
||||||
|
await Exec.exec(buildCmd.command, buildCmd.args, {
|
||||||
|
cwd: fixturesDir
|
||||||
|
});
|
||||||
|
})()
|
||||||
|
).resolves.not.toThrow();
|
||||||
|
|
||||||
|
const metadata = bake.resolveMetadata();
|
||||||
|
expect(metadata).toBeDefined();
|
||||||
|
const buildRefs = bake.resolveRefs(metadata);
|
||||||
|
expect(buildRefs).toBeDefined();
|
||||||
|
|
||||||
|
const history = new History({buildx: buildx});
|
||||||
|
const exportRes = await history.export({
|
||||||
|
refs: buildRefs ?? []
|
||||||
|
});
|
||||||
|
expect(exportRes).toBeDefined();
|
||||||
|
expect(exportRes?.dockerbuildFilename).toBeDefined();
|
||||||
|
expect(exportRes?.dockerbuildSize).toBeDefined();
|
||||||
|
expect(exportRes?.summaries).toBeDefined();
|
||||||
|
|
||||||
|
const uploadRes = await GitHub.uploadArtifact({
|
||||||
|
filename: exportRes?.dockerbuildFilename,
|
||||||
|
mimeType: 'application/gzip',
|
||||||
|
retentionDays: 1
|
||||||
|
});
|
||||||
|
expect(uploadRes).toBeDefined();
|
||||||
|
expect(uploadRes?.url).toBeDefined();
|
||||||
|
|
||||||
|
await GitHub.writeBuildSummary({
|
||||||
|
exportRes: exportRes,
|
||||||
|
uploadRes: uploadRes,
|
||||||
|
inputs: {
|
||||||
|
files: path.join(fixturesDir, 'hello-bake.hcl')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -17,26 +17,33 @@
|
|||||||
import {describe, expect, jest, it, beforeEach, afterEach} from '@jest/globals';
|
import {describe, expect, jest, it, beforeEach, afterEach} from '@jest/globals';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
import {GitHub, GitHubRepo} from '../src/github';
|
import {GitHub} from '../src/github';
|
||||||
|
import {GitHubRepo} from '../src/types/github';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
import * as repoFixture from './fixtures/repo.json';
|
import repoFixture from './fixtures/github-repo.json';
|
||||||
jest.spyOn(GitHub.prototype, 'repoData').mockImplementation((): Promise<GitHubRepo> => {
|
jest.spyOn(GitHub.prototype, 'repoData').mockImplementation((): Promise<GitHubRepo> => {
|
||||||
return <Promise<GitHubRepo>>(repoFixture as unknown);
|
return <Promise<GitHubRepo>>(repoFixture as unknown);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('repoData', () => {
|
||||||
|
it('returns GitHub repo data', async () => {
|
||||||
|
const github = new GitHub();
|
||||||
|
expect((await github.repoData()).name).toEqual('Hello-World');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('context', () => {
|
describe('context', () => {
|
||||||
it('returns repository name from payload', async () => {
|
it('returns repository name from payload', async () => {
|
||||||
const github = new GitHub();
|
expect(GitHub.context.payload.repository?.name).toEqual('test-docker-action');
|
||||||
expect(github.context.payload.repository?.name).toEqual('test-docker-action');
|
|
||||||
});
|
});
|
||||||
it('is repository private', async () => {
|
it('is repository private', async () => {
|
||||||
const github = new GitHub();
|
expect(GitHub.context.payload.repository?.private).toEqual(true);
|
||||||
expect(github.context.payload.repository?.private).toEqual(true);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -54,12 +61,46 @@ describe('serverURL', () => {
|
|||||||
});
|
});
|
||||||
it('returns default', async () => {
|
it('returns default', async () => {
|
||||||
process.env.GITHUB_SERVER_URL = '';
|
process.env.GITHUB_SERVER_URL = '';
|
||||||
const github = new GitHub();
|
expect(GitHub.serverURL).toEqual('https://github.com');
|
||||||
expect(github.serverURL).toEqual('https://github.com');
|
|
||||||
});
|
});
|
||||||
it('returns from env', async () => {
|
it('returns from env', async () => {
|
||||||
const github = new GitHub();
|
expect(GitHub.serverURL).toEqual('https://foo.github.com');
|
||||||
expect(github.serverURL).toEqual('https://foo.github.com');
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('apiURL', () => {
|
||||||
|
const originalEnv = process.env;
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
GITHUB_API_URL: 'https://bar.github.com'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = originalEnv;
|
||||||
|
});
|
||||||
|
it('returns default', async () => {
|
||||||
|
process.env.GITHUB_API_URL = '';
|
||||||
|
expect(GitHub.apiURL).toEqual('https://api.github.com');
|
||||||
|
});
|
||||||
|
it('returns from env', async () => {
|
||||||
|
expect(GitHub.apiURL).toEqual('https://bar.github.com');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('repository', () => {
|
||||||
|
it('returns GitHub repository', async () => {
|
||||||
|
expect(GitHub.repository).toEqual('docker/actions-toolkit');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('workflowRunURL', () => {
|
||||||
|
it('returns 2188748038', async () => {
|
||||||
|
expect(GitHub.workflowRunURL()).toEqual('https://github.com/docker/actions-toolkit/actions/runs/2188748038');
|
||||||
|
});
|
||||||
|
it('returns 2188748038 with attempts 2', async () => {
|
||||||
|
expect(GitHub.workflowRunURL(true)).toEqual('https://github.com/docker/actions-toolkit/actions/runs/2188748038/attempts/2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -76,21 +117,52 @@ describe('actionsRuntimeToken', () => {
|
|||||||
});
|
});
|
||||||
it('empty', async () => {
|
it('empty', async () => {
|
||||||
process.env.ACTIONS_RUNTIME_TOKEN = '';
|
process.env.ACTIONS_RUNTIME_TOKEN = '';
|
||||||
const github = new GitHub();
|
expect(GitHub.actionsRuntimeToken).toBeUndefined();
|
||||||
expect(github.actionsRuntimeToken).toEqual({});
|
});
|
||||||
|
it('malformed', async () => {
|
||||||
|
process.env.ACTIONS_RUNTIME_TOKEN = 'foo';
|
||||||
|
expect(() => {
|
||||||
|
GitHub.actionsRuntimeToken;
|
||||||
|
}).toThrow();
|
||||||
});
|
});
|
||||||
it('fixture', async () => {
|
it('fixture', async () => {
|
||||||
process.env.ACTIONS_RUNTIME_TOKEN = fs.readFileSync(path.join(__dirname, 'fixtures', 'runtimeToken.txt')).toString().trim();
|
process.env.ACTIONS_RUNTIME_TOKEN = fs
|
||||||
const github = new GitHub();
|
.readFileSync(path.join(__dirname, 'fixtures', 'runtimeToken.txt'))
|
||||||
const runtimeToken = github.actionsRuntimeToken;
|
.toString()
|
||||||
expect(runtimeToken.ac).toEqual('[{"Scope":"refs/heads/master","Permission":3}]');
|
.trim();
|
||||||
expect(runtimeToken.iss).toEqual('vstoken.actions.githubusercontent.com');
|
const runtimeToken = GitHub.actionsRuntimeToken;
|
||||||
|
expect(runtimeToken?.ac).toEqual('[{"Scope":"refs/heads/master","Permission":3}]');
|
||||||
|
expect(runtimeToken?.iss).toEqual('vstoken.actions.githubusercontent.com');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('repoData', () => {
|
describe('printActionsRuntimeTokenACs', () => {
|
||||||
it('returns GitHub repository', async () => {
|
const originalEnv = process.env;
|
||||||
const github = new GitHub();
|
beforeEach(() => {
|
||||||
expect((await github.repoData()).name).toEqual('Hello-World');
|
jest.resetModules();
|
||||||
|
process.env = {
|
||||||
|
...originalEnv
|
||||||
|
};
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = originalEnv;
|
||||||
|
});
|
||||||
|
it('empty', async () => {
|
||||||
|
process.env.ACTIONS_RUNTIME_TOKEN = '';
|
||||||
|
await expect(GitHub.printActionsRuntimeTokenACs()).rejects.toThrow(new Error('ACTIONS_RUNTIME_TOKEN not set'));
|
||||||
|
});
|
||||||
|
it('malformed', async () => {
|
||||||
|
process.env.ACTIONS_RUNTIME_TOKEN = 'foo';
|
||||||
|
await expect(GitHub.printActionsRuntimeTokenACs()).rejects.toThrow(new Error('Cannot parse GitHub Actions Runtime Token: Invalid token specified: missing part #2'));
|
||||||
|
});
|
||||||
|
it('refs/heads/master', async () => {
|
||||||
|
const infoSpy = jest.spyOn(core, 'info');
|
||||||
|
process.env.ACTIONS_RUNTIME_TOKEN = fs
|
||||||
|
.readFileSync(path.join(__dirname, 'fixtures', 'runtimeToken.txt'))
|
||||||
|
.toString()
|
||||||
|
.trim();
|
||||||
|
await GitHub.printActionsRuntimeTokenACs();
|
||||||
|
expect(infoSpy).toHaveBeenCalledTimes(1);
|
||||||
|
expect(infoSpy).toHaveBeenCalledWith(`refs/heads/master: read/write`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
50
__tests__/oci/oci.test.ts
Normal file
50
__tests__/oci/oci.test.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2024 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {afterEach, beforeEach, describe, expect, jest, test} from '@jest/globals';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import * as rimraf from 'rimraf';
|
||||||
|
|
||||||
|
import {OCI} from '../../src/oci/oci';
|
||||||
|
|
||||||
|
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
const tmpDir = path.join(process.env.TEMP || '/tmp', 'docker-jest');
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
rimraf.sync(tmpDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('loadArchive', () => {
|
||||||
|
// prettier-ignore
|
||||||
|
test.each(fs.readdirSync(path.join(fixturesDir, 'oci-archive')).filter(file => {
|
||||||
|
return fs.statSync(path.join(path.join(fixturesDir, 'oci-archive'), file)).isFile();
|
||||||
|
}).map(filename => [filename]))('extracting %p', async (filename) => {
|
||||||
|
const res = await OCI.loadArchive({
|
||||||
|
file: path.join(fixturesDir, 'oci-archive', filename)
|
||||||
|
});
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(res?.root.index).toBeDefined();
|
||||||
|
expect(res?.root.layout).toBeDefined();
|
||||||
|
// console.log(JSON.stringify(res, null, 2));
|
||||||
|
});
|
||||||
|
});
|
||||||
30
__tests__/testResultsProcessor.ts
Normal file
30
__tests__/testResultsProcessor.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2024 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
module.exports = results => {
|
||||||
|
const allSkipped = results.testResults.every(result => {
|
||||||
|
return result.skipped;
|
||||||
|
});
|
||||||
|
if (allSkipped) {
|
||||||
|
console.log('All tests were skipped!');
|
||||||
|
// create an empty file to signal that all tests were skipped for CI
|
||||||
|
fs.closeSync(fs.openSync('./coverage/allSkipped.txt', 'w'));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
};
|
||||||
@@ -31,6 +31,12 @@ describe('getInputList', () => {
|
|||||||
expect(res).toEqual(['bar']);
|
expect(res).toEqual(['bar']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('empty correctly', async () => {
|
||||||
|
setInput('foo', '');
|
||||||
|
const res = Util.getInputList('foo');
|
||||||
|
expect(res).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
it('multiline correctly', async () => {
|
it('multiline correctly', async () => {
|
||||||
setInput('foo', 'bar\nbaz');
|
setInput('foo', 'bar\nbaz');
|
||||||
const res = Util.getInputList('foo');
|
const res = Util.getInputList('foo');
|
||||||
@@ -69,16 +75,40 @@ describe('getInputList', () => {
|
|||||||
|
|
||||||
it('multiline and ignoring comma correctly', async () => {
|
it('multiline and ignoring comma correctly', async () => {
|
||||||
setInput('cache-from', 'user/app:cache\ntype=local,src=path/to/dir');
|
setInput('cache-from', 'user/app:cache\ntype=local,src=path/to/dir');
|
||||||
const res = Util.getInputList('cache-from', true);
|
const res = Util.getInputList('cache-from', {ignoreComma: true});
|
||||||
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
|
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('multiline and ignoring comment correctly', async () => {
|
||||||
|
setInput('labels', 'foo=bar\nbar=qux#baz');
|
||||||
|
const res = Util.getInputList('labels');
|
||||||
|
expect(res).toEqual(['foo=bar', 'bar=qux#baz']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('multiline with comment', async () => {
|
||||||
|
setInput('labels', 'foo=bar\nbar=qux#baz');
|
||||||
|
const res = Util.getInputList('labels', {comment: '#'});
|
||||||
|
expect(res).toEqual(['foo=bar', 'bar=qux']);
|
||||||
|
});
|
||||||
|
|
||||||
it('different new lines and ignoring comma correctly', async () => {
|
it('different new lines and ignoring comma correctly', async () => {
|
||||||
setInput('cache-from', 'user/app:cache\r\ntype=local,src=path/to/dir');
|
setInput('cache-from', 'user/app:cache\r\ntype=local,src=path/to/dir');
|
||||||
const res = Util.getInputList('cache-from', true);
|
const res = Util.getInputList('cache-from', {ignoreComma: true});
|
||||||
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
|
expect(res).toEqual(['user/app:cache', 'type=local,src=path/to/dir']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('do not escape surrounding quotes', async () => {
|
||||||
|
setInput('driver-opts', `"env.no_proxy=localhost,127.0.0.1,.mydomain"`);
|
||||||
|
const res = Util.getInputList('driver-opts', {ignoreComma: true, quote: false});
|
||||||
|
expect(res).toEqual(['"env.no_proxy=localhost,127.0.0.1,.mydomain"']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('escape surrounding quotes', async () => {
|
||||||
|
setInput('platforms', 'linux/amd64\n"linux/arm64,linux/arm/v7"');
|
||||||
|
const res = Util.getInputList('platforms');
|
||||||
|
expect(res).toEqual(['linux/amd64', 'linux/arm64', 'linux/arm/v7']);
|
||||||
|
});
|
||||||
|
|
||||||
it('multiline values', async () => {
|
it('multiline values', async () => {
|
||||||
setInput(
|
setInput(
|
||||||
'secrets',
|
'secrets',
|
||||||
@@ -88,7 +118,7 @@ bbbbbbb
|
|||||||
ccccccccc"
|
ccccccccc"
|
||||||
FOO=bar`
|
FOO=bar`
|
||||||
);
|
);
|
||||||
const res = Util.getInputList('secrets', true);
|
const res = Util.getInputList('secrets', {ignoreComma: true});
|
||||||
expect(res).toEqual([
|
expect(res).toEqual([
|
||||||
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
||||||
`MYSECRET=aaaaaaaa
|
`MYSECRET=aaaaaaaa
|
||||||
@@ -111,7 +141,7 @@ FOO=bar
|
|||||||
bbbb
|
bbbb
|
||||||
ccc"`
|
ccc"`
|
||||||
);
|
);
|
||||||
const res = Util.getInputList('secrets', true);
|
const res = Util.getInputList('secrets', {ignoreComma: true});
|
||||||
expect(res).toEqual([
|
expect(res).toEqual([
|
||||||
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
||||||
`MYSECRET=aaaaaaaa
|
`MYSECRET=aaaaaaaa
|
||||||
@@ -134,7 +164,7 @@ bbbbbbb
|
|||||||
ccccccccc
|
ccccccccc
|
||||||
FOO=bar`
|
FOO=bar`
|
||||||
);
|
);
|
||||||
const res = Util.getInputList('secrets', true);
|
const res = Util.getInputList('secrets', {ignoreComma: true});
|
||||||
expect(res).toEqual(['GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'MYSECRET=aaaaaaaa', 'bbbbbbb', 'ccccccccc', 'FOO=bar']);
|
expect(res).toEqual(['GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789', 'MYSECRET=aaaaaaaa', 'bbbbbbb', 'ccccccccc', 'FOO=bar']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -145,7 +175,7 @@ FOO=bar`
|
|||||||
`"GPG_KEY=${pgp}"
|
`"GPG_KEY=${pgp}"
|
||||||
FOO=bar`
|
FOO=bar`
|
||||||
);
|
);
|
||||||
const res = Util.getInputList('secrets', true);
|
const res = Util.getInputList('secrets', {ignoreComma: true});
|
||||||
expect(res).toEqual([`GPG_KEY=${pgp}`, 'FOO=bar']);
|
expect(res).toEqual([`GPG_KEY=${pgp}`, 'FOO=bar']);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -158,7 +188,7 @@ bbbb""bbb
|
|||||||
ccccccccc"
|
ccccccccc"
|
||||||
FOO=bar`
|
FOO=bar`
|
||||||
);
|
);
|
||||||
const res = Util.getInputList('secrets', true);
|
const res = Util.getInputList('secrets', {ignoreComma: true});
|
||||||
expect(res).toEqual([
|
expect(res).toEqual([
|
||||||
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
'GIT_AUTH_TOKEN=abcdefgh,ijklmno=0123456789',
|
||||||
`MYSECRET=aaaaaaaa
|
`MYSECRET=aaaaaaaa
|
||||||
@@ -167,6 +197,12 @@ ccccccccc`,
|
|||||||
'FOO=bar'
|
'FOO=bar'
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('keep quotes', async () => {
|
||||||
|
const output = `type=image,"name=ghcr.io/nginxinc/nginx-unprivileged,docker.io/nginxinc/nginx-unprivileged",push-by-digest=true,name-canonical=true,push=true`;
|
||||||
|
setInput('outputs', output);
|
||||||
|
expect(Util.getInputList('outputs', {ignoreComma: true, quote: false})).toEqual([output]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('asyncForEach', () => {
|
describe('asyncForEach', () => {
|
||||||
@@ -182,13 +218,142 @@ describe('asyncForEach', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isValidUrl', () => {
|
describe('isValidURL', () => {
|
||||||
test.each([
|
test.each([
|
||||||
['https://github.com/docker/buildx.git', true],
|
['https://github.com/docker/buildx.git', true],
|
||||||
['https://github.com/docker/buildx.git#refs/pull/648/head', true],
|
['https://github.com/docker/buildx.git#refs/pull/648/head', true],
|
||||||
|
['git@github.com:moby/buildkit.git', false],
|
||||||
|
['git://github.com/user/repo.git', false],
|
||||||
|
['github.com/moby/buildkit.git#main', false],
|
||||||
['v0.4.1', false]
|
['v0.4.1', false]
|
||||||
])('given %p', async (url, expected) => {
|
])('given %p', async (url, expected) => {
|
||||||
expect(Util.isValidUrl(url)).toEqual(expected);
|
expect(Util.isValidURL(url)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isValidRef', () => {
|
||||||
|
test.each([
|
||||||
|
['https://github.com/docker/buildx.git', true],
|
||||||
|
['https://github.com/docker/buildx.git#refs/pull/648/head', true],
|
||||||
|
['git@github.com:moby/buildkit.git', true],
|
||||||
|
['git://github.com/user/repo.git', true],
|
||||||
|
['github.com/moby/buildkit.git#main', true],
|
||||||
|
['v0.4.1', false]
|
||||||
|
])('given %p', async (url, expected) => {
|
||||||
|
expect(Util.isValidRef(url)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('trimPrefix', () => {
|
||||||
|
test.each([
|
||||||
|
['', 'abc', ''],
|
||||||
|
['abc', 'a', 'bc'],
|
||||||
|
['abc', 'ab', 'c'],
|
||||||
|
['abc', '', 'abc'],
|
||||||
|
['abc', '', 'abc'],
|
||||||
|
['abc', 'd', 'abc'],
|
||||||
|
['abc', 'abc', ''],
|
||||||
|
['abc', 'abcd', 'abc'],
|
||||||
|
['abcdabc', 'abc', 'dabc'],
|
||||||
|
['abcabc', 'abc', 'abc'],
|
||||||
|
['abcdabc', 'd', 'abcdabc']
|
||||||
|
])('given %p', async (str, prefix, expected) => {
|
||||||
|
expect(Util.trimPrefix(str, prefix)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('trimSuffix', () => {
|
||||||
|
test.each([
|
||||||
|
['', 'abc', ''],
|
||||||
|
['abc', 'c', 'ab'],
|
||||||
|
['abc', '', 'abc'],
|
||||||
|
['abc', 'bc', 'a'],
|
||||||
|
['abc', 'abc', ''],
|
||||||
|
['abc', 'abcd', 'abc'],
|
||||||
|
['abc', 'aabc', 'abc'],
|
||||||
|
['abcdabc', 'abc', 'abcd'],
|
||||||
|
['abcabc', 'abc', 'abc'],
|
||||||
|
['abcdabc', 'd', 'abcdabc']
|
||||||
|
])('given %p', async (str, suffix, expected) => {
|
||||||
|
expect(Util.trimSuffix(str, suffix)).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hash', () => {
|
||||||
|
it('returns 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae', async () => {
|
||||||
|
expect(Util.hash('foo')).toEqual('2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// https://github.com/golang/go/blob/f6b93a4c358b28b350dd8fe1780c1f78e520c09c/src/strconv/atob_test.go#L36-L58
|
||||||
|
describe('parseBool', () => {
|
||||||
|
[
|
||||||
|
{input: '', expected: false, throwsError: true},
|
||||||
|
{input: 'asdf', expected: false, throwsError: true},
|
||||||
|
{input: '0', expected: false, throwsError: false},
|
||||||
|
{input: 'f', expected: false, throwsError: false},
|
||||||
|
{input: 'F', expected: false, throwsError: false},
|
||||||
|
{input: 'FALSE', expected: false, throwsError: false},
|
||||||
|
{input: 'false', expected: false, throwsError: false},
|
||||||
|
{input: 'False', expected: false, throwsError: false},
|
||||||
|
{input: '1', expected: true, throwsError: false},
|
||||||
|
{input: 't', expected: true, throwsError: false},
|
||||||
|
{input: 'T', expected: true, throwsError: false},
|
||||||
|
{input: 'TRUE', expected: true, throwsError: false},
|
||||||
|
{input: 'true', expected: true, throwsError: false},
|
||||||
|
{input: 'True', expected: true, throwsError: false}
|
||||||
|
].forEach(({input, expected, throwsError}) => {
|
||||||
|
test(`parseBool("${input}")`, () => {
|
||||||
|
if (throwsError) {
|
||||||
|
// eslint-disable-next-line jest/no-conditional-expect
|
||||||
|
expect(() => Util.parseBool(input)).toThrow();
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line jest/no-conditional-expect
|
||||||
|
expect(Util.parseBool(input)).toBe(expected);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('formatFileSize', () => {
|
||||||
|
test('should return "0 Bytes" when given 0 bytes', () => {
|
||||||
|
expect(Util.formatFileSize(0)).toBe('0 Bytes');
|
||||||
|
});
|
||||||
|
test('should format bytes to KB correctly', () => {
|
||||||
|
expect(Util.formatFileSize(1024)).toBe('1 KB');
|
||||||
|
expect(Util.formatFileSize(2048)).toBe('2 KB');
|
||||||
|
expect(Util.formatFileSize(1500)).toBe('1.46 KB');
|
||||||
|
});
|
||||||
|
test('should format bytes to MB correctly', () => {
|
||||||
|
expect(Util.formatFileSize(1024 * 1024)).toBe('1 MB');
|
||||||
|
expect(Util.formatFileSize(2.5 * 1024 * 1024)).toBe('2.5 MB');
|
||||||
|
expect(Util.formatFileSize(3.8 * 1024 * 1024)).toBe('3.8 MB');
|
||||||
|
});
|
||||||
|
test('should format bytes to GB correctly', () => {
|
||||||
|
expect(Util.formatFileSize(1024 * 1024 * 1024)).toBe('1 GB');
|
||||||
|
expect(Util.formatFileSize(2.5 * 1024 * 1024 * 1024)).toBe('2.5 GB');
|
||||||
|
expect(Util.formatFileSize(3.8 * 1024 * 1024 * 1024)).toBe('3.8 GB');
|
||||||
|
});
|
||||||
|
test('should format bytes to TB correctly', () => {
|
||||||
|
expect(Util.formatFileSize(1024 * 1024 * 1024 * 1024)).toBe('1 TB');
|
||||||
|
expect(Util.formatFileSize(2.5 * 1024 * 1024 * 1024 * 1024)).toBe('2.5 TB');
|
||||||
|
expect(Util.formatFileSize(3.8 * 1024 * 1024 * 1024 * 1024)).toBe('3.8 TB');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('generateRandomString', () => {
|
||||||
|
it('should generate a random string of default length 10', async () => {
|
||||||
|
const res = Util.generateRandomString();
|
||||||
|
expect(typeof res).toBe('string');
|
||||||
|
expect(res.length).toBe(10);
|
||||||
|
expect(/^[0-9a-f]+$/i.test(res)).toBe(true);
|
||||||
|
});
|
||||||
|
it('should generate a random string of specified length', async () => {
|
||||||
|
const length = 15;
|
||||||
|
const res = Util.generateRandomString(length);
|
||||||
|
expect(typeof res).toBe('string');
|
||||||
|
expect(res.length).toBe(15);
|
||||||
|
expect(/^[0-9a-f]+$/i.test(res)).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -14,14 +14,19 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
ARG NODE_VERSION=16
|
ARG NODE_VERSION=20
|
||||||
ARG DOCKER_VERSION=20.10.22
|
ARG DOCKER_VERSION=26.0.2
|
||||||
ARG BUILDX_VERSION=0.10.0
|
ARG BUILDX_VERSION=0.15.0
|
||||||
|
|
||||||
FROM node:${NODE_VERSION}-alpine AS base
|
FROM node:${NODE_VERSION}-alpine AS base
|
||||||
RUN apk add --no-cache cpio findutils git
|
RUN apk add --no-cache cpio findutils git
|
||||||
RUN yarn config set --home enableTelemetry 0
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
RUN --mount=type=bind,target=.,rw \
|
||||||
|
--mount=type=cache,target=/src/.yarn/cache <<EOT
|
||||||
|
corepack enable
|
||||||
|
yarn --version
|
||||||
|
yarn config set --home enableTelemetry 0
|
||||||
|
EOT
|
||||||
|
|
||||||
FROM base AS deps
|
FROM base AS deps
|
||||||
RUN --mount=type=bind,target=.,rw \
|
RUN --mount=type=bind,target=.,rw \
|
||||||
@@ -79,7 +84,7 @@ RUN --mount=type=bind,target=.,rw \
|
|||||||
--mount=type=bind,from=buildx,source=/buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \
|
--mount=type=bind,from=buildx,source=/buildx,target=/usr/libexec/docker/cli-plugins/docker-buildx \
|
||||||
--mount=type=bind,from=buildx,source=/buildx,target=/usr/bin/buildx \
|
--mount=type=bind,from=buildx,source=/buildx,target=/usr/bin/buildx \
|
||||||
--mount=type=secret,id=GITHUB_TOKEN \
|
--mount=type=secret,id=GITHUB_TOKEN \
|
||||||
GITHUB_TOKEN=$(cat /run/secrets/GITHUB_TOKEN) yarn run test-coverage --coverageDirectory=/tmp/coverage
|
GITHUB_TOKEN=$(cat /run/secrets/GITHUB_TOKEN) yarn run test:coverage --coverageDirectory=/tmp/coverage
|
||||||
|
|
||||||
FROM scratch AS test-coverage
|
FROM scratch AS test-coverage
|
||||||
COPY --from=test /tmp/coverage /
|
COPY --from=test /tmp/coverage /
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
ARG LICENSE_HOLDER="actions-toolkit authors"
|
ARG LICENSE_HOLDER="actions-toolkit authors"
|
||||||
ARG LICENSE_TYPE="apache"
|
ARG LICENSE_TYPE="apache"
|
||||||
ARG LICENSE_FILES=".*\(Dockerfile\|Makefile\|\.js\|\.ts\|\.hcl\|\.sh\)"
|
ARG LICENSE_FILES=".*\(Dockerfile\|Makefile\|\.js\|\.ts\|\.hcl\|\.sh|\.ps1\)"
|
||||||
ARG ADDLICENSE_VERSION="v1.0.0"
|
ARG ADDLICENSE_VERSION="v1.0.0"
|
||||||
|
|
||||||
FROM ghcr.io/google/addlicense:${ADDLICENSE_VERSION} AS addlicense
|
FROM ghcr.io/google/addlicense:${ADDLICENSE_VERSION} AS addlicense
|
||||||
|
|||||||
50
jest.config.itg.ts
Normal file
50
jest.config.itg.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import os from 'os';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-actions-toolkit-'));
|
||||||
|
|
||||||
|
process.env = Object.assign({}, process.env, {
|
||||||
|
TEMP: tmpDir,
|
||||||
|
GITHUB_REPOSITORY: 'docker/actions-toolkit',
|
||||||
|
GITHUB_RUN_ATTEMPT: 2,
|
||||||
|
GITHUB_RUN_ID: 2188748038,
|
||||||
|
GITHUB_RUN_NUMBER: 15,
|
||||||
|
RUNNER_TEMP: path.join(tmpDir, 'runner-temp'),
|
||||||
|
RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache')
|
||||||
|
}) as {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
clearMocks: true,
|
||||||
|
testEnvironment: 'node',
|
||||||
|
moduleFileExtensions: ['js', 'ts'],
|
||||||
|
setupFiles: ['dotenv/config'],
|
||||||
|
testMatch: ['**/*.test.itg.ts'],
|
||||||
|
testTimeout: 1800000, // 30 minutes
|
||||||
|
transform: {
|
||||||
|
'^.+\\.ts$': 'ts-jest'
|
||||||
|
},
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs'
|
||||||
|
},
|
||||||
|
testResultsProcessor: './__tests__/testResultsProcessor.ts',
|
||||||
|
verbose: false
|
||||||
|
};
|
||||||
@@ -14,10 +14,20 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import os from 'os';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'docker-actions-toolkit-'));
|
||||||
|
|
||||||
process.env = Object.assign({}, process.env, {
|
process.env = Object.assign({}, process.env, {
|
||||||
|
TEMP: tmpDir,
|
||||||
GITHUB_REPOSITORY: 'docker/actions-toolkit',
|
GITHUB_REPOSITORY: 'docker/actions-toolkit',
|
||||||
RUNNER_TEMP: '/tmp/github_runner',
|
GITHUB_RUN_ATTEMPT: 2,
|
||||||
RUNNER_TOOL_CACHE: '/tmp/github_tool_cache'
|
GITHUB_RUN_ID: 2188748038,
|
||||||
|
GITHUB_RUN_NUMBER: 15,
|
||||||
|
RUNNER_TEMP: path.join(tmpDir, 'runner-temp'),
|
||||||
|
RUNNER_TOOL_CACHE: path.join(tmpDir, 'runner-tool-cache')
|
||||||
}) as {
|
}) as {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
};
|
};
|
||||||
@@ -34,7 +44,8 @@ module.exports = {
|
|||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
'^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs'
|
'^csv-parse/sync': '<rootDir>/node_modules/csv-parse/dist/cjs/sync.cjs'
|
||||||
},
|
},
|
||||||
collectCoverageFrom: ['src/**/{!(toolkit.ts),}.ts'],
|
collectCoverageFrom: ['src/**/{!(index.ts),}.ts'],
|
||||||
coveragePathIgnorePatterns: ['lib/', 'node_modules/', '__mocks__/', '__tests__/'],
|
coveragePathIgnorePatterns: ['lib/', 'node_modules/', '__mocks__/', '__tests__/'],
|
||||||
|
testResultsProcessor: './__tests__/testResultsProcessor.ts',
|
||||||
verbose: true
|
verbose: true
|
||||||
};
|
};
|
||||||
|
|||||||
83
package.json
83
package.json
@@ -1,12 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "@docker/actions-toolkit",
|
"name": "@docker/actions-toolkit",
|
||||||
|
"version": "0.0.0+unknown",
|
||||||
"description": "Toolkit for Docker (GitHub) Actions",
|
"description": "Toolkit for Docker (GitHub) Actions",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"lint": "eslint src/**/*.ts __tests__/**/*.ts",
|
"lint": "yarn run prettier && yarn run eslint",
|
||||||
"format": "eslint --fix src/**/*.ts __tests__/**/*.ts",
|
"format": "yarn run prettier:fix && yarn run eslint:fix",
|
||||||
|
"eslint": "eslint --max-warnings=0 .",
|
||||||
|
"eslint:fix": "eslint --fix .",
|
||||||
|
"prettier": "prettier --check \"./**/*.ts\"",
|
||||||
|
"prettier:fix": "prettier --write \"./**/*.ts\"",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test-coverage": "jest --coverage"
|
"test:coverage": "jest --coverage",
|
||||||
|
"test:itg": "jest -c jest.config.itg.ts --runInBand --detectOpenHandles",
|
||||||
|
"test:itg-list": "jest -c jest.config.itg.ts --listTests",
|
||||||
|
"test:itg-coverage": "jest --coverage -c jest.config.itg.ts --runInBand --detectOpenHandles"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -22,9 +30,9 @@
|
|||||||
],
|
],
|
||||||
"author": "Docker Inc.",
|
"author": "Docker Inc.",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"packageManager": "yarn@3.3.1",
|
"packageManager": "yarn@3.6.3",
|
||||||
"main": "lib/toolkit.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/toolkit.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
"directories": {
|
"directories": {
|
||||||
"lib": "lib",
|
"lib": "lib",
|
||||||
"test": "__tests__"
|
"test": "__tests__"
|
||||||
@@ -37,33 +45,48 @@
|
|||||||
"registry": "https://registry.npmjs.org/"
|
"registry": "https://registry.npmjs.org/"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/artifact": "^2.1.7",
|
||||||
|
"@actions/cache": "^3.2.4",
|
||||||
|
"@actions/core": "^1.10.1",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/github": "^5.1.1",
|
"@actions/github": "^6.0.0",
|
||||||
"@actions/http-client": "^2.0.1",
|
"@actions/http-client": "^2.2.1",
|
||||||
"csv-parse": "^5.3.3",
|
"@actions/io": "^1.1.3",
|
||||||
"jwt-decode": "^3.1.2",
|
"@actions/tool-cache": "^2.0.1",
|
||||||
"semver": "^7.3.8",
|
"@azure/storage-blob": "^12.15.0",
|
||||||
"tmp": "^0.2.1"
|
"@octokit/core": "^5.1.0",
|
||||||
|
"@octokit/plugin-rest-endpoint-methods": "^10.4.0",
|
||||||
|
"async-retry": "^1.3.3",
|
||||||
|
"csv-parse": "^5.5.6",
|
||||||
|
"gunzip-maybe": "^1.4.2",
|
||||||
|
"handlebars": "^4.7.8",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"jwt-decode": "^4.0.0",
|
||||||
|
"semver": "^7.6.2",
|
||||||
|
"tar-stream": "^3.1.7",
|
||||||
|
"tmp": "^0.2.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/csv-parse": "^1.2.2",
|
"@types/csv-parse": "^1.2.2",
|
||||||
"@types/node": "^16.18.11",
|
"@types/gunzip-maybe": "^1.4.2",
|
||||||
"@types/semver": "^7.3.13",
|
"@types/js-yaml": "^4.0.9",
|
||||||
"@types/tmp": "^0.2.3",
|
"@types/node": "^20.12.10",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.49.0",
|
"@types/semver": "^7.5.8",
|
||||||
"@typescript-eslint/parser": "^5.49.0",
|
"@types/tar-stream": "^3.1.3",
|
||||||
"cpy-cli": "^4.2.0",
|
"@types/tmp": "^0.2.6",
|
||||||
"dotenv": "^16.0.3",
|
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
||||||
"eslint": "^8.33.0",
|
"@typescript-eslint/parser": "^7.8.0",
|
||||||
"eslint-config-prettier": "^8.6.0",
|
"dotenv": "^16.4.5",
|
||||||
"eslint-plugin-jest": "^26.9.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"jest": "^27.5.1",
|
"eslint-plugin-import": "^2.29.1",
|
||||||
"prettier": "^2.8.3",
|
"eslint-plugin-jest": "^28.5.0",
|
||||||
"rimraf": "^4.1.2",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"ts-jest": "^27.1.5",
|
"jest": "^29.7.0",
|
||||||
"ts-node": "^10.9.1",
|
"prettier": "^3.2.5",
|
||||||
"typescript": "^4.9.4"
|
"rimraf": "^5.0.5",
|
||||||
|
"ts-jest": "^29.1.2",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"typescript": "^5.4.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
148
src/builder.ts
148
src/builder.ts
@@ -1,148 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2023 actions-toolkit authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as exec from '@actions/exec';
|
|
||||||
|
|
||||||
import {Buildx} from './buildx';
|
|
||||||
import {Context} from './context';
|
|
||||||
|
|
||||||
export interface BuilderInfo {
|
|
||||||
name?: string;
|
|
||||||
driver?: string;
|
|
||||||
lastActivity?: Date;
|
|
||||||
nodes: NodeInfo[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NodeInfo {
|
|
||||||
name?: string;
|
|
||||||
endpoint?: string;
|
|
||||||
driverOpts?: Array<string>;
|
|
||||||
status?: string;
|
|
||||||
buildkitdFlags?: string;
|
|
||||||
buildkitVersion?: string;
|
|
||||||
platforms?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BuilderOpts {
|
|
||||||
context: Context;
|
|
||||||
buildx?: Buildx;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Builder {
|
|
||||||
private readonly context: Context;
|
|
||||||
private readonly buildx: Buildx;
|
|
||||||
|
|
||||||
constructor(opts: BuilderOpts) {
|
|
||||||
this.context = opts.context;
|
|
||||||
this.buildx =
|
|
||||||
opts?.buildx ||
|
|
||||||
new Buildx({
|
|
||||||
context: this.context
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public async inspect(name: string): Promise<BuilderInfo> {
|
|
||||||
const cmd = this.buildx.getCommand(['inspect', name]);
|
|
||||||
return await exec
|
|
||||||
.getExecOutput(cmd.command, cmd.args, {
|
|
||||||
ignoreReturnCode: true,
|
|
||||||
silent: true
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
|
||||||
throw new Error(res.stderr.trim());
|
|
||||||
}
|
|
||||||
return Builder.parseInspect(res.stdout);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static parseInspect(data: string): BuilderInfo {
|
|
||||||
const builder: BuilderInfo = {
|
|
||||||
nodes: []
|
|
||||||
};
|
|
||||||
let node: NodeInfo = {};
|
|
||||||
for (const line of data.trim().split(`\n`)) {
|
|
||||||
const [key, ...rest] = line.split(':');
|
|
||||||
const value = rest.map(v => v.trim()).join(':');
|
|
||||||
if (key.length == 0 || value.length == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (key.toLowerCase()) {
|
|
||||||
case 'name': {
|
|
||||||
if (builder.name == undefined) {
|
|
||||||
builder.name = value;
|
|
||||||
} else {
|
|
||||||
if (Object.keys(node).length > 0) {
|
|
||||||
builder.nodes.push(node);
|
|
||||||
node = {};
|
|
||||||
}
|
|
||||||
node.name = value;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'driver': {
|
|
||||||
builder.driver = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'last activity': {
|
|
||||||
builder.lastActivity = new Date(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'endpoint': {
|
|
||||||
node.endpoint = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'driver options': {
|
|
||||||
node.driverOpts = (value.match(/(\w+)="([^"]*)"/g) || []).map(v => v.replace(/^(.*)="(.*)"$/g, '$1=$2'));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'status': {
|
|
||||||
node.status = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'flags': {
|
|
||||||
node.buildkitdFlags = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'buildkit': {
|
|
||||||
node.buildkitVersion = value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'platforms': {
|
|
||||||
let platforms: Array<string> = [];
|
|
||||||
// if a preferred platform is being set then use only these
|
|
||||||
// https://docs.docker.com/engine/reference/commandline/buildx_inspect/#get-information-about-a-builder-instance
|
|
||||||
if (value.includes('*')) {
|
|
||||||
for (const platform of value.split(', ')) {
|
|
||||||
if (platform.includes('*')) {
|
|
||||||
platforms.push(platform.replace('*', ''));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// otherwise set all platforms available
|
|
||||||
platforms = value.split(', ');
|
|
||||||
}
|
|
||||||
node.platforms = platforms.join(',');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Object.keys(node).length > 0) {
|
|
||||||
builder.nodes.push(node);
|
|
||||||
}
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
140
src/buildkit.ts
140
src/buildkit.ts
@@ -1,140 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2023 actions-toolkit authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import fs from 'fs';
|
|
||||||
import * as core from '@actions/core';
|
|
||||||
import * as exec from '@actions/exec';
|
|
||||||
import * as semver from 'semver';
|
|
||||||
|
|
||||||
import {Context} from './context';
|
|
||||||
import {Buildx} from './buildx';
|
|
||||||
import {Builder, BuilderInfo} from './builder';
|
|
||||||
|
|
||||||
export interface BuildKitOpts {
|
|
||||||
context: Context;
|
|
||||||
buildx?: Buildx;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class BuildKit {
|
|
||||||
private readonly context: Context;
|
|
||||||
private readonly buildx: Buildx;
|
|
||||||
private containerNamePrefix = 'buildx_buildkit_';
|
|
||||||
|
|
||||||
constructor(opts: BuildKitOpts) {
|
|
||||||
this.context = opts.context;
|
|
||||||
this.buildx =
|
|
||||||
opts?.buildx ||
|
|
||||||
new Buildx({
|
|
||||||
context: this.context
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getBuilderInfo(name: string): Promise<BuilderInfo> {
|
|
||||||
const builder = new Builder({
|
|
||||||
context: this.context,
|
|
||||||
buildx: this.buildx
|
|
||||||
});
|
|
||||||
return builder.inspect(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getVersion(builderName: string): Promise<string | undefined> {
|
|
||||||
const builderInfo = await this.getBuilderInfo(builderName);
|
|
||||||
if (builderInfo.nodes.length == 0) {
|
|
||||||
// a builder always have on node, should not happen.
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
// TODO: get version for all nodes
|
|
||||||
const node = builderInfo.nodes[0];
|
|
||||||
if (!node.buildkitVersion && node.name) {
|
|
||||||
try {
|
|
||||||
return await this.getVersionWithinImage(node.name);
|
|
||||||
} catch (e) {
|
|
||||||
core.warning(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return node.buildkitVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getVersionWithinImage(nodeName: string): Promise<string> {
|
|
||||||
return exec
|
|
||||||
.getExecOutput(`docker`, ['inspect', '--format', '{{.Config.Image}}', `${this.containerNamePrefix}${nodeName}`], {
|
|
||||||
ignoreReturnCode: true,
|
|
||||||
silent: true
|
|
||||||
})
|
|
||||||
.then(bkitimage => {
|
|
||||||
if (bkitimage.exitCode == 0 && bkitimage.stdout.length > 0) {
|
|
||||||
return exec
|
|
||||||
.getExecOutput(`docker`, ['run', '--rm', bkitimage.stdout.trim(), '--version'], {
|
|
||||||
ignoreReturnCode: true,
|
|
||||||
silent: true
|
|
||||||
})
|
|
||||||
.then(bkitversion => {
|
|
||||||
if (bkitversion.exitCode == 0 && bkitversion.stdout.length > 0) {
|
|
||||||
return `${bkitimage.stdout.trim()} => ${bkitversion.stdout.trim()}`;
|
|
||||||
} else if (bkitversion.stderr.length > 0) {
|
|
||||||
throw new Error(bkitimage.stderr.trim());
|
|
||||||
}
|
|
||||||
return bkitversion.stdout.trim();
|
|
||||||
});
|
|
||||||
} else if (bkitimage.stderr.length > 0) {
|
|
||||||
throw new Error(bkitimage.stderr.trim());
|
|
||||||
}
|
|
||||||
return bkitimage.stdout.trim();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public async versionSatisfies(builderName: string, range: string): Promise<boolean> {
|
|
||||||
const builderInfo = await this.getBuilderInfo(builderName);
|
|
||||||
for (const node of builderInfo.nodes) {
|
|
||||||
let bkversion = node.buildkitVersion;
|
|
||||||
if (!bkversion) {
|
|
||||||
try {
|
|
||||||
bkversion = await this.getVersionWithinImage(node.name || '');
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// BuildKit version reported by moby is in the format of `v0.11.0-moby`
|
|
||||||
if (builderInfo.driver == 'docker' && !bkversion.endsWith('-moby')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!semver.satisfies(bkversion.replace(/-moby$/, ''), range)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public generateConfigInline(s: string): string {
|
|
||||||
return this.generateConfig(s, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public generateConfigFile(s: string): string {
|
|
||||||
return this.generateConfig(s, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private generateConfig(s: string, file: boolean): string {
|
|
||||||
if (file) {
|
|
||||||
if (!fs.existsSync(s)) {
|
|
||||||
throw new Error(`config file ${s} not found`);
|
|
||||||
}
|
|
||||||
s = fs.readFileSync(s, {encoding: 'utf-8'});
|
|
||||||
}
|
|
||||||
const configFile = this.context.tmpName({tmpdir: this.context.tmpDir()});
|
|
||||||
fs.writeFileSync(configFile, s);
|
|
||||||
return configFile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
104
src/buildkit/buildkit.ts
Normal file
104
src/buildkit/buildkit.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2023 actions-toolkit authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as core from '@actions/core';
|
||||||
|
import * as semver from 'semver';
|
||||||
|
|
||||||
|
import {Buildx} from '../buildx/buildx';
|
||||||
|
import {Builder} from '../buildx/builder';
|
||||||
|
import {Config} from './config';
|
||||||
|
import {Exec} from '../exec';
|
||||||
|
|
||||||
|
import {BuilderInfo, NodeInfo} from '../types/buildx/builder';
|
||||||
|
|
||||||
|
export interface BuildKitOpts {
|
||||||
|
buildx?: Buildx;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BuildKit {
|
||||||
|
private readonly buildx: Buildx;
|
||||||
|
|
||||||
|
public readonly config: Config;
|
||||||
|
|
||||||
|
constructor(opts?: BuildKitOpts) {
|
||||||
|
this.config = new Config();
|
||||||
|
this.buildx = opts?.buildx || new Buildx();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getVersion(node: NodeInfo): Promise<string | undefined> {
|
||||||
|
if (!node.buildkit && node.name) {
|
||||||
|
try {
|
||||||
|
return await this.getVersionWithinImage(node.name);
|
||||||
|
} catch (e) {
|
||||||
|
core.warning(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node.buildkit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getVersionWithinImage(nodeName: string): Promise<string> {
|
||||||
|
core.debug(`BuildKit.getVersionWithinImage nodeName: ${nodeName}`);
|
||||||
|
return Exec.getExecOutput(`docker`, ['inspect', '--format', '{{.Config.Image}}', `${Buildx.containerNamePrefix}${nodeName}`], {
|
||||||
|
ignoreReturnCode: true,
|
||||||
|
silent: true
|
||||||
|
}).then(bkitimage => {
|
||||||
|
if (bkitimage.exitCode == 0 && bkitimage.stdout.length > 0) {
|
||||||
|
core.debug(`BuildKit.getVersionWithinImage image: ${bkitimage.stdout.trim()}`);
|
||||||
|
return Exec.getExecOutput(`docker`, ['run', '--rm', bkitimage.stdout.trim(), '--version'], {
|
||||||
|
ignoreReturnCode: true,
|
||||||
|
silent: true
|
||||||
|
}).then(bkitversion => {
|
||||||
|
if (bkitversion.exitCode == 0 && bkitversion.stdout.length > 0) {
|
||||||
|
return `${bkitimage.stdout.trim()} => ${bkitversion.stdout.trim()}`;
|
||||||
|
} else if (bkitversion.stderr.length > 0) {
|
||||||
|
throw new Error(bkitimage.stderr.trim());
|
||||||
|
}
|
||||||
|
return bkitversion.stdout.trim();
|
||||||
|
});
|
||||||
|
} else if (bkitimage.stderr.length > 0) {
|
||||||
|
throw new Error(bkitimage.stderr.trim());
|
||||||
|
}
|
||||||
|
return bkitimage.stdout.trim();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async versionSatisfies(builderName: string, range: string, builderInfo?: BuilderInfo): Promise<boolean> {
|
||||||
|
if (!builderInfo) {
|
||||||
|
builderInfo = await new Builder({buildx: this.buildx}).inspect(builderName);
|
||||||
|
}
|
||||||
|
for (const node of builderInfo.nodes) {
|
||||||
|
let bkversion = node.buildkit;
|
||||||
|
core.debug(`BuildKit.versionSatisfies ${bkversion}: ${range}`);
|
||||||
|
if (!bkversion) {
|
||||||
|
try {
|
||||||
|
bkversion = await this.getVersionWithinImage(node.name || '');
|
||||||
|
} catch (e) {
|
||||||
|
core.debug(`BuildKit.versionSatisfies ${node.name}: can't get version`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
core.debug(`BuildKit.versionSatisfies ${node.name}: version ${bkversion}`);
|
||||||
|
// BuildKit version reported by moby is in the format of `v0.11.0-moby`
|
||||||
|
if (builderInfo.driver == 'docker' && !bkversion.endsWith('-moby')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!semver.satisfies(bkversion.replace(/-moby$/, ''), range)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user