mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-21 11:01:38 -05:00
Compare commits
569 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d904740d93 | ||
|
|
3c1b371e7e | ||
|
|
b27e1dd66d | ||
|
|
1d917f7790 | ||
|
|
f3c06e7912 | ||
|
|
066bf98535 | ||
|
|
2b8487115e | ||
|
|
37ce99dea7 | ||
|
|
a7e9a3d14b | ||
|
|
cb0edbdd1a | ||
|
|
7eac18f7a0 | ||
|
|
d314ea393e | ||
|
|
ce43b4e17d | ||
|
|
4fd2f92e27 | ||
|
|
535799fe23 | ||
|
|
36c480699f | ||
|
|
950bb1e53b | ||
|
|
25b80f0498 | ||
|
|
b63fd59372 | ||
|
|
f0f4a0a3cf | ||
|
|
c4cc2e5d68 | ||
|
|
7804f2cf3f | ||
|
|
b52386a36a | ||
|
|
e8158d4374 | ||
|
|
de9d73c948 | ||
|
|
1b9f4cbbae | ||
|
|
1bbf5a78c1 | ||
|
|
d3c474162d | ||
|
|
4cb03a1ef0 | ||
|
|
9a79f7bf49 | ||
|
|
d166d982c4 | ||
|
|
f06fd7f6f7 | ||
|
|
071f631c34 | ||
|
|
f8844b328f | ||
|
|
bba66e4e4d | ||
|
|
41a3c8661c | ||
|
|
eb2cd6238f | ||
|
|
11a969f44f | ||
|
|
6c7a8313b2 | ||
|
|
aeb1e776d4 | ||
|
|
6ae380b65d | ||
|
|
96f345a74a | ||
|
|
f41da46ccb | ||
|
|
ccd458b876 | ||
|
|
1e4ff85ed7 | ||
|
|
6a321b930d | ||
|
|
ef7de661df | ||
|
|
7b1d34b2ce | ||
|
|
c8b3e46495 | ||
|
|
6b10ecd588 | ||
|
|
1d276d90e0 | ||
|
|
0b6d2ea449 | ||
|
|
67f8ffea52 | ||
|
|
830d9eb803 | ||
|
|
c0ad66b823 | ||
|
|
b64b3f6b0b | ||
|
|
386c986480 | ||
|
|
63712909aa | ||
|
|
2534c907de | ||
|
|
4e39c5fcf6 | ||
|
|
3e6ce6b370 | ||
|
|
793fe9c1f2 | ||
|
|
7d180be364 | ||
|
|
aa705f04c8 | ||
|
|
8f835fc84e | ||
|
|
cbf095c0ff | ||
|
|
f7aeccb0d4 | ||
|
|
36cd60f290 | ||
|
|
45d7a6dd62 | ||
|
|
6282958bd1 | ||
|
|
6838261aed | ||
|
|
517558fdfd | ||
|
|
9604d685d1 | ||
|
|
3780203b1d | ||
|
|
86c14cd7e1 | ||
|
|
254f16b31a | ||
|
|
b194a5a784 | ||
|
|
1e3cef5d1b | ||
|
|
36550798f3 | ||
|
|
09d9ad0020 | ||
|
|
e77b0bfa89 | ||
|
|
719a7889fc | ||
|
|
0687d61170 | ||
|
|
1d52740f62 | ||
|
|
a7749471ec | ||
|
|
146b27f511 | ||
|
|
e1fc230273 | ||
|
|
c9c670cc86 | ||
|
|
8bb6b5fc1a | ||
|
|
000923207e | ||
|
|
0d34e83ddd | ||
|
|
39f5ad9e16 | ||
|
|
1959736078 | ||
|
|
529296110b | ||
|
|
a241b511c6 | ||
|
|
f77adcaa4a | ||
|
|
70a5f0702e | ||
|
|
6dbaa7e6f6 | ||
|
|
f3e7337196 | ||
|
|
840084704b | ||
|
|
dde8e169ac | ||
|
|
6188c218ee | ||
|
|
3eedbf04df | ||
|
|
30fb6b25b1 | ||
|
|
887d218342 | ||
|
|
4c008059df | ||
|
|
79875c0b95 | ||
|
|
f2b623b3b2 | ||
|
|
97a4ecdfbb | ||
|
|
1bceb04a4a | ||
|
|
9cefed840e | ||
|
|
dbaa78a737 | ||
|
|
77006cee86 | ||
|
|
8967ec36f4 | ||
|
|
1210bceded | ||
|
|
a891ef4784 | ||
|
|
7fc8b1c849 | ||
|
|
27ee9527bb | ||
|
|
08d717dff7 | ||
|
|
132d22bfe7 | ||
|
|
61662f6086 | ||
|
|
570e41cdcb | ||
|
|
e04c1624bc | ||
|
|
705dcd2b8c | ||
|
|
c3c2d83da1 | ||
|
|
e2a675ef58 | ||
|
|
701f656c55 | ||
|
|
d7ecdd89b1 | ||
|
|
d641988161 | ||
|
|
801f797440 | ||
|
|
394417f93e | ||
|
|
b11e7a8f23 | ||
|
|
3b74d7843f | ||
|
|
aee14c8170 | ||
|
|
265f59ae94 | ||
|
|
2b1c8fe77a | ||
|
|
f551cfb835 | ||
|
|
b8858f011d | ||
|
|
128767c713 | ||
|
|
8352c7631c | ||
|
|
b669ab9481 | ||
|
|
86e0c6963f | ||
|
|
c7da145c92 | ||
|
|
9bb035d3eb | ||
|
|
88ce98b2e1 | ||
|
|
f53f4fc522 | ||
|
|
63c6c0631e | ||
|
|
7b4181dd13 | ||
|
|
9f69139dea | ||
|
|
784d8e9e96 | ||
|
|
fe7ac55e97 | ||
|
|
f45145ceb5 | ||
|
|
fffe8cc17b | ||
|
|
e69bd2c01f | ||
|
|
e10b1eb5a9 | ||
|
|
65ef41d53d | ||
|
|
d38dcc853d | ||
|
|
9ef2ebc0d0 | ||
|
|
dd6e005ed1 | ||
|
|
346bf0e81e | ||
|
|
e421d2fe7e | ||
|
|
2312bed4ad | ||
|
|
75ab9b6812 | ||
|
|
51e5890c83 | ||
|
|
e80b8f92f2 | ||
|
|
7e57503aa6 | ||
|
|
adf6f253f0 | ||
|
|
c09ab8d0a9 | ||
|
|
fd1fc8ac67 | ||
|
|
23b347662a | ||
|
|
5f48e4a28d | ||
|
|
20800a4279 | ||
|
|
cab9ab3b91 | ||
|
|
5afdf04aba | ||
|
|
52782cfebd | ||
|
|
b3d92aaad3 | ||
|
|
de2880d110 | ||
|
|
742232ddd5 | ||
|
|
ae8d3ab1bf | ||
|
|
13b722eaf8 | ||
|
|
30e2b135ce | ||
|
|
55174c6124 | ||
|
|
d122e7636c | ||
|
|
4d8fdf5833 | ||
|
|
2547754d0f | ||
|
|
7de41a98b4 | ||
|
|
fcf00b79fc | ||
|
|
b36ee9318f | ||
|
|
8cc66dade3 | ||
|
|
bfd878bff7 | ||
|
|
6858889f41 | ||
|
|
d95aff1d3c | ||
|
|
14a63977c8 | ||
|
|
8d45e40901 | ||
|
|
52baaf298e | ||
|
|
5dd1cbeed8 | ||
|
|
7ef0ef65f4 | ||
|
|
4023f5ce26 | ||
|
|
e9c9a98ab3 | ||
|
|
ba744ab950 | ||
|
|
34f6083bfc | ||
|
|
a3efb193e0 | ||
|
|
727f37d6a5 | ||
|
|
4e849f0d60 | ||
|
|
10047b9a59 | ||
|
|
b406dda13c | ||
|
|
6e2bf7521f | ||
|
|
c86085352e | ||
|
|
c4d0754954 | ||
|
|
19dd85bfe3 | ||
|
|
15803c2a05 | ||
|
|
d54b7b9970 | ||
|
|
72a43854f8 | ||
|
|
a7ba78b186 | ||
|
|
d34b65ebb7 | ||
|
|
55331f9677 | ||
|
|
e7c66d9424 | ||
|
|
cd8a747522 | ||
|
|
d0aae8e95b | ||
|
|
402604ba34 | ||
|
|
7b58568d26 | ||
|
|
d9cf93cdae | ||
|
|
23f9e37986 | ||
|
|
7554fbcaa0 | ||
|
|
58758286d8 | ||
|
|
d59d6583bd | ||
|
|
36ee34663b | ||
|
|
eb1212a606 | ||
|
|
1cf905a7b8 | ||
|
|
e9fefd2487 | ||
|
|
6c4bf812cd | ||
|
|
0718876300 | ||
|
|
6acda40894 | ||
|
|
909d022562 | ||
|
|
449d27a5ae | ||
|
|
40a2181953 | ||
|
|
bf82204453 | ||
|
|
6395402b80 | ||
|
|
d3a457daa3 | ||
|
|
a8f2039fb6 | ||
|
|
21315a8a5d | ||
|
|
c121eeec4d | ||
|
|
bab0463b0b | ||
|
|
0f598dd30b | ||
|
|
20a291334e | ||
|
|
6578e5e4cf | ||
|
|
784f8ac963 | ||
|
|
5ec567a4f7 | ||
|
|
794daa3440 | ||
|
|
ec638e2b40 | ||
|
|
e1cf51653e | ||
|
|
010107aea8 | ||
|
|
d202fd703e | ||
|
|
e9b678494c | ||
|
|
7a8681481e | ||
|
|
8bd5ea5c84 | ||
|
|
02064efcaa | ||
|
|
8747ac5c52 | ||
|
|
02f859ac92 | ||
|
|
d7f8b0bfed | ||
|
|
192f7cc390 | ||
|
|
ca05e01144 | ||
|
|
7dfa347250 | ||
|
|
e073c012af | ||
|
|
6c1b13b8be | ||
|
|
fb07ba9e04 | ||
|
|
fcd4c6e15b | ||
|
|
b342a2df7e | ||
|
|
5c823e436a | ||
|
|
3a0ac7279a | ||
|
|
d98a421035 | ||
|
|
1d7e5925a9 | ||
|
|
387f4cd116 | ||
|
|
675969eebc | ||
|
|
4e5846c2c1 | ||
|
|
2d68b2bbce | ||
|
|
dd2d6e0b5c | ||
|
|
170950dca8 | ||
|
|
a577c3feca | ||
|
|
6d81b02c18 | ||
|
|
7a41bfc167 | ||
|
|
90176658fd | ||
|
|
fe1aefdd5f | ||
|
|
9fcfe5b23c | ||
|
|
c2cc32a4a0 | ||
|
|
828c6760e2 | ||
|
|
0738c148ca | ||
|
|
4191ef8aa5 | ||
|
|
41b639c7d6 | ||
|
|
c04f78981c | ||
|
|
197d56a29b | ||
|
|
cd7c94976c | ||
|
|
ed8d2f9927 | ||
|
|
dc14201088 | ||
|
|
562e0fdde7 | ||
|
|
a595fb8fd1 | ||
|
|
683d906138 | ||
|
|
379b24d78c | ||
|
|
d8b3db2ee3 | ||
|
|
4e299dc4b2 | ||
|
|
a5cc1ea223 | ||
|
|
b4195d8984 | ||
|
|
f804e5dd48 | ||
|
|
e6773dd842 | ||
|
|
f829218c2c | ||
|
|
49b0640fde | ||
|
|
63a700ef3f | ||
|
|
03d2e83250 | ||
|
|
316798a9b5 | ||
|
|
bc79d62b35 | ||
|
|
c4db69f391 | ||
|
|
f4e37d3dce | ||
|
|
805dda533a | ||
|
|
463271f0d9 | ||
|
|
7c399e84eb | ||
|
|
92a2233022 | ||
|
|
a6000aef67 | ||
|
|
c707911800 | ||
|
|
630cdbc84f | ||
|
|
4db0814b94 | ||
|
|
b96fb5aa90 | ||
|
|
a0cf244245 | ||
|
|
81e785506c | ||
|
|
69c254aeac | ||
|
|
2d9004e481 | ||
|
|
c53c6d86e2 | ||
|
|
c65c41d704 | ||
|
|
838c27bfa3 | ||
|
|
fec1b7821f | ||
|
|
adbbf7ae7f | ||
|
|
be62f1864d | ||
|
|
ca6ad43e8f | ||
|
|
bd6d438c8c | ||
|
|
7392ce7e31 | ||
|
|
e82e267159 | ||
|
|
eb25cc810f | ||
|
|
d6dab3dd18 | ||
|
|
a795e64bed | ||
|
|
055f10ff8d | ||
|
|
b9ebdf9eb7 | ||
|
|
3bd033b25d | ||
|
|
b7d1e950f3 | ||
|
|
3f31290e8e | ||
|
|
3b7a5b64af | ||
|
|
6a0dd0415b | ||
|
|
45b5f8d136 | ||
|
|
a29bb210b2 | ||
|
|
3c8943aab2 | ||
|
|
bab5118996 | ||
|
|
27f014c70d | ||
|
|
e7773425ee | ||
|
|
0a43ed84e3 | ||
|
|
80db3a492f | ||
|
|
b65a6bd741 | ||
|
|
b6083b6447 | ||
|
|
fe0cff07d6 | ||
|
|
4166c622f3 | ||
|
|
989ee0b2c7 | ||
|
|
cffa7c6b49 | ||
|
|
4621d2e1af | ||
|
|
c62619c17b | ||
|
|
af3d307d40 | ||
|
|
8537a30996 | ||
|
|
b51387bb46 | ||
|
|
f002a26fe4 | ||
|
|
459fab256e | ||
|
|
25b8137a45 | ||
|
|
2f825f8a97 | ||
|
|
aad20bc338 | ||
|
|
893015010d | ||
|
|
027bac766e | ||
|
|
9d2e5ff93e | ||
|
|
85b4bf13f9 | ||
|
|
0d3cec074d | ||
|
|
d9501ffc03 | ||
|
|
f325a2df08 | ||
|
|
5e68ff1dfe | ||
|
|
ae8784e462 | ||
|
|
668f59ca2e | ||
|
|
b50c4fdb49 | ||
|
|
236db4d1b1 | ||
|
|
c39b13a93e | ||
|
|
5a87e552bc | ||
|
|
1fa453f8f2 | ||
|
|
783215c160 | ||
|
|
bdf3261612 | ||
|
|
08b2d9668e | ||
|
|
8a670a8baa | ||
|
|
aaef400194 | ||
|
|
e4a3ec1aac | ||
|
|
1a1556ca75 | ||
|
|
7914fcf101 | ||
|
|
23a69f9b69 | ||
|
|
6263cc2f87 | ||
|
|
f2d4801634 | ||
|
|
301c6f24fe | ||
|
|
fc0721450d | ||
|
|
a6d442bb3b | ||
|
|
b07266e8c2 | ||
|
|
a786e63445 | ||
|
|
d6abcb892d | ||
|
|
3071a7b710 | ||
|
|
6c51b934f9 | ||
|
|
9f2940e8f8 | ||
|
|
aeb4e87c1f | ||
|
|
85e1e01177 | ||
|
|
d063355b1a | ||
|
|
80007a72cc | ||
|
|
bdb81bc9b1 | ||
|
|
023e10b496 | ||
|
|
27cb693bd5 | ||
|
|
80a9d94648 | ||
|
|
6fad30bf3c | ||
|
|
a0c2dc199e | ||
|
|
95980130c8 | ||
|
|
8cc0fdfdc5 | ||
|
|
f83605cbf4 | ||
|
|
90d6defa05 | ||
|
|
ca904ed380 | ||
|
|
784a9270c8 | ||
|
|
d585e75706 | ||
|
|
01509de495 | ||
|
|
fa227c88c9 | ||
|
|
cb607e34d7 | ||
|
|
de9a4e02b1 | ||
|
|
820838fae8 | ||
|
|
85f1f3e0dc | ||
|
|
2d1ffeb47c | ||
|
|
a86301312c | ||
|
|
206188f3ab | ||
|
|
d8a8107dc6 | ||
|
|
26e6cd28c2 | ||
|
|
02093f8497 | ||
|
|
62a0bcc69f | ||
|
|
7181d4c79e | ||
|
|
4551329db0 | ||
|
|
5c14fe4f4c | ||
|
|
d1d6b229ce | ||
|
|
94b4437a6a | ||
|
|
ebdfea25ad | ||
|
|
5f2d8b2bd5 | ||
|
|
85d6b2ef46 | ||
|
|
f424bea0de | ||
|
|
364684c79e | ||
|
|
4d7467a5d5 | ||
|
|
b299f7ed3f | ||
|
|
0c54c12772 | ||
|
|
65b4847874 | ||
|
|
33d2735970 | ||
|
|
822199c9be | ||
|
|
e50bded5d1 | ||
|
|
27763c860c | ||
|
|
634b9f8d08 | ||
|
|
3844638156 | ||
|
|
eb77d86136 | ||
|
|
025e0831e7 | ||
|
|
5bb35d4eed | ||
|
|
f013a88163 | ||
|
|
4f9d45335e | ||
|
|
fee8e78011 | ||
|
|
1be5c926d3 | ||
|
|
72632bc376 | ||
|
|
9890cc79c0 | ||
|
|
b3107dc4b1 | ||
|
|
eccb77aca3 | ||
|
|
5d0f0afdc6 | ||
|
|
33259764f7 | ||
|
|
c9aa3e9f4b | ||
|
|
8e9957adbe | ||
|
|
442c16bc3c | ||
|
|
1c83aa61d7 | ||
|
|
9e3d678536 | ||
|
|
9a944b614d | ||
|
|
bc78f6a573 | ||
|
|
da076c152c | ||
|
|
a2c39369c9 | ||
|
|
be6b23eff0 | ||
|
|
0ab4752643 | ||
|
|
10ff8aa116 | ||
|
|
4f61be2495 | ||
|
|
d5fa5fca3a | ||
|
|
8b543d1d12 | ||
|
|
87f1e26e39 | ||
|
|
9990f7c8e2 | ||
|
|
d6a08a60d9 | ||
|
|
628c8da716 | ||
|
|
79cda5cbe5 | ||
|
|
c34de52a03 | ||
|
|
eb928e0b8f | ||
|
|
84001139cc | ||
|
|
00f98457e8 | ||
|
|
ebd4c6844b | ||
|
|
3b4800de51 | ||
|
|
7b5117b185 | ||
|
|
d36b755d6d | ||
|
|
96729a4817 | ||
|
|
d8fd5b36f7 | ||
|
|
dfa6799fcc | ||
|
|
c64655ae71 | ||
|
|
5e93f2ca9b | ||
|
|
7db7c2927c | ||
|
|
ffdefd3b52 | ||
|
|
02341088eb | ||
|
|
8032f59d41 | ||
|
|
0193f8a6dc | ||
|
|
23cbb98162 | ||
|
|
9b3d65b1d4 | ||
|
|
e2b4dd5a79 | ||
|
|
19c7971630 | ||
|
|
5731366a1c | ||
|
|
ef100b8e82 | ||
|
|
7b92c9eb65 | ||
|
|
5547c2baba | ||
|
|
40ee82ee3e | ||
|
|
3c84575755 | ||
|
|
696db01dc8 | ||
|
|
e0cb88599d | ||
|
|
eff847f35a | ||
|
|
2da0428454 | ||
|
|
1b63fec4e5 | ||
|
|
f137174719 | ||
|
|
75d9246f5e | ||
|
|
cbaffd0b0d | ||
|
|
b33afe3efb | ||
|
|
19f63ea88f | ||
|
|
a1a1793221 | ||
|
|
8da49ff14e | ||
|
|
f0ebc6ed60 | ||
|
|
aaf174e85c | ||
|
|
13dd74efcc | ||
|
|
bafbca492b | ||
|
|
3472e229f1 | ||
|
|
3a04235001 | ||
|
|
0f385b386f | ||
|
|
28ab7372d2 | ||
|
|
e66192cbfd | ||
|
|
63cff7a5ab | ||
|
|
f1b23c96a9 | ||
|
|
ede0937c2b | ||
|
|
83698a14b0 | ||
|
|
2be1394748 | ||
|
|
8135867e06 | ||
|
|
87d5da00bf | ||
|
|
678f2e3878 | ||
|
|
81e8eb9a82 | ||
|
|
fe360afec7 | ||
|
|
80c8b06ec8 | ||
|
|
7ff42eeb08 | ||
|
|
3dbd5ac2c1 | ||
|
|
3c321ee8b7 | ||
|
|
f6128d262b | ||
|
|
d24a289af5 | ||
|
|
89cc59a2fd | ||
|
|
25f563229f | ||
|
|
33ea2d8ee6 | ||
|
|
9e8b01fd1e | ||
|
|
bb468a5b98 | ||
|
|
9a28d47c5b | ||
|
|
45763e12b4 | ||
|
|
316c6a536f | ||
|
|
f5392e3c8f | ||
|
|
4dd59c6b8d | ||
|
|
9e574ae602 | ||
|
|
1dd7e93063 | ||
|
|
13276cf52e | ||
|
|
baa6e4b380 | ||
|
|
3bc5306258 | ||
|
|
c45cfaf01b | ||
|
|
0612a8ac35 |
@@ -8,17 +8,17 @@
|
||||
**/semver/**
|
||||
**/test/**/*.js
|
||||
**/node_modules/**
|
||||
**/vscode-api-tests/testWorkspace/**
|
||||
**/vscode-api-tests/testWorkspace2/**
|
||||
**/extensions/**/out/**
|
||||
**/extensions/**/build/**
|
||||
**/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts
|
||||
**/big-data-cluster/src/bigDataCluster/controller/clusterApiGenerated2.ts
|
||||
**/extensions/markdown-language-features/media/**
|
||||
**/extensions/markdown-language-features/notebook-out/**
|
||||
**/extensions/typescript-basics/test/colorize-fixtures/**
|
||||
**/extensions/**/dist/**
|
||||
**/extensions/typescript-language-features/test-workspace/**
|
||||
/extensions/**/out/**
|
||||
/extensions/**/build/**
|
||||
/extensions/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts
|
||||
/extensions/big-data-cluster/src/bigDataCluster/controller/clusterApiGenerated2.ts
|
||||
/extensions/markdown-language-features/media/**
|
||||
/extensions/markdown-language-features/notebook-out/**
|
||||
/extensions/typescript-basics/test/colorize-fixtures/**
|
||||
/extensions/**/dist/**
|
||||
/extensions/types
|
||||
/extensions/typescript-language-features/test-workspace/**
|
||||
/test/automation/out
|
||||
|
||||
# These files are not linted by `yarn eslint`, so we exclude them from being linted in the editor.
|
||||
# This ensures that if we add new rules and they pass CI, the are also no errors in the editor.
|
||||
|
||||
@@ -212,6 +212,8 @@
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"azdata",
|
||||
"mssql",
|
||||
"azurecore",
|
||||
"**/{vs,sql}/base/common/**",
|
||||
"**/{vs,sql}/base/parts/*/common/**",
|
||||
"**/{vs,sql}/platform/*/common/**"
|
||||
@@ -472,6 +474,8 @@
|
||||
"restrictions": [
|
||||
"vscode",
|
||||
"azdata",
|
||||
"mssql",
|
||||
"azurecore",
|
||||
"vs/nls",
|
||||
"**/{vs,sql}/base/common/**",
|
||||
"**/{vs,sql}/platform/*/common/**",
|
||||
@@ -550,6 +554,7 @@
|
||||
"**/{vs,sql}/workbench/common/**",
|
||||
"**/{vs,sql}/workbench/services/**/common/**",
|
||||
"**/{vs,sql}/workbench/api/**/common/**",
|
||||
"**/{vs,sql}/workbench/contrib/**/common/**",
|
||||
"vs/workbench/contrib/files/common/editors/fileEditorInput", // this should be fine, it only accesses constants from contrib
|
||||
"vscode-textmate",
|
||||
"vscode-oniguruma",
|
||||
@@ -577,6 +582,8 @@
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"azdata",
|
||||
"mssql",
|
||||
"azurecore",
|
||||
"vscode",
|
||||
"**/{vs,sql}/base/**/{common,browser,worker}/**",
|
||||
"**/{vs,sql}/platform/**/{common,browser}/**",
|
||||
@@ -585,6 +592,7 @@
|
||||
"**/{vs,sql}/workbench/{common,browser}/**",
|
||||
"**/{vs,sql}/workbench/api/{common,browser}/**",
|
||||
"**/{vs,sql}/workbench/services/**/{common,browser}/**",
|
||||
"**/{vs,sql}/workbench/contrib/**/common/**",
|
||||
"vscode-textmate",
|
||||
"vscode-oniguruma",
|
||||
"iconv-lite-umd",
|
||||
@@ -1143,6 +1151,7 @@
|
||||
"src/sql/base/browser/ui/table/plugins/checkboxSelectColumn.plugin.ts",
|
||||
"src/sql/base/browser/ui/table/plugins/headerFilter.plugin.ts",
|
||||
"src/sql/base/browser/ui/table/plugins/rowDetailView.ts",
|
||||
"src/sql/base/browser/ui/table/plugins/rowMoveManager.plugin.ts",
|
||||
"src/sql/base/browser/ui/table/plugins/rowSelectionModel.plugin.ts",
|
||||
"src/sql/workbench/services/notebook/browser/outputs/factories.ts",
|
||||
"src/sql/workbench/services/notebook/browser/outputs/mimemodel.ts",
|
||||
|
||||
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@@ -11,6 +11,7 @@
|
||||
/extensions/query-history/ @Charles-Gagnon
|
||||
/extensions/resource-deployment/ @Charles-Gagnon
|
||||
/extensions/schema-compare/ @kisantia
|
||||
/extensions/sql-bindings/ @vasubhog @Charles-Gagnon @lucyzhang929 @chlafreniere @MaddyDev
|
||||
/extensions/sql-database-projects/ @Benjin @kisantia
|
||||
/extensions/mssql/config.json @Charles-Gagnon @alanrenmsft @kburtram
|
||||
|
||||
|
||||
19
.github/label-actions.yml
vendored
19
.github/label-actions.yml
vendored
@@ -2,8 +2,9 @@
|
||||
Needs Logs:
|
||||
comment: "We need more info to debug your particular issue. If you could attach your logs to the issue (ensure no private data is in them), it would help us fix the issue much faster.
|
||||
|
||||
First open the Settings page, find the `Mssql: Tracing Level` setting and change that to `All` then restart ADS and repro your issue.
|
||||
|
||||
There are two types of logs to collect:
|
||||
Next there are two types of logs to collect:
|
||||
|
||||
|
||||
**Console Logs**
|
||||
@@ -27,6 +28,22 @@ There are two types of logs to collect:
|
||||
|
||||
- This will open the log folder locally. Please zip up this folder and attach it to the issue."
|
||||
|
||||
# actions for Needs Logs - Azure label
|
||||
Needs Logs - Azure:
|
||||
comment: "We need more info to debug your Azure Active Directory issue. If you could attach your logs to the issue (ensure no private data is in them), it would help us fix the issue much faster.
|
||||
|
||||
- In the settings menu, find the setting titled `Azure: Logging Level` and select the `Verbose` option
|
||||
|
||||
- Run the process that produces your error
|
||||
|
||||
- Open command palette (Click **View** -> **Command Palette**)
|
||||
|
||||
- Run the command: **`Developer: Open Logs Folder`**
|
||||
|
||||
- Follow this path to find the Azure Accounts log file: `[default log folder]/exthost1/output_logging_[earliest timestamp]/#-Azure Acounts.log`
|
||||
|
||||
- Please attach the Azure-Accounts.log file to the issue."
|
||||
|
||||
# actions for Out of Scope label
|
||||
Out of Scope:
|
||||
comment: "Thank you for opening this suggestion! This enhancement is not planned in our
|
||||
|
||||
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
@@ -13,7 +13,7 @@ on:
|
||||
jobs:
|
||||
windows:
|
||||
name: Windows
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
CHILD_CONCURRENCY: "1"
|
||||
@@ -131,12 +131,15 @@ jobs:
|
||||
ELECTRON_SKIP_BINARY_DOWNLOAD: 1
|
||||
run: yarn --frozen-lockfile --network-timeout 180000
|
||||
|
||||
# Don't inline source maps so that we generate code coverage for ts files
|
||||
- name: Compile and Download
|
||||
run: yarn npm-run-all --max_old_space_size=4095 -lp compile "electron x64" playwright-install download-builtin-extensions
|
||||
env:
|
||||
SQL_NO_INLINE_SOURCEMAP: 1
|
||||
|
||||
- name: Run Unit Tests (Electron)
|
||||
id: electron-unit-tests
|
||||
run: DISPLAY=:10 ./scripts/test.sh --runGlob "**/sql/**/*.test.js" # {{SQL CARBON EDIT}} Run only our tests with coverage. Disable for now since it's currently broken --coverage
|
||||
run: DISPLAY=:10 ./scripts/test.sh --runGlob "**/sql/**/*.test.js" --coverage
|
||||
|
||||
- name: Run Extension Unit Tests (Electron)
|
||||
id: electron-extension-unit-tests
|
||||
|
||||
2
.yarnrc
2
.yarnrc
@@ -1,3 +1,3 @@
|
||||
disturl "https://electronjs.org/headers"
|
||||
target "13.5.0"
|
||||
target "13.6.6"
|
||||
runtime "electron"
|
||||
|
||||
137
CHANGELOG.md
137
CHANGELOG.md
@@ -1,37 +1,10 @@
|
||||
# Change Log
|
||||
|
||||
## Version 1.34.0
|
||||
* Release date: December 15, 2021
|
||||
## Version 1.36.1
|
||||
* Release date: April 22, 2022
|
||||
* Release status: General Availability
|
||||
## What's new in this version
|
||||
* New Features:
|
||||
* Added “Currently restoring backup file” in the migration progress details page of Azure SQL Migration extension when backup files location is Azure Storage blob container
|
||||
* Enhancements to diagnostics in Azure SQL Migration extension
|
||||
* Support for project build with .NET 6 in SQL Database Projects extension
|
||||
* Publish to container in SQL Database Projects extension
|
||||
* Undo and redo support for notebook cell-level operations
|
||||
|
||||
* Extension Updates:
|
||||
* Azure SQL Migration
|
||||
* Langpacks
|
||||
* SQL Database Projects
|
||||
|
||||
* Bug Fixes:
|
||||
* Fix for multiple database migrations when using network share as backup files location in Azure SQL Migration extension
|
||||
* Fix for multiple database migrations when using blob storage containers as backup files location in Azure SQL Migration extension
|
||||
* Fix to pre-populate target database names in the migration wizard in Azure SQL Migration extension
|
||||
* Fix to column sorting in grids where the presence of null values could lead to unexpected results
|
||||
* Fix for Python upgrades when two or more notebooks were open
|
||||
|
||||
## Version 1.33.1
|
||||
* Release date: Nov 4, 2021
|
||||
* Release status: General Availability
|
||||
|
||||
## Hotfix release
|
||||
- Fix for [#16535 Unable to See Saved Connections in Restricted Mode](https://github.com/microsoft/azuredatastudio/issues/17535)
|
||||
- Fix for [#17579 Can't type in Notebook code cell after editing text cell](https://github.com/microsoft/azuredatastudio/issues/17579)
|
||||
|
||||
|
||||
- April Hotfix addressing these issues https://github.com/microsoft/azuredatastudio/milestone/88?closed=1.
|
||||
|
||||
| Platform |
|
||||
| --------------------------------------- |
|
||||
@@ -43,31 +16,107 @@
|
||||
| [Linux RPM][linux-rpm] |
|
||||
| [Linux DEB][linux-deb] |
|
||||
|
||||
[win-user]: https://go.microsoft.com/fwlink/?linkid=2176805
|
||||
[win-system]: https://go.microsoft.com/fwlink/?linkid=2175910
|
||||
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2176806
|
||||
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2176807
|
||||
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2176505
|
||||
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2176005
|
||||
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2176006
|
||||
[win-user]: https://go.microsoft.com/fwlink/?linkid=2193235
|
||||
[win-system]: https://go.microsoft.com/fwlink/?linkid=2193326
|
||||
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2193236
|
||||
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2192971
|
||||
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2193237
|
||||
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2193238
|
||||
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2193327
|
||||
|
||||
## Version 1.36.2
|
||||
* Release date: May 20, 2022
|
||||
* Release status: General Availability
|
||||
## What's new in this version
|
||||
- Fix connectivity issue with PBI data source
|
||||
- Fix query plan zoom and icon issues
|
||||
- Issues fixed in this release https://github.com/microsoft/azuredatastudio/milestone/89?closed=1
|
||||
|
||||
## Version 1.36.1
|
||||
* Release date: April 22, 2022
|
||||
* Release status: General Availability
|
||||
## What's new in this version
|
||||
* April Hotfix addressing these issues https://github.com/microsoft/azuredatastudio/milestone/88?closed=1.
|
||||
* Hotfix RCA - https://github.com/microsoft/azuredatastudio/wiki/ADS-April-2022-Hotfix-RCA
|
||||
|
||||
## Version 1.36.0
|
||||
* Release date: April 20, 2022
|
||||
* Release status: General Availability
|
||||
## What's new in this version
|
||||
- General Availability of the Azure SQL Migration Extension for ADS
|
||||
- Support for .NET Interactive Notebooks Extension
|
||||
- New Table Designer Features including support for System Versioned, Graph and Memory Optomized Tables
|
||||
- Query Plan Viewer Updates includign warning and parallelism icons, the option to disable tooltips and support for opening .sqlplan files
|
||||
- Improvements in SQL Projects and Schema Compare
|
||||
|
||||
## Version 1.35.1
|
||||
* Release date: March 17, 2022
|
||||
* Release status: General Availability
|
||||
## Hotfix release
|
||||
- Fix for [Excel number format #18615](https://github.com/microsoft/azuredatastudio/issues/18615)
|
||||
- Fix for [Geometry Data Type Returned as Unknown Charset in Results Grid #18630](https://github.com/microsoft/azuredatastudio/issues/18630)
|
||||
|
||||
## Version 1.35.0
|
||||
* Release date: February 24, 2022
|
||||
* Release status: General Availability
|
||||
## What's new in this version
|
||||
* New Features:
|
||||
* Table Designer - Added functionality for creation and management of tables for SQL Servers. Built using DacFx framework
|
||||
* Query Plan Viewer - Added functionality for users to view a graphic view of estimated and actual query plans without need for an extension
|
||||
* Azure Arc Extension - Updated the Data Controller deployment wizard and the SQL Managed Instance - Azure Arc deployment wizard to reflect the deployment experience in Azure Portal
|
||||
|
||||
* Bug Fixes:
|
||||
* Azure Arc Extension - SQL Managed Instance-Azure Arc is now fixed for both indirect connectivity mode and direct connectivity mode
|
||||
* Notebooks - Support for keyboard navigation between cells to minimize mouse clicking
|
||||
|
||||
## Version 1.34.0
|
||||
* Release date: December 15, 2021
|
||||
* Release status: General Availability
|
||||
## What's new in this version
|
||||
* New Features:
|
||||
* Added “Currently restoring backup file” in the migration progress details page of Azure SQL Migration extension when backup files location is Azure Storage blob container
|
||||
* Enhancements to diagnostics in Azure SQL Migration extension
|
||||
* Support for project build with .NET 6 in SQL Database Projects extension
|
||||
* Publish to container in SQL Database Projects extension
|
||||
* Undo and redo support for notebook cell-level operations
|
||||
|
||||
* Extension Updates:
|
||||
* Azure SQL Migration
|
||||
* Langpacks
|
||||
* SQL Database Projects
|
||||
|
||||
* Bug Fixes:
|
||||
* Fix for multiple database migrations when using network share as backup files location in Azure SQL Migration extension
|
||||
* Fix for multiple database migrations when using blob storage containers as backup files location in Azure SQL Migration extension
|
||||
* Fix to pre-populate target database names in the migration wizard in Azure SQL Migration extension
|
||||
* Fix to column sorting in grids where the presence of null values could lead to unexpected results
|
||||
* Fix for Python upgrades when two or more notebooks were open
|
||||
|
||||
## Version 1.33.1
|
||||
* Release date: Nov 4, 2021
|
||||
* Release status: General Availability
|
||||
|
||||
## Hotfix release
|
||||
- Fix for [#16535 Unable to See Saved Connections in Restricted Mode](https://github.com/microsoft/azuredatastudio/issues/17535)
|
||||
- Fix for [#17579 Can't type in Notebook code cell after editing text cell](https://github.com/microsoft/azuredatastudio/issues/17579)
|
||||
|
||||
## Version 1.33.0
|
||||
* Release date: October 27, 2021
|
||||
* Release status: General Availability
|
||||
## What's new in this version
|
||||
* New Notebook Features:
|
||||
* Notebook Views
|
||||
* Split cell support
|
||||
* Keyboard shortcuts for Markdown Toolbar Cells
|
||||
* Notebook Views
|
||||
* Split cell support
|
||||
* Keyboard shortcuts for Markdown Toolbar Cells
|
||||
* Ctrl/Cmd + B = Bold Text
|
||||
* Ctrl/Cmd + I = Italicize Text
|
||||
* Ctrl/Cmd + U = Underline Text
|
||||
* Ctrl/Cmd + Shift + K = Add Code Block
|
||||
* Ctrl/Cmd + Shift + H = Highlight Text
|
||||
* Book improvements
|
||||
* Book improvements
|
||||
* Add a new section
|
||||
* Drag and Drop
|
||||
|
||||
|
||||
* Extension Updates:
|
||||
* Import
|
||||
* Langpacks
|
||||
@@ -83,8 +132,8 @@
|
||||
* Release date: August 18, 2021
|
||||
* Release status: General Availability
|
||||
* Extension Updates:
|
||||
* Arc/Az CLI extensions - Azure Arc extension now uses Azure CLI instead of Azure Data CLI for deploying and interacting with Azure Arc
|
||||
instances
|
||||
* Arc/Az CLI extensions - Azure Arc extension now uses Azure CLI instead of Azure Data CLI for deploying and interacting with Azure Arc
|
||||
instances
|
||||
* Langpacks
|
||||
* SQL Database Projects
|
||||
* Azure Monitor
|
||||
|
||||
14
README.md
14
README.md
@@ -131,10 +131,10 @@ Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Licensed under the [Source EULA](LICENSE.txt).
|
||||
|
||||
[win-user]: https://go.microsoft.com/fwlink/?linkid=2183280
|
||||
[win-system]: https://go.microsoft.com/fwlink/?linkid=2183423
|
||||
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2183190
|
||||
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2183189
|
||||
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2183277
|
||||
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2183342
|
||||
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2183341
|
||||
[win-user]: https://go.microsoft.com/fwlink/?linkid=2193235
|
||||
[win-system]: https://go.microsoft.com/fwlink/?linkid=2193326
|
||||
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2193236
|
||||
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2192971
|
||||
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2193237
|
||||
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2193238
|
||||
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2193327
|
||||
|
||||
@@ -45,6 +45,7 @@ make-error: https://github.com/JsCommunity/make-error
|
||||
mark.js: https://github.com/julmot/mark.js
|
||||
minimist: https://github.com/substack/minimist
|
||||
moment: https://github.com/moment/moment
|
||||
mxgraph: https://github.com/jgraph/mxgraph
|
||||
native-keymap: https://github.com/Microsoft/node-native-keymap
|
||||
native-watchdog: https://github.com/Microsoft/node-native-watchdog
|
||||
ng2-charts: https://github.com/valor-software/ng2-charts
|
||||
@@ -1538,6 +1539,193 @@ OTHER DEALINGS IN THE SOFTWARE.
|
||||
=========================================
|
||||
END OF moment NOTICES AND INFORMATION
|
||||
|
||||
|
||||
%% mxgraph NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
(e) Neither the Work nor Derivative Works may be used or form any
|
||||
part of a larger work that integrates or is supposed to be
|
||||
integrated with a product or service owned or marketed by an
|
||||
Atlassian entity, including its successors and assignees in title.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
//SEIBERT/MEDIA GmbH, Wiesbaden, Germany is the exclusive licensee of
|
||||
JGraph for software products based on this codebase within the Atlassian
|
||||
ecosystem of products.
|
||||
=========================================
|
||||
END OF mxgraph NOTICES AND INFORMATION
|
||||
|
||||
%% native-keymap NOTICES AND INFORMATION BEGIN HERE
|
||||
=========================================
|
||||
Copyright (c) Microsoft Corporation
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
"Atomics": "readonly",
|
||||
"SharedArrayBuffer": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"rules": {
|
||||
}
|
||||
}
|
||||
2
build/actions/.gitignore
vendored
2
build/actions/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
*.js.map
|
||||
@@ -1,96 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export interface GitHub {
|
||||
query(query: Query): AsyncIterableIterator<GitHubIssue[]>
|
||||
|
||||
hasWriteAccess(user: User): Promise<boolean>
|
||||
|
||||
repoHasLabel(label: string): Promise<boolean>
|
||||
createLabel(label: string, color: string, description: string): Promise<void>
|
||||
deleteLabel(label: string): Promise<void>
|
||||
|
||||
readConfig(path: string): Promise<any>
|
||||
|
||||
createIssue(owner: string, repo: string, title: string, body: string): Promise<void>
|
||||
|
||||
releaseContainsCommit(release: string, commit: string): Promise<boolean>
|
||||
}
|
||||
|
||||
export interface GitHubIssue extends GitHub {
|
||||
getIssue(): Promise<Issue>
|
||||
|
||||
postComment(body: string): Promise<void>
|
||||
deleteComment(id: number): Promise<void>
|
||||
getComments(last?: boolean): AsyncIterableIterator<Comment[]>
|
||||
|
||||
closeIssue(): Promise<void>
|
||||
lockIssue(): Promise<void>
|
||||
|
||||
setMilestone(milestoneId: number): Promise<void>
|
||||
|
||||
addLabel(label: string): Promise<void>
|
||||
removeLabel(label: string): Promise<void>
|
||||
|
||||
addAssignee(assignee: string): Promise<void>
|
||||
|
||||
getClosingInfo(): Promise<{ hash: string | undefined; timestamp: number } | undefined>
|
||||
}
|
||||
|
||||
type SortVar =
|
||||
| 'comments'
|
||||
| 'reactions'
|
||||
| 'reactions-+1'
|
||||
| 'reactions--1'
|
||||
| 'reactions-smile'
|
||||
| 'reactions-thinking_face'
|
||||
| 'reactions-heart'
|
||||
| 'reactions-tada'
|
||||
| 'interactions'
|
||||
| 'created'
|
||||
| 'updated'
|
||||
type SortOrder = 'asc' | 'desc'
|
||||
export type Reactions = {
|
||||
'+1': number
|
||||
'-1': number
|
||||
laugh: number
|
||||
hooray: number
|
||||
confused: number
|
||||
heart: number
|
||||
rocket: number
|
||||
eyes: number
|
||||
}
|
||||
|
||||
export interface User {
|
||||
name: string
|
||||
isGitHubApp?: boolean
|
||||
}
|
||||
export interface Comment {
|
||||
author: User
|
||||
body: string
|
||||
id: number
|
||||
timestamp: number
|
||||
}
|
||||
export interface Issue {
|
||||
author: User
|
||||
body: string
|
||||
title: string
|
||||
labels: string[]
|
||||
open: boolean
|
||||
locked: boolean
|
||||
number: number
|
||||
numComments: number
|
||||
reactions: Reactions
|
||||
milestoneId: number | null
|
||||
assignee?: string
|
||||
createdAt: number
|
||||
updatedAt: number
|
||||
closedAt?: number
|
||||
}
|
||||
export interface Query {
|
||||
q: string
|
||||
sort?: SortVar
|
||||
order?: SortOrder
|
||||
}
|
||||
@@ -1,293 +0,0 @@
|
||||
"use strict";
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core_1 = require("@actions/core");
|
||||
const github_1 = require("@actions/github");
|
||||
const child_process_1 = require("child_process");
|
||||
const utils_1 = require("../utils/utils");
|
||||
class OctoKit {
|
||||
constructor(token, params, options = { readonly: false }) {
|
||||
this.token = token;
|
||||
this.params = params;
|
||||
this.options = options;
|
||||
// when in readonly mode, record labels just-created so at to not throw unneccesary errors
|
||||
this.mockLabels = new Set();
|
||||
this.writeAccessCache = {};
|
||||
this.octokit = new github_1.GitHub(token);
|
||||
}
|
||||
async *query(query) {
|
||||
const q = query.q + ` repo:${this.params.owner}/${this.params.repo}`;
|
||||
console.log(`Querying for ${q}:`);
|
||||
const options = this.octokit.search.issuesAndPullRequests.endpoint.merge({
|
||||
...query,
|
||||
q,
|
||||
per_page: 100,
|
||||
headers: { Accept: 'application/vnd.github.squirrel-girl-preview+json' },
|
||||
});
|
||||
let pageNum = 0;
|
||||
const timeout = async () => {
|
||||
if (pageNum < 2) {
|
||||
/* pass */
|
||||
}
|
||||
else if (pageNum < 4) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000));
|
||||
}
|
||||
else {
|
||||
await new Promise((resolve) => setTimeout(resolve, 30000));
|
||||
}
|
||||
};
|
||||
for await (const pageResponse of this.octokit.paginate.iterator(options)) {
|
||||
await timeout();
|
||||
await utils_1.logRateLimit(this.token);
|
||||
const page = pageResponse.data;
|
||||
console.log(`Page ${++pageNum}: ${page.map(({ number }) => number).join(' ')}`);
|
||||
yield page.map((issue) => new OctoKitIssue(this.token, this.params, this.octokitIssueToIssue(issue)));
|
||||
}
|
||||
}
|
||||
async createIssue(owner, repo, title, body) {
|
||||
core_1.debug(`Creating issue \`${title}\` on ${owner}/${repo}`);
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.create({ owner, repo, title, body });
|
||||
}
|
||||
octokitIssueToIssue(issue) {
|
||||
var _a, _b, _c, _d, _e, _f;
|
||||
return {
|
||||
author: { name: issue.user.login, isGitHubApp: issue.user.type === 'Bot' },
|
||||
body: issue.body,
|
||||
number: issue.number,
|
||||
title: issue.title,
|
||||
labels: issue.labels.map((label) => label.name),
|
||||
open: issue.state === 'open',
|
||||
locked: issue.locked,
|
||||
numComments: issue.comments,
|
||||
reactions: issue.reactions,
|
||||
assignee: (_b = (_a = issue.assignee) === null || _a === void 0 ? void 0 : _a.login) !== null && _b !== void 0 ? _b : (_d = (_c = issue.assignees) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.login,
|
||||
milestoneId: (_f = (_e = issue.milestone) === null || _e === void 0 ? void 0 : _e.number) !== null && _f !== void 0 ? _f : null,
|
||||
createdAt: +new Date(issue.created_at),
|
||||
updatedAt: +new Date(issue.updated_at),
|
||||
closedAt: issue.closed_at ? +new Date(issue.closed_at) : undefined,
|
||||
};
|
||||
}
|
||||
async hasWriteAccess(user) {
|
||||
if (user.name in this.writeAccessCache) {
|
||||
core_1.debug('Got permissions from cache for ' + user);
|
||||
return this.writeAccessCache[user.name];
|
||||
}
|
||||
core_1.debug('Fetching permissions for ' + user);
|
||||
const permissions = (await this.octokit.repos.getCollaboratorPermissionLevel({
|
||||
...this.params,
|
||||
username: user.name,
|
||||
})).data.permission;
|
||||
return (this.writeAccessCache[user.name] = permissions === 'admin' || permissions === 'write');
|
||||
}
|
||||
async repoHasLabel(name) {
|
||||
try {
|
||||
await this.octokit.issues.getLabel({ ...this.params, name });
|
||||
return true;
|
||||
}
|
||||
catch (err) {
|
||||
if (err.status === 404) {
|
||||
return this.options.readonly && this.mockLabels.has(name);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
async createLabel(name, color, description) {
|
||||
core_1.debug('Creating label ' + name);
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.createLabel({ ...this.params, color, description, name });
|
||||
else
|
||||
this.mockLabels.add(name);
|
||||
}
|
||||
async deleteLabel(name) {
|
||||
core_1.debug('Deleting label ' + name);
|
||||
try {
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.deleteLabel({ ...this.params, name });
|
||||
}
|
||||
catch (err) {
|
||||
if (err.status === 404) {
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
async readConfig(path) {
|
||||
core_1.debug('Reading config at ' + path);
|
||||
const repoPath = `.github/${path}.json`;
|
||||
const data = (await this.octokit.repos.getContents({ ...this.params, path: repoPath })).data;
|
||||
if ('type' in data && data.type === 'file') {
|
||||
if (data.encoding === 'base64' && data.content) {
|
||||
return JSON.parse(Buffer.from(data.content, 'base64').toString('utf-8'));
|
||||
}
|
||||
throw Error(`Could not read contents "${data.content}" in encoding "${data.encoding}"`);
|
||||
}
|
||||
throw Error('Found directory at config path when expecting file' + JSON.stringify(data));
|
||||
}
|
||||
async releaseContainsCommit(release, commit) {
|
||||
if (utils_1.getInput('commitReleasedDebuggingOverride')) {
|
||||
return true;
|
||||
}
|
||||
return new Promise((resolve, reject) => child_process_1.exec(`git -C ./repo merge-base --is-ancestor ${commit} ${release}`, (err) => !err || err.code === 1 ? resolve(!err) : reject(err)));
|
||||
}
|
||||
}
|
||||
exports.OctoKit = OctoKit;
|
||||
class OctoKitIssue extends OctoKit {
|
||||
constructor(token, params, issueData, options = { readonly: false }) {
|
||||
super(token, params, options);
|
||||
this.params = params;
|
||||
this.issueData = issueData;
|
||||
}
|
||||
async addAssignee(assignee) {
|
||||
core_1.debug('Adding assignee ' + assignee + ' to ' + this.issueData.number);
|
||||
if (!this.options.readonly) {
|
||||
await this.octokit.issues.addAssignees({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
assignees: [assignee],
|
||||
});
|
||||
}
|
||||
}
|
||||
async closeIssue() {
|
||||
core_1.debug('Closing issue ' + this.issueData.number);
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.update({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
state: 'closed',
|
||||
});
|
||||
}
|
||||
async lockIssue() {
|
||||
core_1.debug('Locking issue ' + this.issueData.number);
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.lock({ ...this.params, issue_number: this.issueData.number });
|
||||
}
|
||||
async getIssue() {
|
||||
if (isIssue(this.issueData)) {
|
||||
core_1.debug('Got issue data from query result ' + this.issueData.number);
|
||||
return this.issueData;
|
||||
}
|
||||
console.log('Fetching issue ' + this.issueData.number);
|
||||
const issue = (await this.octokit.issues.get({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
mediaType: { previews: ['squirrel-girl'] },
|
||||
})).data;
|
||||
return (this.issueData = this.octokitIssueToIssue(issue));
|
||||
}
|
||||
async postComment(body) {
|
||||
core_1.debug(`Posting comment ${body} on ${this.issueData.number}`);
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.createComment({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
body,
|
||||
});
|
||||
}
|
||||
async deleteComment(id) {
|
||||
core_1.debug(`Deleting comment ${id} on ${this.issueData.number}`);
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.deleteComment({
|
||||
owner: this.params.owner,
|
||||
repo: this.params.repo,
|
||||
comment_id: id,
|
||||
});
|
||||
}
|
||||
async setMilestone(milestoneId) {
|
||||
core_1.debug(`Setting milestone for ${this.issueData.number} to ${milestoneId}`);
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.update({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
milestone: milestoneId,
|
||||
});
|
||||
}
|
||||
async *getComments(last) {
|
||||
core_1.debug('Fetching comments for ' + this.issueData.number);
|
||||
const response = this.octokit.paginate.iterator(this.octokit.issues.listComments.endpoint.merge({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
per_page: 100,
|
||||
...(last ? { per_page: 1, page: (await this.getIssue()).numComments } : {}),
|
||||
}));
|
||||
for await (const page of response) {
|
||||
yield page.data.map((comment) => ({
|
||||
author: { name: comment.user.login, isGitHubApp: comment.user.type === 'Bot' },
|
||||
body: comment.body,
|
||||
id: comment.id,
|
||||
timestamp: +new Date(comment.created_at),
|
||||
}));
|
||||
}
|
||||
}
|
||||
async addLabel(name) {
|
||||
core_1.debug(`Adding label ${name} to ${this.issueData.number}`);
|
||||
if (!(await this.repoHasLabel(name))) {
|
||||
throw Error(`Action could not execute becuase label ${name} is not defined.`);
|
||||
}
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.addLabels({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
labels: [name],
|
||||
});
|
||||
}
|
||||
async removeLabel(name) {
|
||||
core_1.debug(`Removing label ${name} from ${this.issueData.number}`);
|
||||
try {
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.removeLabel({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
name,
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
if (err.status === 404) {
|
||||
console.log(`Label ${name} not found on issue`);
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
async getClosingInfo() {
|
||||
var _a;
|
||||
if ((await this.getIssue()).open) {
|
||||
return;
|
||||
}
|
||||
const options = this.octokit.issues.listEventsForTimeline.endpoint.merge({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
});
|
||||
let closingCommit;
|
||||
for await (const event of this.octokit.paginate.iterator(options)) {
|
||||
const timelineEvents = event.data;
|
||||
for (const timelineEvent of timelineEvents) {
|
||||
if (timelineEvent.event === 'closed') {
|
||||
closingCommit = {
|
||||
hash: (_a = timelineEvent.commit_id) !== null && _a !== void 0 ? _a : undefined,
|
||||
timestamp: +new Date(timelineEvent.created_at),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(`Got ${closingCommit} as closing commit of ${this.issueData.number}`);
|
||||
return closingCommit;
|
||||
}
|
||||
}
|
||||
exports.OctoKitIssue = OctoKitIssue;
|
||||
function isIssue(object) {
|
||||
const isIssue = 'author' in object &&
|
||||
'body' in object &&
|
||||
'title' in object &&
|
||||
'labels' in object &&
|
||||
'open' in object &&
|
||||
'locked' in object &&
|
||||
'number' in object &&
|
||||
'numComments' in object &&
|
||||
'reactions' in object &&
|
||||
'milestoneId' in object;
|
||||
return isIssue;
|
||||
}
|
||||
@@ -1,336 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { debug } from '@actions/core'
|
||||
import { GitHub as GitHubAPI } from '@actions/github'
|
||||
import { Octokit } from '@octokit/rest'
|
||||
import { exec } from 'child_process'
|
||||
import { getInput, logRateLimit } from '../utils/utils'
|
||||
import { Comment, GitHub, GitHubIssue, Issue, Query, User } from './api'
|
||||
|
||||
export class OctoKit implements GitHub {
|
||||
protected octokit: GitHubAPI
|
||||
// when in readonly mode, record labels just-created so at to not throw unneccesary errors
|
||||
protected mockLabels: Set<string> = new Set()
|
||||
|
||||
constructor(
|
||||
private token: string,
|
||||
protected params: { repo: string; owner: string },
|
||||
protected options: { readonly: boolean } = { readonly: false },
|
||||
) {
|
||||
this.octokit = new GitHubAPI(token)
|
||||
}
|
||||
|
||||
async *query(query: Query): AsyncIterableIterator<GitHubIssue[]> {
|
||||
const q = query.q + ` repo:${this.params.owner}/${this.params.repo}`
|
||||
console.log(`Querying for ${q}:`)
|
||||
|
||||
const options = this.octokit.search.issuesAndPullRequests.endpoint.merge({
|
||||
...query,
|
||||
q,
|
||||
per_page: 100,
|
||||
headers: { Accept: 'application/vnd.github.squirrel-girl-preview+json' },
|
||||
})
|
||||
|
||||
let pageNum = 0
|
||||
|
||||
const timeout = async () => {
|
||||
if (pageNum < 2) {
|
||||
/* pass */
|
||||
} else if (pageNum < 4) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000))
|
||||
} else {
|
||||
await new Promise((resolve) => setTimeout(resolve, 30000))
|
||||
}
|
||||
}
|
||||
|
||||
for await (const pageResponse of this.octokit.paginate.iterator(options)) {
|
||||
await timeout()
|
||||
await logRateLimit(this.token)
|
||||
const page: Array<Octokit.SearchIssuesAndPullRequestsResponseItemsItem> = pageResponse.data
|
||||
console.log(`Page ${++pageNum}: ${page.map(({ number }) => number).join(' ')}`)
|
||||
yield page.map(
|
||||
(issue) => new OctoKitIssue(this.token, this.params, this.octokitIssueToIssue(issue)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async createIssue(owner: string, repo: string, title: string, body: string): Promise<void> {
|
||||
debug(`Creating issue \`${title}\` on ${owner}/${repo}`)
|
||||
if (!this.options.readonly) await this.octokit.issues.create({ owner, repo, title, body })
|
||||
}
|
||||
|
||||
protected octokitIssueToIssue(
|
||||
issue: Octokit.IssuesGetResponse | Octokit.SearchIssuesAndPullRequestsResponseItemsItem,
|
||||
): Issue {
|
||||
return {
|
||||
author: { name: issue.user.login, isGitHubApp: issue.user.type === 'Bot' },
|
||||
body: issue.body,
|
||||
number: issue.number,
|
||||
title: issue.title,
|
||||
labels: (issue.labels as Octokit.IssuesGetLabelResponse[]).map((label) => label.name),
|
||||
open: issue.state === 'open',
|
||||
locked: (issue as any).locked,
|
||||
numComments: issue.comments,
|
||||
reactions: (issue as any).reactions,
|
||||
assignee: issue.assignee?.login ?? (issue as any).assignees?.[0]?.login,
|
||||
milestoneId: issue.milestone?.number ?? null,
|
||||
createdAt: +new Date(issue.created_at),
|
||||
updatedAt: +new Date(issue.updated_at),
|
||||
closedAt: issue.closed_at ? +new Date((issue.closed_at as unknown) as string) : undefined,
|
||||
}
|
||||
}
|
||||
|
||||
private writeAccessCache: Record<string, boolean> = {}
|
||||
async hasWriteAccess(user: User): Promise<boolean> {
|
||||
if (user.name in this.writeAccessCache) {
|
||||
debug('Got permissions from cache for ' + user)
|
||||
return this.writeAccessCache[user.name]
|
||||
}
|
||||
debug('Fetching permissions for ' + user)
|
||||
const permissions = (
|
||||
await this.octokit.repos.getCollaboratorPermissionLevel({
|
||||
...this.params,
|
||||
username: user.name,
|
||||
})
|
||||
).data.permission
|
||||
return (this.writeAccessCache[user.name] = permissions === 'admin' || permissions === 'write')
|
||||
}
|
||||
|
||||
async repoHasLabel(name: string): Promise<boolean> {
|
||||
try {
|
||||
await this.octokit.issues.getLabel({ ...this.params, name })
|
||||
return true
|
||||
} catch (err) {
|
||||
if (err.status === 404) {
|
||||
return this.options.readonly && this.mockLabels.has(name)
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async createLabel(name: string, color: string, description: string): Promise<void> {
|
||||
debug('Creating label ' + name)
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.createLabel({ ...this.params, color, description, name })
|
||||
else this.mockLabels.add(name)
|
||||
}
|
||||
|
||||
async deleteLabel(name: string): Promise<void> {
|
||||
debug('Deleting label ' + name)
|
||||
try {
|
||||
if (!this.options.readonly) await this.octokit.issues.deleteLabel({ ...this.params, name })
|
||||
} catch (err) {
|
||||
if (err.status === 404) {
|
||||
return
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async readConfig(path: string): Promise<any> {
|
||||
debug('Reading config at ' + path)
|
||||
const repoPath = `.github/${path}.json`
|
||||
const data = (await this.octokit.repos.getContents({ ...this.params, path: repoPath })).data
|
||||
|
||||
if ('type' in data && data.type === 'file') {
|
||||
if (data.encoding === 'base64' && data.content) {
|
||||
return JSON.parse(Buffer.from(data.content, 'base64').toString('utf-8'))
|
||||
}
|
||||
throw Error(`Could not read contents "${data.content}" in encoding "${data.encoding}"`)
|
||||
}
|
||||
throw Error('Found directory at config path when expecting file' + JSON.stringify(data))
|
||||
}
|
||||
|
||||
async releaseContainsCommit(release: string, commit: string): Promise<boolean> {
|
||||
if (getInput('commitReleasedDebuggingOverride')) {
|
||||
return true
|
||||
}
|
||||
return new Promise((resolve, reject) =>
|
||||
exec(`git -C ./repo merge-base --is-ancestor ${commit} ${release}`, (err) =>
|
||||
!err || err.code === 1 ? resolve(!err) : reject(err),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class OctoKitIssue extends OctoKit implements GitHubIssue {
|
||||
constructor(
|
||||
token: string,
|
||||
protected params: { repo: string; owner: string },
|
||||
private issueData: { number: number } | Issue,
|
||||
options: { readonly: boolean } = { readonly: false },
|
||||
) {
|
||||
super(token, params, options)
|
||||
}
|
||||
|
||||
async addAssignee(assignee: string): Promise<void> {
|
||||
debug('Adding assignee ' + assignee + ' to ' + this.issueData.number)
|
||||
if (!this.options.readonly) {
|
||||
await this.octokit.issues.addAssignees({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
assignees: [assignee],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async closeIssue(): Promise<void> {
|
||||
debug('Closing issue ' + this.issueData.number)
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.update({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
state: 'closed',
|
||||
})
|
||||
}
|
||||
|
||||
async lockIssue(): Promise<void> {
|
||||
debug('Locking issue ' + this.issueData.number)
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.lock({ ...this.params, issue_number: this.issueData.number })
|
||||
}
|
||||
|
||||
async getIssue(): Promise<Issue> {
|
||||
if (isIssue(this.issueData)) {
|
||||
debug('Got issue data from query result ' + this.issueData.number)
|
||||
return this.issueData
|
||||
}
|
||||
|
||||
console.log('Fetching issue ' + this.issueData.number)
|
||||
const issue = (
|
||||
await this.octokit.issues.get({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
mediaType: { previews: ['squirrel-girl'] },
|
||||
})
|
||||
).data
|
||||
return (this.issueData = this.octokitIssueToIssue(issue))
|
||||
}
|
||||
|
||||
async postComment(body: string): Promise<void> {
|
||||
debug(`Posting comment ${body} on ${this.issueData.number}`)
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.createComment({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
body,
|
||||
})
|
||||
}
|
||||
|
||||
async deleteComment(id: number): Promise<void> {
|
||||
debug(`Deleting comment ${id} on ${this.issueData.number}`)
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.deleteComment({
|
||||
owner: this.params.owner,
|
||||
repo: this.params.repo,
|
||||
comment_id: id,
|
||||
})
|
||||
}
|
||||
|
||||
async setMilestone(milestoneId: number) {
|
||||
debug(`Setting milestone for ${this.issueData.number} to ${milestoneId}`)
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.update({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
milestone: milestoneId,
|
||||
})
|
||||
}
|
||||
|
||||
async *getComments(last?: boolean): AsyncIterableIterator<Comment[]> {
|
||||
debug('Fetching comments for ' + this.issueData.number)
|
||||
|
||||
const response = this.octokit.paginate.iterator(
|
||||
this.octokit.issues.listComments.endpoint.merge({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
per_page: 100,
|
||||
...(last ? { per_page: 1, page: (await this.getIssue()).numComments } : {}),
|
||||
}),
|
||||
)
|
||||
|
||||
for await (const page of response) {
|
||||
yield (page.data as Octokit.IssuesListCommentsResponseItem[]).map((comment) => ({
|
||||
author: { name: comment.user.login, isGitHubApp: comment.user.type === 'Bot' },
|
||||
body: comment.body,
|
||||
id: comment.id,
|
||||
timestamp: +new Date(comment.created_at),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
async addLabel(name: string): Promise<void> {
|
||||
debug(`Adding label ${name} to ${this.issueData.number}`)
|
||||
if (!(await this.repoHasLabel(name))) {
|
||||
throw Error(`Action could not execute becuase label ${name} is not defined.`)
|
||||
}
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.addLabels({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
labels: [name],
|
||||
})
|
||||
}
|
||||
|
||||
async removeLabel(name: string): Promise<void> {
|
||||
debug(`Removing label ${name} from ${this.issueData.number}`)
|
||||
try {
|
||||
if (!this.options.readonly)
|
||||
await this.octokit.issues.removeLabel({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
name,
|
||||
})
|
||||
} catch (err) {
|
||||
if (err.status === 404) {
|
||||
console.log(`Label ${name} not found on issue`)
|
||||
return
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async getClosingInfo(): Promise<{ hash: string | undefined; timestamp: number } | undefined> {
|
||||
if ((await this.getIssue()).open) {
|
||||
return
|
||||
}
|
||||
|
||||
const options = this.octokit.issues.listEventsForTimeline.endpoint.merge({
|
||||
...this.params,
|
||||
issue_number: this.issueData.number,
|
||||
})
|
||||
let closingCommit: { hash: string | undefined; timestamp: number } | undefined
|
||||
for await (const event of this.octokit.paginate.iterator(options)) {
|
||||
const timelineEvents = event.data as Octokit.IssuesListEventsForTimelineResponseItem[]
|
||||
for (const timelineEvent of timelineEvents) {
|
||||
if (timelineEvent.event === 'closed') {
|
||||
closingCommit = {
|
||||
hash: timelineEvent.commit_id ?? undefined,
|
||||
timestamp: +new Date(timelineEvent.created_at),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(`Got ${closingCommit} as closing commit of ${this.issueData.number}`)
|
||||
return closingCommit
|
||||
}
|
||||
}
|
||||
|
||||
function isIssue(object: any): object is Issue {
|
||||
const isIssue =
|
||||
'author' in object &&
|
||||
'body' in object &&
|
||||
'title' in object &&
|
||||
'labels' in object &&
|
||||
'open' in object &&
|
||||
'locked' in object &&
|
||||
'number' in object &&
|
||||
'numComments' in object &&
|
||||
'reactions' in object &&
|
||||
'milestoneId' in object
|
||||
|
||||
return isIssue
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
"use strict";
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class Testbed {
|
||||
constructor(config) {
|
||||
var _a, _b, _c, _d, _e;
|
||||
this.config = {
|
||||
globalLabels: (_a = config === null || config === void 0 ? void 0 : config.globalLabels) !== null && _a !== void 0 ? _a : [],
|
||||
configs: (_b = config === null || config === void 0 ? void 0 : config.configs) !== null && _b !== void 0 ? _b : {},
|
||||
writers: (_c = config === null || config === void 0 ? void 0 : config.writers) !== null && _c !== void 0 ? _c : [],
|
||||
releasedCommits: (_d = config === null || config === void 0 ? void 0 : config.releasedCommits) !== null && _d !== void 0 ? _d : [],
|
||||
queryRunner: (_e = config === null || config === void 0 ? void 0 : config.queryRunner) !== null && _e !== void 0 ? _e : async function* () {
|
||||
yield [];
|
||||
},
|
||||
};
|
||||
}
|
||||
async *query(query) {
|
||||
for await (const page of this.config.queryRunner(query)) {
|
||||
yield page.map((issue) => issue instanceof TestbedIssue ? issue : new TestbedIssue(this.config, issue));
|
||||
}
|
||||
}
|
||||
async createIssue(_owner, _repo, _title, _body) {
|
||||
// pass...
|
||||
}
|
||||
async readConfig(path) {
|
||||
return JSON.parse(JSON.stringify(this.config.configs[path]));
|
||||
}
|
||||
async hasWriteAccess(user) {
|
||||
return this.config.writers.includes(user.name);
|
||||
}
|
||||
async repoHasLabel(label) {
|
||||
return this.config.globalLabels.includes(label);
|
||||
}
|
||||
async createLabel(label, _color, _description) {
|
||||
this.config.globalLabels.push(label);
|
||||
}
|
||||
async deleteLabel(labelToDelete) {
|
||||
this.config.globalLabels = this.config.globalLabels.filter((label) => label !== labelToDelete);
|
||||
}
|
||||
async releaseContainsCommit(_release, commit) {
|
||||
return this.config.releasedCommits.includes(commit);
|
||||
}
|
||||
}
|
||||
exports.Testbed = Testbed;
|
||||
class TestbedIssue extends Testbed {
|
||||
constructor(globalConfig, issueConfig) {
|
||||
var _a, _b, _c;
|
||||
super(globalConfig);
|
||||
issueConfig = issueConfig !== null && issueConfig !== void 0 ? issueConfig : {};
|
||||
issueConfig.comments = (_a = issueConfig === null || issueConfig === void 0 ? void 0 : issueConfig.comments) !== null && _a !== void 0 ? _a : [];
|
||||
issueConfig.labels = (_b = issueConfig === null || issueConfig === void 0 ? void 0 : issueConfig.labels) !== null && _b !== void 0 ? _b : [];
|
||||
issueConfig.issue = {
|
||||
author: { name: 'JacksonKearl' },
|
||||
body: 'issue body',
|
||||
locked: false,
|
||||
numComments: ((_c = issueConfig === null || issueConfig === void 0 ? void 0 : issueConfig.comments) === null || _c === void 0 ? void 0 : _c.length) || 0,
|
||||
number: 1,
|
||||
open: true,
|
||||
title: 'issue title',
|
||||
assignee: undefined,
|
||||
reactions: {
|
||||
'+1': 0,
|
||||
'-1': 0,
|
||||
confused: 0,
|
||||
eyes: 0,
|
||||
heart: 0,
|
||||
hooray: 0,
|
||||
laugh: 0,
|
||||
rocket: 0,
|
||||
},
|
||||
closedAt: undefined,
|
||||
createdAt: +new Date(),
|
||||
updatedAt: +new Date(),
|
||||
...issueConfig.issue,
|
||||
};
|
||||
this.issueConfig = issueConfig;
|
||||
}
|
||||
async addAssignee(assignee) {
|
||||
this.issueConfig.issue.assignee = assignee;
|
||||
}
|
||||
async setMilestone(milestoneId) {
|
||||
this.issueConfig.issue.milestoneId = milestoneId;
|
||||
}
|
||||
async getIssue() {
|
||||
const labels = [...this.issueConfig.labels];
|
||||
return { ...this.issueConfig.issue, labels };
|
||||
}
|
||||
async postComment(body, author) {
|
||||
this.issueConfig.comments.push({
|
||||
author: { name: author !== null && author !== void 0 ? author : 'bot' },
|
||||
body,
|
||||
id: Math.random(),
|
||||
timestamp: +new Date(),
|
||||
});
|
||||
}
|
||||
async deleteComment(id) {
|
||||
this.issueConfig.comments = this.issueConfig.comments.filter((comment) => comment.id !== id);
|
||||
}
|
||||
async *getComments(last) {
|
||||
yield last
|
||||
? [this.issueConfig.comments[this.issueConfig.comments.length - 1]]
|
||||
: this.issueConfig.comments;
|
||||
}
|
||||
async addLabel(label) {
|
||||
this.issueConfig.labels.push(label);
|
||||
}
|
||||
async removeLabel(labelToDelete) {
|
||||
this.issueConfig.labels = this.issueConfig.labels.filter((label) => label !== labelToDelete);
|
||||
}
|
||||
async closeIssue() {
|
||||
this.issueConfig.issue.open = false;
|
||||
}
|
||||
async lockIssue() {
|
||||
this.issueConfig.issue.locked = true;
|
||||
}
|
||||
async getClosingInfo() {
|
||||
return this.issueConfig.closingCommit;
|
||||
}
|
||||
}
|
||||
exports.TestbedIssue = TestbedIssue;
|
||||
@@ -1,170 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Comment, GitHub, GitHubIssue, Issue, Query, User } from './api'
|
||||
|
||||
type TestbedConfig = {
|
||||
globalLabels: string[]
|
||||
configs: Record<string, any>
|
||||
writers: string[]
|
||||
releasedCommits: string[]
|
||||
queryRunner: (query: Query) => AsyncIterableIterator<(TestbedIssueConstructorArgs | TestbedIssue)[]>
|
||||
}
|
||||
|
||||
export type TestbedConstructorArgs = Partial<TestbedConfig>
|
||||
|
||||
export class Testbed implements GitHub {
|
||||
public config: TestbedConfig
|
||||
|
||||
constructor(config?: TestbedConstructorArgs) {
|
||||
this.config = {
|
||||
globalLabels: config?.globalLabels ?? [],
|
||||
configs: config?.configs ?? {},
|
||||
writers: config?.writers ?? [],
|
||||
releasedCommits: config?.releasedCommits ?? [],
|
||||
queryRunner:
|
||||
config?.queryRunner ??
|
||||
async function* () {
|
||||
yield []
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async *query(query: Query): AsyncIterableIterator<GitHubIssue[]> {
|
||||
for await (const page of this.config.queryRunner(query)) {
|
||||
yield page.map((issue) =>
|
||||
issue instanceof TestbedIssue ? issue : new TestbedIssue(this.config, issue),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async createIssue(_owner: string, _repo: string, _title: string, _body: string): Promise<void> {
|
||||
// pass...
|
||||
}
|
||||
|
||||
async readConfig(path: string): Promise<any> {
|
||||
return JSON.parse(JSON.stringify(this.config.configs[path]))
|
||||
}
|
||||
|
||||
async hasWriteAccess(user: User): Promise<boolean> {
|
||||
return this.config.writers.includes(user.name)
|
||||
}
|
||||
|
||||
async repoHasLabel(label: string): Promise<boolean> {
|
||||
return this.config.globalLabels.includes(label)
|
||||
}
|
||||
|
||||
async createLabel(label: string, _color: string, _description: string): Promise<void> {
|
||||
this.config.globalLabels.push(label)
|
||||
}
|
||||
|
||||
async deleteLabel(labelToDelete: string): Promise<void> {
|
||||
this.config.globalLabels = this.config.globalLabels.filter((label) => label !== labelToDelete)
|
||||
}
|
||||
|
||||
async releaseContainsCommit(_release: string, commit: string): Promise<boolean> {
|
||||
return this.config.releasedCommits.includes(commit)
|
||||
}
|
||||
}
|
||||
|
||||
type TestbedIssueConfig = {
|
||||
issue: Omit<Issue, 'labels'>
|
||||
comments: Comment[]
|
||||
labels: string[]
|
||||
closingCommit: { hash: string | undefined; timestamp: number } | undefined
|
||||
}
|
||||
|
||||
export type TestbedIssueConstructorArgs = Partial<Omit<TestbedIssueConfig, 'issue'>> & {
|
||||
issue?: Partial<Omit<Issue, 'labels'>>
|
||||
}
|
||||
|
||||
export class TestbedIssue extends Testbed implements GitHubIssue {
|
||||
public issueConfig: TestbedIssueConfig
|
||||
|
||||
constructor(globalConfig?: TestbedConstructorArgs, issueConfig?: TestbedIssueConstructorArgs) {
|
||||
super(globalConfig)
|
||||
issueConfig = issueConfig ?? {}
|
||||
issueConfig.comments = issueConfig?.comments ?? []
|
||||
issueConfig.labels = issueConfig?.labels ?? []
|
||||
issueConfig.issue = {
|
||||
author: { name: 'JacksonKearl' },
|
||||
body: 'issue body',
|
||||
locked: false,
|
||||
numComments: issueConfig?.comments?.length || 0,
|
||||
number: 1,
|
||||
open: true,
|
||||
title: 'issue title',
|
||||
assignee: undefined,
|
||||
reactions: {
|
||||
'+1': 0,
|
||||
'-1': 0,
|
||||
confused: 0,
|
||||
eyes: 0,
|
||||
heart: 0,
|
||||
hooray: 0,
|
||||
laugh: 0,
|
||||
rocket: 0,
|
||||
},
|
||||
closedAt: undefined,
|
||||
createdAt: +new Date(),
|
||||
updatedAt: +new Date(),
|
||||
...issueConfig.issue,
|
||||
}
|
||||
|
||||
this.issueConfig = issueConfig as TestbedIssueConfig
|
||||
}
|
||||
|
||||
async addAssignee(assignee: string): Promise<void> {
|
||||
this.issueConfig.issue.assignee = assignee
|
||||
}
|
||||
|
||||
async setMilestone(milestoneId: number): Promise<void> {
|
||||
this.issueConfig.issue.milestoneId = milestoneId
|
||||
}
|
||||
|
||||
async getIssue(): Promise<Issue> {
|
||||
const labels = [...this.issueConfig.labels]
|
||||
return { ...this.issueConfig.issue, labels }
|
||||
}
|
||||
|
||||
async postComment(body: string, author?: string): Promise<void> {
|
||||
this.issueConfig.comments.push({
|
||||
author: { name: author ?? 'bot' },
|
||||
body,
|
||||
id: Math.random(),
|
||||
timestamp: +new Date(),
|
||||
})
|
||||
}
|
||||
|
||||
async deleteComment(id: number): Promise<void> {
|
||||
this.issueConfig.comments = this.issueConfig.comments.filter((comment) => comment.id !== id)
|
||||
}
|
||||
|
||||
async *getComments(last?: boolean): AsyncIterableIterator<Comment[]> {
|
||||
yield last
|
||||
? [this.issueConfig.comments[this.issueConfig.comments.length - 1]]
|
||||
: this.issueConfig.comments
|
||||
}
|
||||
|
||||
async addLabel(label: string): Promise<void> {
|
||||
this.issueConfig.labels.push(label)
|
||||
}
|
||||
|
||||
async removeLabel(labelToDelete: string): Promise<void> {
|
||||
this.issueConfig.labels = this.issueConfig.labels.filter((label) => label !== labelToDelete)
|
||||
}
|
||||
|
||||
async closeIssue(): Promise<void> {
|
||||
this.issueConfig.issue.open = false
|
||||
}
|
||||
|
||||
async lockIssue(): Promise<void> {
|
||||
this.issueConfig.issue.locked = true
|
||||
}
|
||||
|
||||
async getClosingInfo(): Promise<{ hash: string | undefined; timestamp: number } | undefined> {
|
||||
return this.issueConfig.closingCommit
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
name: 'PR Labeler'
|
||||
description: 'Automatically add a Label to a PR'
|
||||
inputs:
|
||||
token:
|
||||
description: GitHub token with issue, comment, and label read/write permissions
|
||||
default: ${{ github.token }}
|
||||
label:
|
||||
description: Github label to add to the PR
|
||||
required: true
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'index.js'
|
||||
@@ -1,22 +0,0 @@
|
||||
"use strict";
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core = require("@actions/core");
|
||||
const github_1 = require("@actions/github");
|
||||
const octokit_1 = require("../api/octokit");
|
||||
const utils_1 = require("../utils/utils");
|
||||
const token = utils_1.getRequiredInput('token');
|
||||
const label = utils_1.getRequiredInput('label');
|
||||
async function main() {
|
||||
const pr = new octokit_1.OctoKitIssue(token, github_1.context.repo, { number: github_1.context.issue.number });
|
||||
pr.addLabel(label);
|
||||
}
|
||||
main()
|
||||
.then(() => utils_1.logRateLimit(token))
|
||||
.catch(async (error) => {
|
||||
core.setFailed(error.message);
|
||||
await utils_1.logErrorToIssue(error.message, true, token);
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as core from '@actions/core'
|
||||
import { context } from '@actions/github'
|
||||
import { OctoKitIssue } from '../api/octokit'
|
||||
import { getRequiredInput, logErrorToIssue, logRateLimit } from '../utils/utils'
|
||||
|
||||
const token = getRequiredInput('token');
|
||||
const label = getRequiredInput('label');
|
||||
|
||||
async function main() {
|
||||
|
||||
const pr = new OctoKitIssue(token, context.repo, { number: context.issue.number });
|
||||
|
||||
pr.addLabel(label);
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => logRateLimit(token))
|
||||
.catch(async (error) => {
|
||||
core.setFailed(error.message)
|
||||
await logErrorToIssue(error.message, true, token)
|
||||
})
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"name": "github-actions",
|
||||
"version": "1.0.0",
|
||||
"description": "GitHub Actions",
|
||||
"scripts": {
|
||||
"test": "mocha -r ts-node/register **/*.test.ts",
|
||||
"build": "tsc -p ./tsconfig.json",
|
||||
"lint": "eslint -c .eslintrc --fix --ext .ts .",
|
||||
"watch-typecheck": "tsc --watch"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/microsoft/azuredatastudio.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.6",
|
||||
"@actions/github": "^2.1.1",
|
||||
"axios": "^0.21.4",
|
||||
"ts-node": "^8.6.2",
|
||||
"typescript": "^3.8.3"
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2019",
|
||||
"strict": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"removeComments": false,
|
||||
"resolveJsonModule": true,
|
||||
"lib": [
|
||||
"es2020"
|
||||
],
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
"use strict";
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const core = require("@actions/core");
|
||||
const github_1 = require("@actions/github");
|
||||
const axios_1 = require("axios");
|
||||
const octokit_1 = require("../api/octokit");
|
||||
exports.getInput = (name) => core.getInput(name) || undefined;
|
||||
exports.getRequiredInput = (name) => core.getInput(name, { required: true });
|
||||
exports.normalizeIssue = (issue) => {
|
||||
const { body, title } = issue;
|
||||
const isBug = body.includes('bug_report_template') || /Issue Type:.*Bug.*/.test(body);
|
||||
const isFeatureRequest = body.includes('feature_request_template') || /Issue Type:.*Feature Request.*/.test(body);
|
||||
const cleanse = (str) => str
|
||||
.toLowerCase()
|
||||
.replace(/<!--.*?-->/gu, '')
|
||||
.replace(/.* version: .*/gu, '')
|
||||
.replace(/issue type: .*/gu, '')
|
||||
.replace(/<details>(.|\s)*?<\/details>/gu, '')
|
||||
.replace(/vs ?code/gu, '')
|
||||
.replace(/we have written.*please paste./gu, '')
|
||||
.replace(/steps to reproduce:/gu, '')
|
||||
.replace(/does this issue occur when all extensions are disabled.*/gu, '')
|
||||
.replace(/```(.|\s)*?```/gu, '')
|
||||
.replace(/!?\[.*?\]\(.*?\)/gu, '')
|
||||
.replace(/\s+/gu, ' ');
|
||||
return {
|
||||
body: cleanse(body),
|
||||
title: cleanse(title),
|
||||
issueType: isBug ? 'bug' : isFeatureRequest ? 'feature_request' : 'unknown',
|
||||
};
|
||||
};
|
||||
exports.loadLatestRelease = async (quality) => (await axios_1.default.get(`https://vscode-update.azurewebsites.net/api/update/darwin/${quality}/latest`)).data;
|
||||
exports.daysAgoToTimestamp = (days) => +new Date(Date.now() - days * 24 * 60 * 60 * 1000);
|
||||
exports.daysAgoToHumanReadbleDate = (days) => new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().replace(/\.\d{3}\w$/, '');
|
||||
exports.logRateLimit = async (token) => {
|
||||
const usageData = (await new github_1.GitHub(token).rateLimit.get()).data.resources;
|
||||
['core', 'graphql', 'search'].forEach(async (category) => {
|
||||
const usage = 1 - usageData[category].remaining / usageData[category].limit;
|
||||
const message = `Usage at ${usage} for ${category}`;
|
||||
if (usage > 0) {
|
||||
console.log(message);
|
||||
}
|
||||
if (usage > 0.5) {
|
||||
await exports.logErrorToIssue(message, false, token);
|
||||
}
|
||||
});
|
||||
};
|
||||
exports.logErrorToIssue = async (message, ping, token) => {
|
||||
// Attempt to wait out abuse detection timeout if present
|
||||
await new Promise((resolve) => setTimeout(resolve, 10000));
|
||||
const dest = github_1.context.repo.repo === 'vscode-internalbacklog'
|
||||
? { repo: 'vscode-internalbacklog', issue: 974 }
|
||||
: { repo: 'vscode', issue: 93814 };
|
||||
return new octokit_1.OctoKitIssue(token, { owner: 'Microsoft', repo: dest.repo }, { number: dest.issue })
|
||||
.postComment(`
|
||||
Workflow: ${github_1.context.workflow}
|
||||
|
||||
Error: ${message}
|
||||
|
||||
Issue: ${ping ? `${github_1.context.repo.owner}/${github_1.context.repo.repo}#` : ''}${github_1.context.issue.number}
|
||||
|
||||
Repo: ${github_1.context.repo.owner}/${github_1.context.repo.repo}
|
||||
|
||||
<!-- Context:
|
||||
${JSON.stringify(github_1.context, null, 2).replace(/<!--/gu, '<@--').replace(/-->/gu, '--@>')}
|
||||
-->
|
||||
`);
|
||||
};
|
||||
@@ -1,95 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as core from '@actions/core'
|
||||
import { context, GitHub } from '@actions/github'
|
||||
import axios from 'axios'
|
||||
import { OctoKitIssue } from '../api/octokit'
|
||||
import { Issue } from '../api/api'
|
||||
|
||||
export const getInput = (name: string) => core.getInput(name) || undefined
|
||||
export const getRequiredInput = (name: string) => core.getInput(name, { required: true })
|
||||
|
||||
export const normalizeIssue = (
|
||||
issue: Issue,
|
||||
): { body: string; title: string; issueType: 'bug' | 'feature_request' | 'unknown' } => {
|
||||
const { body, title } = issue
|
||||
|
||||
const isBug = body.includes('bug_report_template') || /Issue Type:.*Bug.*/.test(body)
|
||||
const isFeatureRequest =
|
||||
body.includes('feature_request_template') || /Issue Type:.*Feature Request.*/.test(body)
|
||||
|
||||
const cleanse = (str: string) =>
|
||||
str
|
||||
.toLowerCase()
|
||||
.replace(/<!--.*?-->/gu, '')
|
||||
.replace(/.* version: .*/gu, '')
|
||||
.replace(/issue type: .*/gu, '')
|
||||
.replace(/<details>(.|\s)*?<\/details>/gu, '')
|
||||
.replace(/vs ?code/gu, '')
|
||||
.replace(/we have written.*please paste./gu, '')
|
||||
.replace(/steps to reproduce:/gu, '')
|
||||
.replace(/does this issue occur when all extensions are disabled.*/gu, '')
|
||||
.replace(/```(.|\s)*?```/gu, '')
|
||||
.replace(/!?\[.*?\]\(.*?\)/gu, '')
|
||||
.replace(/\s+/gu, ' ')
|
||||
|
||||
return {
|
||||
body: cleanse(body),
|
||||
title: cleanse(title),
|
||||
issueType: isBug ? 'bug' : isFeatureRequest ? 'feature_request' : 'unknown',
|
||||
}
|
||||
}
|
||||
|
||||
export interface Release {
|
||||
productVersion: string
|
||||
timestamp: number
|
||||
version: string
|
||||
}
|
||||
|
||||
export const loadLatestRelease = async (quality: 'stable' | 'insider'): Promise<Release | undefined> =>
|
||||
(await axios.get(`https://vscode-update.azurewebsites.net/api/update/darwin/${quality}/latest`)).data
|
||||
|
||||
export const daysAgoToTimestamp = (days: number): number => +new Date(Date.now() - days * 24 * 60 * 60 * 1000)
|
||||
|
||||
export const daysAgoToHumanReadbleDate = (days: number) =>
|
||||
new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().replace(/\.\d{3}\w$/, '')
|
||||
|
||||
export const logRateLimit = async (token: string) => {
|
||||
const usageData = (await new GitHub(token).rateLimit.get()).data.resources
|
||||
;(['core', 'graphql', 'search'] as const).forEach(async (category) => {
|
||||
const usage = 1 - usageData[category].remaining / usageData[category].limit
|
||||
const message = `Usage at ${usage} for ${category}`
|
||||
if (usage > 0) {
|
||||
console.log(message)
|
||||
}
|
||||
if (usage > 0.5) {
|
||||
await logErrorToIssue(message, false, token)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const logErrorToIssue = async (message: string, ping: boolean, token: string): Promise<void> => {
|
||||
// Attempt to wait out abuse detection timeout if present
|
||||
await new Promise((resolve) => setTimeout(resolve, 10000))
|
||||
const dest =
|
||||
context.repo.repo === 'vscode-internalbacklog'
|
||||
? { repo: 'vscode-internalbacklog', issue: 974 }
|
||||
: { repo: 'vscode', issue: 93814 }
|
||||
return new OctoKitIssue(token, { owner: 'Microsoft', repo: dest.repo }, { number: dest.issue })
|
||||
.postComment(`
|
||||
Workflow: ${context.workflow}
|
||||
|
||||
Error: ${message}
|
||||
|
||||
Issue: ${ping ? `${context.repo.owner}/${context.repo.repo}#` : ''}${context.issue.number}
|
||||
|
||||
Repo: ${context.repo.owner}/${context.repo.repo}
|
||||
|
||||
<!-- Context:
|
||||
${JSON.stringify(context, null, 2).replace(/<!--/gu, '<@--').replace(/-->/gu, '--@>')}
|
||||
-->
|
||||
`)
|
||||
}
|
||||
@@ -1,421 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@actions/core@^1.2.6":
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.2.6.tgz#a78d49f41a4def18e88ce47c2cac615d5694bf09"
|
||||
integrity sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA==
|
||||
|
||||
"@actions/github@^2.1.1":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@actions/github/-/github-2.1.1.tgz#bcabedff598196d953f58ba750d5e75549a75142"
|
||||
integrity sha512-kAgTGUx7yf5KQCndVeHSwCNZuDBvPyxm5xKTswW2lofugeuC1AZX73nUUVDNaysnM9aKFMHv9YCdVJbg7syEyA==
|
||||
dependencies:
|
||||
"@actions/http-client" "^1.0.3"
|
||||
"@octokit/graphql" "^4.3.1"
|
||||
"@octokit/rest" "^16.43.1"
|
||||
|
||||
"@actions/http-client@^1.0.3":
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-1.0.8.tgz#8bd76e8eca89dc8bcf619aa128eba85f7a39af45"
|
||||
integrity sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==
|
||||
dependencies:
|
||||
tunnel "0.0.6"
|
||||
|
||||
"@octokit/auth-token@^2.4.0":
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.0.tgz#b64178975218b99e4dfe948253f0673cbbb59d9f"
|
||||
integrity sha512-eoOVMjILna7FVQf96iWc3+ZtE/ZT6y8ob8ZzcqKY1ibSQCnu4O/B7pJvzMx5cyZ/RjAff6DAdEb0O0Cjcxidkg==
|
||||
dependencies:
|
||||
"@octokit/types" "^2.0.0"
|
||||
|
||||
"@octokit/endpoint@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-6.0.1.tgz#16d5c0e7a83e3a644d1ddbe8cded6c3d038d31d7"
|
||||
integrity sha512-pOPHaSz57SFT/m3R5P8MUu4wLPszokn5pXcB/pzavLTQf2jbU+6iayTvzaY6/BiotuRS0qyEUkx3QglT4U958A==
|
||||
dependencies:
|
||||
"@octokit/types" "^2.11.1"
|
||||
is-plain-object "^3.0.0"
|
||||
universal-user-agent "^5.0.0"
|
||||
|
||||
"@octokit/graphql@^4.3.1":
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.3.1.tgz#9ee840e04ed2906c7d6763807632de84cdecf418"
|
||||
integrity sha512-hCdTjfvrK+ilU2keAdqNBWOk+gm1kai1ZcdjRfB30oA3/T6n53UVJb7w0L5cR3/rhU91xT3HSqCd+qbvH06yxA==
|
||||
dependencies:
|
||||
"@octokit/request" "^5.3.0"
|
||||
"@octokit/types" "^2.0.0"
|
||||
universal-user-agent "^4.0.0"
|
||||
|
||||
"@octokit/plugin-paginate-rest@^1.1.1":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz#004170acf8c2be535aba26727867d692f7b488fc"
|
||||
integrity sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==
|
||||
dependencies:
|
||||
"@octokit/types" "^2.0.1"
|
||||
|
||||
"@octokit/plugin-request-log@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz#eef87a431300f6148c39a7f75f8cfeb218b2547e"
|
||||
integrity sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw==
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods@2.4.0":
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz#3288ecf5481f68c494dd0602fc15407a59faf61e"
|
||||
integrity sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==
|
||||
dependencies:
|
||||
"@octokit/types" "^2.0.1"
|
||||
deprecation "^2.3.1"
|
||||
|
||||
"@octokit/request-error@^1.0.2":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-1.2.1.tgz#ede0714c773f32347576c25649dc013ae6b31801"
|
||||
integrity sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==
|
||||
dependencies:
|
||||
"@octokit/types" "^2.0.0"
|
||||
deprecation "^2.0.0"
|
||||
once "^1.4.0"
|
||||
|
||||
"@octokit/request-error@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.0.0.tgz#94ca7293373654400fbb2995f377f9473e00834b"
|
||||
integrity sha512-rtYicB4Absc60rUv74Rjpzek84UbVHGHJRu4fNVlZ1mCcyUPPuzFfG9Rn6sjHrd95DEsmjSt1Axlc699ZlbDkw==
|
||||
dependencies:
|
||||
"@octokit/types" "^2.0.0"
|
||||
deprecation "^2.0.0"
|
||||
once "^1.4.0"
|
||||
|
||||
"@octokit/request@^5.2.0", "@octokit/request@^5.3.0":
|
||||
version "5.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.4.2.tgz#74f8e5bbd39dc738a1b127629791f8ad1b3193ee"
|
||||
integrity sha512-zKdnGuQ2TQ2vFk9VU8awFT4+EYf92Z/v3OlzRaSh4RIP0H6cvW1BFPXq4XYvNez+TPQjqN+0uSkCYnMFFhcFrw==
|
||||
dependencies:
|
||||
"@octokit/endpoint" "^6.0.1"
|
||||
"@octokit/request-error" "^2.0.0"
|
||||
"@octokit/types" "^2.11.1"
|
||||
deprecation "^2.0.0"
|
||||
is-plain-object "^3.0.0"
|
||||
node-fetch "^2.3.0"
|
||||
once "^1.4.0"
|
||||
universal-user-agent "^5.0.0"
|
||||
|
||||
"@octokit/rest@^16.43.1":
|
||||
version "16.43.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.43.1.tgz#3b11e7d1b1ac2bbeeb23b08a17df0b20947eda6b"
|
||||
integrity sha512-gfFKwRT/wFxq5qlNjnW2dh+qh74XgTQ2B179UX5K1HYCluioWj8Ndbgqw2PVqa1NnVJkGHp2ovMpVn/DImlmkw==
|
||||
dependencies:
|
||||
"@octokit/auth-token" "^2.4.0"
|
||||
"@octokit/plugin-paginate-rest" "^1.1.1"
|
||||
"@octokit/plugin-request-log" "^1.0.0"
|
||||
"@octokit/plugin-rest-endpoint-methods" "2.4.0"
|
||||
"@octokit/request" "^5.2.0"
|
||||
"@octokit/request-error" "^1.0.2"
|
||||
atob-lite "^2.0.0"
|
||||
before-after-hook "^2.0.0"
|
||||
btoa-lite "^1.0.0"
|
||||
deprecation "^2.0.0"
|
||||
lodash.get "^4.4.2"
|
||||
lodash.set "^4.3.2"
|
||||
lodash.uniq "^4.5.0"
|
||||
octokit-pagination-methods "^1.1.0"
|
||||
once "^1.4.0"
|
||||
universal-user-agent "^4.0.0"
|
||||
|
||||
"@octokit/types@^2.0.0", "@octokit/types@^2.0.1", "@octokit/types@^2.11.1":
|
||||
version "2.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-2.12.1.tgz#4a26b4a85ec121043d3b0745b5798f9d8fd968ca"
|
||||
integrity sha512-LRLR1tjbcCfAmUElvTmMvLEzstpx6Xt/aQVTg2xvd+kHA2Ekp1eWl5t+gU7bcwjXHYEAzh4hH4WH+kS3vh+wRw==
|
||||
dependencies:
|
||||
"@types/node" ">= 8"
|
||||
|
||||
"@types/node@>= 8":
|
||||
version "13.13.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.2.tgz#160d82623610db590a64e8ca81784e11117e5a54"
|
||||
integrity sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==
|
||||
|
||||
arg@^4.1.0:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
||||
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
|
||||
|
||||
atob-lite@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696"
|
||||
integrity sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=
|
||||
|
||||
axios@^0.21.4:
|
||||
version "0.21.4"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
|
||||
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
|
||||
dependencies:
|
||||
follow-redirects "^1.14.0"
|
||||
|
||||
before-after-hook@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"
|
||||
integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==
|
||||
|
||||
btoa-lite@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337"
|
||||
integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc=
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||
|
||||
cross-spawn@^6.0.0:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
|
||||
dependencies:
|
||||
nice-try "^1.0.4"
|
||||
path-key "^2.0.1"
|
||||
semver "^5.5.0"
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
deprecation@^2.0.0, deprecation@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
|
||||
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
|
||||
|
||||
diff@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||
|
||||
end-of-stream@^1.1.0:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
execa@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
|
||||
integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
|
||||
dependencies:
|
||||
cross-spawn "^6.0.0"
|
||||
get-stream "^4.0.0"
|
||||
is-stream "^1.1.0"
|
||||
npm-run-path "^2.0.0"
|
||||
p-finally "^1.0.0"
|
||||
signal-exit "^3.0.0"
|
||||
strip-eof "^1.0.0"
|
||||
|
||||
follow-redirects@^1.14.0:
|
||||
version "1.14.8"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
|
||||
integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==
|
||||
|
||||
get-stream@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
|
||||
integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
|
||||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
is-plain-object@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.0.tgz#47bfc5da1b5d50d64110806c199359482e75a928"
|
||||
integrity sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==
|
||||
dependencies:
|
||||
isobject "^4.0.0"
|
||||
|
||||
is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
isobject@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0"
|
||||
integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==
|
||||
|
||||
lodash.get@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
|
||||
|
||||
lodash.set@^4.3.2:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23"
|
||||
integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=
|
||||
|
||||
lodash.uniq@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||
|
||||
macos-release@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f"
|
||||
integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==
|
||||
|
||||
make-error@^1.1.1:
|
||||
version "1.3.6"
|
||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
node-fetch@^2.3.0:
|
||||
version "2.6.7"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
||||
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
||||
|
||||
npm-run-path@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
|
||||
integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
|
||||
dependencies:
|
||||
path-key "^2.0.0"
|
||||
|
||||
octokit-pagination-methods@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4"
|
||||
integrity sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==
|
||||
|
||||
once@^1.3.1, once@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
os-name@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801"
|
||||
integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==
|
||||
dependencies:
|
||||
macos-release "^2.2.0"
|
||||
windows-release "^3.1.0"
|
||||
|
||||
p-finally@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
|
||||
integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
|
||||
|
||||
path-key@^2.0.0, path-key@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
|
||||
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
|
||||
|
||||
pump@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
|
||||
integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
|
||||
dependencies:
|
||||
end-of-stream "^1.1.0"
|
||||
once "^1.3.1"
|
||||
|
||||
semver@^5.5.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
|
||||
dependencies:
|
||||
shebang-regex "^1.0.0"
|
||||
|
||||
shebang-regex@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
||||
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
|
||||
|
||||
signal-exit@^3.0.0:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||
|
||||
source-map-support@^0.5.17:
|
||||
version "0.5.19"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
|
||||
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map@^0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
strip-eof@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
|
||||
integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
|
||||
|
||||
ts-node@^8.6.2:
|
||||
version "8.9.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.9.0.tgz#d7bf7272dcbecd3a2aa18bd0b96c7d2f270c15d4"
|
||||
integrity sha512-rwkXfOs9zmoHrV8xE++dmNd6ZIS+nmHHCxcV53ekGJrxFLMbp+pizpPS07ARvhwneCIECPppOwbZHvw9sQtU4w==
|
||||
dependencies:
|
||||
arg "^4.1.0"
|
||||
diff "^4.0.1"
|
||||
make-error "^1.1.1"
|
||||
source-map-support "^0.5.17"
|
||||
yn "3.1.1"
|
||||
|
||||
tunnel@0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
|
||||
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
|
||||
|
||||
typescript@^3.8.3:
|
||||
version "3.8.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061"
|
||||
integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==
|
||||
|
||||
universal-user-agent@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-4.0.1.tgz#fd8d6cb773a679a709e967ef8288a31fcc03e557"
|
||||
integrity sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==
|
||||
dependencies:
|
||||
os-name "^3.1.0"
|
||||
|
||||
universal-user-agent@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-5.0.0.tgz#a3182aa758069bf0e79952570ca757de3579c1d9"
|
||||
integrity sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q==
|
||||
dependencies:
|
||||
os-name "^3.1.0"
|
||||
|
||||
which@^1.2.9:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
||||
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
windows-release@^3.1.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.3.0.tgz#dce167e9f8be733f21c849ebd4d03fe66b29b9f0"
|
||||
integrity sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ==
|
||||
dependencies:
|
||||
execa "^1.0.0"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
yn@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
||||
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
||||
@@ -17,6 +17,13 @@ steps:
|
||||
mv azuredatastudio-darwin-unsigned.zip azuredatastudio-darwin.zip
|
||||
displayName: 'Rename the file'
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .NET Core sdk for signing'
|
||||
inputs:
|
||||
packageType: sdk
|
||||
version: 2.1.x
|
||||
installationPath: $(Agent.ToolsDirectory)/dotnet
|
||||
|
||||
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
|
||||
displayName: 'ESRP CodeSigning'
|
||||
inputs:
|
||||
|
||||
@@ -106,7 +106,7 @@ steps:
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
./scripts/test.sh --build --tfs "Unit Tests" # Disable code coverage since it's currently broken --coverage
|
||||
./scripts/test.sh --build --tfs "Unit Tests" --coverage
|
||||
displayName: Run unit tests
|
||||
condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true'))
|
||||
|
||||
@@ -128,14 +128,24 @@ steps:
|
||||
yarn gulp compile-extensions
|
||||
displayName: Compile Extensions
|
||||
|
||||
# Per https://developercommunity.visualstudio.com/t/variablesexpressions-dont-work-with-continueonerro/1187733 we can't use variables
|
||||
# in continueOnError directly so instead make two copies of the task and only run one or the other based on the SMOKE_FAIL_ON_ERROR value
|
||||
- script: |
|
||||
set -e
|
||||
APP_ROOT=$(agent.builddirectory)/azuredatastudio-darwin-x64
|
||||
APP_NAME="`ls $APP_ROOT | head -n 1`"
|
||||
yarn smoketest --build "$APP_ROOT/$APP_NAME" --screenshots "$(build.artifactstagingdirectory)/smokeshots" --log "$(build.artifactstagingdirectory)/logs/darwin/smoke.log" --extensionsDir "$(build.sourcesdirectory)/extensions"
|
||||
displayName: Run smoke tests (Electron)
|
||||
displayName: Run smoke tests (Electron) (Continue on Error)
|
||||
continueOnError: true
|
||||
condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true'))
|
||||
condition: and(succeeded(), and(eq(variables['RUN_TESTS'], 'true'), ne(variables['SMOKE_FAIL_ON_ERROR'], 'true')))
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
APP_ROOT=$(agent.builddirectory)/azuredatastudio-darwin-x64
|
||||
APP_NAME="`ls $APP_ROOT | head -n 1`"
|
||||
yarn smoketest --build "$APP_ROOT/$APP_NAME" --screenshots "$(build.artifactstagingdirectory)/smokeshots" --log "$(build.artifactstagingdirectory)/logs/darwin/smoke.log" --extensionsDir "$(build.sourcesdirectory)/extensions"
|
||||
displayName: Run smoke tests (Electron) (Fail on Error)
|
||||
condition: and(succeeded(), and(eq(variables['RUN_TESTS'], 'true'), eq(variables['SMOKE_FAIL_ON_ERROR'], 'true')))
|
||||
|
||||
# - script: |
|
||||
# set -e
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Download base image ubuntu 21.04
|
||||
FROM ubuntu:21.04
|
||||
#Download base image ubuntu 22.04
|
||||
FROM mcr.microsoft.com/mirror/docker/library/ubuntu:22.04
|
||||
ENV TZ=America/Los_Angeles
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Download base image ubuntu 18.04
|
||||
FROM ubuntu:18.04
|
||||
FROM mcr.microsoft.com/mirror/docker/library/ubuntu:18.04
|
||||
|
||||
#Adding apt repos for g++-4.9
|
||||
RUN echo "deb http://dk.archive.ubuntu.com/ubuntu/ xenial main" >> /etc/apt/sources.list
|
||||
|
||||
@@ -119,7 +119,7 @@ steps:
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests" # Disable code coverage since it's currently broken --coverage
|
||||
DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests" --coverage
|
||||
displayName: Run unit tests (Electron)
|
||||
condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true'))
|
||||
|
||||
|
||||
@@ -6,6 +6,9 @@ trigger:
|
||||
|
||||
pr: none
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
@@ -52,13 +55,13 @@ steps:
|
||||
git reset --hard upstream/master
|
||||
git push --force
|
||||
|
||||
# Update the type
|
||||
# Update and format the typings file
|
||||
cd ..
|
||||
node build/azure-pipelines/publish-types/update-types.js
|
||||
|
||||
cd DefinitelyTyped
|
||||
TAG_VERSION=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||
|
||||
# Create and push the branch
|
||||
cd DefinitelyTyped
|
||||
git diff --color | cat
|
||||
git add -A
|
||||
git status
|
||||
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
steps:
|
||||
- template: linux/sql-product-build-linux.yml
|
||||
parameters:
|
||||
extensionsToUnitTest: ["admin-tool-ext-win", "agent", "azcli", "azurecore", "cms", "dacpac", "data-workspace", "import", "machine-learning", "notebook", "resource-deployment", "schema-compare", "sql-database-projects"]
|
||||
extensionsToUnitTest: ["admin-tool-ext-win", "agent", "azcli", "azurecore", "cms", "dacpac", "data-workspace", "import", "machine-learning", "notebook", "resource-deployment", "schema-compare", "sql-bindings", "sql-database-projects"]
|
||||
timeoutInMinutes: 90
|
||||
|
||||
- job: Windows
|
||||
@@ -60,16 +60,17 @@ jobs:
|
||||
- template: win32/sql-product-build-win32.yml
|
||||
timeoutInMinutes: 90
|
||||
|
||||
- job: Windows_Test
|
||||
condition: and(succeeded(), eq(variables['VSCODE_BUILD_WIN32'], 'true'))
|
||||
pool:
|
||||
name: mssqltools
|
||||
dependsOn:
|
||||
- Linux
|
||||
- Windows
|
||||
steps:
|
||||
- template: win32/sql-product-test-win32.yml
|
||||
timeoutInMinutes: 90
|
||||
# disable due to invalid machine pool (karlb 3/9/2022)
|
||||
# - job: Windows_Test
|
||||
# condition: and(succeeded(), eq(variables['VSCODE_BUILD_WIN32'], 'true'))
|
||||
# pool:
|
||||
# name: mssqltools
|
||||
# dependsOn:
|
||||
# - Linux
|
||||
# - Windows
|
||||
# steps:
|
||||
# - template: win32/sql-product-test-win32.yml
|
||||
# timeoutInMinutes: 90
|
||||
|
||||
- job: Release
|
||||
condition: and(succeeded(), or(eq(variables['VSCODE_RELEASE'], 'true'), and(eq(variables['VSCODE_QUALITY'], 'insider'), eq(variables['Build.Reason'], 'Schedule'))))
|
||||
@@ -79,7 +80,8 @@ jobs:
|
||||
- macOS
|
||||
- Linux
|
||||
- Windows
|
||||
- Windows_Test
|
||||
# disable due to invalid machine pool (karlb 3/9/2022)
|
||||
# - Windows_Test
|
||||
- macOS_Signing
|
||||
steps:
|
||||
- template: sql-release.yml
|
||||
|
||||
@@ -77,9 +77,11 @@ steps:
|
||||
node build/azure-pipelines/mixin
|
||||
displayName: Mix in quality
|
||||
|
||||
# Run these separately to avoid OOM errors on pipeline machines
|
||||
- script: |
|
||||
set -e
|
||||
yarn npm-run-all -lp core-ci extensions-ci hygiene eslint valid-layers-check
|
||||
yarn npm-run-all -lp core-ci extensions-ci
|
||||
yarn npm-run-all -lp hygiene eslint valid-layers-check
|
||||
displayName: Compile & Hygiene
|
||||
|
||||
- script: |
|
||||
@@ -93,6 +95,7 @@ steps:
|
||||
AZURE_STORAGE_ACCESS_KEY="$(sourcemap-storage-key)" \
|
||||
node build/azure-pipelines/upload-sourcemaps
|
||||
displayName: Upload sourcemaps
|
||||
condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false'))
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Download base image ubuntu 21.04
|
||||
FROM ubuntu:21.04
|
||||
#Download base image ubuntu 22.04
|
||||
FROM mcr.microsoft.com/mirror/docker/library/ubuntu:22.04
|
||||
ENV TZ=America/Los_Angeles
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
|
||||
@@ -104,14 +104,26 @@ steps:
|
||||
yarn gulp compile-extensions
|
||||
displayName: Compile Extensions
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
node ./node_modules/playwright/install.js
|
||||
APP_ROOT=$(Agent.BuildDirectory)/vscode-reh-web-linux-x64
|
||||
xvfb-run yarn smoketest --build "$(Agent.BuildDirectory)/vscode-reh-web-linux-x64" --web --headless --screenshots "$(Build.ArtifactStagingDirectory)/smokeshots" --log "$(Build.ArtifactStagingDirectory)/logs/web/smoke.log"
|
||||
displayName: Run smoke tests (Browser)
|
||||
continueOnError: true
|
||||
condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true'))
|
||||
# disable smoke tests (karlb 3/2/2022)
|
||||
# # Per https://developercommunity.visualstudio.com/t/variablesexpressions-dont-work-with-continueonerro/1187733 we can't use variables
|
||||
# # in continueOnError directly so instead make two copies of the task and only run one or the other based on the SMOKE_FAIL_ON_ERROR value
|
||||
# - script: |
|
||||
# set -e
|
||||
# node ./node_modules/playwright/install.js
|
||||
# APP_ROOT=$(Agent.BuildDirectory)/vscode-reh-web-linux-x64
|
||||
# xvfb-run yarn smoketest --build "$(Agent.BuildDirectory)/vscode-reh-web-linux-x64" --web --headless --screenshots "$(Build.ArtifactStagingDirectory)/smokeshots" --log "$(Build.ArtifactStagingDirectory)/logs/web/smoke.log"
|
||||
# displayName: Run smoke tests (Browser) (Continue on Error)
|
||||
# continueOnError: true
|
||||
# condition: and(succeeded(), and(eq(variables['RUN_TESTS'], 'true'), ne(variables['SMOKE_FAIL_ON_ERROR'], 'true')))
|
||||
|
||||
# disable smoke tests (karlb 3/2/2022)
|
||||
# - script: |
|
||||
# set -e
|
||||
# node ./node_modules/playwright/install.js
|
||||
# APP_ROOT=$(Agent.BuildDirectory)/vscode-reh-web-linux-x64
|
||||
# xvfb-run yarn smoketest --build "$(Agent.BuildDirectory)/vscode-reh-web-linux-x64" --web --headless --screenshots "$(Build.ArtifactStagingDirectory)/smokeshots" --log "$(Build.ArtifactStagingDirectory)/logs/web/smoke.log"
|
||||
# displayName: Run smoke tests (Browser) (Fail on Error)
|
||||
# condition: and(succeeded(), and(eq(variables['RUN_TESTS'], 'true'), eq(variables['SMOKE_FAIL_ON_ERROR'], 'true')))
|
||||
|
||||
# - script: |
|
||||
# set -e
|
||||
|
||||
@@ -51,7 +51,7 @@ steps:
|
||||
$AppNameShort = $AppProductJson.nameShort
|
||||
exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; $env:INTEGRATION_TEST_CLI_PATH = "$AppRoot\bin\$AppNameShort"; .\scripts\sql-test-integration.bat }
|
||||
continueOnError: false
|
||||
condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true'))
|
||||
condition: and(succeeded(), and(eq(variables['RUN_TESTS'], 'true'), ne(variables['RUN_INTEGRATION_TESTS'], 'false')))
|
||||
displayName: Run stable tests
|
||||
env:
|
||||
BDC_BACKEND_USERNAME: $(ads-integration-test-bdc-server-username)
|
||||
@@ -75,7 +75,7 @@ steps:
|
||||
$AppNameShort = $AppProductJson.nameShort
|
||||
exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; .\scripts\sql-test-integration-unstable.bat }
|
||||
continueOnError: true
|
||||
condition: and(succeeded(), eq(variables['RUN_UNSTABLE_TESTS'], 'true'))
|
||||
condition: and(succeeded(), and(eq(variables['RUN_UNSTABLE_TESTS'], 'true'), ne(variables['RUN_INTEGRATION_TESTS'], 'false')))
|
||||
displayName: Run unstable integration tests
|
||||
env:
|
||||
BDC_BACKEND_USERNAME: $(ads-integration-test-bdc-server-username)
|
||||
@@ -99,4 +99,4 @@ steps:
|
||||
mergeTestResults: true
|
||||
failTaskOnFailedTests: true
|
||||
continueOnError: true
|
||||
condition: and(succeededOrFailed(), eq(variables['RUN_TESTS'], 'true'))
|
||||
condition: and(succeededOrFailed(), and(eq(variables['RUN_TESTS'], 'true'), ne(variables['RUN_INTEGRATION_TESTS'], 'false')))
|
||||
|
||||
@@ -122,7 +122,8 @@ module.exports.indentationFilter = [
|
||||
'!extensions/simple-browser/media/*.js',
|
||||
'!resources/xlf/LocProject.json',
|
||||
'!build/**/*',
|
||||
'!test/coverage/**'
|
||||
'!test/coverage/**',
|
||||
'!extensions/**/coverage/**'
|
||||
];
|
||||
|
||||
module.exports.copyrightFilter = [
|
||||
@@ -182,6 +183,7 @@ module.exports.copyrightFilter = [
|
||||
'!src/sql/base/browser/ui/table/plugins/checkboxSelectColumn.plugin.ts',
|
||||
'!src/sql/base/browser/ui/table/plugins/cellSelectionModel.plugin.ts',
|
||||
'!src/sql/base/browser/ui/table/plugins/autoSizeColumns.plugin.ts',
|
||||
'!src/sql/base/browser/ui/table/plugins/rowMoveManager.plugin.ts',
|
||||
'!src/sql/workbench/services/notebook/browser/outputs/sanitizer.ts',
|
||||
'!src/sql/workbench/contrib/notebook/browser/outputs/renderers.ts',
|
||||
'!src/sql/workbench/services/notebook/browser/outputs/tableRenderers.ts',
|
||||
|
||||
@@ -240,7 +240,7 @@ exports.compileExtensionsBuildTask = compileExtensionsBuildTask;
|
||||
//Get every extension in 'extensions' to create XLF files.
|
||||
const exportCompilations = glob.sync('**/package.json', {
|
||||
cwd: extensionsPath,
|
||||
ignore: ['**/out/**', '**/node_modules/**', 'package.json']
|
||||
ignore: ['**/out/**', '**/node_modules/**', '**/sqltoolsservice/**', 'package.json']
|
||||
});
|
||||
|
||||
//Run the localization packaging task on all extensions in ADS.
|
||||
|
||||
@@ -129,16 +129,19 @@ gulp.task('package-external-extensions', task.series(
|
||||
const packageManifestPath = path.join(packageDir, 'package.json');
|
||||
const json = require('gulp-json-editor');
|
||||
const packageJsonStream = gulp.src(packageManifestPath) // Create stream for the original package.json
|
||||
.pipe(json(data => { // And now use gulp-json-editor to modify the contents
|
||||
.pipe(json(data => {
|
||||
// And now use gulp-json-editor to modify the contents
|
||||
const updateData = JSON.parse(fs.readFileSync(vscodeManifestFullPath)); // Read in the set of values to replace from package.vscode.json
|
||||
Object.keys(updateData).forEach(key => {
|
||||
data[key] = updateData[key];
|
||||
});
|
||||
// Remove ADS-only menus. This is a subset of the menus listed in https://github.com/microsoft/azuredatastudio/blob/main/src/vs/workbench/api/common/menusExtensionPoint.ts
|
||||
// More can be added to the list as needed.
|
||||
['objectExplorer/item/context', 'dataExplorer/context', 'dashboard/toolbar'].forEach(menu => {
|
||||
delete data.contributes.menus[menu];
|
||||
});
|
||||
if(data.contributes?.menus){
|
||||
// Remove ADS-only menus. This is a subset of the menus listed in https://github.com/microsoft/azuredatastudio/blob/main/src/vs/workbench/api/common/menusExtensionPoint.ts
|
||||
// More can be added to the list as needed.
|
||||
['objectExplorer/item/context', 'dataExplorer/context', 'dashboard/toolbar'].forEach(menu => {
|
||||
delete data.contributes.menus[menu];
|
||||
});
|
||||
}
|
||||
return data;
|
||||
}, { beautify: false }))
|
||||
.pipe(gulp.dest(packageDir));
|
||||
|
||||
@@ -135,6 +135,7 @@ const extensionsFilter = filter([
|
||||
'**/schema-compare.xlf',
|
||||
'**/server-report.xlf',
|
||||
'**/sql-assessment.xlf',
|
||||
'**/sql-bindings.xlf',
|
||||
'**/sql-database-projects.xlf',
|
||||
'**/sql-migration.xlf',
|
||||
'**/xml-language-features.xlf'
|
||||
|
||||
@@ -37,9 +37,17 @@ function createCompile(src, build, emitError) {
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json');
|
||||
const overrideOptions = Object.assign(Object.assign({}, getTypeScriptCompilerOptions(src)), { inlineSources: Boolean(build) });
|
||||
if (!build) {
|
||||
if (!build && !process.env['SQL_NO_INLINE_SOURCEMAP']) {
|
||||
overrideOptions.inlineSourceMap = true;
|
||||
}
|
||||
else if (!build) {
|
||||
console.warn('********************************************************************************************');
|
||||
console.warn('* Inlining of source maps is DISABLED, which will prevent debugging from working properly, *');
|
||||
console.warn('* but is required to generate code coverage reports. *');
|
||||
console.warn('* To re-enable inlining of source maps clear the SQL_NO_INLINE_SOURCEMAP environment var *');
|
||||
console.warn('* and re-run the build/watch task *');
|
||||
console.warn('********************************************************************************************');
|
||||
}
|
||||
const compilation = tsb.create(projectPath, overrideOptions, false, err => reporter(err));
|
||||
function pipeline(token) {
|
||||
const bom = require('gulp-bom');
|
||||
|
||||
@@ -44,8 +44,15 @@ function createCompile(src: string, build: boolean, emitError?: boolean) {
|
||||
|
||||
const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json');
|
||||
const overrideOptions = { ...getTypeScriptCompilerOptions(src), inlineSources: Boolean(build) };
|
||||
if (!build) {
|
||||
if (!build && !process.env['SQL_NO_INLINE_SOURCEMAP']) {
|
||||
overrideOptions.inlineSourceMap = true;
|
||||
} else if (!build) {
|
||||
console.warn('********************************************************************************************');
|
||||
console.warn('* Inlining of source maps is DISABLED, which will prevent debugging from working properly, *');
|
||||
console.warn('* but is required to generate code coverage reports. *');
|
||||
console.warn('* To re-enable inlining of source maps clear the SQL_NO_INLINE_SOURCEMAP environment var *');
|
||||
console.warn('* and re-run the build/watch task *');
|
||||
console.warn('********************************************************************************************');
|
||||
}
|
||||
|
||||
const compilation = tsb.create(projectPath, overrideOptions, false, err => reporter(err));
|
||||
@@ -87,7 +94,6 @@ function createCompile(src: string, build: boolean, emitError?: boolean) {
|
||||
export function compileTask(src: string, out: string, build: boolean): () => NodeJS.ReadWriteStream {
|
||||
|
||||
return function () {
|
||||
|
||||
if (os.totalmem() < 4_000_000_000) {
|
||||
throw new Error('compilation requires 4GB of RAM');
|
||||
}
|
||||
|
||||
@@ -231,6 +231,7 @@ const externalExtensions = [
|
||||
'schema-compare',
|
||||
'server-report',
|
||||
'sql-assessment',
|
||||
'sql-bindings',
|
||||
'sql-database-projects',
|
||||
'sql-migration'
|
||||
];
|
||||
|
||||
@@ -267,6 +267,7 @@ const externalExtensions = [
|
||||
'schema-compare',
|
||||
'server-report',
|
||||
'sql-assessment',
|
||||
'sql-bindings',
|
||||
'sql-database-projects',
|
||||
'sql-migration'
|
||||
];
|
||||
|
||||
@@ -18,6 +18,13 @@ const File = require("vinyl");
|
||||
const rimraf = require("rimraf");
|
||||
const gulp = require("gulp");
|
||||
const vfs = require("vinyl-fs");
|
||||
/**
|
||||
* If you need to compile this file for any changes, please run: yarn tsc -p ./build/tsconfig.json
|
||||
*/
|
||||
//List of extensions that we changed from vscode, so we can exclude them from having "Microsoft." appended in front.
|
||||
const alteredVSCodeExtensions = [
|
||||
'git'
|
||||
];
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
// Modified packageLocalExtensionsStream from extensions.ts, but for langpacks.
|
||||
function packageLangpacksStream() {
|
||||
@@ -134,10 +141,13 @@ function modifyI18nPackFiles(existingTranslationFolder, resultingTranslationPath
|
||||
for (let extension in extensionsPacks) {
|
||||
const translatedExtFile = i18n.createI18nFile(`extensions/${extension}`, extensionsPacks[extension]);
|
||||
this.queue(translatedExtFile);
|
||||
//handle edge case for 'Microsoft.sqlservernotebook' where extension name is the same as extension ID.
|
||||
//(Other extensions need to have publisher appended in front as their ID.)
|
||||
const adsExtensionId = (extension === 'Microsoft.sqlservernotebook') ? extension : 'Microsoft.' + extension;
|
||||
resultingTranslationPaths.push({ id: adsExtensionId, resourceName: `extensions/${extension}.i18n.json` });
|
||||
// exclude altered vscode extensions from having a new path even if we provide a new I18n file.
|
||||
if (alteredVSCodeExtensions.indexOf(extension) === -1) {
|
||||
//handle edge case for 'Microsoft.sqlservernotebook' where extension name is the same as extension ID.
|
||||
//(Other extensions need to have publisher appended in front as their ID.)
|
||||
let adsExtensionId = (extension === 'Microsoft.sqlservernotebook') ? extension : 'Microsoft.' + extension;
|
||||
resultingTranslationPaths.push({ id: adsExtensionId, resourceName: `extensions/${extension}.i18n.json` });
|
||||
}
|
||||
}
|
||||
this.queue(null);
|
||||
})
|
||||
@@ -162,7 +172,6 @@ const VSCODEExtensions = [
|
||||
"bat",
|
||||
"configuration-editing",
|
||||
"docker",
|
||||
"extension-editing",
|
||||
"git-ui",
|
||||
"git",
|
||||
"github-authentication",
|
||||
|
||||
@@ -17,6 +17,15 @@ import * as rimraf from 'rimraf';
|
||||
import * as gulp from 'gulp';
|
||||
import * as vfs from 'vinyl-fs';
|
||||
|
||||
/**
|
||||
* If you need to compile this file for any changes, please run: yarn tsc -p ./build/tsconfig.json
|
||||
*/
|
||||
|
||||
//List of extensions that we changed from vscode, so we can exclude them from having "Microsoft." appended in front.
|
||||
const alteredVSCodeExtensions = [
|
||||
'git'
|
||||
]
|
||||
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
|
||||
// Modified packageLocalExtensionsStream from extensions.ts, but for langpacks.
|
||||
@@ -68,7 +77,7 @@ function updateMainI18nFile(existingTranslationFilePath: string, originalFilePat
|
||||
|
||||
// Delete any SQL strings that are no longer part of ADS in current langpack.
|
||||
for (let contentKey of Object.keys(objectContents)) {
|
||||
if(contentKey.startsWith('sql') && messages.contents[contentKey] === undefined){
|
||||
if (contentKey.startsWith('sql') && messages.contents[contentKey] === undefined) {
|
||||
delete objectContents[`${contentKey}`]
|
||||
}
|
||||
}
|
||||
@@ -148,10 +157,14 @@ export function modifyI18nPackFiles(existingTranslationFolder: string, resulting
|
||||
const translatedExtFile = i18n.createI18nFile(`extensions/${extension}`, extensionsPacks[extension]);
|
||||
this.queue(translatedExtFile);
|
||||
|
||||
//handle edge case for 'Microsoft.sqlservernotebook' where extension name is the same as extension ID.
|
||||
//(Other extensions need to have publisher appended in front as their ID.)
|
||||
const adsExtensionId = (extension === 'Microsoft.sqlservernotebook') ? extension : 'Microsoft.' + extension;
|
||||
resultingTranslationPaths.push({ id: adsExtensionId, resourceName: `extensions/${extension}.i18n.json` });
|
||||
// exclude altered vscode extensions from having a new path even if we provide a new I18n file.
|
||||
if (alteredVSCodeExtensions.indexOf(extension) === -1) {
|
||||
//handle edge case for 'Microsoft.sqlservernotebook' where extension name is the same as extension ID.
|
||||
//(Other extensions need to have publisher appended in front as their ID.)
|
||||
let adsExtensionId = (extension === 'Microsoft.sqlservernotebook') ? extension : 'Microsoft.' + extension;
|
||||
|
||||
resultingTranslationPaths.push({ id: adsExtensionId, resourceName: `extensions/${extension}.i18n.json` });
|
||||
}
|
||||
}
|
||||
this.queue(null);
|
||||
})
|
||||
@@ -399,7 +412,7 @@ export function renameVscodeLangpacks(): Promise<void> {
|
||||
|
||||
//Copy files to vscode langpack, then remove the ADS langpack, and finally rename the vscode langpack to match the ADS one.
|
||||
globMDArray.forEach(element => {
|
||||
fs.copyFileSync(element, path.join(locVSCODEFolder,path.parse(element).base));
|
||||
fs.copyFileSync(element, path.join(locVSCODEFolder, path.parse(element).base));
|
||||
});
|
||||
rimraf.sync(locADSFolder);
|
||||
fs.renameSync(locVSCODEFolder, locADSFolder);
|
||||
|
||||
@@ -48,6 +48,7 @@ exports.dirs = [
|
||||
'extensions/server-report',
|
||||
'extensions/simple-browser',
|
||||
'extensions/sql-assessment',
|
||||
'extensions/sql-bindings',
|
||||
'extensions/sql-database-projects',
|
||||
'extensions/sql-migration',
|
||||
'extensions/vscode-test-resolver',
|
||||
|
||||
@@ -60,14 +60,14 @@
|
||||
"mime": "^1.4.1",
|
||||
"mkdirp": "^1.0.4",
|
||||
"p-limit": "^3.1.0",
|
||||
"plist": "^3.0.1",
|
||||
"plist": "^3.0.5",
|
||||
"rollup": "^1.20.3",
|
||||
"rollup-plugin-commonjs": "^10.1.0",
|
||||
"rollup-plugin-node-resolve": "^5.2.0",
|
||||
"source-map": "0.6.1",
|
||||
"tmp": "^0.2.1",
|
||||
"typescript": "^4.5.0-dev.20210817",
|
||||
"vsce": "1.48.0",
|
||||
"vsce": "2.8.0",
|
||||
"vscode-universal-bundler": "^0.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
752
build/yarn.lock
752
build/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"rules": {
|
||||
"no-cond-assign": 2,
|
||||
"jsdoc/check-param-names": "error"
|
||||
"jsdoc/check-param-names": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": ["error"],
|
||||
"@typescript-eslint/await-thenable": ["error"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,17 +108,17 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/ads-extension-telemetry": "^1.1.3",
|
||||
"@microsoft/ads-service-downloader": "0.2.3",
|
||||
"@microsoft/ads-service-downloader": "0.2.4",
|
||||
"vscode-nls": "^4.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^12.11.7",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha": "^7.1.1",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"should": "^13.2.3",
|
||||
"@microsoft/vscodetestcover": "^1.2.0"
|
||||
"@microsoft/vscodetestcover": "^1.2.1"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "41",
|
||||
|
||||
@@ -82,6 +82,7 @@ async function handleLaunchSsmsMinGswDialogCommand(connectionContext?: azdata.Ob
|
||||
if (!connectionContext) {
|
||||
TelemetryReporter.sendErrorEvent(TelemetryViews.SsmsMinGsw, 'NoConnectionContext');
|
||||
void vscode.window.showErrorMessage(localize('adminToolExtWin.noConnectionContextForGsw', "No ConnectionContext provided for handleLaunchSsmsMinPropertiesDialogCommand"));
|
||||
return;
|
||||
}
|
||||
|
||||
return launchSsmsDialog(
|
||||
@@ -101,7 +102,7 @@ async function launchSsmsDialog(action: string, connectionContext: azdata.Object
|
||||
return;
|
||||
}
|
||||
|
||||
let oeNode: azdata.objectexplorer.ObjectExplorerNode;
|
||||
let oeNode: azdata.objectexplorer.ObjectExplorerNode | undefined;
|
||||
// Server node is a Connection node and so doesn't have the NodeInfo
|
||||
if (connectionContext.isConnectionNode) {
|
||||
oeNode = undefined;
|
||||
@@ -153,11 +154,11 @@ async function launchSsmsDialog(action: string, connectionContext: azdata.Object
|
||||
// Process has exited so remove from map of running processes
|
||||
runningProcesses.delete(proc.pid);
|
||||
const err = stderr.toString();
|
||||
if ((execException && execException.code !== 0) || err !== '') {
|
||||
if ((execException?.code !== 0) || err !== '') {
|
||||
TelemetryReporter.sendErrorEvent(
|
||||
TelemetryViews.SsmsMinDialog,
|
||||
'LaunchSsmsDialogError',
|
||||
execException ? execException.code.toString() : '',
|
||||
execException ? execException?.code?.toString() : '',
|
||||
getTelemetryErrorType(err));
|
||||
}
|
||||
|
||||
@@ -170,7 +171,7 @@ async function launchSsmsDialog(action: string, connectionContext: azdata.Object
|
||||
|
||||
// If we're not using AAD the tool prompts for a password on stdin
|
||||
if (params.useAad !== true) {
|
||||
proc.stdin.end(password ? password : '');
|
||||
proc.stdin!.end(password ? password : '');
|
||||
}
|
||||
|
||||
// Save the process into our map so we can make sure to stop them if we exit before shutting down
|
||||
|
||||
@@ -8,6 +8,6 @@ import * as vscode from 'vscode';
|
||||
|
||||
describe('Extension activate test', () => {
|
||||
it('Extension should activate correctly', async function (): Promise<void> {
|
||||
await vscode.extensions.getExtension('Microsoft.admin-tool-ext-win').activate();
|
||||
await vscode.extensions.getExtension('Microsoft.admin-tool-ext-win')!.activate();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as vscode from 'vscode';
|
||||
*/
|
||||
export class ExtHostObjectExplorerNodeStub implements azdata.objectexplorer.ObjectExplorerNode {
|
||||
// Stub properties
|
||||
private parent: azdata.objectexplorer.ObjectExplorerNode;
|
||||
private parent: azdata.objectexplorer.ObjectExplorerNode | undefined;
|
||||
|
||||
// Base properties
|
||||
public connectionId: string;
|
||||
@@ -24,10 +24,10 @@ export class ExtHostObjectExplorerNodeStub implements azdata.objectexplorer.Obje
|
||||
public metadata: azdata.ObjectMetadata;
|
||||
public errorMessage: string;
|
||||
|
||||
constructor(nodeName: string, nodeSchema: string, nodeType: string, parent: azdata.objectexplorer.ObjectExplorerNode) {
|
||||
constructor(nodeName: string, nodeSchema: string, nodeType: string, parent?: azdata.objectexplorer.ObjectExplorerNode) {
|
||||
this.parent = parent;
|
||||
this.nodeType = nodeType;
|
||||
this.metadata = { metadataType: undefined, metadataTypeName: undefined, name: nodeName, schema: nodeSchema, urn: undefined, parentName: undefined, parentTypeName: undefined };
|
||||
this.metadata = { metadataType: azdata.MetadataType.Table, metadataTypeName: 'MyMetadataTypeName', name: nodeName, schema: nodeSchema, urn: 'urn', parentName: undefined, parentTypeName: undefined };
|
||||
}
|
||||
|
||||
isExpanded(): Thenable<boolean> {
|
||||
@@ -38,7 +38,7 @@ export class ExtHostObjectExplorerNodeStub implements azdata.objectexplorer.Obje
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
setSelected(selected: boolean, clearOtherSelections: boolean = undefined): Thenable<void> {
|
||||
setSelected(selected: boolean, clearOtherSelections: boolean): Thenable<void> {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
|
||||
@@ -77,14 +77,14 @@ describe('buildUrn Method Tests', () => {
|
||||
|
||||
it('Urn should be correct with Server and only Databases folder', async function (): Promise<void> {
|
||||
const leafNode: ExtHostObjectExplorerNodeStub =
|
||||
new ExtHostObjectExplorerNodeStub('MyServer', undefined, 'Server', undefined)
|
||||
.createChild('Databases', undefined, 'Folder');
|
||||
new ExtHostObjectExplorerNodeStub('MyServer', 'MySchema', 'Server', undefined)
|
||||
.createChild('Databases', '', 'Folder');
|
||||
should(await buildUrn(leafNode)).equal('Server');
|
||||
});
|
||||
|
||||
it('Urn should be correct with Server and Database node', async function (): Promise<void> {
|
||||
const leafNode: ExtHostObjectExplorerNodeStub =
|
||||
new ExtHostObjectExplorerNodeStub('Databases', undefined, 'Folder', undefined)
|
||||
new ExtHostObjectExplorerNodeStub('Databases', 'MySchema', 'Folder', undefined)
|
||||
.createChild(dbName, dbSchema, 'Database');
|
||||
should(await buildUrn(leafNode)).equal(
|
||||
`Server/Database[@Name='${escapedDbName}' and @Schema='${escapedDbSchema}']`);
|
||||
@@ -92,9 +92,9 @@ describe('buildUrn Method Tests', () => {
|
||||
|
||||
it('Urn should be correct with Multiple levels of Nodes', async function (): Promise<void> {
|
||||
const rootNode: ExtHostObjectExplorerNodeStub =
|
||||
new ExtHostObjectExplorerNodeStub('Databases', undefined, 'Folder', undefined)
|
||||
new ExtHostObjectExplorerNodeStub('Databases', 'MySchema', 'Folder', undefined)
|
||||
.createChild(dbName, dbSchema, 'Database')
|
||||
.createChild('Tables', undefined, 'Folder')
|
||||
.createChild('Tables', 'MySchema', 'Folder')
|
||||
.createChild(tableName, tableSchema, 'Table');
|
||||
should(await buildUrn(rootNode)).equal(
|
||||
`Server/Database[@Name='${escapedDbName}' and @Schema='${escapedDbSchema}']/Table[@Name='${escapedTableName}' and @Schema='${escapedTableSchema}']`);
|
||||
@@ -102,10 +102,10 @@ describe('buildUrn Method Tests', () => {
|
||||
|
||||
it('Urn should be correct with Multiple levels of Nodes without schemas', async function (): Promise<void> {
|
||||
const rootNode: ExtHostObjectExplorerNodeStub =
|
||||
new ExtHostObjectExplorerNodeStub('Databases', undefined, 'Folder', undefined)
|
||||
.createChild(dbName, undefined, 'Database')
|
||||
.createChild('Tables', undefined, 'Folder')
|
||||
.createChild(tableName, undefined, 'Table');
|
||||
new ExtHostObjectExplorerNodeStub('Databases', '', 'Folder', undefined)
|
||||
.createChild(dbName, '', 'Database')
|
||||
.createChild('Tables', '', 'Folder')
|
||||
.createChild(tableName, '', 'Table');
|
||||
should(await buildUrn(rootNode)).equal(
|
||||
`Server/Database[@Name='${escapedDbName}']/Table[@Name='${escapedTableName}']`);
|
||||
});
|
||||
|
||||
@@ -126,7 +126,7 @@ export const nodeTypeToUrnNameMapping: { [oeNodeType: string]: SmoMapping } = {
|
||||
* Builds the URN string for a given ObjectExplorerNode in the form understood by SsmsMin
|
||||
* @param node The node to get the URN of
|
||||
*/
|
||||
export async function buildUrn(node: azdata.objectexplorer.ObjectExplorerNode): Promise<string> {
|
||||
export async function buildUrn(node?: azdata.objectexplorer.ObjectExplorerNode): Promise<string> {
|
||||
let urnNodes: string[] = [];
|
||||
while (node) {
|
||||
// Server is special since it's a connection node - always add it as the root
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
10
extensions/agent/.eslintrc.json
Normal file
10
extensions/agent/.eslintrc.json
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
{
|
||||
"parserOptions": {
|
||||
"project": "./extensions/agent/tsconfig.json"
|
||||
},
|
||||
"rules": {
|
||||
// Disabled until the issues can be fixed
|
||||
"@typescript-eslint/explicit-function-return-type": ["off"]
|
||||
}
|
||||
}
|
||||
@@ -19,12 +19,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
@@ -89,14 +89,14 @@
|
||||
"vscode-nls": "^4.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^12.11.7",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha": "^7.1.1",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"should": "^13.2.1",
|
||||
"typemoq": "^2.1.0",
|
||||
"@microsoft/vscodetestcover": "^1.2.0"
|
||||
"@microsoft/vscodetestcover": "^1.2.1"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "10",
|
||||
|
||||
@@ -40,7 +40,7 @@ export abstract class AgentDialog<T extends IAgentDialogData> {
|
||||
let event = dialogName ? dialogName : null;
|
||||
this.dialog = azdata.window.createModelViewDialog(this.title, event);
|
||||
|
||||
await this.model.initialize();
|
||||
this.model.initialize();
|
||||
|
||||
await this.initializeDialog(this.dialog);
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"strict": false,
|
||||
"noUnusedParameters": false
|
||||
"noUnusedParameters": false,
|
||||
"strictNullChecks": false
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
9
extensions/arc/.eslintrc.json
Normal file
9
extensions/arc/.eslintrc.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"project": "./extensions/arc/tsconfig.json"
|
||||
},
|
||||
"rules": {
|
||||
// Disabled until the issues can be fixed
|
||||
"@typescript-eslint/explicit-function-return-type": ["off"]
|
||||
}
|
||||
}
|
||||
16
extensions/arc/images/upgrade.svg
Normal file
16
extensions/arc/images/upgrade.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
|
||||
<defs>
|
||||
<linearGradient id="a8a99b72-4483-4aed-9c09-505d227627b7" x1="9" y1="778.831" x2="9" y2="790.831" gradientTransform="matrix(1, 0, 0, -1, 0, 791.516)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#0078d4" />
|
||||
<stop offset="0.82" stop-color="#5ea0ef" />
|
||||
</linearGradient>
|
||||
<linearGradient id="ab11b5a0-213c-48d8-9a74-d2a9e98a4058" x1="9" y1="774.201" x2="9" y2="778.831" gradientTransform="matrix(1, 0, 0, -1, 0, 791.516)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#ccc" />
|
||||
<stop offset="1" stop-color="#707070" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect y="0.685" width="18" height="12" rx="0.6" fill="url(#a8a99b72-4483-4aed-9c09-505d227627b7)" />
|
||||
<path d="M12.61,16.315c-1.78-.28-1.85-1.56-1.85-3.63H7.23c0,2.07-.06,3.35-1.84,3.63a1,1,0,0,0-.89,1h9A1,1,0,0,0,12.61,16.315Z" fill="url(#ab11b5a0-213c-48d8-9a74-d2a9e98a4058)" />
|
||||
<path d="M4.939,6.782l0,2.588a.147.147,0,0,0,.147.147.149.149,0,0,0,.086-.028l.712-.512A4.174,4.174,0,0,0,7.506,10.3a4.084,4.084,0,0,0,1.674.361,3.909,3.909,0,0,0,.684-.06,3.993,3.993,0,0,0,1.123-.369,3.848,3.848,0,0,0,.952-.677,3.917,3.917,0,0,0,1.108-1.983.224.224,0,0,0-.153-.261.216.216,0,0,0-.066-.01.223.223,0,0,0-.214.158v0A3.372,3.372,0,0,1,11.52,9.079a3.186,3.186,0,0,1-1.762.712c-.093.009-.186.013-.278.013a3.161,3.161,0,0,1-1.531-.4,3.106,3.106,0,0,1-1.135-1.1l.99-.712a.147.147,0,0,0-.048-.261L5.123,6.641a.128.128,0,0,0-.038,0A.146.146,0,0,0,4.939,6.782Z" fill="#fff" opacity="0.8" />
|
||||
<path d="M13.065,6.628V4.041a.148.148,0,0,0-.148-.147.146.146,0,0,0-.085.028l-.67.484a4.193,4.193,0,0,0-1.7-1.357,4.114,4.114,0,0,0-1.618-.335A3.929,3.929,0,0,0,4.962,5.857a.2.2,0,0,0,.136.227.225.225,0,0,0,.058.008.2.2,0,0,0,.188-.139v0a3.4,3.4,0,0,1,1.1-1.632A3.213,3.213,0,0,1,8.2,3.607c.094-.009.188-.014.281-.014a3.13,3.13,0,0,1,1.517.4,3.052,3.052,0,0,1,1.154,1.143l-.957.69a.147.147,0,0,0,.049.261l2.634.687a.122.122,0,0,0,.037.005A.147.147,0,0,0,13.065,6.628Z" fill="#fff" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -185,21 +185,24 @@
|
||||
"print (f'Creating Azure Arc Data Controller: {arc_data_controller_name} using configuration {arc_cluster_context}')\n",
|
||||
"os.environ[\"AZDATA_USERNAME\"] = arc_admin_username\n",
|
||||
"os.environ[\"AZDATA_PASSWORD\"] = arc_admin_password\n",
|
||||
"os.environ[\"LOG_WORKSPACE_ID\"] = log_analytics_workspace_id\n",
|
||||
"os.environ[\"LOG_SHARED_KEY\"] = log_analytics_primary_key\n",
|
||||
"\n",
|
||||
"# If connection mode is indirect\n",
|
||||
"namespace = f' --k8s-namespace {arc_data_controller_namespace}' if is_indirect else ''\n",
|
||||
"use_k8s = ' --use-k8s' if is_indirect else ''\n",
|
||||
"\n",
|
||||
"# If connection mode is direct\n",
|
||||
"custom_location = f' --custom-location {arc_data_controller_custom_location}' if not is_indirect else ''\n",
|
||||
"\n",
|
||||
"cluster_name = f' --cluster-name {arc_cluster_context}' if not is_indirect else ''\n",
|
||||
"auto_upload_metrics_value = 'true' if arc_data_controller_auto_upload_metrics == 'true' else 'false'\n",
|
||||
"auto_upload_logs_value = 'true' if arc_data_controller_auto_upload_logs == 'true' else 'false'\n",
|
||||
"\n",
|
||||
"auto_upload_metrics = f' --auto-upload-metrics {auto_upload_metrics_value}' if not is_indirect else ''\n",
|
||||
"auto_upload_logs = f' --auto-upload-logs {auto_upload_logs_value}' if not is_indirect else ''\n",
|
||||
"\n",
|
||||
"if os.name == 'nt':\n",
|
||||
" print(f'If you don\\'t see output produced by az, you can run the following command in a terminal window to check the deployment status:\\n\\t {os.environ[\"AZDATA_NB_VAR_KUBECTL\"]} get pods -n {arc_data_controller_namespace}')\n",
|
||||
"run_command(f'az arcdata dc create --connectivity-mode {arc_data_controller_connectivity_mode} --name {arc_data_controller_name}{namespace} --subscription {arc_subscription} --resource-group {arc_resource_group} --location {arc_data_controller_location} --storage-class {arc_data_controller_storage_class} --profile-name {arc_profile} --infrastructure {arc_infrastructure}{custom_location}{auto_upload_metrics}{auto_upload_logs}{use_k8s}')\n",
|
||||
"run_command(f'az arcdata dc create --connectivity-mode {arc_data_controller_connectivity_mode} --name {arc_data_controller_name}{namespace} --subscription {arc_subscription} --resource-group {arc_resource_group} --location {arc_data_controller_location} --storage-class {arc_data_controller_storage_class} --profile-name {arc_profile} --infrastructure {arc_infrastructure}{custom_location}{cluster_name}{auto_upload_metrics}{auto_upload_logs}{use_k8s}')\n",
|
||||
"print(f'Azure Arc Data Controller: {arc_data_controller_name} created.') "
|
||||
]
|
||||
},
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
"name": "arc",
|
||||
"displayName": "%arc.displayName%",
|
||||
"description": "%arc.description%",
|
||||
"version": "0.12.0",
|
||||
"version": "1.3.0",
|
||||
"publisher": "Microsoft",
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
|
||||
"icon": "images/extension.png",
|
||||
"engines": {
|
||||
"vscode": "*",
|
||||
"azdata": ">=1.32.0"
|
||||
"azdata": ">=1.35.0"
|
||||
},
|
||||
"activationEvents": [
|
||||
"onCommand:arc.connectToController",
|
||||
@@ -20,12 +20,12 @@
|
||||
"Microsoft.azcli",
|
||||
"Microsoft.resource-deployment"
|
||||
],
|
||||
"capabilities": {
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
@@ -360,6 +360,49 @@
|
||||
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
|
||||
"value": "Direct"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "options",
|
||||
"label": "%arc.data.controller.log.analytics.workspace.names%",
|
||||
"variableName": "AZDATA_NB_VAR_LOG_ANALYTICS_WORKSPACE_NAMES",
|
||||
"required": true,
|
||||
"options": {
|
||||
"source": {
|
||||
"providerId": "arc.logAnalyticsWorkspaceNames"
|
||||
},
|
||||
"optionsType": "dropdown"
|
||||
},
|
||||
"enabled": {
|
||||
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_AUTO_UPLOAD_LOGS",
|
||||
"value": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "%arc.data.controller.log.analytics.workspace.id%",
|
||||
"required": true,
|
||||
"isEvaluated": true,
|
||||
"variableName": "AZDATA_NB_VAR_LOG_ANALYTICS_WORKSPACE_ID",
|
||||
"valueProvider": {
|
||||
"providerId": "workspace-name-to-id",
|
||||
"triggerFields": [
|
||||
"AZDATA_NB_VAR_LOG_ANALYTICS_WORKSPACE_NAMES"
|
||||
]
|
||||
},
|
||||
"enabled": {
|
||||
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_AUTO_UPLOAD_LOGS",
|
||||
"value": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"label": "%arc.data.controller.log.analytics.primary.key%",
|
||||
"required": true,
|
||||
"variableName": "AZDATA_NB_VAR_LOG_ANALYTICS_PRIMARY_KEY",
|
||||
"enabled": {
|
||||
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_AUTO_UPLOAD_LOGS",
|
||||
"value": "true"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1091,8 +1134,7 @@
|
||||
"defaultValue": "2",
|
||||
"optionsType": "radio"
|
||||
},
|
||||
"dynamicOptions":
|
||||
{
|
||||
"dynamicOptions": {
|
||||
"target": "AZDATA_NB_VAR_SQL_SERVICE_TIER",
|
||||
"alternates": [
|
||||
{
|
||||
@@ -1344,7 +1386,7 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1390,6 +1432,9 @@
|
||||
"resourceDeploymentOptionsSources": [
|
||||
{
|
||||
"id": "arc.controllers"
|
||||
},
|
||||
{
|
||||
"id": "arc.logAnalyticsWorkspaceNames"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1399,19 +1444,19 @@
|
||||
"yamljs": "^0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^12.11.7",
|
||||
"@types/sinon": "^9.0.4",
|
||||
"@types/uuid": "^8.3.0",
|
||||
"@types/yamljs": "^0.2.31",
|
||||
"@microsoft/azdata-test": "^1.5.1",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha": "^7.1.1",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"should": "^13.2.3",
|
||||
"sinon": "^9.0.2",
|
||||
"typemoq": "2.1.0",
|
||||
"@microsoft/vscodetestcover": "^1.2.0"
|
||||
"@microsoft/vscodetestcover": "^1.2.1"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "68",
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"arc.openDashboard": "Manage",
|
||||
|
||||
"resource.type.azure.arc.display.name": "Azure Arc data controller",
|
||||
"resource.type.azure.arc.description": "Creates an Azure Arc data controller",
|
||||
"resource.type.azure.arc.description": "Creates an Azure Arc data controller. Ensure that you have run az login before starting this wizard.",
|
||||
"arc.data.controller.new.wizard.title": "Create Azure Arc data controller",
|
||||
"arc.data.controller.cluster.environment.title": "What is your target existing Kubernetes cluster environment?",
|
||||
"arc.data.controller.select.cluster.title": "Select from existing Kubernetes clusters",
|
||||
@@ -43,6 +43,9 @@
|
||||
"arc.data.controller.auto.upload.metrics.description": "Enable the automatic upload of metrics. Direct mode only.",
|
||||
"arc.data.controller.auto.upload.logs": "Auto-upload Logs",
|
||||
"arc.data.controller.auto.upload.logs.description": "Enable the automatic upload of logs. Direct mode only.",
|
||||
"arc.data.controller.log.analytics.workspace.names": "Log Analytics workspace",
|
||||
"arc.data.controller.log.analytics.workspace.id": "Log Analytics workspace ID",
|
||||
"arc.data.controller.log.analytics.primary.key": "Log Analytics primary key",
|
||||
|
||||
"arc.data.controller.metrics.and.logs.dashboard.credentials.title": "Metrics and Logs Dashboard Credentials",
|
||||
"arc.data.controller.metrics.and.logs.dashboard.credentials.username": "Username",
|
||||
@@ -102,7 +105,7 @@
|
||||
"arc.sql.high.availability": "High availability",
|
||||
"arc.sql.high.availability.description": "Enable additional replicas for high availabilty. The compute and storage configuration selected below will be applied to all replicas.",
|
||||
"arc.sql.service.tier.general.purpose": "General Purpose (Up to 24 vCores and 128 Gi of RAM, standard high availability)",
|
||||
"arc.sql.service.tier.business.critical": "[PREVIEW] Business Critical (Unlimited vCores and RAM, advanced high availability)",
|
||||
"arc.sql.service.tier.business.critical": "Business Critical (Unlimited vCores and RAM, advanced high availability)",
|
||||
"arc.sql.one.replica": "1 replica",
|
||||
"arc.sql.two.replicas": "2 replicas",
|
||||
"arc.sql.three.replicas": "3 replicas",
|
||||
|
||||
@@ -12,24 +12,19 @@ export const SqlManagedInstanceGeneralPurpose = {
|
||||
licenseIncludedPricePerCore: 153,
|
||||
maxMemorySize: 128,
|
||||
maxVCores: 24,
|
||||
|
||||
replicaOptions: [
|
||||
{
|
||||
text: loc.replicaOne,
|
||||
value: 1,
|
||||
}
|
||||
],
|
||||
|
||||
defaultReplicaValue: 1
|
||||
};
|
||||
|
||||
const SqlManagedInstanceBusinessCritical = {
|
||||
tierName: loc.businessCriticalLabel,
|
||||
|
||||
// Set to real values when BC is ready
|
||||
basePricePerCore: 0,
|
||||
licenseIncludedPricePerCore: 0,
|
||||
|
||||
basePricePerCore: 160,
|
||||
licenseIncludedPricePerCore: 434,
|
||||
replicaOptions: [
|
||||
{
|
||||
text: loc.replicaTwo,
|
||||
@@ -40,7 +35,6 @@ const SqlManagedInstanceBusinessCritical = {
|
||||
value: 3,
|
||||
}
|
||||
],
|
||||
|
||||
defaultReplicaValue: 3
|
||||
};
|
||||
|
||||
|
||||
28
extensions/arc/src/common/workspaceUtils.ts
Normal file
28
extensions/arc/src/common/workspaceUtils.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { InputValueType } from 'resource-deployment';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as vscode from 'vscode';
|
||||
import { errorListingLogAnalyticsWorkspaces } from '../localizedConstants';
|
||||
|
||||
export const licenseTypeVarName = 'AZDATA_NB_VAR_LOG_ANALYTICS_WORKSPACE_NAMES';
|
||||
|
||||
// Gets the Log Analytics workspace id from the workspace name.
|
||||
export async function getWorkspaceIdFromName(triggerFields: { [key: string]: InputValueType }): Promise<string | undefined> {
|
||||
try {
|
||||
const _azApi = <azExt.IExtension>vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
const workspaces = await _azApi.az.monitor.logAnalytics.workspace.list();
|
||||
const targetWorkspace = workspaces.stdout.find(workspace => workspace.name === triggerFields[licenseTypeVarName]);
|
||||
if (targetWorkspace) {
|
||||
return targetWorkspace.customerId;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage(errorListingLogAnalyticsWorkspaces(e));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ export class IconPathHelper {
|
||||
public static properties: IconPath;
|
||||
public static networking: IconPath;
|
||||
public static pitr: IconPath;
|
||||
public static upgrade: IconPath;
|
||||
public static refresh: IconPath;
|
||||
public static reset: IconPath;
|
||||
public static support: IconPath;
|
||||
@@ -160,6 +161,10 @@ export class IconPathHelper {
|
||||
light: context.asAbsolutePath('images/pitr.svg'),
|
||||
dark: context.asAbsolutePath('images/pitr.svg'),
|
||||
};
|
||||
IconPathHelper.upgrade = {
|
||||
light: context.asAbsolutePath('images/upgrade.svg'),
|
||||
dark: context.asAbsolutePath('images/upgrade.svg'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,6 +183,7 @@ export const enum ConnectionMode {
|
||||
|
||||
export namespace cssStyles {
|
||||
export const text = { 'user-select': 'text', 'cursor': 'text' };
|
||||
export const code = { 'user-select': 'text', 'cursor': 'text', 'font-style': 'italic' };
|
||||
export const title = { ...text, 'font-weight': 'bold', 'font-size': '14px' };
|
||||
export const tableHeader = { ...text, 'text-align': 'left', 'border': 'none' };
|
||||
export const tableRow = { ...text, 'border-top': 'solid 1px #ccc', 'border-bottom': 'solid 1px #ccc', 'border-left': 'none', 'border-right': 'none' };
|
||||
|
||||
@@ -15,6 +15,8 @@ import { AzureArcTreeDataProvider } from './ui/tree/azureArcTreeDataProvider';
|
||||
import { ControllerTreeNode } from './ui/tree/controllerTreeNode';
|
||||
import { TreeNode } from './ui/tree/treeNode';
|
||||
import * as pricing from './common/pricingUtils';
|
||||
import * as workspace from './common/workspaceUtils';
|
||||
import { LogAnalyticsWorkspaceOptionsSourceProvider } from './providers/logAnalyticsWorkspaceOptionsSourceProvider';
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext): Promise<arc.IExtension> {
|
||||
IconPathHelper.setExtensionContext(context);
|
||||
@@ -61,6 +63,15 @@ export async function activate(context: vscode.ExtensionContext): Promise<arc.IE
|
||||
// register option sources
|
||||
const rdApi = <rd.IExtension>vscode.extensions.getExtension(rd.extension.name)?.exports;
|
||||
context.subscriptions.push(rdApi.registerOptionsSourceProvider(new ArcControllersOptionsSourceProvider(treeDataProvider)));
|
||||
context.subscriptions.push(rdApi.registerOptionsSourceProvider(new LogAnalyticsWorkspaceOptionsSourceProvider()));
|
||||
|
||||
// Register valueprovider for getting the Log Analytics workspace id from the workspace name.
|
||||
context.subscriptions.push(rdApi.registerValueProvider({
|
||||
id: 'workspace-name-to-id',
|
||||
getValue: async (triggerFields: { [key: string]: rd.InputValueType }) => {
|
||||
return workspace.getWorkspaceIdFromName(triggerFields);
|
||||
}
|
||||
}));
|
||||
|
||||
// Register valueprovider for getting the calculated cost per VCore.
|
||||
context.subscriptions.push(rdApi.registerValueProvider({
|
||||
|
||||
@@ -127,7 +127,7 @@ export const indirect = localize('arc.indirect', "Indirect");
|
||||
export const loading = localize('arc.loading', "Loading...");
|
||||
export const refreshToEnterCredentials = localize('arc.refreshToEnterCredentials', "Refresh node to enter credentials");
|
||||
export const noInstancesAvailable = localize('arc.noInstancesAvailable', "No instances available");
|
||||
export const connectToServer = localize('arc.connecToServer', "Connect to Server");
|
||||
export const connectToServer = localize('arc.connectToServer', "Connect to Server");
|
||||
export const connectToController = localize('arc.connectToController', "Connect to Existing Controller");
|
||||
export function connectToMSSql(name: string): string { return localize('arc.connectToMSSql', "Connect to SQL managed instance - Azure Arc ({0})", name); }
|
||||
export function connectToPGSql(name: string): string { return localize('arc.connectToPGSql', "Connect to PostgreSQL Hyperscale - Azure Arc ({0})", name); }
|
||||
@@ -334,3 +334,29 @@ export const userCancelledError = localize('arc.userCancelledError', "User cance
|
||||
export const clusterContextConfigNoLongerValid = (configFile: string, clusterContext: string, error: any) => localize('clusterContextConfigNoLongerValid', "The cluster context information specified by config file: {0} and cluster context: {1} is no longer valid. Error is:\n\t{2}\n Do you want to update this information?", configFile, clusterContext, getErrorMessage(error));
|
||||
export const invalidConfigPath = localize('arc.invalidConfigPath', "Invalid config path");
|
||||
export const loadingClusterContextsError = (error: any): string => localize('arc.loadingClusterContextsError', "Error loading cluster contexts. {0}", getErrorMessage(error));
|
||||
|
||||
// Upgrade
|
||||
export const upgradeManagement = localize('arc.upgradeManagement', "Upgrade Management");
|
||||
export const availableUpgrades = localize('arc.availableUpgrades', "Available Upgrades");
|
||||
export const availableUpgradesDescription = localize('arc.availableUpgradesDescription', "Available upgrades for this resource are listed below. You can apply upgrades by clicking the upgrade button.");
|
||||
export const versionLog = localize('arc.versionLog', "Learn more about each release here.");
|
||||
export const onlyNextImmediateVersion = localize('arc.onlyNextImmediateVersion', "Currently, only upgrading to the next immediate version is supported.");
|
||||
export const onlyNextImmediateVersionMiaa = localize('arc.onlyNextImmediateVersionMiaa', "The version of a SQL Managed Instance can not be newer than the version of its data controller. Currently, only upgrading to the next immediate version is supported.");
|
||||
export const version = localize('arc.version', "Version");
|
||||
export const releaseDate = localize('arc.releaseDate', "Release Date");
|
||||
export const releaseNotes = localize('arc.releaseNotes', "Release Notes");
|
||||
export const upgrade = localize('arc.upgrade', "Upgrade");
|
||||
export const upgradeDataController = localize('arc.upgradeDataController', "Upgrade Data Controller");
|
||||
export const upgradeMiaa = localize('arc.upgradeMiaa', "Upgrade SQL Managed Instance");
|
||||
export const areYouSure = localize('arc.areYouSure', "Are you sure you want to apply the selected upgrade?");
|
||||
export const upgradeDialogController = localize('arc.upgradeDialogController', "During a data controller upgrade, portions of the data control plane such as Custom Resource Definitions (CRDs) and containers may be upgraded. An upgrade of the data controller will not cause downtime for the data services (SQL Managed Instance or PostgreSQL server).");
|
||||
export const upgradeDialogMiaa = localize('arc.upgradeDialogMiaa', "During a SQL managed instance upgrade, portions of the data control plane such as Custom Resource Definitions (CRDs) and containers may be upgraded. An upgrade of the SQL managed instance will not cause downtime for the data services (SQL Managed Instance or PostgreSQL server).");
|
||||
export const monitorUpgrade = localize('arc.monitorUpgrade', "You can check the status of the upgrade by running the following command:");
|
||||
export function errorListingLogAnalyticsWorkspaces(error: any): string { return localize('arc.errorListingLogAnalyticsWorkspaces', "Error listing Log Analytics workspaces {0}", getErrorMessage(error, true)); }
|
||||
export const noUpgrades = localize('arc.noUpgrades', 'The current version is the latest version. No upgrades available.');
|
||||
export function upgradingController(param: any): string { return localize('arc.upgradingController', "Data controller is being upgraded. You can check the status of the upgrade by running the following command: 'kubectl get datacontrollers -A'", param); }
|
||||
export function upgradingMiaa(param: any): string { return localize('arc.upgradingMiaa', "SQL managed instance is being upgraded. You can check the status of the upgrade by running the following command: 'kubectl get sqlmi -A'", param); }
|
||||
export const currentVersion = localize('arc.currentVersion', "Current version");
|
||||
export const showMiaaError = localize('arc.showMiaaError', "Error showing details of SQL managed instance.");
|
||||
export const miaaVersionError = localize('arc.miaaVersionError', "Error getting SQL managed instance version number.");
|
||||
export const errorGettingConnectionMode = localize('arc.errorGettingConnectionMode', "Error getting data controller connection mode.");
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { ControllerInfo, ResourceType } from 'arc';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as vscode from 'vscode';
|
||||
import { ConnectionMode } from '../constants';
|
||||
import * as loc from '../localizedConstants';
|
||||
import { AzureArcTreeDataProvider } from '../ui/tree/azureArcTreeDataProvider';
|
||||
|
||||
@@ -66,8 +67,17 @@ export class ControllerModel {
|
||||
await this.refresh(false, this.info.namespace);
|
||||
}
|
||||
}
|
||||
|
||||
public async refresh(showErrors: boolean = true, namespace: string): Promise<void> {
|
||||
const newRegistrations: Registration[] = [];
|
||||
await this.refreshController(showErrors, namespace);
|
||||
if (this._controllerConfig?.spec.settings.azure.connectionMode === ConnectionMode.direct) {
|
||||
await this.refreshDirectMode(this._controllerConfig?.spec.settings.azure.resourceGroup, namespace);
|
||||
} else {
|
||||
await this.refreshIndirectMode(namespace);
|
||||
}
|
||||
}
|
||||
|
||||
public async refreshController(showErrors: boolean = true, namespace: string): Promise<void> {
|
||||
await Promise.all([
|
||||
this._azApi.az.arcdata.dc.config.show(namespace, this.azAdditionalEnvVars).then(result => {
|
||||
this._controllerConfig = result.stdout;
|
||||
@@ -96,35 +106,68 @@ export class ControllerModel {
|
||||
}
|
||||
this._onEndpointsUpdated.fire(this._endpoints);
|
||||
throw err;
|
||||
}),
|
||||
Promise.all([
|
||||
this._azApi.az.postgres.arcserver.list(namespace, this.azAdditionalEnvVars).then(result => {
|
||||
newRegistrations.push(...result.stdout.map(r => {
|
||||
return {
|
||||
instanceName: r.name,
|
||||
state: r.state,
|
||||
instanceType: ResourceType.postgresInstances
|
||||
};
|
||||
}));
|
||||
}),
|
||||
this._azApi.az.sql.miarc.list(namespace, this.azAdditionalEnvVars).then(result => {
|
||||
newRegistrations.push(...result.stdout.map(r => {
|
||||
return {
|
||||
instanceName: r.name,
|
||||
state: r.state,
|
||||
instanceType: ResourceType.sqlManagedInstances
|
||||
};
|
||||
}));
|
||||
|
||||
})
|
||||
]).then(() => {
|
||||
this._registrations = newRegistrations;
|
||||
this.registrationsLastUpdated = new Date();
|
||||
this._onRegistrationsUpdated.fire(this._registrations);
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
public async refreshDirectMode(resourceGroup: string, namespace: string): Promise<void> {
|
||||
const newRegistrations: Registration[] = [];
|
||||
await Promise.all([
|
||||
this._azApi.az.postgres.arcserver.list(namespace, this.azAdditionalEnvVars).then(result => {
|
||||
newRegistrations.push(...result.stdout.map(r => {
|
||||
return {
|
||||
instanceName: r.name,
|
||||
state: r.state,
|
||||
instanceType: ResourceType.postgresInstances
|
||||
};
|
||||
}));
|
||||
}),
|
||||
this._azApi.az.sql.miarc.list({ resourceGroup: resourceGroup, namespace: undefined }, this.azAdditionalEnvVars).then(result => {
|
||||
newRegistrations.push(...result.stdout.map(r => {
|
||||
return {
|
||||
instanceName: r.name,
|
||||
state: r.state,
|
||||
instanceType: ResourceType.sqlManagedInstances
|
||||
};
|
||||
}));
|
||||
|
||||
})
|
||||
]).then(() => {
|
||||
this._registrations = newRegistrations;
|
||||
this.registrationsLastUpdated = new Date();
|
||||
this._onRegistrationsUpdated.fire(this._registrations);
|
||||
});
|
||||
}
|
||||
|
||||
public async refreshIndirectMode(namespace: string): Promise<void> {
|
||||
const newRegistrations: Registration[] = [];
|
||||
await Promise.all([
|
||||
this._azApi.az.postgres.arcserver.list(namespace, this.azAdditionalEnvVars).then(result => {
|
||||
newRegistrations.push(...result.stdout.map(r => {
|
||||
return {
|
||||
instanceName: r.name,
|
||||
state: r.state,
|
||||
instanceType: ResourceType.postgresInstances
|
||||
};
|
||||
}));
|
||||
}),
|
||||
this._azApi.az.sql.miarc.list({ resourceGroup: undefined, namespace: namespace }, this.azAdditionalEnvVars).then(result => {
|
||||
newRegistrations.push(...result.stdout.map(r => {
|
||||
return {
|
||||
instanceName: r.name,
|
||||
state: r.state,
|
||||
instanceType: ResourceType.sqlManagedInstances
|
||||
};
|
||||
}));
|
||||
|
||||
})
|
||||
]).then(() => {
|
||||
this._registrations = newRegistrations;
|
||||
this.registrationsLastUpdated = new Date();
|
||||
this._onRegistrationsUpdated.fire(this._registrations);
|
||||
});
|
||||
}
|
||||
|
||||
public get endpoints(): azExt.DcEndpointListResult[] {
|
||||
return this._endpoints;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { ConnectToMiaaSqlDialog } from '../ui/dialogs/connectMiaaDialog';
|
||||
import { AzureArcTreeDataProvider } from '../ui/tree/azureArcTreeDataProvider';
|
||||
import { ControllerModel, Registration } from './controllerModel';
|
||||
import { ResourceModel } from './resourceModel';
|
||||
import { ConnectionMode } from '../constants';
|
||||
|
||||
export type DatabaseModel = { name: string, status: string, earliestBackup: string, lastBackup: string };
|
||||
export type RPModel = { recoveryPointObjective: string, retentionDays: string };
|
||||
@@ -29,6 +30,7 @@ export type PITRModel = {
|
||||
latestPitr: string,
|
||||
destDbName: string
|
||||
};
|
||||
export type UpgradeModel = {};
|
||||
|
||||
export const systemDbs = ['master', 'msdb', 'tempdb', 'model'];
|
||||
export class MiaaModel extends ResourceModel {
|
||||
@@ -97,7 +99,26 @@ export class MiaaModel extends ResourceModel {
|
||||
this._refreshPromise = new Deferred();
|
||||
try {
|
||||
try {
|
||||
const result = await this._azApi.az.sql.miarc.show(this.info.name, this.controllerModel.info.namespace, this.controllerModel.azAdditionalEnvVars);
|
||||
let result;
|
||||
if (this.controllerModel.info.connectionMode === ConnectionMode.direct) {
|
||||
result = await this._azApi.az.sql.miarc.show(
|
||||
this.info.name,
|
||||
{
|
||||
resourceGroup: this.controllerModel.info.resourceGroup,
|
||||
namespace: undefined
|
||||
},
|
||||
this.controllerModel.azAdditionalEnvVars
|
||||
);
|
||||
} else {
|
||||
result = await this._azApi.az.sql.miarc.show(
|
||||
this.info.name,
|
||||
{
|
||||
resourceGroup: undefined,
|
||||
namespace: this.controllerModel.info.namespace
|
||||
},
|
||||
this.controllerModel.azAdditionalEnvVars
|
||||
);
|
||||
}
|
||||
this._config = result.stdout;
|
||||
this.configLastUpdated = new Date();
|
||||
this.rpSettings.retentionDays = this._config?.spec?.backup?.retentionPeriodInDays?.toString() ?? '';
|
||||
@@ -166,7 +187,7 @@ export class MiaaModel extends ResourceModel {
|
||||
if (!result.connected) {
|
||||
throw new Error(result.errorMessage);
|
||||
}
|
||||
this._activeConnectionId = result.connectionId;
|
||||
this._activeConnectionId = result.connectionId!;
|
||||
}
|
||||
|
||||
const provider = azdata.dataprotocol.getProvider<azdata.MetadataProvider>(this._connectionProfile!.providerName, azdata.DataProviderType.MetadataProvider);
|
||||
|
||||
@@ -148,7 +148,7 @@ export class PostgresModel extends ResourceModel {
|
||||
if (!result.connected) {
|
||||
throw new Error(result.errorMessage);
|
||||
}
|
||||
this._activeConnectionId = result.connectionId;
|
||||
this._activeConnectionId = result.connectionId!;
|
||||
}
|
||||
|
||||
// TODO Need to make separate calls for worker nodes and coordinator node
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azExt from 'az-ext';
|
||||
import * as rd from 'resource-deployment';
|
||||
import * as vscode from 'vscode';
|
||||
import { errorListingLogAnalyticsWorkspaces } from '../localizedConstants';
|
||||
|
||||
/**
|
||||
* Class that provides options sources for Log Analytics workspace names
|
||||
*/
|
||||
export class LogAnalyticsWorkspaceOptionsSourceProvider implements rd.IOptionsSourceProvider {
|
||||
readonly id = 'arc.logAnalyticsWorkspaceNames';
|
||||
private readonly _azApi: azExt.IExtension;
|
||||
|
||||
constructor() {
|
||||
this._azApi = <azExt.IExtension>vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
}
|
||||
|
||||
public async getOptions(): Promise<string[]> {
|
||||
try {
|
||||
const workspacesListResult = await this._azApi.az.monitor.logAnalytics.workspace.list();
|
||||
return workspacesListResult.stdout.map(workspace => workspace.name);
|
||||
} catch (err) {
|
||||
vscode.window.showErrorMessage(errorListingLogAnalyticsWorkspaces(err));
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,9 +52,6 @@ describe('radioOptionsGroup', function (): void {
|
||||
const label = radioOptionsGroup.items[0] as azdata.TextComponent;
|
||||
should(label.value).not.be.undefined();
|
||||
label.value!.should.deepEqual(loc.loadingClusterContextsError(loadingError));
|
||||
should(label.CSSStyles).not.be.undefined();
|
||||
should(label.CSSStyles!.color).not.be.undefined();
|
||||
label.CSSStyles!.color.should.equal('Red');
|
||||
});
|
||||
|
||||
describe('getters and setters', async () => {
|
||||
|
||||
@@ -67,7 +67,7 @@ export class RadioOptionsGroup {
|
||||
this.component().loadingCompletedText = this._loadingCompleteMessage;
|
||||
}
|
||||
catch (e) {
|
||||
const errorLabel = this._modelBuilder.text().withProps({ value: loc.loadingClusterContextsError(e), CSSStyles: { 'color': 'Red' } }).component();
|
||||
const errorLabel = this._modelBuilder.text().withProps({ value: loc.loadingClusterContextsError(e), textType: azdata.TextType.Error }).component();
|
||||
this._divContainer.addItem(errorLabel);
|
||||
this.component().loadingCompletedText = this._loadingCompleteErrorMessage(e);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Dashboard } from '../../components/dashboard';
|
||||
import { ControllerModel } from '../../../models/controllerModel';
|
||||
import { ControllerDashboardOverviewPage } from './controllerDashboardOverviewPage';
|
||||
import * as loc from '../../../localizedConstants';
|
||||
import { ControllerUpgradesPage } from './controllerUpgrades';
|
||||
|
||||
export class ControllerDashboard extends Dashboard {
|
||||
|
||||
@@ -23,8 +24,10 @@ export class ControllerDashboard extends Dashboard {
|
||||
|
||||
protected async registerTabs(modelView: azdata.ModelView): Promise<(azdata.DashboardTab | azdata.DashboardTabGroup)[]> {
|
||||
const overviewPage = new ControllerDashboardOverviewPage(modelView, this.dashboard, this._controllerModel);
|
||||
const upgradesPage = new ControllerUpgradesPage(modelView, this.dashboard, this._controllerModel);
|
||||
return [
|
||||
overviewPage.tab
|
||||
overviewPage.tab,
|
||||
upgradesPage.tab
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ export class ControllerDashboardOverviewPage extends DashboardPage {
|
||||
subscriptionId: '-',
|
||||
connectionMode: '-',
|
||||
instanceNamespace: '-',
|
||||
status: '-'
|
||||
};
|
||||
|
||||
constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _controllerModel: ControllerModel) {
|
||||
@@ -219,6 +220,7 @@ export class ControllerDashboardOverviewPage extends DashboardPage {
|
||||
this.controllerProperties.subscriptionId = config?.spec.settings.azure.subscription || this.controllerProperties.subscriptionId;
|
||||
this.controllerProperties.connectionMode = getConnectionModeDisplayText(config?.spec.settings.azure.connectionMode) || this.controllerProperties.connectionMode;
|
||||
this.controllerProperties.instanceNamespace = config?.metadata.namespace || this.controllerProperties.instanceNamespace;
|
||||
this.controllerProperties.status = config?.status.state || this.controllerProperties.status;
|
||||
this.refreshDisplayedProperties();
|
||||
|
||||
let registrations: (string | azdata.ImageComponent | azdata.HyperlinkComponent)[][] = this._controllerModel.registrations
|
||||
@@ -285,6 +287,10 @@ export class ControllerDashboardOverviewPage extends DashboardPage {
|
||||
{
|
||||
displayName: loc.namespace,
|
||||
value: this.controllerProperties.instanceNamespace
|
||||
},
|
||||
{
|
||||
displayName: loc.status,
|
||||
value: this.controllerProperties.status
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as loc from '../../../localizedConstants';
|
||||
import { IconPathHelper, cssStyles, ConnectionMode } from '../../../constants';
|
||||
import { DashboardPage } from '../../components/dashboardPage';
|
||||
import { ControllerModel } from '../../../models/controllerModel';
|
||||
import { UpgradeController } from '../../dialogs/upgradeController';
|
||||
|
||||
export class ControllerUpgradesPage extends DashboardPage {
|
||||
constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _controllerModel: ControllerModel) {
|
||||
super(modelView, dashboard);
|
||||
this._azApi = vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
}
|
||||
private _upgradesContainer!: azdata.DivContainer;
|
||||
private _upgradesTableLoading!: azdata.LoadingComponent;
|
||||
private _upgradesTable!: azdata.DeclarativeTableComponent;
|
||||
private _upgradesMessage!: azdata.TextComponent;
|
||||
private readonly _azApi: azExt.IExtension;
|
||||
|
||||
public get title(): string {
|
||||
return loc.upgradeManagement;
|
||||
}
|
||||
|
||||
public get id(): string {
|
||||
return 'upgrades';
|
||||
}
|
||||
|
||||
public get icon(): { dark: string, light: string } {
|
||||
return IconPathHelper.upgrade;
|
||||
}
|
||||
protected async refresh(): Promise<void> {
|
||||
await Promise.resolve(this._controllerModel.refresh(false, this._controllerModel.info.namespace));
|
||||
this.handleTableUpdated();
|
||||
}
|
||||
|
||||
public get container(): azdata.Component {
|
||||
const root = this.modelView.modelBuilder.flexContainer()
|
||||
.withLayout({ flexFlow: 'column' })
|
||||
.withProps({ CSSStyles: { 'margin': '18px' } })
|
||||
.component();
|
||||
const content = this.modelView.modelBuilder.divContainer().component();
|
||||
this._upgradesContainer = this.modelView.modelBuilder.divContainer().component();
|
||||
root.addItem(content, { CSSStyles: { 'margin': '5px' } });
|
||||
|
||||
// Upgrades title and description
|
||||
const availableUpgradesTitle = this.modelView.modelBuilder.text().withProps({
|
||||
value: loc.availableUpgrades,
|
||||
CSSStyles: { ...cssStyles.title },
|
||||
}).component();
|
||||
content.addItem(availableUpgradesTitle);
|
||||
|
||||
const infoAvailableUpgrades = this.modelView.modelBuilder.text().withProps({
|
||||
value: loc.availableUpgradesDescription,
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
|
||||
}).component();
|
||||
|
||||
const upgradesVersionLogLink = this.modelView.modelBuilder.hyperlink().withProps({
|
||||
label: loc.versionLog,
|
||||
url: 'https://docs.microsoft.com/azure/azure-arc/data/version-log'
|
||||
}).component();
|
||||
|
||||
const upgradesInfoAndLink = this.modelView.modelBuilder.flexContainer()
|
||||
.withLayout({ flexWrap: 'wrap' })
|
||||
.withItems([
|
||||
infoAvailableUpgrades,
|
||||
upgradesVersionLogLink
|
||||
], { CSSStyles: { 'margin-right': '5px' } }).component();
|
||||
|
||||
content.addItem(upgradesInfoAndLink, { CSSStyles: { 'min-height': '30px' } });
|
||||
|
||||
const infoOnlyNextImmediateVersion = this.modelView.modelBuilder.text().withProps({
|
||||
value: loc.onlyNextImmediateVersion,
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
|
||||
}).component();
|
||||
|
||||
content.addItem(infoOnlyNextImmediateVersion, { CSSStyles: { 'min-height': '30px' } });
|
||||
|
||||
// Create loaded components
|
||||
this._upgradesTableLoading = this.modelView.modelBuilder.loadingComponent().component();
|
||||
this._upgradesTable = this.modelView.modelBuilder.declarativeTable().withProps({
|
||||
width: '100%',
|
||||
columns: [
|
||||
{
|
||||
displayName: loc.version,
|
||||
valueType: azdata.DeclarativeDataType.string,
|
||||
isReadOnly: true,
|
||||
width: '30%',
|
||||
headerCssStyles: cssStyles.tableHeader,
|
||||
rowCssStyles: cssStyles.tableRow
|
||||
},
|
||||
{
|
||||
displayName: loc.releaseDate,
|
||||
valueType: azdata.DeclarativeDataType.string,
|
||||
isReadOnly: true,
|
||||
width: '30%',
|
||||
headerCssStyles: cssStyles.tableHeader,
|
||||
rowCssStyles: cssStyles.tableRow
|
||||
},
|
||||
{
|
||||
displayName: loc.upgrade,
|
||||
valueType: azdata.DeclarativeDataType.component,
|
||||
isReadOnly: true,
|
||||
width: '10%',
|
||||
headerCssStyles: cssStyles.tableHeader,
|
||||
rowCssStyles: cssStyles.tableRow,
|
||||
}
|
||||
],
|
||||
dataValues: []
|
||||
}).component();
|
||||
|
||||
this._upgradesMessage = this.modelView.modelBuilder.text()
|
||||
.withProps({ CSSStyles: { 'text-align': 'center' } })
|
||||
.component();
|
||||
|
||||
this.handleTableUpdated();
|
||||
this._upgradesTableLoading.component = this._upgradesTable;
|
||||
|
||||
root.addItem(this._upgradesContainer);
|
||||
root.addItem(this._upgradesMessage);
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
this._upgradesTableLoading.loading = false;
|
||||
this._upgradesContainer.addItem(this._upgradesTableLoading, { CSSStyles: { 'margin-bottom': '20px' } });
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public get toolbarContainer(): azdata.ToolbarContainer {
|
||||
// Refresh
|
||||
const refreshButton = this.modelView.modelBuilder.button().withProps({
|
||||
label: loc.refresh,
|
||||
iconPath: IconPathHelper.refresh
|
||||
}).component();
|
||||
this.disposables.push(
|
||||
refreshButton.onDidClick(async () => {
|
||||
refreshButton.enabled = false;
|
||||
try {
|
||||
await this.refresh();
|
||||
} finally {
|
||||
refreshButton.enabled = true;
|
||||
}
|
||||
}));
|
||||
|
||||
return this.modelView.modelBuilder.toolbarContainer().withToolbarItems(
|
||||
[
|
||||
{ component: refreshButton, toolbarSeparatorAfter: true },
|
||||
|
||||
]
|
||||
).component();
|
||||
}
|
||||
|
||||
private formatTableData(result: azExt.AzOutput<azExt.DcListUpgradesResult>): (string | azdata.ButtonComponent)[][] {
|
||||
let formattedValues: (string | azdata.ButtonComponent)[][] = [];
|
||||
const versions = result.stdout.versions;
|
||||
const dates = result.stdout.dates;
|
||||
const currentVersion = result.stdout.currentVersion;
|
||||
const nextVersion = this.getNextVersion(versions, currentVersion);
|
||||
|
||||
// Iterate through all data controller versions from latest to oldest and stop when the loop reaches the current version.
|
||||
// Only makes table entries for the current version and newer. The upgrade button will only be enabled for the very next
|
||||
// version due to Azure CLI constraints.
|
||||
for (let i = 0; i < versions.length; i++) {
|
||||
if (versions[i] === currentVersion) {
|
||||
formattedValues.push([versions[i], dates[i], this.createUpgradeButton(loc.currentVersion, false, '')]);
|
||||
break;
|
||||
} else if (versions[i] === nextVersion) {
|
||||
formattedValues.push([versions[i], dates[i], this.createUpgradeButton(loc.upgrade, true, nextVersion)]);
|
||||
} else {
|
||||
formattedValues.push([versions[i], dates[i], this.createUpgradeButton(loc.upgrade, false, '')]);
|
||||
}
|
||||
}
|
||||
return formattedValues;
|
||||
}
|
||||
|
||||
private async handleTableUpdated(): Promise<void> {
|
||||
const result = await this._azApi.az.arcdata.dc.listUpgrades(this._controllerModel.info.namespace);
|
||||
let tableDisplay = this.formatTableData(result);
|
||||
let tableValues = tableDisplay.map(d => {
|
||||
return d.map((value: any): azdata.DeclarativeTableCellValue => {
|
||||
return { value: value };
|
||||
});
|
||||
});
|
||||
|
||||
this._upgradesTable.setDataValues(tableValues);
|
||||
this._upgradesTableLoading.loading = false;
|
||||
this._upgradesContainer.addItem(this._upgradesTableLoading, { CSSStyles: { 'margin-bottom': '20px' } });
|
||||
}
|
||||
|
||||
// Given the list of available versions and the current version, if the current version is not the newest,
|
||||
// then return the next version available. List of versions is ordered newest to oldest.
|
||||
// If current version is the newest, then return undefined.
|
||||
private getNextVersion(versions: string[], currentVersion: string): string | undefined {
|
||||
let index = versions.indexOf(currentVersion);
|
||||
// The version at index 0 will be the newest
|
||||
if (index > 0) {
|
||||
return versions[index - 1];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
//Create restore button for every database entry in the database table
|
||||
private createUpgradeButton(label: string, enabled: boolean, nextVersion: string): azdata.ButtonComponent | string {
|
||||
let upgradeButton = this.modelView.modelBuilder.button().withProps({
|
||||
label: label,
|
||||
enabled: enabled
|
||||
}).component();
|
||||
|
||||
this.disposables.push(
|
||||
upgradeButton.onDidClick(async () => {
|
||||
const upgradeDialog = new UpgradeController(this._controllerModel);
|
||||
upgradeDialog.showDialog(loc.upgradeDataController);
|
||||
let dialogClosed = await upgradeDialog.waitForClose();
|
||||
if (dialogClosed) {
|
||||
try {
|
||||
upgradeButton.enabled = false;
|
||||
vscode.window.showInformationMessage(loc.upgradingController('kubectl get datacontrollers -A\' should not be localized.'));
|
||||
await vscode.window.withProgress(
|
||||
{
|
||||
location: vscode.ProgressLocation.Notification,
|
||||
title: loc.updatingInstance(this._controllerModel.info.name),
|
||||
cancellable: true
|
||||
},
|
||||
async (_progress, _token): Promise<void> => {
|
||||
if (nextVersion !== '') {
|
||||
if (this._controllerModel.info.connectionMode === ConnectionMode.direct) {
|
||||
await this._azApi.az.arcdata.dc.upgrade(
|
||||
nextVersion,
|
||||
this._controllerModel.info.name,
|
||||
this._controllerModel.info.resourceGroup,
|
||||
undefined, // Indirect mode argument - namespace
|
||||
);
|
||||
} else {
|
||||
await this._azApi.az.arcdata.dc.upgrade(
|
||||
nextVersion,
|
||||
this._controllerModel.info.name,
|
||||
undefined, // Direct mode argument - resourceGroup
|
||||
this._controllerModel.info.namespace,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
vscode.window.showInformationMessage(loc.noUpgrades);
|
||||
}
|
||||
|
||||
try {
|
||||
await this._controllerModel.refresh(false, this._controllerModel.info.namespace);
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(loc.refreshFailed(error));
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
return upgradeButton;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { MiaaConnectionStringsPage } from './miaaConnectionStringsPage';
|
||||
import { MiaaModel } from '../../../models/miaaModel';
|
||||
import { MiaaComputeAndStoragePage } from './miaaComputeAndStoragePage';
|
||||
import { MiaaBackupsPage } from './miaaBackupsPage';
|
||||
import { MiaaUpgradeManagementPage } from './miaaUpgradeManagementPage';
|
||||
|
||||
export class MiaaDashboard extends Dashboard {
|
||||
|
||||
@@ -31,6 +32,7 @@ export class MiaaDashboard extends Dashboard {
|
||||
const connectionStringsPage = new MiaaConnectionStringsPage(modelView, this.dashboard, this._miaaModel);
|
||||
const computeAndStoragePage = new MiaaComputeAndStoragePage(modelView, this.dashboard, this._miaaModel);
|
||||
const miaaBackupsPage = new MiaaBackupsPage(modelView, this.dashboard, this._controllerModel, this._miaaModel);
|
||||
const upgradeManagementPage = new MiaaUpgradeManagementPage(modelView, this.dashboard, this._controllerModel, this._miaaModel);
|
||||
return [
|
||||
overviewPage.tab,
|
||||
{
|
||||
@@ -38,7 +40,8 @@ export class MiaaDashboard extends Dashboard {
|
||||
tabs: [
|
||||
connectionStringsPage.tab,
|
||||
computeAndStoragePage.tab,
|
||||
miaaBackupsPage.tab
|
||||
miaaBackupsPage.tab,
|
||||
upgradeManagementPage.tab
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as azExt from 'az-ext';
|
||||
import * as azurecore from 'azurecore';
|
||||
import * as vscode from 'vscode';
|
||||
import { getDatabaseStateDisplayText, promptForInstanceDeletion } from '../../../common/utils';
|
||||
import { cssStyles, IconPathHelper, miaaTroubleshootDocsUrl } from '../../../constants';
|
||||
import { ConnectionMode, cssStyles, IconPathHelper, miaaTroubleshootDocsUrl } from '../../../constants';
|
||||
import * as loc from '../../../localizedConstants';
|
||||
import { ControllerModel } from '../../../models/controllerModel';
|
||||
import { MiaaModel } from '../../../models/miaaModel';
|
||||
@@ -243,7 +243,25 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
|
||||
cancellable: false
|
||||
},
|
||||
async (_progress, _token) => {
|
||||
return await this._azApi.az.sql.miarc.delete(this._miaaModel.info.name, this._controllerModel.info.namespace, this._controllerModel.azAdditionalEnvVars);
|
||||
if (this._controllerModel.info.connectionMode === ConnectionMode.direct) {
|
||||
return await this._azApi.az.sql.miarc.delete(
|
||||
this._miaaModel.info.name,
|
||||
{
|
||||
resourceGroup: this._controllerModel.info.resourceGroup,
|
||||
namespace: undefined,
|
||||
},
|
||||
this._controllerModel.azAdditionalEnvVars
|
||||
);
|
||||
} else {
|
||||
return await this._azApi.az.sql.miarc.delete(
|
||||
this._miaaModel.info.name,
|
||||
{
|
||||
resourceGroup: undefined,
|
||||
namespace: this._controllerModel.info.namespace,
|
||||
},
|
||||
this._controllerModel.azAdditionalEnvVars
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
await this._controllerModel.refreshTreeNode();
|
||||
@@ -337,7 +355,7 @@ export class MiaaDashboardOverviewPage extends DashboardPage {
|
||||
if (this._miaaModel.config) {
|
||||
this._instanceProperties.status = this._miaaModel.config.status.state || '-';
|
||||
this._instanceProperties.externalEndpoint = this._miaaModel.config.status.primaryEndpoint || loc.notConfigured;
|
||||
this._instanceProperties.vCores = this._miaaModel.config.spec.scheduling?.default?.resources?.limits?.cpu?.toString() || '';
|
||||
this._instanceProperties.vCores = this._miaaModel.config.spec?.scheduling?.default?.resources?.limits?.cpu?.toString() || '';
|
||||
this._databasesMessage.value = !this._miaaModel.config.status.primaryEndpoint ? loc.noExternalEndpoint : '';
|
||||
if (!this._miaaModel.config.status.primaryEndpoint) {
|
||||
this._databasesContainer.removeItem(this._connectToServerLoading);
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as azdata from 'azdata';
|
||||
import * as azExt from 'az-ext';
|
||||
import * as loc from '../../../localizedConstants';
|
||||
import { IconPathHelper, cssStyles, ConnectionMode } from '../../../constants';
|
||||
import { DashboardPage } from '../../components/dashboardPage';
|
||||
import { ControllerModel } from '../../../models/controllerModel';
|
||||
import { UpgradeSqlMiaa } from '../../dialogs/upgradeSqlMiaa';
|
||||
import { MiaaModel } from '../../../models/miaaModel';
|
||||
|
||||
export class MiaaUpgradeManagementPage extends DashboardPage {
|
||||
constructor(modelView: azdata.ModelView, dashboard: azdata.window.ModelViewDashboard, private _controllerModel: ControllerModel, private _miaaModel: MiaaModel) {
|
||||
super(modelView, dashboard);
|
||||
this._azApi = vscode.extensions.getExtension(azExt.extension.name)?.exports;
|
||||
}
|
||||
private _upgradesContainer!: azdata.DivContainer;
|
||||
private _upgradesTableLoading!: azdata.LoadingComponent;
|
||||
private _upgradesTable!: azdata.DeclarativeTableComponent;
|
||||
private _upgradesMessage!: azdata.TextComponent;
|
||||
private readonly _azApi: azExt.IExtension;
|
||||
|
||||
public get title(): string {
|
||||
return loc.upgradeManagement;
|
||||
}
|
||||
|
||||
public get id(): string {
|
||||
return 'upgrades';
|
||||
}
|
||||
|
||||
public get icon(): { dark: string, light: string } {
|
||||
return IconPathHelper.upgrade;
|
||||
}
|
||||
protected async refresh(): Promise<void> {
|
||||
await Promise.resolve(this._controllerModel.refresh(false, this._controllerModel.info.namespace));
|
||||
this.handleTableUpdated();
|
||||
}
|
||||
|
||||
public get container(): azdata.Component {
|
||||
const root = this.modelView.modelBuilder.flexContainer()
|
||||
.withLayout({ flexFlow: 'column' })
|
||||
.withProps({ CSSStyles: { 'margin': '18px' } })
|
||||
.component();
|
||||
const content = this.modelView.modelBuilder.divContainer().component();
|
||||
this._upgradesContainer = this.modelView.modelBuilder.divContainer().component();
|
||||
root.addItem(content, { CSSStyles: { 'margin': '5px' } });
|
||||
|
||||
// Upgrades title and description
|
||||
const availableUpgradesTitle = this.modelView.modelBuilder.text().withProps({
|
||||
value: loc.availableUpgrades,
|
||||
CSSStyles: { ...cssStyles.title },
|
||||
}).component();
|
||||
content.addItem(availableUpgradesTitle);
|
||||
|
||||
const infoAvailableUpgrades = this.modelView.modelBuilder.text().withProps({
|
||||
value: loc.availableUpgradesDescription,
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
|
||||
}).component();
|
||||
|
||||
const upgradesVersionLogLink = this.modelView.modelBuilder.hyperlink().withProps({
|
||||
label: loc.versionLog,
|
||||
url: 'https://docs.microsoft.com/azure/azure-arc/data/upgrade-sql-managed-instance-direct-cli?WT.mc_id=Portal-Microsoft_Azure_HybridData_Platform'
|
||||
}).component();
|
||||
|
||||
const upgradesInfoAndLink = this.modelView.modelBuilder.flexContainer()
|
||||
.withLayout({ flexWrap: 'wrap' })
|
||||
.withItems([
|
||||
infoAvailableUpgrades,
|
||||
upgradesVersionLogLink
|
||||
], { CSSStyles: { 'margin-right': '5px' } }).component();
|
||||
|
||||
content.addItem(upgradesInfoAndLink, { CSSStyles: { 'min-height': '30px' } });
|
||||
|
||||
const infoOnlyNextImmediateVersion = this.modelView.modelBuilder.text().withProps({
|
||||
value: loc.onlyNextImmediateVersionMiaa,
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
|
||||
}).component();
|
||||
|
||||
content.addItem(infoOnlyNextImmediateVersion, { CSSStyles: { 'min-height': '30px' } });
|
||||
|
||||
// Create loaded components
|
||||
this._upgradesTableLoading = this.modelView.modelBuilder.loadingComponent().component();
|
||||
this._upgradesTable = this.modelView.modelBuilder.declarativeTable().withProps({
|
||||
width: '100%',
|
||||
columns: [
|
||||
{
|
||||
displayName: loc.version,
|
||||
valueType: azdata.DeclarativeDataType.string,
|
||||
isReadOnly: true,
|
||||
width: '30%',
|
||||
headerCssStyles: cssStyles.tableHeader,
|
||||
rowCssStyles: cssStyles.tableRow
|
||||
},
|
||||
{
|
||||
displayName: loc.releaseDate,
|
||||
valueType: azdata.DeclarativeDataType.string,
|
||||
isReadOnly: true,
|
||||
width: '30%',
|
||||
headerCssStyles: cssStyles.tableHeader,
|
||||
rowCssStyles: cssStyles.tableRow
|
||||
},
|
||||
{
|
||||
displayName: loc.upgrade,
|
||||
valueType: azdata.DeclarativeDataType.component,
|
||||
isReadOnly: true,
|
||||
width: '10%',
|
||||
headerCssStyles: cssStyles.tableHeader,
|
||||
rowCssStyles: cssStyles.tableRow,
|
||||
}
|
||||
],
|
||||
dataValues: []
|
||||
}).component();
|
||||
|
||||
this._upgradesMessage = this.modelView.modelBuilder.text()
|
||||
.withProps({ CSSStyles: { 'text-align': 'center' } })
|
||||
.component();
|
||||
|
||||
this.handleTableUpdated();
|
||||
this._upgradesTableLoading.component = this._upgradesTable;
|
||||
|
||||
root.addItem(this._upgradesContainer);
|
||||
root.addItem(this._upgradesMessage);
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
this._upgradesTableLoading.loading = false;
|
||||
this._upgradesContainer.addItem(this._upgradesTableLoading, { CSSStyles: { 'margin-bottom': '20px' } });
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public get toolbarContainer(): azdata.ToolbarContainer {
|
||||
// Refresh
|
||||
const refreshButton = this.modelView.modelBuilder.button().withProps({
|
||||
label: loc.refresh,
|
||||
iconPath: IconPathHelper.refresh
|
||||
}).component();
|
||||
this.disposables.push(
|
||||
refreshButton.onDidClick(async () => {
|
||||
refreshButton.enabled = false;
|
||||
try {
|
||||
await this.refresh();
|
||||
} finally {
|
||||
refreshButton.enabled = true;
|
||||
}
|
||||
}));
|
||||
|
||||
return this.modelView.modelBuilder.toolbarContainer().withToolbarItems(
|
||||
[
|
||||
{ component: refreshButton, toolbarSeparatorAfter: true },
|
||||
|
||||
]
|
||||
).component();
|
||||
}
|
||||
|
||||
private async getMiaaVersion(): Promise<string | undefined> {
|
||||
try {
|
||||
let miaaShowResult;
|
||||
if (this._controllerModel.info.connectionMode === ConnectionMode.direct || this._controllerModel.controllerConfig?.spec.settings.azure.connectionMode === ConnectionMode.direct) {
|
||||
miaaShowResult = await this._azApi.az.sql.miarc.show(
|
||||
this._miaaModel.info.name,
|
||||
{
|
||||
resourceGroup: this._controllerModel.info.resourceGroup,
|
||||
namespace: undefined
|
||||
},
|
||||
this._controllerModel.azAdditionalEnvVars
|
||||
);
|
||||
} else {
|
||||
miaaShowResult = await this._azApi.az.sql.miarc.show(
|
||||
this._miaaModel.info.name,
|
||||
{
|
||||
resourceGroup: undefined,
|
||||
namespace: this._controllerModel.info.namespace
|
||||
},
|
||||
this._controllerModel.azAdditionalEnvVars
|
||||
);
|
||||
}
|
||||
return miaaShowResult.stdout.status.runningVersion;
|
||||
} catch (e) {
|
||||
console.error(loc.showMiaaError, e);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private async formatTableData(result: azExt.AzOutput<azExt.DcListUpgradesResult>): Promise<(string | azdata.ButtonComponent)[][]> {
|
||||
let formattedValues: (string | azdata.ButtonComponent)[][] = [];
|
||||
|
||||
const versions = result.stdout.versions;
|
||||
const dates = result.stdout.dates;
|
||||
|
||||
const currentControllerVersion = result.stdout.currentVersion;
|
||||
|
||||
const currentMiaaVersion = await this.getMiaaVersion();
|
||||
const nextMiaaVersion = currentMiaaVersion ? this.getNextVersion(versions, currentMiaaVersion) : console.error(loc.miaaVersionError);
|
||||
|
||||
if (currentMiaaVersion === currentControllerVersion) {
|
||||
for (let i = 0; i < versions.length; i++) {
|
||||
if (versions[i] === currentMiaaVersion) {
|
||||
formattedValues.push([versions[i], dates[i], this.createUpgradeButton(loc.currentVersion, false)]);
|
||||
break;
|
||||
} else {
|
||||
formattedValues.push([versions[i], dates[i], this.createUpgradeButton(loc.upgrade, false)]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < versions.length; i++) {
|
||||
if (versions[i] === nextMiaaVersion) {
|
||||
formattedValues.push([versions[i], dates[i], this.createUpgradeButton(loc.upgrade, true)]);
|
||||
formattedValues.push([versions[i + 1], dates[i + 1], this.createUpgradeButton(loc.currentVersion, false)]);
|
||||
break;
|
||||
} else {
|
||||
formattedValues.push([versions[i], dates[i], this.createUpgradeButton(loc.upgrade, false)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return formattedValues;
|
||||
}
|
||||
|
||||
private async handleTableUpdated(): Promise<void> {
|
||||
const result = await this._azApi.az.arcdata.dc.listUpgrades(this._controllerModel.info.namespace);
|
||||
let tableDisplay = await this.formatTableData(result);
|
||||
let tableValues = tableDisplay.map(d => {
|
||||
return d.map((value: any): azdata.DeclarativeTableCellValue => {
|
||||
return { value: value };
|
||||
});
|
||||
});
|
||||
|
||||
this._upgradesTable.setDataValues(tableValues);
|
||||
this._upgradesTableLoading.loading = false;
|
||||
this._upgradesContainer.addItem(this._upgradesTableLoading, { CSSStyles: { 'margin-bottom': '20px' } });
|
||||
}
|
||||
|
||||
// Given the list of available versions and the current version, if the current version is not the newest,
|
||||
// then return the next version available. List of versions is ordered newest to oldest.
|
||||
// If current version is the newest, then return undefined.
|
||||
private getNextVersion(versions: string[], currentVersion: string): string | undefined {
|
||||
let index = versions.indexOf(currentVersion);
|
||||
// The version at index 0 will be the newest
|
||||
if (index > 0) {
|
||||
return versions[index - 1];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
//Create restore button for every database entry in the database table
|
||||
private createUpgradeButton(label: string, enabled: boolean): azdata.ButtonComponent | string {
|
||||
let upgradeButton = this.modelView.modelBuilder.button().withProps({
|
||||
label: label,
|
||||
enabled: enabled
|
||||
}).component();
|
||||
|
||||
this.disposables.push(
|
||||
upgradeButton.onDidClick(async () => {
|
||||
const upgradeDialog = new UpgradeSqlMiaa(this._controllerModel);
|
||||
upgradeDialog.showDialog(loc.upgradeMiaa);
|
||||
let dialogClosed = await upgradeDialog.waitForClose();
|
||||
if (dialogClosed) {
|
||||
try {
|
||||
upgradeButton.enabled = false;
|
||||
vscode.window.showInformationMessage(loc.upgradingMiaa('kubectl get sqlmi -A\' should not be localized.'));
|
||||
await vscode.window.withProgress(
|
||||
{
|
||||
location: vscode.ProgressLocation.Notification,
|
||||
title: loc.updatingInstance(this._miaaModel.info.name),
|
||||
cancellable: true
|
||||
},
|
||||
async (_progress, _token): Promise<void> => {
|
||||
if (this._controllerModel.info.connectionMode === ConnectionMode.direct) {
|
||||
await this._azApi.az.sql.miarc.upgrade(
|
||||
this._miaaModel.info.name,
|
||||
{
|
||||
resourceGroup: this._controllerModel.info.resourceGroup,
|
||||
namespace: undefined
|
||||
}
|
||||
);
|
||||
} else {
|
||||
await this._azApi.az.sql.miarc.upgrade(
|
||||
this._miaaModel.info.name,
|
||||
{
|
||||
resourceGroup: undefined,
|
||||
namespace: this._controllerModel.info.namespace,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
await this._controllerModel.refresh(false, this._controllerModel.info.namespace);
|
||||
} catch (error) {
|
||||
vscode.window.showErrorMessage(loc.refreshFailed(error));
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
return upgradeButton;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { AzureArcTreeDataProvider } from '../tree/azureArcTreeDataProvider';
|
||||
import { RadioOptionsGroup } from '../components/radioOptionsGroup';
|
||||
import { getCurrentClusterContext, getDefaultKubeConfigPath, getKubeConfigClusterContexts, KubeClusterContext } from '../../common/kubeUtils';
|
||||
import { FilePicker } from '../components/filePicker';
|
||||
import { ConnectionMode } from '../../constants';
|
||||
|
||||
export type ConnectToControllerDialogModel = { controllerModel: ControllerModel };
|
||||
|
||||
@@ -203,9 +204,9 @@ export class ConnectToControllerDialog extends ControllerDialogBase {
|
||||
controllerModel.info.connectionMode = <string>controllerModel.controllerConfig?.spec.settings.azure.connectionMode;
|
||||
controllerModel.info.location = <string>controllerModel.controllerConfig?.spec.settings.azure.location;
|
||||
|
||||
if (controllerModel.info.connectionMode === 'direct') {
|
||||
if (controllerModel.info.connectionMode === ConnectionMode.direct) {
|
||||
const rawCustomLocation = <string>controllerModel.controllerConfig?.metadata.annotations['management.azure.com/customLocation'];
|
||||
const exp = /\/\bsubscriptions\b\/[\S]*\/\bresourceGroups\/[\S]*\/providers\/[\S]*\/customLocations\/([\S]*)/;
|
||||
const exp = /customlocations\/([\S]*)/;
|
||||
controllerModel.info.customLocation = <string>exp.exec(rawCustomLocation)?.pop();
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -111,7 +111,7 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
|
||||
};
|
||||
const result = await azdata.connection.connect(connectionProfile, false, false);
|
||||
if (result.connected) {
|
||||
connectionProfile.id = result.connectionId;
|
||||
connectionProfile.id = result.connectionId!;
|
||||
const credentialProvider = await azdata.credentials.getProvider(credentialNamespace);
|
||||
if (connectionProfile.savePassword) {
|
||||
await credentialProvider.saveCredential(createCredentialId(this._controllerModel.info.id, this._model.info.resourceType, this._model.info.name), connectionProfile.password);
|
||||
|
||||
@@ -303,7 +303,7 @@ export class RestoreSqlDialog extends InitializingComponent {
|
||||
}
|
||||
|
||||
public refreshPitrSettings(): void {
|
||||
this.pitrSettings.instanceName = this._miaaModel?.config?.metadata.name || this.pitrSettings.instanceName;
|
||||
this.pitrSettings.instanceName = this._miaaModel?.config?.name || this.pitrSettings.instanceName;
|
||||
this.pitrSettings.resourceGroupName = this._controllerModel?.controllerConfig?.spec.settings.azure.resourceGroup || this.pitrSettings.resourceGroupName;
|
||||
this.pitrSettings.location = this._azurecoreApi.getRegionDisplayName(this._controllerModel?.controllerConfig?.spec.settings.azure.location) || this.pitrSettings.location;
|
||||
this.pitrSettings.subscriptionId = this._controllerModel?.controllerConfig?.spec.settings.azure.subscription || this.pitrSettings.subscriptionId;
|
||||
|
||||
94
extensions/arc/src/ui/dialogs/upgradeController.ts
Normal file
94
extensions/arc/src/ui/dialogs/upgradeController.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { Deferred } from '../../common/promise';
|
||||
import * as loc from '../../localizedConstants';
|
||||
import * as vscode from 'vscode';
|
||||
import { cssStyles } from '../../constants';
|
||||
import { InitializingComponent } from '../components/initializingComponent';
|
||||
import { UpgradeModel } from '../../models/miaaModel';
|
||||
import { ControllerModel } from '../../models/controllerModel';
|
||||
|
||||
export class UpgradeController extends InitializingComponent {
|
||||
protected modelBuilder!: azdata.ModelBuilder;
|
||||
private pitrSettings: UpgradeModel = [];
|
||||
private upgradeControllerDialogName = 'UpgradeControllerDialog';
|
||||
|
||||
protected _completionPromise = new Deferred<UpgradeModel | undefined>();
|
||||
protected disposables: vscode.Disposable[] = [];
|
||||
constructor(protected _controllerModel: ControllerModel) {
|
||||
super();
|
||||
}
|
||||
|
||||
public showDialog(dialogTitle: string): azdata.window.Dialog {
|
||||
const dialog = azdata.window.createModelViewDialog(dialogTitle, this.upgradeControllerDialogName, 'narrow', 'flyout');
|
||||
dialog.cancelButton.onClick(() => this.handleCancel());
|
||||
dialog.registerContent(async view => {
|
||||
this.modelBuilder = view.modelBuilder;
|
||||
const areYouSure = this.modelBuilder.text().withProps({
|
||||
value: loc.areYouSure,
|
||||
CSSStyles: { ...cssStyles.title, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' },
|
||||
}).component();
|
||||
const areYouSureInfo = this.modelBuilder.text().withProps({
|
||||
value: loc.upgradeDialogController,
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'max-width': 'auto' }
|
||||
}).component();
|
||||
const upgradeDialog = this.modelBuilder.flexContainer().withLayout({ flexWrap: 'wrap' }).component();
|
||||
|
||||
upgradeDialog.addItem(areYouSureInfo, { CSSStyles: { 'margin-right': '5px' } });
|
||||
|
||||
const monitorUpgradeInfo = this.modelBuilder.text().withProps({
|
||||
value: loc.monitorUpgrade,
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'max-width': 'auto' }
|
||||
}).component();
|
||||
|
||||
upgradeDialog.addItem(monitorUpgradeInfo, { CSSStyles: { 'margin-right': '5px' } });
|
||||
|
||||
const monitorUpgradeCommandInfo = this.modelBuilder.text().withProps({
|
||||
value: 'kubectl get datacontrollers -A',
|
||||
CSSStyles: { ...cssStyles.code, 'margin-block-start': '0px', 'max-width': 'auto' }
|
||||
}).component();
|
||||
|
||||
upgradeDialog.addItem(monitorUpgradeCommandInfo, { CSSStyles: { 'margin-right': '5px' } });
|
||||
|
||||
let formModel = this.modelBuilder.formContainer()
|
||||
.withFormItems([{
|
||||
components: [
|
||||
{
|
||||
component: areYouSure
|
||||
},
|
||||
{
|
||||
component: upgradeDialog
|
||||
}
|
||||
],
|
||||
title: ''
|
||||
}]).withLayout({ width: '100%' }).component();
|
||||
await view.initializeModel(formModel);
|
||||
this.initialized = true;
|
||||
});
|
||||
|
||||
dialog.okButton.label = loc.upgrade;
|
||||
dialog.cancelButton.label = loc.cancel;
|
||||
dialog.registerCloseValidator(async () => await this.validate());
|
||||
dialog.okButton.onClick(() => {
|
||||
this._completionPromise.resolve(this.pitrSettings);
|
||||
});
|
||||
azdata.window.openDialog(dialog);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public async validate(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
private handleCancel(): void {
|
||||
this._completionPromise.resolve(undefined);
|
||||
}
|
||||
|
||||
public waitForClose(): Promise<UpgradeModel | undefined> {
|
||||
return this._completionPromise.promise;
|
||||
}
|
||||
}
|
||||
94
extensions/arc/src/ui/dialogs/upgradeSqlMiaa.ts
Normal file
94
extensions/arc/src/ui/dialogs/upgradeSqlMiaa.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdata from 'azdata';
|
||||
import { Deferred } from '../../common/promise';
|
||||
import * as loc from '../../localizedConstants';
|
||||
import * as vscode from 'vscode';
|
||||
import { cssStyles } from '../../constants';
|
||||
import { InitializingComponent } from '../components/initializingComponent';
|
||||
import { UpgradeModel } from '../../models/miaaModel';
|
||||
import { ControllerModel } from '../../models/controllerModel';
|
||||
|
||||
export class UpgradeSqlMiaa extends InitializingComponent {
|
||||
protected modelBuilder!: azdata.ModelBuilder;
|
||||
private pitrSettings: UpgradeModel = [];
|
||||
private upgradeMiaaDialogName = 'UpgradeSqlMiaaDialog';
|
||||
|
||||
protected _completionPromise = new Deferred<UpgradeModel | undefined>();
|
||||
protected disposables: vscode.Disposable[] = [];
|
||||
constructor(protected _controllerModel: ControllerModel) {
|
||||
super();
|
||||
}
|
||||
|
||||
public showDialog(dialogTitle: string): azdata.window.Dialog {
|
||||
const dialog = azdata.window.createModelViewDialog(dialogTitle, this.upgradeMiaaDialogName, 'narrow', 'flyout');
|
||||
dialog.cancelButton.onClick(() => this.handleCancel());
|
||||
dialog.registerContent(async view => {
|
||||
this.modelBuilder = view.modelBuilder;
|
||||
const areYouSure = this.modelBuilder.text().withProps({
|
||||
value: loc.areYouSure,
|
||||
CSSStyles: { ...cssStyles.title, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' },
|
||||
}).component();
|
||||
const areYouSureInfo = this.modelBuilder.text().withProps({
|
||||
value: loc.upgradeDialogMiaa,
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'max-width': 'auto' }
|
||||
}).component();
|
||||
const upgradeDialog = this.modelBuilder.flexContainer().withLayout({ flexWrap: 'wrap' }).component();
|
||||
|
||||
upgradeDialog.addItem(areYouSureInfo, { CSSStyles: { 'margin-right': '5px' } });
|
||||
|
||||
const monitorUpgradeInfo = this.modelBuilder.text().withProps({
|
||||
value: loc.monitorUpgrade,
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'max-width': 'auto' }
|
||||
}).component();
|
||||
|
||||
upgradeDialog.addItem(monitorUpgradeInfo, { CSSStyles: { 'margin-right': '5px' } });
|
||||
|
||||
const monitorUpgradeCommandInfo = this.modelBuilder.text().withProps({
|
||||
value: 'kubectl get sqlmi -A',
|
||||
CSSStyles: { ...cssStyles.code, 'margin-block-start': '0px', 'max-width': 'auto' }
|
||||
}).component();
|
||||
|
||||
upgradeDialog.addItem(monitorUpgradeCommandInfo, { CSSStyles: { 'margin-right': '5px' } });
|
||||
|
||||
let formModel = this.modelBuilder.formContainer()
|
||||
.withFormItems([{
|
||||
components: [
|
||||
{
|
||||
component: areYouSure
|
||||
},
|
||||
{
|
||||
component: upgradeDialog
|
||||
}
|
||||
],
|
||||
title: ''
|
||||
}]).withLayout({ width: '100%' }).component();
|
||||
await view.initializeModel(formModel);
|
||||
this.initialized = true;
|
||||
});
|
||||
|
||||
dialog.okButton.label = loc.upgrade;
|
||||
dialog.cancelButton.label = loc.cancel;
|
||||
dialog.registerCloseValidator(async () => await this.validate());
|
||||
dialog.okButton.onClick(() => {
|
||||
this._completionPromise.resolve(this.pitrSettings);
|
||||
});
|
||||
azdata.window.openDialog(dialog);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public async validate(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
private handleCancel(): void {
|
||||
this._completionPromise.resolve(undefined);
|
||||
}
|
||||
|
||||
public waitForClose(): Promise<UpgradeModel | undefined> {
|
||||
return this._completionPromise.promise;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
9
extensions/azcli/.eslintrc.json
Normal file
9
extensions/azcli/.eslintrc.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"project": "./extensions/azcli/tsconfig.json"
|
||||
},
|
||||
"rules": {
|
||||
// Disabled until the issues can be fixed
|
||||
"@typescript-eslint/explicit-function-return-type": ["off"]
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,13 @@
|
||||
"name": "azcli",
|
||||
"displayName": "%azcli.arc.displayName%",
|
||||
"description": "%azcli.arc.description%",
|
||||
"version": "0.4.0",
|
||||
"version": "1.3.0",
|
||||
"publisher": "Microsoft",
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
|
||||
"icon": "images/extension.png",
|
||||
"engines": {
|
||||
"vscode": "*",
|
||||
"azdata": ">=1.26.0"
|
||||
"azdata": ">=1.35.0"
|
||||
},
|
||||
"activationEvents": [
|
||||
"*"
|
||||
@@ -94,21 +94,21 @@
|
||||
"which": "^2.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^12.11.7",
|
||||
"@types/request": "^2.48.5",
|
||||
"@types/semver": "^7.3.1",
|
||||
"@types/sinon": "^9.0.4",
|
||||
"@types/uuid": "^8.0.0",
|
||||
"@types/which": "^1.3.2",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha": "^7.1.1",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"nock": "^13.0.2",
|
||||
"should": "^13.2.3",
|
||||
"sinon": "^9.0.2",
|
||||
"typemoq": "^2.1.0",
|
||||
"@microsoft/vscodetestcover": "^1.2.0"
|
||||
"@microsoft/vscodetestcover": "^1.2.1"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "84",
|
||||
|
||||
@@ -54,6 +54,22 @@ export function getAzApi(localAzDiscovered: Promise<IAzTool | undefined>, azTool
|
||||
validateAz(azToolService.localAz);
|
||||
return azToolService.localAz!.arcdata.dc.config.show(namespace, additionalEnvVars);
|
||||
}
|
||||
},
|
||||
listUpgrades: async (namespace: string, usek8s?: boolean, additionalEnvVars?: azExt.AdditionalEnvVars) => {
|
||||
await localAzDiscovered;
|
||||
validateAz(azToolService.localAz);
|
||||
return azToolService.localAz!.arcdata.dc.listUpgrades(namespace, usek8s, additionalEnvVars);
|
||||
},
|
||||
upgrade: async (
|
||||
desiredVersion: string,
|
||||
name: string,
|
||||
resourceGroup?: string,
|
||||
namespace?: string,
|
||||
additionalEnvVars?: azExt.AdditionalEnvVars
|
||||
) => {
|
||||
await localAzDiscovered;
|
||||
validateAz(azToolService.localAz);
|
||||
return azToolService.localAz!.arcdata.dc.upgrade(desiredVersion, name, resourceGroup, namespace, additionalEnvVars);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -101,20 +117,47 @@ export function getAzApi(localAzDiscovered: Promise<IAzTool | undefined>, azTool
|
||||
},
|
||||
sql: {
|
||||
miarc: {
|
||||
delete: async (name: string, namespace: string, additionalEnvVars?: azExt.AdditionalEnvVars) => {
|
||||
delete: async (
|
||||
name: string,
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string;
|
||||
// Indirect mode arguments
|
||||
namespace?: string;
|
||||
},
|
||||
additionalEnvVars?: azExt.AdditionalEnvVars
|
||||
) => {
|
||||
await localAzDiscovered;
|
||||
validateAz(azToolService.localAz);
|
||||
return azToolService.localAz!.sql.miarc.delete(name, namespace, additionalEnvVars);
|
||||
return azToolService.localAz!.sql.miarc.delete(name, args, additionalEnvVars);
|
||||
},
|
||||
list: async (namespace: string, additionalEnvVars?: azExt.AdditionalEnvVars) => {
|
||||
list: async (
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string;
|
||||
// Indirect mode arguments
|
||||
namespace?: string;
|
||||
},
|
||||
additionalEnvVars?: azExt.AdditionalEnvVars
|
||||
) => {
|
||||
await localAzDiscovered;
|
||||
validateAz(azToolService.localAz);
|
||||
return azToolService.localAz!.sql.miarc.list(namespace, additionalEnvVars);
|
||||
return azToolService.localAz!.sql.miarc.list(args, additionalEnvVars);
|
||||
},
|
||||
show: async (name: string, namespace: string, additionalEnvVars?: azExt.AdditionalEnvVars) => {
|
||||
show: async (
|
||||
name: string,
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string;
|
||||
// Indirect mode arguments
|
||||
namespace?: string;
|
||||
},
|
||||
// Additional arguments
|
||||
additionalEnvVars?: azExt.AdditionalEnvVars
|
||||
) => {
|
||||
await localAzDiscovered;
|
||||
validateAz(azToolService.localAz);
|
||||
return azToolService.localAz!.sql.miarc.show(name, namespace, additionalEnvVars);
|
||||
return azToolService.localAz!.sql.miarc.show(name, args, additionalEnvVars);
|
||||
},
|
||||
update: async (
|
||||
name: string,
|
||||
@@ -136,6 +179,21 @@ export function getAzApi(localAzDiscovered: Promise<IAzTool | undefined>, azTool
|
||||
await localAzDiscovered;
|
||||
validateAz(azToolService.localAz);
|
||||
return azToolService.localAz!.sql.miarc.update(name, args, resourceGroup, namespace, usek8s, additionalEnvVars);
|
||||
},
|
||||
upgrade: async (
|
||||
name: string,
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string;
|
||||
// Indirect mode arguments
|
||||
namespace?: string;
|
||||
},
|
||||
// Additional arguments
|
||||
additionalEnvVars?: azExt.AdditionalEnvVars
|
||||
) => {
|
||||
await localAzDiscovered;
|
||||
validateAz(azToolService.localAz);
|
||||
return azToolService.localAz!.sql.miarc.upgrade(name, args, additionalEnvVars);
|
||||
}
|
||||
},
|
||||
midbarc: {
|
||||
@@ -154,6 +212,17 @@ export function getAzApi(localAzDiscovered: Promise<IAzTool | undefined>, azTool
|
||||
}
|
||||
}
|
||||
},
|
||||
monitor: {
|
||||
logAnalytics: {
|
||||
workspace: {
|
||||
list: async (resourceGroup?: string, subscription?: string, additionalEnvVars?: azExt.AdditionalEnvVars) => {
|
||||
await localAzDiscovered;
|
||||
validateAz(azToolService.localAz);
|
||||
return azToolService.localAz!.monitor.logAnalytics.workspace.list(resourceGroup, subscription, additionalEnvVars);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
getPath: async () => {
|
||||
await localAzDiscovered;
|
||||
throwIfNoAz(azToolService.localAz);
|
||||
|
||||
@@ -90,6 +90,38 @@ export class AzTool implements azExt.IAzApi {
|
||||
show: (namespace: string, additionalEnvVars?: azExt.AdditionalEnvVars): Promise<azExt.AzOutput<azExt.DcConfigShowResult>> => {
|
||||
return this.executeCommand<azExt.DcConfigShowResult>(['arcdata', 'dc', 'config', 'show', '--k8s-namespace', namespace, '--use-k8s'], additionalEnvVars);
|
||||
}
|
||||
},
|
||||
listUpgrades: async (namespace: string, usek8s?: boolean, additionalEnvVars?: azExt.AdditionalEnvVars): Promise<azExt.AzOutput<azExt.DcListUpgradesResult>> => {
|
||||
const argsArray = ['arcdata', 'dc', 'list-upgrades'];
|
||||
if (namespace) { argsArray.push('--k8s-namespace', namespace); }
|
||||
if (usek8s) { argsArray.push('--use-k8s'); }
|
||||
|
||||
const output = await this.executeCommand<string>(argsArray, additionalEnvVars);
|
||||
const versions = <string[]>parseDcListUpgrades(output.stdout);
|
||||
const currentVersion = <string>parseCurrentVersion(output.stdout);
|
||||
let dates: string[] = [];
|
||||
for (let i = 0; i < versions.length; i++) {
|
||||
dates.push(parseReleaseDateFromUpgrade(versions[i]));
|
||||
}
|
||||
return {
|
||||
stdout: {
|
||||
versions: versions,
|
||||
currentVersion: currentVersion,
|
||||
dates: dates
|
||||
},
|
||||
stderr: output.stderr
|
||||
};
|
||||
},
|
||||
upgrade: (desiredVersion: string, name: string, resourceGroup?: string, namespace?: string, additionalEnvVars?: azExt.AdditionalEnvVars): Promise<azExt.AzOutput<void>> => {
|
||||
const argsArray = ['arcdata', 'dc', 'upgrade', '--desired-version', desiredVersion, '--name', name];
|
||||
// Direct mode argument
|
||||
if (resourceGroup) { argsArray.push('--resource-group', resourceGroup); }
|
||||
// Indirect mode arguments
|
||||
if (namespace) {
|
||||
argsArray.push('--k8s-namespace', namespace);
|
||||
argsArray.push('--use-k8s');
|
||||
}
|
||||
return this.executeCommand<void>(argsArray, additionalEnvVars);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -145,14 +177,67 @@ export class AzTool implements azExt.IAzApi {
|
||||
|
||||
public sql = {
|
||||
miarc: {
|
||||
delete: (name: string, namespace: string, additionalEnvVars?: azExt.AdditionalEnvVars): Promise<azExt.AzOutput<void>> => {
|
||||
return this.executeCommand<void>(['sql', 'mi-arc', 'delete', '-n', name, '--k8s-namespace', namespace, '--use-k8s'], additionalEnvVars);
|
||||
delete: (
|
||||
name: string,
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string,
|
||||
// Indirect mode arguments
|
||||
namespace?: string
|
||||
// Additional arguments
|
||||
},
|
||||
additionalEnvVars?: azExt.AdditionalEnvVars
|
||||
): Promise<azExt.AzOutput<void>> => {
|
||||
const argsArray = ['sql', 'mi-arc', 'delete', '-n', name];
|
||||
if (args.resourceGroup) {
|
||||
argsArray.push('--resource-group', args.resourceGroup);
|
||||
}
|
||||
if (args.namespace) {
|
||||
argsArray.push('--k8s-namespace', args.namespace);
|
||||
argsArray.push('--use-k8s');
|
||||
}
|
||||
return this.executeCommand<void>(argsArray, additionalEnvVars);
|
||||
},
|
||||
list: (namespace: string, additionalEnvVars?: azExt.AdditionalEnvVars): Promise<azExt.AzOutput<azExt.SqlMiListResult[]>> => {
|
||||
return this.executeCommand<azExt.SqlMiListResult[]>(['sql', 'mi-arc', 'list', '--k8s-namespace', namespace, '--use-k8s'], additionalEnvVars);
|
||||
list: (
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string,
|
||||
// Indirect mode arguments
|
||||
namespace?: string
|
||||
// Additional arguments
|
||||
},
|
||||
additionalEnvVars?: azExt.AdditionalEnvVars
|
||||
): Promise<azExt.AzOutput<azExt.SqlMiListResult[]>> => {
|
||||
const argsArray = ['sql', 'mi-arc', 'list'];
|
||||
if (args.resourceGroup) {
|
||||
argsArray.push('--resource-group', args.resourceGroup);
|
||||
}
|
||||
if (args.namespace) {
|
||||
argsArray.push('--k8s-namespace', args.namespace);
|
||||
argsArray.push('--use-k8s');
|
||||
}
|
||||
return this.executeCommand<azExt.SqlMiListResult[]>(argsArray, additionalEnvVars);
|
||||
},
|
||||
show: (name: string, namespace: string, additionalEnvVars?: azExt.AdditionalEnvVars): Promise<azExt.AzOutput<azExt.SqlMiShowResult>> => {
|
||||
return this.executeCommand<azExt.SqlMiShowResult>(['sql', 'mi-arc', 'show', '-n', name, '--k8s-namespace', namespace, '--use-k8s'], additionalEnvVars);
|
||||
show: (
|
||||
name: string,
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string,
|
||||
// Indirect mode arguments
|
||||
namespace?: string
|
||||
// Additional arguments
|
||||
},
|
||||
additionalEnvVars?: azExt.AdditionalEnvVars
|
||||
): Promise<azExt.AzOutput<azExt.SqlMiShowResult>> => {
|
||||
const argsArray = ['sql', 'mi-arc', 'show', '-n', name];
|
||||
if (args.resourceGroup) {
|
||||
argsArray.push('--resource-group', args.resourceGroup);
|
||||
}
|
||||
if (args.namespace) {
|
||||
argsArray.push('--k8s-namespace', args.namespace);
|
||||
argsArray.push('--use-k8s');
|
||||
}
|
||||
return this.executeSqlMiShow(argsArray, additionalEnvVars);
|
||||
},
|
||||
update: (
|
||||
name: string,
|
||||
@@ -183,6 +268,25 @@ export class AzTool implements azExt.IAzApi {
|
||||
if (namespace) { argsArray.push('--k8s-namespace', namespace); }
|
||||
if (usek8s) { argsArray.push('--use-k8s'); }
|
||||
return this.executeCommand<void>(argsArray, additionalEnvVars);
|
||||
},
|
||||
upgrade: (
|
||||
name: string,
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string,
|
||||
// Indirect mode arguments
|
||||
namespace?: string
|
||||
// Additional arguments
|
||||
},
|
||||
additionalEnvVars?: azExt.AdditionalEnvVars
|
||||
): Promise<azExt.AzOutput<void>> => {
|
||||
const argsArray = ['sql', 'mi-arc', 'upgrade', '--name', name];
|
||||
if (args.resourceGroup) { argsArray.push('--resource-group', args.resourceGroup); }
|
||||
if (args.namespace) {
|
||||
argsArray.push('--k8s-namespace', args.namespace);
|
||||
argsArray.push('--use-k8s');
|
||||
}
|
||||
return this.executeCommand<void>(argsArray, additionalEnvVars);
|
||||
}
|
||||
},
|
||||
midbarc: {
|
||||
@@ -209,6 +313,19 @@ export class AzTool implements azExt.IAzApi {
|
||||
}
|
||||
};
|
||||
|
||||
public monitor = {
|
||||
logAnalytics: {
|
||||
workspace: {
|
||||
list: (resourceGroup?: string, subscription?: string, additionalEnvVars?: azExt.AdditionalEnvVars): Promise<azExt.AzOutput<azExt.LogAnalyticsWorkspaceListResult[]>> => {
|
||||
const argsArray = ['monitor', 'log-analytics', 'workspace', 'list'];
|
||||
if (resourceGroup) { argsArray.push('--resource-group', resourceGroup); }
|
||||
if (subscription) { argsArray.push('--subscription', subscription); }
|
||||
return this.executeCommand<azExt.LogAnalyticsWorkspaceListResult[]>(argsArray, additionalEnvVars);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the output of running '--version' command on the az tool.
|
||||
@@ -223,6 +340,64 @@ export class AzTool implements azExt.IAzApi {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes az sql mi-arc show and returns a normalized object, SqlMiShowResult, regardless of the indirect or direct mode raw output shape.
|
||||
* @param args The args to pass to az
|
||||
* @param additionalEnvVars Additional environment variables to set for this execution
|
||||
*/
|
||||
public async executeSqlMiShow(args: string[], additionalEnvVars?: azExt.AdditionalEnvVars): Promise<azExt.AzOutput<azExt.SqlMiShowResult>> {
|
||||
try {
|
||||
const result = await executeAzCommand(`"${this._path}"`, args.concat(['--output', 'json']), additionalEnvVars);
|
||||
|
||||
let stdout = <unknown>result.stdout;
|
||||
let stderr = <unknown>result.stderr;
|
||||
|
||||
try {
|
||||
// Automatically try parsing the JSON. This is expected to fail for some az commands such as resource delete.
|
||||
stdout = JSON.parse(result.stdout);
|
||||
} catch (err) {
|
||||
// If the output was not pure JSON, catch the error and log it here.
|
||||
Logger.log(loc.azOutputParseErrorCaught(args.concat(['--output', 'json']).toString()));
|
||||
throw err;
|
||||
}
|
||||
|
||||
if ((<azExt.SqlMiShowResultDirect>stdout).properties) {
|
||||
// Then it is direct mode
|
||||
return {
|
||||
stdout: {
|
||||
name: (<azExt.SqlMiShowResultDirect>stdout).name,
|
||||
spec: (<azExt.SqlMiShowResultDirect>stdout).properties.k8SRaw.spec,
|
||||
status: (<azExt.SqlMiShowResultDirect>stdout).properties.k8SRaw.status
|
||||
},
|
||||
stderr: <string[]>stderr
|
||||
};
|
||||
} else {
|
||||
// It must be indirect mode
|
||||
return {
|
||||
stdout: {
|
||||
name: (<azExt.SqlMiShowResultIndirect>stdout).metadata?.name,
|
||||
spec: (<azExt.SqlMiShowResultIndirect>stdout).spec,
|
||||
status: (<azExt.SqlMiShowResultIndirect>stdout).status
|
||||
},
|
||||
stderr: <string[]>stderr
|
||||
};
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof ExitCodeError) {
|
||||
try {
|
||||
await fs.promises.access(this._path);
|
||||
//this.path exists
|
||||
} catch (e) {
|
||||
// this.path does not exist
|
||||
await vscode.commands.executeCommand('setContext', azFound, false);
|
||||
throw new NoAzureCLIError();
|
||||
}
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executes the specified az command.
|
||||
* @param args The args to pass to az
|
||||
@@ -543,6 +718,70 @@ function parseArcExtensionVersion(raw: string): string | undefined {
|
||||
return exp.exec(raw)?.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses out all available upgrades
|
||||
* @param raw The raw version output from az arcdata dc list-upgrades
|
||||
*/
|
||||
function parseDcListUpgrades(raw: string): string[] | undefined {
|
||||
// Currently the version is a multi-line string that contains other version information such
|
||||
// as the Python installation, with the first line holding the version of az itself.
|
||||
//
|
||||
// Found 6 valid versions. The current datacontroller version is v1.2.0_2021-12-15.
|
||||
// v1.4.1_2022-03-08
|
||||
// v1.4.0_2022-02-25
|
||||
// v1.3.0_2022-01-27
|
||||
// v1.2.0_2021-12-15 << current version
|
||||
// v1.1.0_2021-11-02
|
||||
// v1.0.0_2021-07-30
|
||||
let versions: string[] = [];
|
||||
const lines = raw.split('\n');
|
||||
const exp = /^(v\d*.\d*.\d*.\d*.\d*.\d*.\d)/;
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
let result = exp.exec(lines[i])?.pop();
|
||||
if (result) {
|
||||
versions.push(result);
|
||||
}
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses out the release date from the upgrade version number and formats it into MM/DD/YYYY format.
|
||||
* For example: v1.4.1_2022-03-08 ==> 03/08/2022
|
||||
* @param raw The raw upgrade version number, such as: v1.4.1_2022-03-08
|
||||
*/
|
||||
function parseReleaseDateFromUpgrade(raw: string): string {
|
||||
let formattedDate = '';
|
||||
const exp = /^v\d*.\d*.\d*_(\d*).(\d*).(\d*.\d)/;
|
||||
let rawDate = exp.exec(raw);
|
||||
if (rawDate) {
|
||||
formattedDate += rawDate[2] + '/' + rawDate[3] + '/' + rawDate[1];
|
||||
} else {
|
||||
console.error(loc.releaseDateNotParsed);
|
||||
}
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses out the current version number out of all available upgrades
|
||||
* @param raw The raw version output from az arcdata dc list-upgrades
|
||||
*/
|
||||
function parseCurrentVersion(raw: string): string | undefined {
|
||||
// Currently the version is a multi-line string that contains other version information such
|
||||
// as the Python installation, with the first line holding the version of az itself.
|
||||
//
|
||||
// Found 6 valid versions. The current datacontroller version is v1.2.0_2021-12-15.
|
||||
// v1.4.1_2022-03-08
|
||||
// v1.4.0_2022-02-25
|
||||
// v1.3.0_2022-01-27
|
||||
// v1.2.0_2021-12-15 << current version
|
||||
// v1.1.0_2021-11-02
|
||||
// v1.0.0_2021-07-30
|
||||
|
||||
const exp = /The current datacontroller version is\s*(v\d*.\d*.\d*.\d*.\d*.\d*.\d)/;
|
||||
return exp.exec(raw)?.pop();
|
||||
}
|
||||
|
||||
async function executeAzCommand(command: string, args: string[], additionalEnvVars: azExt.AdditionalEnvVars = {}): Promise<ProcessOutput> {
|
||||
const debug = vscode.workspace.getConfiguration(azConfigSection).get(debugConfigKey);
|
||||
if (debug) {
|
||||
|
||||
@@ -72,3 +72,4 @@ export const userResponseToInstallPrompt = (response: string | undefined): strin
|
||||
export const userResponseToUpdatePrompt = (response: string | undefined): string => localize('az.userResponseUpdate', "User Response on prompt to update Azure CLI: {0}", response);
|
||||
export const userRequestedInstall = localize('az.userRequestedInstall', "User requested to install Azure CLI and arcdata extension using 'Azure CLI: Install' command");
|
||||
export const updateCheckSkipped = localize('az.updateCheckSkipped', "No check for new Azure CLI version availability performed as Azure CLI was not found to be installed");
|
||||
export const releaseDateNotParsed = localize('arc.releaseDateNotParsed', "Release date could not be parsed.");
|
||||
|
||||
@@ -110,15 +110,18 @@ describe('az', function () {
|
||||
describe('sql', function (): void {
|
||||
describe('mi-arc', function (): void {
|
||||
it('delete', async function (): Promise<void> {
|
||||
await azTool.sql.miarc.delete(name, namespace);
|
||||
// Assume indirect mode
|
||||
await azTool.sql.miarc.delete(name, {resourceGroup: undefined, namespace: namespace});
|
||||
verifyExecuteCommandCalledWithArgs(['sql', 'mi-arc', 'delete', name, '--k8s-namespace', namespace, '--use-k8s']);
|
||||
});
|
||||
it('list', async function (): Promise<void> {
|
||||
await azTool.sql.miarc.list(namespace);
|
||||
// Assume indirect mode
|
||||
await azTool.sql.miarc.list({resourceGroup: undefined, namespace: namespace});
|
||||
verifyExecuteCommandCalledWithArgs(['sql', 'mi-arc', 'list', '--k8s-namespace', namespace, '--use-k8s']);
|
||||
});
|
||||
it('show', async function (): Promise<void> {
|
||||
await azTool.sql.miarc.show(name, namespace);
|
||||
// Assume indirect mode
|
||||
await azTool.sql.miarc.show(name, {resourceGroup: undefined, namespace: namespace});
|
||||
verifyExecuteCommandCalledWithArgs(['sql', 'mi-arc', 'show', name, '--k8s-namespace', namespace, '--use-k8s']);
|
||||
});
|
||||
});
|
||||
|
||||
300
extensions/azcli/src/typings/az-ext.d.ts
vendored
300
extensions/azcli/src/typings/az-ext.d.ts
vendored
@@ -116,6 +116,12 @@ declare module 'az-ext' {
|
||||
}
|
||||
}
|
||||
|
||||
export interface DcListUpgradesResult {
|
||||
versions: string[], // ["v1.4.1_2022-03-08", "v1.4.0_2022-02-25"]
|
||||
currentVersion: string, // "v1.4.1_2022-03-08"
|
||||
dates: string[] // ["03/08/2022", "02/25/2022"]
|
||||
}
|
||||
|
||||
export interface StorageVolume {
|
||||
className?: string, // "local-storage"
|
||||
size: string // "5Gi"
|
||||
@@ -132,6 +138,42 @@ declare module 'az-ext' {
|
||||
}
|
||||
|
||||
export interface SqlMiShowResult {
|
||||
name: string, // "miaa-instance"
|
||||
spec: {
|
||||
backup?: {
|
||||
retentionPeriodInDays: number, // 1
|
||||
}
|
||||
scheduling?: {
|
||||
default?: {
|
||||
resources?: {
|
||||
limits?: SchedulingOptions,
|
||||
requests?: SchedulingOptions
|
||||
}
|
||||
}
|
||||
}
|
||||
services: {
|
||||
primary: ServiceSpec
|
||||
}
|
||||
storage: {
|
||||
data: {
|
||||
volumes: StorageVolume[]
|
||||
},
|
||||
logs: {
|
||||
volumes: StorageVolume[]
|
||||
}
|
||||
}
|
||||
},
|
||||
status: {
|
||||
readyReplicas: string, // "1/1"
|
||||
state: string, // "Ready",
|
||||
logSearchDashboard: string, // https://127.0.0.1:30777/kibana/app/kibana#/discover?_a=(query:(language:kuery,query:'custom_resource_name:miaa1'))
|
||||
metricsDashboard: string, // https://127.0.0.1:30777/grafana/d/40q72HnGk/sql-managed-instance-metrics?var-hostname=miaa1-0
|
||||
primaryEndpoint?: string // "10.91.86.39:32718"
|
||||
runningVersion: string // "v1.5.0_2022-04-05"
|
||||
}
|
||||
}
|
||||
|
||||
export interface SqlMiShowResultIndirect {
|
||||
apiVersion: string, // "sql.arcdata.microsoft.com/v1alpha1"
|
||||
kind: string, // "sqlmanagedinstance"
|
||||
metadata: {
|
||||
@@ -173,9 +215,167 @@ declare module 'az-ext' {
|
||||
logSearchDashboard: string, // https://127.0.0.1:30777/kibana/app/kibana#/discover?_a=(query:(language:kuery,query:'custom_resource_name:miaa1'))
|
||||
metricsDashboard: string, // https://127.0.0.1:30777/grafana/d/40q72HnGk/sql-managed-instance-metrics?var-hostname=miaa1-0
|
||||
primaryEndpoint?: string // "10.91.86.39:32718"
|
||||
runningVersion: string // "v1.5.0_2022-04-05"
|
||||
}
|
||||
}
|
||||
|
||||
export interface SqlMiShowResultDirect {
|
||||
extendedLocation: {
|
||||
name: string, // /subscriptions/a2382b66-3h2k-3h2k-2gdd-8ef45dgfdc33/resourcegroups/name-rg/providers/microsoft.extendedlocation/customlocations/custom-loc,
|
||||
type: string, // CustomLocation
|
||||
},
|
||||
id: string, // /subscriptions/a2382b66-3h2k-3h2k-2gdd-8ef45dgfdc33/resourceGroups/name-rg/providers/Microsoft.AzureArcData/sqlManagedInstances/sql1,
|
||||
location: string, // eastus2,
|
||||
name: string, // sql2,
|
||||
properties: {
|
||||
activeDirectoryInformation: string, // null,
|
||||
admin: string, // admin,
|
||||
basicLoginInformation: string, // null,
|
||||
clusterId: string, // null,
|
||||
dataControllerId: string, // dc-name,
|
||||
endTime: string, // null,
|
||||
extensionId: string, // null,
|
||||
k8SRaw: {
|
||||
spec: {
|
||||
backup: {
|
||||
retentionPeriodInDays: number, // 7
|
||||
},
|
||||
dev: boolean, // true,
|
||||
licenseType: string, // BasePrice,
|
||||
metadata: {
|
||||
annotations: string, // ,
|
||||
labels: string, // ,
|
||||
namespace: string, // namespace-name
|
||||
},
|
||||
replicas: number, // 1,
|
||||
scheduling: {
|
||||
additionalProperties: string, // null,
|
||||
default: {
|
||||
additionalProperties: string, // null,
|
||||
resources: {
|
||||
additionalProperties: string, // null,
|
||||
limits: {
|
||||
cpu: string, // 4,
|
||||
memory: string, // 8Gi
|
||||
},
|
||||
requests: {
|
||||
cpu: string, // 2,
|
||||
memory: string, // 4Gi
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
security: {
|
||||
adminLoginSecret: string, // sql-login-secret,
|
||||
serviceCertificateSecret: string, //
|
||||
},
|
||||
services: {
|
||||
primary: {
|
||||
annotations: string, // ,
|
||||
labels: string, // ,
|
||||
type: string, // NodePort
|
||||
}
|
||||
},
|
||||
settings: {
|
||||
collation: string, // SQL_Latin1_General_CP1_CI_AS,
|
||||
language: {
|
||||
lcid: number, // 1234
|
||||
},
|
||||
sqlagent: {
|
||||
enabled: boolean, // false
|
||||
},
|
||||
timezone: string, // UTC,
|
||||
traceFlags: boolean, // false
|
||||
},
|
||||
storage: {
|
||||
backups: {
|
||||
volumes: [
|
||||
{
|
||||
annotations: string, // ,
|
||||
className: string, // azurefile,
|
||||
labels: string, // ,
|
||||
size: string, // 5Gi
|
||||
}
|
||||
]
|
||||
},
|
||||
data: {
|
||||
volumes: [
|
||||
{
|
||||
annotations: string, // ,
|
||||
className: string, // default,
|
||||
labels: string, // ,
|
||||
size: string, // 5Gi
|
||||
}
|
||||
]
|
||||
},
|
||||
datalogs: {
|
||||
volumes: [
|
||||
{
|
||||
annotations: string, // ,
|
||||
className: string, // default,
|
||||
labels: string, // ,
|
||||
size: string, // 5Gi
|
||||
}
|
||||
]
|
||||
},
|
||||
logs: {
|
||||
volumes: [
|
||||
{
|
||||
annotations: string, // ,
|
||||
className: string, // default,
|
||||
labels: string, // ,
|
||||
size: string, // 5Gi
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
tier: string, // GeneralPurpose
|
||||
},
|
||||
status: {
|
||||
endpoints: {
|
||||
logSearchDashboard: string, // https://localhost:12345/app/kibana#/discover?_a=(query:(language:kuery,query:'custom_resource_name:sql1')),
|
||||
metricsDashboard: string, // https://12.123.1.4:12345/d/sdfgwseg/sql-managed-instance-metrics?var-hostname=sql1-0,
|
||||
mirroring: string, // 10.224.0.4:32040,
|
||||
primary: string, // 10.224.0.4,32477
|
||||
},
|
||||
highAvailability: {
|
||||
lastUpdateTime: string, // 2022-05-09T23:40:19.626856Z,
|
||||
mirroringCertificate: string,
|
||||
},
|
||||
lastUpdateTime: string, // 2022-05-09T23:41:00.137919Z,
|
||||
logSearchDashboard: string,
|
||||
metricsDashboard: string,
|
||||
observedGeneration: number, // 1,
|
||||
primaryEndpoint: string, // 10.224.0.4,32477,
|
||||
readyReplicas: string, // 1/1,
|
||||
roles: {
|
||||
sql: {
|
||||
lastUpdateTime: string, // 2022-05-09T23:39:53.364002Z,
|
||||
readyReplicas: number, // 1,
|
||||
replicas: number, // 1
|
||||
}
|
||||
},
|
||||
runningVersion: string, // v1.4.0_2022-02-25,
|
||||
state: string, // Ready
|
||||
}
|
||||
},
|
||||
lastUploadedDate: string, // null,
|
||||
licenseType: string, // BasePrice,
|
||||
provisioningState: string, // Succeeded,
|
||||
startTime: string, // null
|
||||
},
|
||||
resourceGroup: string, // rg-name,
|
||||
sku: {
|
||||
capacity: string, // null,
|
||||
dev: string, // null,
|
||||
family: string, // null,
|
||||
size: string, // null,
|
||||
tier: string, // GeneralPurpose
|
||||
},
|
||||
tags: {},
|
||||
type: string, // microsoft.azurearcdata/sqlmanagedinstances
|
||||
}
|
||||
|
||||
export interface SqlMiDbRestoreResult {
|
||||
destDatabase: string, //testDbToRestore
|
||||
earliestRestoreTime: string, // "2020-08-19T20:25:11Z"
|
||||
@@ -187,6 +387,45 @@ declare module 'az-ext' {
|
||||
state: string //Completed
|
||||
}
|
||||
|
||||
export interface LogAnalyticsWorkspaceListResult {
|
||||
createdDate: string, // "2020-02-25T16:59:38Z"
|
||||
customerId: string, // "7e136a79-c0b6-4878-86bf-7bf7a6a7e6f6",
|
||||
eTag: string, // null,
|
||||
etag: string, // "\"00006df1-0000-0700-0000-61ee552f0000\"",
|
||||
features: {
|
||||
clusterResourceId: string, // null,
|
||||
disableLocalAuth: boolean, // null,
|
||||
enableDataExport: boolean, // null,
|
||||
enableLogAccessUsingOnlyResourcePermissions: boolean, //true,
|
||||
immediatePurgeDataOn30Days: boolean, // null,
|
||||
legacy: number, // 0,
|
||||
searchVersion: number // 1
|
||||
},
|
||||
forceCmkForQuery: boolean, // null,
|
||||
id: string, // "/subscriptions/a5082b19-8a6e-4bc5-8fdd-8ef39dfebc39/resourcegroups/bugbash/providers/microsoft.operationalinsights/workspaces/bugbash-logs",
|
||||
location: string, // "westus",
|
||||
modifiedDate: string, // "2022-02-21T09:18:22.3906451Z",
|
||||
name: string, // "bugbash-logs",
|
||||
privateLinkScopedResources: string, // null,
|
||||
provisioningState: string, // "Succeeded",
|
||||
publicNetworkAccessForIngestion: string, // "Enabled",
|
||||
publicNetworkAccessForQuery: string, // "Enabled",
|
||||
resourceGroup: string, // "bugbash",
|
||||
retentionInDays: number, // 30,
|
||||
sku: {
|
||||
capacityReservationLevel: number, // null,
|
||||
lastSkuUpdate: string, // "2020-02-25T16:59:38Z",
|
||||
name: string, // "pergb2018"
|
||||
},
|
||||
tags: string[], //null,
|
||||
type: string, //"Microsoft.OperationalInsights/workspaces",
|
||||
workspaceCapping: {
|
||||
dailyQuotaGb: number, //-1.0,
|
||||
dataIngestionStatus: string, // "RespectQuota",
|
||||
quotaNextResetTime: string, // "2022-02-21T19:00:00Z"
|
||||
}
|
||||
}
|
||||
|
||||
export interface PostgresServerShowResult {
|
||||
apiVersion: string, // "arcdata.microsoft.com/v1alpha1"
|
||||
kind: string, // "postgresql"
|
||||
@@ -293,7 +532,9 @@ declare module 'az-ext' {
|
||||
config: {
|
||||
list(additionalEnvVars?: AdditionalEnvVars): Promise<AzOutput<DcConfigListResult[]>>,
|
||||
show(namespace?: string, additionalEnvVars?: AdditionalEnvVars): Promise<AzOutput<DcConfigShowResult>>
|
||||
}
|
||||
},
|
||||
listUpgrades(namespace: string, usek8s?: boolean, additionalEnvVars?: AdditionalEnvVars): Promise<AzOutput<DcListUpgradesResult>>,
|
||||
upgrade(desiredVersion: string, name: string, resourceGroup?: string, namespace?: string, additionalEnvVars?: AdditionalEnvVars): Promise<AzOutput<void>>,
|
||||
}
|
||||
},
|
||||
postgres: {
|
||||
@@ -325,9 +566,38 @@ declare module 'az-ext' {
|
||||
},
|
||||
sql: {
|
||||
miarc: {
|
||||
delete(name: string, namespace?: string, additionalEnvVars?: AdditionalEnvVars): Promise<AzOutput<void>>,
|
||||
list(namespace?: string, additionalEnvVars?: AdditionalEnvVars): Promise<AzOutput<SqlMiListResult[]>>,
|
||||
show(name: string, namespace?: string, additionalEnvVars?: AdditionalEnvVars): Promise<AzOutput<SqlMiShowResult>>,
|
||||
delete(
|
||||
name: string,
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string,
|
||||
// Indirect mode arguments
|
||||
namespace?: string
|
||||
},
|
||||
// Additional arguments
|
||||
additionalEnvVars?: AdditionalEnvVars
|
||||
): Promise<AzOutput<void>>,
|
||||
list(
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string,
|
||||
// Indirect mode arguments
|
||||
namespace?: string
|
||||
},
|
||||
// Additional arguments
|
||||
additionalEnvVars?: AdditionalEnvVars
|
||||
): Promise<AzOutput<SqlMiListResult[]>>,
|
||||
show(
|
||||
name: string,
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string,
|
||||
// Indirect mode arguments
|
||||
namespace?: string
|
||||
},
|
||||
// Additional arguments
|
||||
additionalEnvVars?: AdditionalEnvVars
|
||||
): Promise<AzOutput<SqlMiShowResult>>,
|
||||
update(
|
||||
name: string,
|
||||
args: {
|
||||
@@ -345,6 +615,17 @@ declare module 'az-ext' {
|
||||
usek8s?: boolean,
|
||||
// Additional arguments
|
||||
additionalEnvVars?: AdditionalEnvVars
|
||||
): Promise<AzOutput<void>>,
|
||||
upgrade(
|
||||
name: string,
|
||||
args: {
|
||||
// Direct mode arguments
|
||||
resourceGroup?: string,
|
||||
// Indirect mode arguments
|
||||
namespace?: string
|
||||
},
|
||||
// Additional arguments
|
||||
additionalEnvVars?: AdditionalEnvVars
|
||||
): Promise<AzOutput<void>>
|
||||
},
|
||||
midbarc: {
|
||||
@@ -362,6 +643,17 @@ declare module 'az-ext' {
|
||||
): Promise<AzOutput<SqlMiDbRestoreResult>>
|
||||
}
|
||||
},
|
||||
monitor: {
|
||||
logAnalytics: {
|
||||
workspace: {
|
||||
list(
|
||||
resourceGroup?: string, // test-rg
|
||||
subscription?: string, // 122c121a-095a-4f5d-22e4-cc6b238490a3
|
||||
additionalEnvVars?: AdditionalEnvVars
|
||||
): Promise<AzOutput<LogAnalyticsWorkspaceListResult[]>>
|
||||
}
|
||||
}
|
||||
},
|
||||
getPath(): Promise<string>,
|
||||
/**
|
||||
* The semVersion corresponding to this installation of the Azure CLI. version() method should have been run
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,8 @@
|
||||
{
|
||||
"ignoreVoid": true
|
||||
}
|
||||
]
|
||||
],
|
||||
// Disabled until the issues can be fixed
|
||||
"@typescript-eslint/explicit-function-return-type": ["off"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,26 +348,26 @@
|
||||
"@azure/arm-resourcegraph": "^4.0.0",
|
||||
"@azure/arm-subscriptions": "^3.0.0",
|
||||
"@azure/storage-blob": "^12.6.0",
|
||||
"axios": "^0.21.4",
|
||||
"axios": "^0.27.2",
|
||||
"node-fetch": "^2.6.7",
|
||||
"qs": "^6.9.1",
|
||||
"vscode-nls": "^4.0.0",
|
||||
"ws": "^7.2.0"
|
||||
"ws": "^7.4.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/keytar": "4.4.0",
|
||||
"@types/mocha": "^5.2.5",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^12.11.7",
|
||||
"@types/qs": "^6.9.1",
|
||||
"@types/request": "^2.48.1",
|
||||
"@types/sinon": "^9.0.4",
|
||||
"@types/ws": "^6.0.4",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha": "^7.1.1",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"should": "^13.2.1",
|
||||
"sinon": "^9.0.2",
|
||||
"typemoq": "^2.1.0",
|
||||
"@microsoft/vscodetestcover": "^1.2.0"
|
||||
"@microsoft/vscodetestcover": "^1.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="28" width="28" version="1.1" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<path fill="#0072C6" d="M11.423,44.326l23.623-4.156L22.894,25.748l6.328-17.346L50,44.33L11.423,44.326z M27.566,5.67L11.469,40.109v-0.034H0l12.717-21.975L27.566,5.67z" />
|
||||
</g>
|
||||
|
||||
<svg width="150" height="150" viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="e399c19f-b68f-429d-b176-18c2117ff73c" x1="-1032.172" x2="-1059.213" y1="145.312" y2="65.426" gradientTransform="matrix(1 0 0 -1 1075 158)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#114a8b"/>
|
||||
<stop offset="1" stop-color="#0669bc"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="ac2a6fc2-ca48-4327-9a3c-d4dcc3256e15" x1="-1023.725" x2="-1029.98" y1="108.083" y2="105.968" gradientTransform="matrix(1 0 0 -1 1075 158)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-opacity=".3"/>
|
||||
<stop offset=".071" stop-opacity=".2"/>
|
||||
<stop offset=".321" stop-opacity=".1"/>
|
||||
<stop offset=".623" stop-opacity=".05"/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="a7fee970-a784-4bb1-af8d-63d18e5f7db9" x1="-1027.165" x2="-997.482" y1="147.642" y2="68.561" gradientTransform="matrix(1 0 0 -1 1075 158)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#3ccbf4"/>
|
||||
<stop offset="1" stop-color="#2892df"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path fill="url(#e399c19f-b68f-429d-b176-18c2117ff73c)" d="M33.338 6.544h26.038l-27.03 80.087a4.152 4.152 0 0 1-3.933 2.824H8.149a4.145 4.145 0 0 1-3.928-5.47L29.404 9.368a4.152 4.152 0 0 1 3.934-2.825z"/>
|
||||
<path fill="#0078d4" d="M71.175 60.261h-41.29a1.911 1.911 0 0 0-1.305 3.309l26.532 24.764a4.171 4.171 0 0 0 2.846 1.121h23.38z"/>
|
||||
<path fill="url(#ac2a6fc2-ca48-4327-9a3c-d4dcc3256e15)" d="M33.338 6.544a4.118 4.118 0 0 0-3.943 2.879L4.252 83.917a4.14 4.14 0 0 0 3.908 5.538h20.787a4.443 4.443 0 0 0 3.41-2.9l5.014-14.777 17.91 16.705a4.237 4.237 0 0 0 2.666.972H81.24L71.024 60.261l-29.781.007L59.47 6.544z"/>
|
||||
<path fill="url(#a7fee970-a784-4bb1-af8d-63d18e5f7db9)" d="M66.595 9.364a4.145 4.145 0 0 0-3.928-2.82H33.648a4.146 4.146 0 0 1 3.928 2.82l25.184 74.62a4.146 4.146 0 0 1-3.928 5.472h29.02a4.146 4.146 0 0 0 3.927-5.472z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 331 B After Width: | Height: | Size: 2.1 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user