Compare commits
647 Commits
Author | SHA1 | Date |
---|---|---|
|
c08cd7bcfb | |
|
243fc424c6 | |
|
8203df0b7a | |
|
1b3b149dbb | |
|
e7822a0290 | |
|
45a5e35df2 | |
|
bc04fbfd78 | |
|
ea2852dd9a | |
|
18140f827a | |
|
d8b50c36e4 | |
|
5d720bb8a0 | |
|
d110e07917 | |
|
751bc8a075 | |
|
c502bcff68 | |
|
38f5d4b793 | |
|
528961a836 | |
|
5e5a81ddb5 | |
|
76d851afc5 | |
|
d82294e03f | |
|
4178e0a07b | |
|
9953a03bda | |
|
0f05ba41fb | |
|
c570d57aa4 | |
|
8df5264704 | |
|
780a56ed93 | |
|
1dfea72f46 | |
|
4a9e235d68 | |
|
f1c4c5766b | |
|
a8acb3f9a7 | |
|
f94abf303b | |
|
32b8c63071 | |
|
b048033711 | |
|
7de8e24e0d | |
|
29954e5d00 | |
|
9aa7522028 | |
|
8748b2e7ad | |
|
911913c80c | |
|
44dbd3c265 | |
|
77442414b8 | |
|
7b41d858fb | |
|
f4251b23f9 | |
|
f6258a2636 | |
|
c9202732af | |
|
bfce5a9547 | |
|
aee15ce0ad | |
|
cfd0824279 | |
|
02e0944151 | |
|
d9acce14c7 | |
|
fa46dd6bc5 | |
|
22e7e9902e | |
|
4356ef99f2 | |
|
c8707aff90 | |
|
0091b94408 | |
|
eae69c59ed | |
|
ed1ae4e868 | |
|
de1b30f66e | |
|
06f47c8204 | |
|
bd8aab272a | |
|
42bd82e6d2 | |
|
fb8eeacdca | |
|
33d9f0028e | |
|
f4c7058406 | |
|
412f8cac6c | |
|
f0c0434f01 | |
|
69d265b0e7 | |
|
ada713fa6c | |
|
6a3cf8beea | |
|
3013147563 | |
|
0c52a76701 | |
|
373252b3c0 | |
|
097ae026e0 | |
|
16f7df2e0c | |
|
7ce42707ac | |
|
ad67679608 | |
|
4a3edac4d4 | |
|
c07956ac9f | |
|
ccae3d1f71 | |
|
7c45a59720 | |
|
08462f4d3d | |
|
814dd1ca07 | |
|
f7c510438b | |
|
727ec51a93 | |
|
3377e89ad9 | |
|
d2bc2a3b9a | |
|
98717b3e4c | |
|
f4737bbcae | |
|
c904f3fc18 | |
|
3dd4637ca5 | |
|
5ffd31d938 | |
|
498ce12916 | |
|
488216c4bc | |
|
c4e0853d16 | |
|
72a4939265 | |
|
29c8c5e587 | |
|
d62dbaa71f | |
|
84bd2d709e | |
|
b1a1235d45 | |
|
74fb89f782 | |
|
9216587f3d | |
|
139f21560b | |
|
608e0af98f | |
|
0791744e95 | |
|
d42c1e350b | |
|
d1a7091db2 | |
|
d8ae516bc8 | |
|
5d0c5afb0e | |
|
795bdb6c80 | |
|
531163eca4 | |
|
3a207733aa | |
|
a01e6f57f5 | |
|
bec357e41d | |
|
4d3df7200a | |
|
a7fcb59b41 | |
|
66ea4c697f | |
|
957699bcc5 | |
|
c04c0d8332 | |
|
43e7572538 | |
|
526a12ef9f | |
|
c9c23f93e9 | |
|
5bb083d020 | |
|
0bf0db866e | |
|
49b6dd589d | |
|
afda559a08 | |
|
9499ff5f45 | |
|
6b72400de6 | |
|
d53a160a25 | |
|
dd74456400 | |
|
cecfc0d579 | |
|
c9cc53fefe | |
|
d62c862a48 | |
|
58dbbf8c3c | |
|
ecfa32a416 | |
|
6301ff0522 | |
|
a8586c106b | |
|
42e607fba9 | |
|
a57c6a326d | |
|
b9e901e235 | |
|
b1ae9b1ee4 | |
|
1669934db9 | |
|
a9e9b62a82 | |
|
10385e72f3 | |
|
9ecdacfa25 | |
|
84fcbcb3cc | |
|
7e9450d314 | |
|
262231455d | |
|
e5edff9946 | |
|
203f9fe12a | |
|
a2a89fdef0 | |
|
07eee611a5 | |
|
3ff70d149e | |
|
3ce6c725e4 | |
|
1517ec3795 | |
|
110012fecc | |
|
f7ac69ddc7 | |
|
325b286d0b | |
|
735e1008ff | |
|
fa2cb5db71 | |
|
b852fbd67b | |
|
5a1ffe9e4a | |
|
4367699d97 | |
|
91e821cb5c | |
|
c405b72492 | |
|
968cf0a6ac | |
|
809fd39d43 | |
|
bf3f0d85e1 | |
|
56d989612d | |
|
cf7fdbd767 | |
|
47853a20ff | |
|
dbdd81d1a3 | |
|
a36c382fa1 | |
|
5fad9fd396 | |
|
3e5d5f7278 | |
|
5d66d5c4c5 | |
|
3988ba7830 | |
|
b13b637677 | |
|
375e81e6d2 | |
|
8a6ae92e88 | |
|
ac1d744f15 | |
|
67bca7aec6 | |
|
2fa127b631 | |
|
0ad8d0b144 | |
|
1f856ee41f | |
|
5432492968 | |
|
3ee9f786e2 | |
|
a2ad772491 | |
|
f1b96de7fe | |
|
2e68ecd1e9 | |
|
e2c4c41dae | |
|
c8840ede49 | |
|
cd90845687 | |
|
17e011c630 | |
|
48337ef606 | |
|
e9e8320d64 | |
|
62bb92dbda | |
|
242b58607d | |
|
0505884cb5 | |
|
02b377c32c | |
|
0adc94f79b | |
|
adab52b298 | |
|
2ee17661f8 | |
|
1ef294691b | |
|
59d8a0c4bb | |
|
2bd55c17ed | |
|
f0ed5cb36b | |
|
6b6c823302 | |
|
0a62dba4e8 | |
|
d666cfe8e3 | |
|
6074760b89 | |
|
813e7deb4a | |
|
6ab5b4f668 | |
|
56c31d3e9b | |
|
603e9b1207 | |
|
b12f10ff97 | |
|
4235a0ec23 | |
|
3930745bec | |
|
c43a300dc4 | |
|
8c9afb6b8b | |
|
0db80b63b3 | |
|
c22572f3bd | |
|
e178a944d6 | |
|
bfcfc0f13d | |
|
713a9499c3 | |
|
8d52264333 | |
|
45c7b74353 | |
|
ce34472d38 | |
|
958a531928 | |
|
75caac9c42 | |
|
f13d2af1a4 | |
|
e2496a24ce | |
|
7ed47a732b | |
|
0af178c514 | |
|
7d615c63ef | |
|
9ef1a21cc0 | |
|
8616a4ca7a | |
|
7410ece496 | |
|
ce21306f08 | |
|
b77f24140e | |
|
e7b5393963 | |
|
d0280c93df | |
|
f0ecebd037 | |
|
b893858477 | |
|
fd46245b3a | |
|
4ad31e11b0 | |
|
b8b16c1382 | |
|
49a2597c07 | |
|
723a8f4cfe | |
|
dc00d430d3 | |
|
8890c9a913 | |
|
f9e36f63bf | |
|
870e3338a1 | |
|
3f26e5551b | |
|
e8a7eebb19 | |
|
0331efe90e | |
|
5352e7080c | |
|
6ab96ffce9 | |
|
f8fcd0a89a | |
|
83dad353d9 | |
|
13d1f73a61 | |
|
221018fe74 | |
|
4d7abdef22 | |
|
0edbcc48d6 | |
|
2914f8895d | |
|
958abb5438 | |
|
003dd2b9fc | |
|
8954029f18 | |
|
76e48787c9 | |
|
a56d3e21ca | |
|
e557e50e84 | |
|
2c2fe0dad1 | |
|
0fe891e8d7 | |
|
06df285152 | |
|
11f06d671b | |
|
d7ef4dcfba | |
|
6d74d55b52 | |
|
051c0f44e0 | |
|
3b4c6d30be | |
|
987415a6f8 | |
|
64ba9dec19 | |
|
ab354230b5 | |
|
0336572461 | |
|
ae7e4fe587 | |
|
f877c20208 | |
|
531e4c440f | |
|
48685a7c85 | |
|
f25ef35441 | |
|
4088e54c67 | |
|
9a613e9591 | |
|
8280237017 | |
|
584ece3e1f | |
|
80521ef38e | |
|
d1e64386fc | |
|
e1a999cfa9 | |
|
7c4705bcc4 | |
|
6b8fc8add9 | |
|
b6dbbcc476 | |
|
5ece0e5027 | |
|
a7e6edbe66 | |
|
96b251e209 | |
|
d9e9ee5f00 | |
|
6c325fd3d1 | |
|
0378f2c134 | |
|
ba5071b500 | |
|
e3074c181f | |
|
6986499806 | |
|
1d954434fe | |
|
6116ed1d9e | |
|
8fe4b4d9ab | |
|
f3e4a55bb3 | |
|
da8c69a2c4 | |
|
0d48762de2 | |
|
d9912ec330 | |
|
fdcf34e13e | |
|
15c49d2a13 | |
|
3fd840ae31 | |
|
3180a33ac2 | |
|
0dec7acff7 | |
|
52cffce497 | |
|
1e0b1351d3 | |
|
45ef326653 | |
|
bec37d2923 | |
|
91a581e0c0 | |
|
4de19906ea | |
|
04db01b558 | |
|
66ec13f929 | |
|
cf150c8802 | |
|
a75ba27081 | |
|
48a6c34c23 | |
|
7fc3d67335 | |
|
03188e3daf | |
|
ef6e4f6dc7 | |
|
ada1ea6581 | |
|
0a008043cb | |
|
5b5e38b2e4 | |
|
1e8287a7e7 | |
|
e292f96d2d | |
|
493d9881b2 | |
|
ef7a248644 | |
|
232f802cd7 | |
|
a00a3713c0 | |
|
2018fad17b | |
|
3333d65455 | |
|
1888d97ebb | |
|
9d6fbc241d | |
|
b6d5a26f79 | |
|
804c1b29be | |
|
06777e6a83 | |
|
5f21c573c7 | |
|
55e087252b | |
|
0115938125 | |
|
0b490fd751 | |
|
42a9fee04d | |
|
85dc1eeda9 | |
|
b4a60bb809 | |
|
0ef5f6710d | |
|
e82e0eec54 | |
|
92c7bacb93 | |
|
3325f90e16 | |
|
f25667dd83 | |
|
590008b44f | |
|
a1d97d6734 | |
|
818be7f582 | |
|
6115e5f562 | |
|
5b7389c251 | |
|
c50f6ec4df | |
|
2165a24896 | |
|
0e027d723f | |
|
2de474a5a7 | |
|
684aafe89c | |
|
2d3d7f4f02 | |
|
8eade6c6f4 | |
|
e01886b8ad | |
|
117fba6c30 | |
|
faece5c355 | |
|
741d8fe16a | |
|
7bd8cb5169 | |
|
a0471b6e0a | |
|
6a83d94543 | |
|
2fe8bb1150 | |
|
1d9b5f4515 | |
|
6c0598a11f | |
|
b8357b48cd | |
|
876cd4eb09 | |
|
ddbf51b9ca | |
|
1fe3e4e2bc | |
|
a6098000e6 | |
|
30e281cd66 | |
|
5021db883c | |
|
92aaab5ad3 | |
|
c80affc2e1 | |
|
0dd744c6d2 | |
|
1723cdfce0 | |
|
b6ba64dfa0 | |
|
a44e50bf2b | |
|
b3b424d803 | |
|
1481037283 | |
|
1e1d8b162e | |
|
d464a76c22 | |
|
54398fe256 | |
|
ae36f50354 | |
|
a6cbb654e7 | |
|
1d1f4b2d2a | |
|
c1062b66a5 | |
|
4937ffab4f | |
|
192f6a9def | |
|
b342dd1962 | |
|
15592c1cea | |
|
02abf96234 | |
|
08abd306f2 | |
|
3ee8ef0eac | |
|
bcb62e8f1e | |
|
ea6cf5090a | |
|
3e2c13fe91 | |
|
2e8fdf277d | |
|
2330778519 | |
|
f29aa2068a | |
|
965a57d69c | |
|
c13cb8e5f8 | |
|
1f67dc9658 | |
|
707e59c8f7 | |
|
10356ac4f4 | |
|
e3da59d262 | |
|
600ae44efd | |
|
7dbd60760a | |
|
e361d5e0f5 | |
|
1efedbd7f7 | |
|
bd043fc803 | |
|
e739642b6f | |
|
06cc76f311 | |
|
366946c3e0 | |
|
719b7ff147 | |
|
6bd010cfbd | |
|
e52a1ac580 | |
|
918407dc3e | |
|
2a5af9afaf | |
|
5863adf1ca | |
|
c6b0cfd25b | |
|
3cd1bbc739 | |
|
d17d979ca1 | |
|
052601f0b6 | |
|
6bad575a09 | |
|
0b5cd009ad | |
|
5af8d9200b | |
|
9f21c5698c | |
|
f8d06a6e2d | |
|
785c9f3fa3 | |
|
d0ee780a27 | |
|
98d649ef70 | |
|
8505f7edbc | |
|
5a0e4bf014 | |
|
486f1462e7 | |
|
aae7ef41f4 | |
|
ebe87a09fb | |
|
c0c1b422b5 | |
|
b7bec64067 | |
|
ce93d670b6 | |
|
3e3ba5e3a8 | |
|
38931c8396 | |
|
c3a766d3f9 | |
|
2164b8a452 | |
|
73617d09c1 | |
|
8b87c174e4 | |
|
cafa80a156 | |
|
2d9093c00c | |
|
241a0d4659 | |
|
05bf943d11 | |
|
3324e6a235 | |
|
9c3d8e1313 | |
|
2f0de36377 | |
|
5db30ae1a7 | |
|
2fb528ffd5 | |
|
58e50f2124 | |
|
3643022260 | |
|
f816d7d35e | |
|
81c91ffb7c | |
|
1a778c3b4c | |
|
117bbe7b93 | |
|
e95fa4691c | |
|
90c778f20a | |
|
2cc584c875 | |
|
88b56f06e8 | |
|
d4ea5db099 | |
|
f07d3cd72e | |
|
dafc473811 | |
|
e116980b41 | |
|
7b9c47206f | |
|
5d966ab5eb | |
|
1a1a26a5c4 | |
|
a6914d7162 | |
|
b1aff185cf | |
|
5ab19cf9b6 | |
|
177746ff70 | |
|
77735ff8e6 | |
|
ab6b22ee45 | |
|
7410720785 | |
|
d16cd7e096 | |
|
842e0f9a14 | |
|
1c69bbfe16 | |
|
87f02c268d | |
|
03adb20f05 | |
|
7fe92ab551 | |
|
78c9877514 | |
|
07e3204438 | |
|
21fbcb324f | |
|
353f851f6a | |
|
11c167a7a9 | |
|
9f51b2733d | |
|
c4a4f9b01b | |
|
92f1f32cd6 | |
|
067590dc31 | |
|
c9806eb7f2 | |
|
934b140016 | |
|
81610b7b99 | |
|
4817399e23 | |
|
07bcb80d9e | |
|
4ebefa7918 | |
|
4e59a9b7bd | |
|
fd0c09d01b | |
|
606a0a9f88 | |
|
84d14e5353 | |
|
b3751e34ef | |
|
c74ffc6d13 | |
|
3e78d72888 | |
|
f6b10a16a4 | |
|
dfc703a143 | |
|
6d9c79ee24 | |
|
82f6e1461d | |
|
65570ee59e | |
|
5e3a904d4b | |
|
a9fa7f3f6b | |
|
9594a17faa | |
|
f29800c92b | |
|
81169b5a2a | |
|
918440fb59 | |
|
0cb2854c47 | |
|
4df562b3a4 | |
|
40ded4d610 | |
|
3ff24a4001 | |
|
cd223c591e | |
|
f5251259b0 | |
|
c31f082b73 | |
|
e731f1288d | |
|
a3d82dada9 | |
|
19e9557da1 | |
|
881ae8c6a7 | |
|
611530945e | |
|
d85636b3d5 | |
|
8b9f59e437 | |
|
38ff1abf83 | |
|
8c55a0928f | |
|
2bf4937220 | |
|
8831c9a279 | |
|
0c92605c5c | |
|
36d797af50 | |
|
98fad096ba | |
|
3a44ccff5a | |
|
d14e97ea79 | |
|
3d2249e171 | |
|
264ec7a86d | |
|
f09a33a963 | |
|
92d5e723b8 | |
|
f42a729811 | |
|
d69d9255c6 | |
|
21ef178447 | |
|
207a180c56 | |
|
f1647cb5ec | |
|
b4e144932a | |
|
2533998737 | |
|
5e11309d7c | |
|
8d2c7caf36 | |
|
df85841cb6 | |
|
fbdbb6f7ac | |
|
62a796fb22 | |
|
d22836b392 | |
|
a70a97db54 | |
|
97e59d2845 | |
|
196a8aa2a4 | |
|
8d8ec2ae31 | |
|
f9a86702e6 | |
|
9cdeb5919c | |
|
536fdc26af | |
|
2cc27c7baa | |
|
3c4c882a04 | |
|
cd1bb911ff | |
|
1edce17f54 | |
|
6e3fdebe2b | |
|
25419a8d57 | |
|
85a3c10137 | |
|
0f9ef3068e | |
|
8204dc6ec2 | |
|
397304e2eb | |
|
50d73f2d77 | |
|
68093b0f1a | |
|
5609f7e1d3 | |
|
3db0b1cd58 | |
|
b3038dd2ad | |
|
5e3db79cda | |
|
e7f48371eb | |
|
4cd1cb8639 | |
|
3700568de0 | |
|
da2228a41b | |
|
493b7ff4fa | |
|
1368589930 | |
|
2a7d261e50 | |
|
22b18df5e4 | |
|
a411570c60 | |
|
a5b7b34879 | |
|
b3f574f373 | |
|
4832ee1ce9 | |
|
44dd9d1e55 | |
|
ac5caff5ea | |
|
c80aa72f7f | |
|
8ccf0d66b5 | |
|
f24464c6ed | |
|
456a4b90ac | |
|
94eabf47c4 | |
|
18fab63b02 | |
|
9324c2f4cf | |
|
4be39a64f2 | |
|
7760893ac0 | |
|
e30e95ef4e | |
|
1b19006a0f | |
|
225b568d52 | |
|
7e3dd1425f | |
|
43682e07eb | |
|
b3d523fb36 | |
|
f9e5484fd3 | |
|
42b79c20f2 | |
|
34788522ff | |
|
2b6b6eb112 | |
|
5927873c43 | |
|
c387e186dd | |
|
5e1b3bf7a3 | |
|
f4b3a1168b | |
|
ba34d06f00 | |
|
ec98e4e130 | |
|
3f9a005923 | |
|
4b014f57ab | |
|
ceb5b2dc06 | |
|
fde86f9a0c | |
|
5508e24bfd | |
|
12581efe74 | |
|
e374a143c6 | |
|
4fa58ceeb0 | |
|
118f8c97c1 | |
|
c76f8a57e3 | |
|
d83ac63cd6 | |
|
e3d17fd452 |
|
@ -1 +1 @@
|
|||
* @buildpacks/distribution-maintainers
|
||||
* @buildpacks/platform-maintainers @buildpacks/toc @edmorley
|
|
@ -1,16 +1,11 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
labels:
|
||||
- semver:patch
|
||||
- type:dependency-upgrade
|
||||
- package-ecosystem: gomod
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
ignore:
|
||||
- dependency-name: github.com/onsi/gomega
|
||||
labels:
|
||||
- semver:patch
|
||||
- type:dependency-upgrade
|
||||
|
|
|
@ -25,3 +25,18 @@
|
|||
- name: type:task
|
||||
description: A general task
|
||||
color: e3d9fc
|
||||
- name: type:informational
|
||||
description: Provides information or notice to the community
|
||||
color: e3d9fc
|
||||
- name: type:poll
|
||||
description: Request for feedback from the community
|
||||
color: e3d9fc
|
||||
- name: note:ideal-for-contribution
|
||||
description: An issue that a contributor can help us with
|
||||
color: 54f7a8
|
||||
- name: note:on-hold
|
||||
description: We can't start working on this issue yet
|
||||
color: 54f7a8
|
||||
- name: note:good-first-issue
|
||||
description: A good first issue to get started with
|
||||
color: 54f7a8
|
||||
|
|
|
@ -4,4 +4,4 @@ github:
|
|||
|
||||
codeowners:
|
||||
- path: "*"
|
||||
owner: "@buildpacks/distribution-maintainers"
|
||||
owner: "@buildpacks/platform-maintainers @buildpacks/toc"
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.6.0
|
||||
1.41.2
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
name: Action buildpack-compute-metadata
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- buildpack/compute-metadata/**
|
||||
- internal/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- buildpack/compute-metadata/**
|
||||
- internal/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: buildpack/compute-metadata/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/buildpack/compute-metadata
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -0,0 +1,76 @@
|
|||
name: Action buildpackage-verify-metadata
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- buildpackage/verify-metadata/**
|
||||
- internal/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- buildpackage/verify-metadata/**
|
||||
- internal/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: buildpackage/verify-metadata/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/buildpackage/verify-metadata
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -0,0 +1,78 @@
|
|||
name: Action registry-add-entry
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/add-entry/**
|
||||
- registry/internal/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/add-entry/**
|
||||
- registry/internal/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: registry/add-entry/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/registry/add-entry
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -0,0 +1,78 @@
|
|||
name: Action registry-compute-metadata
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/compute-metadata/**
|
||||
- registry/internal/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/compute-metadata/**
|
||||
- registry/internal/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: registry/compute-metadata/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/registry/compute-metadata
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -0,0 +1,14 @@
|
|||
name: Creating the PR to update the version of buildpacks/github-actions on buildpacks/registry-index
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
jobs:
|
||||
myEvent:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Repository Dispatch
|
||||
uses: peter-evans/repository-dispatch@v3
|
||||
with:
|
||||
token: ${{ secrets.DISTRIBUTION_GITHUB_TOKEN }}
|
||||
repository: buildpacks/registry-index
|
||||
event-type: release-event
|
|
@ -0,0 +1,78 @@
|
|||
name: Action registry-request-add-entry
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/request-add-entry/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/request-add-entry/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: registry/request-add-entry/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/registry/request-add-entry
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -0,0 +1,78 @@
|
|||
name: Action registry-request-yank-entry
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/request-yank-entry/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/request-yank-entry/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: registry/request-yank-entry/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/registry/request-yank-entry
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -0,0 +1,78 @@
|
|||
name: Action registry-verify-namespace-owner
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/verify-namespace-owner/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/verify-namespace-owner/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: registry/verify-namespace-owner/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/registry/verify-namespace-owner
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -0,0 +1,78 @@
|
|||
name: Action registry-yank-entry
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/yank-entry/**
|
||||
- registry/internal/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/yank-entry/**
|
||||
- registry/internal/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v3.0.0
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: registry/yank-entry/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/registry/yank-entry
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -1,73 +0,0 @@
|
|||
name: Create Action buildpack-info
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- info/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- info/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "::set-output name=version::${VERSION}"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: info/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/buildpack-info
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -1,73 +0,0 @@
|
|||
name: Create Action registry
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- registry/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- registry/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "::set-output name=version::${VERSION}"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: registry/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/registry
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -1,73 +0,0 @@
|
|||
name: Create Action verify-buildpackage
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- verify/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- verify/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "::set-output name=version::${VERSION}"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: verify/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/verify-buildpackage
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: mheap/github-action-required-labels@v1
|
||||
- uses: mheap/github-action-required-labels@v5
|
||||
with:
|
||||
count: 1
|
||||
labels: semver:major, semver:minor, semver:patch
|
||||
|
@ -22,7 +22,7 @@ jobs:
|
|||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: mheap/github-action-required-labels@v1
|
||||
- uses: mheap/github-action-required-labels@v5
|
||||
with:
|
||||
count: 1
|
||||
labels: type:bug, type:dependency-upgrade, type:documentation, type:enhancement, type:question, type:task
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: micnncim/action-label-syncer@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
|
@ -1,5 +1,10 @@
|
|||
name: Tests
|
||||
"on":
|
||||
merge_group:
|
||||
types:
|
||||
- checks_requested
|
||||
branches:
|
||||
- main
|
||||
pull_request: {}
|
||||
push:
|
||||
branches:
|
||||
|
@ -10,15 +15,15 @@ jobs:
|
|||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
path: ${{ env.HOME }}/go/pkg/mod
|
||||
restore-keys: ${{ runner.os }}-go-
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.15"
|
||||
go-version: "1.24"
|
||||
- name: Install richgo
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
@ -37,7 +42,7 @@ jobs:
|
|||
"https://github.com/kyoh86/richgo/releases/download/v${RICHGO_VERSION}/richgo_${RICHGO_VERSION}_linux_amd64.tar.gz" \
|
||||
| tar -C "${HOME}"/bin -xz richgo
|
||||
env:
|
||||
RICHGO_VERSION: 0.3.3
|
||||
RICHGO_VERSION: 0.3.10
|
||||
- name: Run Tests
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
|
@ -0,0 +1,72 @@
|
|||
name: Update Go
|
||||
"on":
|
||||
schedule:
|
||||
- cron: 26 2 * * 1
|
||||
workflow_dispatch: {}
|
||||
jobs:
|
||||
update:
|
||||
name: Update Go
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.24"
|
||||
- uses: actions/checkout@v4
|
||||
- name: Update Go Version & Modules
|
||||
id: update-go
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [ -z "${GO_VERSION:-}" ]; then
|
||||
echo "No go version set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OLD_GO_VERSION=$(grep -P '^go \d\.\d+' go.mod | cut -d ' ' -f 2 | cut -d '.' -f 1-2)
|
||||
|
||||
go mod edit -go="$GO_VERSION"
|
||||
go mod tidy
|
||||
go get -u -t ./...
|
||||
go mod tidy
|
||||
|
||||
git add go.mod go.sum
|
||||
git checkout -- .
|
||||
|
||||
if [ "$OLD_GO_VERSION" == "$GO_VERSION" ]; then
|
||||
COMMIT_TITLE="Bump Go Modules"
|
||||
COMMIT_BODY="Bumps Go modules used by the project. See the commit for details on what modules were updated."
|
||||
COMMIT_SEMVER="semver:patch"
|
||||
else
|
||||
COMMIT_TITLE="Bump Go from ${OLD_GO_VERSION} to ${GO_VERSION}"
|
||||
COMMIT_BODY="Bumps Go from ${OLD_GO_VERSION} to ${GO_VERSION} and update Go modules used by the project. See the commit for details on what modules were updated."
|
||||
COMMIT_SEMVER="semver:minor"
|
||||
fi
|
||||
|
||||
echo "commit-title=${COMMIT_TITLE}" >> "$GITHUB_OUTPUT"
|
||||
echo "commit-body=${COMMIT_BODY}" >> "$GITHUB_OUTPUT"
|
||||
echo "commit-semver=${COMMIT_SEMVER}" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GO_VERSION: "1.24"
|
||||
- uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
author: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }} <${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}@users.noreply.github.com>
|
||||
body: |-
|
||||
${{ steps.update-go.outputs.commit-body }}
|
||||
|
||||
<details>
|
||||
<summary>Release Notes</summary>
|
||||
${{ steps.pipeline.outputs.release-notes }}
|
||||
</details>
|
||||
branch: update/go
|
||||
commit-message: |-
|
||||
${{ steps.update-go.outputs.commit-title }}
|
||||
|
||||
${{ steps.update-go.outputs.commit-body }}
|
||||
delete-branch: true
|
||||
labels: ${{ steps.update-go.outputs.commit-semver }}, type:task
|
||||
signoff: true
|
||||
title: ${{ steps.update-go.outputs.commit-title }}
|
||||
token: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
|
@ -1,5 +1,10 @@
|
|||
name: Update Pipeline
|
||||
"on":
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- .github/pipeline-descriptor.yml
|
||||
schedule:
|
||||
- cron: 0 5 * * 1-5
|
||||
workflow_dispatch: {}
|
||||
|
@ -9,19 +14,19 @@ jobs:
|
|||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-go@v2
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.15"
|
||||
go-version: "1.24"
|
||||
- name: Install octo
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GO111MODULE=on go get -u -ldflags="-s -w" github.com/paketo-buildpacks/pipeline-builder/cmd/octo
|
||||
- uses: actions/checkout@v2
|
||||
- id: pipeline
|
||||
name: Update Pipeline
|
||||
go install -ldflags="-s -w" github.com/paketo-buildpacks/pipeline-builder/cmd/octo@latest
|
||||
- uses: actions/checkout@v4
|
||||
- name: Update Pipeline
|
||||
id: pipeline
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
|
@ -33,6 +38,7 @@ jobs:
|
|||
OLD_VERSION="0.0.0"
|
||||
fi
|
||||
|
||||
rm .github/workflows/pb-*.yml || true
|
||||
octo --descriptor "${DESCRIPTOR}"
|
||||
|
||||
PAYLOAD=$(gh api /repos/paketo-buildpacks/pipeline-builder/releases/latest)
|
||||
|
@ -49,16 +55,25 @@ jobs:
|
|||
)
|
||||
|
||||
git add .github/
|
||||
git add .gitignore
|
||||
|
||||
if [ -f scripts/build.sh ]; then
|
||||
git add scripts/build.sh
|
||||
fi
|
||||
|
||||
git checkout -- .
|
||||
|
||||
echo "::set-output name=old-version::${OLD_VERSION}"
|
||||
echo "::set-output name=new-version::${NEW_VERSION}"
|
||||
echo "::set-output name=release-notes::${RELEASE_NOTES//$'\n'/%0A}"
|
||||
echo "old-version=${OLD_VERSION}" >> "$GITHUB_OUTPUT"
|
||||
echo "new-version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
DELIMITER=$(openssl rand -hex 16) # roughly the same entropy as uuid v4 used in https://github.com/actions/toolkit/blob/b36e70495fbee083eb20f600eafa9091d832577d/packages/core/src/file-command.ts#L28
|
||||
printf "release-notes<<%s\n%s\n%s\n" "${DELIMITER}" "${RELEASE_NOTES}" "${DELIMITER}" >> "${GITHUB_OUTPUT}" # see https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
|
||||
env:
|
||||
DESCRIPTOR: .github/pipeline-descriptor.yml
|
||||
GITHUB_TOKEN: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
- uses: peter-evans/create-pull-request@v3
|
||||
- uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
author: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }} <${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}@users.noreply.github.com>
|
||||
body: |-
|
||||
Bumps pipeline from `${{ steps.pipeline.outputs.old-version }}` to `${{ steps.pipeline.outputs.new-version }}`.
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
name: update-pack-version
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
types:
|
||||
- pack-release
|
||||
|
||||
jobs:
|
||||
update-pack-version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Retrieve latest pack version
|
||||
id: version
|
||||
run: |
|
||||
NEW_VERSION=$(curl -s -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/buildpacks/pack/releases/latest | jq .tag_name -r | cut -c 2-)
|
||||
echo "new_version=${NEW_VERSION}" >> ${GITHUB_OUTPUT}
|
||||
- name: Update setup-pack/action.yml with the new Pack version
|
||||
run: |
|
||||
sed -i -z "s/default: '[0-9]\{1,\}.[0-9]\{1,\}.[0-9]\{1,\}'/default: '${{ steps.version.outputs.new_version }}'/" setup-pack/action.yml
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
token: ${{ secrets.DISTRIBUTION_GITHUB_TOKEN }}
|
||||
commit-message: Update default Pack version to v${{ steps.version.outputs.new_version }}
|
||||
title: Update default Pack version to v${{ steps.version.outputs.new_version }}
|
||||
body: |
|
||||
Updates the `setup-pack` action's default `pack-version` to the latest Pack release.
|
||||
|
||||
Release notes:
|
||||
https://github.com/buildpacks/pack/releases/tag/v${{ steps.version.outputs.new_version }}
|
||||
labels: |
|
||||
semver:patch
|
||||
type:dependency-upgrade
|
||||
branch: update-version
|
||||
base: main
|
||||
signoff: true
|
|
@ -11,3 +11,10 @@
|
|||
# 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.
|
||||
|
||||
bin/
|
||||
linux/
|
||||
dependencies/
|
||||
package/
|
||||
scratch/
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
FROM golang:1.15 as build-stage
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends upx
|
||||
FROM golang:1.24 as build-stage
|
||||
|
||||
WORKDIR /src
|
||||
ENV GO111MODULE=on CGO_ENABLED=0
|
||||
|
@ -17,9 +15,8 @@ RUN go build \
|
|||
|
||||
RUN strip /bin/action
|
||||
|
||||
RUN upx -q -9 /bin/action
|
||||
|
||||
FROM scratch
|
||||
LABEL org.opencontainers.image.source=https://github.com/buildpacks/github-actions
|
||||
COPY --from=build-stage /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||
COPY --from=build-stage /bin/action /bin/action
|
||||
ENTRYPOINT ["/bin/action"]
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -187,7 +187,7 @@
|
|||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
Copyright 2020 The Cloud Native Buildpacks Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
223
README.md
223
README.md
|
@ -1,36 +1,42 @@
|
|||
# GitHub Actions
|
||||
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/4748)
|
||||
|
||||
`github-actions` is a collection of end-user [GitHub Actions][gha] that integrate with Cloud Native Buildpacks projects.
|
||||
|
||||
[gha]: https://docs.github.com/en/free-pro-team@latest/actions
|
||||
|
||||
- [GitHub Actions](#github-actions)
|
||||
- [Buildpack Info Action](#buildpack-info-action)
|
||||
- [Inputs](#inputs)
|
||||
- [Outputs](#outputs)
|
||||
- [Registry Action](#registry-action)
|
||||
- [Add](#add)
|
||||
- [Inputs](#inputs-1)
|
||||
- [Yank](#yank)
|
||||
- [Inputs](#inputs-2)
|
||||
- [Buildpack](#buildpack)
|
||||
- [Compute Metadata Action](#compute-metadata-action)
|
||||
- [Buildpackage](#buildpackage)
|
||||
- [Verify Metadata Action](#verify-metadata-action)
|
||||
- [Registry](#registry)
|
||||
- [Add Entry Action](#add-entry-action)
|
||||
- [Compute Registry Metadata Action](#compute-registry-metadata-action)
|
||||
- [Request Add Entry Action](#request-add-entry-action)
|
||||
- [Request Yank Entry Action](#request-yank-entry-action)
|
||||
- [Verify Namespace Owner Action](#verify-namespace-owner-action)
|
||||
- [Yank Entry Action](#yank-entry-action)
|
||||
- [Setup pack CLI Action](#setup-pack-cli-action)
|
||||
- [Inputs](#inputs-3)
|
||||
- [Verify Buildpackage Action](#verify-buildpackage-action)
|
||||
- [Inputs](#inputs-4)
|
||||
- [Setup Tools Action](#setup-tools-action)
|
||||
- [License](#license)
|
||||
|
||||
## Buildpack Info Action
|
||||
The buildpack-info action parses a `buildpack.toml` and exposes the contents of the `[buildpack]` block as output parameters.
|
||||
## Buildpack
|
||||
|
||||
### Compute Metadata Action
|
||||
The `buildpack/compute-metadata` action parses a `buildpack.toml` and exposes the contents of the `[buildpack]` block as output parameters.
|
||||
|
||||
```yaml
|
||||
uses: docker://ghcr.io/buildpacks/actions/buildpack-info
|
||||
uses: docker://ghcr.io/buildpacks/actions/buildpack/compute-metadata
|
||||
```
|
||||
|
||||
#### Inputs
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `path` | Optional path to `buildpack.toml`. Defaults to `<working-dir>/buildpack.toml`
|
||||
|
||||
#### Outputs
|
||||
#### Outputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `id` | The contents of `buildpack.id`
|
||||
|
@ -38,22 +44,91 @@ uses: docker://ghcr.io/buildpacks/actions/buildpack-info
|
|||
| `version` | The contents of `buildpack.version`
|
||||
| `homepage` | The contents of `buildpack.homepage`
|
||||
|
||||
## Registry Action
|
||||
The registry action adds and yanks buildpack releases in the [Buildpack Registry Index][bri].
|
||||
## Buildpackage
|
||||
|
||||
### Verify Metadata Action
|
||||
The `buildpackage/verify-metadata` action parses the metadata on a buildpackage and verifies that the `id` and `version` match expected values.
|
||||
|
||||
```yaml
|
||||
uses: docker://ghcr.io/buildpacks/actions/buildpackage/verify-metadata
|
||||
with:
|
||||
id: test-buildpack
|
||||
version: "1.0.0"
|
||||
address: ghcr.io/example/test-buildpack@sha256:04ba2d17480910bd340f0305d846b007148dafd64bc6fc2626870c174b7c7de7
|
||||
```
|
||||
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `id` | The expected `id` for the buildpackage
|
||||
| `version` | The expected `version` for the buildpackage
|
||||
| `address` | The digest-style address of the buildpackage to verify
|
||||
|
||||
## Registry
|
||||
[bri]: https://github.com/buildpacks/registry-index
|
||||
|
||||
### Add
|
||||
### Add Entry Action
|
||||
The `registry/add-entry` adds an entry to the [Buildpack Registry Index][bri].
|
||||
|
||||
```yaml
|
||||
uses: docker://ghcr.io/buildpacks/actions/registry
|
||||
uses: docker://ghcr.io/buildpacks/actions/registry/add-entry
|
||||
with:
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
owner: ${{ env.INDEX_OWNER }}
|
||||
repository: ${{ env.INDEX_REPOSITORY }}
|
||||
namespace: ${{ steps.metadata.outputs.namespace }}
|
||||
name: ${{ steps.metadata.outputs.name }}
|
||||
version: ${{ steps.metadata.outputs.version }}
|
||||
address: ${{ steps.metadata.outputs.address }}
|
||||
```
|
||||
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `token` | A GitHub token with permissions to commit to the registry index repository.
|
||||
| `owner` | The owner name of the registry index repository.
|
||||
| `repository` | The repository name of the registry index repository.
|
||||
| `namespace` | The namespace of the buildpack to register.
|
||||
| `name` | The name of the buildpack to register.
|
||||
| `version` | The version of the buildpack to register.
|
||||
| `address` | The address of the buildpack to register.
|
||||
|
||||
### Compute Registry Metadata Action
|
||||
The `registry/compute-metadata` action parses a [`buildpacks/registry-index`][bri] issue and exposes the contents as output parameters.
|
||||
|
||||
```yaml
|
||||
uses: docker://ghcr.io/buildpacks/actions/registry/compute-metadata
|
||||
with:
|
||||
issue: ${{ toJSON(github.events.issue) }}
|
||||
```
|
||||
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `issue` | The GitHub issue payload.
|
||||
|
||||
#### Outputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `id` | The contents of `id`
|
||||
| `version` | The contents of `version`
|
||||
| `address` | The contents of `addr`
|
||||
| `namespace` | The namespace portion of `id`
|
||||
| `name` | The name portion of `id`
|
||||
|
||||
### Request Add Entry Action
|
||||
The `registry/request-add-entry` action adds an entry to the [Buildpack Registry Index][bri].
|
||||
|
||||
```yaml
|
||||
uses: docker://ghcr.io/buildpacks/actions/registry/request-add-entry
|
||||
with:
|
||||
token: ${{ secrets.IMPLEMENTATION_PAT }}
|
||||
id: $buildpacksio/test-buildpack
|
||||
version: {{ steps.deploy.outputs.version }}
|
||||
version: ${{ steps.deploy.outputs.version }}
|
||||
address: index.docker.io/buildpacksio/test-buildpack@${{ steps.deploy.outputs.digest }}
|
||||
```
|
||||
|
||||
#### Inputs
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `token` | A GitHub token with `public_repo` scope to open an issue against [`buildpacks/registry-index`][bri].
|
||||
|
@ -61,61 +136,101 @@ with:
|
|||
| `version` | The version of the buildpack that is being added to the registry.
|
||||
| `address` | The Docker URI of the buildpack artifact. This is must be in `{host}/{repo}@{digest}` form.
|
||||
|
||||
### Yank
|
||||
### Request Yank Entry Action
|
||||
The `registry/request-yank-entry` action yanks an entry from the [Buildpack Registry Index][bri].
|
||||
|
||||
```yaml
|
||||
uses: docker://ghcr.io/buildpacks/actions/registry
|
||||
uses: docker://ghcr.io/buildpacks/actions/registry/request-yank-entry
|
||||
with:
|
||||
token: ${{ secrets.IMPLEMENTATION_PAT }}
|
||||
id: buildpacksio/test-buildpack
|
||||
version: ${{ steps.deploy.outputs.version }}
|
||||
yank: true
|
||||
```
|
||||
|
||||
#### Inputs
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `token` | A GitHub token with `public_repo` scope to open an issue against [`buildpacks/registry-index`][bri].
|
||||
| `id` | A buildpack id that your user is allowed to manage. This is must be in `{namespace}/{name}` format.
|
||||
| `version` | The version of the buildpack that is being added to the registry.
|
||||
| `yank` | `true` if this version should be yanked.
|
||||
|
||||
### Verify Namespace Owner Action
|
||||
The `registry/verify-namespace-owner` action verifies that a user is an owner of a namespace in the [Buildpack Registry Index][bri].
|
||||
|
||||
```yaml
|
||||
uses: docker://ghcr.io/buildpacks/actions/registry/verify-namespace-owner
|
||||
with:
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
owner: ${{ env.NAMESPACES_OWNER }}
|
||||
repository: ${{ env.NAMESPACES_REPOSITORY }}
|
||||
namespace: ${{ steps.metadata.outputs.namespace }}
|
||||
user: ${{ toJSON(github.event.issue.user) }}
|
||||
add-if-missing: true
|
||||
```
|
||||
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `token` | A GitHub token with permissions to commit to the registry namespaces repository.
|
||||
| `owner` | The owner name of the registry namespaces repository.
|
||||
| `repository` | The repository name of the registry namespaces repository.
|
||||
| `namespace` | The namespace to check ownership for.
|
||||
| `user` | The Github user payload.
|
||||
| `add-if-missing` | Whether to add the current user as the owner of the namespace if that namespace does not exist. (Optional. Default `false`)
|
||||
|
||||
### Yank Entry Action
|
||||
The `registry/yank-entry` action yanks an entry from the [Buildpack Registry Index][bri].
|
||||
|
||||
```yaml
|
||||
uses: docker://ghcr.io/buildpacks/actions/registry/yank-entry
|
||||
with:
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
owner: ${{ env.INDEX_OWNER }}
|
||||
repository: ${{ env.INDEX_REPOSITORY }}
|
||||
namespace: ${{ steps.metadata.outputs.namespace }}
|
||||
name: ${{ steps.metadata.outputs.name }}
|
||||
version: ${{ steps.metadata.outputs.version }}
|
||||
```
|
||||
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `token` | A GitHub token with permissions to commit to the registry index repository.
|
||||
| `owner` | The owner name of the registry index repository.
|
||||
| `repository` | The repository name of the registry index repository.
|
||||
| `namespace` | The namespace of the buildpack to register.
|
||||
| `name` | The name of the buildpack to register.
|
||||
| `version` | The version of the buildpack to register.
|
||||
|
||||
## Setup pack CLI Action
|
||||
The setup-pack action adds [crane][crane], [`jq`][jq], [`pack`][pack], and [`yj`][yj] to the environment.
|
||||
The `setup-pack` action adds [`pack`][pack] to the environment.
|
||||
|
||||
[pack]: https://github.com/buildpacks/pack
|
||||
|
||||
```yaml
|
||||
uses: buildpacks/github-actions/setup-pack@v5.0.0
|
||||
```
|
||||
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `pack-version` | Optional version of [`pack`][pack] to install. Defaults to latest release.
|
||||
|
||||
## Setup Tools Action
|
||||
The `setup-tools` action adds [crane][crane] and [`yj`][yj] to the environment.
|
||||
|
||||
[crane]: https://github.com/google/go-containerregistry/tree/master/cmd/crane
|
||||
[jq]: https://stedolan.github.io/jq/
|
||||
[pack]: https://github.com/buildpacks/pack
|
||||
[yj]: https://github.com/sclevine/yj
|
||||
|
||||
```yaml
|
||||
uses: buildpacks/github-actions/setup-pack
|
||||
uses: buildpacks/github-actions/setup-tools@v5.0.0
|
||||
```
|
||||
|
||||
#### Inputs
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `crane-version` | Optional version of [`crane`][crane] to install. Defaults to latest release.
|
||||
| `jq-version` | Optional version of [`jq`][jq] to install. Defaults to latest release.
|
||||
| `pack-version` | Optional version of [`pack`][pack] to install. Defaults to latest release.
|
||||
| `yj-version` | Optional version of [`yj`][yj] to install. Defaults to latest release.
|
||||
|
||||
## Verify Buildpackage Action
|
||||
The verify-buildpackage action parses the metadata on a buildpackage and verifies that the `id` and `version` match expected values.
|
||||
|
||||
```yaml
|
||||
uses: docker://ghcr.io/buildpacks/actions/verify-buildpackage
|
||||
with:
|
||||
id: test-buildpack
|
||||
version: "1.0.0"
|
||||
address: ghcr.io/example/test-buildpack@sha256:04ba2d17480910bd340f0305d846b007148dafd64bc6fc2626870c174b7c7de7
|
||||
```
|
||||
|
||||
#### Inputs
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `id` | The expected `id` for the buildpackage
|
||||
| `version` | The expected `version` for the buildpackage
|
||||
| `address` | The digest-style address of the buildpackage to verify
|
||||
| `crane-version` | Optional version of [`crane`][crane] to install. Defaults to `0.12.1`.
|
||||
| `yj-version` | Optional version of [`yj`][yj] to install. Defaults to `5.1.0`.
|
||||
|
||||
## License
|
||||
This library is released under version 2.0 of the [Apache License][a].
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/buildpacks/github-actions/buildpack/compute-metadata"
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := metadata.ComputeMetadata(&toolkit.DefaultToolkit{}); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package metadata
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/buildpacks/libcnb"
|
||||
"github.com/pelletier/go-toml"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
)
|
||||
|
||||
func ComputeMetadata(tk toolkit.Toolkit) error {
|
||||
c := parseConfig(tk)
|
||||
|
||||
b, err := ioutil.ReadFile(c.Path)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to read %s", c.Path)
|
||||
}
|
||||
|
||||
var bp libcnb.Buildpack
|
||||
if err := toml.Unmarshal(b, &bp); err != nil {
|
||||
return toolkit.FailedErrorf("unable to unmarshal %s", c.Path)
|
||||
}
|
||||
|
||||
fmt.Printf(`Metadata:
|
||||
ID: %s
|
||||
Name: %s
|
||||
Version: %s
|
||||
Homepage: %s
|
||||
`, bp.Info.ID, bp.Info.Name, bp.Info.Version, bp.Info.Homepage)
|
||||
|
||||
tk.SetOutput("id", bp.Info.ID)
|
||||
tk.SetOutput("name", bp.Info.Name)
|
||||
tk.SetOutput("version", bp.Info.Version)
|
||||
tk.SetOutput("homepage", bp.Info.Homepage)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type config struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
func parseConfig(tk toolkit.Toolkit) config {
|
||||
c := config{Path: "buildpack.toml"}
|
||||
|
||||
if s, ok := tk.GetInput("path"); ok {
|
||||
c.Path = s
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2020 the original author or authors.
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,10 +14,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package info_test
|
||||
package metadata_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
|
@ -25,31 +24,29 @@ import (
|
|||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
|
||||
"github.com/buildpacks/github-actions/info"
|
||||
"github.com/buildpacks/github-actions/buildpack/compute-metadata"
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
)
|
||||
|
||||
func TestBuildpackInfo(t *testing.T) {
|
||||
spec.Run(t, "buildpack-info", func(t *testing.T, when spec.G, it spec.S) {
|
||||
func TestComputeMetadata(t *testing.T) {
|
||||
spec.Run(t, "compute-metadata", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
b = &bytes.Buffer{}
|
||||
|
||||
i = info.BuildpackInfo{
|
||||
Path: filepath.Join("testdata", "buildpack.toml"),
|
||||
Writer: b,
|
||||
}
|
||||
tk = &toolkit.MockToolkit{}
|
||||
)
|
||||
|
||||
it("informs", func() {
|
||||
Expect(i.Inform()).To(Succeed())
|
||||
it.Before(func() {
|
||||
tk.On("GetInput", "path").Return(filepath.Join("testdata", "buildpack.toml"), true)
|
||||
})
|
||||
|
||||
Expect(b.String()).To(Equal(`::set-output name=id::test-id
|
||||
::set-output name=name::test-name
|
||||
::set-output name=version::test-version
|
||||
::set-output name=homepage::test-homepage
|
||||
`,
|
||||
))
|
||||
it("computes metadata", func() {
|
||||
tk.On("SetOutput", "id", "test-id")
|
||||
tk.On("SetOutput", "name", "test-name")
|
||||
tk.On("SetOutput", "version", "test-version")
|
||||
tk.On("SetOutput", "homepage", "test-homepage")
|
||||
|
||||
Expect(metadata.ComputeMetadata(tk)).To(Succeed())
|
||||
})
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
|
@ -22,32 +22,13 @@ import (
|
|||
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
|
||||
"github.com/buildpacks/github-actions/verify"
|
||||
"github.com/buildpacks/github-actions/buildpackage/verify-metadata"
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
v verify.Verifier
|
||||
|
||||
err error
|
||||
ok bool
|
||||
)
|
||||
|
||||
v.Image = remote.Image
|
||||
|
||||
if v.ID, ok = os.LookupEnv("INPUT_ID"); !ok {
|
||||
panic(fmt.Errorf("id must be specified"))
|
||||
}
|
||||
|
||||
if v.Version, ok = os.LookupEnv("INPUT_VERSION"); !ok {
|
||||
panic(fmt.Errorf("version must be specified"))
|
||||
}
|
||||
|
||||
if v.Address, ok = os.LookupEnv("INPUT_ADDRESS"); !ok {
|
||||
panic(fmt.Errorf("address must be specified"))
|
||||
}
|
||||
|
||||
if err = v.Verify(); err != nil {
|
||||
panic(err)
|
||||
if err := metadata.VerifyMetadata(&toolkit.DefaultToolkit{}, remote.Image); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package metadata
|
||||
|
||||
import (
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
)
|
||||
|
||||
//go:generate mockery --all --output=./internal/mocks --case=underscore
|
||||
|
||||
type ImageFunction func(name.Reference, ...remote.Option) (v1.Image, error)
|
|
@ -0,0 +1,46 @@
|
|||
// Code generated by mockery v2.4.0-beta. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
name "github.com/google/go-containerregistry/pkg/name"
|
||||
remote "github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
)
|
||||
|
||||
// ImageFunction is an autogenerated mock type for the ImageFunction type
|
||||
type ImageFunction struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Execute provides a mock function with given fields: _a0, _a1
|
||||
func (_m *ImageFunction) Execute(_a0 name.Reference, _a1 ...remote.Option) (v1.Image, error) {
|
||||
_va := make([]interface{}, len(_a1))
|
||||
for _i := range _a1 {
|
||||
_va[_i] = _a1[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, _a0)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 v1.Image
|
||||
if rf, ok := ret.Get(0).(func(name.Reference, ...remote.Option) v1.Image); ok {
|
||||
r0 = rf(_a0, _a1...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(v1.Image)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(name.Reference, ...remote.Option) error); ok {
|
||||
r1 = rf(_a0, _a1...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package metadata
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
)
|
||||
|
||||
const MetadataLabel = "io.buildpacks.buildpackage.metadata"
|
||||
|
||||
func VerifyMetadata(tk toolkit.Toolkit, imageFn ImageFunction) error {
|
||||
c, err := parseConfig(tk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ref, err := name.ParseReference(c.Address)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to parse address %s as image reference", c.Address)
|
||||
}
|
||||
|
||||
if _, ok := ref.(name.Digest); !ok {
|
||||
return toolkit.FailedErrorf("address %s must be in digest form <host>/<repository>@sh256:<digest>", c.Address)
|
||||
}
|
||||
|
||||
image, err := imageFn(ref)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to retrieve image %s", c.Address)
|
||||
}
|
||||
|
||||
configFile, err := image.ConfigFile()
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to retrieve config file\n%w", err)
|
||||
}
|
||||
|
||||
raw, ok := configFile.Config.Labels[MetadataLabel]
|
||||
if !ok {
|
||||
return toolkit.FailedErrorf("unable to retrieve %s label", MetadataLabel)
|
||||
}
|
||||
|
||||
var m metadata
|
||||
if err := json.Unmarshal([]byte(raw), &m); err != nil {
|
||||
return toolkit.FailedErrorf("unable to unmarshal %s label", MetadataLabel)
|
||||
}
|
||||
|
||||
if c.ID != m.ID {
|
||||
return toolkit.FailedErrorf("invalid id in buildpackage: expected %s, found %s", c.ID, m.ID)
|
||||
}
|
||||
|
||||
if c.Version != m.Version {
|
||||
return toolkit.FailedErrorf("invalid version in buildpackage: expected %s, found %s", c.Version, m.Version)
|
||||
|
||||
}
|
||||
|
||||
var stacks []string
|
||||
for _, s := range m.Stacks {
|
||||
stacks = append(stacks, s.ID)
|
||||
}
|
||||
|
||||
fmt.Printf(`Verified %s
|
||||
ID: %s
|
||||
Version: %s
|
||||
Homepage: %s
|
||||
Stacks: %s
|
||||
`, c.Address, m.ID, m.Version, m.Homepage, strings.Join(stacks, ", "))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type config struct {
|
||||
ID string
|
||||
Version string
|
||||
Address string
|
||||
}
|
||||
|
||||
func parseConfig(tk toolkit.Toolkit) (config, error) {
|
||||
var (
|
||||
c config
|
||||
ok bool
|
||||
)
|
||||
|
||||
c.ID, ok = tk.GetInput("id")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("id must be specified")
|
||||
}
|
||||
|
||||
c.Version, ok = tk.GetInput("version")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("version must be specified")
|
||||
}
|
||||
|
||||
c.Address, ok = tk.GetInput("address")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("address must be specified")
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
type metadata struct {
|
||||
ID string
|
||||
Version string
|
||||
Homepage string
|
||||
Stacks []stack
|
||||
}
|
||||
|
||||
type stack struct {
|
||||
ID string
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package metadata_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/fake"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/buildpacks/github-actions/buildpackage/verify-metadata"
|
||||
"github.com/buildpacks/github-actions/buildpackage/verify-metadata/internal/mocks"
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
)
|
||||
|
||||
func TestVerifyMetadata(t *testing.T) {
|
||||
spec.Run(t, "verify-metadata", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
f = &mocks.ImageFunction{}
|
||||
i = &fake.FakeImage{}
|
||||
|
||||
tk = &toolkit.MockToolkit{}
|
||||
)
|
||||
|
||||
it.Before(func() {
|
||||
tk.On("GetInput", "id").Return("test-id", true)
|
||||
tk.On("GetInput", "version").Return("test-version", true)
|
||||
})
|
||||
|
||||
it("fails if address is not a digest image reference", func() {
|
||||
tk.On("GetInput", "address").Return("test-host/test-repository:test-version", true)
|
||||
|
||||
Expect(metadata.VerifyMetadata(tk, f.Execute)).
|
||||
To(MatchError("::error ::address test-host/test-repository:test-version must be in digest form <host>/<repository>@sh256:<digest>"))
|
||||
})
|
||||
|
||||
context("valid address", func() {
|
||||
it.Before(func() {
|
||||
tk.On("GetInput", "address").Return("host/repository@sha256:04ba2d17480910bd340f0305d846b007148dafd64bc6fc2626870c174b7c7de7", true)
|
||||
f.On("Execute", mock.Anything).Return(i, nil)
|
||||
})
|
||||
|
||||
it("fails if io.buildpacks.buildpackage.metadata is not on image", func() {
|
||||
i.ConfigFileReturns(&v1.ConfigFile{
|
||||
Config: v1.Config{
|
||||
Labels: map[string]string{},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
Expect(metadata.VerifyMetadata(tk, f.Execute)).
|
||||
To(MatchError("::error ::unable to retrieve io.buildpacks.buildpackage.metadata label"))
|
||||
})
|
||||
|
||||
it("fails if id does not match", func() {
|
||||
i.ConfigFileReturns(&v1.ConfigFile{
|
||||
Config: v1.Config{
|
||||
Labels: map[string]string{metadata.MetadataLabel: `{ "id": "another-id", "version": "test-version" }`},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
Expect(metadata.VerifyMetadata(tk, f.Execute)).
|
||||
To(MatchError("::error ::invalid id in buildpackage: expected test-id, found another-id"))
|
||||
})
|
||||
|
||||
it("fails if version does not match", func() {
|
||||
i.ConfigFileReturns(&v1.ConfigFile{
|
||||
Config: v1.Config{
|
||||
Labels: map[string]string{metadata.MetadataLabel: `{ "id": "test-id", "version": "another-version" }`},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
Expect(metadata.VerifyMetadata(tk, f.Execute)).
|
||||
To(MatchError("::error ::invalid version in buildpackage: expected test-version, found another-version"))
|
||||
})
|
||||
|
||||
it("passes if version and id match", func() {
|
||||
i.ConfigFileReturns(&v1.ConfigFile{
|
||||
Config: v1.Config{
|
||||
Labels: map[string]string{metadata.MetadataLabel: `{ "id": "test-id", "version": "test-version" }`},
|
||||
},
|
||||
}, nil)
|
||||
|
||||
Expect(metadata.VerifyMetadata(tk, f.Execute)).To(Succeed())
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
43
go.mod
43
go.mod
|
@ -1,13 +1,42 @@
|
|||
module github.com/buildpacks/github-actions
|
||||
|
||||
go 1.15
|
||||
go 1.24
|
||||
|
||||
require (
|
||||
github.com/buildpacks/libcnb v1.18.0
|
||||
github.com/google/go-containerregistry v0.1.4
|
||||
github.com/google/go-github/v32 v32.1.0
|
||||
github.com/onsi/gomega v1.10.3
|
||||
github.com/pelletier/go-toml v1.8.1
|
||||
github.com/buildpacks/libcnb v1.30.4
|
||||
github.com/google/go-containerregistry v0.20.6
|
||||
github.com/google/go-github/v39 v39.2.0
|
||||
github.com/onsi/gomega v1.38.0
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/sclevine/spec v1.4.0
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
|
||||
github.com/stretchr/testify v1.10.0
|
||||
golang.org/x/oauth2 v0.30.0
|
||||
gopkg.in/retry.v1 v1.0.3
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.17.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/cli v28.3.3+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.9.3 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/vbatts/tar-split v0.12.1 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
816
go.sum
816
go.sum
|
@ -1,758 +1,116 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v42.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
|
||||
github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/aws/aws-sdk-go v1.28.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.31.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/buildpacks/libcnb v1.18.0 h1:Q7I+HjQ1Cq02/AqhTOrzecuNESip9xE2axckxnymYLQ=
|
||||
github.com/buildpacks/libcnb v1.18.0/go.mod h1:yzAQd//jyUXVx6Z/F0cKk/hrl49QZq1OE/hP5+/ZPuQ=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/buildpacks/libcnb v1.30.4 h1:Jp6cJxYsZQgqix+lpRdSpjHt5bv5yCJqgkw9zWmS6xU=
|
||||
github.com/buildpacks/libcnb v1.30.4/go.mod h1:vjEDAlK3/Rf67AcmBzphXoqIlbdFgBNUK5d8wjreJbY=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.17.0 h1:+TyQIsR/zSFI1Rm31EQBwpAA1ovYgIKHy7kctL3sLcE=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.17.0/go.mod h1:s06tWAiJcXQo9/8AReBCIo/QxcXFZ2n4qfsRnpl71SM=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017 h1:2HQmlpI3yI9deH18Q6xiSOIjXD4sLI55Y/gfpa8/558=
|
||||
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7 h1:Cvj7S8I4Xpx78KAl6TwTmMHuHlZ/0SM60NUneGJQ7IE=
|
||||
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
|
||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/docker/cli v28.3.3+incompatible h1:fp9ZHAr1WWPGdIWBM1b3zLtgCF+83gRdVMTJsUeiyAo=
|
||||
github.com/docker/cli v28.3.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||
github.com/frankban/quicktest v1.2.2 h1:xfmOhhoH5fGPgbEAlhLpJH9p0z/0Qizio9osmvn9IUY=
|
||||
github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-containerregistry v0.1.4 h1:fZm+V2pYnvb8NMPM1YOsyxr31XKfpHTun5oVTRnG8qc=
|
||||
github.com/google/go-containerregistry v0.1.4/go.mod h1:6EGiuQp36pL82lX6rFN0s9AJOVL0Mlgx/DAsYZW5X3s=
|
||||
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
|
||||
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
|
||||
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU=
|
||||
github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=
|
||||
github.com/google/go-github/v39 v39.2.0 h1:rNNM311XtPOz5rDdsJXAp2o8F67X9FnROXTvto3aSnQ=
|
||||
github.com/google/go-github/v39 v39.2.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA=
|
||||
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
|
||||
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
|
||||
github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
|
||||
github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a h1:3QH7VyOaaiUHNrA9Se4YQIRkDTCw1EJls9xTUCaCeRM=
|
||||
github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a/go.mod h1:4r5QyqhjIWCcK8DO4KMclc5Iknq5qVBAlbYYzAbUScQ=
|
||||
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
|
||||
github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/vdemeester/k8s-pkg-credentialprovider v1.18.1-0.20201019120933-f1d16962a4db/go.mod h1:grWy0bkr1XO6hqbaaCKaPXqkBVlMGHYG6PGykktwbJc=
|
||||
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo=
|
||||
github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
|
||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M=
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/retry.v1 v1.0.3 h1:a9CArYczAVv6Qs6VGoLMio99GEs7kY9UzSF9+LD+iGs=
|
||||
gopkg.in/retry.v1 v1.0.3/go.mod h1:FJkXmWiMaAo7xB+xhvDF59zhfjDWyzmyAxiT4dB688g=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY=
|
||||
k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig=
|
||||
k8s.io/apiserver v0.18.8/go.mod h1:12u5FuGql8Cc497ORNj79rhPdiXQC4bf53X/skR/1YM=
|
||||
k8s.io/client-go v0.18.8/go.mod h1:HqFqMllQ5NnQJNwjro9k5zMyfhZlOwpuTLVrxjkYSxU=
|
||||
k8s.io/cloud-provider v0.18.8/go.mod h1:cn9AlzMPVIXA4HHLVbgGUigaQlZyHSZ7WAwDEFNrQSs=
|
||||
k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
|
||||
k8s.io/component-base v0.18.8/go.mod h1:00frPRDas29rx58pPCxNkhUfPbwajlyyvu8ruNgSErU=
|
||||
k8s.io/csi-translation-lib v0.18.8/go.mod h1:6cA6Btlzxy9s3QrS4BCZzQqclIWnTLr6Jx3H2ctAzY4=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
|
||||
k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
|
||||
k8s.io/legacy-cloud-providers v0.18.8/go.mod h1:tgp4xYf6lvjrWnjQwTOPvWQE9IVqSBGPF4on0IyICQE=
|
||||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
|
||||
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package info
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/buildpacks/libcnb"
|
||||
"github.com/pelletier/go-toml"
|
||||
)
|
||||
|
||||
type BuildpackInfo struct {
|
||||
Path string
|
||||
Writer io.Writer
|
||||
}
|
||||
|
||||
func (b BuildpackInfo) Inform() error {
|
||||
c, err := ioutil.ReadFile(b.Path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read %s\n%w", b.Path, err)
|
||||
}
|
||||
|
||||
var bp libcnb.Buildpack
|
||||
if err := toml.Unmarshal(c, &bp); err != nil {
|
||||
return fmt.Errorf("unable to unmarhal %s\n%w", b.Path, err)
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(b.Writer, "::set-output name=id::%s\n", bp.Info.ID)
|
||||
_, _ = fmt.Fprintf(b.Writer, "::set-output name=name::%s\n", bp.Info.Name)
|
||||
_, _ = fmt.Fprintf(b.Writer, "::set-output name=version::%s\n", bp.Info.Version)
|
||||
_, _ = fmt.Fprintf(b.Writer, "::set-output name=homepage::%s\n", bp.Info.Homepage)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
// Code generated by mockery v2.4.0-beta. DO NOT EDIT.
|
||||
|
||||
package toolkit
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
|
||||
// MockToolkit is an autogenerated mock type for the Toolkit type
|
||||
type MockToolkit struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// AddMask provides a mock function with given fields: mask
|
||||
func (_m *MockToolkit) AddMask(mask string) {
|
||||
_m.Called(mask)
|
||||
}
|
||||
|
||||
// AddPath provides a mock function with given fields: paths
|
||||
func (_m *MockToolkit) AddPath(paths ...string) error {
|
||||
_va := make([]interface{}, len(paths))
|
||||
for _i := range paths {
|
||||
_va[_i] = paths[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(...string) error); ok {
|
||||
r0 = rf(paths...)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Debug provides a mock function with given fields: a
|
||||
func (_m *MockToolkit) Debug(a ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, a...)
|
||||
_m.Called(_ca...)
|
||||
}
|
||||
|
||||
// Debugf provides a mock function with given fields: format, a
|
||||
func (_m *MockToolkit) Debugf(format string, a ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, format)
|
||||
_ca = append(_ca, a...)
|
||||
_m.Called(_ca...)
|
||||
}
|
||||
|
||||
// EndGroup provides a mock function with given fields:
|
||||
func (_m *MockToolkit) EndGroup() {
|
||||
_m.Called()
|
||||
}
|
||||
|
||||
// Error provides a mock function with given fields: a
|
||||
func (_m *MockToolkit) Error(a ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, a...)
|
||||
_m.Called(_ca...)
|
||||
}
|
||||
|
||||
// Errorc provides a mock function with given fields: context
|
||||
func (_m *MockToolkit) Errorc(context MessageContext) {
|
||||
_m.Called(context)
|
||||
}
|
||||
|
||||
// Errorf provides a mock function with given fields: format, a
|
||||
func (_m *MockToolkit) Errorf(format string, a ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, format)
|
||||
_ca = append(_ca, a...)
|
||||
_m.Called(_ca...)
|
||||
}
|
||||
|
||||
// ExportVariable provides a mock function with given fields: name, value
|
||||
func (_m *MockToolkit) ExportVariable(name string, value string) error {
|
||||
ret := _m.Called(name, value)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||
r0 = rf(name, value)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetInput provides a mock function with given fields: name
|
||||
func (_m *MockToolkit) GetInput(name string) (string, bool) {
|
||||
ret := _m.Called(name)
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func(string) string); ok {
|
||||
r0 = rf(name)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 bool
|
||||
if rf, ok := ret.Get(1).(func(string) bool); ok {
|
||||
r1 = rf(name)
|
||||
} else {
|
||||
r1 = ret.Get(1).(bool)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetInputList provides a mock function with given fields: name
|
||||
func (_m *MockToolkit) GetInputList(name string) ([]string, bool) {
|
||||
ret := _m.Called(name)
|
||||
|
||||
var r0 []string
|
||||
if rf, ok := ret.Get(0).(func(string) []string); ok {
|
||||
r0 = rf(name)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]string)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 bool
|
||||
if rf, ok := ret.Get(1).(func(string) bool); ok {
|
||||
r1 = rf(name)
|
||||
} else {
|
||||
r1 = ret.Get(1).(bool)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetState provides a mock function with given fields: name
|
||||
func (_m *MockToolkit) GetState(name string) (string, bool) {
|
||||
ret := _m.Called(name)
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func(string) string); ok {
|
||||
r0 = rf(name)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 bool
|
||||
if rf, ok := ret.Get(1).(func(string) bool); ok {
|
||||
r1 = rf(name)
|
||||
} else {
|
||||
r1 = ret.Get(1).(bool)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// IsDebug provides a mock function with given fields:
|
||||
func (_m *MockToolkit) IsDebug() bool {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func() bool); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetOutput provides a mock function with given fields: name, value
|
||||
func (_m *MockToolkit) SetOutput(name string, value string) {
|
||||
_m.Called(name, value)
|
||||
}
|
||||
|
||||
// SetState provides a mock function with given fields: name, value
|
||||
func (_m *MockToolkit) SetState(name string, value string) {
|
||||
_m.Called(name, value)
|
||||
}
|
||||
|
||||
// StartGroup provides a mock function with given fields: title
|
||||
func (_m *MockToolkit) StartGroup(title string) {
|
||||
_m.Called(title)
|
||||
}
|
||||
|
||||
// Warning provides a mock function with given fields: a
|
||||
func (_m *MockToolkit) Warning(a ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, a...)
|
||||
_m.Called(_ca...)
|
||||
}
|
||||
|
||||
// Warningc provides a mock function with given fields: context
|
||||
func (_m *MockToolkit) Warningc(context MessageContext) {
|
||||
_m.Called(context)
|
||||
}
|
||||
|
||||
// Warningf provides a mock function with given fields: format, a
|
||||
func (_m *MockToolkit) Warningf(format string, a ...interface{}) {
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, format)
|
||||
_ca = append(_ca, a...)
|
||||
_m.Called(_ca...)
|
||||
}
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package toolkit
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
//go:generate mockery --all --inpackage --case=underscore
|
||||
|
||||
type Toolkit interface {
|
||||
AddPath(paths ...string) error
|
||||
ExportVariable(name string, value string) error
|
||||
|
||||
GetInput(name string) (string, bool)
|
||||
GetInputList(name string) ([]string, bool)
|
||||
SetOutput(name string, value string)
|
||||
GetState(name string) (string, bool)
|
||||
SetState(name string, value string)
|
||||
AddMask(mask string)
|
||||
|
||||
StartGroup(title string)
|
||||
EndGroup()
|
||||
|
||||
IsDebug() bool
|
||||
Debug(a ...interface{})
|
||||
Debugf(format string, a ...interface{})
|
||||
Warning(a ...interface{})
|
||||
Warningc(context MessageContext)
|
||||
Warningf(format string, a ...interface{})
|
||||
Error(a ...interface{})
|
||||
Errorc(context MessageContext)
|
||||
Errorf(format string, a ...interface{})
|
||||
}
|
||||
|
||||
type MessageContext struct {
|
||||
File string
|
||||
Line string
|
||||
Column string
|
||||
Message string
|
||||
}
|
||||
|
||||
func (m *MessageContext) String() string {
|
||||
var s []string
|
||||
if m.File != "" {
|
||||
s = append(s, fmt.Sprintf("file=%s", m.File))
|
||||
}
|
||||
if m.Line != "" {
|
||||
s = append(s, fmt.Sprintf("line=%s", m.Line))
|
||||
}
|
||||
if m.Column != "" {
|
||||
s = append(s, fmt.Sprintf("col=%s", m.Column))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s::%s", strings.Join(s, ","), escape(m.Message))
|
||||
}
|
||||
|
||||
func FailedError(a ...interface{}) error {
|
||||
return errors.New(errorString(a...))
|
||||
}
|
||||
|
||||
func FailedErrorc(context MessageContext) error {
|
||||
return errors.New(errorStringc(context))
|
||||
}
|
||||
|
||||
func FailedErrorf(format string, a ...interface{}) error {
|
||||
return errors.New(errorStringf(format, a...))
|
||||
}
|
||||
|
||||
type DefaultToolkit struct {
|
||||
once sync.Once
|
||||
|
||||
Environment map[string]string
|
||||
Writer io.Writer
|
||||
Delemiter string
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) AddPath(paths ...string) error {
|
||||
d.once.Do(d.init)
|
||||
|
||||
path, ok := d.Environment["GITHUB_PATH"]
|
||||
if !ok {
|
||||
return FailedError("$GITHUB_PATH must be set")
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return FailedErrorf("unable to open %s\n%w", path, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
for _, p := range paths {
|
||||
_, _ = fmt.Fprintln(f, p)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) ExportVariable(name string, value string) error {
|
||||
return d.export("GITHUB_ENV", name, value)
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) export(env string, name string, value string) error {
|
||||
d.once.Do(d.init)
|
||||
|
||||
path, ok := d.Environment[env]
|
||||
if !ok {
|
||||
return FailedErrorf("$%s must be set", env)
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return FailedErrorf("unable to open %s\n%w", path, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if strings.ContainsRune(value, '\n') {
|
||||
if _, err := fmt.Fprintln(f, fmt.Sprintf("%s<<%s\n%s\n%s", name, d.Delemiter, value, d.Delemiter)); err != nil {
|
||||
return FailedError("unable to write variable")
|
||||
}
|
||||
} else {
|
||||
_, _ = fmt.Fprintln(f, fmt.Sprintf("%s=%s", name, value))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) GetInput(name string) (string, bool) {
|
||||
d.once.Do(d.init)
|
||||
s, ok := d.Environment[fmt.Sprintf("INPUT_%s", strings.ToUpper(name))]
|
||||
return s, ok
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) GetInputList(name string) ([]string, bool) {
|
||||
d.once.Do(d.init)
|
||||
s, ok := d.Environment[fmt.Sprintf("INPUT_%s", strings.ToUpper(name))]
|
||||
ss := strings.Split(s, ",")
|
||||
return ss, ok
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) SetOutput(name string, value string) {
|
||||
err := d.export("GITHUB_OUTPUT", name, value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) GetState(name string) (string, bool) {
|
||||
d.once.Do(d.init)
|
||||
s, ok := d.Environment[fmt.Sprintf("STATE_%s", strings.ToUpper(name))]
|
||||
return s, ok
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) SetState(name string, value string) {
|
||||
err := d.export("GITHUB_STATE", name, value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) AddMask(mask string) {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintf(d.Writer, "::add-mask::%s\n", escape(mask))
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) StartGroup(title string) {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintf(d.Writer, "::group::%s\n", title)
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) EndGroup() {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintln(d.Writer, "::endgroup::")
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) IsDebug() bool {
|
||||
d.once.Do(d.init)
|
||||
|
||||
t, err := strconv.ParseBool(d.Environment["RUNNER_DEBUG"])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) Debug(a ...interface{}) {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintf(d.Writer, "::debug::%s\n", escape(fmt.Sprint(a...)))
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) Debugf(format string, a ...interface{}) {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintf(d.Writer, "::debug::%s\n", escape(fmt.Sprintf(format, a...)))
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) Error(a ...interface{}) {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintln(d.Writer, errorString(a...))
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) Errorc(context MessageContext) {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintln(d.Writer, errorStringc(context))
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) Errorf(format string, a ...interface{}) {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintln(d.Writer, errorStringf(format, a...))
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) Warning(a ...interface{}) {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintf(d.Writer, "::warning ::%s\n", escape(fmt.Sprint(a...)))
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) Warningc(context MessageContext) {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintln(d.Writer, "::warning", escape(context.String()))
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) Warningf(format string, a ...interface{}) {
|
||||
d.once.Do(d.init)
|
||||
_, _ = fmt.Fprintf(d.Writer, "::warning ::%s\n", escape(fmt.Sprintf(format, a...)))
|
||||
}
|
||||
|
||||
func (d *DefaultToolkit) init() {
|
||||
if d.Environment == nil {
|
||||
d.Environment = make(map[string]string)
|
||||
|
||||
for _, s := range os.Environ() {
|
||||
t := strings.SplitN(s, "=", 2)
|
||||
d.Environment[t[0]] = t[1]
|
||||
}
|
||||
}
|
||||
|
||||
if d.Writer == nil {
|
||||
d.Writer = os.Stdout
|
||||
}
|
||||
|
||||
if d.Delemiter == "" {
|
||||
data := make([]byte, 16) // roughly the same entropy as uuid v4 used in https://github.com/actions/toolkit/blob/b36e70495fbee083eb20f600eafa9091d832577d/packages/core/src/file-command.ts#L28
|
||||
_, err := rand.Read(data)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("could not generate random delimiter: %w", err))
|
||||
}
|
||||
d.Delemiter = hex.EncodeToString(data)
|
||||
}
|
||||
}
|
||||
|
||||
func errorString(a ...interface{}) string {
|
||||
return fmt.Sprintf("::error ::%s", escape(fmt.Sprint(a...)))
|
||||
}
|
||||
|
||||
func errorStringc(context MessageContext) string {
|
||||
return fmt.Sprintf("::error %s", context.String())
|
||||
}
|
||||
|
||||
func errorStringf(format string, a ...interface{}) string {
|
||||
return fmt.Sprintf("::error ::%s", escape(fmt.Errorf(format, a...).Error()))
|
||||
}
|
||||
|
||||
func escape(s string) string {
|
||||
return strings.ReplaceAll(s, "\n", "%0A")
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package toolkit_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
)
|
||||
|
||||
func TestToolkit(t *testing.T) {
|
||||
spec.Run(t, "Toolkit", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
)
|
||||
|
||||
context("MessageContext", func() {
|
||||
|
||||
it("renders string", func() {
|
||||
mc := toolkit.MessageContext{Message: "test-message-1\ntest-message-2"}
|
||||
Expect(mc.String()).To(Equal("::test-message-1%0Atest-message-2"))
|
||||
|
||||
mc.File = "test-file"
|
||||
Expect(mc.String()).To(Equal("file=test-file::test-message-1%0Atest-message-2"))
|
||||
|
||||
mc.Line = "test-line"
|
||||
Expect(mc.String()).To(Equal("file=test-file,line=test-line::test-message-1%0Atest-message-2"))
|
||||
|
||||
mc.Column = "test-column"
|
||||
Expect(mc.String()).To(Equal("file=test-file,line=test-line,col=test-column::test-message-1%0Atest-message-2"))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
context("FailedError", func() {
|
||||
|
||||
it("returns failed error", func() {
|
||||
Expect(toolkit.FailedError("test-message-1", "test-message-2\ntest-message-3")).
|
||||
To(MatchError("::error ::test-message-1test-message-2%0Atest-message-3"))
|
||||
})
|
||||
|
||||
it("returns failed errorc", func() {
|
||||
Expect(toolkit.FailedErrorc(toolkit.MessageContext{
|
||||
File: "test-file",
|
||||
Line: "test-line",
|
||||
Column: "test-column",
|
||||
Message: "test-message-1 test-message-2\ntest-message-3",
|
||||
})).
|
||||
To(MatchError("::error file=test-file,line=test-line,col=test-column::test-message-1 test-message-2%0Atest-message-3"))
|
||||
})
|
||||
|
||||
it("returns failed errorf", func() {
|
||||
Expect(toolkit.FailedErrorf("%s %s\n%s", "test-message-1", "test-message-2", "test-message-3")).
|
||||
To(MatchError("::error ::test-message-1 test-message-2%0Atest-message-3"))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
context("DefaultToolkit", func() {
|
||||
|
||||
var (
|
||||
b = &bytes.Buffer{}
|
||||
tk = toolkit.DefaultToolkit{Writer: b, Delemiter: "EOF"}
|
||||
)
|
||||
|
||||
it("adds path", func() {
|
||||
f, err := os.CreateTemp("", "github-path")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
_, err = fmt.Fprintln(f, "test-value")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(f.Close()).To(Succeed())
|
||||
|
||||
tk.Environment = map[string]string{"GITHUB_PATH": f.Name()}
|
||||
|
||||
Expect(tk.AddPath("test-path-1", "test-path-2")).To(Succeed())
|
||||
|
||||
b, err := os.ReadFile(f.Name())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(string(b)).To(Equal("test-value\ntest-path-1\ntest-path-2\n"))
|
||||
})
|
||||
|
||||
it("exports variable", func() {
|
||||
f, err := os.CreateTemp("", "github-env")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
_, err = fmt.Fprintln(f, "TEST_KEY=test-value")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(f.Close()).To(Succeed())
|
||||
|
||||
tk.Environment = map[string]string{"GITHUB_ENV": f.Name()}
|
||||
|
||||
Expect(tk.ExportVariable("TEST_NAME_1", "test-value-1")).To(Succeed())
|
||||
Expect(tk.ExportVariable("TEST_NAME_2", "test-value-2\ntest-value-3")).To(Succeed())
|
||||
|
||||
b, err := os.ReadFile(f.Name())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(string(b)).To(Equal("TEST_KEY=test-value\nTEST_NAME_1=test-value-1\nTEST_NAME_2<<EOF\ntest-value-2\ntest-value-3\nEOF\n"))
|
||||
})
|
||||
|
||||
it("gets input", func() {
|
||||
tk.Environment = map[string]string{"INPUT_TEST-1": "test-value"}
|
||||
|
||||
s, ok := tk.GetInput("test-1")
|
||||
Expect(ok).To(BeTrue())
|
||||
Expect(s).To(Equal("test-value"))
|
||||
|
||||
_, ok = tk.GetInput("test-2")
|
||||
Expect(ok).To(BeFalse())
|
||||
})
|
||||
|
||||
it("gets input list", func() {
|
||||
tk.Environment = map[string]string{"INPUT_BLOCKED_NAMESPACES_TEST-1": "test-value-1,test-value-2,test-value-3"}
|
||||
|
||||
s, ok := tk.GetInputList("blocked_namespaces_test-1")
|
||||
Expect(ok).To(BeTrue())
|
||||
Expect(s).To(Equal([]string{"test-value-1", "test-value-2", "test-value-3"}))
|
||||
|
||||
_, ok = tk.GetInputList("test-2")
|
||||
Expect(ok).To(BeFalse())
|
||||
})
|
||||
|
||||
it("sets output", func() {
|
||||
f, err := os.CreateTemp("", "github-output")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
_, err = fmt.Fprintln(f, "TEST_OUTPUT=test-value")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(f.Close()).To(Succeed())
|
||||
tk.Environment = map[string]string{"GITHUB_OUTPUT": f.Name()}
|
||||
|
||||
tk.SetOutput("test-name", "test-value-1\ntest-value-2")
|
||||
|
||||
b, err := os.ReadFile(f.Name())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(string(b)).To(Equal("TEST_OUTPUT=test-value\ntest-name<<EOF\ntest-value-1\ntest-value-2\nEOF\n"))
|
||||
})
|
||||
|
||||
it("gets state", func() {
|
||||
tk.Environment = map[string]string{"STATE_TEST-1": "test-value"}
|
||||
|
||||
s, ok := tk.GetState("test-1")
|
||||
Expect(ok).To(BeTrue())
|
||||
Expect(s).To(Equal("test-value"))
|
||||
|
||||
_, ok = tk.GetState("test-2")
|
||||
Expect(ok).To(BeFalse())
|
||||
})
|
||||
|
||||
it("sets state", func() {
|
||||
f, err := os.CreateTemp("", "github-state")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
_, err = fmt.Fprintln(f, "TEST_STATE=test-value")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(f.Close()).To(Succeed())
|
||||
tk.Environment = map[string]string{"GITHUB_STATE": f.Name()}
|
||||
|
||||
tk.SetState("test-name", "test-value-1\ntest-value-2")
|
||||
|
||||
b, err := os.ReadFile(f.Name())
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(string(b)).To(Equal("TEST_STATE=test-value\ntest-name<<EOF\ntest-value-1\ntest-value-2\nEOF\n"))
|
||||
})
|
||||
|
||||
it("adds mask", func() {
|
||||
tk.AddMask("test-mask")
|
||||
|
||||
Expect(b.String()).To(Equal("::add-mask::test-mask\n"))
|
||||
})
|
||||
|
||||
it("starts group", func() {
|
||||
tk.StartGroup("test-title")
|
||||
|
||||
Expect(b.String()).To(Equal("::group::test-title\n"))
|
||||
})
|
||||
|
||||
it("ends group", func() {
|
||||
tk.EndGroup()
|
||||
|
||||
Expect(b.String()).To(Equal("::endgroup::\n"))
|
||||
})
|
||||
|
||||
it("returns isDebug", func() {
|
||||
tk.Environment = map[string]string{}
|
||||
|
||||
Expect(tk.IsDebug()).To(BeFalse())
|
||||
|
||||
tk.Environment["RUNNER_DEBUG"] = "true"
|
||||
|
||||
Expect(tk.IsDebug()).To(BeTrue())
|
||||
})
|
||||
|
||||
it("writes debug", func() {
|
||||
tk.Debug("test-message-1", "test-message-2\ntest-message-3")
|
||||
|
||||
Expect(b.String()).To(Equal("::debug::test-message-1test-message-2%0Atest-message-3\n"))
|
||||
})
|
||||
|
||||
it("writes debugf", func() {
|
||||
tk.Debugf("%s %s\n%s", "test-message-1", "test-message-2", "test-message-3")
|
||||
|
||||
Expect(b.String()).To(Equal("::debug::test-message-1 test-message-2%0Atest-message-3\n"))
|
||||
})
|
||||
|
||||
it("writes warning", func() {
|
||||
tk.Warning("test-message-1", "test-message-2\ntest-message-3")
|
||||
|
||||
Expect(b.String()).To(Equal("::warning ::test-message-1test-message-2%0Atest-message-3\n"))
|
||||
})
|
||||
|
||||
it("writes warningc", func() {
|
||||
tk.Warningc(toolkit.MessageContext{
|
||||
File: "test-file",
|
||||
Line: "test-line",
|
||||
Column: "test-column",
|
||||
Message: "test-message-1 test-message-2\ntest-message-3",
|
||||
})
|
||||
|
||||
Expect(b.String()).To(Equal("::warning file=test-file,line=test-line,col=test-column::test-message-1 test-message-2%0Atest-message-3\n"))
|
||||
})
|
||||
|
||||
it("writes warningf", func() {
|
||||
tk.Warningf("%s %s\n%s", "test-message-1", "test-message-2", "test-message-3")
|
||||
|
||||
Expect(b.String()).To(Equal("::warning ::test-message-1 test-message-2%0Atest-message-3\n"))
|
||||
})
|
||||
|
||||
it("writes error", func() {
|
||||
tk.Error("test-message-1", "test-message-2\ntest-message-3")
|
||||
|
||||
Expect(b.String()).To(Equal("::error ::test-message-1test-message-2%0Atest-message-3\n"))
|
||||
})
|
||||
|
||||
it("writes errorc", func() {
|
||||
tk.Errorc(toolkit.MessageContext{
|
||||
File: "test-file",
|
||||
Line: "test-line",
|
||||
Column: "test-column",
|
||||
Message: "test-message-1 test-message-2\ntest-message-3",
|
||||
})
|
||||
|
||||
Expect(b.String()).To(Equal("::error file=test-file,line=test-line,col=test-column::test-message-1 test-message-2%0Atest-message-3\n"))
|
||||
})
|
||||
|
||||
it("writes errorf", func() {
|
||||
tk.Errorf("%s %s\n%s", "test-message-1", "test-message-2", "test-message-3")
|
||||
|
||||
Expect(b.String()).To(Equal("::error ::test-message-1 test-message-2%0Atest-message-3\n"))
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package entry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
)
|
||||
|
||||
func AddEntry(tk toolkit.Toolkit, repositories services.RepositoriesService, strategy retry.Strategy) error {
|
||||
c, err := parseConfig(tk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file := index.Path(c.Namespace, c.Name)
|
||||
|
||||
for a := retry.Start(strategy, nil); a.Next(); {
|
||||
content, _, resp, err := repositories.GetContents(context.Background(), c.Owner, c.Repository, file, nil)
|
||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
||||
fmt.Printf("New Index: %s\n", c.Name)
|
||||
content = &github.RepositoryContent{}
|
||||
} else if err != nil {
|
||||
return toolkit.FailedErrorf("unable to read index %s\n%w", c.Name, err)
|
||||
}
|
||||
|
||||
s, err := content.GetContent()
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to get index content\n%w", err)
|
||||
}
|
||||
|
||||
entries, err := index.UnmarshalEntries(s)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to unmarshal entries\n%w", err)
|
||||
}
|
||||
|
||||
if contains(entries, c.Namespace, c.Version) {
|
||||
return toolkit.FailedErrorf("index %s already has namespace %s and version %s", c.Name, c.Namespace, c.Version)
|
||||
}
|
||||
|
||||
entries = append(entries, index.Entry{
|
||||
Namespace: c.Namespace,
|
||||
Name: c.Name,
|
||||
Version: c.Version,
|
||||
Address: c.Address,
|
||||
})
|
||||
|
||||
s, err = index.MarshalEntries(entries)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to marshal entries\n%w", err)
|
||||
}
|
||||
|
||||
if _, resp, err := repositories.CreateFile(context.Background(), c.Owner, c.Repository, file, &github.RepositoryContentFileOptions{
|
||||
Author: &github.CommitAuthor{
|
||||
Name: github.String("buildpacks-bot"),
|
||||
Email: github.String("cncf-buildpacks-maintainers@lists.cncf.io"),
|
||||
},
|
||||
Message: github.String(fmt.Sprintf("ADD %s/%s@%s", c.Namespace, c.Name, c.Version)),
|
||||
SHA: content.SHA,
|
||||
Content: []byte(s),
|
||||
}); resp != nil && resp.StatusCode == http.StatusConflict {
|
||||
tk.Warning("retrying index update after conflict")
|
||||
continue
|
||||
} else if err != nil {
|
||||
return toolkit.FailedErrorf("unable to create index\n%w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Added %s/%s@%s\n", c.Namespace, c.Name, c.Version)
|
||||
return nil
|
||||
}
|
||||
|
||||
return toolkit.FailedError("timed out")
|
||||
}
|
||||
|
||||
type config struct {
|
||||
Owner string
|
||||
Repository string
|
||||
Namespace string
|
||||
Name string
|
||||
Version string
|
||||
Address string
|
||||
}
|
||||
|
||||
func parseConfig(tk toolkit.Toolkit) (config, error) {
|
||||
var (
|
||||
c config
|
||||
ok bool
|
||||
)
|
||||
|
||||
c.Owner, ok = tk.GetInput("owner")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("owner must be set")
|
||||
}
|
||||
|
||||
c.Repository, ok = tk.GetInput("repository")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("repository must be set")
|
||||
}
|
||||
|
||||
c.Namespace, ok = tk.GetInput("namespace")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("namespace must be set")
|
||||
}
|
||||
|
||||
c.Name, ok = tk.GetInput("name")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("name must be set")
|
||||
}
|
||||
|
||||
c.Version, ok = tk.GetInput("version")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("version must be set")
|
||||
}
|
||||
|
||||
c.Address, ok = tk.GetInput("address")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("address must be set")
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func contains(entries []index.Entry, namespace string, version string) bool {
|
||||
for _, e := range entries {
|
||||
if e.Namespace == namespace && e.Version == version {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package entry_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
entry "github.com/buildpacks/github-actions/registry/add-entry"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
)
|
||||
|
||||
func TestAddEntry(t *testing.T) {
|
||||
spec.Run(t, "add-entry", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
ExpectWithOffset = NewWithT(t).ExpectWithOffset
|
||||
|
||||
r = &services.MockRepositoriesService{}
|
||||
rOpts *github.RepositoryContentGetOptions
|
||||
s = retry.LimitCount(2, retry.Regular{Min: 2})
|
||||
tk = &toolkit.MockToolkit{}
|
||||
)
|
||||
|
||||
asJSONString := func(v interface{}) string {
|
||||
b, err := json.Marshal(v)
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
it.Before(func() {
|
||||
tk.On("GetInput", "owner").Return("test-owner", true)
|
||||
tk.On("GetInput", "repository").Return("test-repository", true)
|
||||
tk.On("GetInput", "namespace").Return("test-namespace", true)
|
||||
tk.On("GetInput", "name").Return("test-name", true)
|
||||
tk.On("GetInput", "version").Return("test-version", true)
|
||||
tk.On("GetInput", "address").Return("test-address", true)
|
||||
})
|
||||
|
||||
context("index does not exist", func() {
|
||||
it.Before(func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), rOpts).
|
||||
Return(nil, nil, &github.Response{Response: &http.Response{StatusCode: http.StatusNotFound}}, nil)
|
||||
})
|
||||
|
||||
it("creates new index", func() {
|
||||
r.On("CreateFile", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), &github.RepositoryContentFileOptions{
|
||||
Author: &github.CommitAuthor{
|
||||
Name: github.String("buildpacks-bot"),
|
||||
Email: github.String("cncf-buildpacks-maintainers@lists.cncf.io"),
|
||||
},
|
||||
Message: github.String("ADD test-namespace/test-name@test-version"),
|
||||
Content: []byte(fmt.Sprintf("%s\n", asJSONString(index.Entry{
|
||||
Namespace: "test-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
}))),
|
||||
}).
|
||||
Return(nil, nil, nil)
|
||||
|
||||
Expect(entry.AddEntry(tk, r, s)).To(Succeed())
|
||||
})
|
||||
})
|
||||
|
||||
context("index does exist", func() {
|
||||
|
||||
it("fails if version already exists", func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), rOpts).
|
||||
Return(&github.RepositoryContent{
|
||||
Content: github.String(asJSONString(index.Entry{
|
||||
Namespace: "test-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
})),
|
||||
SHA: github.String("test-sha"),
|
||||
}, nil, nil, nil)
|
||||
|
||||
Expect(entry.AddEntry(tk, r, s)).
|
||||
To(MatchError("::error ::index test-name already has namespace test-namespace and version test-version"))
|
||||
})
|
||||
|
||||
it("adds entry to index", func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), rOpts).
|
||||
Return(&github.RepositoryContent{
|
||||
Content: github.String(asJSONString(index.Entry{
|
||||
Namespace: "another-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
})),
|
||||
SHA: github.String("test-sha"),
|
||||
}, nil, nil, nil)
|
||||
|
||||
r.On("CreateFile", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), &github.RepositoryContentFileOptions{
|
||||
Author: &github.CommitAuthor{
|
||||
Name: github.String("buildpacks-bot"),
|
||||
Email: github.String("cncf-buildpacks-maintainers@lists.cncf.io"),
|
||||
},
|
||||
Message: github.String("ADD test-namespace/test-name@test-version"),
|
||||
Content: []byte(fmt.Sprintf("%s\n%s\n",
|
||||
asJSONString(index.Entry{
|
||||
Namespace: "another-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
}),
|
||||
asJSONString(index.Entry{
|
||||
Namespace: "test-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
}),
|
||||
)),
|
||||
SHA: github.String("test-sha"),
|
||||
}).
|
||||
Return(nil, nil, nil)
|
||||
|
||||
Expect(entry.AddEntry(tk, r, s)).To(Succeed())
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"golang.org/x/oauth2"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
entry "github.com/buildpacks/github-actions/registry/add-entry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tk := &toolkit.DefaultToolkit{}
|
||||
|
||||
t, ok := tk.GetInput("token")
|
||||
if !ok {
|
||||
fmt.Println(toolkit.FailedError("token must be specified"))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
gh := github.NewClient(oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(&oauth2.Token{AccessToken: t})))
|
||||
|
||||
strategy := retry.LimitTime(2*time.Minute,
|
||||
retry.Exponential{
|
||||
Initial: time.Second,
|
||||
Jitter: true,
|
||||
},
|
||||
)
|
||||
|
||||
if err := entry.AddEntry(tk, gh.Repositories, strategy); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright 2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/go-github/v32/github"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/buildpacks/github-actions/registry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
r registry.Registry
|
||||
|
||||
err error
|
||||
ok bool
|
||||
)
|
||||
|
||||
var token oauth2.Token
|
||||
if token.AccessToken, ok = os.LookupEnv("INPUT_TOKEN"); !ok {
|
||||
panic(fmt.Errorf("token must be specified"))
|
||||
}
|
||||
r.Issues = github.NewClient(oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(&token))).Issues
|
||||
|
||||
if r.ID, ok = os.LookupEnv("INPUT_ID"); !ok {
|
||||
panic(fmt.Errorf("id must be specified"))
|
||||
}
|
||||
|
||||
if r.Version, ok = os.LookupEnv("INPUT_VERSION"); !ok {
|
||||
panic(fmt.Errorf("id must be specified"))
|
||||
}
|
||||
|
||||
yank := false
|
||||
if s, ok := os.LookupEnv("INPUT_YANK"); ok {
|
||||
if yank, err = strconv.ParseBool(s); err != nil {
|
||||
panic(fmt.Errorf("unable to parse INPUT_YANK='%s' as a bool", s))
|
||||
}
|
||||
}
|
||||
|
||||
if yank {
|
||||
if err := r.Yank(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
address, ok := os.LookupEnv("INPUT_ADDRESS")
|
||||
if !ok {
|
||||
panic(fmt.Errorf("address must be specified"))
|
||||
}
|
||||
|
||||
if err := r.Add(address); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,22 +17,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/buildpacks/github-actions/info"
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/compute-metadata"
|
||||
)
|
||||
|
||||
func main() {
|
||||
i := info.BuildpackInfo{
|
||||
Path: "buildpack.toml",
|
||||
Writer: os.Stdout,
|
||||
}
|
||||
|
||||
if s, ok := os.LookupEnv("INPUT_PATH"); ok {
|
||||
i.Path = s
|
||||
}
|
||||
|
||||
if err := i.Inform(); err != nil {
|
||||
panic(err)
|
||||
if err := metadata.ComputeMetadata(&toolkit.DefaultToolkit{}); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package metadata
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"github.com/pelletier/go-toml"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/namespace"
|
||||
)
|
||||
|
||||
func ComputeMetadata(tk toolkit.Toolkit) error {
|
||||
c, err := parseConfig(tk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var issue github.Issue
|
||||
if err := json.Unmarshal([]byte(c.Issue), &issue); err != nil {
|
||||
return toolkit.FailedErrorf("unable to unmarshal issue\n%w", err)
|
||||
}
|
||||
|
||||
var request index.Request
|
||||
if err := toml.Unmarshal([]byte(strings.ReplaceAll(*issue.Body, "```", "")), &request); err != nil {
|
||||
return toolkit.FailedErrorf("unable to unmarshal body\n%w", err)
|
||||
}
|
||||
|
||||
var (
|
||||
ns string
|
||||
name string
|
||||
)
|
||||
if g := index.ValidRequestId.FindStringSubmatch(request.ID); g == nil {
|
||||
return toolkit.FailedErrorf("invalid id %s", request.ID)
|
||||
} else {
|
||||
ns = g[1]
|
||||
name = g[2]
|
||||
}
|
||||
|
||||
if namespace.IsRestricted(ns) {
|
||||
return toolkit.FailedErrorf("restricted namespace %s", ns)
|
||||
}
|
||||
|
||||
if !index.ValidRequestVersion.MatchString(request.Version) {
|
||||
return toolkit.FailedErrorf("invalid version %s", request.Version)
|
||||
}
|
||||
|
||||
if !request.Yank && !index.ValidRequestAddress.MatchString(request.Address) {
|
||||
return toolkit.FailedErrorf("invalid address %s", request.Address)
|
||||
}
|
||||
|
||||
fmt.Printf(`Metadata:
|
||||
ID: %s
|
||||
Version: %s
|
||||
Address: %s
|
||||
Namespace: %s
|
||||
Name: %s
|
||||
`, request.ID, request.Version, request.Address, ns, name)
|
||||
|
||||
tk.SetOutput("id", request.ID)
|
||||
tk.SetOutput("namespace", ns)
|
||||
tk.SetOutput("name", name)
|
||||
tk.SetOutput("version", request.Version)
|
||||
|
||||
if !request.Yank {
|
||||
tk.SetOutput("address", request.Address)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type config struct {
|
||||
Issue string
|
||||
}
|
||||
|
||||
func parseConfig(tk toolkit.Toolkit) (config, error) {
|
||||
var (
|
||||
c config
|
||||
ok bool
|
||||
)
|
||||
|
||||
c.Issue, ok = tk.GetInput("issue")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("issue must be set")
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package metadata_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/pelletier/go-toml"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/compute-metadata"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
)
|
||||
|
||||
func TestComputeMetadata(t *testing.T) {
|
||||
spec.Run(t, "compute-metadata", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
ExpectWithOffset = NewWithT(t).ExpectWithOffset
|
||||
|
||||
tk = &toolkit.MockToolkit{}
|
||||
)
|
||||
|
||||
asJSONString := func(v interface{}) string {
|
||||
b, err := json.Marshal(v)
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
asTOMLString := func(v interface{}) string {
|
||||
b, err := toml.Marshal(v)
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
it("returns error when id is invalid", func() {
|
||||
tk.On("GetInput", "issue").Return(asJSONString(github.Issue{
|
||||
Body: github.String(fmt.Sprintf("```\n%s\n```", asTOMLString(index.Request{
|
||||
ID: "test@namespace/test-name",
|
||||
}))),
|
||||
}), true)
|
||||
|
||||
Expect(metadata.ComputeMetadata(tk)).To(MatchError("::error ::invalid id test@namespace/test-name"))
|
||||
})
|
||||
|
||||
it("returns error if namespace is restricted", func() {
|
||||
tk.On("GetInput", "issue").Return(asJSONString(github.Issue{
|
||||
Body: github.String(asTOMLString(index.Request{
|
||||
ID: "cnb/test-name",
|
||||
})),
|
||||
}), true)
|
||||
|
||||
Expect(metadata.ComputeMetadata(tk)).To(MatchError("::error ::restricted namespace cnb"))
|
||||
})
|
||||
|
||||
it("returns error when version is invalid", func() {
|
||||
tk.On("GetInput", "issue").Return(asJSONString(github.Issue{
|
||||
Body: github.String(fmt.Sprintf("```\n%s\n```", asTOMLString(index.Request{
|
||||
ID: "test-namespace/test-name",
|
||||
Version: "test-version",
|
||||
}))),
|
||||
}), true)
|
||||
|
||||
Expect(metadata.ComputeMetadata(tk)).To(MatchError("::error ::invalid version test-version"))
|
||||
})
|
||||
|
||||
it("returns error when yank is false and address is invalid", func() {
|
||||
tk.On("GetInput", "issue").Return(asJSONString(github.Issue{
|
||||
Body: github.String(asTOMLString(index.Request{
|
||||
ID: "test-namespace/test-name",
|
||||
Version: "0.0.0",
|
||||
Address: "host.com:443/repository/image:tag",
|
||||
})),
|
||||
}), true)
|
||||
|
||||
Expect(metadata.ComputeMetadata(tk)).To(MatchError("::error ::invalid address host.com:443/repository/image:tag"))
|
||||
})
|
||||
|
||||
it("computes metadata when yank is false", func() {
|
||||
tk.On("GetInput", "issue").Return(asJSONString(github.Issue{
|
||||
Body: github.String(asTOMLString(index.Request{
|
||||
ID: "test-namespace/test-name",
|
||||
Version: "0.0.0",
|
||||
Address: "host.com:443/repository/image@sha256:133f2117e15569ca59645eddad78f4a6a675c435f9614e4b137364274f3a7614",
|
||||
})),
|
||||
}), true)
|
||||
tk.On("SetOutput", "id", "test-namespace/test-name")
|
||||
tk.On("SetOutput", "version", "0.0.0")
|
||||
tk.On("SetOutput", "address", "host.com:443/repository/image@sha256:133f2117e15569ca59645eddad78f4a6a675c435f9614e4b137364274f3a7614")
|
||||
tk.On("SetOutput", "namespace", "test-namespace")
|
||||
tk.On("SetOutput", "name", "test-name")
|
||||
|
||||
Expect(metadata.ComputeMetadata(tk)).To(Succeed())
|
||||
})
|
||||
|
||||
it("computes metadata when yank is true", func() {
|
||||
tk.On("GetInput", "issue").Return(asJSONString(github.Issue{
|
||||
Body: github.String(asTOMLString(index.Request{
|
||||
ID: "test-namespace/test-name",
|
||||
Version: "0.0.0",
|
||||
Yank: true,
|
||||
})),
|
||||
}), true)
|
||||
tk.On("SetOutput", "id", "test-namespace/test-name")
|
||||
tk.On("SetOutput", "version", "0.0.0")
|
||||
tk.On("SetOutput", "namespace", "test-namespace")
|
||||
tk.On("SetOutput", "name", "test-name")
|
||||
|
||||
Expect(metadata.ComputeMetadata(tk)).To(Succeed())
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package index
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Entry struct {
|
||||
Namespace string `json:"ns"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Yanked bool `json:"yanked"`
|
||||
Address string `json:"addr"`
|
||||
}
|
||||
|
||||
func MarshalEntries(entries []Entry) (string, error) {
|
||||
b := &bytes.Buffer{}
|
||||
j := json.NewEncoder(b)
|
||||
|
||||
for _, e := range entries {
|
||||
if err := j.Encode(e); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return b.String(), nil
|
||||
}
|
||||
|
||||
func UnmarshalEntries(content string) ([]Entry, error) {
|
||||
var entries []Entry
|
||||
|
||||
scanner := bufio.NewScanner(strings.NewReader(content))
|
||||
for scanner.Scan() {
|
||||
var e Entry
|
||||
if err := json.Unmarshal(scanner.Bytes(), &e); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entries = append(entries, e)
|
||||
}
|
||||
|
||||
return entries, scanner.Err()
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package index_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
)
|
||||
|
||||
func TestEntry(t *testing.T) {
|
||||
spec.Run(t, "entry", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
ExpectWithOffset = NewWithT(t).ExpectWithOffset
|
||||
)
|
||||
|
||||
asJSONString := func(v interface{}) string {
|
||||
b, err := json.Marshal(v)
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
it("marshals entries", func() {
|
||||
Expect(index.MarshalEntries([]index.Entry{
|
||||
{
|
||||
Namespace: "test-namespace-1",
|
||||
Name: "test-name-1",
|
||||
Version: "test-version-1",
|
||||
Address: "test-address-1",
|
||||
},
|
||||
{
|
||||
Namespace: "test-namespace-2",
|
||||
Name: "test-name-2",
|
||||
Version: "test-version-2",
|
||||
Address: "test-address-2",
|
||||
},
|
||||
})).To(Equal(fmt.Sprintf("%s\n%s\n",
|
||||
asJSONString(index.Entry{
|
||||
Namespace: "test-namespace-1",
|
||||
Name: "test-name-1",
|
||||
Version: "test-version-1",
|
||||
Address: "test-address-1",
|
||||
}),
|
||||
asJSONString(index.Entry{
|
||||
Namespace: "test-namespace-2",
|
||||
Name: "test-name-2",
|
||||
Version: "test-version-2",
|
||||
Address: "test-address-2",
|
||||
}),
|
||||
)))
|
||||
})
|
||||
|
||||
it("unmarshals entries", func() {
|
||||
Expect(index.UnmarshalEntries(fmt.Sprintf("%s\n%s\n",
|
||||
asJSONString(index.Entry{
|
||||
Namespace: "test-namespace-1",
|
||||
Name: "test-name-1",
|
||||
Version: "test-version-1",
|
||||
Address: "test-address-1",
|
||||
}),
|
||||
asJSONString(index.Entry{
|
||||
Namespace: "test-namespace-2",
|
||||
Name: "test-name-2",
|
||||
Version: "test-version-2",
|
||||
Address: "test-address-2",
|
||||
}),
|
||||
))).To(Equal([]index.Entry{
|
||||
{
|
||||
Namespace: "test-namespace-1",
|
||||
Name: "test-name-1",
|
||||
Version: "test-version-1",
|
||||
Address: "test-address-1",
|
||||
},
|
||||
{
|
||||
Namespace: "test-namespace-2",
|
||||
Name: "test-name-2",
|
||||
Version: "test-version-2",
|
||||
Address: "test-address-2",
|
||||
},
|
||||
}))
|
||||
})
|
||||
})
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package index
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func Path(namespace string, name string) string {
|
||||
var path string
|
||||
|
||||
switch len(name) {
|
||||
case 1:
|
||||
path = "1"
|
||||
case 2:
|
||||
path = "2"
|
||||
case 3:
|
||||
path = filepath.Join("3", name[0:2])
|
||||
default:
|
||||
path = filepath.Join(name[0:2], name[2:4])
|
||||
}
|
||||
|
||||
return filepath.Join(path, filepath.Join(fmt.Sprintf("%s_%s", namespace, name)))
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package index_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
)
|
||||
|
||||
func TestPath(t *testing.T) {
|
||||
spec.Run(t, "path", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
)
|
||||
|
||||
it("returns path for 1 character name", func() {
|
||||
Expect(index.Path("test-namespace", "a")).To(Equal(filepath.Join("1", "test-namespace_a")))
|
||||
})
|
||||
|
||||
it("returns path for 2 character name", func() {
|
||||
Expect(index.Path("test-namespace", "ab")).To(Equal(filepath.Join("2", "test-namespace_ab")))
|
||||
})
|
||||
|
||||
it("returns path for 3 character name", func() {
|
||||
Expect(index.Path("test-namespace", "abc")).To(Equal(filepath.Join("3", "ab", "test-namespace_abc")))
|
||||
})
|
||||
|
||||
it("returns path for 4+ character name", func() {
|
||||
Expect(index.Path("test-namespace", "abcd")).To(Equal(filepath.Join("ab", "cd", "test-namespace_abcd")))
|
||||
})
|
||||
})
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package index
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var (
|
||||
ValidRequestId = regexp.MustCompile(`^([a-zA-Z0-9.-]+)/([a-zA-Z0-9./-]+)$`)
|
||||
ValidRequestVersion = regexp.MustCompile(`^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`)
|
||||
ValidRequestAddress = regexp.MustCompile(`(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9](?::[0-9]+)?/[^:]+@sha256:[A-Fa-f0-9]{64}`)
|
||||
)
|
||||
|
||||
type Request struct {
|
||||
ID string
|
||||
Version string
|
||||
Address string `toml:"addr"`
|
||||
Yank bool `toml:"yank,omitempty"`
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package index
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
)
|
||||
|
||||
const (
|
||||
RequestFailureLabel = "failure"
|
||||
RequestSuccessLabel = "succeeded"
|
||||
)
|
||||
|
||||
func WaitForCompletion(number int, url string, tk toolkit.Toolkit, issues services.IssuesService, strategy retry.Strategy) error {
|
||||
for a := retry.Start(strategy, nil); a.Next(); {
|
||||
issue, _, err := issues.Get(context.Background(), "buildpacks", "registry-index", number)
|
||||
if err != nil {
|
||||
tk.Warningf("unable to get state for %s", url)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, l := range issue.Labels {
|
||||
if *l.Name == RequestFailureLabel {
|
||||
return toolkit.FailedErrorf("Registry request %s failed", url)
|
||||
} else if *l.Name == RequestSuccessLabel {
|
||||
fmt.Printf("Registry request %s succeeded\n", url)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toolkit.FailedError("timed out waiting for request to be processed")
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package index_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
)
|
||||
|
||||
func TestWaitForCompletion(t *testing.T) {
|
||||
spec.Run(t, "wait-for-completion", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
i = &services.MockIssuesService{}
|
||||
s = retry.LimitCount(2, retry.Regular{Min: 2})
|
||||
tk = &toolkit.MockToolkit{}
|
||||
)
|
||||
|
||||
it("it handles success", func() {
|
||||
i.On("Get", mock.Anything, "buildpacks", "registry-index", 1).
|
||||
Return(&github.Issue{Labels: []*github.Label{{Name: github.String(index.RequestSuccessLabel)}}}, nil, nil)
|
||||
|
||||
Expect(index.WaitForCompletion(1, "test-url", tk, i, s)).To(Succeed())
|
||||
})
|
||||
|
||||
it("it handles failure", func() {
|
||||
i.On("Get", mock.Anything, "buildpacks", "registry-index", 1).
|
||||
Return(&github.Issue{Labels: []*github.Label{{Name: github.String(index.RequestFailureLabel)}}}, nil, nil)
|
||||
|
||||
Expect(index.WaitForCompletion(1, "test-url", tk, i, s)).
|
||||
To(MatchError("::error ::Registry request test-url failed"))
|
||||
})
|
||||
|
||||
it("retries", func() {
|
||||
i.On("Get", mock.Anything, "buildpacks", "registry-index", 1).
|
||||
Return(&github.Issue{}, nil, nil).
|
||||
Once()
|
||||
i.On("Get", mock.Anything, "buildpacks", "registry-index", 1).
|
||||
Return(&github.Issue{Labels: []*github.Label{{Name: github.String(index.RequestSuccessLabel)}}}, nil, nil)
|
||||
|
||||
Expect(index.WaitForCompletion(1, "test-url", tk, i, s)).To(Succeed())
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package namespace
|
||||
|
||||
var restrictedNamespaces = []string{
|
||||
"buildpack",
|
||||
"buildpack-io",
|
||||
"buildpack.io",
|
||||
"buildpackio",
|
||||
"buildpacks",
|
||||
"buildpacks-io",
|
||||
"buildpacks.io",
|
||||
"cnb",
|
||||
"cnbs",
|
||||
"cncf",
|
||||
"cncf-cnb",
|
||||
"cncf-cnbs",
|
||||
"example",
|
||||
"examples",
|
||||
"official",
|
||||
"pack",
|
||||
"sample",
|
||||
"samples",
|
||||
}
|
||||
|
||||
type Namespace struct {
|
||||
Owners []Owner `json:"owners"`
|
||||
}
|
||||
|
||||
func IsRestricted(namespace string) bool {
|
||||
for _, n := range restrictedNamespaces {
|
||||
if n == namespace {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package namespace_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
|
||||
"github.com/buildpacks/github-actions/registry/internal/namespace"
|
||||
)
|
||||
|
||||
func TestNamespace(t *testing.T) {
|
||||
spec.Run(t, "namespace", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
)
|
||||
|
||||
it("identifies restricted namespaces", func() {
|
||||
Expect(namespace.IsRestricted("cnb")).To(BeTrue())
|
||||
Expect(namespace.IsRestricted("test-namespace")).To(BeFalse())
|
||||
})
|
||||
})
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package namespace
|
||||
|
||||
const (
|
||||
OrganizationType = "github_org"
|
||||
UserType = "github_user"
|
||||
)
|
||||
|
||||
type Owner struct {
|
||||
ID int64 `json:"id"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type OwnerPredicate func(Owner) bool
|
||||
|
||||
func IsOwner(owners []Owner, predicate OwnerPredicate) bool {
|
||||
for _, o := range owners {
|
||||
if predicate(o) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func ByUser(id int64) OwnerPredicate {
|
||||
return func(owner Owner) bool {
|
||||
return owner.Type == UserType && owner.ID == id
|
||||
}
|
||||
}
|
||||
|
||||
func ByOrganizations(ids []int64) OwnerPredicate {
|
||||
return func(owner Owner) bool {
|
||||
for _, id := range ids {
|
||||
if owner.Type == OrganizationType && owner.ID == id {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package namespace_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
|
||||
"github.com/buildpacks/github-actions/registry/internal/namespace"
|
||||
)
|
||||
|
||||
func TestOwner(t *testing.T) {
|
||||
spec.Run(t, "owner", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
)
|
||||
|
||||
it("identifies owner by predicate", func() {
|
||||
Expect(namespace.IsOwner([]namespace.Owner{{}}, func(_ namespace.Owner) bool {
|
||||
return false
|
||||
})).To(BeFalse())
|
||||
|
||||
Expect(namespace.IsOwner([]namespace.Owner{{}}, func(_ namespace.Owner) bool {
|
||||
return true
|
||||
})).To(BeTrue())
|
||||
})
|
||||
|
||||
it("identifies owner by user", func() {
|
||||
Expect(namespace.ByUser(1)(namespace.Owner{ID: 2, Type: namespace.OrganizationType})).To(BeFalse())
|
||||
Expect(namespace.ByUser(1)(namespace.Owner{ID: 2, Type: namespace.UserType})).To(BeFalse())
|
||||
Expect(namespace.ByUser(1)(namespace.Owner{ID: 1, Type: namespace.OrganizationType})).To(BeFalse())
|
||||
Expect(namespace.ByUser(1)(namespace.Owner{ID: 1, Type: namespace.UserType})).To(BeTrue())
|
||||
})
|
||||
|
||||
it("identifies owner by organizations", func() {
|
||||
Expect(namespace.ByOrganizations([]int64{1})(namespace.Owner{ID: 2, Type: namespace.UserType})).To(BeFalse())
|
||||
Expect(namespace.ByOrganizations([]int64{1})(namespace.Owner{ID: 2, Type: namespace.OrganizationType})).To(BeFalse())
|
||||
Expect(namespace.ByOrganizations([]int64{1})(namespace.Owner{ID: 1, Type: namespace.UserType})).To(BeFalse())
|
||||
Expect(namespace.ByOrganizations([]int64{1})(namespace.Owner{ID: 1, Type: namespace.OrganizationType})).To(BeTrue())
|
||||
})
|
||||
})
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package namespace
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const version = "v1"
|
||||
|
||||
func Path(namespace string) string {
|
||||
return filepath.Join(version, fmt.Sprintf("%s.json", namespace))
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package namespace_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
|
||||
"github.com/buildpacks/github-actions/registry/internal/namespace"
|
||||
)
|
||||
|
||||
func TestPath(t *testing.T) {
|
||||
spec.Run(t, "path", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
)
|
||||
|
||||
it("returns namespace path", func() {
|
||||
Expect(namespace.Path("test-namespace")).To(Equal(filepath.Join("v1", "test-namespace.json")))
|
||||
})
|
||||
})
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
// Code generated by mockery v2.4.0-beta. DO NOT EDIT.
|
||||
|
||||
package services
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
github "github.com/google/go-github/v39/github"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockIssuesService is an autogenerated mock type for the IssuesService type
|
||||
type MockIssuesService struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Create provides a mock function with given fields: ctx, owner, repo, issue
|
||||
func (_m *MockIssuesService) Create(ctx context.Context, owner string, repo string, issue *github.IssueRequest) (*github.Issue, *github.Response, error) {
|
||||
ret := _m.Called(ctx, owner, repo, issue)
|
||||
|
||||
var r0 *github.Issue
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, *github.IssueRequest) *github.Issue); ok {
|
||||
r0 = rf(ctx, owner, repo, issue)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*github.Issue)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *github.Response
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, *github.IssueRequest) *github.Response); ok {
|
||||
r1 = rf(ctx, owner, repo, issue)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*github.Response)
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(context.Context, string, string, *github.IssueRequest) error); ok {
|
||||
r2 = rf(ctx, owner, repo, issue)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// Get provides a mock function with given fields: ctx, owner, repo, number
|
||||
func (_m *MockIssuesService) Get(ctx context.Context, owner string, repo string, number int) (*github.Issue, *github.Response, error) {
|
||||
ret := _m.Called(ctx, owner, repo, number)
|
||||
|
||||
var r0 *github.Issue
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, int) *github.Issue); ok {
|
||||
r0 = rf(ctx, owner, repo, number)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*github.Issue)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *github.Response
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, int) *github.Response); ok {
|
||||
r1 = rf(ctx, owner, repo, number)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*github.Response)
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(context.Context, string, string, int) error); ok {
|
||||
r2 = rf(ctx, owner, repo, number)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// Code generated by mockery v2.4.0-beta. DO NOT EDIT.
|
||||
|
||||
package services
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
github "github.com/google/go-github/v39/github"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockOrganizationsService is an autogenerated mock type for the OrganizationsService type
|
||||
type MockOrganizationsService struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// List provides a mock function with given fields: ctx, user, opts
|
||||
func (_m *MockOrganizationsService) List(ctx context.Context, user string, opts *github.ListOptions) ([]*github.Organization, *github.Response, error) {
|
||||
ret := _m.Called(ctx, user, opts)
|
||||
|
||||
var r0 []*github.Organization
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, *github.ListOptions) []*github.Organization); ok {
|
||||
r0 = rf(ctx, user, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*github.Organization)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *github.Response
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, *github.ListOptions) *github.Response); ok {
|
||||
r1 = rf(ctx, user, opts)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*github.Response)
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(context.Context, string, *github.ListOptions) error); ok {
|
||||
r2 = rf(ctx, user, opts)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
// Code generated by mockery v2.4.0-beta. DO NOT EDIT.
|
||||
|
||||
package services
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
github "github.com/google/go-github/v39/github"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// MockRepositoriesService is an autogenerated mock type for the RepositoriesService type
|
||||
type MockRepositoriesService struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// CreateFile provides a mock function with given fields: ctx, owner, repo, path, opts
|
||||
func (_m *MockRepositoriesService) CreateFile(ctx context.Context, owner string, repo string, path string, opts *github.RepositoryContentFileOptions) (*github.RepositoryContentResponse, *github.Response, error) {
|
||||
ret := _m.Called(ctx, owner, repo, path, opts)
|
||||
|
||||
var r0 *github.RepositoryContentResponse
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, *github.RepositoryContentFileOptions) *github.RepositoryContentResponse); ok {
|
||||
r0 = rf(ctx, owner, repo, path, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*github.RepositoryContentResponse)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 *github.Response
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, *github.RepositoryContentFileOptions) *github.Response); ok {
|
||||
r1 = rf(ctx, owner, repo, path, opts)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*github.Response)
|
||||
}
|
||||
}
|
||||
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(context.Context, string, string, string, *github.RepositoryContentFileOptions) error); ok {
|
||||
r2 = rf(ctx, owner, repo, path, opts)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// GetContents provides a mock function with given fields: ctx, owner, repo, path, opts
|
||||
func (_m *MockRepositoriesService) GetContents(ctx context.Context, owner string, repo string, path string, opts *github.RepositoryContentGetOptions) (*github.RepositoryContent, []*github.RepositoryContent, *github.Response, error) {
|
||||
ret := _m.Called(ctx, owner, repo, path, opts)
|
||||
|
||||
var r0 *github.RepositoryContent
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, *github.RepositoryContentGetOptions) *github.RepositoryContent); ok {
|
||||
r0 = rf(ctx, owner, repo, path, opts)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*github.RepositoryContent)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 []*github.RepositoryContent
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, *github.RepositoryContentGetOptions) []*github.RepositoryContent); ok {
|
||||
r1 = rf(ctx, owner, repo, path, opts)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).([]*github.RepositoryContent)
|
||||
}
|
||||
}
|
||||
|
||||
var r2 *github.Response
|
||||
if rf, ok := ret.Get(2).(func(context.Context, string, string, string, *github.RepositoryContentGetOptions) *github.Response); ok {
|
||||
r2 = rf(ctx, owner, repo, path, opts)
|
||||
} else {
|
||||
if ret.Get(2) != nil {
|
||||
r2 = ret.Get(2).(*github.Response)
|
||||
}
|
||||
}
|
||||
|
||||
var r3 error
|
||||
if rf, ok := ret.Get(3).(func(context.Context, string, string, string, *github.RepositoryContentGetOptions) error); ok {
|
||||
r3 = rf(ctx, owner, repo, path, opts)
|
||||
} else {
|
||||
r3 = ret.Error(3)
|
||||
}
|
||||
|
||||
return r0, r1, r2, r3
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
)
|
||||
|
||||
//go:generate mockery --all --inpackage --case=underscore
|
||||
|
||||
type IssuesService interface {
|
||||
Create(ctx context.Context, owner string, repo string, issue *github.IssueRequest) (*github.Issue, *github.Response, error)
|
||||
Get(ctx context.Context, owner string, repo string, number int) (*github.Issue, *github.Response, error)
|
||||
}
|
||||
|
||||
type OrganizationsService interface {
|
||||
List(ctx context.Context, user string, opts *github.ListOptions) ([]*github.Organization, *github.Response, error)
|
||||
}
|
||||
|
||||
type RepositoriesService interface {
|
||||
CreateFile(ctx context.Context, owner, repo, path string, opts *github.RepositoryContentFileOptions) (*github.RepositoryContentResponse, *github.Response, error)
|
||||
GetContents(ctx context.Context, owner, repo, path string, opts *github.RepositoryContentGetOptions) (fileContent *github.RepositoryContent, directoryContent []*github.RepositoryContent, resp *github.Response, err error)
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright 2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package registry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-github/v32/github"
|
||||
"github.com/pelletier/go-toml"
|
||||
)
|
||||
|
||||
type IssuesService interface {
|
||||
Create(ctx context.Context, owner string, repo string, issue *github.IssueRequest) (*github.Issue, *github.Response, error)
|
||||
}
|
||||
|
||||
type Registry struct {
|
||||
Issues IssuesService
|
||||
ID string
|
||||
Version string
|
||||
}
|
||||
|
||||
func (r Registry) Add(address string) error {
|
||||
body, err := toml.Marshal(map[string]string{
|
||||
"id": r.ID,
|
||||
"version": r.Version,
|
||||
"addr": address,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to marshal to TOML\n%w", err)
|
||||
}
|
||||
|
||||
req := &github.IssueRequest{
|
||||
Title: github.String(fmt.Sprintf("ADD %s@%s", r.ID, r.Version)),
|
||||
Body: github.String(string(body)),
|
||||
}
|
||||
|
||||
issue, _, err := r.Issues.Create(context.Background(), "buildpacks", "registry-index", req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create issue\n%w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Created issue %s\n", *issue.HTMLURL)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r Registry) Yank() error {
|
||||
body, err := toml.Marshal(map[string]string{
|
||||
"id": r.ID,
|
||||
"version": r.Version,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to marshal to TOML\n%w", err)
|
||||
}
|
||||
|
||||
req := &github.IssueRequest{
|
||||
Title: github.String(fmt.Sprintf("YANK %s@%s", r.ID, r.Version)),
|
||||
Body: github.String(string(body)),
|
||||
}
|
||||
|
||||
issue, _, err := r.Issues.Create(context.Background(), "buildpacks", "registry-index", req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create issue\n%w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Created issue %s\n", *issue.HTMLURL)
|
||||
return nil
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* Copyright 2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package registry_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v32/github"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/pelletier/go-toml"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
|
||||
"github.com/buildpacks/github-actions/registry"
|
||||
)
|
||||
|
||||
func TestRegistry(t *testing.T) {
|
||||
spec.Run(t, "registry", func(t *testing.T, when spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
i = TestIssues{Response: &github.Issue{HTMLURL: github.String("test-html-url")}}
|
||||
|
||||
r = registry.Registry{
|
||||
Issues: &i,
|
||||
ID: "test-namespace/test-name",
|
||||
Version: "test-version",
|
||||
}
|
||||
)
|
||||
|
||||
it("creates add issue", func() {
|
||||
Expect(r.Add("test-address")).To(Succeed())
|
||||
|
||||
Expect(i.Owner).To(Equal("buildpacks"))
|
||||
Expect(i.Repo).To(Equal("registry-index"))
|
||||
Expect(*i.Request.Title).To(Equal("ADD test-namespace/test-name@test-version"))
|
||||
|
||||
var body map[string]string
|
||||
Expect(toml.Unmarshal([]byte(*i.Request.Body), &body)).To(Succeed())
|
||||
Expect(body).To(Equal(map[string]string{
|
||||
"id": "test-namespace/test-name",
|
||||
"version": "test-version",
|
||||
"addr": "test-address",
|
||||
}))
|
||||
})
|
||||
|
||||
it("creates yank issue", func() {
|
||||
Expect(r.Yank()).To(Succeed())
|
||||
|
||||
Expect(i.Owner).To(Equal("buildpacks"))
|
||||
Expect(i.Repo).To(Equal("registry-index"))
|
||||
Expect(*i.Request.Title).To(Equal("YANK test-namespace/test-name@test-version"))
|
||||
|
||||
var body map[string]string
|
||||
Expect(toml.Unmarshal([]byte(*i.Request.Body), &body)).To(Succeed())
|
||||
Expect(body).To(Equal(map[string]string{
|
||||
"id": "test-namespace/test-name",
|
||||
"version": "test-version",
|
||||
}))
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
||||
|
||||
type TestIssues struct {
|
||||
Owner string
|
||||
Repo string
|
||||
Request *github.IssueRequest
|
||||
|
||||
Response *github.Issue
|
||||
}
|
||||
|
||||
func (t *TestIssues) Create(_ context.Context, owner string, repo string, issue *github.IssueRequest) (*github.Issue, *github.Response, error) {
|
||||
t.Owner = owner
|
||||
t.Repo = repo
|
||||
t.Request = issue
|
||||
|
||||
return t.Response, nil, nil
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"golang.org/x/oauth2"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
entry "github.com/buildpacks/github-actions/registry/request-add-entry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tk := &toolkit.DefaultToolkit{}
|
||||
|
||||
t, ok := tk.GetInput("token")
|
||||
if !ok {
|
||||
fmt.Println(toolkit.FailedError("token must be specified"))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
gh := github.NewClient(oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(&oauth2.Token{AccessToken: t})))
|
||||
|
||||
strategy := retry.LimitTime(20*time.Minute,
|
||||
retry.Exponential{
|
||||
Initial: time.Second,
|
||||
MaxDelay: 30 * time.Second,
|
||||
},
|
||||
)
|
||||
|
||||
if err := entry.RequestAddEntry(tk, gh.Issues, strategy); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package entry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"github.com/pelletier/go-toml"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
)
|
||||
|
||||
func RequestAddEntry(tk toolkit.Toolkit, issues services.IssuesService, strategy retry.Strategy) error {
|
||||
c, err := parseConfig(tk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body, err := toml.Marshal(index.Request{
|
||||
ID: c.ID,
|
||||
Version: c.Version,
|
||||
Address: c.Address,
|
||||
})
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to marshal to TOML\n%w", err)
|
||||
}
|
||||
|
||||
req := &github.IssueRequest{
|
||||
Title: github.String(fmt.Sprintf("ADD %s@%s", c.ID, c.Version)),
|
||||
Body: github.String(fmt.Sprintf("```\n%s\n```", string(body))),
|
||||
}
|
||||
|
||||
issue, _, err := issues.Create(context.Background(), "buildpacks", "registry-index", req)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to create issue\n%w", err)
|
||||
}
|
||||
|
||||
url := *issue.HTMLURL
|
||||
number := *issue.Number
|
||||
|
||||
fmt.Printf("Created issue %s\n", url)
|
||||
return index.WaitForCompletion(number, url, tk, issues, strategy)
|
||||
}
|
||||
|
||||
type config struct {
|
||||
ID string
|
||||
Version string
|
||||
Address string
|
||||
}
|
||||
|
||||
func parseConfig(tk toolkit.Toolkit) (config, error) {
|
||||
var (
|
||||
c config
|
||||
ok bool
|
||||
)
|
||||
|
||||
c.ID, ok = tk.GetInput("id")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("id must be set")
|
||||
}
|
||||
|
||||
c.Version, ok = tk.GetInput("version")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("version must be set")
|
||||
}
|
||||
|
||||
c.Address, ok = tk.GetInput("address")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("address must be set")
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package entry_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/pelletier/go-toml"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
"github.com/buildpacks/github-actions/registry/request-add-entry"
|
||||
)
|
||||
|
||||
func TestRequestAddEntry(t *testing.T) {
|
||||
spec.Run(t, "request-add-entry", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
i = &services.MockIssuesService{}
|
||||
s = retry.LimitCount(2, retry.Regular{Min: 2})
|
||||
tk = &toolkit.MockToolkit{}
|
||||
)
|
||||
|
||||
it.Before(func() {
|
||||
tk.On("GetInput", "id").Return("test-namespace/test-name", true)
|
||||
tk.On("GetInput", "version").Return("test-version", true)
|
||||
tk.On("GetInput", "address").Return("test-address", true)
|
||||
|
||||
b, err := toml.Marshal(index.Request{
|
||||
ID: "test-namespace/test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
i.On("Create", mock.Anything, "buildpacks", "registry-index", &github.IssueRequest{
|
||||
Title: github.String("ADD test-namespace/test-name@test-version"),
|
||||
Body: github.String(fmt.Sprintf("```\n%s\n```", string(b))),
|
||||
}).Return(&github.Issue{
|
||||
Number: github.Int(1),
|
||||
HTMLURL: github.String("test-html-url"),
|
||||
}, nil, nil)
|
||||
})
|
||||
|
||||
it("add entry succeeds", func() {
|
||||
i.On("Get", mock.Anything, "buildpacks", "registry-index", 1).Return(&github.Issue{
|
||||
Labels: []*github.Label{{Name: github.String(index.RequestSuccessLabel)}},
|
||||
}, nil, nil)
|
||||
|
||||
Expect(entry.RequestAddEntry(tk, i, s)).To(Succeed())
|
||||
})
|
||||
|
||||
it("add entry fails", func() {
|
||||
i.On("Get", mock.Anything, "buildpacks", "registry-index", 1).Return(&github.Issue{
|
||||
Labels: []*github.Label{{Name: github.String(index.RequestFailureLabel)}},
|
||||
}, nil, nil)
|
||||
|
||||
Expect(entry.RequestAddEntry(tk, i, s)).
|
||||
To(MatchError("::error ::Registry request test-html-url failed"))
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"golang.org/x/oauth2"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
entry "github.com/buildpacks/github-actions/registry/request-yank-entry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tk := &toolkit.DefaultToolkit{}
|
||||
|
||||
t, ok := tk.GetInput("token")
|
||||
if !ok {
|
||||
fmt.Println(toolkit.FailedError("token must be specified"))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
gh := github.NewClient(oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(&oauth2.Token{AccessToken: t})))
|
||||
|
||||
strategy := retry.LimitTime(20*time.Minute,
|
||||
retry.Exponential{
|
||||
Initial: time.Second,
|
||||
MaxDelay: 30 * time.Second,
|
||||
},
|
||||
)
|
||||
|
||||
if err := entry.RequestYankEntry(tk, gh.Issues, strategy); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package entry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"github.com/pelletier/go-toml"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
)
|
||||
|
||||
func RequestYankEntry(tk toolkit.Toolkit, issues services.IssuesService, strategy retry.Strategy) error {
|
||||
c, err := parseConfig(tk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body, err := toml.Marshal(index.Request{
|
||||
ID: c.ID,
|
||||
Version: c.Version,
|
||||
Yank: true,
|
||||
})
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to marshal to TOML\n%w", err)
|
||||
}
|
||||
|
||||
req := &github.IssueRequest{
|
||||
Title: github.String(fmt.Sprintf("YANK %s@%s", c.ID, c.Version)),
|
||||
Body: github.String(fmt.Sprintf("```\n%s\n```", string(body))),
|
||||
}
|
||||
|
||||
issue, _, err := issues.Create(context.Background(), "buildpacks", "registry-index", req)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to create issue\n%w", err)
|
||||
}
|
||||
|
||||
url := *issue.HTMLURL
|
||||
number := *issue.Number
|
||||
|
||||
fmt.Printf("Created issue %s\n", url)
|
||||
return index.WaitForCompletion(number, url, tk, issues, strategy)
|
||||
}
|
||||
|
||||
type config struct {
|
||||
ID string
|
||||
Version string
|
||||
}
|
||||
|
||||
func parseConfig(tk toolkit.Toolkit) (config, error) {
|
||||
var (
|
||||
c config
|
||||
ok bool
|
||||
)
|
||||
|
||||
c.ID, ok = tk.GetInput("id")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("id must be set")
|
||||
}
|
||||
|
||||
c.Version, ok = tk.GetInput("version")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("version must be set")
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package entry_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/pelletier/go-toml"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
"github.com/buildpacks/github-actions/registry/request-yank-entry"
|
||||
)
|
||||
|
||||
func TestRequestYankEntry(t *testing.T) {
|
||||
spec.Run(t, "request-yank-entry", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
i = &services.MockIssuesService{}
|
||||
s = retry.LimitCount(2, retry.Regular{Min: 2})
|
||||
tk = &toolkit.MockToolkit{}
|
||||
)
|
||||
|
||||
it.Before(func() {
|
||||
tk.On("GetInput", "id").Return("test-namespace/test-name", true)
|
||||
tk.On("GetInput", "version").Return("test-version", true)
|
||||
|
||||
b, err := toml.Marshal(index.Request{
|
||||
ID: "test-namespace/test-name",
|
||||
Version: "test-version",
|
||||
Yank: true,
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
i.On("Create", mock.Anything, "buildpacks", "registry-index", &github.IssueRequest{
|
||||
Title: github.String("YANK test-namespace/test-name@test-version"),
|
||||
Body: github.String(fmt.Sprintf("```\n%s\n```", string(b))),
|
||||
}).Return(&github.Issue{
|
||||
Number: github.Int(1),
|
||||
HTMLURL: github.String("test-html-url"),
|
||||
}, nil, nil)
|
||||
})
|
||||
|
||||
it("yank entry succeeds", func() {
|
||||
i.On("Get", mock.Anything, "buildpacks", "registry-index", 1).Return(&github.Issue{
|
||||
Labels: []*github.Label{{Name: github.String(index.RequestSuccessLabel)}},
|
||||
}, nil, nil)
|
||||
|
||||
Expect(entry.RequestYankEntry(tk, i, s)).To(Succeed())
|
||||
})
|
||||
|
||||
it("yank entry fails", func() {
|
||||
i.On("Get", mock.Anything, "buildpacks", "registry-index", 1).Return(&github.Issue{
|
||||
Labels: []*github.Label{{Name: github.String(index.RequestFailureLabel)}},
|
||||
}, nil, nil)
|
||||
|
||||
Expect(entry.RequestYankEntry(tk, i, s)).
|
||||
To(MatchError("::error ::Registry request test-html-url failed"))
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"golang.org/x/oauth2"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/verify-namespace-owner"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tk := &toolkit.DefaultToolkit{}
|
||||
|
||||
t, ok := tk.GetInput("token")
|
||||
if !ok {
|
||||
fmt.Println(toolkit.FailedError("token must be specified"))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
gh := github.NewClient(oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(&oauth2.Token{AccessToken: t})))
|
||||
|
||||
strategy := retry.LimitTime(2*time.Minute,
|
||||
retry.Exponential{
|
||||
Initial: time.Second,
|
||||
Jitter: true,
|
||||
},
|
||||
)
|
||||
|
||||
if err := owner.VerifyNamespaceOwner(tk, gh.Organizations, gh.Repositories, strategy); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package owner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/namespace"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
)
|
||||
|
||||
func VerifyNamespaceOwner(tk toolkit.Toolkit, organizations services.OrganizationsService, repositories services.RepositoriesService, strategy retry.Strategy) error {
|
||||
c, err := parseConfig(tk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var user github.User
|
||||
if err := json.Unmarshal([]byte(c.User), &user); err != nil {
|
||||
return toolkit.FailedErrorf("unable to unmarshal user\n%w", err)
|
||||
}
|
||||
|
||||
n, err := getNamespace(tk, c, user, repositories, strategy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isBlockedNamespaces(config{}) {
|
||||
return toolkit.FailedErrorf("The namespace '%s' is restricted.", c.Namespace)
|
||||
}
|
||||
|
||||
if namespace.IsOwner(n.Owners, namespace.ByUser(*user.ID)) {
|
||||
fmt.Printf("Verified %s is an owner of %s\n", *user.Login, c.Namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
ids, err := listOrganizations(*user.Login, organizations)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to list organizations for %s\n%w", *user.Login, err)
|
||||
}
|
||||
|
||||
if namespace.IsOwner(n.Owners, namespace.ByOrganizations(ids)) {
|
||||
fmt.Printf("Verified %s is an owner of %s\n", *user.Login, c.Namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
return toolkit.FailedErrorf("%s is not an owner of %s", *user.Login, c.Namespace)
|
||||
}
|
||||
|
||||
type config struct {
|
||||
User string
|
||||
Owner string
|
||||
Repository string
|
||||
Namespace string
|
||||
AddIfMissing bool
|
||||
blockedNamespaces []string
|
||||
}
|
||||
|
||||
func parseConfig(tk toolkit.Toolkit) (config, error) {
|
||||
var (
|
||||
c = config{AddIfMissing: false}
|
||||
ok bool
|
||||
)
|
||||
|
||||
c.User, ok = tk.GetInput("user")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("user must be set")
|
||||
}
|
||||
|
||||
c.Owner, ok = tk.GetInput("owner")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("owner must be set")
|
||||
}
|
||||
|
||||
c.Repository, ok = tk.GetInput("repository")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("repository must be set")
|
||||
}
|
||||
|
||||
c.Namespace, ok = tk.GetInput("namespace")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("namespace must be set")
|
||||
}
|
||||
|
||||
c.blockedNamespaces, ok = tk.GetInputList("blocked_namespaces")
|
||||
if !ok {
|
||||
defaultBlockedNamespaces := []string{"cncf", "buildpacks", "cnb", "buildpacksio", "buildpack"}
|
||||
c.blockedNamespaces = defaultBlockedNamespaces
|
||||
}
|
||||
|
||||
if s, ok := tk.GetInput("add-if-missing"); ok {
|
||||
if t, err := strconv.ParseBool(s); err == nil {
|
||||
c.AddIfMissing = t
|
||||
}
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func getNamespace(tk toolkit.Toolkit, c config, user github.User, repositories services.RepositoriesService, strategy retry.Strategy) (namespace.Namespace, error) {
|
||||
file := namespace.Path(c.Namespace)
|
||||
|
||||
for a := retry.Start(strategy, nil); a.Next(); {
|
||||
content, _, resp, err := repositories.GetContents(context.Background(), c.Owner, c.Repository, file, nil)
|
||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
||||
if !c.AddIfMissing {
|
||||
return namespace.Namespace{}, toolkit.FailedErrorf("invalid namespace %s", c.Namespace)
|
||||
}
|
||||
|
||||
b, err := json.Marshal(namespace.Namespace{Owners: []namespace.Owner{{ID: *user.ID, Type: namespace.UserType}}})
|
||||
if err != nil {
|
||||
return namespace.Namespace{}, toolkit.FailedErrorf("unable to decode namespace\n%w", err)
|
||||
}
|
||||
|
||||
tk.Debugf("creating new namespace: %s\n%s", file, b)
|
||||
if _, resp, err := repositories.CreateFile(context.Background(), c.Owner, c.Repository, file, &github.RepositoryContentFileOptions{
|
||||
Author: &github.CommitAuthor{
|
||||
Name: github.String("buildpacks-bot"),
|
||||
Email: github.String("cncf-buildpacks-maintainers@lists.cncf.io"),
|
||||
},
|
||||
Message: github.String(fmt.Sprintf("New Namespace: %s", c.Namespace)),
|
||||
Content: b,
|
||||
}); resp != nil && resp.StatusCode == http.StatusConflict {
|
||||
tk.Warningf("retrying namespace update after conflict: %s", file)
|
||||
continue
|
||||
} else if err != nil {
|
||||
tk.Errorf("unable to create namespace: %s", file)
|
||||
return namespace.Namespace{}, toolkit.FailedErrorf("unable to create namespace\n%w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("New Namespace: %s\n", c.Namespace)
|
||||
continue
|
||||
} else if err != nil {
|
||||
return namespace.Namespace{}, toolkit.FailedErrorf("unable to read namespace %s\n%w", c.Namespace, err)
|
||||
}
|
||||
|
||||
s, err := content.GetContent()
|
||||
if err != nil {
|
||||
return namespace.Namespace{}, toolkit.FailedErrorf("unable to get namespace content\n%w", err)
|
||||
}
|
||||
|
||||
var n namespace.Namespace
|
||||
if err := json.Unmarshal([]byte(s), &n); err != nil {
|
||||
return namespace.Namespace{}, toolkit.FailedErrorf("unable to unmarshal owners\n%w", err)
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
return namespace.Namespace{}, toolkit.FailedError("timed out")
|
||||
}
|
||||
|
||||
func listOrganizations(user string, organizations services.OrganizationsService) ([]int64, error) {
|
||||
var ids []int64
|
||||
|
||||
opt := &github.ListOptions{PerPage: 100}
|
||||
|
||||
for {
|
||||
orgs, rsp, err := organizations.List(context.Background(), user, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, o := range orgs {
|
||||
ids = append(ids, *o.ID)
|
||||
}
|
||||
|
||||
if rsp.NextPage == 0 {
|
||||
break
|
||||
}
|
||||
opt.Page = rsp.NextPage
|
||||
}
|
||||
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func isBlockedNamespaces(c config) bool {
|
||||
for _, name := range c.blockedNamespaces {
|
||||
if c.Namespace == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package owner_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/namespace"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
owner "github.com/buildpacks/github-actions/registry/verify-namespace-owner"
|
||||
)
|
||||
|
||||
func TestVerifyNamespaceOwner(t *testing.T) {
|
||||
spec.Run(t, "verify-namespace-owner", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
ExpectWithOffset = NewWithT(t).ExpectWithOffset
|
||||
|
||||
o = &services.MockOrganizationsService{}
|
||||
r = &services.MockRepositoriesService{}
|
||||
rOpts *github.RepositoryContentGetOptions
|
||||
s = retry.LimitCount(2, retry.Regular{Min: 2})
|
||||
tk = &toolkit.MockToolkit{}
|
||||
)
|
||||
|
||||
asJSONString := func(v interface{}) string {
|
||||
b, err := json.Marshal(v)
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
it.Before(func() {
|
||||
tk.On("Debugf", mock.Anything, mock.Anything, mock.Anything).Return()
|
||||
tk.On("GetInput", "owner").Return("test-owner", true)
|
||||
tk.On("GetInput", "repository").Return("test-repository", true)
|
||||
tk.On("GetInput", "namespace").Return("test-namespace", true)
|
||||
tk.On("GetInput", "user").
|
||||
Return(asJSONString(github.User{ID: github.Int64(1), Login: github.String("test-user")}), true)
|
||||
})
|
||||
|
||||
context("unknown namespace", func() {
|
||||
it.Before(func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("v1", "test-namespace.json"), rOpts).
|
||||
Return(nil, nil, &github.Response{Response: &http.Response{StatusCode: http.StatusNotFound}}, nil).
|
||||
Once()
|
||||
})
|
||||
|
||||
it("fails if add-if-missing is false", func() {
|
||||
tk.On("GetInput", "add-if-missing").Return("", false)
|
||||
tk.On("GetInputList", "blocked_namespaces").Return([]string{"test-owner"}, false)
|
||||
Expect(owner.VerifyNamespaceOwner(tk, o, r, s)).
|
||||
To(MatchError("::error ::invalid namespace test-namespace"))
|
||||
})
|
||||
|
||||
it("fails if namespace is blocked", func() {
|
||||
tk.On("GetInput", "add-if-missing").Return("", false)
|
||||
tk.On("GetInputList", "blocked_namespaces").Return([]string{"test-owner"}, false)
|
||||
Expect(owner.VerifyNamespaceOwner(tk, o, r, s)).
|
||||
To(MatchError("::error ::invalid namespace test-namespace"))
|
||||
})
|
||||
|
||||
it("succeeds if add-if-missing is true", func() {
|
||||
tk.On("GetInput", "add-if-missing").Return("true", true)
|
||||
tk.On("GetInputList", "blocked_namespaces").Return([]string{"true"}, true)
|
||||
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("v1", "test-namespace.json"), rOpts).
|
||||
Return(&github.RepositoryContent{
|
||||
Content: github.String(asJSONString(namespace.Namespace{Owners: []namespace.Owner{{ID: 1, Type: namespace.UserType}}})),
|
||||
}, nil, nil, nil)
|
||||
|
||||
c := asJSONString(namespace.Namespace{Owners: []namespace.Owner{{ID: 1, Type: namespace.UserType}}})
|
||||
|
||||
r.On("CreateFile", mock.Anything, "test-owner", "test-repository", filepath.Join("v1", "test-namespace.json"), &github.RepositoryContentFileOptions{
|
||||
Author: &github.CommitAuthor{
|
||||
Name: github.String("buildpacks-bot"),
|
||||
Email: github.String("cncf-buildpacks-maintainers@lists.cncf.io"),
|
||||
},
|
||||
Message: github.String("New Namespace: test-namespace"),
|
||||
Content: []byte(c),
|
||||
}).Return(&github.RepositoryContentResponse{
|
||||
Content: &github.RepositoryContent{Content: github.String(c)},
|
||||
}, nil, nil)
|
||||
|
||||
Expect(owner.VerifyNamespaceOwner(tk, o, r, s)).To(Succeed())
|
||||
})
|
||||
})
|
||||
|
||||
context("user-owned namespace", func() {
|
||||
|
||||
it.Before(func() {
|
||||
tk.On("GetInput", "add-if-missing").Return("", false)
|
||||
tk.On("GetInputList", "blocked_namespaces").Return([]string{"test-owner"}, false)
|
||||
o.On("List", mock.Anything, "test-user", mock.Anything).
|
||||
Return([]*github.Organization{}, &github.Response{}, nil)
|
||||
})
|
||||
|
||||
it("fails if user does not own", func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("v1", "test-namespace.json"), rOpts).
|
||||
Return(&github.RepositoryContent{
|
||||
Content: github.String(asJSONString(namespace.Namespace{Owners: []namespace.Owner{{ID: 2, Type: namespace.UserType}}})),
|
||||
}, nil, nil, nil)
|
||||
|
||||
Expect(owner.VerifyNamespaceOwner(tk, o, r, s)).
|
||||
To(MatchError("::error ::test-user is not an owner of test-namespace"))
|
||||
})
|
||||
|
||||
it("succeeds if user does own", func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("v1", "test-namespace.json"), rOpts).
|
||||
Return(&github.RepositoryContent{
|
||||
Content: github.String(asJSONString(namespace.Namespace{Owners: []namespace.Owner{{ID: 1, Type: namespace.UserType}}})),
|
||||
}, nil, nil, nil)
|
||||
|
||||
Expect(owner.VerifyNamespaceOwner(tk, o, r, s)).To(Succeed())
|
||||
})
|
||||
})
|
||||
|
||||
context("organization-owned namespace", func() {
|
||||
|
||||
it.Before(func() {
|
||||
tk.On("GetInput", "add-if-missing").Return("", false)
|
||||
tk.On("GetInputList", "blocked_namespaces").Return([]string{""}, false)
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("v1", "test-namespace.json"), rOpts).
|
||||
Return(&github.RepositoryContent{
|
||||
Content: github.String(asJSONString(namespace.Namespace{Owners: []namespace.Owner{{ID: 1, Type: namespace.OrganizationType}}})),
|
||||
}, nil, nil, nil)
|
||||
})
|
||||
|
||||
it("fails if user does not own", func() {
|
||||
o.On("List", mock.Anything, "test-user", mock.Anything).
|
||||
Return([]*github.Organization{}, &github.Response{}, nil)
|
||||
|
||||
Expect(owner.VerifyNamespaceOwner(tk, o, r, s)).
|
||||
To(MatchError("::error ::test-user is not an owner of test-namespace"))
|
||||
})
|
||||
|
||||
it("succeeds if user does own", func() {
|
||||
o.On("List", mock.Anything, "test-user", mock.Anything).
|
||||
Return([]*github.Organization{{ID: github.Int64(1)}}, &github.Response{}, nil)
|
||||
|
||||
Expect(owner.VerifyNamespaceOwner(tk, o, r, s)).To(Succeed())
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"golang.org/x/oauth2"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
entry "github.com/buildpacks/github-actions/registry/yank-entry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tk := &toolkit.DefaultToolkit{}
|
||||
|
||||
t, ok := tk.GetInput("token")
|
||||
if !ok {
|
||||
fmt.Println(toolkit.FailedError("token must be specified"))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
gh := github.NewClient(oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(&oauth2.Token{AccessToken: t})))
|
||||
|
||||
strategy := retry.LimitTime(2*time.Minute,
|
||||
retry.Exponential{
|
||||
Initial: time.Second,
|
||||
Jitter: true,
|
||||
},
|
||||
)
|
||||
|
||||
if err := entry.YankEntry(tk, gh.Repositories, strategy); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package entry
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
)
|
||||
|
||||
func YankEntry(tk toolkit.Toolkit, repositories services.RepositoriesService, strategy retry.Strategy) error {
|
||||
c, err := parseConfig(tk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file := index.Path(c.Namespace, c.Name)
|
||||
|
||||
for a := retry.Start(strategy, nil); a.Next(); {
|
||||
content, _, resp, err := repositories.GetContents(context.Background(), c.Owner, c.Repository, file, nil)
|
||||
if resp != nil && resp.StatusCode == http.StatusNotFound {
|
||||
return toolkit.FailedErrorf("index %s does not exist", c.Name)
|
||||
} else if err != nil {
|
||||
return toolkit.FailedErrorf("unable to read index %s\n%w", c.Name, err)
|
||||
}
|
||||
|
||||
s, err := content.GetContent()
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to get index content\n%w", err)
|
||||
}
|
||||
|
||||
entries, err := index.UnmarshalEntries(s)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to unmarshal entries\n%w", err)
|
||||
}
|
||||
|
||||
i := indexOf(entries, c.Namespace, c.Version)
|
||||
if i == nil {
|
||||
return toolkit.FailedErrorf("index %s already does not have namespace %s and version %s", c.Name, c.Namespace, c.Version)
|
||||
}
|
||||
|
||||
entries[*i].Yanked = true
|
||||
|
||||
s, err = index.MarshalEntries(entries)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to marshal entries\n%w", err)
|
||||
}
|
||||
|
||||
if _, resp, err := repositories.CreateFile(context.Background(), c.Owner, c.Repository, file, &github.RepositoryContentFileOptions{
|
||||
Author: &github.CommitAuthor{
|
||||
Name: github.String("buildpacks-bot"),
|
||||
Email: github.String("cncf-buildpacks-maintainers@lists.cncf.io"),
|
||||
},
|
||||
Message: github.String(fmt.Sprintf("YANK %s/%s@%s", c.Namespace, c.Name, c.Version)),
|
||||
SHA: content.SHA,
|
||||
Content: []byte(s),
|
||||
}); resp != nil && resp.StatusCode == http.StatusConflict {
|
||||
tk.Warning("retrying index update after conflict")
|
||||
continue
|
||||
} else if err != nil {
|
||||
return toolkit.FailedErrorf("unable to create index\n%w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Yanked %s/%s@%s\n", c.Namespace, c.Name, c.Version)
|
||||
return nil
|
||||
}
|
||||
|
||||
return toolkit.FailedError("timed out")
|
||||
}
|
||||
|
||||
type config struct {
|
||||
Owner string
|
||||
Repository string
|
||||
Namespace string
|
||||
Name string
|
||||
Version string
|
||||
}
|
||||
|
||||
func parseConfig(tk toolkit.Toolkit) (config, error) {
|
||||
var (
|
||||
c config
|
||||
ok bool
|
||||
)
|
||||
|
||||
c.Owner, ok = tk.GetInput("owner")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("owner must be set")
|
||||
}
|
||||
|
||||
c.Repository, ok = tk.GetInput("repository")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("repository must be set")
|
||||
}
|
||||
|
||||
c.Namespace, ok = tk.GetInput("namespace")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("namespace must be set")
|
||||
}
|
||||
|
||||
c.Name, ok = tk.GetInput("name")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("name must be set")
|
||||
}
|
||||
|
||||
c.Version, ok = tk.GetInput("version")
|
||||
if !ok {
|
||||
return config{}, toolkit.FailedError("version must be set")
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func indexOf(entries []index.Entry, namespace string, version string) *int {
|
||||
for i, e := range entries {
|
||||
if e.Namespace == namespace && e.Version == version {
|
||||
return &i
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package entry_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v39/github"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"gopkg.in/retry.v1"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
entry "github.com/buildpacks/github-actions/registry/yank-entry"
|
||||
)
|
||||
|
||||
func TestYankEntry(t *testing.T) {
|
||||
spec.Run(t, "yank-entry", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
ExpectWithOffset = NewWithT(t).ExpectWithOffset
|
||||
|
||||
r = &services.MockRepositoriesService{}
|
||||
rOpts *github.RepositoryContentGetOptions
|
||||
s = retry.LimitCount(2, retry.Regular{Min: 2})
|
||||
tk = &toolkit.MockToolkit{}
|
||||
)
|
||||
|
||||
asJSONString := func(v interface{}) string {
|
||||
b, err := json.Marshal(v)
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
it.Before(func() {
|
||||
tk.On("GetInput", "owner").Return("test-owner", true)
|
||||
tk.On("GetInput", "repository").Return("test-repository", true)
|
||||
tk.On("GetInput", "namespace").Return("test-namespace", true)
|
||||
tk.On("GetInput", "name").Return("test-name", true)
|
||||
tk.On("GetInput", "version").Return("test-version", true)
|
||||
|
||||
})
|
||||
|
||||
context("index does not exist", func() {
|
||||
it.Before(func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), rOpts).
|
||||
Return(nil, nil, &github.Response{Response: &http.Response{StatusCode: http.StatusNotFound}}, nil)
|
||||
})
|
||||
|
||||
it("fails if index does not exist", func() {
|
||||
Expect(entry.YankEntry(tk, r, s)).
|
||||
To(MatchError("::error ::index test-name does not exist"))
|
||||
})
|
||||
})
|
||||
|
||||
context("index does exist", func() {
|
||||
|
||||
it("fails if version does not exist", func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), rOpts).
|
||||
Return(&github.RepositoryContent{
|
||||
Content: github.String(asJSONString(index.Entry{
|
||||
Namespace: "test-namespace",
|
||||
Name: "test-name",
|
||||
Version: "another-version",
|
||||
Address: "test-address",
|
||||
})),
|
||||
SHA: github.String("test-sha"),
|
||||
}, nil, nil, nil)
|
||||
|
||||
Expect(entry.YankEntry(tk, r, s)).
|
||||
To(MatchError("::error ::index test-name already does not have namespace test-namespace and version test-version"))
|
||||
})
|
||||
|
||||
it("adds entry to index", func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), rOpts).
|
||||
Return(&github.RepositoryContent{
|
||||
Content: github.String(asJSONString(index.Entry{
|
||||
Namespace: "test-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
})),
|
||||
SHA: github.String("test-sha"),
|
||||
}, nil, nil, nil)
|
||||
|
||||
r.On("CreateFile", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), &github.RepositoryContentFileOptions{
|
||||
Author: &github.CommitAuthor{
|
||||
Name: github.String("buildpacks-bot"),
|
||||
Email: github.String("cncf-buildpacks-maintainers@lists.cncf.io"),
|
||||
},
|
||||
Message: github.String("YANK test-namespace/test-name@test-version"),
|
||||
Content: []byte(fmt.Sprintf("%s\n",
|
||||
asJSONString(index.Entry{
|
||||
Namespace: "test-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
Yanked: true,
|
||||
}),
|
||||
)),
|
||||
SHA: github.String("test-sha"),
|
||||
}).
|
||||
Return(nil, nil, nil)
|
||||
|
||||
Expect(entry.YankEntry(tk, r, s)).To(Succeed())
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
|
@ -1,29 +1,17 @@
|
|||
name: 'Setup pack CLI'
|
||||
description: 'Setup the Cloud Native Buildpacks pack CLI as well as other useful tools and add them to $PATH'
|
||||
description: 'Install the Cloud Native Buildpacks pack CLI and add it to $PATH'
|
||||
author: 'Cloud Native Buildpacks'
|
||||
|
||||
inputs:
|
||||
crane-version:
|
||||
description: 'The version of crane to install'
|
||||
required: false
|
||||
default: '0.1.4'
|
||||
jq-version:
|
||||
description: 'The version of jq to install'
|
||||
required: false
|
||||
default: '1.6'
|
||||
pack-version:
|
||||
description: 'The version of pack to install'
|
||||
required: false
|
||||
default: '0.14.2'
|
||||
yj-version:
|
||||
description: 'The version of yj to install'
|
||||
required: false
|
||||
default: '5.0.0'
|
||||
default: '0.38.2'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Setup pack CLI
|
||||
- name: Install pack CLI
|
||||
shell: bash
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
@ -33,24 +21,10 @@ runs:
|
|||
mkdir -p "${HOME}"/bin
|
||||
echo "PATH=${HOME}/bin:${PATH}" >> "${GITHUB_ENV}"
|
||||
|
||||
CRANE_VERSION=${{ inputs.crane-version }}
|
||||
echo "Installing crane ${CRANE_VERSION}"
|
||||
curl \
|
||||
--show-error \
|
||||
--silent \
|
||||
--location \
|
||||
"https://github.com/google/go-containerregistry/releases/download/v${CRANE_VERSION}/go-containerregistry_Linux_x86_64.tar.gz" \
|
||||
| tar -C "${HOME}/bin" -xz crane
|
||||
|
||||
JQ_VERSION=${{ inputs.jq-version }}
|
||||
echo "Installing jq ${JQ_VERSION}"
|
||||
curl \
|
||||
--show-error \
|
||||
--silent \
|
||||
--location \
|
||||
--output "${HOME}/bin/jq" \
|
||||
"https://github.com/stedolan/jq/releases/download/jq-${JQ_VERSION}/jq-linux64"
|
||||
chmod +x "${HOME}"/bin/jq
|
||||
PLATFORM="linux"
|
||||
if [ $(arch) = "aarch64" ]; then
|
||||
PLATFORM="linux-arm64"
|
||||
fi
|
||||
|
||||
PACK_VERSION=${{ inputs.pack-version }}
|
||||
echo "Installing pack ${PACK_VERSION}"
|
||||
|
@ -58,15 +32,9 @@ runs:
|
|||
--show-error \
|
||||
--silent \
|
||||
--location \
|
||||
"https://github.com/buildpacks/pack/releases/download/v${PACK_VERSION}/pack-v${PACK_VERSION}-linux.tgz" \
|
||||
--fail \
|
||||
--retry 3 \
|
||||
--connect-timeout 5 \
|
||||
--max-time 60 \
|
||||
"https://github.com/buildpacks/pack/releases/download/v${PACK_VERSION}/pack-v${PACK_VERSION}-${PLATFORM}.tgz" \
|
||||
| tar -C "${HOME}/bin" -xz pack
|
||||
|
||||
YJ_VERSION=${{ inputs.yj-version }}
|
||||
echo "Installing yj ${YJ_VERSION}"
|
||||
curl \
|
||||
--show-error \
|
||||
--silent \
|
||||
--location \
|
||||
--output "${HOME}/bin/yj" \
|
||||
"https://github.com/sclevine/yj/releases/download/v${YJ_VERSION}/yj-linux"
|
||||
chmod +x "${HOME}"/bin/yj
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
name: 'Setup tools'
|
||||
description: 'Install the tools crane and yq, and add them to $PATH'
|
||||
author: 'Cloud Native Buildpacks'
|
||||
|
||||
inputs:
|
||||
crane-version:
|
||||
description: 'The version of crane to install'
|
||||
required: false
|
||||
default: '0.19.1'
|
||||
yj-version:
|
||||
description: 'The version of yj to install'
|
||||
required: false
|
||||
default: '5.1.0'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Install additional buildpack management tools
|
||||
shell: bash
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
mkdir -p "${HOME}"/bin
|
||||
echo "PATH=${HOME}/bin:${PATH}" >> "${GITHUB_ENV}"
|
||||
|
||||
CRANE_PLATFORM="Linux_x86_64"
|
||||
if [ $(arch) = "aarch64" ]; then
|
||||
CRANE_PLATFORM="Linux_arm64"
|
||||
fi
|
||||
CRANE_VERSION=${{ inputs.crane-version }}
|
||||
echo "Installing crane ${CRANE_VERSION}"
|
||||
curl \
|
||||
--show-error \
|
||||
--silent \
|
||||
--location \
|
||||
--fail \
|
||||
--retry 3 \
|
||||
--connect-timeout 5 \
|
||||
--max-time 60 \
|
||||
"https://github.com/google/go-containerregistry/releases/download/v${CRANE_VERSION}/go-containerregistry_${CRANE_PLATFORM}.tar.gz" \
|
||||
| tar -C "${HOME}/bin" -xz crane
|
||||
|
||||
YJ_VERSION=${{ inputs.yj-version }}
|
||||
echo "Installing yj ${YJ_VERSION}"
|
||||
YJ_DOWNLOAD_FILENAME="yj-linux"
|
||||
if [[ "${YJ_VERSION}" < "5.1.0" ]]; then
|
||||
YJ_PLATFORM=""
|
||||
else
|
||||
YJ_PLATFORM="-amd64"
|
||||
fi
|
||||
if [ $(arch) = "aarch64" ]; then
|
||||
YJ_PLATFORM="-arm64"
|
||||
fi
|
||||
curl \
|
||||
--show-error \
|
||||
--silent \
|
||||
--location \
|
||||
--fail \
|
||||
--retry 3 \
|
||||
--connect-timeout 5 \
|
||||
--max-time 60 \
|
||||
--output "${HOME}/bin/yj" \
|
||||
"https://github.com/sclevine/yj/releases/download/v${YJ_VERSION}/${YJ_DOWNLOAD_FILENAME}${YJ_PLATFORM}"
|
||||
chmod +x "${HOME}"/bin/yj
|
102
verify/verify.go
102
verify/verify.go
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package verify
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
)
|
||||
|
||||
const MetadataLabel = "io.buildpacks.buildpackage.metadata"
|
||||
|
||||
type Verifier struct {
|
||||
Image func(name.Reference, ...remote.Option) (v1.Image, error)
|
||||
|
||||
ID string
|
||||
Version string
|
||||
Address string
|
||||
}
|
||||
|
||||
func (v Verifier) Verify() error {
|
||||
ref, err := name.ParseReference(v.Address)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse address %s as image reference\n%w", v.Address, err)
|
||||
}
|
||||
|
||||
if _, ok := ref.(name.Digest); !ok {
|
||||
return fmt.Errorf("address %s must be in digest form <host>/<repository>@sh256:<digest>", v.Address)
|
||||
}
|
||||
|
||||
image, err := v.Image(ref)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to retrieve image %s\n%w", v.Address, err)
|
||||
}
|
||||
|
||||
configFile, err := image.ConfigFile()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to retrieve config file\n%w", err)
|
||||
}
|
||||
|
||||
raw, ok := configFile.Config.Labels[MetadataLabel]
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to retrieve %s label", MetadataLabel)
|
||||
}
|
||||
|
||||
var m metadata
|
||||
if err := json.Unmarshal([]byte(raw), &m); err != nil {
|
||||
return fmt.Errorf("unable to unmarshal %s label", MetadataLabel)
|
||||
}
|
||||
|
||||
if v.ID != m.ID {
|
||||
return fmt.Errorf("invalid id in buildpackage: expected '%s', found '%s'", v.ID, m.ID)
|
||||
}
|
||||
|
||||
if v.Version != m.Version {
|
||||
return fmt.Errorf("invalid version in buildpackage: expected '%s', found '%s'", v.Version, m.Version)
|
||||
|
||||
}
|
||||
|
||||
var stacks []string
|
||||
for _, s := range m.Stacks {
|
||||
stacks = append(stacks, s.ID)
|
||||
}
|
||||
|
||||
fmt.Printf(`Verified %s
|
||||
ID: %s
|
||||
Version: %s
|
||||
Homepage: %s
|
||||
Stacks: %s
|
||||
`, v.Address, m.ID, m.Version, m.Homepage, strings.Join(stacks, ", "))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type metadata struct {
|
||||
ID string
|
||||
Version string
|
||||
Homepage string
|
||||
Stacks []stack
|
||||
}
|
||||
|
||||
type stack struct {
|
||||
ID string
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or 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
|
||||
*
|
||||
* https://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.
|
||||
*/
|
||||
|
||||
package verify_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/fake"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
|
||||
"github.com/buildpacks/github-actions/verify"
|
||||
)
|
||||
|
||||
func TestVerify(t *testing.T) {
|
||||
spec.Run(t, "verify", func(t *testing.T, when spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
|
||||
r = &TestRemote{Labels: make(map[string]string)}
|
||||
|
||||
v = verify.Verifier{
|
||||
Image: r.Image,
|
||||
|
||||
ID: "test-id",
|
||||
Version: "test-version",
|
||||
Address: "host/repository@sha256:04ba2d17480910bd340f0305d846b007148dafd64bc6fc2626870c174b7c7de7",
|
||||
}
|
||||
)
|
||||
|
||||
it("fails if address is not a digest image reference", func() {
|
||||
v.Address = "test-host/test-repository:test-version"
|
||||
|
||||
Expect(v.Verify()).To(MatchError("address test-host/test-repository:test-version must be in digest form <host>/<repository>@sh256:<digest>"))
|
||||
})
|
||||
|
||||
it("fails if io.buildpacks.buildpackage.metadata is not on image", func() {
|
||||
Expect(v.Verify()).To(MatchError("unable to retrieve io.buildpacks.buildpackage.metadata label"))
|
||||
})
|
||||
|
||||
it("fails if id does not match", func() {
|
||||
r.Labels[verify.MetadataLabel] = `{ "id": "another-id", "version": "test-version" }`
|
||||
|
||||
Expect(v.Verify()).To(MatchError("invalid id in buildpackage: expected 'test-id', found 'another-id'"))
|
||||
})
|
||||
|
||||
it("fails if version does not match", func() {
|
||||
r.Labels[verify.MetadataLabel] = `{ "id": "test-id", "version": "another-version" }`
|
||||
|
||||
Expect(v.Verify()).To(MatchError("invalid version in buildpackage: expected 'test-version', found 'another-version'"))
|
||||
})
|
||||
|
||||
it("passes if version and id match", func() {
|
||||
r.Labels[verify.MetadataLabel] = `{ "id": "test-id", "version": "test-version" }`
|
||||
|
||||
Expect(v.Verify()).To(Succeed())
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
||||
|
||||
type TestRemote struct {
|
||||
Labels map[string]string
|
||||
}
|
||||
|
||||
func (t *TestRemote) Image(_ name.Reference, _ ...remote.Option) (v1.Image, error) {
|
||||
i := &fake.FakeImage{}
|
||||
i.ConfigFileReturns(&v1.ConfigFile{
|
||||
Config: v1.Config{
|
||||
Labels: t.Labels,
|
||||
},
|
||||
}, nil)
|
||||
|
||||
return i, nil
|
||||
}
|
Loading…
Reference in New Issue