mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-05 09:04:56 +00:00
Compare commits
605 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52f01a71d2 | ||
|
|
ab6774bef9 | ||
|
|
7930671a51 | ||
|
|
3acd546337 | ||
|
|
3bcf30348a | ||
|
|
74909d4fd5 | ||
|
|
691eb3cb2d | ||
|
|
6ddc56632e | ||
|
|
5c183c8353 | ||
|
|
5e62fec49c | ||
|
|
8f590ff360 | ||
|
|
24bb109ec3 | ||
|
|
efdf6c2b81 | ||
|
|
b40051e4a4 | ||
|
|
02506bcda4 | ||
|
|
58dc0f2b2f | ||
|
|
5a648baff4 | ||
|
|
5ec3279910 | ||
|
|
e29db64e7f | ||
|
|
f8ec1ff6d7 | ||
|
|
e1a62c1f03 | ||
|
|
27fa5654af | ||
|
|
0a7852b1eb | ||
|
|
0ca9f2cc6d | ||
|
|
4750e2535f | ||
|
|
9ff483cd4e | ||
|
|
c38dd1cc5e | ||
|
|
735d91a003 | ||
|
|
02946a0f4f | ||
|
|
22aa7ff25f | ||
|
|
912cd7fb8b | ||
|
|
559d9bb9a8 | ||
|
|
944f4ee895 | ||
|
|
94d518e09a | ||
|
|
b9dff62f1f | ||
|
|
1bc8d6a0b8 | ||
|
|
04ade02254 | ||
|
|
655b6d5399 | ||
|
|
9df1eac0b8 | ||
|
|
e58b21c599 | ||
|
|
c1e53b90a2 | ||
|
|
1fecb22627 | ||
|
|
770bde8088 | ||
|
|
bb7ed6869e | ||
|
|
ac55ae467c | ||
|
|
626e9f96e9 | ||
|
|
0efcaa1b6b | ||
|
|
8a1f022c49 | ||
|
|
7faa909ab1 | ||
|
|
c9a7744270 | ||
|
|
2c9c4c2cd3 | ||
|
|
b0bb925ef6 | ||
|
|
272835cfba | ||
|
|
0c66780fda | ||
|
|
74e6fd8d4a | ||
|
|
6815110727 | ||
|
|
7bda0f87e6 | ||
|
|
38521dc8b2 | ||
|
|
1effd9b22e | ||
|
|
d7a7c6aa50 | ||
|
|
4de1baf2eb | ||
|
|
d66f7da3c0 | ||
|
|
9b948613dc | ||
|
|
77200ed8fc | ||
|
|
d42c53c3da | ||
|
|
28316861e3 | ||
|
|
9bc42c7eca | ||
|
|
994a5d9b54 | ||
|
|
0ddbe89d88 | ||
|
|
fdffac6911 | ||
|
|
72466d0768 | ||
|
|
4a982b3bcf | ||
|
|
348c56ba30 | ||
|
|
83d92af07d | ||
|
|
b4397eb64f | ||
|
|
2ae7bea5b1 | ||
|
|
1908d1a213 | ||
|
|
e6530f5017 | ||
|
|
9ef492f5f8 | ||
|
|
a41d9c0ac2 | ||
|
|
d4dd352ebe | ||
|
|
c23d31f912 | ||
|
|
94b5563a0e | ||
|
|
446d2d3370 | ||
|
|
c8492d2014 | ||
|
|
1a223a99d1 | ||
|
|
b8a2438679 | ||
|
|
f38978e7c9 | ||
|
|
44dbe39001 | ||
|
|
424580971e | ||
|
|
6d552ce85e | ||
|
|
031dd6d4ea | ||
|
|
d2503d46eb | ||
|
|
1d701b9a8e | ||
|
|
29c3744c53 | ||
|
|
794f19637d | ||
|
|
822c01c360 | ||
|
|
76da19bac6 | ||
|
|
c53638c08d | ||
|
|
aa31043871 | ||
|
|
e2d6d5548f | ||
|
|
8f1bfa46a9 | ||
|
|
0a607e0450 | ||
|
|
e41abe4cfe | ||
|
|
5a846755a8 | ||
|
|
e99891f22d | ||
|
|
eaf7965e79 | ||
|
|
1d2b4c6057 | ||
|
|
e609ab201f | ||
|
|
43e996355a | ||
|
|
d41c7fb899 | ||
|
|
093851ec0c | ||
|
|
c5f5e606b0 | ||
|
|
b45c8b582e | ||
|
|
d94ad8caac | ||
|
|
8dfc95d002 | ||
|
|
466b1bb173 | ||
|
|
1a93429ffa | ||
|
|
e5f150f093 | ||
|
|
e6d709a8a0 | ||
|
|
708e361264 | ||
|
|
34ad5cdaef | ||
|
|
65c6479ee4 | ||
|
|
394d535906 | ||
|
|
70cf3176b7 | ||
|
|
c11fe97b47 | ||
|
|
d5926fce8c | ||
|
|
9ba6539b5b | ||
|
|
8ae091b8c3 | ||
|
|
d04585f630 | ||
|
|
dedb4ba833 | ||
|
|
1887a36ca5 | ||
|
|
4787fef74a | ||
|
|
5be4873d36 | ||
|
|
0e342999fd | ||
|
|
f16f02b6b0 | ||
|
|
3a3053fb49 | ||
|
|
425439ec42 | ||
|
|
2a4a2db6f6 | ||
|
|
562013e3bd | ||
|
|
1f7c1ef91e | ||
|
|
1a80c95ae3 | ||
|
|
bbb97d06da | ||
|
|
20ce8c0cd5 | ||
|
|
940bf15ac4 | ||
|
|
5fe8fae6ae | ||
|
|
826281453f | ||
|
|
979ef24c39 | ||
|
|
fad07b2cab | ||
|
|
e147487d9c | ||
|
|
1e15ae5766 | ||
|
|
5d5110126e | ||
|
|
b467ab1d76 | ||
|
|
635ec0a401 | ||
|
|
578f92e376 | ||
|
|
00604bd4b0 | ||
|
|
8f09df655c | ||
|
|
fbc196e828 | ||
|
|
d120f3ada8 | ||
|
|
d24009f494 | ||
|
|
721e5e4dd9 | ||
|
|
612fbb4f97 | ||
|
|
bba27fb02e | ||
|
|
92e5b3d937 | ||
|
|
014566fcc9 | ||
|
|
3fbeefe329 | ||
|
|
ce09a7c09f | ||
|
|
4757a95528 | ||
|
|
5e4cd0f81d | ||
|
|
536bf01dd9 | ||
|
|
99a60c37d0 | ||
|
|
bfe6f0b4dd | ||
|
|
aac0d24aed | ||
|
|
c60648ce9b | ||
|
|
48e33e2d73 | ||
|
|
3236a91d0b | ||
|
|
d790ead446 | ||
|
|
12ed9db207 | ||
|
|
5a4bb70869 | ||
|
|
de52651c7f | ||
|
|
ce45c15d13 | ||
|
|
e65cae121e | ||
|
|
51b6f5a105 | ||
|
|
bfbb7e9e6b | ||
|
|
03dea53b30 | ||
|
|
0bdecc776d | ||
|
|
b4389b7380 | ||
|
|
d796fc2ab0 | ||
|
|
a8dc00b406 | ||
|
|
76039d8d3e | ||
|
|
b6b5b58889 | ||
|
|
6f5f0ab986 | ||
|
|
f7b07f4216 | ||
|
|
df7f782e05 | ||
|
|
3fb30a6cce | ||
|
|
2c5fa4f008 | ||
|
|
4433a72b96 | ||
|
|
1853dd9895 | ||
|
|
d98586773c | ||
|
|
bf30185c65 | ||
|
|
09e38e4a91 | ||
|
|
97f41ab620 | ||
|
|
0cbeff6f61 | ||
|
|
f3ed31b4b7 | ||
|
|
020f86bcc1 | ||
|
|
997cf3bd92 | ||
|
|
af399adf14 | ||
|
|
255e53673e | ||
|
|
3ba1b3fc61 | ||
|
|
135eb07f9e | ||
|
|
3362069ae8 | ||
|
|
fe7400abe1 | ||
|
|
4cca8a16ab | ||
|
|
5a3e5a1565 | ||
|
|
87063d20ce | ||
|
|
7b6728e8a9 | ||
|
|
1bff46d5f0 | ||
|
|
81bac496b4 | ||
|
|
b31aa44d40 | ||
|
|
bff8ca6178 | ||
|
|
be33cfd174 | ||
|
|
0eb11d14ad | ||
|
|
b0d8c8e14f | ||
|
|
72378abe56 | ||
|
|
fc36aac0fb | ||
|
|
e7f4d82881 | ||
|
|
2dd62f7603 | ||
|
|
79b3b1dabc | ||
|
|
fd0aa4a2ee | ||
|
|
da57fbeadd | ||
|
|
3f12e4925f | ||
|
|
21cb05a30c | ||
|
|
7a8ff2c489 | ||
|
|
d108434881 | ||
|
|
20fd9b6574 | ||
|
|
26ac56e163 | ||
|
|
78b74d5b15 | ||
|
|
1556167262 | ||
|
|
5186710f84 | ||
|
|
c7f25e8fe3 | ||
|
|
ab703fe3ae | ||
|
|
5275ff5493 | ||
|
|
4fad21fe5c | ||
|
|
eec2074b88 | ||
|
|
dd58b1bbf6 | ||
|
|
05452bb297 | ||
|
|
4307e1eb6b | ||
|
|
10c7f93a85 | ||
|
|
adca2a7225 | ||
|
|
eb3f160a64 | ||
|
|
53488a1498 | ||
|
|
d46b6c4863 | ||
|
|
e3ffd04804 | ||
|
|
bddcfe1b8b | ||
|
|
f18d07a4a2 | ||
|
|
44166f7256 | ||
|
|
8e82d1e02c | ||
|
|
002e64c819 | ||
|
|
773d92760e | ||
|
|
84c8828e8c | ||
|
|
fb6de18b2f | ||
|
|
d525bd9113 | ||
|
|
d8bb51a222 | ||
|
|
da4d89275f | ||
|
|
9bf5ea3e56 | ||
|
|
7fcc5e599e | ||
|
|
aa86d3a2ee | ||
|
|
9a90ce694c | ||
|
|
9b3fa43b81 | ||
|
|
2698e7fd0d | ||
|
|
58fd3857c0 | ||
|
|
3755661ff6 | ||
|
|
c649995a7a | ||
|
|
448d3731e5 | ||
|
|
019a2f57cb | ||
|
|
6f9bb024be | ||
|
|
707d585698 | ||
|
|
b73c75182f | ||
|
|
775d6212d3 | ||
|
|
357ff9853d | ||
|
|
cd7892b7ed | ||
|
|
9512964366 | ||
|
|
5473a12c0e | ||
|
|
c249cdf76a | ||
|
|
0e01094ffd | ||
|
|
c68220166a | ||
|
|
deeafb3a12 | ||
|
|
4d44542ca6 | ||
|
|
f83c92cb87 | ||
|
|
03c0b6b364 | ||
|
|
c5eb16139f | ||
|
|
bfb9e9b5c5 | ||
|
|
af4de0b14f | ||
|
|
0553ca3c02 | ||
|
|
9422b93857 | ||
|
|
951f5540a3 | ||
|
|
2b9929222c | ||
|
|
b1c64a5f7e | ||
|
|
5164c8c1f9 | ||
|
|
18fad62f5c | ||
|
|
7eaff644e3 | ||
|
|
9fd4818d81 | ||
|
|
d144c9f6f5 | ||
|
|
a6752bb49c | ||
|
|
ae7da1b018 | ||
|
|
3819342ff2 | ||
|
|
3058c56394 | ||
|
|
afad85f4a4 | ||
|
|
557a7c3360 | ||
|
|
44580f6af0 | ||
|
|
5d75ceeeb5 | ||
|
|
8d5330df74 | ||
|
|
761965240d | ||
|
|
ad32ed5dd5 | ||
|
|
6a4f70cf43 | ||
|
|
3996955e3b | ||
|
|
1c8f1a05d0 | ||
|
|
bbac03107e | ||
|
|
32f064c2de | ||
|
|
39704bc812 | ||
|
|
a421265483 | ||
|
|
e6214cb6ec | ||
|
|
ba7d34bce5 | ||
|
|
ace3c37fcc | ||
|
|
5ba2dff008 | ||
|
|
dff8a0db7d | ||
|
|
ccda45bdd2 | ||
|
|
eeb536d460 | ||
|
|
1e6e0336c3 | ||
|
|
f2ac2e5b84 | ||
|
|
af6f431c15 | ||
|
|
01ae21e1fa | ||
|
|
34141958eb | ||
|
|
c194cff0bd | ||
|
|
6b6f2d6910 | ||
|
|
2e975e79dd | ||
|
|
c5a295a87b | ||
|
|
119b4cdf10 | ||
|
|
bf6af934f6 | ||
|
|
1971749449 | ||
|
|
b383ce36cd | ||
|
|
fc9a9f479b | ||
|
|
227174db1b | ||
|
|
9f129075dd | ||
|
|
935b4f847c | ||
|
|
ec99a0ce05 | ||
|
|
7ba5f82aef | ||
|
|
546d5764e6 | ||
|
|
6f411bd459 | ||
|
|
29d8f61c90 | ||
|
|
bedf838fe5 | ||
|
|
fda89b05e7 | ||
|
|
de8af5f114 | ||
|
|
14db45ae95 | ||
|
|
27b14af388 | ||
|
|
18dc427bc3 | ||
|
|
1ad2e629ac | ||
|
|
05288be934 | ||
|
|
05b73a59be | ||
|
|
f3fd5ff76b | ||
|
|
4958d096b0 | ||
|
|
7f2006488e | ||
|
|
008a05a470 | ||
|
|
3d7721d59d | ||
|
|
35fb10c95b | ||
|
|
c4c4ec6a67 | ||
|
|
f4be15baec | ||
|
|
17b40b68df | ||
|
|
cd5c4b5cb7 | ||
|
|
d28c887237 | ||
|
|
541011ba90 | ||
|
|
fc658f4a95 | ||
|
|
84f68fc2c0 | ||
|
|
f78760cb83 | ||
|
|
8f6db00402 | ||
|
|
d00d0bd951 | ||
|
|
8f5cd13e78 | ||
|
|
3b4cfc642f | ||
|
|
5807f34935 | ||
|
|
efae4cccd6 | ||
|
|
b461a684ad | ||
|
|
b95808a052 | ||
|
|
1716e7a397 | ||
|
|
acda594cba | ||
|
|
94d20f1bdc | ||
|
|
f9079bb681 | ||
|
|
0d07ff2390 | ||
|
|
42bab6990e | ||
|
|
89a566a645 | ||
|
|
7af5bd3894 | ||
|
|
a57c27679d | ||
|
|
68a72b2dfc | ||
|
|
602f795133 | ||
|
|
5df89a925b | ||
|
|
23126e1ff6 | ||
|
|
e1f715f837 | ||
|
|
fbcaed40e7 | ||
|
|
88757ce488 | ||
|
|
fc9462eee9 | ||
|
|
e1314730be | ||
|
|
36978dbed6 | ||
|
|
53d1991211 | ||
|
|
1ea445ab15 | ||
|
|
78410f531a | ||
|
|
96c0321696 | ||
|
|
0895f1fb30 | ||
|
|
b6188f4b11 | ||
|
|
2ed1a7b219 | ||
|
|
9bee6bd5cc | ||
|
|
198f30c86d | ||
|
|
454f1887cf | ||
|
|
4e1e4e9435 | ||
|
|
f7768563e1 | ||
|
|
6aa0e71b84 | ||
|
|
f1b3a10969 | ||
|
|
90e70ed986 | ||
|
|
094a479c2a | ||
|
|
20f1d487c8 | ||
|
|
4c9bda1406 | ||
|
|
d5debc0bf5 | ||
|
|
f5aee7c360 | ||
|
|
248cd9a8ab | ||
|
|
06abb702f5 | ||
|
|
ee289706ec | ||
|
|
6cbf310a5a | ||
|
|
855fd8a73a | ||
|
|
8dbd354659 | ||
|
|
1c7ae04f4f | ||
|
|
0bb6e362bf | ||
|
|
617350fc7d | ||
|
|
2713340532 | ||
|
|
31d552ab7e | ||
|
|
e11326f05f | ||
|
|
6648fe4dcc | ||
|
|
f669164674 | ||
|
|
c6d8904ca2 | ||
|
|
8c5a1e2de3 | ||
|
|
395414c336 | ||
|
|
96f653ea19 | ||
|
|
fa089de40d | ||
|
|
4175f5391e | ||
|
|
61c417992a | ||
|
|
befae6bc9b | ||
|
|
e7eb13e966 | ||
|
|
88eaaf9ce4 | ||
|
|
20cc082a02 | ||
|
|
402d12a0e1 | ||
|
|
58ba11e13c | ||
|
|
cb6ca52b03 | ||
|
|
cd2ab73e5d | ||
|
|
b16e725514 | ||
|
|
004fcc8e80 | ||
|
|
a01a3ef011 | ||
|
|
20cf45270d | ||
|
|
f3ac12254c | ||
|
|
e0eb216b9b | ||
|
|
90afed1e74 | ||
|
|
83d2ed8ace | ||
|
|
a0b64ca3e3 | ||
|
|
b9fc5ad769 | ||
|
|
ef1a44a413 | ||
|
|
798dc49da4 | ||
|
|
902081d44e | ||
|
|
7969b73979 | ||
|
|
c8734bd6ee | ||
|
|
6d3c273ffd | ||
|
|
f4b3830a0e | ||
|
|
36534f1915 | ||
|
|
7dcbe64d4e | ||
|
|
60057c666d | ||
|
|
60a83f4907 | ||
|
|
b11ce2c8d2 | ||
|
|
3b8f2c1ac3 | ||
|
|
be065e2de3 | ||
|
|
675c737e48 | ||
|
|
1255384cab | ||
|
|
3d423c3299 | ||
|
|
ad4737850d | ||
|
|
9dcacd413c | ||
|
|
c1998eddf3 | ||
|
|
db3f63e8f2 | ||
|
|
e562ca1011 | ||
|
|
f6adf93f90 | ||
|
|
053eba5d98 | ||
|
|
49f1ba676f | ||
|
|
48c109e149 | ||
|
|
259d7988d9 | ||
|
|
0a49258ddd | ||
|
|
fd35d3427e | ||
|
|
ef0a20b358 | ||
|
|
f01997f8ee | ||
|
|
281a068cfb | ||
|
|
fe5be0cb47 | ||
|
|
8aab1d6459 | ||
|
|
2eaaeef4a7 | ||
|
|
5fbfabb3b2 | ||
|
|
ec64260b6a | ||
|
|
2e23a4830b | ||
|
|
41a3d6f62f | ||
|
|
752bc9ca0e | ||
|
|
c08f6fdba4 | ||
|
|
b23b7e896b | ||
|
|
d68b421a4b | ||
|
|
1f510799e2 | ||
|
|
66ea97c7c9 | ||
|
|
ee300e7b60 | ||
|
|
ef2d135e9b | ||
|
|
c82fb89d57 | ||
|
|
725bf63a32 | ||
|
|
c1ca578f7d | ||
|
|
530dd5ff7f | ||
|
|
11370bc07e | ||
|
|
1c53daf1c4 | ||
|
|
b2556db33b | ||
|
|
89310c9b97 | ||
|
|
8e09af910f | ||
|
|
885aea3425 | ||
|
|
a616150f2d | ||
|
|
d80dae8a89 | ||
|
|
34ff08b92b | ||
|
|
2f7b51d7ff | ||
|
|
b7cee3185e | ||
|
|
1c5455e6ed | ||
|
|
2d303fd5d3 | ||
|
|
fbe2543c03 | ||
|
|
d6b640726e | ||
|
|
f875b37641 | ||
|
|
53c4fc6dfa | ||
|
|
6c310249d9 | ||
|
|
02e1f528bf | ||
|
|
c870104370 | ||
|
|
627d8ef787 | ||
|
|
5563823a7a | ||
|
|
d6804bb0fd | ||
|
|
1350633690 | ||
|
|
50196d8fde | ||
|
|
2e0ccb53ec | ||
|
|
1498ee405b | ||
|
|
cb863c4afa | ||
|
|
2629d39501 | ||
|
|
38305cd984 | ||
|
|
93116c24f2 | ||
|
|
017b9c8615 | ||
|
|
9ce3a96862 | ||
|
|
a0ff520ba4 | ||
|
|
a8b8986d89 | ||
|
|
8ffc096fee | ||
|
|
7e457f7b4c | ||
|
|
aedf2d339e | ||
|
|
ffd5ae52b3 | ||
|
|
3093194da8 | ||
|
|
68b4f792f0 | ||
|
|
e2c6e4f9fc | ||
|
|
9ff7dbffb7 | ||
|
|
0c561da061 | ||
|
|
06951319a6 | ||
|
|
0bfcab4067 | ||
|
|
2c4db4fa16 | ||
|
|
23b4f9ee12 | ||
|
|
e5330b1917 | ||
|
|
183611a556 | ||
|
|
7786456ba4 | ||
|
|
f4bf7e3ddf | ||
|
|
05d88215d1 | ||
|
|
b240a70e51 | ||
|
|
00fd468e9b | ||
|
|
b5a7f8b7eb | ||
|
|
f03277fd17 | ||
|
|
ee93071149 | ||
|
|
21fdced2bd | ||
|
|
10b4558947 | ||
|
|
0fbed5d9d6 | ||
|
|
8d117123d7 | ||
|
|
063ffda09d | ||
|
|
39c83bd25b | ||
|
|
4444c3d1a6 | ||
|
|
717dd93f37 | ||
|
|
c58673c55f | ||
|
|
768e55072d | ||
|
|
8c84daec2b | ||
|
|
e54a5b6128 | ||
|
|
ee1e50f391 | ||
|
|
268636c440 | ||
|
|
06fa0cdb60 | ||
|
|
73dbb39009 | ||
|
|
47848cb5da | ||
|
|
eff6a03a51 | ||
|
|
08f6a41ef4 | ||
|
|
6d1345ffe5 | ||
|
|
689f615b11 | ||
|
|
f82ea5d9c4 | ||
|
|
dc4979a80c | ||
|
|
1f48bc4301 | ||
|
|
beabd1e050 | ||
|
|
19e20a6a20 | ||
|
|
e4f13ddae4 | ||
|
|
752d0545ca | ||
|
|
08341d3d6c | ||
|
|
ef665df330 | ||
|
|
b38017cd23 | ||
|
|
0c550a2827 | ||
|
|
87ffdad862 | ||
|
|
c6e8024e16 | ||
|
|
4200b3c3e5 | ||
|
|
10976a9257 |
20
.codesandbox/task.json
Normal file
20
.codesandbox/task.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "https://codesandbox.io/schemas/tasks.json",
|
||||
"setupTasks": [
|
||||
{
|
||||
"name": "Install Dependencies",
|
||||
"command": "yarn install"
|
||||
}
|
||||
],
|
||||
|
||||
"tasks": {
|
||||
"start-web": {
|
||||
"name": "Start Web",
|
||||
"command": "yarn nx dev @affine/web --port 8080",
|
||||
"runAtStart": true,
|
||||
"preview": {
|
||||
"port": 8080
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
"server",
|
||||
"web",
|
||||
"docs",
|
||||
"storybook",
|
||||
"component",
|
||||
"workspace",
|
||||
"env",
|
||||
@@ -21,7 +22,9 @@
|
||||
"templates",
|
||||
"y-indexeddb",
|
||||
"debug",
|
||||
"theme"
|
||||
"storage",
|
||||
"infra",
|
||||
"plugin-infra"
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ _next
|
||||
lib
|
||||
.eslintrc.js
|
||||
packages/i18n/src/i18n-generated.ts
|
||||
e2e-dist-*
|
||||
|
||||
16
.eslintrc.js
16
.eslintrc.js
@@ -21,6 +21,11 @@ const createPattern = packageName => [
|
||||
message: 'Do not import package itself',
|
||||
allowTypeImports: false,
|
||||
},
|
||||
{
|
||||
group: ['@blocksuite/store'],
|
||||
message: "Import from '@blocksuite/global/utils'",
|
||||
importNames: ['assertExists', 'assertEquals'],
|
||||
},
|
||||
];
|
||||
|
||||
const allPackages = [
|
||||
@@ -41,6 +46,7 @@ const allPackages = [
|
||||
'apps/web',
|
||||
'apps/server',
|
||||
'apps/electron',
|
||||
'apps/storybook',
|
||||
'plugins/copilot',
|
||||
'plugins/bookmark-block',
|
||||
];
|
||||
@@ -64,6 +70,7 @@ const config = {
|
||||
'plugin:react/recommended',
|
||||
'plugin:react/jsx-runtime',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'prettier',
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
@@ -81,7 +88,7 @@ const config = {
|
||||
'@typescript-eslint',
|
||||
'simple-import-sort',
|
||||
'sonarjs',
|
||||
'import',
|
||||
'i',
|
||||
'unused-imports',
|
||||
'unicorn',
|
||||
],
|
||||
@@ -132,6 +139,11 @@ const config = {
|
||||
message: "Don't import from src",
|
||||
allowTypeImports: false,
|
||||
},
|
||||
{
|
||||
group: ['@blocksuite/store'],
|
||||
message: "Import from '@blocksuite/global/utils'",
|
||||
importNames: ['assertExists', 'assertEquals'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -157,6 +169,7 @@ const config = {
|
||||
'sonarjs/no-duplicated-branches': 'error',
|
||||
'sonarjs/no-collection-size-mischeck': 'error',
|
||||
'sonarjs/no-useless-catch': 'error',
|
||||
'sonarjs/no-identical-functions': 'error',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
@@ -201,6 +214,7 @@ const config = {
|
||||
'scripts/**/*',
|
||||
'**/benchmark/**/*',
|
||||
'**/__debug__/**/*',
|
||||
'**/e2e/**/*',
|
||||
],
|
||||
rules: {
|
||||
'@typescript-eslint/no-non-null-assertion': 0,
|
||||
|
||||
1
.github/CLA.md
vendored
1
.github/CLA.md
vendored
@@ -59,3 +59,4 @@ Example:
|
||||
- 三咲智子 Kevin Deng, @sxzz, 2023/04/21
|
||||
- Moeyua, @moeyua, 2023/04/22
|
||||
- Shishu, @shishudesu, 2023/05/19
|
||||
- Kushagra Singh, @kush002, 2023/06/28
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/BUG-REPORT.yml
vendored
14
.github/ISSUE_TEMPLATE/BUG-REPORT.yml
vendored
@@ -18,22 +18,22 @@ body:
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What version of our software are you running?
|
||||
label: Distribution version
|
||||
description: What version of AFFiNE are you using?
|
||||
options:
|
||||
- app.affine.pro
|
||||
- stage.affine.pro
|
||||
- dev.affine.live
|
||||
- affine-preview.vercel.app
|
||||
- macOS x64
|
||||
- macOS ARM 64
|
||||
- Windows x64
|
||||
- Linux
|
||||
- Web (app.affine.pro)
|
||||
- Web (stage.affine.pro)
|
||||
- Web (dev.affine.live)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: browsers
|
||||
attributes:
|
||||
label: What browsers are you seeing the problem on?
|
||||
label: What browsers are you seeing the problem on if you're using web version?
|
||||
multiple: true
|
||||
options:
|
||||
- Chrome
|
||||
|
||||
29
.github/actions/build-rust/action.yml
vendored
29
.github/actions/build-rust/action.yml
vendored
@@ -4,6 +4,9 @@ inputs:
|
||||
target:
|
||||
description: 'Cargo target'
|
||||
required: true
|
||||
nx_token:
|
||||
description: 'Nx Cloud access token'
|
||||
required: false
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
@@ -24,28 +27,34 @@ runs:
|
||||
.cargo-cache
|
||||
target/${{ inputs.target }}
|
||||
key: stable-${{ inputs.target }}-cargo-cache
|
||||
|
||||
- name: Build
|
||||
if: ${{ inputs.target != 'x86_64-unknown-linux-gnu' && inputs.target != 'aarch64-unknown-linux-gnu' }}
|
||||
shell: bash
|
||||
run: yarn workspace @affine/native build --target ${{ inputs.target }}
|
||||
run: |
|
||||
yarn nx build @affine/native --target ${{ inputs.target }}
|
||||
env:
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ inputs.nx_token }}
|
||||
|
||||
- name: Build
|
||||
if: ${{ inputs.target == 'x86_64-unknown-linux-gnu' }}
|
||||
uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
|
||||
options: --user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build
|
||||
run: >-
|
||||
export CC=x86_64-unknown-linux-gnu-gcc &&
|
||||
export CC_x86_64_unknown_linux_gnu=x86_64-unknown-linux-gnu-gcc &&
|
||||
yarn workspace @affine/native build --target ${{ inputs.target }}
|
||||
options: --user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build -e NX_CLOUD_ACCESS_TOKEN=${{ inputs.nx_token }}
|
||||
run: |
|
||||
export CC=x86_64-unknown-linux-gnu-gcc
|
||||
export CC_x86_64_unknown_linux_gnu=x86_64-unknown-linux-gnu-gcc
|
||||
yarn nx build @affine/native --target ${{ inputs.target }}
|
||||
chmod -R 777 node_modules/.cache
|
||||
chmod -R 777 target
|
||||
|
||||
- name: Build
|
||||
if: ${{ inputs.target == 'aarch64-unknown-linux-gnu' }}
|
||||
uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
|
||||
options: --user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build
|
||||
run: >-
|
||||
yarn workspace @affine/native build --target ${{ inputs.target }}
|
||||
options: --user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build -e NX_CLOUD_ACCESS_TOKEN=${{ inputs.nx_token }}
|
||||
run: |
|
||||
yarn nx build @affine/native --target ${{ inputs.target }}
|
||||
chmod -R 777 node_modules/.cache
|
||||
chmod -R 777 target
|
||||
|
||||
74
.github/actions/setup-node/action.yml
vendored
74
.github/actions/setup-node/action.yml
vendored
@@ -13,10 +13,18 @@ inputs:
|
||||
description: 'Run the install step for Playwright.'
|
||||
required: false
|
||||
default: 'false'
|
||||
electron-install:
|
||||
description: 'Download the Electron binary'
|
||||
required: false
|
||||
default: 'true'
|
||||
npm-token:
|
||||
description: 'The NPM token to use for private packages.'
|
||||
required: false
|
||||
default: ''
|
||||
hard-link-nm:
|
||||
description: 'set nmMode to hardlinks-local in .yarnrc.yml'
|
||||
required: false
|
||||
default: 'true'
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
@@ -29,33 +37,10 @@ runs:
|
||||
scope: '@toeverything'
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Expose yarn config as "$GITHUB_OUTPUT"
|
||||
id: yarn-config
|
||||
- name: Set nmMode
|
||||
if: ${{ inputs.hard-link-nm == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "CACHE_FOLDER=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore yarn cache
|
||||
uses: actions/cache@v3
|
||||
id: yarn-download-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-config.outputs.CACHE_FOLDER }}
|
||||
key: yarn-download-cache-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: |
|
||||
yarn-download-cache-
|
||||
|
||||
- name: Restore node_modules cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Restore yarn install state
|
||||
id: yarn-install-state-cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .yarn/ci-cache/
|
||||
key: ${{ runner.os }}-yarn-install-state-cache-${{ hashFiles('yarn.lock', '.yarnrc.yml') }}
|
||||
run: yarn config set nmMode hardlinks-local
|
||||
|
||||
- name: yarn install
|
||||
if: ${{ inputs.package-install == 'true' }}
|
||||
@@ -64,9 +49,9 @@ runs:
|
||||
run: yarn install ${{ inputs.extra-flags }}
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ inputs.npm-token }}
|
||||
YARN_ENABLE_GLOBAL_CACHE: 'false'
|
||||
YARN_INSTALL_STATE_PATH: .yarn/ci-cache/install-state.gz
|
||||
HUSKY: '0'
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
|
||||
ELECTRON_SKIP_BINARY_DOWNLOAD: '1'
|
||||
|
||||
- name: yarn install (try again)
|
||||
if: ${{ steps.install.outcome == 'failure' }}
|
||||
@@ -74,15 +59,15 @@ runs:
|
||||
run: yarn install ${{ inputs.extra-flags }}
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ inputs.npm-token }}
|
||||
YARN_ENABLE_GLOBAL_CACHE: 'false'
|
||||
YARN_INSTALL_STATE_PATH: .yarn/ci-cache/install-state.gz
|
||||
HUSKY: '0'
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'
|
||||
ELECTRON_SKIP_BINARY_DOWNLOAD: '1'
|
||||
|
||||
- name: Get installed Playwright version
|
||||
id: playwright-version
|
||||
if: ${{ inputs.playwright-install == 'true' }}
|
||||
shell: bash
|
||||
run: echo "version=$(yarn why --json @playwright/test | grep -h 'workspace:.' | jq --raw-output '.children[].locator' | sed -e 's/@playwright\/test@.*://')" >> $GITHUB_OUTPUT
|
||||
run: echo "version=$(yarn why --json @playwright/test | grep -h 'workspace:.' | jq --raw-output '.children[].locator' | sed -e 's/@playwright\/test@.*://' | head -n 1)" >> $GITHUB_OUTPUT
|
||||
|
||||
# Attempt to restore the correct Playwright browser binaries based on the
|
||||
# currently installed version of Playwright (The browser binary versions
|
||||
@@ -113,3 +98,30 @@ runs:
|
||||
shell: bash
|
||||
if: inputs.playwright-install == 'true' && steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
run: yarn playwright install --with-deps
|
||||
|
||||
- name: Get installed Electron version
|
||||
id: electron-version
|
||||
if: ${{ inputs.electron-install == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "version=$(yarn why --json electron | grep -h 'workspace:.' | jq --raw-output '.children[].locator' | sed -e 's/@playwright\/test@.*://' | head -n 1)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
id: electron-cache
|
||||
if: ${{ inputs.electron-install == 'true' }}
|
||||
with:
|
||||
path: 'node_modules/.cache/electron'
|
||||
key: '${{ runner.os }}-electron-${{ steps.electron-version.outputs.version }}'
|
||||
restore-keys: |
|
||||
${{ runner.os }}-electron-
|
||||
|
||||
- name: Install Electron binary
|
||||
shell: bash
|
||||
if: inputs.electron-install == 'true'
|
||||
run: node apps/electron/node_modules/electron/install.js
|
||||
env:
|
||||
ELECTRON_OVERRIDE_DIST_PATH: ./node_modules/.cache/electron
|
||||
|
||||
- name: Build Infra
|
||||
shell: bash
|
||||
run: yarn run build:infra
|
||||
|
||||
31
.github/actions/setup-rust/action.yml
vendored
Normal file
31
.github/actions/setup-rust/action.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: 'AFFiNE Rust setup'
|
||||
description: 'Rust setup, including cache configuration'
|
||||
inputs:
|
||||
target:
|
||||
description: 'Cargo target'
|
||||
required: true
|
||||
toolchain:
|
||||
description: 'Rustup toolchain'
|
||||
required: false
|
||||
default: 'stable'
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: ${{ inputs.toolchain }}
|
||||
targets: ${{ inputs.target }}
|
||||
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry/index/
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: cargo-cache-${{ runner.os }}-${{ inputs.toolchain }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
cargo-cache-${{ runner.os }}-${{ inputs.toolchain }}-
|
||||
40
.github/deployment/Caddyfile
vendored
40
.github/deployment/Caddyfile
vendored
@@ -1,40 +0,0 @@
|
||||
:80 {
|
||||
root /* ./dist
|
||||
|
||||
file_server {
|
||||
# precompressed br
|
||||
}
|
||||
|
||||
encode {
|
||||
zstd
|
||||
gzip 9
|
||||
}
|
||||
|
||||
header {
|
||||
# 7 days
|
||||
Cache-Control "public, max-age=86400, must-revalidate"
|
||||
}
|
||||
|
||||
handle /api/* {
|
||||
reverse_proxy {$API_SERVER} {
|
||||
health_uri /api/healthz
|
||||
@error status 500 502 503 503
|
||||
handle_response @error {
|
||||
root * /dist
|
||||
rewrite * /50x.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@notStatic {
|
||||
not path /_next/static/*
|
||||
}
|
||||
|
||||
handle @notStatic {
|
||||
header {
|
||||
Cache-Control "no-cache, no-store, must-revalidate"
|
||||
}
|
||||
try_files {path} /index.html
|
||||
}
|
||||
}
|
||||
13
.github/deployment/Dockerfile
vendored
13
.github/deployment/Dockerfile
vendored
@@ -1,13 +0,0 @@
|
||||
FROM node:16-alpine as relocate
|
||||
WORKDIR /app
|
||||
COPY ./apps/web/out ./dist
|
||||
COPY ./.github/deployment/Caddyfile ./Caddyfile
|
||||
|
||||
FROM caddy:2.6.2-alpine
|
||||
ARG API_SERVER
|
||||
WORKDIR /app
|
||||
COPY --from=relocate /app .
|
||||
|
||||
EXPOSE 80
|
||||
ENV API_SERVER=$API_SERVER
|
||||
CMD ["caddy", "run"]
|
||||
11
.github/deployment/front/Dockerfile
vendored
Normal file
11
.github/deployment/front/Dockerfile
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
FROM openresty/openresty:1.21.4.1-0-buster
|
||||
WORKDIR /app
|
||||
COPY ./apps/web/out ./dist
|
||||
COPY ./.github/deployment/front/nginx.conf /usr/local/openresty/nginx/conf/nginx.conf
|
||||
COPY ./.github/deployment/front/affine.nginx.conf /etc/nginx/conf.d/affine.nginx.conf
|
||||
|
||||
RUN mkdir -p /var/log/nginx && \
|
||||
rm /etc/nginx/conf.d/default.conf
|
||||
|
||||
EXPOSE 8080
|
||||
CMD ["/usr/local/openresty/bin/openresty", "-g", "daemon off;"]
|
||||
13
.github/deployment/front/affine.nginx.conf
vendored
Normal file
13
.github/deployment/front/affine.nginx.conf
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
server {
|
||||
listen 8080;
|
||||
root /app/dist;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/index.html $uri.html =404;
|
||||
}
|
||||
|
||||
error_page 404 /404.html;
|
||||
location = /404.html {
|
||||
internal;
|
||||
}
|
||||
}
|
||||
14
.github/deployment/front/nginx.conf
vendored
Normal file
14
.github/deployment/front/nginx.conf
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
worker_processes 4;
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pcre_jit on;
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
http {
|
||||
include mime.types;
|
||||
log_format main '$remote_addr [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
access_log /var/log/nginx/access.log main;
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
10
.github/deployment/node/Dockerfile
vendored
Normal file
10
.github/deployment/node/Dockerfile
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM node:18-bookworm-slim
|
||||
|
||||
COPY ./apps/server /app
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends openssl && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
CMD ["node", "--es-module-specifier-resolution=node", "./dist/index.js"]
|
||||
1
.github/helm/affine-cloud/.gitignore
vendored
Normal file
1
.github/helm/affine-cloud/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
charts/
|
||||
23
.github/helm/affine-cloud/.helmignore
vendored
Normal file
23
.github/helm/affine-cloud/.helmignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
6
.github/helm/affine-cloud/Chart.lock
vendored
Normal file
6
.github/helm/affine-cloud/Chart.lock
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
version: 12.5.8
|
||||
digest: sha256:c91c0dc1370e879538dc9d6e435e731a726ef99d6a3b081372318483792b48a7
|
||||
generated: "2023-06-27T18:34:12.683806+08:00"
|
||||
12
.github/helm/affine-cloud/Chart.yaml
vendored
Normal file
12
.github/helm/affine-cloud/Chart.yaml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
apiVersion: v2
|
||||
name: affine-cloud
|
||||
description: A Helm chart for AFFiNE Cloud
|
||||
|
||||
type: application
|
||||
version: 0.6.1
|
||||
appVersion: '0.6.1'
|
||||
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
version: 12.5.8
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
30
.github/helm/affine-cloud/readme.md
vendored
Normal file
30
.github/helm/affine-cloud/readme.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# Helm Chart Configuration
|
||||
|
||||
The following table lists the configurable parameters of this Helm chart and their default values.
|
||||
|
||||
## AFFiNE Cloud Server parameters
|
||||
|
||||
| Parameter | Description | Default |
|
||||
| ------------------------------ | -------------------------------------------------- | ------------------ |
|
||||
| `affineCloud.tag` | The Docker tag of the AffineCloud image to be used | `'nightly-latest'` |
|
||||
| `affineCloud.resources.cpu` | The CPU resources allocated for AffineCloud | `'250m'` |
|
||||
| `affineCloud.resources.memory` | The memory resources allocated for AffineCloud | `'0.5Gi'` |
|
||||
| `affineCloud.signKey` | The key used to sign the JWT tokens | `'c2VjcmV0'` |
|
||||
| `affineCloud.service.type` | The type of the Kubernetes service | `'ClusterIP'` |
|
||||
| `affineCloud.service.port` | The port of the Kubernetes service | `'http'` |
|
||||
| `affineCloud.mail.account` | The email account used to send emails | `''` |
|
||||
| `affineCloud.mail.password` | The password of the email account | `''` |
|
||||
|
||||
## PostgreSQL parameters
|
||||
|
||||
| Parameter | Description | Default |
|
||||
| -------------------------------------------- | ------------------------------------------------------------------------------------- | ------------ |
|
||||
| `postgresql.auth.username` | Username for the PostgreSQL database | `'affine'` |
|
||||
| `postgresql.auth.password` | Password for the PostgreSQL database. Please change this for production environments. | `'password'` |
|
||||
| `postgresql.auth.database` | The name of the default database that will be created on image startup | `'affine'` |
|
||||
| `postgresql.primary.resources.limits.cpu` | The CPU resources allocated for the PostgreSQL primary node | `'500m'` |
|
||||
| `postgresql.primary.resources.limits.memory` | The memory resources allocated for the PostgreSQL primary node | `'0.5Gi'` |
|
||||
|
||||
For more postgres parameters, please refer to: https://artifacthub.io/packages/helm/bitnami/postgresql
|
||||
|
||||
Please note that for the `postgresql.auth.password`, you should provide your own password for production environments. The default value is provided only for demonstration purposes.
|
||||
51
.github/helm/affine-cloud/templates/_helper.tpl
vendored
Normal file
51
.github/helm/affine-cloud/templates/_helper.tpl
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "affine-cloud.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "affine-cloud.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "affine-cloud.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "affine-cloud.labels" -}}
|
||||
helm.sh/chart: {{ include "affine-cloud.chart" . }}
|
||||
{{ include "affine-cloud.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "affine-cloud.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "affine-cloud.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
51
.github/helm/affine-cloud/templates/deployment.yaml
vendored
Normal file
51
.github/helm/affine-cloud/templates/deployment.yaml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: "{{ include "affine-cloud.fullname" . }}"
|
||||
labels:
|
||||
{{- include "affine-cloud.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "affine-cloud.selectorLabels" . | nindent 6 }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "affine-cloud.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
restartPolicy: Always
|
||||
containers:
|
||||
- name: affine-cloud
|
||||
image: "ghcr.io/toeverything/cloud-self-hosted:{{ .Values.affineCloud.tag | default .Chart.AppVersion }}"
|
||||
env:
|
||||
- name: PG_USER
|
||||
value: "{{ .Values.postgresql.auth.username }}"
|
||||
- name: PG_PASS
|
||||
value: "{{ .Values.postgresql.auth.password }}"
|
||||
- name: PG_DATABASE
|
||||
value: "{{ .Values.postgresql.auth.database }}"
|
||||
- name: PG_HOST
|
||||
value: "{{ .Values.postgresql.fullnameOverride | default (printf "%s-postgresql" .Release.Name) }}"
|
||||
- name: DATABASE_URL
|
||||
value: "{{ .Values.affineCloud.databaseUrl | default "postgresql://$(PG_USER):$(PG_PASS)@$(PG_HOST)/$(PG_DATABASE)" }}"
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: affine-cloud-secret
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/healthz
|
||||
port: 3000
|
||||
failureThreshold: 1
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
resources:
|
||||
limits:
|
||||
cpu: "{{ .Values.affineCloud.resources.cpu }}"
|
||||
memory: "{{ .Values.affineCloud.resources.memory }}"
|
||||
9
.github/helm/affine-cloud/templates/secret.yaml
vendored
Normal file
9
.github/helm/affine-cloud/templates/secret.yaml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: affine-cloud-secret
|
||||
type: Opaque
|
||||
data:
|
||||
SIGN_KEY: "{{ .Values.affineCloud.signKey }}"
|
||||
MAIL_ACCOUNT: "{{ .Values.affineCloud.mail.account }}"
|
||||
MAIL_PASSWORD: "{{ .Values.affineCloud.mail.password }}"
|
||||
15
.github/helm/affine-cloud/templates/services.yaml
vendored
Normal file
15
.github/helm/affine-cloud/templates/services.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: "{{ include "affine-cloud.fullname" . }}"
|
||||
labels:
|
||||
{{- include "affine-cloud.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: "{{ .Values.affineCloud.service.type }}"
|
||||
ports:
|
||||
- name: http
|
||||
protocol: TCP
|
||||
port: {{ .Values.affineCloud.service.port }}
|
||||
targetPort: 3000
|
||||
selector:
|
||||
{{- include "affine-cloud.selectorLabels" . | nindent 4 }}
|
||||
30
.github/helm/affine-cloud/values.yaml
vendored
Normal file
30
.github/helm/affine-cloud/values.yaml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
affineCloud:
|
||||
tag: 'canary-5e0d5e0cc65ea46f326fdde12658bfac59b38c9f-0949'
|
||||
# databaseUrl: 'postgresql://affine:password@affine-cloud-postgresql:5432/affine'
|
||||
signKey: TUFtdFdzQTJhdGJuem01TA==
|
||||
mail:
|
||||
account: ''
|
||||
password: ''
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
resources:
|
||||
cpu: '250m'
|
||||
memory: 0.5Gi
|
||||
postgresql:
|
||||
fullnameOverride: tcp-postgresql
|
||||
auth:
|
||||
# only for demo, please modify it at prod env
|
||||
username: affine
|
||||
password: password
|
||||
database: affine
|
||||
primary:
|
||||
initdb:
|
||||
scripts:
|
||||
01-init.sql: |
|
||||
CREATE DATABASE affine_binary;
|
||||
GRANT ALL PRIVILEGES ON DATABASE affine_binary TO affine;
|
||||
resources:
|
||||
limits:
|
||||
cpu: '500m'
|
||||
memory: 0.5Gi
|
||||
23
.github/helm/affine/.helmignore
vendored
Normal file
23
.github/helm/affine/.helmignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
6
.github/helm/affine/Chart.yaml
vendored
Normal file
6
.github/helm/affine/Chart.yaml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: affine
|
||||
description: AFFiNE cloud chart
|
||||
type: application
|
||||
version: 0.0.0
|
||||
appVersion: '0.7.0-canary.18'
|
||||
6
.github/helm/affine/charts/graphql/Chart.yaml
vendored
Normal file
6
.github/helm/affine/charts/graphql/Chart.yaml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: graphql
|
||||
description: AFFiNE GraphQL server
|
||||
type: application
|
||||
version: 0.0.0
|
||||
appVersion: '0.7.0-canary.18'
|
||||
16
.github/helm/affine/charts/graphql/templates/NOTES.txt
vendored
Normal file
16
.github/helm/affine/charts/graphql/templates/NOTES.txt
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "graphql.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "graphql.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "graphql.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "graphql.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
||||
132
.github/helm/affine/charts/graphql/templates/_helpers.tpl
vendored
Normal file
132
.github/helm/affine/charts/graphql/templates/_helpers.tpl
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "graphql.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "graphql.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "graphql.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "graphql.labels" -}}
|
||||
helm.sh/chart: {{ include "graphql.chart" . }}
|
||||
{{ include "graphql.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "graphql.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "graphql.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "graphql.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "graphql.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "jwt.key" -}}
|
||||
{{- $secret := lookup "v1" "Secret" .Release.Namespace .Values.app.jwt.secretName -}}
|
||||
{{- if and $secret $secret.data.private -}}
|
||||
{{/*
|
||||
Reusing existing secret data
|
||||
*/}}
|
||||
key: {{ $secret.data.private }}
|
||||
{{- else -}}
|
||||
{{/*
|
||||
Generate new data
|
||||
*/}}
|
||||
key: {{ genPrivateKey "ecdsa" | b64enc }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "objectStorage.r2" -}}
|
||||
{{- $secret := lookup "v1" "Secret" .Release.Namespace .Values.app.objectStorage.r2.secretName -}}
|
||||
{{- if $secret -}}
|
||||
{{/*
|
||||
Reusing existing secret data
|
||||
*/}}
|
||||
accountId: {{ $secret.data.accountId }}
|
||||
accessKeyId: {{ $secret.data.accessKeyId }}
|
||||
secretAccessKey: {{ $secret.data.secretAccessKey }}
|
||||
bucket: {{ $secret.data.bucket }}
|
||||
{{- else -}}
|
||||
{{/*
|
||||
Generate new data
|
||||
*/}}
|
||||
accountId: {{ .Values.app.objectStorage.r2.accountId | b64enc }}
|
||||
accessKeyId: {{ .Values.app.objectStorage.r2.accessKeyId | b64enc }}
|
||||
secretAccessKey: {{ .Values.app.objectStorage.r2.secretAccessKey | b64enc }}
|
||||
bucket: {{ .Values.app.objectStorage.r2.bucket | b64enc }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "objectStorage.oauth.google" -}}
|
||||
{{- $secret := lookup "v1" "Secret" .Release.Namespace .Values.app.oauth.google.secretName -}}
|
||||
{{- if $secret -}}
|
||||
{{/*
|
||||
Reusing existing secret data
|
||||
*/}}
|
||||
clientId: {{ $secret.data.clientId }}
|
||||
clientSecret: {{ $secret.data.clientSecret }}
|
||||
{{- else -}}
|
||||
{{/*
|
||||
Generate new data
|
||||
*/}}
|
||||
clientId: "{{ .Values.app.oauth.google.clientId | b64enc }}"
|
||||
clientSecret: "{{ .Values.app.oauth.google.clientSecret | b64enc }}"
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "objectStorage.oauth.github" -}}
|
||||
{{- $secret := lookup "v1" "Secret" .Release.Namespace .Values.app.oauth.github.secretName -}}
|
||||
{{- if $secret -}}
|
||||
{{/*
|
||||
Reusing existing secret data
|
||||
*/}}
|
||||
clientId: {{ $secret.data.clientId }}
|
||||
clientSecret: {{ $secret.data.clientSecret }}
|
||||
{{- else -}}
|
||||
{{/*
|
||||
Generate new data
|
||||
*/}}
|
||||
clientId: "{{ .Values.app.oauth.github.clientId | b64enc }}"
|
||||
clientSecret: "{{ .Values.app.oauth.github.clientSecret | b64enc }}"
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
126
.github/helm/affine/charts/graphql/templates/deployment.yaml
vendored
Normal file
126
.github/helm/affine/charts/graphql/templates/deployment.yaml
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "graphql.fullname" . }}
|
||||
labels:
|
||||
{{- include "graphql.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "graphql.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "graphql.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "graphql.serviceAccountName" . }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
env:
|
||||
- name: AUTH_PRIVATE_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.jwt.secretName }}"
|
||||
key: key
|
||||
- name: NODE_ENV
|
||||
value: "{{ .Values.env }}"
|
||||
- name: DATABSE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: pg-postgresql
|
||||
key: postgres-password
|
||||
- name: DATABASE_URL
|
||||
value: postgres://{{ .Values.database.user }}:$(DATABSE_PASSWORD)@{{ .Values.database.url }}:{{ .Values.database.port }}/{{ .Values.database.name }}
|
||||
- name: AFFINE_SERVER_PORT
|
||||
value: "{{ .Values.service.port }}"
|
||||
- name: AFFINE_SERVER_SUB_PATH
|
||||
value: "{{ .Values.app.path }}"
|
||||
- name: AFFINE_SERVER_HOST
|
||||
value: "{{ .Values.app.host }}"
|
||||
- name: ENABLE_R2_OBJECT_STORAGE
|
||||
value: "{{ .Values.app.objectStorage.r2.enabled }}"
|
||||
{{ if .Values.app.objectStorage.r2.enabled }}
|
||||
- name: R2_OBJECT_STORAGE_ACCOUNT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.objectStorage.r2.secretName }}"
|
||||
key: accountId
|
||||
- name: R2_OBJECT_STORAGE_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.objectStorage.r2.secretName }}"
|
||||
key: accessKeyId
|
||||
- name: R2_OBJECT_STORAGE_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.objectStorage.r2.secretName }}"
|
||||
key: secretAccessKey
|
||||
- name: R2_OBJECT_STORAGE_BUCKET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.objectStorage.r2.secretName }}"
|
||||
key: bucket
|
||||
{{ end }}
|
||||
{{ if .Values.app.oauth.google.enabled }}
|
||||
- name: OAUTH_GOOGLE_CLIENT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.oauth.google.secretName }}"
|
||||
key: clientId
|
||||
- name: OAUTH_GOOGLE_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.oauth.google.secretName }}"
|
||||
key: clientSecret
|
||||
{{ end }}
|
||||
{{ if .Values.app.oauth.github.enabled }}
|
||||
- name: OAUTH_GITHUB_CLIENT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.oauth.github.secretName }}"
|
||||
key: clientId
|
||||
- name: OAUTH_GITHUB_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: "{{ .Values.app.oauth.github.secretName }}"
|
||||
key: clientSecret
|
||||
{{ end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probe.initialDelaySeconds }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probe.initialDelaySeconds }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
7
.github/helm/affine/charts/graphql/templates/jwt-secret.yaml
vendored
Normal file
7
.github/helm/affine/charts/graphql/templates/jwt-secret.yaml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.jwt.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
{{- ( include "jwt.key" . ) | indent 2 -}}
|
||||
34
.github/helm/affine/charts/graphql/templates/migration.yaml
vendored
Normal file
34
.github/helm/affine/charts/graphql/templates/migration.yaml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ include "graphql.fullname" . }}-database-migration
|
||||
labels:
|
||||
{{- include "graphql.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "-1"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation
|
||||
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
command: ["yarn", "prisma", "migrate", "deploy"]
|
||||
env:
|
||||
- name: NODE_ENV
|
||||
value: "{{ .Values.env }}"
|
||||
- name: DATABSE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: pg-postgresql
|
||||
key: postgres-password
|
||||
- name: DATABASE_URL
|
||||
value: postgres://{{ .Values.database.user }}:$(DATABSE_PASSWORD)@{{ .Values.database.url }}:{{ .Values.database.port }}/{{ .Values.database.name }}
|
||||
resources:
|
||||
requests:
|
||||
cpu: '100m'
|
||||
memory: '200Mi'
|
||||
restartPolicy: Never
|
||||
backoffLimit: 1
|
||||
10
.github/helm/affine/charts/graphql/templates/oauth-github-secret.yaml
vendored
Normal file
10
.github/helm/affine/charts/graphql/templates/oauth-github-secret.yaml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{{- if .Values.app.oauth.github.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.oauth.github.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
{{- ( include "objectStorage.oauth.github" . ) | indent 2 -}}
|
||||
|
||||
{{- end }}
|
||||
10
.github/helm/affine/charts/graphql/templates/oauth-google-secret.yaml
vendored
Normal file
10
.github/helm/affine/charts/graphql/templates/oauth-google-secret.yaml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{{- if .Values.app.oauth.google.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.oauth.google.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
{{- ( include "objectStorage.oauth.google" . ) | indent 2 -}}
|
||||
|
||||
{{- end }}
|
||||
9
.github/helm/affine/charts/graphql/templates/r2-secret.yaml
vendored
Normal file
9
.github/helm/affine/charts/graphql/templates/r2-secret.yaml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{{- if .Values.app.objectStorage.r2.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: "{{ .Values.app.objectStorage.r2.secretName }}"
|
||||
type: Opaque
|
||||
data:
|
||||
{{- ( include "objectStorage.r2" . ) | indent 2 -}}
|
||||
{{- end }}
|
||||
15
.github/helm/affine/charts/graphql/templates/service.yaml
vendored
Normal file
15
.github/helm/affine/charts/graphql/templates/service.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "graphql.fullname" . }}
|
||||
labels:
|
||||
{{- include "graphql.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "graphql.selectorLabels" . | nindent 4 }}
|
||||
12
.github/helm/affine/charts/graphql/templates/serviceaccount.yaml
vendored
Normal file
12
.github/helm/affine/charts/graphql/templates/serviceaccount.yaml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "graphql.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "graphql.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
15
.github/helm/affine/charts/graphql/templates/tests/test-connection.yaml
vendored
Normal file
15
.github/helm/affine/charts/graphql/templates/tests/test-connection.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "graphql.fullname" . }}-test-connection"
|
||||
labels:
|
||||
{{- include "graphql.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
containers:
|
||||
- name: wget
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['{{ include "graphql.fullname" . }}:{{ .Values.service.port }}']
|
||||
restartPolicy: Never
|
||||
69
.github/helm/affine/charts/graphql/values.yaml
vendored
Normal file
69
.github/helm/affine/charts/graphql/values.yaml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
replicaCount: 1
|
||||
image:
|
||||
repository: ghcr.io/toeverything/affine-graphql
|
||||
pullPolicy: IfNotPresent
|
||||
tag: ''
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ''
|
||||
fullnameOverride: ''
|
||||
# map to NODE_ENV environment variable
|
||||
env: 'production'
|
||||
database:
|
||||
user: 'postgres'
|
||||
url: 'pg-postgresql'
|
||||
port: '5432'
|
||||
name: 'affine'
|
||||
app:
|
||||
# AFFINE_SERVER_SUB_PATH
|
||||
path: ''
|
||||
# AFFINE_SERVER_HOST
|
||||
host: '0.0.0.0'
|
||||
jwt:
|
||||
secretName: jwt-private-key
|
||||
# base64 encoded ecdsa private key
|
||||
privateKey: ''
|
||||
objectStorage:
|
||||
r2:
|
||||
enabled: false
|
||||
secretName: r2
|
||||
accountId: ''
|
||||
accessKeyId: ''
|
||||
secretAccessKey: ''
|
||||
bucket: ''
|
||||
oauth:
|
||||
google:
|
||||
enabled: false
|
||||
secretName: oauth-google
|
||||
clientId: ''
|
||||
clientSecret: ''
|
||||
github:
|
||||
enabled: false
|
||||
secretName: oauth-github
|
||||
clientId: ''
|
||||
clientSecret: ''
|
||||
|
||||
serviceAccount:
|
||||
create: true
|
||||
annotations: {}
|
||||
name: 'affine-graphql'
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext:
|
||||
fsGroup: 2000
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: '2000m'
|
||||
memory: 4Gi
|
||||
requests:
|
||||
cpu: '1000m'
|
||||
memory: 2Gi
|
||||
|
||||
probe:
|
||||
initialDelaySeconds: 20
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
23
.github/helm/affine/charts/web/.helmignore
vendored
Normal file
23
.github/helm/affine/charts/web/.helmignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
6
.github/helm/affine/charts/web/Chart.yaml
vendored
Normal file
6
.github/helm/affine/charts/web/Chart.yaml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: web
|
||||
description: A Helm chart for Kubernetes
|
||||
type: application
|
||||
version: 0.0.0
|
||||
appVersion: "0.7.0-canary.18"
|
||||
16
.github/helm/affine/charts/web/templates/NOTES.txt
vendored
Normal file
16
.github/helm/affine/charts/web/templates/NOTES.txt
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "web.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "web.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "web.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "web.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
||||
62
.github/helm/affine/charts/web/templates/_helpers.tpl
vendored
Normal file
62
.github/helm/affine/charts/web/templates/_helpers.tpl
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "web.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "web.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "web.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "web.labels" -}}
|
||||
helm.sh/chart: {{ include "web.chart" . }}
|
||||
{{ include "web.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "web.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "web.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "web.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "web.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
57
.github/helm/affine/charts/web/templates/deployment.yaml
vendored
Normal file
57
.github/helm/affine/charts/web/templates/deployment.yaml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "web.fullname" . }}
|
||||
labels:
|
||||
{{- include "web.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "web.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "web.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "web.serviceAccountName" . }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probe.initialDelaySeconds }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probe.initialDelaySeconds }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
15
.github/helm/affine/charts/web/templates/service.yaml
vendored
Normal file
15
.github/helm/affine/charts/web/templates/service.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "web.fullname" . }}
|
||||
labels:
|
||||
{{- include "web.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "web.selectorLabels" . | nindent 4 }}
|
||||
12
.github/helm/affine/charts/web/templates/serviceaccount.yaml
vendored
Normal file
12
.github/helm/affine/charts/web/templates/serviceaccount.yaml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "web.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "web.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
15
.github/helm/affine/charts/web/templates/tests/test-connection.yaml
vendored
Normal file
15
.github/helm/affine/charts/web/templates/tests/test-connection.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "web.fullname" . }}-test-connection"
|
||||
labels:
|
||||
{{- include "web.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
containers:
|
||||
- name: wget
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['{{ include "web.fullname" . }}:{{ .Values.service.port }}']
|
||||
restartPolicy: Never
|
||||
37
.github/helm/affine/charts/web/values.yaml
vendored
Normal file
37
.github/helm/affine/charts/web/values.yaml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: ghcr.io/toeverything/affine-front
|
||||
pullPolicy: IfNotPresent
|
||||
tag: ""
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
create: true
|
||||
annotations: {}
|
||||
name: "affine-web"
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext:
|
||||
fsGroup: 2000
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: '500m'
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: '500m'
|
||||
memory: 2Gi
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
probe:
|
||||
initialDelaySeconds: 1
|
||||
62
.github/helm/affine/templates/_helpers.tpl
vendored
Normal file
62
.github/helm/affine/templates/_helpers.tpl
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "affine.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "affine.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "affine.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "affine.labels" -}}
|
||||
helm.sh/chart: {{ include "affine.chart" . }}
|
||||
{{ include "affine.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "affine.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "affine.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "affine.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "affine.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
64
.github/helm/affine/templates/ingress.yaml
vendored
Normal file
64
.github/helm/affine/templates/ingress.yaml
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "affine.fullname" . -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "affine.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: "{{ .Values.ingress.host }}"
|
||||
http:
|
||||
paths:
|
||||
- path: /graphql
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: affine-graphql
|
||||
port:
|
||||
number: {{ .Values.graphql.service.port }}
|
||||
- path: /api
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: affine-graphql
|
||||
port:
|
||||
number: {{ .Values.graphql.service.port }}
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: affine-web
|
||||
port:
|
||||
number: {{ .Values.web.service.port }}
|
||||
|
||||
{{- end }}
|
||||
17
.github/helm/affine/values.yaml
vendored
Normal file
17
.github/helm/affine/values.yaml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ''
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
host: affine.pro
|
||||
tls: []
|
||||
|
||||
graphql:
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
|
||||
web:
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
60
.github/helm/deployment_guide.md
vendored
Normal file
60
.github/helm/deployment_guide.md
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
# Cluster Deployment Guide
|
||||
|
||||
This document provides a step-by-step guide for developers on how to deploy services in a Kubernetes cluster. The following content assumes that the reader already has a basic understanding of Kubernetes concepts and operations.
|
||||
|
||||
### 1. Configure Service Mesh (Optional)
|
||||
|
||||
In the Kubernetes cluster, we optionally use Service Mesh (like Istio and Anthos Service Mesh) to manage the network interactions of microservices. If Service Mesh is already deployed on your cluster or do not need to use the service network, you can skip this step. In this step, we assume that you are using Google Kubernetes Engine (GKE) and have already installed Anthos Service Mesh on your cluster, if you wish to use another Ingress Controller, please refer to the relevant documentation.
|
||||
|
||||
To configure your kubectl context to interact with your Kubernetes cluster using the gcloud tool, you need to execute the following commands:
|
||||
|
||||
```sh
|
||||
export CLUSTER_NAME=your_cluster_name
|
||||
export REGION=your_cluster_region
|
||||
export PROJECT=your_project_id
|
||||
gcloud container clusters get-credentials $CLUSTER_NAME --region $REGION --project $PROJECT
|
||||
```
|
||||
|
||||
In this command, you should replace `CLUSTER_NAME`, `REGION` and `PROJECT` with the actual name, region and project id of your Kubernetes cluster. This command retrieves the access credentials for your Kubernetes cluster and automatically configures kubectl to use these credentials.
|
||||
|
||||
Now, to inject Service Mesh for a specific Namespace, first, set the environment variable `NAMESPACE` that should correspond to your target Kubernetes Namespace. In this example, we use `prod` as the target Namespace:
|
||||
|
||||
```sh
|
||||
export NAMESPACE=prod
|
||||
```
|
||||
|
||||
Then, we label the Namespace which will enable Istio to automatically inject the sidecar container for all new Pods under this Namespace:
|
||||
|
||||
```sh
|
||||
kubectl label namespace $NAMESPACE istio-injection- istio.io/rev=asm-managed --overwrite
|
||||
```
|
||||
|
||||
Finally, we trigger the Kubernetes Deployment restart mechanism to allow existing Pods to also obtain sidecar container injection:
|
||||
|
||||
```sh
|
||||
kubectl rollout restart deployment -n $NAMESPACE
|
||||
```
|
||||
|
||||
### 2. Deploying the Application
|
||||
|
||||
Next, we will deploy our application in the Kubernetes cluster through Helm. First, set relevant environment variables:
|
||||
|
||||
```sh
|
||||
export NAMESPACE=prod
|
||||
export RELEASE=affine-cloud-prod
|
||||
export PATH=.github/helm/affine-cloud
|
||||
```
|
||||
|
||||
- `NAMESPACE` should be consistent with the first step, indicating your target Kubernetes Namespace.
|
||||
- `RELEASE` is the name of your Helm release.
|
||||
- `PATH` is the location of your Helm chart in your file system.
|
||||
|
||||
Finally, use the `helm upgrade --install` command to deploy or upgrade your application:
|
||||
|
||||
```sh
|
||||
helm upgrade --namespace $NAMESPACE --create-namespace --install $RELEASE $PATH
|
||||
```
|
||||
|
||||
This command creates (if it doesn't already exist) and deploys your Helm chart in the specified Namespace. If the release already exists, it will be upgraded.
|
||||
|
||||
The above are the complete steps for deploying an application in a Kubernetes cluster. Make sure all prerequisites are met before deploying, and also ensure that you have the correct permissions for operations in Kubernetes.
|
||||
2
.github/helm/releaser.yaml
vendored
Normal file
2
.github/helm/releaser.yaml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
owner: toeverything
|
||||
git-repo: helm-charts
|
||||
18
.github/labeler.yml
vendored
18
.github/labeler.yml
vendored
@@ -8,14 +8,20 @@ test:
|
||||
- '**/tests/**/*'
|
||||
- '**/__tests__/**/*'
|
||||
|
||||
plugin:copilot:
|
||||
- 'plugins/copilot/**/*'
|
||||
|
||||
mod:dev:
|
||||
- 'scripts/**/*'
|
||||
- 'packages/cli/**/*'
|
||||
- 'packages/debug/**/*'
|
||||
|
||||
mod:plugin:
|
||||
- 'plugins/**/*'
|
||||
|
||||
plugin:bookmark-block:
|
||||
- 'plugins/bookmark-block/**/*'
|
||||
|
||||
plugin:copilot:
|
||||
- 'plugins/copilot/**/*'
|
||||
|
||||
mod:plugin-infra:
|
||||
- 'packages/plugin-infra/**/*'
|
||||
|
||||
@@ -29,6 +35,10 @@ mod:hooks: 'packages/hooks/**/*'
|
||||
|
||||
mod:component: 'packages/component/**/*'
|
||||
|
||||
mod:storage: 'packages/storage/**/*'
|
||||
|
||||
mod:native: 'packages/native/**/*'
|
||||
|
||||
mod:store:
|
||||
- 'packages/jotai/**/*'
|
||||
- '**/atoms/**/*'
|
||||
@@ -48,3 +58,5 @@ app:web: 'apps/web/**/*'
|
||||
app:electron: 'apps/electron/**/*'
|
||||
|
||||
app:server: 'apps/server/**/*'
|
||||
|
||||
app:docs: 'apps/docs/**/*'
|
||||
|
||||
304
.github/workflows/build.yml
vendored
304
.github/workflows/build.yml
vendored
@@ -10,7 +10,10 @@ on:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/build.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
pull_request:
|
||||
merge_group:
|
||||
branches:
|
||||
- master
|
||||
- v[0-9]+.[0-9]+.x-staging
|
||||
@@ -19,12 +22,16 @@ on:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/build.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
|
||||
env:
|
||||
DEBUG: napi:*
|
||||
BUILD_TYPE: canary
|
||||
APP_NAME: affine
|
||||
COVERAGE: true
|
||||
MACOSX_DEPLOYMENT_TARGET: '10.13'
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
@@ -36,12 +43,42 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
- name: Run checks
|
||||
with:
|
||||
electron-install: false
|
||||
- name: Run i18n codegen
|
||||
run: yarn i18n-codegen gen
|
||||
- name: Run Type Check
|
||||
run: yarn typecheck
|
||||
- name: Run ESLint
|
||||
run: yarn lint:eslint --max-warnings=0
|
||||
- name: Run Prettier
|
||||
# Set nmMode in `actions/setup-node` will modify the .yarnrc.yml
|
||||
run: |
|
||||
yarn i18n-codegen gen
|
||||
yarn typecheck
|
||||
yarn lint --max-warnings=0
|
||||
yarn circular
|
||||
git checkout .yarnrc.yml
|
||||
yarn lint:prettier
|
||||
- name: Run circular
|
||||
run: yarn circular
|
||||
- name: Upload server dist
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: server-dist
|
||||
path: ./apps/server/dist
|
||||
if-no-files-found: error
|
||||
|
||||
build-docs:
|
||||
name: Build Docs
|
||||
runs-on: ubuntu-latest
|
||||
environment: development
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
- run: yarn nx build @affine/docs
|
||||
env:
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
|
||||
build-storybook:
|
||||
name: Build Storybook
|
||||
@@ -52,12 +89,16 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
- run: yarn nx build @affine/storybook
|
||||
env:
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
- name: Upload storybook artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: storybook
|
||||
path: ./packages/storybook/storybook-static
|
||||
path: ./apps/storybook/storybook-static
|
||||
if-no-files-found: error
|
||||
|
||||
build-web:
|
||||
@@ -69,45 +110,9 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
- name: Cache Next.js
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
${{ github.workspace }}/apps/web/.next/cache
|
||||
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-
|
||||
- name: Build Web
|
||||
run: yarn nx build @affine/web
|
||||
env:
|
||||
API_SERVER_PROFILE: local
|
||||
ENABLE_DEBUG_PAGE: 1
|
||||
ENABLE_PLUGIN: true
|
||||
ENABLE_ALL_PAGE_FILTER: true
|
||||
ENABLE_LEGACY_PROVIDER: true
|
||||
ENABLE_PRELOADING: false
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: next-js
|
||||
path: ./apps/web/.next
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Build Web (Desktop)
|
||||
run: yarn nx build @affine/web
|
||||
env:
|
||||
API_SERVER_PROFILE: affine
|
||||
ENABLE_DEBUG_PAGE: 1
|
||||
ENABLE_PLUGIN: true
|
||||
ENABLE_ALL_PAGE_FILTER: true
|
||||
ENABLE_LEGACY_PROVIDER: false
|
||||
ENABLE_PRELOADING: false
|
||||
|
||||
- name: Export static resources
|
||||
run: yarn workspace @affine/web export
|
||||
|
||||
- name: Upload static resources artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: next-js-static
|
||||
@@ -153,10 +158,24 @@ jobs:
|
||||
working-directory: apps/server
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
- name: Setup Rust
|
||||
uses: ./.github/actions/setup-rust
|
||||
with:
|
||||
target: 'x86_64-unknown-linux-gnu'
|
||||
- name: Build Storage
|
||||
run: yarn build:storage
|
||||
- name: Run server tests
|
||||
run: yarn nx test:coverage @affine/server
|
||||
run: yarn test:coverage
|
||||
working-directory: apps/server
|
||||
env:
|
||||
CARGO_TARGET_DIR: '${{ github.workspace }}/target'
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
- name: Upload storage.node
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: storage.node
|
||||
path: ./packages/storage/storage.node
|
||||
if-no-files-found: error
|
||||
- name: Upload server test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
@@ -164,7 +183,7 @@ jobs:
|
||||
files: ./apps/server/.coverage/lcov.info
|
||||
flags: server-test
|
||||
name: affine
|
||||
fail_ci_if_error: true
|
||||
fail_ci_if_error: false
|
||||
|
||||
storybook-test:
|
||||
name: Storybook Test
|
||||
@@ -177,13 +196,14 @@ jobs:
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
electron-install: false
|
||||
- name: Download storybook artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: storybook
|
||||
path: ./packages/storybook/storybook-static
|
||||
path: ./apps/storybook/storybook-static
|
||||
- name: Run storybook tests
|
||||
working-directory: ./packages/storybook
|
||||
working-directory: ./apps/storybook
|
||||
run: |
|
||||
yarn exec concurrently -k -s first -n "SB,TEST" -c "magenta,blue" "yarn exec serve ./storybook-static -l 6006" "yarn exec wait-on tcp:6006 && yarn test"
|
||||
|
||||
@@ -193,18 +213,9 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shard: [1, 2, 3, 4]
|
||||
shard: [1, 2, 3, 4, 5]
|
||||
environment: development
|
||||
needs: [build-web, build-storybook]
|
||||
services:
|
||||
octobase:
|
||||
image: ghcr.io/toeverything/cloud-self-hosted:nightly-latest
|
||||
ports:
|
||||
- 3000:3000
|
||||
env:
|
||||
SIGN_KEY: 'test123'
|
||||
RUST_LOG: 'debug'
|
||||
JWST_DEV: '1'
|
||||
needs: build-web
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -212,24 +223,16 @@ jobs:
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
electron-install: false
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: next-js
|
||||
path: ./apps/web/.next
|
||||
|
||||
- name: Download storybook artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: storybook
|
||||
path: ./packages/storybook/storybook-static
|
||||
|
||||
- name: Wait for Octobase Ready
|
||||
run: |
|
||||
node ./scripts/wait-3000-healthz.mjs
|
||||
name: next-js-static
|
||||
path: ./apps/web/out
|
||||
|
||||
- name: Run playwright tests
|
||||
run: yarn e2e --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
||||
working-directory: tests/affine-local
|
||||
env:
|
||||
COVERAGE: true
|
||||
|
||||
@@ -243,7 +246,7 @@ jobs:
|
||||
files: ./.coverage/lcov.info
|
||||
flags: e2etest
|
||||
name: affine
|
||||
fail_ci_if_error: true
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
@@ -253,6 +256,46 @@ jobs:
|
||||
path: ./test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
e2e-migration-test:
|
||||
name: E2E Migration Test
|
||||
runs-on: ubuntu-latest
|
||||
environment: development
|
||||
needs: [build-web]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
electron-install: false
|
||||
|
||||
- name: Download next static
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: next-js-static
|
||||
path: ./apps/web/out
|
||||
|
||||
- name: Unzip
|
||||
run: yarn unzip
|
||||
working-directory: ./tests/affine-legacy/0.7.0-canary.18
|
||||
|
||||
- name: Run legacy playwright tests
|
||||
run: yarn e2e --forbid-only
|
||||
working-directory: ./tests/affine-legacy/0.7.0-canary.18
|
||||
|
||||
- name: Run vitest
|
||||
run: yarn test
|
||||
working-directory: ./tests/affine-legacy/0.7.0-canary.18
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-migration
|
||||
path: ./tests/affine-legacy/0.7.0-canary.18/test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
desktop-test:
|
||||
name: Desktop Test
|
||||
runs-on: ${{ matrix.spec.os }}
|
||||
@@ -297,23 +340,30 @@ jobs:
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
hard-link-nm: false
|
||||
- name: Build AFFiNE native
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: ${{ matrix.spec.target }}
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
- name: Run unit tests
|
||||
if: ${{ matrix.spec.test }}
|
||||
shell: bash
|
||||
run: yarn nx test @affine/monorepo
|
||||
env:
|
||||
NATIVE_TEST: 'true'
|
||||
- name: Build layers
|
||||
run: yarn workspace @affine/electron build
|
||||
|
||||
- name: Download static resource artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: next-js-static
|
||||
path: ./apps/electron/resources/web-static
|
||||
path: apps/electron/resources/web-static
|
||||
|
||||
- name: Build Plugins
|
||||
run: yarn run build:plugins
|
||||
|
||||
- name: Build Desktop Layers
|
||||
run: yarn workspace @affine/electron build
|
||||
|
||||
- name: Run desktop tests
|
||||
if: ${{ matrix.spec.test && matrix.spec.os == 'ubuntu-latest' }}
|
||||
@@ -327,6 +377,17 @@ jobs:
|
||||
env:
|
||||
COVERAGE: true
|
||||
|
||||
- name: Make bundle
|
||||
if: ${{ matrix.spec.os == 'macos-latest' && matrix.spec.arch == 'arm64' }}
|
||||
run: yarn workspace @affine/electron make --platform=darwin --arch=arm64
|
||||
|
||||
- name: Bundle output check
|
||||
if: ${{ matrix.spec.os == 'macos-latest' && matrix.spec.arch == 'arm64' }}
|
||||
run: |
|
||||
./scripts/unzip-macos-arm64.sh
|
||||
yarn ts-node-esm ./scripts/macos-arm64-output-check.mts
|
||||
working-directory: apps/electron
|
||||
|
||||
- name: Collect code coverage report
|
||||
if: ${{ matrix.spec.test }}
|
||||
run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov
|
||||
@@ -339,12 +400,7 @@ jobs:
|
||||
files: ./.coverage/lcov.info
|
||||
flags: e2etest-${{ matrix.spec.os }}-${{ matrix.spec.arch }}
|
||||
name: affine
|
||||
fail_ci_if_error: true
|
||||
|
||||
- name: Run desktop tests
|
||||
if: ${{ matrix.spec.test && matrix.spec.os != 'ubuntu-latest' }}
|
||||
run: yarn test
|
||||
working-directory: apps/electron
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
@@ -358,20 +414,12 @@ jobs:
|
||||
name: Unit Test
|
||||
runs-on: ubuntu-latest
|
||||
environment: development
|
||||
services:
|
||||
octobase:
|
||||
image: ghcr.io/toeverything/cloud-self-hosted:nightly-latest
|
||||
ports:
|
||||
- 3000:3000
|
||||
env:
|
||||
SIGN_KEY: 'test123'
|
||||
RUST_LOG: 'debug'
|
||||
JWST_DEV: '1'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
electron-install: false
|
||||
|
||||
- name: Unit Test
|
||||
run: yarn nx test:coverage @affine/monorepo
|
||||
@@ -383,4 +431,80 @@ jobs:
|
||||
files: ./.coverage/store/lcov.info
|
||||
flags: unittest
|
||||
name: affine
|
||||
fail_ci_if_error: true
|
||||
fail_ci_if_error: false
|
||||
|
||||
build-docker:
|
||||
if: github.ref == 'refs/heads/master'
|
||||
name: Build Docker
|
||||
needs:
|
||||
- lint
|
||||
- desktop-test
|
||||
- server-test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Download next static
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: next-js-static
|
||||
path: ./apps/web/out
|
||||
- name: Download server dist
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: server-dist
|
||||
path: ./apps/server/dist
|
||||
- name: Download storage.node
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: storage.node
|
||||
path: ./apps/server
|
||||
- name: Setup Git short hash
|
||||
run: |
|
||||
echo "GIT_SHORT_HASH=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
logout: false
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Build front Dockerfile
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
pull: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
provenance: true
|
||||
file: .github/deployment/front/Dockerfile
|
||||
tags: ghcr.io/toeverything/affine-front:${{ env.GIT_SHORT_HASH }},ghcr.io/toeverything/affine-front:latest
|
||||
|
||||
# setup node without cache configuration
|
||||
# Prisma cache is not compatible with docker build cache
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
registry-url: https://npm.pkg.github.com
|
||||
scope: '@toeverything'
|
||||
|
||||
- name: Install Node.js dependencies
|
||||
run: yarn workspaces focus @affine/server --production
|
||||
|
||||
- name: Generate Prisma client
|
||||
run: yarn workspace @affine/server prisma generate
|
||||
|
||||
- name: Build graphql Dockerfile
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
pull: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
provenance: true
|
||||
file: .github/deployment/node/Dockerfile
|
||||
tags: ghcr.io/toeverything/affine-graphql:${{ env.GIT_SHORT_HASH }},ghcr.io/toeverything/affine-graphql:latest
|
||||
|
||||
18
.github/workflows/cancel.yml
vendored
Normal file
18
.github/workflows/cancel.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: Cancel
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- edited
|
||||
- synchronize
|
||||
|
||||
jobs:
|
||||
cancel:
|
||||
name: 'Cancel Previous Runs'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
steps:
|
||||
- uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
# See https://api.github.com/repos/toeverything/AFFiNE/actions/workflows
|
||||
workflow_id: 44038251, 61883931
|
||||
access_token: ${{ github.token }}
|
||||
1
.github/workflows/codeql.yml
vendored
1
.github/workflows/codeql.yml
vendored
@@ -15,6 +15,7 @@ on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
merge_group:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
|
||||
|
||||
66
.github/workflows/helm-releaser.yml
vendored
Normal file
66
.github/workflows/helm-releaser.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
name: Release Charts
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
paths:
|
||||
- '.github/helm/**/Chart.yml'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Checkout Helm chart repo
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: toeverything/helm-charts
|
||||
path: .helm-chart-repo
|
||||
ref: gh-pages
|
||||
token: ${{ secrets.HELM_RELEASER_TOKEN }}
|
||||
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@v3
|
||||
|
||||
- name: Install chart releaser
|
||||
run: |
|
||||
set -e
|
||||
arch="$(dpkg --print-architecture)"
|
||||
curl -s https://api.github.com/repos/helm/chart-releaser/releases/latest \
|
||||
| yq --indent 0 --no-colors --input-format json --unwrapScalar \
|
||||
".assets[] | select(.name | test("\""^chart-releaser_.+_linux_${arch}\.tar\.gz$"\"")) | .browser_download_url" \
|
||||
| xargs curl -SsL \
|
||||
| tar zxf - -C /usr/local/bin
|
||||
|
||||
- name: Package charts
|
||||
working-directory: .helm-chart-repo
|
||||
run: |
|
||||
mkdir -p .cr-index
|
||||
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||||
helm repo update
|
||||
|
||||
helm dependencies build ../.github/helm/affine
|
||||
helm dependencies build ../.github/helm/affine-cloud
|
||||
cr package ../.github/helm/affine
|
||||
cr package ../.github/helm/affine-cloud
|
||||
|
||||
- name: Publish charts
|
||||
working-directory: .helm-chart-repo
|
||||
run: |
|
||||
set -ex
|
||||
git config --local user.name "$GITHUB_ACTOR"
|
||||
git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||
owner=$(cut -d '/' -f 1 <<< '${{ github.repository }}')
|
||||
repo=helm-charts
|
||||
git_hash=$(git rev-parse HEAD)
|
||||
cr upload --commit "$git_hash" \
|
||||
--git-repo "$repo" --owner "$owner" \
|
||||
--token '${{ secrets.HELM_RELEASER_TOKEN }}' \
|
||||
--skip-existing
|
||||
cr index --git-repo "$repo" --owner "$owner" \
|
||||
--token '${{ secrets.HELM_RELEASER_TOKEN }}' \
|
||||
--index-path .cr-index --push
|
||||
2
.github/workflows/languages-sync.yml
vendored
2
.github/workflows/languages-sync.yml
vendored
@@ -6,11 +6,13 @@ on:
|
||||
paths:
|
||||
- 'packages/i18n/**'
|
||||
- '.github/workflows/languages-sync.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
pull_request_target:
|
||||
branches: ['master']
|
||||
paths:
|
||||
- 'packages/i18n/**'
|
||||
- '.github/workflows/languages-sync.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
15
.github/workflows/nightly-build.yml
vendored
15
.github/workflows/nightly-build.yml
vendored
@@ -11,6 +11,9 @@ on:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/nightly-build.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
@@ -31,7 +34,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
environment: production
|
||||
outputs:
|
||||
version: 0.0.0-${{ steps.version.outputs.version }}
|
||||
version: 0.0.0-internal.${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: toeverything/set-build-version@latest
|
||||
@@ -57,10 +60,6 @@ jobs:
|
||||
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
||||
NEXT_PUBLIC_SENTRY_DSN: ${{ secrets.NEXT_PUBLIC_SENTRY_DSN }}
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
API_SERVER_PROFILE: prod
|
||||
ENABLE_TEST_PROPERTIES: false
|
||||
ENABLE_IMAGE_PREVIEW_MODAL: false
|
||||
ENABLE_BOOKMARK_OPERATION: true
|
||||
RELEASE_VERSION: ${{ needs.set-build-version.outputs.version }}
|
||||
|
||||
- name: Upload Artifact (web-static)
|
||||
@@ -116,6 +115,7 @@ jobs:
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: ${{ matrix.spec.target }}
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
- name: Replace Version
|
||||
run: ./scripts/set-version.sh ${{ needs.set-build-version.outputs.version }}
|
||||
- uses: actions/download-artifact@v3
|
||||
@@ -123,7 +123,10 @@ jobs:
|
||||
name: before-make-web-static
|
||||
path: apps/electron/resources/web-static
|
||||
|
||||
- name: Build layers
|
||||
- name: Build Plugins
|
||||
run: yarn run build:plugins
|
||||
|
||||
- name: Build Desktop Layers
|
||||
run: yarn workspace @affine/electron build
|
||||
|
||||
- name: Signing By Apple Developer ID
|
||||
|
||||
54
.github/workflows/nx.yml
vendored
Normal file
54
.github/workflows/nx.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
name: NX
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- v[0-9]+.[0-9]+.x-staging
|
||||
- v[0-9]+.[0-9]+.x
|
||||
paths-ignore:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/nx.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
pull_request:
|
||||
merge_group:
|
||||
branches:
|
||||
- master
|
||||
- v[0-9]+.[0-9]+.x-staging
|
||||
- v[0-9]+.[0-9]+.x
|
||||
paths-ignore:
|
||||
- README.md
|
||||
- .github/**
|
||||
- '!.github/workflows/nx.yml'
|
||||
- '!.github/actions/build-rust/action.yml'
|
||||
- '!.github/actions/setup-node/action.yml'
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Nx Cloud - Main Job
|
||||
uses: nrwl/ci/.github/workflows/nx-cloud-main.yml@v0.13.0
|
||||
with:
|
||||
runs-on: macos-latest
|
||||
main-branch-name: master
|
||||
number-of-agents: 5
|
||||
init-commands: |
|
||||
yarn exec nx-cloud start-ci-run --stop-agents-after="build" --agent-count=5
|
||||
environment-variables: |
|
||||
BUILD_TYPE=canary
|
||||
# parallel-commands: |
|
||||
# yarn exec nx-cloud record -- yarn exec nx format:check
|
||||
parallel-commands-on-agents: |
|
||||
yarn exec nx affected --target=build --parallel=5
|
||||
timeout: 60
|
||||
|
||||
agents:
|
||||
name: Nx Cloud - Agents
|
||||
uses: nrwl/ci/.github/workflows/nx-cloud-agents.yml@v0.13.0
|
||||
with:
|
||||
runs-on: macos-latest
|
||||
number-of-agents: 5
|
||||
environment-variables: |
|
||||
BUILD_TYPE=canary
|
||||
timeout: 60
|
||||
52
.github/workflows/release-desktop-app.yml
vendored
52
.github/workflows/release-desktop-app.yml
vendored
@@ -1,6 +1,9 @@
|
||||
name: Release Desktop App
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-canary.[0-9]+'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
@@ -28,14 +31,8 @@ permissions:
|
||||
contents: write
|
||||
security-events: write
|
||||
|
||||
concurrency:
|
||||
# The concurrency group contains the workflow name and the branch name for
|
||||
# pull requests or the commit hash for any other events.
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
BUILD_TYPE: ${{ github.event.inputs.build-type }}
|
||||
BUILD_TYPE: ${{ github.event.inputs.build-type || (github.ref_type == 'tag' && contains(github.ref, 'canary') && 'canary') }}
|
||||
DEBUG: napi:*
|
||||
APP_NAME: affine
|
||||
MACOSX_DEPLOYMENT_TARGET: '10.13'
|
||||
@@ -43,22 +40,31 @@ env:
|
||||
jobs:
|
||||
before-make:
|
||||
runs-on: ubuntu-latest
|
||||
environment: ${{ github.ref_name == 'master' && 'production' || 'development' }}
|
||||
environment: production
|
||||
outputs:
|
||||
RELEASE_VERSION: ${{ steps.get-canary-version.outputs.RELEASE_VERSION }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
- name: Get canary version
|
||||
id: get-canary-version
|
||||
if: ${{ github.ref_type == 'tag' }}
|
||||
run: |
|
||||
TAG_VERSION=${GITHUB_REF#refs/tags/v}
|
||||
PACKAGE_VERSION=$(node -p "require('./apps/electron/package.json').version")
|
||||
if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then
|
||||
echo "Tag version ($TAG_VERSION) does not match package.json version ($PACKAGE_VERSION)"
|
||||
exit 1
|
||||
fi
|
||||
echo "RELEASE_VERSION=$(node -p "require('./apps/electron/package.json').version")" >> $GITHUB_OUTPUT
|
||||
- name: generate-assets
|
||||
run: yarn workspace @affine/electron generate-assets
|
||||
env:
|
||||
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
|
||||
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
API_SERVER_PROFILE: prod
|
||||
ENABLE_TEST_PROPERTIES: false
|
||||
ENABLE_IMAGE_PREVIEW_MODAL: false
|
||||
ENABLE_BOOKMARK_OPERATION: true
|
||||
RELEASE_VERSION: ${{ github.event.inputs.version }}
|
||||
RELEASE_VERSION: ${{ github.event.inputs.version || steps.get-canary-version.outputs.RELEASE_VERSION }}
|
||||
|
||||
- name: Upload Artifact (web-static)
|
||||
uses: actions/upload-artifact@v3
|
||||
@@ -67,7 +73,7 @@ jobs:
|
||||
path: apps/electron/resources/web-static
|
||||
|
||||
make-distribution:
|
||||
environment: ${{ github.ref_name == 'master' && 'production' || 'development' }}
|
||||
environment: production
|
||||
strategy:
|
||||
# all combinations: macos-latest x64, macos-latest arm64, windows-latest x64, ubuntu-latest x64
|
||||
matrix:
|
||||
@@ -111,12 +117,16 @@ jobs:
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: ${{ matrix.spec.target }}
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: before-make-web-static
|
||||
path: apps/electron/resources/web-static
|
||||
|
||||
- name: Build layers
|
||||
- name: Build Plugins
|
||||
run: yarn run build:plugins
|
||||
|
||||
- name: Build Desktop Layers
|
||||
run: yarn workspace @affine/electron build
|
||||
|
||||
- name: Signing By Apple Developer ID
|
||||
@@ -157,7 +167,7 @@ jobs:
|
||||
path: builds
|
||||
|
||||
release:
|
||||
needs: make-distribution
|
||||
needs: [before-make, make-distribution]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -190,16 +200,16 @@ jobs:
|
||||
cp ./apps/electron/scripts/generate-yml.js .
|
||||
node generate-yml.js
|
||||
env:
|
||||
RELEASE_VERSION: ${{ github.event.inputs.version }}
|
||||
RELEASE_VERSION: ${{ github.event.inputs.version || needs.before-make.outputs.RELEASE_VERSION }}
|
||||
- name: Create Release Draft
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
with:
|
||||
name: Desktop APP ${{ github.event.inputs.version }}
|
||||
body: 'TODO: Add release notes here'
|
||||
draft: ${{ github.event.inputs.is-draft }}
|
||||
prerelease: ${{ github.event.inputs.is-pre-release }}
|
||||
name: ${{ github.event.inputs.version || needs.before-make.outputs.RELEASE_VERSION }}
|
||||
body: ''
|
||||
draft: ${{ github.event.inputs.is-draft || true }}
|
||||
prerelease: ${{ github.event.inputs.is-pre-release || needs.before-make.outputs.version }}
|
||||
files: |
|
||||
./VERSION
|
||||
./*.zip
|
||||
|
||||
22
.github/workflows/workers.yml
vendored
Normal file
22
.github/workflows/workers.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Deploy Cloudflare Worker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- packages/workers/**
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy
|
||||
environment: production
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Publish
|
||||
uses: cloudflare/wrangler-action@2.0.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: 'packages/workers'
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -55,13 +55,15 @@ Thumbs.db
|
||||
.history
|
||||
|
||||
.next
|
||||
.vercel
|
||||
out/
|
||||
storybook-static
|
||||
i18n-generated.ts
|
||||
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/playwright/.cache/
|
||||
test-results
|
||||
playwright-report
|
||||
playwright/.cache
|
||||
download
|
||||
|
||||
# Cache
|
||||
.eslintcache
|
||||
|
||||
@@ -2,7 +2,22 @@
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
# check lockfile is up to date
|
||||
yarn install
|
||||
yarn install --mode=skip-build --inline-builds --immutable
|
||||
|
||||
# build infra code
|
||||
yarn -T run build:infra
|
||||
|
||||
# generate prisma client type
|
||||
yarn workspace @affine/server prisma generate
|
||||
|
||||
# generate i18n
|
||||
yarn i18n-codegen gen
|
||||
|
||||
# lint staged files
|
||||
yarn exec lint-staged
|
||||
|
||||
# type check
|
||||
yarn typecheck
|
||||
|
||||
# circular dependency check
|
||||
yarn circular
|
||||
|
||||
1
.npmrc
1
.npmrc
@@ -1,2 +1,3 @@
|
||||
shell-emulator=true
|
||||
electron_mirror="https://cdn.npmmirror.com/binaries/electron/"
|
||||
engine-strict=true
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
target
|
||||
lib
|
||||
test-results
|
||||
packages/i18n/src/i18n-generated.ts
|
||||
packages/graphql/src/graphql/index.ts
|
||||
.next
|
||||
out
|
||||
dist
|
||||
.yarn
|
||||
tests/affine-legacy/0.7.0-canary.18/static
|
||||
.github/helm
|
||||
_next
|
||||
storybook-static
|
||||
|
||||
19
README.md
19
README.md
@@ -2,13 +2,13 @@
|
||||
|
||||
<h1 style="border-bottom: none">
|
||||
<b><a href="https://affine.pro">AFFiNE.PRO</a></b><br />
|
||||
The Next-Gen Collaborative Knowledge Base
|
||||
Write, Draw and Plan All at Once
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
AFFiNE is a next-gen knowledge base that brings planning, sorting and creating all together.<br />
|
||||
Privacy first, open-source, customizable and ready to use - a free replacement for Notion & Miro. <br />
|
||||
One hyper-fused platform for wildly creative minds. <br />
|
||||
A privacy-focussed, local-first, open-source, and ready-to-use alternative for Notion & Miro.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
@@ -60,7 +60,7 @@ See https://github.com/all-?/all-contributors/issues/361#issuecomment-637166066
|
||||
|
||||
<br />
|
||||
<div align="center">
|
||||
<em>See docs, canvas and tables are hyper merged with AFFiNE - just like the word affine (əˈfʌɪn | a-fine).</em>
|
||||
<em>Docs, canvas and tables are hyper-merged with AFFiNE - just like the word affine (əˈfʌɪn | a-fine).</em>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
@@ -123,6 +123,8 @@ If you have questions, you are welcome to contact us. One of the best places to
|
||||
## Plugins
|
||||
|
||||
> Plugins are a way to extend the functionality of AFFiNE.
|
||||
>
|
||||
> (Currently, plugins are under heavy development, and the SDK is not yet available.)
|
||||
|
||||
| Name | |
|
||||
| ------------------------------------------------ | ----------------------------------------- |
|
||||
@@ -135,7 +137,7 @@ We would also like to give thanks to open-source projects that make AFFiNE possi
|
||||
|
||||
- [BlockSuite](https://github.com/toeverything/BlockSuite) - 💠 BlockSuite is the open-source collaborative editor project behind AFFiNE.
|
||||
- [OctoBase](https://github.com/toeverything/OctoBase) - 🐙 OctoBase is the open-source database behind AFFiNE, local-first, yet collaborative. A light-weight, scalable, data engine written in Rust.
|
||||
- [Yjs](https://github.com/yjs/yjs) & [Yrs](https://github.com/y-crdt/y-crdt) - Fundamental support of CRDTs for our implementation on state management and data sync.
|
||||
- [Yjs](https://github.com/yjs/yjs) - Fundamental support of CRDTs for our implementation on state management and data sync.
|
||||
- [Electron](https://github.com/electron/electron) - Build cross-platform desktop apps with JavaScript, HTML, and CSS.
|
||||
- [React](https://github.com/facebook/react) - View layer support and web GUI framework.
|
||||
- [Rust](https://github.com/rust-lang/rust) - High performance language that extends the ability and availability of our real-time backend, OctoBase.
|
||||
@@ -156,7 +158,8 @@ We would like to express our gratitude to all the individuals who have already c
|
||||
|
||||
## Self-Host
|
||||
|
||||
Get started with Docker and deploy your own feature-rich, restriction-free deployment of AFFiNE - check the [latest packages].
|
||||
Get started with Docker and deploy your own feature-rich, restriction-free deployment of AFFiNE.
|
||||
We are working hard to get this updated to the latest version, you can keep an eye on the [latest packages].
|
||||
|
||||
## Hiring
|
||||
|
||||
@@ -197,7 +200,7 @@ See [LICENSE] for details.
|
||||
[rust-version-icon]: https://img.shields.io/badge/Rust-1.70.0-dea584
|
||||
[stars-icon]: https://img.shields.io/github/stars/toeverything/AFFiNE.svg?style=flat&logo=github&colorB=red&label=stars
|
||||
[codecov]: https://codecov.io/gh/toeverything/affine/branch/master/graphs/badge.svg?branch=master
|
||||
[node-version-icon]: https://img.shields.io/badge/node-%3E=18.16.0-success
|
||||
[node-version-icon]: https://img.shields.io/badge/node-%3E=18.16.1-success
|
||||
[typescript-version-icon]: https://img.shields.io/github/package-json/dependency-version/toeverything/affine/dev/typescript
|
||||
[react-version-icon]: https://img.shields.io/github/package-json/dependency-version/toeverything/affine/dev/react?color=rgb%2897%2C%20218%2C%20251%29
|
||||
[react-version-icon]: https://img.shields.io/github/package-json/dependency-version/toeverything/AFFiNE/react?filename=apps%2Fweb%2Fpackage.json&color=rgb(97%2C228%2C251)
|
||||
[blocksuite-icon]: https://img.shields.io/github/package-json/dependency-version/toeverything/AFFiNE/@blocksuite/store?color=6880ff&filename=apps%2Fweb%2Fpackage.json&label=blocksuite
|
||||
|
||||
25
apps/README.md
Normal file
25
apps/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Apps structure
|
||||
|
||||
> This is the structure of the `apps` directory.
|
||||
|
||||
## docs
|
||||
|
||||
AFFiNE Developer Documentation using [waku](https://github.com/dai-shi/waku).
|
||||
|
||||
## electron
|
||||
|
||||
> `web` needs to be built before electron.
|
||||
|
||||
AFFiNE Desktop (macOS, Linux and Windows Distribution) using [Electron](https://www.electronjs.org/).
|
||||
|
||||
## server
|
||||
|
||||
Server using [Nest.js](https://nestjs.com/).
|
||||
|
||||
## storybook
|
||||
|
||||
Storybook using [Storybook](https://storybook.js.org/).
|
||||
|
||||
## web
|
||||
|
||||
AFFiNE Core Application using [React.js](https://reactjs.org/).
|
||||
17
apps/docs/entries.ts
Normal file
17
apps/docs/entries.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { defineRouter } from 'waku/router/server';
|
||||
|
||||
export default defineRouter(
|
||||
async id => {
|
||||
switch (id) {
|
||||
case 'index': {
|
||||
const { default: AppCreator } = await import('./src/app.js');
|
||||
return AppCreator(id);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
async () => {
|
||||
return ['index'];
|
||||
}
|
||||
);
|
||||
36
apps/docs/index.html
Normal file
36
apps/docs/index.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>AFFiNE Developer Documentation</title>
|
||||
<style>
|
||||
@keyframes spinner {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.spinner {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin: auto;
|
||||
border: 2px solid #ddd;
|
||||
border-top-color: #222;
|
||||
border-radius: 50%;
|
||||
animation: spinner 1s linear infinite;
|
||||
}
|
||||
#root > .spinner {
|
||||
margin-top: calc(50% - 18px);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!--placeholder1-->
|
||||
<div id="root">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
<!--/placeholder1-->
|
||||
<script src="./src/index.tsx" defer type="module"></script>
|
||||
<!--placeholder2-->
|
||||
<!--/placeholder2-->
|
||||
</body>
|
||||
</html>
|
||||
35
apps/docs/package.json
Normal file
35
apps/docs/package.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "@affine/docs",
|
||||
"version": "0.7.1",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "waku dev",
|
||||
"build": "waku build",
|
||||
"build:vercel": "waku build && cp -Lr ./dist/.vercel/output ./.vercel/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@affine/component": "workspace:*",
|
||||
"@blocksuite/block-std": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/blocks": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/global": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230717055529-79180930-nightly",
|
||||
"express": "^4.18.2",
|
||||
"jotai": "^2.2.2",
|
||||
"react": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-dom": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"react-server-dom-webpack": "18.3.0-canary-1fdacbefd-20230630",
|
||||
"waku": "0.12.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.14",
|
||||
"@types/react-dom": "^18.2.6",
|
||||
"@vanilla-extract/css": "^1.12.0",
|
||||
"@vanilla-extract/vite-plugin": "^3.8.2",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"typescript": "^5.1.6"
|
||||
}
|
||||
}
|
||||
6
apps/docs/postcss.config.mjs
Normal file
6
apps/docs/postcss.config.mjs
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
44
apps/docs/src/app.tsx
Normal file
44
apps/docs/src/app.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
/// <reference types="vite/client" />
|
||||
'use server';
|
||||
import { existsSync, readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import type { ReactElement } from 'react';
|
||||
import { lazy } from 'react';
|
||||
|
||||
import { Sidebar } from './components/sidebar/index.js';
|
||||
import { saveFile } from './server-fns.js';
|
||||
|
||||
const Editor = lazy(() =>
|
||||
import('./components/editor.js').then(({ Editor }) => ({ default: Editor }))
|
||||
);
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
const AppCreator = (pathname: string) =>
|
||||
function App(): ReactElement {
|
||||
let path = resolve(__dirname, 'pages', 'binary');
|
||||
if (!existsSync(path)) {
|
||||
path = resolve(__dirname, '..', '..', 'src', 'pages', 'binary');
|
||||
}
|
||||
const buffer = [...readFileSync(path)];
|
||||
|
||||
return (
|
||||
<div className="flex flex-col-reverse sm:flex-row h-screen">
|
||||
<nav className="w-full sm:w-64">
|
||||
<Sidebar />
|
||||
</nav>
|
||||
<main className="flex-1 p-6 w-full sm:w-[calc(100%-16rem)] overflow-scroll">
|
||||
<Editor
|
||||
workspaceId={pathname}
|
||||
pageId="1"
|
||||
onSave={saveFile}
|
||||
binary={buffer}
|
||||
/>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AppCreator;
|
||||
11
apps/docs/src/atom.ts
Normal file
11
apps/docs/src/atom.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
|
||||
import { atom } from 'jotai/vanilla';
|
||||
|
||||
export const workspaceAtom = atom(async () => {
|
||||
const { Workspace } = await import('@blocksuite/store');
|
||||
return new Workspace({
|
||||
id: 'test-workspace',
|
||||
})
|
||||
.register(AffineSchemas)
|
||||
.register(__unstableSchemas);
|
||||
});
|
||||
53
apps/docs/src/components/editor.tsx
Normal file
53
apps/docs/src/components/editor.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
'use client';
|
||||
import '@blocksuite/editor/themes/affine.css';
|
||||
|
||||
import { BlockSuiteEditor } from '@affine/component/block-suite-editor';
|
||||
import type { Page } from '@blocksuite/store';
|
||||
import { useAtomValue } from 'jotai/react';
|
||||
import type { ReactElement } from 'react';
|
||||
import { use } from 'react';
|
||||
import { applyUpdate } from 'yjs';
|
||||
|
||||
import { workspaceAtom } from '../atom.js';
|
||||
|
||||
export type EditorProps = {
|
||||
workspaceId: string;
|
||||
pageId: string;
|
||||
binary?: number[];
|
||||
onSave: (binary: any) => Promise<void>;
|
||||
};
|
||||
|
||||
export const Editor = (props: EditorProps): ReactElement => {
|
||||
const workspace = useAtomValue(workspaceAtom);
|
||||
let page = workspace.getPage('page0') as Page;
|
||||
if (!page) {
|
||||
page = workspace.createPage({
|
||||
id: 'page0',
|
||||
});
|
||||
}
|
||||
|
||||
if (props.binary && !page.root) {
|
||||
use(
|
||||
page.waitForLoaded().then(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
applyUpdate(page._ySpaceDoc, new Uint8Array(props.binary as number[]));
|
||||
})
|
||||
);
|
||||
if (import.meta.env.MODE !== 'development') {
|
||||
page.awarenessStore.setReadonly(page, true);
|
||||
}
|
||||
} else if (!page.root) {
|
||||
use(
|
||||
page.waitForLoaded().then(() => {
|
||||
const pageBlockId = page.addBlock('affine:page', {
|
||||
title: new page.Text(''),
|
||||
});
|
||||
page.addBlock('affine:surface', {}, pageBlockId);
|
||||
const noteBlockId = page.addBlock('affine:note', {}, pageBlockId);
|
||||
page.addBlock('affine:paragraph', {}, noteBlockId);
|
||||
})
|
||||
);
|
||||
}
|
||||
return <BlockSuiteEditor page={page} mode="page" onInit={() => {}} />;
|
||||
};
|
||||
31
apps/docs/src/components/sidebar/index.tsx
Normal file
31
apps/docs/src/components/sidebar/index.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
'use server';
|
||||
|
||||
import { lazy } from 'react';
|
||||
|
||||
import { saveFile } from '../../server-fns.js';
|
||||
|
||||
const SaveToLocal = lazy(() =>
|
||||
import('./save-to-local.js').then(({ SaveToLocal }) => ({
|
||||
default: SaveToLocal,
|
||||
}))
|
||||
);
|
||||
|
||||
export const Sidebar = () => {
|
||||
return (
|
||||
<div
|
||||
className="h-screen text-black overflow-y-auto"
|
||||
style={{
|
||||
backgroundColor: '#f9f7f7',
|
||||
}}
|
||||
>
|
||||
<a href="/">
|
||||
<div className="flex items-center justify-center h-16 font-bold">
|
||||
AFFiNE
|
||||
</div>
|
||||
</a>
|
||||
{import.meta.env.MODE === 'development' && (
|
||||
<SaveToLocal saveFile={saveFile} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
28
apps/docs/src/components/sidebar/save-to-local.tsx
Normal file
28
apps/docs/src/components/sidebar/save-to-local.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
'use client';
|
||||
import { assertExists } from '@blocksuite/global/utils';
|
||||
import { useAtomValue } from 'jotai/react';
|
||||
import { useCallback } from 'react';
|
||||
import { encodeStateAsUpdate } from 'yjs';
|
||||
|
||||
import { workspaceAtom } from '../../atom.js';
|
||||
|
||||
type SaveToLocalProps = {
|
||||
saveFile: (update: number[]) => void;
|
||||
};
|
||||
|
||||
export const SaveToLocal = (props: SaveToLocalProps) => {
|
||||
const workspace = useAtomValue(workspaceAtom);
|
||||
const saveFile = props.saveFile;
|
||||
const onSave = useCallback(() => {
|
||||
const page = workspace.getPage('page0');
|
||||
assertExists(page);
|
||||
saveFile([...encodeStateAsUpdate(page.spaceDoc)]);
|
||||
}, [saveFile, workspace]);
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center justify-center h-16 font-bold">
|
||||
<button onClick={onSave}>Save to Local</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
3
apps/docs/src/index.css
Normal file
3
apps/docs/src/index.css
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
14
apps/docs/src/index.tsx
Normal file
14
apps/docs/src/index.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import '@blocksuite/editor/themes/affine.css';
|
||||
import './index.css';
|
||||
|
||||
import { StrictMode } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { Router } from 'waku/router/client';
|
||||
|
||||
const root = createRoot(document.getElementById('root') as HTMLElement);
|
||||
|
||||
root.render(
|
||||
<StrictMode>
|
||||
<Router />
|
||||
</StrictMode>
|
||||
);
|
||||
BIN
apps/docs/src/pages/binary
Normal file
BIN
apps/docs/src/pages/binary
Normal file
Binary file not shown.
10
apps/docs/src/server-fns.ts
Normal file
10
apps/docs/src/server-fns.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
'use server';
|
||||
import { writeFile } from 'node:fs/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
|
||||
export async function saveFile(binary: any) {
|
||||
const data = new Uint8Array(binary);
|
||||
await writeFile(__dirname + 'pages' + '/binary', data);
|
||||
}
|
||||
8
apps/docs/tailwind.config.mjs
Normal file
8
apps/docs/tailwind.config.mjs
Normal file
@@ -0,0 +1,8 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ['./index.html', './src/**/*.{ts,tsx}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
24
apps/docs/tsconfig.json
Normal file
24
apps/docs/tsconfig.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "Node16",
|
||||
"strict": true,
|
||||
"target": "esnext",
|
||||
"downlevelIteration": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "NodeNext",
|
||||
"skipLibCheck": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": ["src", "entries.ts"],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.node.json"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/component"
|
||||
}
|
||||
]
|
||||
}
|
||||
14
apps/docs/tsconfig.node.json
Normal file
14
apps/docs/tsconfig.node.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "Node16",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"outDir": "dist/scripts",
|
||||
"rootDir": "."
|
||||
},
|
||||
"include": ["vite.config.ts", "vite.prod.config.ts"]
|
||||
}
|
||||
13
apps/docs/vite.config.ts
Normal file
13
apps/docs/vite.config.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import path from 'node:path';
|
||||
import url from 'node:url';
|
||||
|
||||
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
|
||||
import { defineConfig } from 'waku/config';
|
||||
|
||||
export default defineConfig({
|
||||
root: path.dirname(url.fileURLToPath(import.meta.url)),
|
||||
plugins: [vanillaExtractPlugin()],
|
||||
build: {
|
||||
target: 'esnext',
|
||||
},
|
||||
});
|
||||
2
apps/electron/.gitignore
vendored
2
apps/electron/.gitignore
vendored
@@ -13,3 +13,5 @@ resources/web-static
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
dev.json
|
||||
|
||||
zip-out
|
||||
|
||||
@@ -140,3 +140,44 @@ test('affine onboarding button', async ({ page }) => {
|
||||
|
||||
expect(await onboardingModal.isVisible()).toEqual(false);
|
||||
});
|
||||
|
||||
test('windows only check', async ({ page }) => {
|
||||
const windowOnlyUI = page.locator('[data-platform-target=win32]');
|
||||
if (process.platform === 'win32') {
|
||||
await expect(windowOnlyUI).toBeVisible();
|
||||
} else {
|
||||
await expect(windowOnlyUI).not.toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('delete workspace', async ({ page }) => {
|
||||
await page.getByTestId('current-workspace').click();
|
||||
await page.getByTestId('add-or-new-workspace').click();
|
||||
await page.getByTestId('new-workspace').click();
|
||||
await page.getByTestId('create-workspace-default-location-button').click();
|
||||
await page.getByTestId('create-workspace-input').type('Delete Me');
|
||||
await page.getByTestId('create-workspace-create-button').click();
|
||||
await page.getByTestId('create-workspace-continue-button').click();
|
||||
await page.getByTestId('slider-bar-workspace-setting-button').click();
|
||||
await page.getByTestId('current-workspace-label').click();
|
||||
expect(await page.getByTestId('workspace-name-input').inputValue()).toBe(
|
||||
'Delete Me'
|
||||
);
|
||||
const contentElement = await page.getByTestId('setting-modal-content');
|
||||
const boundingBox = await contentElement.boundingBox();
|
||||
if (!boundingBox) {
|
||||
throw new Error('boundingBox is null');
|
||||
}
|
||||
await page.mouse.move(
|
||||
boundingBox.x + boundingBox.width / 2,
|
||||
boundingBox.y + boundingBox.height / 2
|
||||
);
|
||||
await page.mouse.wheel(0, 500);
|
||||
await page.getByTestId('delete-workspace-button').click();
|
||||
await page.getByTestId('delete-workspace-input').type('Delete Me');
|
||||
await page.getByTestId('delete-workspace-confirm-button').click();
|
||||
await page.waitForTimeout(1000);
|
||||
expect(await page.getByTestId('workspace-name').textContent()).toBe(
|
||||
'Demo Workspace'
|
||||
);
|
||||
});
|
||||
@@ -16,6 +16,8 @@ function generateUUID() {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
|
||||
type RoutePath = 'setting';
|
||||
|
||||
export const test = base.extend<{
|
||||
page: Page;
|
||||
electronApp: ElectronApplication;
|
||||
@@ -24,9 +26,8 @@ export const test = base.extend<{
|
||||
appData: string;
|
||||
sessionData: string;
|
||||
};
|
||||
workspace: {
|
||||
// get current workspace
|
||||
current: () => Promise<any>; // todo: type
|
||||
router: {
|
||||
goto: (path: RoutePath) => Promise<void>;
|
||||
};
|
||||
}>({
|
||||
page: async ({ electronApp }, use) => {
|
||||
@@ -41,10 +42,6 @@ export const test = base.extend<{
|
||||
});
|
||||
});
|
||||
}
|
||||
const logFilePath = await page.evaluate(async () => {
|
||||
// @ts-expect-error
|
||||
return window.apis?.debug.logFilePath();
|
||||
});
|
||||
// wat for blocksuite to be loaded
|
||||
await page.waitForSelector('v-line');
|
||||
if (enableCoverage) {
|
||||
@@ -71,10 +68,6 @@ export const test = base.extend<{
|
||||
);
|
||||
}
|
||||
await page.close();
|
||||
if (logFilePath) {
|
||||
const logs = await fs.readFile(logFilePath, 'utf-8');
|
||||
console.log(logs);
|
||||
}
|
||||
},
|
||||
electronApp: async ({}, use) => {
|
||||
// a random id to avoid conflicts between tests
|
||||
@@ -124,14 +117,4 @@ export const test = base.extend<{
|
||||
});
|
||||
await use(appInfo);
|
||||
},
|
||||
workspace: async ({ page }, use) => {
|
||||
await use({
|
||||
current: async () => {
|
||||
return await page.evaluate(async () => {
|
||||
// @ts-expect-error
|
||||
return globalThis.currentWorkspace;
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -17,11 +17,13 @@ test('check workspace has a DB file', async ({ appInfo, workspace }) => {
|
||||
expect(await fs.exists(dbPath)).toBe(true);
|
||||
});
|
||||
|
||||
test('move workspace db file', async ({ page, appInfo, workspace }) => {
|
||||
test.skip('move workspace db file', async ({ page, appInfo, workspace }) => {
|
||||
const w = await workspace.current();
|
||||
const settingButton = page.getByTestId('slider-bar-workspace-setting-button');
|
||||
// goto settings
|
||||
await settingButton.click();
|
||||
await page.getByTestId('slider-bar-workspace-setting-button').click();
|
||||
await expect(page.getByTestId('setting-modal')).toBeVisible();
|
||||
|
||||
// goto workspace setting
|
||||
await page.getByTestId('workspace-list-item').click();
|
||||
|
||||
const tmpPath = path.join(appInfo.sessionData, w.id + '-tmp-dir');
|
||||
|
||||
@@ -44,19 +46,24 @@ test('move workspace db file', async ({ page, appInfo, workspace }) => {
|
||||
|
||||
test('export then add', async ({ page, appInfo, workspace }) => {
|
||||
const w = await workspace.current();
|
||||
const settingButton = page.getByTestId('slider-bar-workspace-setting-button');
|
||||
// goto settings
|
||||
await settingButton.click();
|
||||
|
||||
await page.getByTestId('slider-bar-workspace-setting-button').click();
|
||||
await expect(page.getByTestId('setting-modal')).toBeVisible();
|
||||
|
||||
const originalId = w.id;
|
||||
|
||||
const newWorkspaceName = 'new-test-name';
|
||||
|
||||
// goto workspace setting
|
||||
await page.getByTestId('workspace-list-item').click();
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// change workspace name
|
||||
await page.getByTestId('workspace-name-input').fill(newWorkspaceName);
|
||||
await page.getByTestId('save-workspace-name').click();
|
||||
await page.waitForSelector('text="Update workspace name success"');
|
||||
await page.click('[data-tab-key="export"]');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const tmpPath = path.join(appInfo.sessionData, w.id + '-tmp.db');
|
||||
|
||||
@@ -73,10 +80,11 @@ test('export then add', async ({ page, appInfo, workspace }) => {
|
||||
|
||||
expect(await fs.exists(tmpPath)).toBe(true);
|
||||
|
||||
await page.getByTestId('modal-close-button').click();
|
||||
|
||||
// add workspace
|
||||
// we are reusing the same db file so that we don't need to maintain one
|
||||
// in the codebase
|
||||
|
||||
await page.getByTestId('current-workspace').click();
|
||||
await page.getByTestId('add-or-new-workspace').click();
|
||||
|
||||
@@ -26,6 +26,8 @@ const arch =
|
||||
? process.argv[process.argv.indexOf('--arch') + 1]
|
||||
: process.arch;
|
||||
|
||||
const windowsIconUrl = `https://cdn.affine.pro/app-icons/icon_${buildType}.ico`;
|
||||
|
||||
/**
|
||||
* @type {import('@electron-forge/shared-types').ForgeConfig}
|
||||
*/
|
||||
@@ -52,6 +54,8 @@ module.exports = {
|
||||
teamId: process.env.APPLE_TEAM_ID,
|
||||
}
|
||||
: undefined,
|
||||
// We need the following line for updater
|
||||
extraResource: ['./resources/app-update.yml'],
|
||||
},
|
||||
makers: [
|
||||
{
|
||||
@@ -93,6 +97,7 @@ module.exports = {
|
||||
config: {
|
||||
name: 'AFFiNE',
|
||||
setupIcon: icoPath,
|
||||
iconUrl: windowsIconUrl,
|
||||
loadingGif: './resources/icons/affine_installing.gif',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@affine/electron",
|
||||
"private": true,
|
||||
"version": "0.6.1",
|
||||
"version": "0.7.1",
|
||||
"author": "affine",
|
||||
"repository": {
|
||||
"url": "https://github.com/toeverything/AFFiNE",
|
||||
@@ -11,49 +11,45 @@
|
||||
"homepage": "https://github.com/toeverything/AFFiNE",
|
||||
"scripts": {
|
||||
"dev": "yarn cross-env DEV_SERVER_URL=http://localhost:8080 node scripts/dev.mjs",
|
||||
"watch": "yarn cross-env DEV_SERVER_URL=http://localhost:8080 node scripts/dev.mjs --watch",
|
||||
"prod": "yarn node scripts/dev.mjs",
|
||||
"build": "zx scripts/build-layers.mjs",
|
||||
"dev:prod": "yarn node scripts/dev.mjs",
|
||||
"build": "NODE_ENV=production zx scripts/build-layers.mjs",
|
||||
"generate-assets": "zx scripts/generate-assets.mjs",
|
||||
"package": "electron-forge package",
|
||||
"make": "electron-forge make",
|
||||
"test": "DEBUG=pw:browser playwright test"
|
||||
"test": "DEBUG=pw:browser yarn -T run playwright test -c ./playwright.config.ts"
|
||||
},
|
||||
"config": {
|
||||
"forge": "./forge.config.js"
|
||||
},
|
||||
"main": "./dist/main.js",
|
||||
"exports": {
|
||||
"./scripts/plugins/build-plugins.mjs": "./scripts/plugins/build-plugins.mjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@affine-test/kit": "workspace:*",
|
||||
"@affine/env": "workspace:*",
|
||||
"@affine/native": "workspace:*",
|
||||
"@blocksuite/blocks": "0.0.0-20230607055421-9b20fcaf-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230607055421-9b20fcaf-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230607055421-9b20fcaf-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230607055421-9b20fcaf-nightly",
|
||||
"@electron-forge/cli": "^6.1.1",
|
||||
"@electron-forge/core": "^6.1.1",
|
||||
"@electron-forge/core-utils": "^6.1.1",
|
||||
"@electron-forge/maker-deb": "^6.1.1",
|
||||
"@electron-forge/maker-dmg": "^6.1.1",
|
||||
"@electron-forge/maker-squirrel": "^6.1.1",
|
||||
"@electron-forge/maker-zip": "^6.1.1",
|
||||
"@electron-forge/shared-types": "^6.1.1",
|
||||
"@electron/remote": "2.0.9",
|
||||
"@blocksuite/blocks": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/editor": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/lit": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@blocksuite/store": "0.0.0-20230717055529-79180930-nightly",
|
||||
"@electron-forge/cli": "^6.2.1",
|
||||
"@electron-forge/core": "^6.2.1",
|
||||
"@electron-forge/core-utils": "^6.2.1",
|
||||
"@electron-forge/maker-deb": "^6.2.1",
|
||||
"@electron-forge/maker-dmg": "^6.2.1",
|
||||
"@electron-forge/maker-squirrel": "^6.2.1",
|
||||
"@electron-forge/maker-zip": "^6.2.1",
|
||||
"@electron-forge/shared-types": "^6.2.1",
|
||||
"@electron/remote": "2.0.10",
|
||||
"@toeverything/infra": "workspace:*",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@types/uuid": "^9.0.1",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"cross-env": "7.0.3",
|
||||
"electron": "=25.0.1",
|
||||
"electron": "^25.2.0",
|
||||
"electron-log": "^5.0.0-beta.24",
|
||||
"electron-squirrel-startup": "1.0.0",
|
||||
"electron-window-state": "^5.0.3",
|
||||
"esbuild": "^0.17.19",
|
||||
"esbuild": "^0.18.11",
|
||||
"fs-extra": "^11.1.1",
|
||||
"jotai": "^2.1.1",
|
||||
"playwright": "=1.33.0",
|
||||
"jotai": "^2.2.2",
|
||||
"ts-node": "^10.9.1",
|
||||
"undici": "^5.22.1",
|
||||
"uuid": "^9.0.0",
|
||||
@@ -63,12 +59,12 @@
|
||||
"dependencies": {
|
||||
"@toeverything/plugin-infra": "workspace:*",
|
||||
"async-call-rpc": "^6.3.1",
|
||||
"electron-updater": "^5.3.0",
|
||||
"electron-updater": "^6.0.0",
|
||||
"link-preview-js": "^3.0.4",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nanoid": "^4.0.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"yjs": "^13.6.1"
|
||||
"yjs": "^13.6.6"
|
||||
},
|
||||
"build": {
|
||||
"protocols": [
|
||||
@@ -85,7 +81,6 @@
|
||||
"hoistingLimits": "workspaces"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"playwright": "*",
|
||||
"ts-node": "*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ import type { PlaywrightTestConfig } from '@playwright/test';
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
const config: PlaywrightTestConfig = {
|
||||
testDir: './tests',
|
||||
testDir: './e2e',
|
||||
testIgnore: '**/lib/**',
|
||||
fullyParallel: true,
|
||||
timeout: process.env.CI ? 50_000 : 30_000,
|
||||
use: {
|
||||
|
||||
24
apps/electron/project.json
Normal file
24
apps/electron/project.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "@affine/electron",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"root": "apps/electron",
|
||||
"sourceRoot": "apps/electron/src",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "nx:run-script",
|
||||
"dependsOn": [
|
||||
{
|
||||
"projects": ["@affine/bookmark-block"],
|
||||
"target": "build",
|
||||
"params": "ignore"
|
||||
},
|
||||
"^build"
|
||||
],
|
||||
"options": {
|
||||
"script": "build"
|
||||
},
|
||||
"outputs": ["{projectRoot}/dist"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
#!/usr/bin/env zx
|
||||
import 'zx/globals';
|
||||
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
import { spawnSync } from 'child_process';
|
||||
import * as esbuild from 'esbuild';
|
||||
|
||||
import { config, rootDir } from './common.mjs';
|
||||
import { config } from './common.mjs';
|
||||
|
||||
const NODE_ENV =
|
||||
process.env.NODE_ENV === 'development' ? 'development' : 'production';
|
||||
@@ -18,20 +15,10 @@ if (process.platform === 'win32') {
|
||||
|
||||
async function buildLayers() {
|
||||
const common = config();
|
||||
console.log('Build plugin infra');
|
||||
spawnSync('yarn', ['build'], {
|
||||
stdio: 'inherit',
|
||||
cwd: resolve(rootDir, './packages/plugin-infra'),
|
||||
});
|
||||
|
||||
console.log('Build plugins');
|
||||
await import('./plugins/build-plugins.mjs');
|
||||
|
||||
await esbuild.build(common.workers);
|
||||
await esbuild.build({
|
||||
...common.layers,
|
||||
define: {
|
||||
...common.define,
|
||||
'process.env.NODE_ENV': `"${NODE_ENV}"`,
|
||||
'process.env.BUILD_TYPE': `"${process.env.BUILD_TYPE || 'stable'}"`,
|
||||
},
|
||||
|
||||
@@ -15,16 +15,9 @@ const DEV_SERVER_URL = process.env.DEV_SERVER_URL;
|
||||
/** @type 'production' | 'development'' */
|
||||
const mode = (process.env.NODE_ENV = process.env.NODE_ENV || 'development');
|
||||
|
||||
// List of env that will be replaced by esbuild
|
||||
const ENV_MACROS = ['AFFINE_GOOGLE_CLIENT_ID', 'AFFINE_GOOGLE_CLIENT_SECRET'];
|
||||
|
||||
/** @return {{layers: import('esbuild').BuildOptions, workers: import('esbuild').BuildOptions}} */
|
||||
export const config = () => {
|
||||
const define = Object.fromEntries([
|
||||
...ENV_MACROS.map(key => [
|
||||
'process.env.' + key,
|
||||
JSON.stringify(process.env[key] ?? ''),
|
||||
]),
|
||||
['process.env.NODE_ENV', `"${mode}"`],
|
||||
['process.env.USE_WORKER', '"true"'],
|
||||
]);
|
||||
@@ -45,7 +38,12 @@ export const config = () => {
|
||||
bundle: true,
|
||||
target: `node${NODE_MAJOR_VERSION}`,
|
||||
platform: 'node',
|
||||
external: ['electron', 'electron-updater', '@toeverything/plugin-infra'],
|
||||
external: [
|
||||
'electron',
|
||||
'electron-updater',
|
||||
'@toeverything/plugin-infra',
|
||||
'yjs',
|
||||
],
|
||||
define: define,
|
||||
format: 'cjs',
|
||||
loader: {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
/* eslint-disable no-async-promise-executor */
|
||||
import { spawn } from 'node:child_process';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import path, { resolve } from 'node:path';
|
||||
import path from 'node:path';
|
||||
|
||||
import electronPath from 'electron';
|
||||
import * as esbuild from 'esbuild';
|
||||
import which from 'which';
|
||||
|
||||
import { config, electronDir, rootDir } from './common.mjs';
|
||||
import { config, electronDir } from './common.mjs';
|
||||
|
||||
// this means we don't spawn electron windows, mainly for testing
|
||||
const watchMode = process.argv.includes('--watch');
|
||||
@@ -68,14 +67,6 @@ function spawnOrReloadElectron() {
|
||||
}
|
||||
|
||||
const common = config();
|
||||
const yarnPath = which.sync('yarn');
|
||||
async function watchPlugins() {
|
||||
spawn(yarnPath, ['dev'], {
|
||||
stdio: 'inherit',
|
||||
cwd: resolve(rootDir, './packages/plugin-infra'),
|
||||
});
|
||||
await import('./plugins/dev-plugins.mjs');
|
||||
}
|
||||
|
||||
async function watchLayers() {
|
||||
return new Promise(async resolve => {
|
||||
@@ -134,7 +125,6 @@ async function watchWorkers() {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await watchPlugins();
|
||||
await watchLayers();
|
||||
await watchWorkers();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user