mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-21 17:41:16 +02:00
Compare commits
1125 Commits
v1.15.0
...
release/v1
Author | SHA1 | Date | |
---|---|---|---|
|
9aa13c585e | ||
|
eeaa9250e0 | ||
|
713bc6c8dc | ||
|
6b7e860b0f | ||
|
0f89417d75 | ||
|
7c80a0b630 | ||
|
b42df3105d | ||
|
6162fb0a19 | ||
|
df0b330af7 | ||
|
51db7b03dd | ||
|
a7b1e20b76 | ||
|
de79d2a235 | ||
|
4b7f0c6c38 | ||
|
ae91913132 | ||
|
0e7791174d | ||
|
736b7b25a4 | ||
|
daf14b275a | ||
|
cf6694e815 | ||
|
704f809e90 | ||
|
0e9499ada7 | ||
|
675f658721 | ||
|
ccc11c1e77 | ||
|
336e1ac779 | ||
|
be99eb26a2 | ||
|
fe9458591a | ||
|
57e816311b | ||
|
09b76295f1 | ||
|
38acce2f3f | ||
|
8f44d00f22 | ||
|
4386eb751f | ||
|
d6aab069ed | ||
|
f4fb8dbc87 | ||
|
c7c18e0eb2 | ||
|
0a2d618d85 | ||
|
c8a83ace59 | ||
|
59d132f0b3 | ||
|
18dd49a4ab | ||
|
46637b1164 | ||
|
7b18c67ac9 | ||
|
6eb3c05cb7 | ||
|
82f24bedc2 | ||
|
88da50674f | ||
|
35a7db49b4 | ||
|
f4729e2418 | ||
|
f7330fd027 | ||
|
755d8e21ad | ||
|
7c0bf06d96 | ||
|
0d196e29e8 | ||
|
b86606fa38 | ||
|
74602bb487 | ||
|
1465e0cbb2 | ||
|
928b603d19 | ||
|
8ff542c1a2 | ||
|
39a0db6ecf | ||
|
9cc93c05cd | ||
|
b31418edd9 | ||
|
242f7f1a52 | ||
|
8d7f1e430a | ||
|
a6b32adc45 | ||
|
1f0dca4614 | ||
|
1d665da32f | ||
|
09adc26eb6 | ||
|
297346a762 | ||
|
acd648061d | ||
|
c5fe0a096d | ||
|
0c7bf6801f | ||
|
5863f7e048 | ||
|
a785c46ca8 | ||
|
6bddfd3086 | ||
|
dd8a726b25 | ||
|
08eecba32b | ||
|
9c2212df15 | ||
|
9b4746967c | ||
|
00da1facc4 | ||
|
b461993775 | ||
|
b885e57762 | ||
|
081449d7a5 | ||
|
ee3a21a537 | ||
|
61c7732e12 | ||
|
57c2ca7f26 | ||
|
0704009dd7 | ||
|
14a6aafb50 | ||
|
471a1e8111 | ||
|
123c254b84 | ||
|
db43f63c53 | ||
|
3ecd520f8e | ||
|
e9935d358c | ||
|
8d653b148b | ||
|
b702f2dac3 | ||
|
d59b8541f2 | ||
|
efd34d0d7d | ||
|
2ec2935f78 | ||
|
540541caa2 | ||
|
a13d64bf98 | ||
|
bab7d885aa | ||
|
42229dc0b8 | ||
|
e3d8e92bdc | ||
|
6fc73a8433 | ||
|
b1a0a78a51 | ||
|
9c7d8b3096 | ||
|
93feb1a666 | ||
|
bb0e2121a3 | ||
|
d21b7fd3af | ||
|
743553f3e9 | ||
|
a3ccbb5b7f | ||
|
4b7cb813e6 | ||
|
23b8214549 | ||
|
08feb6b664 | ||
|
1aa5dc75df | ||
|
ee234aff61 | ||
|
a3f3e310fb | ||
|
ea56bdca5f | ||
|
45c836badc | ||
|
f9ea4ab69a | ||
|
e6d46eeb55 | ||
|
5bb0c92b6c | ||
|
c1e6be47d7 | ||
|
79a5e68816 | ||
|
9bcbbd419f | ||
|
f460b7543e | ||
|
1cb649525d | ||
|
99861e3e06 | ||
|
66b8a43e5f | ||
|
d285905826 | ||
|
4df2320ba6 | ||
|
0fe99cc00c | ||
|
580401ecbf | ||
|
7aa29720f0 | ||
|
3e5c844a77 | ||
|
4047c5c068 | ||
|
03d924238c | ||
|
bc1248ed9e | ||
|
dd52c08b74 | ||
|
b811b819e2 | ||
|
da985b25ce | ||
|
ae9c51df7c | ||
|
ff1c5815bb | ||
|
87f8d37be5 | ||
|
f4b96c1041 | ||
|
a3f72303d1 | ||
|
4317806ade | ||
|
578f19a682 | ||
|
f9b6404950 | ||
|
52517e3e23 | ||
|
36e96e3481 | ||
|
a765410d0f | ||
|
43fc2e528c | ||
|
cb90eda213 | ||
|
5f9c18b2b3 | ||
|
4384b85046 | ||
|
e0973a84a0 | ||
|
054bc55a1c | ||
|
4fb718d405 | ||
|
df35049196 | ||
|
ce75461380 | ||
|
cea85c30a4 | ||
|
6039138323 | ||
|
eb43e73785 | ||
|
c077a0361a | ||
|
6f21a94d18 | ||
|
8ebf0e68ec | ||
|
3685cc7660 | ||
|
9d9ccdbe43 | ||
|
81b29d6263 | ||
|
6591f87b28 | ||
|
efc78c18c1 | ||
|
f5a3c0dd6c | ||
|
382101ecc7 | ||
|
86c3481eff | ||
|
039eb66c8c | ||
|
36148ed083 | ||
|
db4c7dcf15 | ||
|
bec566282e | ||
|
fa9be55018 | ||
|
458239b46d | ||
|
ae85ee1c6f | ||
|
08d5a836ef | ||
|
ad789542b8 | ||
|
1f7802db97 | ||
|
c876124efe | ||
|
3a78ac4b32 | ||
|
7ebc3da7cb | ||
|
2e36ba0a00 | ||
|
69a158dcc2 | ||
|
913d6f3ff3 | ||
|
044cb09ae8 | ||
|
9da8e478dd | ||
|
c8f3672a88 | ||
|
edf85b820d | ||
|
c04a4afac1 | ||
|
65ad6362d7 | ||
|
f9a0ae1dd4 | ||
|
fb26b01688 | ||
|
63628fdf1c | ||
|
2e317d3f6e | ||
|
ce69882180 | ||
|
649abeda40 | ||
|
4cfd62cddf | ||
|
38fc6c75f3 | ||
|
8671602ba9 | ||
|
3d08e3a08c | ||
|
d4a075d738 | ||
|
bb77e6c12d | ||
|
fabc0ad157 | ||
|
a13fb154ae | ||
|
36c66303df | ||
|
f65e29c077 | ||
|
a97c8a8966 | ||
|
69b7776af5 | ||
|
18c1edf15c | ||
|
70ffec4509 | ||
|
bc196a35e1 | ||
|
8d31cfbfff | ||
|
e84a432f76 | ||
|
1fc9f11253 | ||
|
0dfe5fa2d6 | ||
|
1d17313949 | ||
|
9c318a17f5 | ||
|
72fa108cbc | ||
|
db134c5d71 | ||
|
73b68015de | ||
|
e4919e414f | ||
|
f7606de13a | ||
|
483bda4b2d | ||
|
edd57028a1 | ||
|
083b85c655 | ||
|
d5027b6c09 | ||
|
a044ec8b53 | ||
|
f93d72c09b | ||
|
2f22337125 | ||
|
781ad8a79e | ||
|
cada7202aa | ||
|
0b331e2213 | ||
|
0734ca0132 | ||
|
0b83cc21be | ||
|
b68e605d56 | ||
|
42991dc89a | ||
|
160de9fbda | ||
|
d644289fcb | ||
|
fd9ff7cd6f | ||
|
b7c6457648 | ||
|
6b0a71230d | ||
|
c68f1281f6 | ||
|
f19f53c077 | ||
|
6779d9726f | ||
|
6fba174606 | ||
|
531b6d60e1 | ||
|
4a6bae59c0 | ||
|
4a20eadfd7 | ||
|
84f8ef3df6 | ||
|
11b4827791 | ||
|
9dcf0bf6ec | ||
|
8156e0f855 | ||
|
89a3214352 | ||
|
68b59d8966 | ||
|
483409716d | ||
|
089b4e6a45 | ||
|
a7ee4d507a | ||
|
851b54ba9f | ||
|
eed8633fb0 | ||
|
8581e2f4ec | ||
|
076cead40d | ||
|
7dde39a6db | ||
|
43a22c6a21 | ||
|
bd7680f450 | ||
|
212e81f11d | ||
|
2871e58a01 | ||
|
52bfb7f012 | ||
|
4d0a72a271 | ||
|
72b3681648 | ||
|
7960c96c19 | ||
|
661d3d28e9 | ||
|
4b4884ce88 | ||
|
a15353dc00 | ||
|
a38ab71b20 | ||
|
0ed9b006e8 | ||
|
d7c2a2951c | ||
|
e239d354c9 | ||
|
aa1e8f6a74 | ||
|
84145e45c5 | ||
|
2b16ca7c77 | ||
|
35c3553870 | ||
|
8808293247 | ||
|
d413a1f8a4 | ||
|
696521b33b | ||
|
f635d60344 | ||
|
dd135c6258 | ||
|
69a28299e2 | ||
|
eaf09a5368 | ||
|
17b2079f3e | ||
|
ff00b8688b | ||
|
67d73882f4 | ||
|
ba9e4e2570 | ||
|
ee8718e452 | ||
|
72cced1f3e | ||
|
09d2029b6c | ||
|
0857c197a0 | ||
|
c0ed869e0f | ||
|
ed6757ecdc | ||
|
af92473920 | ||
|
8c647bf0f6 | ||
|
242dddfcb7 | ||
|
60b945565d | ||
|
79791ba4ac | ||
|
de578bff8c | ||
|
3a0dee01ed | ||
|
23f5a34c89 | ||
|
70d7475356 | ||
|
4f7764561a | ||
|
832f987d80 | ||
|
69a4bd02f0 | ||
|
e30b20dc68 | ||
|
3dbdf36d95 | ||
|
80705cf4b4 | ||
|
a1c12fb0b3 | ||
|
21ed4fd8da | ||
|
ee60f27aec | ||
|
36a0f4e418 | ||
|
0acc6a4e92 | ||
|
4b3bfd7e89 | ||
|
1514e13bb8 | ||
|
bf7b083cfe | ||
|
a38ba634a4 | ||
|
0572c78938 | ||
|
6da078d616 | ||
|
ec6cc38c6c | ||
|
8760af752a | ||
|
12ad6dd0e3 | ||
|
d228d346c4 | ||
|
623c93ff46 | ||
|
165346c15c | ||
|
0848c716bf | ||
|
74a5d49e86 | ||
|
637c3ec5d8 | ||
|
650a50a7ba | ||
|
48aab263d1 | ||
|
8eec403068 | ||
|
ade41f3f04 | ||
|
f499f23039 | ||
|
496acbe9e5 | ||
|
948949f429 | ||
|
766cb481f7 | ||
|
de8e3948a5 | ||
|
e61b390d54 | ||
|
88da7a7174 | ||
|
5d4ee44ed3 | ||
|
6a3611cc3d | ||
|
7db2f110ad | ||
|
549fd03c0e | ||
|
e9c9a35a61 | ||
|
385dc6a992 | ||
|
25a290e320 | ||
|
1a4e2bfcd1 | ||
|
fb2dc95623 | ||
|
c99b8efba2 | ||
|
431e482e3f | ||
|
7eb380baa4 | ||
|
a3d685077f | ||
|
ffaebb1a84 | ||
|
67d7ad681a | ||
|
626b10794f | ||
|
e0b41f8c37 | ||
|
658a636afe | ||
|
ccb7978538 | ||
|
211f0c32d2 | ||
|
8ce1b539b1 | ||
|
8fa97a25f0 | ||
|
72f9050689 | ||
|
e4e3df6c66 | ||
|
d2fac636d1 | ||
|
38d81cdd01 | ||
|
a2afd38f25 | ||
|
4da2eabd7f | ||
|
13d002a755 | ||
|
e34632bb53 | ||
|
31a2bf29ed | ||
|
16adaaeaa3 | ||
|
26070eb818 | ||
|
c7151c2fb6 | ||
|
532383d7dd | ||
|
d7770539f6 | ||
|
7cc44491fa | ||
|
5754080eb9 | ||
|
a5df7ba6bf | ||
|
ffc08c1914 | ||
|
e0cf3d86c4 | ||
|
ba6efb105a | ||
|
d097fd6be6 | ||
|
62dcf1a6fb | ||
|
a9ed1c5c7c | ||
|
d155ffc610 | ||
|
cb05d3a23a | ||
|
7be82f4af8 | ||
|
7821370c0b | ||
|
273bef1be3 | ||
|
d8ae769dda | ||
|
7cc7f0ed75 | ||
|
bef93abd49 | ||
|
be91df42d1 | ||
|
57d0461ac7 | ||
|
3f34f09537 | ||
|
660c30db80 | ||
|
0ac845042e | ||
|
ce840bb177 | ||
|
bcc13f3889 | ||
|
2cd1479e77 | ||
|
ff2fd08228 | ||
|
25677cdc5b | ||
|
fb5f7791ef | ||
|
e4e411821d | ||
|
b24a965b81 | ||
|
147e42239f | ||
|
1c7db70835 | ||
|
6fe756dc93 | ||
|
f1e85622da | ||
|
487ce3b49e | ||
|
9296baf65a | ||
|
8662ff68da | ||
|
b300e3f485 | ||
|
4cbc865d83 | ||
|
4bbbf35654 | ||
|
a6d4a8546a | ||
|
d29b689f81 | ||
|
dab28c7049 | ||
|
8354670708 | ||
|
6e7d28cf3a | ||
|
e0e3ba6c12 | ||
|
3a3cbcfdf0 | ||
|
e79272ab20 | ||
|
cc129d2ca2 | ||
|
e78ee73d71 | ||
|
b748acf2a0 | ||
|
f58e687a83 | ||
|
4da1d97810 | ||
|
9d943bf374 | ||
|
790e6cfeec | ||
|
bfe597c7b0 | ||
|
0981ec30c3 | ||
|
b4782e24d2 | ||
|
8e9140dd69 | ||
|
bd475f5c9d | ||
|
eba07867ef | ||
|
39eb82446c | ||
|
c3eea2f8af | ||
|
e0118b0d9b | ||
|
5723240490 | ||
|
0a7e8327a0 | ||
|
6d4172987e | ||
|
379a5241c6 | ||
|
f550e356d6 | ||
|
3ca5dc7e32 | ||
|
0a9fcf63a4 | ||
|
719bddcd76 | ||
|
fb8166c6c6 | ||
|
c7e23401a3 | ||
|
183175263d | ||
|
d2d9bc846e | ||
|
9e6e1dc950 | ||
|
b59875aa12 | ||
|
0ff18a808c | ||
|
4cbe792562 | ||
|
a6f961fba4 | ||
|
b30870ef8b | ||
|
eb69c7ec8c | ||
|
12a42baa5e | ||
|
dcdb4873c8 | ||
|
f49d160447 | ||
|
9d6208965c | ||
|
6255ff8c6b | ||
|
6c34f6b954 | ||
|
11d519b385 | ||
|
b4a32afec1 | ||
|
98d903a3c6 | ||
|
a1dca00974 | ||
|
8d85a62e4d | ||
|
f7094c8161 | ||
|
c7c723c548 | ||
|
aa79738a66 | ||
|
1a78e23355 | ||
|
4f81c7dffe | ||
|
5f22e2dfb2 | ||
|
6791aae8de | ||
|
6ceef87671 | ||
|
03ec9e5060 | ||
|
365b16cde1 | ||
|
87be76213a | ||
|
957c3fcb59 | ||
|
4646c7c52d | ||
|
fbf3208229 | ||
|
4f98e82427 | ||
|
34b5436ae1 | ||
|
ba57e30f13 | ||
|
7026a30fdc | ||
|
7d0629adf8 | ||
|
042cac5fed | ||
|
a3517d8668 | ||
|
3fd502cca8 | ||
|
01087e9eef | ||
|
d894c90b70 | ||
|
64b7d0de8e | ||
|
9ecfc54a8f | ||
|
eb8513a690 | ||
|
4a6bd60df0 | ||
|
830ab75ce0 | ||
|
b5a9ee94fd | ||
|
3fec2cb3d3 | ||
|
9defddb286 | ||
|
b1df890951 | ||
|
1fee11d69a | ||
|
24a8d54bfb | ||
|
fbadc1a198 | ||
|
72d82c5b6f | ||
|
04c55e97a2 | ||
|
2e8fc5b034 | ||
|
789d251ae4 | ||
|
1f0dab2116 | ||
|
fcc11253ac | ||
|
371ebce252 | ||
|
f23851f690 | ||
|
6c21961462 | ||
|
e8f1f09132 | ||
|
edd37e9d4a | ||
|
af901a4ca9 | ||
|
e0f81b4ef4 | ||
|
4b4997c73e | ||
|
4f99697888 | ||
|
49933c7fb0 | ||
|
71ed96b0d5 | ||
|
a666829a37 | ||
|
4e7ca946da | ||
|
c97d66d23c | ||
|
754fdd8f9c | ||
|
21f4401f3e | ||
|
3d996c85a5 | ||
|
429ef43793 | ||
|
2dae5b715c | ||
|
188fd2dd1a | ||
|
9450410ff7 | ||
|
e595986458 | ||
|
a1f5c7bfce | ||
|
b2daa7e203 | ||
|
c79cc2d3e8 | ||
|
1dbc58f742 | ||
|
baed01f247 | ||
|
c2ab19888f | ||
|
ed23a6c397 | ||
|
a3efd048a7 | ||
|
49b2cb998b | ||
|
8244cfb8eb | ||
|
58ff86ed4d | ||
|
499b05da22 | ||
|
a159c3175f | ||
|
7743f13bed | ||
|
55e9228866 | ||
|
8511eec4d4 | ||
|
d710af6669 | ||
|
0add627182 | ||
|
ab09296d37 | ||
|
0fa41b6dc4 | ||
|
f8ec43dbc7 | ||
|
931d0cf854 | ||
|
0d69e64e03 | ||
|
013fb73068 | ||
|
c96be0cd98 | ||
|
9f14fe43c6 | ||
|
52869ef386 | ||
|
a8fd76557b | ||
|
38347aa16f | ||
|
d4e281bc02 | ||
|
fc3d082609 | ||
|
7a03473159 | ||
|
a09b40de8d | ||
|
381e131fc8 | ||
|
00448ebe91 | ||
|
e4b95de388 | ||
|
9361b65f54 | ||
|
96ec656cf1 | ||
|
a85e75b2b1 | ||
|
72b0882a45 | ||
|
f34151bdb2 | ||
|
55be5fe339 | ||
|
e1d655991b | ||
|
c3e020ca34 | ||
|
257b7171c3 | ||
|
d1f5584039 | ||
|
878c2ce6e6 | ||
|
1f1ae57139 | ||
|
3c3855a05c | ||
|
6874fe90e5 | ||
|
c98dd7a3e0 | ||
|
b01f6c1a8c | ||
|
ea42d3c04e | ||
|
3c4724d70e | ||
|
81a4fc7528 | ||
|
d8a8961b99 | ||
|
5233051e64 | ||
|
750a8465f5 | ||
|
29cc169d20 | ||
|
95d3266bee | ||
|
adda27668b | ||
|
e3da8c1e88 | ||
|
21f6c0be08 | ||
|
42670e6b1c | ||
|
8fdc5247de | ||
|
171f2d066e | ||
|
3be156f66a | ||
|
bbffcc3aec | ||
|
7e1ae38097 | ||
|
48ccd325a1 | ||
|
447428f446 | ||
|
81926d61db | ||
|
23bd7b1211 | ||
|
d789670894 | ||
|
6f7082ff56 | ||
|
6292603215 | ||
|
3a60e0ad89 | ||
|
ff9564a679 | ||
|
ab1379743e | ||
|
253d9e4158 | ||
|
562785ef4e | ||
|
10db864c66 | ||
|
83a04e42cc | ||
|
cd32b84811 | ||
|
42ea0023a3 | ||
|
d2163df6a0 | ||
|
8eddb75508 | ||
|
424959e07c | ||
|
bab95c3a86 | ||
|
47448083a1 | ||
|
df64fa4865 | ||
|
7f802631c5 | ||
|
0db7a32b92 | ||
|
90eb9fb889 | ||
|
492e1c2fbd | ||
|
a4dc0c5a82 | ||
|
433e81aecf | ||
|
0e189eecaa | ||
|
43bbc54783 | ||
|
33fca2b537 | ||
|
edbaa5d3f0 | ||
|
465fb4169e | ||
|
99b2858e62 | ||
|
b6b1e71665 | ||
|
aa4355ba1f | ||
|
d6d147c2c4 | ||
|
062b051687 | ||
|
a5b4720b91 | ||
|
bb71ceeeb2 | ||
|
3a693bd18c | ||
|
03de593402 | ||
|
021df29623 | ||
|
a3f9e9234c | ||
|
640f0e1ddf | ||
|
ebaf4c48ea | ||
|
513951bc16 | ||
|
d168f0498b | ||
|
9d97cf3a71 | ||
|
30515f2df3 | ||
|
69b61d4373 | ||
|
c9110eb5e4 | ||
|
bd613c704c | ||
|
5e0cf4b82e | ||
|
dbdaa713c9 | ||
|
bc6df18fb3 | ||
|
a161c2ca58 | ||
|
de9625e485 | ||
|
fed8e01ca1 | ||
|
e5b48dcac4 | ||
|
d6f4820967 | ||
|
a5bcf1994f | ||
|
118fbd9436 | ||
|
12938dd35f | ||
|
9d855bd6a1 | ||
|
95da01c5cd | ||
|
e69521f029 | ||
|
cb9c8184c9 | ||
|
e2995ef515 | ||
|
599ff1c054 | ||
|
4e8a81780e | ||
|
1ff944f698 | ||
|
40c8451b7d | ||
|
63c0dc89ef | ||
|
76a3190b8a | ||
|
f5bb788c4e | ||
|
e6e3b212b3 | ||
|
9733b60430 | ||
|
157de0f1c1 | ||
|
f46e67b519 | ||
|
54243eed8d | ||
|
141d1a2aa5 | ||
|
3fc465ba5e | ||
|
0b4a8be26b | ||
|
2b2eb5d0ad | ||
|
4f00de1458 | ||
|
01fc24c78c | ||
|
89beceeb9a | ||
|
a462fcaac8 | ||
|
8f9ac439ca | ||
|
6e2c64f27a | ||
|
b428b0f0ed | ||
|
812a9daab9 | ||
|
849356deaf | ||
|
0277603878 | ||
|
649e1d0dc2 | ||
|
a961666c38 | ||
|
7c951fdd4a | ||
|
3676fafdac | ||
|
843bc9deeb | ||
|
44f2c27d28 | ||
|
f99d50fc9f | ||
|
932780c2bb | ||
|
07c7100c60 | ||
|
ff9638839d | ||
|
943dc08722 | ||
|
6c49517cbd | ||
|
2a9aefdabb | ||
|
82bf564168 | ||
|
d1a056fe52 | ||
|
406bd3780e | ||
|
870f5fbc41 | ||
|
af96286f22 | ||
|
23d36929bc | ||
|
09938ccd99 | ||
|
a115309f4f | ||
|
960c322586 | ||
|
67561e79f1 | ||
|
f3c7f10c9f | ||
|
83df0caf15 | ||
|
053b2f4dce | ||
|
2add8fe9be | ||
|
5879ab83b5 | ||
|
9046c022d2 | ||
|
c1110b8671 | ||
|
c5a408df05 | ||
|
35b918f574 | ||
|
98f7013756 | ||
|
f494776931 | ||
|
0208ea0248 | ||
|
de61816623 | ||
|
9f3d5c0a23 | ||
|
eaf493be5d | ||
|
e2a59c57fc | ||
|
1f41fcc342 | ||
|
4822eed99d | ||
|
c59afa752d | ||
|
f0376b7e02 | ||
|
3397fee9fa | ||
|
62a6717701 | ||
|
db895040dd | ||
|
4a57c9ea17 | ||
|
5326f4c9c5 | ||
|
26dfe88ff2 | ||
|
554988c7b2 | ||
|
7117c7774a | ||
|
b9a2f263b8 | ||
|
8af5450cf7 | ||
|
7333104e89 | ||
|
1a7473ff45 | ||
|
3728f1daa0 | ||
|
8edda8b446 | ||
|
e18ea9e349 | ||
|
55885297f4 | ||
|
6dd015a53e | ||
|
74b6805225 | ||
|
58cd55d353 | ||
|
a889d0cc8c | ||
|
bdfd751af8 | ||
|
56362043d3 | ||
|
96ff3e310f | ||
|
030f696cdd | ||
|
fa8b8c055d | ||
|
d47798ccc7 | ||
|
bd14c40461 | ||
|
5a8dd96b33 | ||
|
01b9d35f1a | ||
|
429258cff3 | ||
|
7bcbdd0707 | ||
|
d0a681fbc3 | ||
|
7b8723158e | ||
|
f2a5d1b42b | ||
|
d8e06a90f0 | ||
|
758c8c8446 | ||
|
c5c88f2f18 | ||
|
ff9a8a2231 | ||
|
6d30a00762 | ||
|
ee73d8409f | ||
|
bb39359668 | ||
|
56d79301b9 | ||
|
001dbf100d | ||
|
88fa9f3fb1 | ||
|
b6147152f8 | ||
|
cd0928f0e8 | ||
|
25a2000787 | ||
|
46cac263ca | ||
|
29acb3213b | ||
|
f0bd1e9896 | ||
|
4afdb1eb78 | ||
|
67bc04fe21 | ||
|
21a784e94a | ||
|
70d8d64cb8 | ||
|
f0ba87fda8 | ||
|
48c2578bd8 | ||
|
167914cf8b | ||
|
987152ba40 | ||
|
760d61b411 | ||
|
20eaca6d05 | ||
|
f4ea6cc4b4 | ||
|
dd22c65002 | ||
|
fc5ee1edf9 | ||
|
89ddbe9699 | ||
|
1f45b3a629 | ||
|
8f75a559ee | ||
|
47193dbcd9 | ||
|
c64e2a319f | ||
|
5b2b2cf923 | ||
|
3b06675811 | ||
|
347d48fdfe | ||
|
206ea10b45 | ||
|
3bbdce2601 | ||
|
ac10c4ecc2 | ||
|
ddd3586c06 | ||
|
ecfac78f6e | ||
|
ba1fdbcfdb | ||
|
d30410675b | ||
|
51bfe62bd9 | ||
|
e9a9c20d52 | ||
|
37b29319aa | ||
|
a82c799fc8 | ||
|
4389b2cacf | ||
|
babab0bf5e | ||
|
f48dce3176 | ||
|
e8574f2f7d | ||
|
b5856c4437 | ||
|
4e0cca3f7d | ||
|
868e937a53 | ||
|
920608e592 | ||
|
123f0aea00 | ||
|
7e98cd58dd | ||
|
74542ad35b | ||
|
7e9bd206fd | ||
|
58d81835e2 | ||
|
91e21d4fca | ||
|
6fb7fb6cfc | ||
|
cbd5dc4dd6 | ||
|
623d2dd411 | ||
|
5842a55b31 | ||
|
4a2655098f | ||
|
9302eba971 | ||
|
b22be7f594 | ||
|
d9c69596ff | ||
|
d9e237e3f2 | ||
|
f2e7d5477f | ||
|
aa631d8cd1 | ||
|
fc1e9e6302 | ||
|
0fa153f421 | ||
|
10108b184e | ||
|
b231d0deab | ||
|
5ac857f4d4 | ||
|
d4bb8e0ae7 | ||
|
a4bfef265d | ||
|
462306e263 | ||
|
6532aa2ed3 | ||
|
ea207f694d | ||
|
d04e581f09 | ||
|
b74a0f9060 | ||
|
8fb3a50a37 | ||
|
0b368aa73d | ||
|
25533657f6 | ||
|
693bea9780 | ||
|
0ffad31b92 | ||
|
ba2e600d17 | ||
|
27b351aba5 | ||
|
f96d0d3d5b | ||
|
e21a35698c | ||
|
8de44d1995 | ||
|
a959ed99c2 | ||
|
45ebcb0d1c | ||
|
db6b7db06d | ||
|
976db2a8b7 | ||
|
fc97e0626e | ||
|
5a42e72c04 | ||
|
e2f0ab3343 | ||
|
87505a9464 | ||
|
0a542dd59f | ||
|
26ef180f46 | ||
|
04b233e940 | ||
|
8af7a21085 | ||
|
132c8c43e1 | ||
|
7c84c94232 | ||
|
a334a95a3c | ||
|
aac7f68af1 | ||
|
77b95fd766 | ||
|
20a2e26e99 | ||
|
3d6cb25e31 | ||
|
eb03e819d3 | ||
|
f394019e9d | ||
|
77f604a928 | ||
|
9ca0e7905c | ||
|
51578d6418 | ||
|
9a938dc298 | ||
|
0faf175694 | ||
|
248b96d8a3 | ||
|
b83b4fbef9 | ||
|
cd78c30fd3 | ||
|
e14b52ea36 | ||
|
df2c7901e6 | ||
|
358555f72c | ||
|
efdbba4453 | ||
|
1b922374db | ||
|
8e18b412c3 | ||
|
ddc709ff7f | ||
|
f55cd033ed | ||
|
bc81d12e68 | ||
|
63d7cbcef1 | ||
|
ded438fb1a | ||
|
9fa6bdb64e | ||
|
cf6d398485 | ||
|
a807031a30 | ||
|
82da380af7 | ||
|
0767fe0d80 | ||
|
eb0330a3fe | ||
|
4c7a70b348 | ||
|
5a73153493 | ||
|
22c73278bc | ||
|
7d1d32a436 | ||
|
f3b36e2a39 | ||
|
076bb8a2a2 | ||
|
6c125e9797 | ||
|
219dec030d | ||
|
b6c752e914 | ||
|
33af0c3aa2 | ||
|
a75b2f2842 | ||
|
268b2d0c91 | ||
|
9b4280ea4b | ||
|
07fde28ddb | ||
|
6e0e414f55 | ||
|
de2e96e37b | ||
|
7062614dee | ||
|
57b0887ab2 | ||
|
83640a595b | ||
|
cbf05c3f79 | ||
|
2bb32006fd | ||
|
d21702475b | ||
|
bb4cc876b1 | ||
|
f2b4b0f491 | ||
|
6d97befddf | ||
|
8d7704b5a2 | ||
|
c0f5da3e1a | ||
|
87eb82cf52 | ||
|
9119d24573 | ||
|
73394f435c | ||
|
06b9d553bc | ||
|
b0ff429882 | ||
|
360d8e7c23 | ||
|
968225e59c | ||
|
d985d4bc2f | ||
|
f5b0e2c9d2 | ||
|
d24eb6e6ce | ||
|
7815f244d6 | ||
|
5e71b9c200 | ||
|
c9c0475f4d | ||
|
90c0180447 | ||
|
cad70599a6 | ||
|
1904941382 | ||
|
88abb0dc8a | ||
|
cd8db3a83d | ||
|
e37342db0c | ||
|
3289aceec2 | ||
|
b60e814055 | ||
|
c446901a5d | ||
|
ba6baff696 | ||
|
28ac4a7a87 | ||
|
29b971b6d5 | ||
|
20efc6b56c | ||
|
b88dbe1208 | ||
|
697213bdb3 | ||
|
e891d68dd7 | ||
|
4e761fa385 | ||
|
efaf109435 | ||
|
648464b504 | ||
|
d22cb600ed | ||
|
921afb57fb | ||
|
1cd4a3b963 | ||
|
f31e7a67cf | ||
|
73defbbd1c | ||
|
94f529af02 | ||
|
db1e3d02a5 | ||
|
b55c699c62 | ||
|
7f85610942 | ||
|
208ae9e996 | ||
|
cee5f7c5e2 | ||
|
2d1935acc7 | ||
|
7844bf1430 | ||
|
06f82641cb | ||
|
0bd58d61e5 | ||
|
e9747de952 | ||
|
3ecc4a1b9e | ||
|
dc2613600c | ||
|
3b2ed4762e | ||
|
03937891e2 | ||
|
4debb74eda | ||
|
c9bca8c5e0 | ||
|
4aa3cacc4f | ||
|
9f0c8f90af | ||
|
f9acad82ca | ||
|
422c30d315 | ||
|
65c6acccf6 | ||
|
e0853d4a21 | ||
|
274aeb3a9e | ||
|
37d0d94843 | ||
|
ea07726dc1 | ||
|
cf4328359b | ||
|
fe3299614a | ||
|
f7a302ca6f | ||
|
f5158b4304 | ||
|
d17f555fe3 | ||
|
74d75eb69c | ||
|
bbf9f41354 | ||
|
23a87a003e | ||
|
a4962a9440 | ||
|
3a6edd3685 | ||
|
6bf5afe5de | ||
|
7224cfc578 | ||
|
5fbccad906 | ||
|
2289580bb7 | ||
|
ca13e1d56c | ||
|
162c32af7e | ||
|
e29e163737 | ||
|
f1a810e090 | ||
|
2d25b7d44b | ||
|
c4d70a0325 | ||
|
2eeae4edb6 | ||
|
89245ee309 | ||
|
d9ef43a712 | ||
|
23d438f565 | ||
|
1dc41c47b9 | ||
|
eaa791bedd | ||
|
9c116f2bb5 | ||
|
07bc380c9f | ||
|
59e6db0b65 | ||
|
14762abf0b | ||
|
620c5690ea | ||
|
2bbf1313b4 | ||
|
afd88a2418 | ||
|
067d82b5a6 | ||
|
ab9bb54144 | ||
|
7e7006e00d | ||
|
9430bb7f40 | ||
|
6e6f23b315 | ||
|
fd39e6dc6a | ||
|
3a1332c326 | ||
|
806aa870cb | ||
|
19e2c6a302 | ||
|
7c4172ef71 | ||
|
f03abe8fb1 | ||
|
35735bbef9 | ||
|
80b7889fee | ||
|
a51cb3d4cb | ||
|
1fc7d6d6ad | ||
|
24366eddec | ||
|
3375e7658e | ||
|
48c7c880b8 | ||
|
e51c73ae5c | ||
|
d686d7b052 | ||
|
e3b6526922 | ||
|
b73e421646 | ||
|
e8306505f2 | ||
|
72738f0cb5 | ||
|
b9a0e33238 | ||
|
4e68d6f41d | ||
|
33e0b38287 | ||
|
3705168837 | ||
|
5b2e2d29ca | ||
|
4b6370c46d | ||
|
9102738797 | ||
|
7c7771e42b | ||
|
e76f8cac9a | ||
|
6a33b290a0 | ||
|
fd15fd4c67 | ||
|
4f23624b16 | ||
|
d717c692fa | ||
|
9f31f3aa8a | ||
|
e0f9635c06 | ||
|
5a84908d42 | ||
|
29a22ade82 | ||
|
5d2e11eedb | ||
|
f135a818f5 | ||
|
342f338bda | ||
|
9421bfedb3 | ||
|
ab77768fce | ||
|
078e2b2c39 | ||
|
afb040e021 | ||
|
81091c4f34 | ||
|
1ce4fb256f | ||
|
9f02d1c3c0 | ||
|
ef395286bf | ||
|
28f6f7bb03 | ||
|
49bd9a1111 | ||
|
97381aad5d | ||
|
b26c3b482f | ||
|
2635778425 | ||
|
08ef45b359 | ||
|
e01b782f33 | ||
|
2256499db5 | ||
|
43262226db | ||
|
bb7a7c4292 | ||
|
2344007fa3 | ||
|
29d4917660 | ||
|
fd3f149abd | ||
|
ec357833bc | ||
|
4b512abf5b | ||
|
e83abfc289 | ||
|
93f31e1897 | ||
|
b08e14bbcf | ||
|
6d8648ce06 | ||
|
95f40047ef | ||
|
7b31aae414 | ||
|
fdb0e82148 | ||
|
e417cca777 | ||
|
8d962daed6 | ||
|
d7ee5dc775 | ||
|
908136c557 | ||
|
251d7f524a | ||
|
ff69dfff7a | ||
|
8df3d6575a |
@@ -1,9 +0,0 @@
|
||||
root = "."
|
||||
tmp_dir = ".air"
|
||||
|
||||
[build]
|
||||
cmd = "make backend"
|
||||
bin = "gitea"
|
||||
include_ext = ["go", "tmpl"]
|
||||
exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata"]
|
||||
include_dir = ["cmd", "models", "modules", "options", "routers", "services", "templates"]
|
10
.air.toml
Normal file
10
.air.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
root = "."
|
||||
tmp_dir = ".air"
|
||||
|
||||
[build]
|
||||
cmd = "make backend"
|
||||
bin = "gitea"
|
||||
include_ext = ["go", "tmpl"]
|
||||
exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata"]
|
||||
include_dir = ["cmd", "models", "modules", "options", "routers", "services", "templates"]
|
||||
exclude_regex = ["_test.go$"]
|
588
.drone.yml
588
.drone.yml
File diff suppressed because it is too large
Load Diff
37
.eslintrc
37
.eslintrc
@@ -2,13 +2,11 @@ root: true
|
||||
reportUnusedDisableDirectives: true
|
||||
|
||||
ignorePatterns:
|
||||
- /templates/base/head.tmpl
|
||||
- /templates/repo/activity.tmpl
|
||||
- /templates/repo/view_file.tmpl
|
||||
- /web_src/js/vendor
|
||||
|
||||
parserOptions:
|
||||
sourceType: module
|
||||
ecmaVersion: 2021
|
||||
ecmaVersion: latest
|
||||
|
||||
plugins:
|
||||
- eslint-plugin-unicorn
|
||||
@@ -28,7 +26,6 @@ globals:
|
||||
CodeMirror: false
|
||||
Dropzone: false
|
||||
SimpleMDE: false
|
||||
u2fApi: false
|
||||
|
||||
settings:
|
||||
html/html-extensions: [".tmpl"]
|
||||
@@ -119,11 +116,12 @@ rules:
|
||||
import/no-amd: [0]
|
||||
import/no-anonymous-default-export: [0]
|
||||
import/no-commonjs: [0]
|
||||
import/no-cycle: [2, {ignoreExternal: true}]
|
||||
import/no-cycle: [2, {ignoreExternal: true, maxDepth: 1}]
|
||||
import/no-default-export: [0]
|
||||
import/no-deprecated: [0]
|
||||
import/no-dynamic-require: [0]
|
||||
import/no-extraneous-dependencies: [2]
|
||||
import/no-import-module-exports: [0]
|
||||
import/no-internal-modules: [0]
|
||||
import/no-mutable-exports: [2]
|
||||
import/no-named-as-default-member: [0]
|
||||
@@ -132,6 +130,7 @@ rules:
|
||||
import/no-named-export: [0]
|
||||
import/no-namespace: [0]
|
||||
import/no-nodejs-modules: [0]
|
||||
import/no-relative-packages: [0]
|
||||
import/no-relative-parent-imports: [0]
|
||||
import/no-restricted-paths: [0]
|
||||
import/no-self-import: [2]
|
||||
@@ -284,6 +283,7 @@ rules:
|
||||
no-unsafe-negation: [2]
|
||||
no-unused-expressions: [2]
|
||||
no-unused-labels: [2]
|
||||
no-unused-private-class-members: [2]
|
||||
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, ignoreRestSiblings: false}]
|
||||
no-use-before-define: [2, nofunc]
|
||||
no-useless-backreference: [0]
|
||||
@@ -316,6 +316,7 @@ rules:
|
||||
prefer-exponentiation-operator: [2]
|
||||
prefer-named-capture-group: [0]
|
||||
prefer-numeric-literals: [2]
|
||||
prefer-object-has-own: [0]
|
||||
prefer-object-spread: [0]
|
||||
prefer-promise-reject-errors: [2, {allowEmptyReject: false}]
|
||||
prefer-regex-literals: [2]
|
||||
@@ -362,14 +363,18 @@ rules:
|
||||
unicorn/import-style: [0]
|
||||
unicorn/new-for-builtins: [2]
|
||||
unicorn/no-abusive-eslint-disable: [0]
|
||||
unicorn/no-array-for-each: [0]
|
||||
unicorn/no-array-for-each: [2]
|
||||
unicorn/no-array-instanceof: [0]
|
||||
unicorn/no-array-method-this-argument: [2]
|
||||
unicorn/no-array-push-push: [2]
|
||||
unicorn/no-await-expression-member: [0]
|
||||
unicorn/no-console-spaces: [0]
|
||||
unicorn/no-document-cookie: [2]
|
||||
unicorn/no-empty-file: [2]
|
||||
unicorn/no-fn-reference-in-iterator: [0]
|
||||
unicorn/no-for-loop: [0]
|
||||
unicorn/no-hex-escape: [0]
|
||||
unicorn/no-invalid-remove-event-listener: [2]
|
||||
unicorn/no-keyword-prefix: [0]
|
||||
unicorn/no-lonely-if: [2]
|
||||
unicorn/no-nested-ternary: [0]
|
||||
@@ -380,10 +385,15 @@ rules:
|
||||
unicorn/no-process-exit: [0]
|
||||
unicorn/no-reduce: [2]
|
||||
unicorn/no-static-only-class: [2]
|
||||
unicorn/no-thenable: [2]
|
||||
unicorn/no-this-assignment: [2]
|
||||
unicorn/no-unreadable-array-destructuring: [0]
|
||||
unicorn/no-unsafe-regex: [0]
|
||||
unicorn/no-unused-properties: [2]
|
||||
unicorn/no-useless-fallback-in-spread: [2]
|
||||
unicorn/no-useless-length-check: [2]
|
||||
unicorn/no-useless-promise-resolve-reject: [2]
|
||||
unicorn/no-useless-spread: [2]
|
||||
unicorn/no-useless-undefined: [0]
|
||||
unicorn/no-zero-fractions: [2]
|
||||
unicorn/number-literal-case: [0]
|
||||
@@ -394,11 +404,15 @@ rules:
|
||||
unicorn/prefer-array-flat: [2]
|
||||
unicorn/prefer-array-index-of: [2]
|
||||
unicorn/prefer-array-some: [2]
|
||||
unicorn/prefer-at: [0]
|
||||
unicorn/prefer-code-point: [2]
|
||||
unicorn/prefer-dataset: [2]
|
||||
unicorn/prefer-date-now: [2]
|
||||
unicorn/prefer-default-parameters: [0]
|
||||
unicorn/prefer-event-key: [2]
|
||||
unicorn/prefer-export-from: [2]
|
||||
unicorn/prefer-includes: [2]
|
||||
unicorn/prefer-json-parse-buffer: [0]
|
||||
unicorn/prefer-math-trunc: [2]
|
||||
unicorn/prefer-modern-dom-apis: [0]
|
||||
unicorn/prefer-module: [2]
|
||||
@@ -407,7 +421,10 @@ rules:
|
||||
unicorn/prefer-node-protocol: [0]
|
||||
unicorn/prefer-node-remove: [0]
|
||||
unicorn/prefer-number-properties: [0]
|
||||
unicorn/prefer-object-from-entries: [2]
|
||||
unicorn/prefer-object-has-own: [0]
|
||||
unicorn/prefer-optional-catch-binding: [2]
|
||||
unicorn/prefer-prototype-methods: [0]
|
||||
unicorn/prefer-query-selector: [0]
|
||||
unicorn/prefer-reflect-apply: [0]
|
||||
unicorn/prefer-regexp-test: [2]
|
||||
@@ -419,10 +436,16 @@ rules:
|
||||
unicorn/prefer-switch: [0]
|
||||
unicorn/prefer-ternary: [0]
|
||||
unicorn/prefer-text-content: [2]
|
||||
unicorn/prefer-top-level-await: [0]
|
||||
unicorn/prefer-trim-start-end: [2]
|
||||
unicorn/prefer-type-error: [0]
|
||||
unicorn/prevent-abbreviations: [0]
|
||||
unicorn/relative-url-style: [2]
|
||||
unicorn/require-array-join-separator: [2]
|
||||
unicorn/require-number-to-fixed-digits-argument: [2]
|
||||
unicorn/require-post-message-target-origin: [0]
|
||||
unicorn/string-content: [0]
|
||||
unicorn/template-indent: [2]
|
||||
unicorn/throw-new-error: [2]
|
||||
use-isnan: [2]
|
||||
valid-typeof: [2, {requireStringLiterals: true}]
|
||||
|
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -4,3 +4,5 @@
|
||||
/templates/**/*.tmpl linguist-language=Handlebars
|
||||
/.eslintrc linguist-language=YAML
|
||||
/.stylelintrc linguist-language=YAML
|
||||
/web_src/fomantic/build/** linguist-generated
|
||||
Dockerfile.* linguist-language=Dockerfile
|
||||
|
90
.github/ISSUE_TEMPLATE/bug-report.yaml
vendored
Normal file
90
.github/ISSUE_TEMPLATE/bug-report.yaml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
name: Bug Report
|
||||
description: Found something you weren't expecting? Report it here!
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
1. Please speak English, this is the language all maintainers can speak and write.
|
||||
2. Please ask questions or configuration/deploy problems on our Discord
|
||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
||||
3. Make sure you are using the latest release and
|
||||
take a moment to check that your issue hasn't been reported before.
|
||||
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.io/en-us/faq)
|
||||
5. Please give all relevant information below for bug reports, because
|
||||
incomplete details will be handled as an invalid report.
|
||||
- type: input
|
||||
id: gitea-ver
|
||||
attributes:
|
||||
label: Gitea Version
|
||||
description: Gitea version (or commit reference) of your instance
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: git-ver
|
||||
attributes:
|
||||
label: Git Version
|
||||
description: The version of git running on the server
|
||||
- type: input
|
||||
id: os-ver
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: The operating system you are using to run Gitea
|
||||
- type: textarea
|
||||
id: run-info
|
||||
attributes:
|
||||
label: How are you running Gitea?
|
||||
description: |
|
||||
Please include information on whether you built Gitea yourself, used one of our downloads, are using https://try.gitea.io or are using some other package
|
||||
Please also tell us how you are running Gitea, e.g. if it is being run from docker, a command-line, systemd etc.
|
||||
If you are using a package or systemd tell us what distribution you are using
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: database
|
||||
attributes:
|
||||
label: Database
|
||||
description: What database system are you running?
|
||||
options:
|
||||
- PostgreSQL
|
||||
- MySQL
|
||||
- MSSQL
|
||||
- SQLite
|
||||
- type: dropdown
|
||||
id: can-reproduce
|
||||
attributes:
|
||||
label: Can you reproduce the bug on the Gitea demo site?
|
||||
description: |
|
||||
If so, please provide a URL in the Description field
|
||||
URL of Gitea demo: https://try.gitea.io
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
It's really important to provide pertinent logs
|
||||
Please read https://docs.gitea.io/en-us/logging-configuration/#debugging-problems
|
||||
In addition, if your problem relates to git commands set `RUN_MODE=dev` at the top of app.ini
|
||||
- type: input
|
||||
id: logs
|
||||
attributes:
|
||||
label: Log Gist
|
||||
description: Please provide a gist URL of your logs, with any sensitive information (e.g. API keys) removed/hidden
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see above)
|
||||
If you are using a proxy or a CDN (e.g. Cloudflare) in front of Gitea, please disable the proxy/CDN fully and access Gitea directly to confirm the issue still persists without those services.
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If this issue involves the Web Interface, please provide one or more screenshots
|
17
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
17
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Security Concern
|
||||
url: https://tinyurl.com/security-gitea
|
||||
about: For security concerns, please send a mail to security@gitea.io instead of opening a public issue.
|
||||
- name: Discord Server
|
||||
url: https://discord.gg/gitea
|
||||
about: Please ask questions and discuss configuration or deployment problems here.
|
||||
- name: Discourse Forum
|
||||
url: https://discourse.gitea.io
|
||||
about: Questions and configuration or deployment problems can also be discussed on our forum.
|
||||
- name: Frequently Asked Questions
|
||||
url: https://docs.gitea.io/en-us/faq
|
||||
about: Please check if your question isn't mentioned here.
|
||||
- name: Crowdin Translations
|
||||
url: https://crowdin.com/project/gitea
|
||||
about: Translations are managed here.
|
23
.github/ISSUE_TEMPLATE/feature-request.yaml
vendored
Normal file
23
.github/ISSUE_TEMPLATE/feature-request.yaml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Feature Request
|
||||
description: Got an idea for a feature that Gitea doesn't have currently? Submit your idea here!
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
1. Please speak English, this is the language all maintainers can speak and write.
|
||||
2. Please ask questions or configuration/deploy problems on our Discord
|
||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
||||
3. Please take a moment to check that your feature hasn't already been suggested.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Feature Description
|
||||
placeholder: |
|
||||
I think it would be great if Gitea had...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If you can, provide screenshots of an implementation on another site e.g. GitHub
|
62
.github/ISSUE_TEMPLATE/ui.bug-report.yaml
vendored
Normal file
62
.github/ISSUE_TEMPLATE/ui.bug-report.yaml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Web Interface Bug Report
|
||||
description: Something doesn't look quite as it should? Report it here!
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
NOTE: If your issue is a security concern, please send an email to security@gitea.io instead of opening a public issue.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
1. Please speak English, this is the language all maintainers can speak and write.
|
||||
2. Please ask questions or configuration/deploy problems on our Discord
|
||||
server (https://discord.gg/gitea) or forum (https://discourse.gitea.io).
|
||||
3. Please take a moment to check that your issue doesn't already exist.
|
||||
4. Make sure it's not mentioned in the FAQ (https://docs.gitea.io/en-us/faq)
|
||||
5. Please give all relevant information below for bug reports, because
|
||||
incomplete details will be handled as an invalid report.
|
||||
- type: input
|
||||
id: gitea-ver
|
||||
attributes:
|
||||
label: Gitea Version
|
||||
description: Gitea version (or commit reference) your instance is running
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os-ver
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: The operating system you are using to access Gitea
|
||||
- type: input
|
||||
id: browser-ver
|
||||
attributes:
|
||||
label: Browser Version
|
||||
description: The browser and version that you are using to access Gitea
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: can-reproduce
|
||||
attributes:
|
||||
label: Can you reproduce the bug on the Gitea demo site?
|
||||
description: |
|
||||
If so, please provide a URL in the Description field
|
||||
URL of Gitea demo: https://try.gitea.io
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Please provide a description of your issue here, with a URL if you were able to reproduce the issue (see above)
|
||||
If using a proxy or a CDN (e.g. CloudFlare) in front of gitea, please disable the proxy/CDN fully and connect to gitea directly to confirm the issue still persists without those services.
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: Please provide at least 1 screenshot showing the issue.
|
||||
validations:
|
||||
required: true
|
6
.github/pull_request_template.md
vendored
6
.github/pull_request_template.md
vendored
@@ -1,7 +1,9 @@
|
||||
<!--
|
||||
|
||||
Please check the following:
|
||||
|
||||
1. Make sure you are targeting the `main` branch, pull requests on release branches are only allowed for bug fixes.
|
||||
2. Read contributing guidelines: https://github.com/go-gitea/gitea/blob/master/CONTRIBUTING.md
|
||||
2. Read contributing guidelines: https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md
|
||||
3. Describe what your pull request does and which issue you're targeting (if any)
|
||||
|
||||
**You MUST delete the content above including this line before posting, otherwise your pull request will be invalid.**
|
||||
-->
|
||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@@ -9,6 +9,8 @@ _test
|
||||
|
||||
# IntelliJ
|
||||
.idea
|
||||
# Goland's output filename can not be set manually
|
||||
/go_build_*
|
||||
|
||||
# MS VSCode
|
||||
.vscode
|
||||
@@ -34,6 +36,8 @@ _testmain.go
|
||||
coverage.all
|
||||
cpu.out
|
||||
|
||||
/modules/migration/bindata.go
|
||||
/modules/migration/bindata.go.hash
|
||||
/modules/options/bindata.go
|
||||
/modules/options/bindata.go.hash
|
||||
/modules/public/bindata.go
|
||||
@@ -83,6 +87,7 @@ cpu.out
|
||||
/public/css
|
||||
/public/fonts
|
||||
/public/img/webpack
|
||||
/vendor
|
||||
/web_src/fomantic/node_modules
|
||||
/web_src/fomantic/build/*
|
||||
!/web_src/fomantic/build/semantic.js
|
||||
|
@@ -9,24 +9,61 @@ linters:
|
||||
- unused
|
||||
- structcheck
|
||||
- varcheck
|
||||
- golint
|
||||
- dupl
|
||||
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
|
||||
- gofmt
|
||||
- misspell
|
||||
- gocritic
|
||||
#- gocritic # TODO: disabled until fixed with go 1.18
|
||||
- bidichk
|
||||
- ineffassign
|
||||
- revive
|
||||
enable-all: false
|
||||
disable-all: true
|
||||
fast: false
|
||||
|
||||
run:
|
||||
timeout: 3m
|
||||
timeout: 10m
|
||||
skip-dirs:
|
||||
- node_modules
|
||||
- public
|
||||
- web_src
|
||||
|
||||
linters-settings:
|
||||
gocritic:
|
||||
disabled-checks:
|
||||
- ifElseChain
|
||||
- singleCaseSwitch # Every time this occurred in the code, there was no other way.
|
||||
revive:
|
||||
ignore-generated-header: false
|
||||
severity: warning
|
||||
confidence: 0.8
|
||||
errorCode: 1
|
||||
warningCode: 1
|
||||
rules:
|
||||
- name: blank-imports
|
||||
- name: context-as-argument
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
- name: exported
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: var-declaration
|
||||
- name: package-comments
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: time-naming
|
||||
- name: unexported-return
|
||||
- name: indent-error-flow
|
||||
- name: errorf
|
||||
- name: duplicated-imports
|
||||
- name: modifies-value-receiver
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
lang-version: 1.18
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
@@ -111,4 +148,14 @@ issues:
|
||||
linters:
|
||||
- staticcheck
|
||||
text: "svc.IsAnInteractiveSession is deprecated: Use IsWindowsService instead."
|
||||
|
||||
- path: models/user/openid.go
|
||||
linters:
|
||||
- golint
|
||||
- linters: staticcheck
|
||||
text: "strings.Title is deprecated: The rule Title uses for word boundaries does not handle Unicode punctuation properly. Use golang.org/x/text/cases instead."
|
||||
- linters: staticcheck
|
||||
text: "util.FindClosure is deprecated: This function can not handle newlines. Many elements can be existed over multiple lines(e.g. link labels). Use text.Reader.FindClosure."
|
||||
- linters: staticcheck
|
||||
text: "gossh.SigAlgoRSASHA2256 is deprecated: use KeyAlgoRSASHA256."
|
||||
- linters: staticcheck
|
||||
text: "gossh.SigAlgoRSASHA2512 is deprecated: use KeyAlgoRSASHA512."
|
||||
|
7
.ignore
7
.ignore
@@ -1,5 +1,8 @@
|
||||
/vendor
|
||||
/public/vendor/plugins
|
||||
*.min.css
|
||||
*.min.js
|
||||
/modules/options/bindata.go
|
||||
/modules/public/bindata.go
|
||||
/modules/templates/bindata.go
|
||||
/public/vendor/plugins
|
||||
/vendor
|
||||
node_modules
|
||||
|
25
.revive.toml
25
.revive.toml
@@ -1,25 +0,0 @@
|
||||
ignoreGeneratedHeader = false
|
||||
severity = "warning"
|
||||
confidence = 0.8
|
||||
errorCode = 1
|
||||
warningCode = 1
|
||||
|
||||
[rule.blank-imports]
|
||||
[rule.context-as-argument]
|
||||
[rule.context-keys-type]
|
||||
[rule.dot-imports]
|
||||
[rule.error-return]
|
||||
[rule.error-strings]
|
||||
[rule.error-naming]
|
||||
[rule.exported]
|
||||
[rule.if-return]
|
||||
[rule.increment-decrement]
|
||||
[rule.var-naming]
|
||||
[rule.var-declaration]
|
||||
[rule.package-comments]
|
||||
[rule.range]
|
||||
[rule.receiver-naming]
|
||||
[rule.time-naming]
|
||||
[rule.unexported-return]
|
||||
[rule.indent-error-flow]
|
||||
[rule.errorf]
|
16
.stylelintrc
16
.stylelintrc
@@ -1,15 +1,31 @@
|
||||
extends: stylelint-config-standard
|
||||
|
||||
overrides:
|
||||
- files: ["**/*.less"]
|
||||
customSyntax: postcss-less
|
||||
|
||||
rules:
|
||||
alpha-value-notation: null
|
||||
at-rule-empty-line-before: null
|
||||
block-closing-brace-empty-line-before: null
|
||||
color-function-notation: null
|
||||
color-hex-length: null
|
||||
comment-empty-line-before: null
|
||||
declaration-block-no-redundant-longhand-properties: null
|
||||
declaration-block-single-line-max-declarations: null
|
||||
declaration-empty-line-before: null
|
||||
hue-degree-notation: null
|
||||
indentation: 2
|
||||
max-line-length: null
|
||||
no-descending-specificity: null
|
||||
no-invalid-position-at-import-rule: null
|
||||
number-leading-zero: never
|
||||
number-max-precision: null
|
||||
property-no-vendor-prefix: null
|
||||
rule-empty-line-before: null
|
||||
selector-class-pattern: null
|
||||
selector-id-pattern: null
|
||||
selector-pseudo-element-colon-notation: double
|
||||
shorthand-property-no-redundant-values: true
|
||||
string-quotes: null
|
||||
value-no-vendor-prefix: null
|
||||
|
845
CHANGELOG.md
845
CHANGELOG.md
@@ -4,7 +4,773 @@ This changelog goes through all the changes that have been made in each release
|
||||
without substantial changes to our git log; to see the highlights of what has
|
||||
been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
|
||||
## [1.15.0-rc1](https://github.com/go-gitea/gitea/releases/tag/v1.15.0-rc1) - 2021-07-15
|
||||
## [1.16.9](https://github.com/go-gitea/gitea/releases/tag/v1.16.9) - 2022-07-12
|
||||
|
||||
* SECURITY
|
||||
* Add write check for creating Commit status (#20332) (#20334)
|
||||
* Check for permission when fetching user controlled issues (#20133) (#20196)
|
||||
* BUGFIXES
|
||||
* Hide notify mail setting ui if not enabled (#20138) (#20337)
|
||||
* Add write check for creating Commit status (#20332) (#20334)
|
||||
* Only show Followers that current user can access (#20220) (#20253)
|
||||
* Release page show all tags in compare dropdown (#20070) (#20071)
|
||||
* Fix permission check for delete tag (#19985) (#20001)
|
||||
* Only log non ErrNotExist errors in git.GetNote (#19884) (#19905)
|
||||
* Use exact search instead of fuzzy search for branch filter dropdown (#19885) (#19893)
|
||||
* Set Setpgid on child git processes (#19865) (#19881)
|
||||
* Import git from alpine 3.16 repository as 2.30.4 is needed for `safe.directory = '*'` to work but alpine 3.13 has 2.30.3 (#19876)
|
||||
* Ensure responses are context.ResponseWriters (#19843) (#19859)
|
||||
* Fix incorrect usage of `Count` function (#19850)
|
||||
* Fix raw endpoint PDF file headers (#19825) (#19826)
|
||||
* Make WIP prefixes case insensitive, e.g. allow `Draft` as a WIP prefix (#19780) (#19811)
|
||||
* Don't return 500 on NotificationUnreadCount (#19802)
|
||||
* Prevent NPE when cache service is disabled (#19703) (#19783)
|
||||
* Detect truncated utf-8 characters at the end of content as still representing utf-8 (#19773) (#19774)
|
||||
* Fix doctor pq: syntax error at or near "." quote user table name (#19765) (#19770)
|
||||
* Fix bug with assigneees (#19757)
|
||||
|
||||
## [1.16.8](https://github.com/go-gitea/gitea/releases/tag/v1.16.8) - 2022-05-16
|
||||
|
||||
* ENHANCEMENTS
|
||||
* Add doctor check/fix for bogus action rows (#19656) (#19669)
|
||||
* Make .cs highlighting legible on dark themes. (#19604) (#19605)
|
||||
* BUGFIXES
|
||||
* Fix oauth setting list bug (#19681)
|
||||
* Delete user related oauth stuff on user deletion too (#19677) (#19680)
|
||||
* Fix new release from tags list UI (#19670) (#19673)
|
||||
* Prevent NPE when checking repo units if the user is nil (#19625) (#19630)
|
||||
* GetFeeds must always discard actions with dangling repo_id (#19598) (#19629)
|
||||
* Call MultipartForm.RemoveAll when request finishes (#19606) (#19607)
|
||||
* Avoid MoreThanOne error when creating a branch whose name conflicts with other ref names (#19557) (#19591)
|
||||
* Fix sending empty notifications (#19589) (#19590)
|
||||
* Ignore DNS error when doing migration allow/block check (#19566) (#19567)
|
||||
* Fix issue overview for teams (#19652) (#19653)
|
||||
|
||||
## [1.16.7](https://github.com/go-gitea/gitea/releases/tag/v1.16.7) - 2022-05-02
|
||||
|
||||
* SECURITY
|
||||
* Escape git fetch remote (#19487) (#19490)
|
||||
* BUGFIXES
|
||||
* Don't overwrite err with nil (#19572) (#19574)
|
||||
* On Migrations, only write commit-graph if wiki clone was successful (#19563) (#19568)
|
||||
* Respect DefaultUserIsRestricted system default when creating new user (#19310) (#19560)
|
||||
* Don't error when branch's commit doesn't exist (#19547) (#19548)
|
||||
* Support `hostname:port` to pass host matcher's check (#19543) (#19544)
|
||||
* Prevent intermittent race in attribute reader close (#19537) (#19539)
|
||||
* Fix 64-bit atomic operations on 32-bit machines (#19531) (#19532)
|
||||
* Prevent dangling archiver goroutine (#19516) (#19526)
|
||||
* Fix migrate release from github (#19510) (#19523)
|
||||
* When view _Siderbar or _Footer, just display once (#19501) (#19522)
|
||||
* Fix blame page select range error and some typos (#19503)
|
||||
* Fix name of doctor fix "authorized-keys" in hints (#19464) (#19484)
|
||||
* User specific repoID or xorm builder conditions for issue search (#19475) (#19476)
|
||||
* Prevent dangling cat-file calls (goroutine alternative) (#19454) (#19466)
|
||||
* RepoAssignment ensure to close before overwrite (#19449) (#19460)
|
||||
* Set correct PR status on 3way on conflict checking (#19457) (#19458)
|
||||
* Mark TemplateLoading error as "UnprocessableEntity" (#19445) (#19446)
|
||||
|
||||
## [1.16.6](https://github.com/go-gitea/gitea/releases/tag/v1.16.6) - 2022-04-20
|
||||
|
||||
* ENHANCEMENTS
|
||||
* Only request write when necessary (#18657) (#19422)
|
||||
* Disable service worker by default (#18914) (#19342)
|
||||
* BUGFIXES
|
||||
* When dumping trim the standard suffices instead of a random suffix (#19440) (#19447)
|
||||
* Fix DELETE request for non-existent public key (#19443) (#19444)
|
||||
* Don't panic on ErrEmailInvalid (#19441) (#19442)
|
||||
* Add uploadpack.allowAnySHA1InWant to allow --filter=blob:none with older git clients (#19430) (#19438)
|
||||
* Warn on SSH connection for incorrect configuration (#19317) (#19437)
|
||||
* Search Issues via API, dont show 500 if filter result in empty list (#19244) (#19436)
|
||||
* When updating mirror repo intervals by API reschedule next update too (#19429) (#19433)
|
||||
* Fix nil error when some pages are rendered outside request context (#19427) (#19428)
|
||||
* Fix double blob-hunk on diff page (#19404) (#19405)
|
||||
* Don't allow merging PR's which are being conflict checked (#19357) (#19358)
|
||||
* Fix middleware function's placements (#19377) (#19378)
|
||||
* Fix invalid CSRF token bug, make sure CSRF tokens can be up-to-date (#19338)
|
||||
* Restore user autoregistration with email addresses (#19261) (#19312)
|
||||
* Move checks for pulls before merge into own function (#19271) (#19277)
|
||||
* Granular webhook events in editHook (#19251) (#19257)
|
||||
* Only send webhook events to active system webhooks and only deliver to active hooks (#19234) (#19248)
|
||||
* Use full output of git show-ref --tags to get tags for PushUpdateAddTag (#19235) (#19236)
|
||||
* Touch mirrors on even on fail to update (#19217) (#19233)
|
||||
* Hide sensitive content on admin panel progress monitor (#19218 & #19226) (#19231)
|
||||
* Fix clone url JS error for the empty repo page (#19209)
|
||||
* Bump goldmark to v1.4.11 (#19201) (#19203)
|
||||
* TESTING
|
||||
* Prevent intermittent failures in RepoIndexerTest (#19225 #19229) (#19228)
|
||||
* BUILD
|
||||
* Revert the minimal golang version requirement from 1.17 to 1.16 and add a warning in Makefile (#19319)
|
||||
* MISC
|
||||
* Performance improvement for add team user when org has more than 1000 repositories (#19227) (#19289)
|
||||
* Check go and nodejs version by go.mod and package.json (#19197) (#19254)
|
||||
|
||||
## [1.16.5](https://github.com/go-gitea/gitea/releases/tag/v1.16.5) - 2022-03-23
|
||||
|
||||
* BREAKING
|
||||
* Bump to build with go1.18 (#19120 et al) (#19127)
|
||||
* SECURITY
|
||||
* Prevent redirect to Host (2) (#19175) (#19186)
|
||||
* Try to prevent autolinking of displaynames by email readers (#19169) (#19183)
|
||||
* Clean paths when looking in Storage (#19124) (#19179)
|
||||
* Do not send notification emails to inactive users (#19131) (#19139)
|
||||
* Do not send activation email if manual confirm is set (#19119) (#19122)
|
||||
* ENHANCEMENTS
|
||||
* Use the new/choose link for New Issue on project page (#19172) (#19176)
|
||||
* BUGFIXES
|
||||
* Fix showing issues in your repositories (#18916) (#19191)
|
||||
* Fix compare link in active feeds for new branch (#19149) (#19185)
|
||||
* Redirect .wiki/* ui link to /wiki (#18831) (#19184)
|
||||
* Ensure deploy keys with write access can push (#19010) (#19182)
|
||||
* Ensure that setting.LocalURL always has a trailing slash (#19171) (#19177)
|
||||
* Cleanup protected branches when deleting users & teams (#19158) (#19174)
|
||||
* Use IterateBufferSize whilst querying repositories during adoption check (#19140) (#19160)
|
||||
* Fix NPE /repos/issues/search when not signed in (#19154) (#19155)
|
||||
* Use custom favicon when viewing static files if it exists (#19130) (#19152)
|
||||
* Fix the editor height in review box (#19003) (#19147)
|
||||
* Ensure isSSH is set whenever DISABLE_HTTP_GIT is set (#19028) (#19146)
|
||||
* Fix wrong scopes caused by empty scope input (#19029) (#19145)
|
||||
* Make migrations SKIP_TLS_VERIFY apply to git too (#19132) (#19141)
|
||||
* Handle email address not exist (#19089) (#19121)
|
||||
* MISC
|
||||
* Update json-iterator to allow compilation with go1.18 (#18644) (#19100)
|
||||
* Update golang.org/x/crypto (#19097) (#19098)
|
||||
|
||||
## [1.16.4](https://github.com/go-gitea/gitea/releases/tag/v1.16.4) - 2022-03-14
|
||||
|
||||
* SECURITY
|
||||
* Restrict email address validation (#17688) (#19085)
|
||||
* Fix lfs bug (#19072) (#19080)
|
||||
* ENHANCEMENTS
|
||||
* Improve SyncMirrors logging (#19045) (#19050)
|
||||
* BUGFIXES
|
||||
* Refactor mirror code & fix `StartToMirror` (#18904) (#19075)
|
||||
* Update the webauthn_credential_id_sequence in Postgres (#19048) (#19060)
|
||||
* Prevent 500 when there is an error during new auth source post (#19041) (#19059)
|
||||
* If rendering has failed due to a net.OpError stop rendering (attempt 2) (#19049) (#19056)
|
||||
* Fix flag validation (#19046) (#19051)
|
||||
* Add pam account authorization check (#19040) (#19047)
|
||||
* Ignore missing comment for user notifications (#18954) (#19043)
|
||||
* Set `rel="nofollow noindex"` on new issue links (#19023) (#19042)
|
||||
* Upgrading binding package (#19034) (#19035)
|
||||
* Don't show context cancelled errors in attribute reader (#19006) (#19027)
|
||||
* Fix update hint bug (#18996) (#19002)
|
||||
* MISC
|
||||
* Fix potential assignee query for repo (#18994) (#18999)
|
||||
|
||||
## [1.16.3](https://github.com/go-gitea/gitea/releases/tag/v1.16.3) - 2022-03-02
|
||||
|
||||
* SECURITY
|
||||
* Git backend ignore replace objects (#18979) (#18980)
|
||||
* ENHANCEMENTS
|
||||
* Adjust error for already locked db and prevent level db lock on malformed connstr (#18923) (#18938)
|
||||
* BUGFIXES
|
||||
* Set max text height to prevent overflow (#18862) (#18977)
|
||||
* Fix newAttachmentPaths deletion for DeleteRepository() (#18973) (#18974)
|
||||
* Accounts with WebAuthn only (no TOTP) now exist ... fix code to handle that case (#18897) (#18964)
|
||||
* Send 404 on `/{org}.gpg` (#18959) (#18962)
|
||||
* Fix admin user list pagination (#18957) (#18960)
|
||||
* Fix lfs management setting (#18947) (#18946)
|
||||
* Fix login with email panic when email is not exist (#18942)
|
||||
* Update go-org to v1.6.1 (#18932) (#18933)
|
||||
* Fix `<strong>` html in translation (#18929) (#18931)
|
||||
* Fix page and missing return on unadopted repos API (#18848) (#18927)
|
||||
* Allow adminstrator teams members to see other teams (#18918) (#18919)
|
||||
* Don't treat BOM escape sequence as hidden character. (#18909) (#18910)
|
||||
* Correctly link URLs to users/repos with dashes, dots or underscores (… (#18908)
|
||||
* Fix redirect when using lowercase repo name (#18775) (#18902)
|
||||
* Fix migration v210 (#18893) (#18892)
|
||||
* Fix team management UI (#18887) (18886)
|
||||
* BeforeSourcePath should point to base commit (#18880) (#18799)
|
||||
* TRANSLATION
|
||||
* Backport locales from master (#18944)
|
||||
* MISC
|
||||
* Don't update email for organisation (#18905) (#18906)
|
||||
|
||||
## [1.16.2](https://github.com/go-gitea/gitea/releases/tag/v1.16.2) - 2022-02-24
|
||||
|
||||
* ENHANCEMENTS
|
||||
* Show fullname on issue edits and gpg/ssh signing info (#18828)
|
||||
* Immediately Hammer if second kill is sent (#18823) (#18826)
|
||||
* Allow mermaid render error to wrap (#18791)
|
||||
* BUGFIXES
|
||||
* Fix ldap user sync missed email in email_address table (#18786) (#18876)
|
||||
* Update assignees check to include any writing team and change org sidebar (#18680) (#18873)
|
||||
* Don't report signal: killed errors in serviceRPC (#18850) (#18865)
|
||||
* Fix bug where certain LDAP settings were reverted (#18859)
|
||||
* Update go-org to 1.6.0 (#18824) (#18839)
|
||||
* Fix login with email for ldap users (#18800) (#18836)
|
||||
* Fix bug for get user by email (#18834)
|
||||
* Fix panic in EscapeReader (#18820) (#18821)
|
||||
* Fix ldap loginname (#18789) (#18804)
|
||||
* Remove redundant call to UpdateRepoStats during migration (#18591) (#18794)
|
||||
* In disk_channel queues synchronously push to disk on shutdown (#18415) (#18788)
|
||||
* Fix template bug of LFS lock (#18784) (#18787)
|
||||
* Attempt to fix the webauthn migration again - part 3 (#18770) (#18771)
|
||||
* Send mail to issue/pr assignee/reviewer also when OnMention is set (#18707) (#18765)
|
||||
* Fix a broken link in commits_list_small.tmpl (#18763) (#18764)
|
||||
* Increase the size of the webauthn_credential credential_id field (#18739) (#18756)
|
||||
* Prevent dangling GetAttribute calls (#18754) (#18755)
|
||||
* Fix isempty detection of git repository (#18746) (#18750)
|
||||
* Fix source code line highlighting on external tracker (#18729) (#18740)
|
||||
* Prevent double encoding of branch names in delete branch (#18714) (#18738)
|
||||
* Always set PullRequestWorkInProgressPrefixes in PrepareViewPullInfo (#18713) (#18737)
|
||||
* Fix forked repositories missed tags (#18719) (#18735)
|
||||
* Fix release typo (#18728) (#18731)
|
||||
* Separate the details links of commit-statuses in headers (#18661) (#18730)
|
||||
* Update object repo with the migrated repository (#18684) (#18726)
|
||||
* Fix bug for version update hint (#18701) (#18705)
|
||||
* Fix issue with docker-rootless shimming script (#18690) (#18699)
|
||||
* Let `MinUnitAccessMode` return correct perm (#18675) (#18689)
|
||||
* Prevent security failure due to bad APP_ID (#18678) (#18682)
|
||||
* Restart zero worker if there is still work to do (#18658) (#18672)
|
||||
* If rendering has failed due to a net.OpError stop rendering (#18642) (#18645)
|
||||
* TESTING
|
||||
* Ensure git tag tests and others create test repos in tmpdir (#18447) (#18767)
|
||||
* BUILD
|
||||
* Reduce CI go module downloads, add make targets (#18708, #18475, #18443) (#18741)
|
||||
* MISC
|
||||
* Put buttons back in org dashboard (#18817) (#18825)
|
||||
* Various Mermaid improvements (#18776) (#18780)
|
||||
* C preprocessor colors improvement (#18671) (#18696)
|
||||
* Fix the missing i18n key for update checker (#18646) (#18665)
|
||||
|
||||
## [1.16.1](https://github.com/go-gitea/gitea/releases/tag/v1.16.1) - 2022-02-06
|
||||
|
||||
* SECURITY
|
||||
* Update JS dependencies, fix lint (#18389) (#18540)
|
||||
* ENHANCEMENTS
|
||||
* Add dropdown icon to label set template dropdown (#18564) (#18571)
|
||||
* BUGFIXES
|
||||
* Comments on migrated issues/prs must link to the comment ID (#18630) (#18637)
|
||||
* Stop logging an error when notes are not found (#18626) (#18635)
|
||||
* Ensure that blob-excerpt links work for wiki (#18587) (#18624)
|
||||
* Only attempt to flush queue if the underlying worker pool is not finished (#18593) (#18620)
|
||||
* Ensure commit-statuses box is sized correctly in headers (#18538) (#18606)
|
||||
* Prevent merge messages from being sorted to the top of email chains (#18566) (#18588)
|
||||
* Prevent panic on prohibited user login with oauth2 (#18562) (#18563)
|
||||
* Collaborator trust model should trust collaborators (#18539) (#18557)
|
||||
* Detect conflicts with 3way merge (#18536) (#18537)
|
||||
* In docker rootless use $GITEA_APP_INI if provided (#18524) (#18535)
|
||||
* Add `GetUserTeams` (#18499) (#18531)
|
||||
* Fix review excerpt (#18502) (#18530)
|
||||
* Fix for AvatarURL database type (#18487) (#18529)
|
||||
* Use `ImagedProvider` for gplus oauth2 provider (#18504) (#18505)
|
||||
* Fix OAuth Source Edit Page (#18495) (#18503)
|
||||
* Use "read" value for General Access (#18496) (#18500)
|
||||
* Prevent NPE on partial match of compare URL and allow short SHA1 compare URLs (#18472) (#18473)
|
||||
* BUILD
|
||||
* Make docker gitea/gitea:v1.16-dev etc refer to the latest build on that branch (#18551) (#18569)
|
||||
* DOCS
|
||||
* Update 1.16.0 changelog to set #17846 as breaking (#18533) (#18534)
|
||||
|
||||
## [1.16.0](https://github.com/go-gitea/gitea/releases/tag/v1.16.0) - 2022-01-30
|
||||
|
||||
* BREAKING
|
||||
* Remove golang vendored directory (#18277)
|
||||
* Paginate releases page & set default page size to 10 (#16857)
|
||||
* Use shadowing script for docker (#17846)
|
||||
* Only allow webhook to send requests to allowed hosts (#17482)
|
||||
* SECURITY
|
||||
* Disable content sniffing on `PlainTextBytes` (#18359) (#18365)
|
||||
* Only view milestones from current repo (#18414) (#18417)
|
||||
* Sanitize user-input on file name (#17666)
|
||||
* Use `hostmatcher` to replace `matchlist` to improve blocking of bad hosts in Webhooks (#17605)
|
||||
* FEATURES
|
||||
* Add/update SMTP auth providers via cli (#18197)
|
||||
* Support webauthn (#17957)
|
||||
* Team permission allow different unit has different permission (#17811)
|
||||
* Implement Well-Known URL for password change (#17777)
|
||||
* Add support for ssh commit signing (#17743)
|
||||
* Allow Loading of Diffs that are too large (#17739)
|
||||
* Add copy button to markdown code blocks (#17638)
|
||||
* Add .gitattribute assisted language detection to blame, diff and render (#17590)
|
||||
* Add `PULL_LIMIT` and `PUSH_LIMIT` to cron.update_mirror task (#17568)
|
||||
* Add Reindex buttons to repository settings page (#17494)
|
||||
* Make SSL cipher suite configurable (#17440)
|
||||
* Add groups scope/claim to OIDC/OAuth2 Provider (#17367)
|
||||
* Add simple update checker to Gitea (#17212)
|
||||
* Migrated Repository will show modifications when possible (#17191)
|
||||
* Create pub/priv keypair for federation (#17071)
|
||||
* Make LDAP be able to skip local 2FA (#16954)
|
||||
* Add nodeinfo endpoint for federation purposes (#16953)
|
||||
* Save and view issue/comment content history (#16909)
|
||||
* Use git attributes to determine generated and vendored status for language stats and diffs (#16773)
|
||||
* Add migrate from Codebase (#16768)
|
||||
* Add migration from GitBucket (#16767)
|
||||
* Add OAuth2 introspection endpoint (#16752)
|
||||
* Add proxy settings and support for migration and webhook (#16704)
|
||||
* Add microsoft oauth2 providers (#16544)
|
||||
* Send registration email on user autoregistration (#16523)
|
||||
* Defer Last Commit Info (#16467)
|
||||
* Support unprotected file patterns (#16395)
|
||||
* Add migrate from OneDev (#16356)
|
||||
* Add option to update pull request by `rebase` (#16125)
|
||||
* Add RSS/Atom feed support for user actions (#16002)
|
||||
* Add support for corporate WeChat webhooks (#15910)
|
||||
* Add a simple way to rename branch like gh (#15870)
|
||||
* Add bundle download for repository (#14538)
|
||||
* Add agit flow support in gitea (#14295)
|
||||
* API
|
||||
* Add MirrorUpdated field to Repository API type (#18267)
|
||||
* Adjust Fork API to allow setting a custom repository name (#18066)
|
||||
* Add API to manage repo tranfers (#17963)
|
||||
* Add API to get file commit history (#17652)
|
||||
* Add API to get issue/pull comments and events (timeline) (#17403)
|
||||
* Add API to get/edit wiki (#17278)
|
||||
* Add API for get user org permissions (#17232)
|
||||
* Add HTML urls to notification API (#17178)
|
||||
* Add API to get commit diff/patch (#17095)
|
||||
* Respond with updated notifications in API (#17064)
|
||||
* Add API to fetch git notes (#16649)
|
||||
* Generalize list header for API (#16551)
|
||||
* Add API Token Cache (#16547)
|
||||
* Allow Token API calls be authorized using the reverse-proxy header (#15119)
|
||||
* ENHANCEMENTS
|
||||
* Make the height of the editor in Review Box smaller (4 lines as GitHub) (#18319)
|
||||
* Return nicer error if trying to pull from non-existent user (#18288)
|
||||
* Show pull link for agit pull request also (#18235)
|
||||
* Enable partial clone by default (#18195)
|
||||
* Added replay of webhooks (#18191)
|
||||
* Show OAuth callback error message (#18185)
|
||||
* Increase Salt randomness (#18179)
|
||||
* Add MP4 as default allowed attachment type (#18170)
|
||||
* Include folders into size cost (#18158)
|
||||
* Remove `/email2user` endpoint (#18127)
|
||||
* Handle invalid issues (#18111)
|
||||
* Load EasyMDE/CodeMirror dynamically, remove RequireEasyMDE (#18069)
|
||||
* Support open compare page directly (#17975)
|
||||
* Prefer "Hiragino Kaku Gothic ProN" in system-ui-ja (#17954)
|
||||
* Clean legacy SimpleMDE code (#17926)
|
||||
* Refactor install page (db type) (#17919)
|
||||
* Improve interface when comparing a branch which has created a pull request (#17911)
|
||||
* Allow default branch to be inferred on compare page (#17908)
|
||||
* Display issue/comment role even if repo archived (#17907)
|
||||
* Always set a message-id on mails (#17900)
|
||||
* Change `<a>` elements to underline on hover (#17898)
|
||||
* Render issue references in file table (#17897)
|
||||
* Handle relative unix socket paths (#17836)
|
||||
* Move accessmode into models/perm (#17828)
|
||||
* Fix some org style problems (#17807)
|
||||
* Add List-Unsubscribe header (#17804)
|
||||
* Create menus for organization pages (#17802)
|
||||
* Switch archive URL code back to href attributes (#17796)
|
||||
* Refactor "refs/*" string usage by using constants (#17784)
|
||||
* Allow forks to org if you can create repos (#17783)
|
||||
* Improve install code to avoid low-level mistakes. (#17779)
|
||||
* Improve ellipsis buttons (#17773)
|
||||
* Add restrict and no-user-rc to authorized_keys (#17772)
|
||||
* Add copy Commit ID button in commits list (#17759)
|
||||
* Make `bind` error more readable (#17750)
|
||||
* Fix navbar on project view (#17749)
|
||||
* More pleasantly handle broken or missing git repositories (#17747)
|
||||
* Use `*PushUpdateOptions` as receiver (#17724)
|
||||
* Remove unused `user` paramater (#17723)
|
||||
* Better builtin avatar generator (#17707)
|
||||
* Cleanup and use global style on popups (#17674)
|
||||
* Move user/org deletion to services (#17673)
|
||||
* Added comment for changing issue ref (#17672)
|
||||
* Allow admins to change user avatars (#17661)
|
||||
* Only set `data-path` once for each file in diff pages (#17657)
|
||||
* Add icon to vscode clone link (#17641)
|
||||
* Add download button for file viewer (#17640)
|
||||
* Add pagination to fork list (#17639)
|
||||
* Use a standalone struct name for Organization (#17632)
|
||||
* Minor readability patch. (#17627)
|
||||
* Add context support for GetUserByID (#17602)
|
||||
* Move merge-section to `> .content` (#17582)
|
||||
* Remove NewSession method from db.Engine interface (#17577)
|
||||
* Move unit into models/unit/ (#17576)
|
||||
* Restrict GetDeletedBranchByID to the repositories deleted branches (#17570)
|
||||
* Refactor commentTags functionality (#17558)
|
||||
* Make Repo Code Indexer an Unique Queue (#17515)
|
||||
* Simplify Gothic to use our session store instead of creating a different store (#17507)
|
||||
* Add settings to allow different SMTP envelope from address (#17479)
|
||||
* Properly determine CSV delimiter (#17459)
|
||||
* Hide label comments if labels were added and removed immediately (#17455)
|
||||
* Tune UI alignment for nav bar notification icon, avatar image, issue label (#17438)
|
||||
* Add appearance section in settings (#17433)
|
||||
* Move key forms before list and add cancel button (#17432)
|
||||
* When copying executables to the docker chmod them (#17423)
|
||||
* Remove deprecated `extendDefaultPlugins` method of svgo (#17399)
|
||||
* Fix the click behavior for <tr> and <td> with [data-href] (#17388)
|
||||
* Refactor update checker to use AppState (#17387)
|
||||
* Improve async/await usage, and sort init calls in `index.js` (#17386)
|
||||
* Use a variable but a function for IsProd because of a slight performance increment (#17368)
|
||||
* Frontend refactor, PascalCase to camelCase, remove unused code (#17365)
|
||||
* Hide command line merge instructions when user can't push (#17339)
|
||||
* Move session to models/login (#17338)
|
||||
* Sync gitea app path for git hooks and authorized keys when starting (#17335)
|
||||
* Make the Mirror Queue a queue (#17326)
|
||||
* Add "Copy branch name" button to pull request page (#17323)
|
||||
* Fix repository summary on mobile (#17322)
|
||||
* Split `index.js` to separate files (#17315)
|
||||
* Show direct match on top for user search (#17303)
|
||||
* Frontend refactor: move Vue related code from `index.js` to `components` dir, and remove unused codes. (#17301)
|
||||
* Upgrade chi to v5 (#17298)
|
||||
* Disable form autofill (#17291)
|
||||
* Improve behavior of "Fork" button (#17288)
|
||||
* Open markdown image links in new window (#17287)
|
||||
* Add hints for special Wiki pages (#17283)
|
||||
* Move add deploy key form before the list and add a cancel button (#17228)
|
||||
* Allow adding multiple issues to a project (#17226)
|
||||
* Add metrics to get issues by repository (#17225)
|
||||
* Add specific event type to header (#17222)
|
||||
* Redirect on project after issue created (#17211)
|
||||
* Reference in new issue modal: dont pre-populate issue title (#17208)
|
||||
* Always set a unique Message-ID header (#17206)
|
||||
* Add projects and project boards in exposed metrics (#17202)
|
||||
* Add metrics to get issues by label (#17201)
|
||||
* Add protection to disable Gitea when run as root (#17168)
|
||||
* Don't return binary file changes in raw PR diffs by default (#17158)
|
||||
* Support sorting for project board issuses (#17152)
|
||||
* Force color-adjust for markdown checkboxes (#17146)
|
||||
* Add option to copy line permalink (#17145)
|
||||
* Move twofactor to models/login (#17143)
|
||||
* Multiple tokens support for migrating from github (#17134)
|
||||
* Unify issue and PR subtitles (#17133)
|
||||
* Make Requests Processes and create process hierarchy. Associate OpenRepository with context. (#17125)
|
||||
* Fix problem when database id is not increment as expected (#17124)
|
||||
* Avatar refactor, move avatar code from `models` to `models.avatars`, remove duplicated code (#17123)
|
||||
* Re-allow clipboard copy on non-https sites (#17118)
|
||||
* DBContext is just a Context (#17100)
|
||||
* Move login related structs and functions to models/login (#17093)
|
||||
* Add SkipLocal2FA option to pam and smtp sources (#17078)
|
||||
* Move db related basic functions to models/db (#17075)
|
||||
* Fixes username tagging in "Reference in new issue" (#17074)
|
||||
* Use light/dark theme based on system preference (#17051)
|
||||
* Always emit the configuration path (#17036)
|
||||
* Add `AbsoluteListOptions` (#17028)
|
||||
* Use common sessioner for API and Web (#17027)
|
||||
* Fix overflow label in small view (#17020)
|
||||
* Report the associated filter if there is an error in LDAP (#17014)
|
||||
* Add "new issue" btn on project (#17001)
|
||||
* Add doctor dbconsistency check for release and attachment (#16978)
|
||||
* Disable Fomantic's CSS tooltips (#16974)
|
||||
* Add Cache-Control to avatar redirects (#16973)
|
||||
* Make mirror feature more configurable (#16957)
|
||||
* Add skip and limit to git.GetTags (#16897)
|
||||
* Remove ParseQueueConnStr as it is unused (#16878)
|
||||
* Remove unused Fomantic sidebar module (#16853)
|
||||
* Allow LDAP Sources to provide Avatars (#16851)
|
||||
* Remove Dashboard/Home button from the navbar (#16844)
|
||||
* Use conditions but not repo ids as query condition (#16839)
|
||||
* Add user settings key/value DB table (#16834)
|
||||
* Add buttons to allow loading of incomplete diffs (#16829)
|
||||
* Add information for migrate failure (#16803)
|
||||
* Add EdDSA JWT signing algorithm (#16786)
|
||||
* Add user status filter to admin user management page (#16770)
|
||||
* Add Option to synchronize Admin & Restricted states from OIDC/OAuth2 along with Setting Scopes (#16766)
|
||||
* Do not use thin scrollbars on Firefox (#16738)
|
||||
* Download LFS in git and web workflow from minio/s3 directly (SERVE_DIRECT) (#16731)
|
||||
* Compute proper foreground color for labels (#16729)
|
||||
* Add edit button to wiki sidebar and footer (#16719)
|
||||
* Fix migration svg color (#16715)
|
||||
* Add link to vscode to repo header (#16664)
|
||||
* Add filter by owner and team to issue/pulls search endpoint (#16662)
|
||||
* Kanban colored boards (#16647)
|
||||
* Allow setting X-FRAME-OPTIONS (#16643)
|
||||
* Separate open and closed issue in metrics (#16637)
|
||||
* Support direct comparison (git diff a..b) as well merge comparison (a…b) (#16635)
|
||||
* Add setting to OAuth handlers to skip local 2FA authentication (#16594)
|
||||
* Make PR merge options more intuitive (#16582)
|
||||
* Show correct text when comparing commits on empty pull request (#16569)
|
||||
* Pre-fill suggested New File 'name' and 'content' with Query Params (#16556)
|
||||
* Add an abstract json layout to make it's easier to change json library (#16528)
|
||||
* Make Mermaid.js limit configurable (#16519)
|
||||
* Improve 2FA autofill (#16473)
|
||||
* Add modals to Organization and Team remove/leave (#16471)
|
||||
* Show tag name on dashboard items list (#16466)
|
||||
* Change default cron schedules from @every 24h to @midnight (#16431)
|
||||
* Prevent double sanitize (#16386)
|
||||
* Replace `list.List` with slices (#16311)
|
||||
* Add configuration option to restrict users by default (#16256)
|
||||
* Move login out of models (#16199)
|
||||
* Support pagination of organizations on user settings pages (#16083)
|
||||
* Switch migration icon to svg (#15954)
|
||||
* Add left padding for chunk header of split diff view (#13397)
|
||||
* Allow U2F 2FA without TOTP (#11573)
|
||||
* BUGFIXES
|
||||
* GitLab reviews may not have the updated_at field set (#18450) (#18461)
|
||||
* Fix detection of no commits when the default branch is not master (#18422) (#18423)
|
||||
* Fix broken oauth2 authentication source edit page (#18412) (#18419)
|
||||
* Place inline diff comment dialogs on split diff in 4th and 8th columns (#18403) (#18404)
|
||||
* Fix restore without topic failure (#18387) (#18400)
|
||||
* Fix commit's time (#18375) (#18392)
|
||||
* Fix partial cloning a repo (#18373) (#18377)
|
||||
* Stop trimming preceding and suffixing spaces from editor filenames (#18334)
|
||||
* Prevent showing webauthn error for every time visiting `/user/settings/security` (#18386)
|
||||
* Fix mime-type detection for HTTP server (#18370) (#18371)
|
||||
* Stop trimming preceding and suffixing spaces from editor filenames (#18334)
|
||||
* Restore propagation of ErrDependenciesLeft (#18325)
|
||||
* Fix PR comments UI (#18323)
|
||||
* Use indirect comparison when showing pull requests (#18313)
|
||||
* Replace satori/go.uuid with gofrs/uuid (#18311)
|
||||
* Fix commit links on compare page (#18310)
|
||||
* Don't show double error response in git hook (#18292)
|
||||
* Handle missing default branch better in owner/repo/branches page (#18290)
|
||||
* Fix CheckRepoStats and reuse it during migration (#18264)
|
||||
* Prevent underline hover on cards (#18259)
|
||||
* Don't delete branch if other PRs with this branch are open (#18164)
|
||||
* Require codereview to have content (#18156)
|
||||
* Allow admin to associate missing LFS objects for repositories (#18143)
|
||||
* When attempting to subscribe other user to issue report why access denied (#18091)
|
||||
* Add option to convert CRLF to LF line endings for sendmail (#18075)
|
||||
* Only create pprof files for gitea serv if explicitly asked for (#18068)
|
||||
* Abort merge if head has been updated before pressing merge (#18032)
|
||||
* Improve TestPatch to use git read-tree -m and implement git-merge-one-file functionality (#18004)
|
||||
* Use JSON module instead of stdlib json (#18003)
|
||||
* Fixed issue merged/closed wording (#17973)
|
||||
* Return nicer error for ForcePrivate (#17971)
|
||||
* Fix overflow in commit graph (#17947)
|
||||
* Prevent services/mailer/mailer_test.go tests from deleteing data directory (#17941)
|
||||
* Use disable_form_autofill on Codebase and Gitbucket (#17936)
|
||||
* Fix a panic in NotifyCreateIssueComment (caused by string truncation) (#17928)
|
||||
* Fix markdown URL parsing (#17924)
|
||||
* Apply CSS Variables to all message elements (#17920)
|
||||
* Improve checkBranchName (#17901)
|
||||
* Update chi/middleware to chi/v5/middleware (#17888)
|
||||
* Fix position of label color picker colors (#17866)
|
||||
* Fix ListUnadoptedRepositories incorrect total count (#17865)
|
||||
* Remove whitespace inside rendered code `<td>` (#17859)
|
||||
* Make Co-committed-by and co-authored-by trailers optional (#17848)
|
||||
* Fix value of User.IsRestricted when oauth2 user registration (#17839)
|
||||
* Use new OneDev /milestones endpoint (#17782)
|
||||
* Prevent deadlock in TestPersistableChannelQueue (#17717)
|
||||
* Simplify code for writing SHA to name-rev (#17696)
|
||||
* Fix database deadlock when update issue labels (#17649)
|
||||
* Add warning for BIDI characters in page renders and in diffs (#17562)
|
||||
* Fix ipv6 parsing for builtin ssh server (#17561)
|
||||
* Multiple Escaping Improvements (#17551)
|
||||
* Fixes #16559 - Do not trim leading spaces for tab delimited (#17442)
|
||||
* Show client-side error if wiki page is empty (#17415)
|
||||
* Fix context popup error (#17398)
|
||||
* Stop sanitizing full name in API (#17396)
|
||||
* Fix issue close/comment buttons on mobile (#17317)
|
||||
* Fix navbar UI (#17235)
|
||||
* Fix problem when database id is not increment as expected (#17229)
|
||||
* Open the DingTalk link in browser (#17084)
|
||||
* Remove heads pointing to missing old refs (#17076)
|
||||
* Fix commit status index problem (#17061)
|
||||
* Handle broken references in mirror sync (#17013)
|
||||
* Fix for create repo page layout (#17012)
|
||||
* Improve LDAP synchronization efficiency (#16994)
|
||||
* Add repo_id for attachment (#16958)
|
||||
* Clean-up HookPreReceive and restore functionality for pushing non-standard refs (#16705)
|
||||
* Remove duplicate csv import in modules/csv/csv.go (#16631)
|
||||
* Improve SMTP authentication and Fix user creation bugs (#16612)
|
||||
* Fixed emoji alias not parsed in links (#16221)
|
||||
* Calculate label URL on API (#16186)
|
||||
* TRANSLATION
|
||||
* Fix mispelling of starred as stared (#17465)
|
||||
* Re-separate the color translation strings (#17390)
|
||||
* Enable Malayalam, Greek, Persian, Hungarian & Indonesian by default (#16998)
|
||||
* BUILD
|
||||
* Add lockfile-check (#18285)
|
||||
* Don't store assets modified time into generated files (#18193)
|
||||
* MISC
|
||||
* Update JS dependencies (#17611)
|
||||
|
||||
## [1.15.11](https://github.com/go-gitea/gitea/releases/tag/v1.15.11) - 2022-01-29
|
||||
|
||||
* SECURITY
|
||||
* Only view milestones from current repo (#18414) (#18418)
|
||||
* BUGFIXES
|
||||
* Fix broken when no commits and default branch is not master (#18422) (#18424)
|
||||
* Fix commit's time (#18375) (#18409)
|
||||
* Fix restore without topic failure (#18387) (#18401)
|
||||
* Fix mermaid import in 1.15 (it uses ESModule now) (#18382)
|
||||
* Update to go/text 0.3.7 (#18336)
|
||||
* MISC
|
||||
* Upgrade EasyMDE to 2.16.1 (#18278) (#18279)
|
||||
|
||||
## [1.15.10](https://github.com/go-gitea/gitea/releases/tag/v1.15.10) - 2022-01-14
|
||||
|
||||
* BUGFIXES
|
||||
* Fix inconsistent PR comment counts (#18260) (#18261)
|
||||
* Fix release link broken (#18252) (#18253)
|
||||
* Fix update user from site administration page bug (#18250) (#18251)
|
||||
* Set HeadCommit when creating tags (#18116) (#18173)
|
||||
* Use correct translation key for error messages due to max repo limits (#18135 & #18153) (#18152)
|
||||
* Fix purple color in suggested label colors (#18241) (#18242)
|
||||
* SECURITY
|
||||
* Bump mermaid from 8.10.1 to 8.13.8 (#18198) (#18206)
|
||||
|
||||
## [1.15.9](https://github.com/go-gitea/gitea/releases/tag/v1.15.9) - 2021-12-30
|
||||
|
||||
* BUGFIXES
|
||||
* Fix wrong redirect on org labels (#18128) (#18134)
|
||||
* Fix: unstable sort skips/duplicates issues across pages (#18094) (#18095)
|
||||
* Revert "Fix delete u2f keys bug (#18042)" (#18107)
|
||||
* Migrating wiki don't require token, so we should move it out of the require form (#17645) (#18104)
|
||||
* Prevent NPE if gitea uploader fails to open url (#18080) (#18101)
|
||||
* Reset locale on login (#17734) (#18100)
|
||||
* Correctly handle failed migrations (#17575) (#18099)
|
||||
* Instead of using routerCtx just escape the url before routing (#18086) (#18098)
|
||||
* Quote references to the user table in consistency checks (#18072) (#18073)
|
||||
* Add NotFound handler (#18062) (#18067)
|
||||
* Ensure that git repository is closed before transfer (#18049) (#18057)
|
||||
* Use common sessioner for API and web routes (#18114)
|
||||
* TRANSLATION
|
||||
* Fix code search result hint on zh-CN (#18053)
|
||||
|
||||
## [1.15.8](https://github.com/go-gitea/gitea/releases/tag/v1.15.8) - 2021-12-20
|
||||
|
||||
* BUGFIXES
|
||||
* Move POST /{username}/action/{action} to simply POST /{username} (#18045) (#18046)
|
||||
* Fix delete u2f keys bug (#18040) (#18042)
|
||||
* Reset Session ID on login (#18018) (#18041)
|
||||
* Prevent off-by-one error on comments on newly appended lines (#18029) (#18035)
|
||||
* Stop printing 03d after escaped characters in logs (#18030) (#18034)
|
||||
* Reset locale on login (#18023) (#18025)
|
||||
* Fix reset password email template (#17025) (#18022)
|
||||
* Fix outType on gitea dump (#18000) (#18016)
|
||||
* Ensure complexity, minlength and isPwned are checked on password setting (#18005) (#18015)
|
||||
* Fix rename notification bug (#18011)
|
||||
* Prevent double decoding of % in url params (#17997) (#18001)
|
||||
* Prevent hang in git cat-file if the repository is not a valid repository (Partial #17991) (#17992)
|
||||
* Prevent deadlock in create issue (#17970) (#17982)
|
||||
* TESTING
|
||||
* Use non-expiring key. (#17984) (#17985)
|
||||
|
||||
## [1.15.7](https://github.com/go-gitea/gitea/releases/tag/v1.15.7) - 2021-12-01
|
||||
|
||||
* ENHANCEMENTS
|
||||
* Only allow webhook to send requests to allowed hosts (#17482) (#17510)
|
||||
* Fix login redirection links (#17451) (#17473)
|
||||
* BUGFIXES
|
||||
* Fix database inconsistent when admin change user email (#17549) (#17840)
|
||||
* Use correct user on releases (#17806) (#17818)
|
||||
* Fix commit count in tag view (#17698) (#17790)
|
||||
* Fix close issue but time watcher still running (#17643) (#17761)
|
||||
* Fix Migrate Description (#17692) (#17727)
|
||||
* Fix bug when project board get open issue number (#17703) (#17726)
|
||||
* Return 400 but not 500 when request archive with wrong format (#17691) (#17700)
|
||||
* Fix bug when read mysql database max lifetime (#17682) (#17690)
|
||||
* Fix database deadlock when update issue labels (#17649) (#17665)
|
||||
* Fix bug on detect issue/comment writer (#17592)
|
||||
* Remove appSubUrl from pasted images (#17572) (#17588)
|
||||
* Make `ParsePatch` more robust (#17573) (#17580)
|
||||
* Fix stats upon searching issues (#17566) (#17578)
|
||||
* Escape issue titles in comments list (#17555) (#17556)
|
||||
* Fix zero created time bug on commit api (#17546) (#17547)
|
||||
* Fix database keyword quote problem on migration v161 (#17522) (#17523)
|
||||
* Fix email with + when active (#17518) (#17520)
|
||||
* Stop double encoding blame commit messages (#17498) (#17500)
|
||||
* Quote the table name in CountOrphanedObjects (#17487) (#17488)
|
||||
* Run Migrate in Install rather than just SyncTables (#17475) (#17486)
|
||||
* BUILD
|
||||
* Fix golangci-lint warnings (#17598 et al) (#17668)
|
||||
* MISC
|
||||
* Preserve color when inverting emojis (#17797) (#17799)
|
||||
|
||||
## [1.15.6](https://github.com/go-gitea/gitea/releases/tag/v1.15.6) - 2021-10-28
|
||||
|
||||
* BUGFIXES
|
||||
* Prevent panic in serv.go with Deploy Keys (#17434) (#17435)
|
||||
* Fix CSV render error (#17406) (#17431)
|
||||
* Read expected buffer size (#17409) (#17430)
|
||||
* Ensure that restricted users can access repos for which they are members (#17460) (#17464)
|
||||
* Make commit-statuses popup show correctly (#17447) (#17466)
|
||||
* TESTING
|
||||
* Add integration tests for private.NoServCommand and private.ServCommand (#17456) (#17463)
|
||||
|
||||
## [1.15.5](https://github.com/go-gitea/gitea/releases/tag/v1.15.5) - 2021-10-21
|
||||
|
||||
* SECURITY
|
||||
* Upgrade Bluemonday to v1.0.16 (#17372) (#17374)
|
||||
* Ensure correct SSH permissions check for private and restricted users (#17370) (#17373)
|
||||
* BUGFIXES
|
||||
* Prevent NPE in CSV diff rendering when column removed (#17018) (#17377)
|
||||
* Offer rsa-sha2-512 and rsa-sha2-256 algorithms in internal SSH (#17281) (#17376)
|
||||
* Don't panic if we fail to parse U2FRegistration data (#17304) (#17371)
|
||||
* Ensure popup text is aligned left (backport for 1.15) (#17343)
|
||||
* Ensure that git daemon export ok is created for mirrors (#17243) (#17306)
|
||||
* Disable core.protectNTFS (#17300) (#17302)
|
||||
* Use pointer for wrappedConn methods (#17295) (#17296)
|
||||
* AutoRegistration is supposed to be working with disabled registration (backport) (#17292)
|
||||
* Handle duplicate keys on GPG key ring (#17242) (#17284)
|
||||
* Fix SVG side by side comparison link (#17375) (#17391)
|
||||
|
||||
## [1.15.4](https://github.com/go-gitea/gitea/releases/tag/v1.15.4) - 2021-10-08
|
||||
* BUGFIXES
|
||||
* Raw file API: don't try to interpret 40char filenames as commit SHA (#17185) (#17272)
|
||||
* Don't allow merged PRs to be reopened (#17192) (#17271)
|
||||
* Fix incorrect repository count on organization tab of dashboard (#17256) (#17266)
|
||||
* Fix unwanted team review request deletion (#17257) (#17264)
|
||||
* Fix broken Activities link in team dashboard (#17255) (#17258)
|
||||
* API pull's head/base have correct permission(#17214) (#17245)
|
||||
* Fix strange behavior of DownloadPullDiffOrPatch in incorrect index (#17223) (#17227)
|
||||
* Upgrade xorm to v1.2.5 (#17177) (#17188)
|
||||
* Fix missing repo link in issue/pull assigned emails (#17183) (#17184)
|
||||
* Fix bug of get context user (#17169) (#17172)
|
||||
* Nicely handle missing user in collaborations (#17049) (#17166)
|
||||
* Add Horizontal scrollbar to inner menu on Chrome (#17086) (#17164)
|
||||
* Fix wrong i18n keys (#17150) (#17153)
|
||||
* Fix Archive Creation: correct transaction ending (#17151)
|
||||
* Prevent panic in Org mode HighlightCodeBlock (#17140) (#17141)
|
||||
* Create doctor command to fix repo_units broken by dumps from 1.14.3-1.14.6 (#17136) (#17137)
|
||||
* ENHANCEMENT
|
||||
* Check user instead of organization when creating a repo from a template via API (#16346) (#17195)
|
||||
* TRANSLATION
|
||||
* v1.15 fix Sprintf format 'verbs' in locale files (#17187)
|
||||
|
||||
## [1.15.3](https://github.com/go-gitea/gitea/releases/tag/v1.15.3) - 2021-09-19
|
||||
|
||||
* ENHANCEMENTS
|
||||
* Add fluid to ui container class to remove margin (#16396) (#16976)
|
||||
* Add caller to cat-file batch calls (#17082) (#17089)
|
||||
* BUGFIXES
|
||||
* Render full plain readme. (#17083) (#17090)
|
||||
* Upgrade xorm to v1.2.4 (#17059)
|
||||
* Fix bug of migrate comments which only fetch one page (#17055) (#17058)
|
||||
* Do not show issue context popup on external issues (#17050) (#17054)
|
||||
* Decrement Fork Num when converting from Fork (#17035) (#17046)
|
||||
* Correctly rollback in ForkRepository (#17034) (#17045)
|
||||
* Fix missing close in WalkGitLog (#17008) (#17009)
|
||||
* Add prefix to SVG id/class attributes (#16997) (#17000)
|
||||
* Fix bug of migrated repository not index (#16991) (#16996)
|
||||
* Skip AllowedUserVisibilityModes validation on update user if it is an organisation (#16988) (#16990)
|
||||
* Fix storage Iterate bug and Add storage doctor to delete garbage attachments (#16971) (#16977)
|
||||
* Fix issue with issue default mail template (#16956) (#16975)
|
||||
* Ensure that rebase conflicts are handled in updates (#16952) (#16960)
|
||||
* Prevent panic on diff generation (#16950) (#16951)
|
||||
|
||||
## [1.15.2](https://github.com/go-gitea/gitea/releases/tag/v1.15.2) - 2021-09-03
|
||||
|
||||
* BUGFIXES
|
||||
* Add unique constraint back into issue_index (#16938)
|
||||
* Close storage objects before cleaning (#16934) (#16942)
|
||||
|
||||
## [1.15.1](https://github.com/go-gitea/gitea/releases/tag/v1.15.1) - 2021-09-02
|
||||
|
||||
* BUGFIXES
|
||||
* Allow BASIC authentication access to /:owner/:repo/releases/download/* (#16916) (#16923)
|
||||
* Prevent leave changes dialogs due to autofill fields (#16912) (#16920)
|
||||
* Ignore review comment when ref commit is missed (#16905) (#16919)
|
||||
* Fix wrong attachment removal (#16915) (#16917)
|
||||
* Gitlab Migrator: dont ignore reactions of last request (#16903) (#16913)
|
||||
* Correctly return the number of Repositories for Organizations (#16807) (#16911)
|
||||
* Test if LFS object is accessible (#16865) (#16904)
|
||||
* Fix git.Blob.DataAsync(): close pipe since we return a NopCloser (#16899) (#16900)
|
||||
* Fix dump and restore respository (#16698) (#16898)
|
||||
* Repare and Improve GetDiffRangeWithWhitespaceBehavior (#16894) (#16895)
|
||||
* Fix wiki raw commit diff/patch view (#16891) (#16892)
|
||||
* Ensure wiki repos are all closed (#16886) (#16888)
|
||||
* List limited and private orgs if authenticated on API (#16866) (#16879)
|
||||
* Simplify split diff view generation and remove JS dependency (#16775) (#16863)
|
||||
* Ensure that the default visibility is set on the user create page (#16845) (#16862)
|
||||
* In Render tolerate not being passed a context (#16842) (#16858)
|
||||
* Upgrade xorm to v1.2.2 (#16663) & Add test to ensure that dumping of login sources remains correct (#16847) (#16848)
|
||||
* Report the correct number of pushes on the feeds (#16811) (#16822)
|
||||
* Add primary_key to issue_index (#16813) (#16820)
|
||||
* Prevent NPE on empty commit (#16812) (#16819)
|
||||
* Fix branch pagination error (#16805) (#16816)
|
||||
* Add missing return to handleSettingRemoteAddrError (#16794) (#16795)
|
||||
* Remove spurious / from issues.opened_by (#16793)
|
||||
* Ensure that template compilation panics are sent to the logs (#16788) (#16792)
|
||||
* Update caddyserver/certmagic (#16789) (#16790)
|
||||
|
||||
## [1.15.0](https://github.com/go-gitea/gitea/releases/tag/v1.15.0) - 2021-08-21
|
||||
|
||||
* BREAKING
|
||||
* Make app.ini permissions more restrictive (#16266)
|
||||
@@ -19,9 +785,15 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Move (custom) assets into subpath `/assets` (#15219)
|
||||
* Use level config in log section when sub log section not set level (#15176)
|
||||
* Links in markdown should be absolute to the repository not the server (#15088)
|
||||
* Upgrade to the latest version of golang-jwt (#16590) (#16606)
|
||||
* Set minimum supported version of go to 1.16 (#16710)
|
||||
* SECURITY
|
||||
* Encrypt LDAP bind password in db with SECRET_KEY (#15547)
|
||||
* Remove random password in Dockerfiles (#15362)
|
||||
* Upgrade to the latest version of golang-jwt and increase minimum go to 1.15 (#16590) (#16606)
|
||||
* Correctly create of git-daemon-export-ok files (#16508) (#16514)
|
||||
* Don't show private user's repo in explore view (#16550) (#16554)
|
||||
* Update node tar dependency to 6.1.6 (#16622) (#16623)
|
||||
* FEATURES
|
||||
* Update Go-Git to take advantage of LargeObjectThreshold (#16316)
|
||||
* Support custom mime type mapping for text files (#16304)
|
||||
@@ -42,7 +814,7 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Add LFS Migration and Mirror (#14726)
|
||||
* Improve notifications for WIP draft PR's (#14663)
|
||||
* Disable Stars config option (#14653)
|
||||
* Add option to provide signature for a token to verify key ownership (#14054)
|
||||
* GPG Key Ownership verification with Signed Token (#14054)
|
||||
* OAuth2 auto-register (#5123)
|
||||
* API
|
||||
* Return updated repository when changing repository using API (#16420)
|
||||
@@ -62,6 +834,8 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Add Active and ProhibitLogin to API (#15689)
|
||||
* Add Location, Website and Description to API (#15675)
|
||||
* Expose resolver via API (#15167)
|
||||
* Swagger AccessToken fixes (#16574) (#16597)
|
||||
* Set AllowedHeaders on API CORS handler (#16524) (#16618)
|
||||
* ENHANCEMENTS
|
||||
* Support HTTP/2 in Let's Encrypt (#16371)
|
||||
* Introduce NotifySubjectType (#16320)
|
||||
@@ -187,6 +961,41 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Add NeedPostProcess for Parser interface to improve performance of csv parser and some external parser (#15153)
|
||||
* Add code block highlight to orgmode back (#14222)
|
||||
* Remove User.GetOrganizations() (#14032)
|
||||
* Restore Accessibility for Dropdown (#16576) (#16617)
|
||||
* Pass down SignedUserName down to AccessLogger context (#16605) (#16616)
|
||||
* Fix table alignment in markdown (#16596) (#16602)
|
||||
* Fix 500 on first wiki page (#16586) (#16598)
|
||||
* Lock goth/gothic and Re-attempt OAuth2 registration on login if registration failed at startup (#16564) (#16570)
|
||||
* Upgrade levelqueue to v0.4.0 (#16560) (#16561)
|
||||
* Handle too long PR titles correctly (#16517) (#16549)
|
||||
* Fix data race in bleve indexer (#16474) (#16509)
|
||||
* Restore CORS on git smart http protocol (#16496) (#16506)
|
||||
* Fix race in log (#16490) (#16505)
|
||||
* Fix prepareWikiFileName to respect existing unescaped files (#16487) (#16498)
|
||||
* Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16480)
|
||||
* Update notification table with only latest data (#16445) (#16469)
|
||||
* Fix crash following ldap authentication update (#16447) (#16448)
|
||||
* Fix direct creation of external users on admin page (partial #16612) (#16613)
|
||||
* Prevent 500 on draft releases without tag (#16634) (#16636)
|
||||
* Restore creation of git-daemon-export-ok files (#16508) (#16514)
|
||||
* Fix data race in bleve indexer (#16474) (#16509)
|
||||
* Restore CORS on git smart http protocol (#16496) (#16506)
|
||||
* Fix race in log (#16490) (#16505)
|
||||
* Fix prepareWikiFileName to respect existing unescaped files (#16487) (#16498)
|
||||
* Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16480)
|
||||
* Update notification table with only latest data (#16445) (#16469)
|
||||
* Fix crash following ldap authentication update (#16447) (#16448)
|
||||
* Restore compatibility with SQLServer 2008 R2 in migrations (#16638)
|
||||
* Fix direct creation of external users on admin page (#16613)
|
||||
* Fix go-git implementation of GetNote when passed a non-existent commit (#16658) (#16659)
|
||||
* Fix NPE in fuzzer (#16680) (#16682)
|
||||
* Set issue_index when finishing migration (#16685) (#16687)
|
||||
* Skip patch download when no patch file exists (#16356) (#16681)
|
||||
* Ensure empty lines are copiable and final new line too (#16678) (#16692)
|
||||
* Fix wrong user in OpenID response (#16736) (#16741)
|
||||
* Do not use thin scrollbars on Firefox (#16738) (#16745)
|
||||
* Recreate Tables should Recreate indexes on MySQL (#16718) (#16739)
|
||||
* Keep attachments on tasklist update (#16750) (#16757)
|
||||
* TESTING
|
||||
* Bump `postgres` and `mysql` versions (#15710)
|
||||
* Add tests for clone from wiki (#15513)
|
||||
@@ -197,7 +1006,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Fix mirror_lfs source string in en-US locale (#15369)
|
||||
* BUILD
|
||||
* Upgrade xorm to v1.1.1 (#16339)
|
||||
* Alpine 3.14 released (#16170)
|
||||
* Disable legal comments in esbuild (#15929)
|
||||
* Switch to Node 16 to build fronted (#15804)
|
||||
* Use esbuild to minify CSS (#15756)
|
||||
@@ -216,6 +1024,37 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
|
||||
* Remove utf8 option from installation page (#16126)
|
||||
* Use Wants= over Requires= in systemd file (#15897)
|
||||
|
||||
## [1.14.7](https://github.com/go-gitea/gitea/releases/tag/v1.14.7) - 2021-09-02
|
||||
|
||||
* BUGFIXES
|
||||
* Add missing gitRepo close at GetDiffRangeWithWhitespaceBehavior (Partial #16894) (#16896)
|
||||
* Fix wiki raw commit diff/patch view (#16891) (#16893)
|
||||
* Ensure wiki repos are all closed (#16886) (#16889)
|
||||
* Upgrade xorm to v1.2.2 (#16663) & Add test to ensure that dumping of login sources remains correct (#16847) (#16849)
|
||||
* Recreate Tables should Recreate indexes on MySQL (#16718) (#16740)
|
||||
|
||||
## [1.14.6](https://github.com/go-gitea/gitea/releases/tag/v1.14.6) - 2021-08-04
|
||||
|
||||
* SECURITY
|
||||
* Bump github.com/markbates/goth from v1.67.1 to v1.68.0 (#16538) (#16540)
|
||||
* Switch to maintained JWT lib (#16532) (#16535)
|
||||
* Upgrade to latest version of golang-jwt (as forked for 1.14) (#16590) (#16607)
|
||||
* BUGFIXES
|
||||
* Add basic edit ldap auth test & actually fix #16252 (#16465) (#16495)
|
||||
* Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16481)
|
||||
|
||||
## [1.14.5](https://github.com/go-gitea/gitea/releases/tag/v1.14.5) - 2021-07-16
|
||||
|
||||
* SECURITY
|
||||
* Hide mirror passwords on repo settings page (#16022) (#16355)
|
||||
* Update bluemonday to v1.0.15 (#16379) (#16380)
|
||||
* BUGFIXES
|
||||
* Retry rename on lock induced failures (#16435) (#16439)
|
||||
* Validate issue index before querying DB (#16406) (#16410)
|
||||
* Fix crash following ldap authentication update (#16447) (#16449)
|
||||
* ENHANCEMENTS
|
||||
* Redirect on bad CSRF instead of presenting bad page (#14937) (#16378)
|
||||
|
||||
## [1.14.4](https://github.com/go-gitea/gitea/releases/tag/v1.14.4) - 2021-07-06
|
||||
|
||||
* BUGFIXES
|
||||
|
@@ -81,23 +81,22 @@ Here's how to run the test suite:
|
||||
|``make lint-frontend`` | lint frontend files |
|
||||
|``make lint-backend`` | lint backend files |
|
||||
|
||||
- run test code (Suggest run in linux)
|
||||
- run test code (Suggest run in Linux)
|
||||
|
||||
| | |
|
||||
| :------------------------------------- | :----------------------------------------------- |
|
||||
|``make test[\#TestSpecificName]`` | run unit test |
|
||||
|``make test-sqlite[\#TestSpecificName]``| run [integration](integrations) test for sqlite |
|
||||
|[More detail message about integrations](integrations/README.md) |
|
||||
|``make test-sqlite[\#TestSpecificName]``| run [integration](integrations) test for SQLite |
|
||||
|[More details about integrations](integrations/README.md) |
|
||||
|
||||
## Vendoring
|
||||
|
||||
We keep a cached copy of dependencies within the `vendor/` directory,
|
||||
managing updates via [Modules](https://golang.org/cmd/go/#hdr-Module_maintenance).
|
||||
We manage dependencies via [Go Modules](https://golang.org/cmd/go/#hdr-Module_maintenance), more details: [go mod](https://go.dev/ref/mod).
|
||||
|
||||
Pull requests should only include `vendor/` updates if they are part of
|
||||
Pull requests should only include `go.mod`, `go.sum` updates if they are part of
|
||||
the same change, be it a bugfix or a feature addition.
|
||||
|
||||
The `vendor/` update needs to be justified as part of the PR description,
|
||||
The `go.mod`, `go.sum` update needs to be justified as part of the PR description,
|
||||
and must be verified by the reviewers and/or merger to always reference
|
||||
an existing upstream commit.
|
||||
|
||||
@@ -106,7 +105,7 @@ You can find more information on how to get started with it on the [Modules Wiki
|
||||
## Translation
|
||||
|
||||
We do all translation work inside [Crowdin](https://crowdin.com/project/gitea).
|
||||
The only translation that is maintained in this git repository is
|
||||
The only translation that is maintained in this Git repository is
|
||||
[`en_US.ini`](https://github.com/go-gitea/gitea/blob/master/options/locale/locale_en-US.ini)
|
||||
and is synced regularly to Crowdin. Once a translation has reached
|
||||
A SATISFACTORY PERCENTAGE it will be synced back into this repo and
|
||||
@@ -157,7 +156,7 @@ import (
|
||||
|
||||
## Design guideline
|
||||
|
||||
To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The gitea code is divided into the following parts:
|
||||
To maintain understandable code and avoid circular dependencies it is important to have a good structure of the code. The Gitea code is divided into the following parts:
|
||||
|
||||
- **integration:** Integrations tests
|
||||
- **models:** Contains the data structures used by xorm to construct database tables. It also contains supporting functions to query and update the database. Dependencies to other code in Gitea should be avoided although some modules might be needed (for example for logging).
|
||||
@@ -207,6 +206,10 @@ In general, HTTP methods are chosen as follows:
|
||||
|
||||
An endpoint which changes/edits an object expects all fields to be optional (except ones to identify the object, which are required).
|
||||
|
||||
### Endpoints returning lists should
|
||||
* support pagination (`page` & `limit` options in query)
|
||||
* set `X-Total-Count` header via **SetTotalCountHeader** ([example](https://github.com/go-gitea/gitea/blob/7aae98cc5d4113f1e9918b7ee7dd09f67c189e3e/routers/api/v1/repo/issue.go#L444))
|
||||
|
||||
|
||||
## Developer Certificate of Origin (DCO)
|
||||
|
||||
@@ -219,7 +222,7 @@ Additionally you could add a line at the end of your commit message.
|
||||
Signed-off-by: Joe Smith <joe.smith@email.com>
|
||||
```
|
||||
|
||||
If you set your `user.name` and `user.email` git configs, you can add the
|
||||
If you set your `user.name` and `user.email` Git configs, you can add the
|
||||
line to the end of your commit automatically with `git commit -s`.
|
||||
|
||||
We assume in good faith that the information you provide is legally binding.
|
||||
@@ -231,8 +234,8 @@ on, finishing, and issuing releases. The overall goal is to make a
|
||||
minor release every three or four months, which breaks down into two or three months of
|
||||
general development followed by one month of testing and polishing
|
||||
known as the release freeze. All the feature pull requests should be
|
||||
merged before feature freeze. And, during the frozen period, a corresponding
|
||||
release branch is open for fixes backported from main branch. Release candidates
|
||||
merged before feature freeze. And, during the frozen period, a corresponding
|
||||
release branch is open for fixes backported from main branch. Release candidates
|
||||
are made during this period for user testing to
|
||||
obtain a final version that is maintained in this branch. A release is
|
||||
maintained by issuing patch releases to only correct critical problems
|
||||
@@ -264,7 +267,7 @@ to the maintainers team. If a maintainer is inactive for more than 3
|
||||
months and forgets to leave the maintainers team, the owners may move
|
||||
him or her from the maintainers team to the advisors team.
|
||||
For security reasons, Maintainers should use 2FA for their accounts and
|
||||
if possible provide gpg signed commits.
|
||||
if possible provide GPG signed commits.
|
||||
https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/
|
||||
https://help.github.com/articles/signing-commits-with-gpg/
|
||||
|
||||
@@ -295,6 +298,11 @@ and lead the development of Gitea.
|
||||
To honor the past owners, here's the history of the owners and the time
|
||||
they served:
|
||||
|
||||
* 2022-01-01 ~ 2022-12-31 - https://github.com/go-gitea/gitea/issues/17872
|
||||
* [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
|
||||
* [Matti Ranta](https://gitea.com/techknowlogick) <techknowlogick@gitea.io>
|
||||
* [Andrew Thornton](https://gitea.com/zeripath) <art27@cantab.net>
|
||||
|
||||
* 2021-01-01 ~ 2021-12-31 - https://github.com/go-gitea/gitea/issues/13801
|
||||
* [Lunny Xiao](https://gitea.com/lunny) <xiaolunwen@gmail.com>
|
||||
* [Lauris Bukšis-Haberkorns](https://gitea.com/lafriks) <lauris@nix.lv>
|
||||
@@ -322,13 +330,13 @@ they served:
|
||||
|
||||
## Versions
|
||||
|
||||
Gitea has the `master` branch as a tip branch and has version branches
|
||||
Gitea has the `main` branch as a tip branch and has version branches
|
||||
such as `release/v0.9`. `release/v0.9` is a release branch and we will
|
||||
tag `v0.9.0` for binary download. If `v0.9.0` has bugs, we will accept
|
||||
pull requests on the `release/v0.9` branch and publish a `v0.9.1` tag,
|
||||
after bringing the bug fix also to the master branch.
|
||||
after bringing the bug fix also to the main branch.
|
||||
|
||||
Since the `master` branch is a tip version, if you wish to use Gitea
|
||||
Since the `main` branch is a tip version, if you wish to use Gitea
|
||||
in production, please download the latest release tag version. All the
|
||||
branches will be protected via GitHub, all the PRs to every branch must
|
||||
be reviewed by two maintainers and must pass the automatic tests.
|
||||
@@ -336,14 +344,14 @@ be reviewed by two maintainers and must pass the automatic tests.
|
||||
## Releasing Gitea
|
||||
|
||||
* Let $vmaj, $vmin and $vpat be Major, Minor and Patch version numbers, $vpat should be rc1, rc2, 0, 1, ...... $vmaj.$vmin will be kept the same as milestones on github or gitea in future.
|
||||
* Before releasing, confirm all the version's milestone issues or PRs has been resolved. Then discuss the release on discord channel #maintainers and get agreed with almost all the owners and mergers. Or you can declare the version and if nobody against in about serval hours.
|
||||
* If this is a big version first you have to create PR for changelog on branch `master` with PRs with label `changelog` and after it has been merged do following steps:
|
||||
* Before releasing, confirm all the version's milestone issues or PRs has been resolved. Then discuss the release on Discord channel #maintainers and get agreed with almost all the owners and mergers. Or you can declare the version and if nobody against in about serval hours.
|
||||
* If this is a big version first you have to create PR for changelog on branch `main` with PRs with label `changelog` and after it has been merged do following steps:
|
||||
* Create `-dev` tag as `git tag -s -F release.notes v$vmaj.$vmin.0-dev` and push the tag as `git push origin v$vmaj.$vmin.0-dev`.
|
||||
* When CI has finished building tag then you have to create a new branch named `release/v$vmaj.$vmin`
|
||||
* If it is bugfix version create PR for changelog on branch `release/v$vmaj.$vmin` and wait till it is reviewed and merged.
|
||||
* Add a tag as `git tag -s -F release.notes v$vmaj.$vmin.$`, release.notes file could be a temporary file to only include the changelog this version which you added to `CHANGELOG.md`.
|
||||
* And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically created a release and upload all the compiled binary. (But currently it didn't add the release notes automatically. Maybe we should fix that.)
|
||||
* If needed send PR for changelog on branch `master`.
|
||||
* And then push the tag as `git push origin v$vmaj.$vmin.$`. Drone CI will automatically create a release and upload all the compiled binary. (But currently it doesn't add the release notes automatically. Maybe we should fix that.)
|
||||
* If needed send PR for changelog on branch `main`.
|
||||
* Send PR to [blog repository](https://gitea.com/gitea/blog) announcing the release.
|
||||
|
||||
## Copyright
|
||||
|
12
Dockerfile
12
Dockerfile
@@ -1,7 +1,5 @@
|
||||
|
||||
###################################
|
||||
#Build stage
|
||||
FROM golang:1.16-alpine3.14 AS build-env
|
||||
FROM golang:1.18-alpine3.15 AS build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
@@ -25,7 +23,7 @@ RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||
# Begin env-to-ini build
|
||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
||||
|
||||
FROM alpine:3.14
|
||||
FROM alpine:3.13
|
||||
LABEL maintainer="maintainers@gitea.io"
|
||||
|
||||
EXPOSE 22 3000
|
||||
@@ -35,7 +33,6 @@ RUN apk --no-cache add \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gettext \
|
||||
git \
|
||||
linux-pam \
|
||||
openssh \
|
||||
s6 \
|
||||
@@ -43,6 +40,8 @@ RUN apk --no-cache add \
|
||||
su-exec \
|
||||
gnupg
|
||||
|
||||
RUN apk add git --repository=http://dl-cdn.alpinelinux.org/alpine/v3.16/main
|
||||
|
||||
RUN addgroup \
|
||||
-S -g 1000 \
|
||||
git && \
|
||||
@@ -66,4 +65,5 @@ CMD ["/bin/s6-svscan", "/etc/s6"]
|
||||
COPY docker/root /
|
||||
COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
|
||||
COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
|
||||
RUN ln -s /app/gitea/gitea /usr/local/bin/gitea
|
||||
RUN chmod 755 /usr/bin/entrypoint /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini
|
||||
RUN chmod 755 /etc/s6/gitea/* /etc/s6/openssh/* /etc/s6/.s6-svscan/*
|
||||
|
@@ -1,7 +1,5 @@
|
||||
|
||||
###################################
|
||||
#Build stage
|
||||
FROM golang:1.16-alpine3.14 AS build-env
|
||||
FROM golang:1.18-alpine3.15 AS build-env
|
||||
|
||||
ARG GOPROXY
|
||||
ENV GOPROXY ${GOPROXY:-direct}
|
||||
@@ -9,7 +7,7 @@ ENV GOPROXY ${GOPROXY:-direct}
|
||||
ARG GITEA_VERSION
|
||||
ARG TAGS="sqlite sqlite_unlock_notify"
|
||||
ENV TAGS "bindata timetzdata $TAGS"
|
||||
ARG CGO_EXTRA_CFLAGS
|
||||
ARG CGO_EXTRA_CFLAGS
|
||||
|
||||
#Build deps
|
||||
RUN apk --no-cache add build-base git nodejs npm
|
||||
@@ -25,7 +23,7 @@ RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
|
||||
# Begin env-to-ini build
|
||||
RUN go build contrib/environment-to-ini/environment-to-ini.go
|
||||
|
||||
FROM alpine:3.14
|
||||
FROM alpine:3.13
|
||||
LABEL maintainer="maintainers@gitea.io"
|
||||
|
||||
EXPOSE 2222 3000
|
||||
@@ -34,10 +32,11 @@ RUN apk --no-cache add \
|
||||
bash \
|
||||
ca-certificates \
|
||||
gettext \
|
||||
git \
|
||||
curl \
|
||||
gnupg
|
||||
|
||||
RUN apk add git --repository=http://dl-cdn.alpinelinux.org/alpine/v3.16/main
|
||||
|
||||
RUN addgroup \
|
||||
-S -g 1000 \
|
||||
git && \
|
||||
@@ -53,8 +52,9 @@ RUN mkdir -p /var/lib/gitea /etc/gitea
|
||||
RUN chown git:git /var/lib/gitea /etc/gitea
|
||||
|
||||
COPY docker/rootless /
|
||||
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /usr/local/bin/gitea
|
||||
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea
|
||||
COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini
|
||||
RUN chmod 755 /usr/local/bin/docker-entrypoint.sh /usr/local/bin/docker-setup.sh /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini
|
||||
|
||||
#git:git
|
||||
USER 1000:1000
|
||||
|
@@ -1,5 +1,4 @@
|
||||
Alexey Makhov <amakhov@avito.ru> (@makhov)
|
||||
Andrey Nering <andrey.nering@gmail.com> (@andreynering)
|
||||
Bo-Yi Wu <appleboy.tw@gmail.com> (@appleboy)
|
||||
Ethan Koenig <ethantkoenig@gmail.com> (@ethantkoenig)
|
||||
Kees de Vries <bouwko@gmail.com> (@Bwko)
|
||||
@@ -44,3 +43,6 @@ Patrick Schratz <patrick.schratz@gmail.com> (@pat-s)
|
||||
Janis Estelmann <admin@oldschoolhack.me> (@KN4CK3R)
|
||||
Steven Kriegler <sk.bunsenbrenner@gmail.com> (@justusbunsi)
|
||||
Jimmy Praet <jimmy.praet@telenet.be> (@jpraet)
|
||||
Leon Hofmeister <dev.lh@web.de> (@delvh)
|
||||
Gusted <williamzijl7@hotmail.com) (@Gusted)
|
||||
singuliere <singuliere@autistici.org> (@singuliere)
|
||||
|
216
Makefile
216
Makefile
@@ -24,9 +24,17 @@ SHASUM ?= shasum -a 256
|
||||
HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
|
||||
COMMA := ,
|
||||
|
||||
XGO_VERSION := go-1.16.x
|
||||
MIN_GO_VERSION := 001014000
|
||||
MIN_NODE_VERSION := 012017000
|
||||
XGO_VERSION := go-1.18.x
|
||||
|
||||
AIR_PACKAGE ?= github.com/cosmtrek/air@v1.29.0
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.4.0
|
||||
ERRCHECK_PACKAGE ?= github.com/kisielk/errcheck@v1.6.0
|
||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.3.0
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.44.2
|
||||
GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.10
|
||||
MISSPELL_PACKAGE ?= github.com/client9/misspell/cmd/misspell@v0.3.4
|
||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.29.0
|
||||
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
|
||||
|
||||
DOCKER_IMAGE ?= gitea/gitea
|
||||
DOCKER_TAG ?= latest
|
||||
@@ -57,8 +65,6 @@ else
|
||||
SED_INPLACE := sed -i ''
|
||||
endif
|
||||
|
||||
GOFMT ?= gofmt -s
|
||||
|
||||
EXTRA_GOFLAGS ?=
|
||||
|
||||
MAKE_VERSION := $(shell $(MAKE) -v | head -n 1)
|
||||
@@ -93,7 +99,7 @@ LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(G
|
||||
|
||||
LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64
|
||||
|
||||
GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/models/migrations code.gitea.io/gitea/integrations/migration-test code.gitea.io/gitea/integrations,$(shell $(GO) list -mod=vendor ./... | grep -v /vendor/))
|
||||
GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/models/migrations code.gitea.io/gitea/integrations/migration-test code.gitea.io/gitea/integrations,$(shell $(GO) list ./... | grep -v /vendor/))
|
||||
|
||||
FOMANTIC_WORK_DIR := web_src/fomantic
|
||||
|
||||
@@ -117,7 +123,7 @@ TEST_TAGS ?= sqlite sqlite_unlock_notify
|
||||
|
||||
TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMANTIC_WORK_DIR)/node_modules $(DIST) $(MAKE_EVIDENCE_DIR) $(AIR_TMP_DIR)
|
||||
|
||||
GO_DIRS := cmd integrations models modules routers build services vendor tools
|
||||
GO_DIRS := cmd integrations models modules routers build services tools
|
||||
|
||||
GO_SOURCES := $(wildcard *.go)
|
||||
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" -not -path modules/options/bindata.go -not -path modules/public/bindata.go -not -path modules/templates/bindata.go)
|
||||
@@ -126,10 +132,6 @@ ifeq ($(filter $(TAGS_SPLIT),bindata),bindata)
|
||||
GO_SOURCES += $(BINDATA_DEST)
|
||||
endif
|
||||
|
||||
GO_SOURCES_OWN := $(filter-out vendor/% %/bindata.go, $(GO_SOURCES))
|
||||
|
||||
#To update swagger use: GO111MODULE=on go get -u github.com/go-swagger/go-swagger/cmd/swagger
|
||||
SWAGGER := $(GO) run -mod=vendor github.com/go-swagger/go-swagger/cmd/swagger
|
||||
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
|
||||
SWAGGER_SPEC_S_TMPL := s|"basePath": *"/api/v1"|"basePath": "{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|g
|
||||
SWAGGER_SPEC_S_JSON := s|"basePath": *"{{AppSubUrl \| JSEscape \| Safe}}/api/v1"|"basePath": "/api/v1"|g
|
||||
@@ -169,6 +171,9 @@ help:
|
||||
@echo " - watch-backend watch backend files and continuously rebuild"
|
||||
@echo " - clean delete backend and integration files"
|
||||
@echo " - clean-all delete backend, frontend and integration files"
|
||||
@echo " - deps install dependencies"
|
||||
@echo " - deps-frontend install frontend dependencies"
|
||||
@echo " - deps-backend install backend dependencies"
|
||||
@echo " - lint lint everything"
|
||||
@echo " - lint-frontend lint frontend files"
|
||||
@echo " - lint-backend lint backend files"
|
||||
@@ -189,8 +194,6 @@ help:
|
||||
@echo " - generate-swagger generate the swagger spec from code comments"
|
||||
@echo " - swagger-validate check if the swagger spec is valid"
|
||||
@echo " - golangci-lint run golangci-lint linter"
|
||||
@echo " - revive run revive linter"
|
||||
@echo " - misspell check for misspellings"
|
||||
@echo " - vet examines Go source code and reports suspicious constructs"
|
||||
@echo " - test[\#TestSpecificName] run unit test"
|
||||
@echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite"
|
||||
@@ -198,10 +201,15 @@ help:
|
||||
|
||||
.PHONY: go-check
|
||||
go-check:
|
||||
$(eval GO_VERSION := $(shell printf "%03d%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9.]+' | tr '.' ' ');))
|
||||
$(eval MIN_GO_VERSION_STR := $(shell grep -Eo '^go\s+[0-9]+\.[0-9.]+' go.mod | cut -d' ' -f2))
|
||||
$(eval MIN_GO_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(MIN_GO_VERSION_STR)' | tr '.' ' ')))
|
||||
$(eval GO_VERSION_STR := $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9.]+'))
|
||||
$(eval GO_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(GO_VERSION_STR)' | tr '.' ' ')))
|
||||
@if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \
|
||||
echo "Gitea requires Go 1.14 or greater to build. You can get it at https://golang.org/dl/"; \
|
||||
echo "Gitea requires Go $(MIN_GO_VERSION_STR) or greater to build, but $(GO_VERSION) was found. You can get an updated version at https://go.dev/dl/"; \
|
||||
exit 1; \
|
||||
else \
|
||||
echo "WARNING: Please ensure Go $(GO_VERSION_STR) is still maintained to avoid possible security problems. You can check it at https://go.dev/dl/"; \
|
||||
fi
|
||||
|
||||
.PHONY: git-check
|
||||
@@ -213,11 +221,12 @@ git-check:
|
||||
|
||||
.PHONY: node-check
|
||||
node-check:
|
||||
$(eval MIN_NODE_VERSION_STR := $(shell grep -Eo '"node":.*[0-9.]+"' package.json | sed -n 's/.*[^0-9.]\([0-9.]*\)"/\1/p'))
|
||||
$(eval MIN_NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell echo '$(MIN_NODE_VERSION_STR)' | tr '.' ' ')))
|
||||
$(eval NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v | cut -c2- | tr '.' ' ');))
|
||||
$(eval MIN_NODE_VER_FMT := $(shell printf "%g.%g.%g" $(shell echo $(MIN_NODE_VERSION) | grep -o ...)))
|
||||
$(eval NPM_MISSING := $(shell hash npm > /dev/null 2>&1 || echo 1))
|
||||
@if [ "$(NODE_VERSION)" -lt "$(MIN_NODE_VERSION)" -o "$(NPM_MISSING)" = "1" ]; then \
|
||||
echo "Gitea requires Node.js $(MIN_NODE_VER_FMT) or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \
|
||||
echo "Gitea requires Node.js $(MIN_NODE_VERSION_STR) or greater and npm to build. You can get it at https://nodejs.org/en/download/"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
@@ -236,14 +245,13 @@ clean:
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
@echo "Running go fmt..."
|
||||
@$(GOFMT) -w $(GO_SOURCES_OWN)
|
||||
@echo "Running gitea-fmt (with gofumpt)..."
|
||||
@MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
|
||||
|
||||
.PHONY: vet
|
||||
vet:
|
||||
@echo "Running go vet..."
|
||||
@$(GO) vet $(GO_PACKAGES)
|
||||
@GOOS= GOARCH= $(GO) build -mod=vendor code.gitea.io/gitea-vet
|
||||
@GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet
|
||||
@$(GO) vet -vettool=gitea-vet $(GO_PACKAGES)
|
||||
|
||||
.PHONY: $(TAGS_EVIDENCE)
|
||||
@@ -257,7 +265,7 @@ endif
|
||||
|
||||
.PHONY: generate-swagger
|
||||
generate-swagger:
|
||||
$(SWAGGER) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)'
|
||||
$(GO) run $(SWAGGER_PACKAGE) generate spec -x "$(SWAGGER_EXCLUDE)" -o './$(SWAGGER_SPEC)'
|
||||
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
|
||||
$(SED_INPLACE) $(SWAGGER_NEWLINE_COMMAND) './$(SWAGGER_SPEC)'
|
||||
|
||||
@@ -273,44 +281,18 @@ swagger-check: generate-swagger
|
||||
.PHONY: swagger-validate
|
||||
swagger-validate:
|
||||
$(SED_INPLACE) '$(SWAGGER_SPEC_S_JSON)' './$(SWAGGER_SPEC)'
|
||||
$(SWAGGER) validate './$(SWAGGER_SPEC)'
|
||||
$(GO) run $(SWAGGER_PACKAGE) validate './$(SWAGGER_SPEC)'
|
||||
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
|
||||
|
||||
.PHONY: errcheck
|
||||
errcheck:
|
||||
@hash errcheck > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
GO111MODULE=off $(GO) get -u github.com/kisielk/errcheck; \
|
||||
fi
|
||||
@echo "Running errcheck..."
|
||||
@errcheck $(GO_PACKAGES)
|
||||
|
||||
.PHONY: revive
|
||||
revive:
|
||||
@hash revive > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
GO111MODULE=off $(GO) get -u github.com/mgechev/revive; \
|
||||
fi
|
||||
@revive -config .revive.toml -exclude=./vendor/... ./...
|
||||
|
||||
.PHONY: misspell-check
|
||||
misspell-check:
|
||||
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
GO111MODULE=off $(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
||||
fi
|
||||
@echo "Running misspell-check..."
|
||||
@misspell -error -i unknwon $(GO_SOURCES_OWN)
|
||||
|
||||
.PHONY: misspell
|
||||
misspell:
|
||||
@hash misspell > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
GO111MODULE=off $(GO) get -u github.com/client9/misspell/cmd/misspell; \
|
||||
fi
|
||||
@echo "Running go misspell..."
|
||||
@misspell -w -i unknwon $(GO_SOURCES_OWN)
|
||||
$(GO) run $(ERRCHECK_PACKAGE) $(GO_PACKAGES)
|
||||
|
||||
.PHONY: fmt-check
|
||||
fmt-check:
|
||||
# get all go files and run go fmt on them
|
||||
@diff=$$($(GOFMT) -d $(GO_SOURCES_OWN)); \
|
||||
# get all go files and run gitea-fmt (with gofmt) on them
|
||||
@diff=$$(MISSPELL_PACKAGE=$(MISSPELL_PACKAGE) GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -l '{file-list}'); \
|
||||
if [ -n "$$diff" ]; then \
|
||||
echo "Please run 'make fmt' and commit the result:"; \
|
||||
echo "$${diff}"; \
|
||||
@@ -321,22 +303,22 @@ fmt-check:
|
||||
checks: checks-frontend checks-backend
|
||||
|
||||
.PHONY: checks-frontend
|
||||
checks-frontend: svg-check
|
||||
checks-frontend: lockfile-check svg-check
|
||||
|
||||
.PHONY: checks-backend
|
||||
checks-backend: misspell-check test-vendor swagger-check swagger-validate
|
||||
checks-backend: gomod-check swagger-check swagger-validate
|
||||
|
||||
.PHONY: lint
|
||||
lint: lint-frontend lint-backend
|
||||
|
||||
.PHONY: lint-frontend
|
||||
lint-frontend: node_modules
|
||||
npx eslint --color --max-warnings=0 web_src/js build templates *.config.js
|
||||
npx eslint --color --max-warnings=0 web_src/js build templates *.config.js docs/assets/js
|
||||
npx stylelint --color --max-warnings=0 web_src/less
|
||||
npx editorconfig-checker templates
|
||||
|
||||
.PHONY: lint-backend
|
||||
lint-backend: golangci-lint revive vet
|
||||
lint-backend: golangci-lint vet
|
||||
|
||||
.PHONY: watch
|
||||
watch:
|
||||
@@ -349,18 +331,15 @@ watch-frontend: node-check node_modules
|
||||
|
||||
.PHONY: watch-backend
|
||||
watch-backend: go-check
|
||||
@hash air > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
GO111MODULE=off $(GO) get -u github.com/cosmtrek/air; \
|
||||
fi
|
||||
air -c .air.conf
|
||||
$(GO) run $(AIR_PACKAGE) -c .air.toml
|
||||
|
||||
.PHONY: test
|
||||
test: test-frontend test-backend
|
||||
|
||||
.PHONY: test-backend
|
||||
test-backend:
|
||||
@echo "Running go test with -tags '$(TEST_TAGS)'..."
|
||||
@$(GO) test $(GOTESTFLAGS) -mod=vendor -tags='$(TEST_TAGS)' $(GO_PACKAGES)
|
||||
@echo "Running go test with $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..."
|
||||
@$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' $(GO_PACKAGES)
|
||||
|
||||
.PHONY: test-frontend
|
||||
test-frontend: node_modules
|
||||
@@ -381,26 +360,29 @@ test-check:
|
||||
.PHONY: test\#%
|
||||
test\#%:
|
||||
@echo "Running go test with -tags '$(TEST_TAGS)'..."
|
||||
@$(GO) test -mod=vendor $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_PACKAGES)
|
||||
@$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_PACKAGES)
|
||||
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
GO111MODULE=on $(GO) run -mod=vendor build/gocovmerge.go integration.coverage.out $(shell find . -type f -name "coverage.out") > coverage.all
|
||||
grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' coverage.out > coverage-bodged.out
|
||||
grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' integration.coverage.out > integration.coverage-bodged.out
|
||||
GO111MODULE=on $(GO) run build/gocovmerge.go integration.coverage-bodged.out coverage-bodged.out > coverage.all || (echo "gocovmerge failed"; echo "integration.coverage.out"; cat integration.coverage.out; echo "coverage.out"; cat coverage.out; exit 1)
|
||||
|
||||
.PHONY: unit-test-coverage
|
||||
unit-test-coverage:
|
||||
@echo "Running unit-test-coverage -tags '$(TEST_TAGS)'..."
|
||||
@$(GO) test $(GOTESTFLAGS) -mod=vendor -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1
|
||||
@echo "Running unit-test-coverage $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..."
|
||||
@$(GO) test $(GOTESTFLAGS) -timeout=20m -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1
|
||||
|
||||
.PHONY: vendor
|
||||
vendor:
|
||||
$(GO) mod tidy && $(GO) mod vendor
|
||||
|
||||
.PHONY: test-vendor
|
||||
test-vendor: vendor
|
||||
@diff=$$(git diff vendor/); \
|
||||
.PHONY: gomod-check
|
||||
gomod-check:
|
||||
@$(GO) mod tidy
|
||||
@diff=$$(git diff go.sum); \
|
||||
if [ -n "$$diff" ]; then \
|
||||
echo "Please run 'make vendor' and commit the result:"; \
|
||||
echo "Please run '$(GO) mod tidy' and commit the result:"; \
|
||||
echo "$${diff}"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@@ -422,6 +404,11 @@ test-sqlite-migration: migrations.sqlite.test migrations.individual.sqlite.test
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.sqlite.test
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.individual.sqlite.test
|
||||
|
||||
.PHONY: test-sqlite-migration\#%
|
||||
test-sqlite-migration\#%: migrations.sqlite.test migrations.individual.sqlite.test generate-ini-sqlite
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/sqlite.ini ./migrations.individual.sqlite.test -test.run $(subst .,/,$*)
|
||||
|
||||
|
||||
generate-ini-mysql:
|
||||
sed -e 's|{{TEST_MYSQL_HOST}}|${TEST_MYSQL_HOST}|g' \
|
||||
-e 's|{{TEST_MYSQL_DBNAME}}|${TEST_MYSQL_DBNAME}|g' \
|
||||
@@ -528,22 +515,22 @@ integration-test-coverage: integrations.cover.test generate-ini-mysql
|
||||
GITEA_ROOT="$(CURDIR)" GITEA_CONF=integrations/mysql.ini ./integrations.cover.test -test.coverprofile=integration.coverage.out
|
||||
|
||||
integrations.mysql.test: git-check $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.mysql.test
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.mysql.test
|
||||
|
||||
integrations.mysql8.test: git-check $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.mysql8.test
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.mysql8.test
|
||||
|
||||
integrations.pgsql.test: git-check $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.pgsql.test
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.pgsql.test
|
||||
|
||||
integrations.mssql.test: git-check $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.mssql.test
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.mssql.test
|
||||
|
||||
integrations.sqlite.test: git-check $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -o integrations.sqlite.test -tags '$(TEST_TAGS)'
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -o integrations.sqlite.test -tags '$(TEST_TAGS)'
|
||||
|
||||
integrations.cover.test: git-check $(GO_SOURCES)
|
||||
$(GO) test $(GOTESTFLAGS) -mod=vendor -c code.gitea.io/gitea/integrations -coverpkg $(shell echo $(GO_PACKAGES) | tr ' ' ',') -o integrations.cover.test
|
||||
$(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/integrations -coverpkg $(shell echo $(GO_PACKAGES) | tr ' ' ',') -o integrations.cover.test
|
||||
|
||||
.PHONY: migrations.mysql.test
|
||||
migrations.mysql.test: $(GO_SOURCES)
|
||||
@@ -604,25 +591,22 @@ backend: go-check generate $(EXECUTABLE)
|
||||
.PHONY: generate
|
||||
generate: $(TAGS_PREREQ)
|
||||
@echo "Running go generate..."
|
||||
@CC= GOOS= GOARCH= $(GO) generate -mod=vendor -tags '$(TAGS)' $(GO_PACKAGES)
|
||||
@CC= GOOS= GOARCH= $(GO) generate -tags '$(TAGS)' $(GO_PACKAGES)
|
||||
|
||||
$(EXECUTABLE): $(GO_SOURCES) $(TAGS_PREREQ)
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build -mod=vendor $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(LDFLAGS)' -o $@
|
||||
|
||||
.PHONY: release
|
||||
release: frontend generate release-windows release-linux release-darwin release-copy release-compress release-sources release-docs release-check
|
||||
release: frontend generate release-windows release-linux release-darwin release-copy release-compress vendor release-sources release-docs release-check
|
||||
|
||||
$(DIST_DIRS):
|
||||
mkdir -p $(DIST_DIRS)
|
||||
|
||||
.PHONY: release-windows
|
||||
release-windows: | $(DIST_DIRS)
|
||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
$(GO) install src.techknowlogick.com/xgo@latest; \
|
||||
fi
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
|
||||
ifeq (,$(findstring gogit,$(TAGS)))
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo gogit $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo gogit $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit .
|
||||
endif
|
||||
ifeq ($(CI),drone)
|
||||
cp /build/* $(DIST)/binaries
|
||||
@@ -630,20 +614,14 @@ endif
|
||||
|
||||
.PHONY: release-linux
|
||||
release-linux: | $(DIST_DIRS)
|
||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
$(GO) install src.techknowlogick.com/xgo@latest; \
|
||||
fi
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out gitea-$(VERSION) .
|
||||
ifeq ($(CI),drone)
|
||||
cp /build/* $(DIST)/binaries
|
||||
endif
|
||||
|
||||
.PHONY: release-darwin
|
||||
release-darwin: | $(DIST_DIRS)
|
||||
@hash xgo > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
$(GO) install src.techknowlogick.com/xgo@latest; \
|
||||
fi
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" xgo -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
|
||||
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) .
|
||||
ifeq ($(CI),drone)
|
||||
cp /build/* $(DIST)/binaries
|
||||
endif
|
||||
@@ -658,10 +636,7 @@ release-check: | $(DIST_DIRS)
|
||||
|
||||
.PHONY: release-compress
|
||||
release-compress: | $(DIST_DIRS)
|
||||
@hash gxz > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
GO111MODULE=off $(GO) get -u github.com/ulikunitz/xz/cmd/gxz; \
|
||||
fi
|
||||
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && gxz -k -9 $${file}; done;
|
||||
cd $(DIST)/release/; for file in `find . -type f -name "*"`; do echo "compressing $${file}" && $(GO) run $(GXZ_PAGAGE) -k -9 $${file}; done;
|
||||
|
||||
.PHONY: release-sources
|
||||
release-sources: | $(DIST_DIRS)
|
||||
@@ -682,6 +657,25 @@ docs:
|
||||
fi
|
||||
cd docs; make trans-copy clean build-offline;
|
||||
|
||||
.PHONY: deps
|
||||
deps: deps-frontend deps-backend
|
||||
|
||||
.PHONY: deps-frontend
|
||||
deps-frontend: node_modules
|
||||
|
||||
.PHONY: deps-backend
|
||||
deps-backend:
|
||||
$(GO) mod download
|
||||
$(GO) install $(AIR_PACKAGE)
|
||||
$(GO) install $(EDITORCONFIG_CHECKER_PACKAGE)
|
||||
$(GO) install $(ERRCHECK_PACKAGE)
|
||||
$(GO) install $(GOFUMPT_PACKAGE)
|
||||
$(GO) install $(GOLANGCI_LINT_PACKAGE)
|
||||
$(GO) install $(GXZ_PAGAGE)
|
||||
$(GO) install $(MISSPELL_PACKAGE)
|
||||
$(GO) install $(SWAGGER_PACKAGE)
|
||||
$(GO) install $(XGO_PACKAGE)
|
||||
|
||||
node_modules: package-lock.json
|
||||
npm install --no-save
|
||||
@touch node_modules
|
||||
@@ -699,7 +693,9 @@ fomantic:
|
||||
cd $(FOMANTIC_WORK_DIR) && npm install --no-save
|
||||
cp -f $(FOMANTIC_WORK_DIR)/theme.config.less $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/theme.config
|
||||
cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/
|
||||
cp -f web_src/js/vendor/dropdown.js $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/definitions/modules
|
||||
cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build
|
||||
rm -f $(FOMANTIC_WORK_DIR)/build/*.min.*
|
||||
|
||||
.PHONY: webpack
|
||||
webpack: $(WEBPACK_DEST)
|
||||
@@ -725,6 +721,17 @@ svg-check: svg
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: lockfile-check
|
||||
lockfile-check:
|
||||
npm install --package-lock-only
|
||||
@diff=$$(git diff package-lock.json); \
|
||||
if [ -n "$$diff" ]; then \
|
||||
echo "package-lock.json is inconsistent with package.json"; \
|
||||
echo "Please run 'npm install --package-lock-only' and commit the result:"; \
|
||||
echo "$${diff}"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
.PHONY: update-translations
|
||||
update-translations:
|
||||
mkdir -p ./translations
|
||||
@@ -762,11 +769,18 @@ pr\#%: clean-all
|
||||
|
||||
.PHONY: golangci-lint
|
||||
golangci-lint:
|
||||
@hash golangci-lint > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
|
||||
export BINARY="golangci-lint"; \
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.37.0; \
|
||||
fi
|
||||
golangci-lint run --timeout 10m
|
||||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run
|
||||
|
||||
# workaround step for the lint-backend-windows CI task because 'go run' can not
|
||||
# have distinct GOOS/GOARCH for its build and run steps
|
||||
.PHONY: golangci-lint-windows
|
||||
golangci-lint-windows:
|
||||
@GOOS= GOARCH= $(GO) install $(GOLANGCI_LINT_PACKAGE)
|
||||
golangci-lint run
|
||||
|
||||
.PHONY: editorconfig-checker
|
||||
editorconfig-checker:
|
||||
$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates
|
||||
|
||||
.PHONY: docker
|
||||
docker:
|
||||
|
15
README.md
15
README.md
@@ -12,13 +12,10 @@
|
||||
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
|
||||
<img src="https://img.shields.io/discord/322538954119184384.svg">
|
||||
</a>
|
||||
<a href="https://microbadger.com/images/gitea/gitea" title="Get your own image badge on microbadger.com">
|
||||
<img src="https://images.microbadger.com/badges/image/gitea/gitea.svg">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/go-gitea/gitea" title="Codecov">
|
||||
<img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg">
|
||||
</a>
|
||||
<a href="https://godoc.org/code.gitea.io/gitea" title="Go Report Card">
|
||||
<a href="https://goreportcard.com/report/code.gitea.io/gitea" title="Go Report Card">
|
||||
<img src="https://goreportcard.com/badge/code.gitea.io/gitea">
|
||||
</a>
|
||||
<a href="https://godoc.org/code.gitea.io/gitea" title="GoDoc">
|
||||
@@ -39,8 +36,8 @@
|
||||
<a href="https://crowdin.com/project/gitea" title="Crowdin">
|
||||
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
||||
</a>
|
||||
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea" title="TODOs">
|
||||
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea">
|
||||
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea&branch=main" title="TODOs">
|
||||
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea/main">
|
||||
</a>
|
||||
<a href="https://www.bountysource.com/teams/gitea" title="Bountysource">
|
||||
<img src="https://img.shields.io/bountysource/team/gitea/activity">
|
||||
@@ -70,14 +67,14 @@ From the root of the source tree, run:
|
||||
|
||||
TAGS="bindata" make build
|
||||
|
||||
or if sqlite support is required:
|
||||
or if SQLite support is required:
|
||||
|
||||
TAGS="bindata sqlite sqlite_unlock_notify" make build
|
||||
|
||||
The `build` target is split into two sub-targets:
|
||||
|
||||
- `make backend` which requires [Go 1.13](https://golang.org/dl/) or greater.
|
||||
- `make frontend` which requires [Node.js 12.17](https://nodejs.org/en/download/) or greater and Internet connectivity to download npm dependencies.
|
||||
- `make backend` which requires [Go 1.17](https://go.dev/dl/) or greater.
|
||||
- `make frontend` which requires [Node.js LTS](https://nodejs.org/en/download/) or greater and Internet connectivity to download npm dependencies.
|
||||
|
||||
When building from the official source tarballs which include pre-built frontend files, the `frontend` target will not be triggered, making it possible to build without Node.js and Internet connectivity.
|
||||
|
||||
|
@@ -12,13 +12,10 @@
|
||||
<a href="https://discord.gg/Gitea" title="Join the Discord chat at https://discord.gg/Gitea">
|
||||
<img src="https://img.shields.io/discord/322538954119184384.svg">
|
||||
</a>
|
||||
<a href="https://microbadger.com/images/gitea/gitea" title="Get your own image badge on microbadger.com">
|
||||
<img src="https://images.microbadger.com/badges/image/gitea/gitea.svg">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/go-gitea/gitea" title="Codecov">
|
||||
<img src="https://codecov.io/gh/go-gitea/gitea/branch/main/graph/badge.svg">
|
||||
</a>
|
||||
<a href="https://godoc.org/code.gitea.io/gitea" title="Go Report Card">
|
||||
<a href="https://goreportcard.com/report/code.gitea.io/gitea" title="Go Report Card">
|
||||
<img src="https://goreportcard.com/badge/code.gitea.io/gitea">
|
||||
</a>
|
||||
<a href="https://godoc.org/code.gitea.io/gitea" title="GoDoc">
|
||||
@@ -39,8 +36,8 @@
|
||||
<a href="https://crowdin.com/project/gitea" title="Crowdin">
|
||||
<img src="https://badges.crowdin.net/gitea/localized.svg">
|
||||
</a>
|
||||
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea" title="TODOs">
|
||||
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea">
|
||||
<a href="https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea&branch=main" title="TODOs">
|
||||
<img src="https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea/main">
|
||||
</a>
|
||||
<a href="https://img.shields.io/bountysource/team/gitea" title="Bountysource">
|
||||
<img src="https://img.shields.io/bountysource/team/gitea/activity">
|
||||
|
3
build.go
3
build.go
@@ -2,7 +2,8 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build vendor
|
||||
//go:build vendor
|
||||
// +build vendor
|
||||
|
||||
package main
|
||||
|
||||
|
285
build/code-batch-process.go
Normal file
285
build/code-batch-process.go
Normal file
@@ -0,0 +1,285 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/build/codeformat"
|
||||
)
|
||||
|
||||
// Windows has a limitation for command line arguments, the size can not exceed 32KB.
|
||||
// So we have to feed the files to some tools (like gofmt/misspell) batch by batch
|
||||
|
||||
// We also introduce a `gitea-fmt` command, it does better import formatting than gofmt/goimports. `gitea-fmt` calls `gofmt` internally.
|
||||
|
||||
var optionLogVerbose bool
|
||||
|
||||
func logVerbose(msg string, args ...interface{}) {
|
||||
if optionLogVerbose {
|
||||
log.Printf(msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func passThroughCmd(cmd string, args []string) error {
|
||||
foundCmd, err := exec.LookPath(cmd)
|
||||
if err != nil {
|
||||
log.Fatalf("can not find cmd: %s", cmd)
|
||||
}
|
||||
c := exec.Cmd{
|
||||
Path: foundCmd,
|
||||
Args: append([]string{cmd}, args...),
|
||||
Stdin: os.Stdin,
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
}
|
||||
return c.Run()
|
||||
}
|
||||
|
||||
type fileCollector struct {
|
||||
dirs []string
|
||||
includePatterns []*regexp.Regexp
|
||||
excludePatterns []*regexp.Regexp
|
||||
batchSize int
|
||||
}
|
||||
|
||||
func newFileCollector(fileFilter string, batchSize int) (*fileCollector, error) {
|
||||
co := &fileCollector{batchSize: batchSize}
|
||||
if fileFilter == "go-own" {
|
||||
co.dirs = []string{
|
||||
"build",
|
||||
"cmd",
|
||||
"contrib",
|
||||
"integrations",
|
||||
"models",
|
||||
"modules",
|
||||
"routers",
|
||||
"services",
|
||||
"tools",
|
||||
}
|
||||
co.includePatterns = append(co.includePatterns, regexp.MustCompile(`.*\.go$`))
|
||||
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`.*\bbindata\.go$`))
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`integrations/gitea-repositories-meta`))
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`integrations/migration-test`))
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`modules/git/tests`))
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`models/fixtures`))
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`models/migrations/fixtures`))
|
||||
co.excludePatterns = append(co.excludePatterns, regexp.MustCompile(`services/gitdiff/testdata`))
|
||||
}
|
||||
|
||||
if co.dirs == nil {
|
||||
return nil, fmt.Errorf("unknown file-filter: %s", fileFilter)
|
||||
}
|
||||
return co, nil
|
||||
}
|
||||
|
||||
func (fc *fileCollector) matchPatterns(path string, regexps []*regexp.Regexp) bool {
|
||||
path = strings.ReplaceAll(path, "\\", "/")
|
||||
for _, re := range regexps {
|
||||
if re.MatchString(path) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (fc *fileCollector) collectFiles() (res [][]string, err error) {
|
||||
var batch []string
|
||||
for _, dir := range fc.dirs {
|
||||
err = filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error {
|
||||
include := len(fc.includePatterns) == 0 || fc.matchPatterns(path, fc.includePatterns)
|
||||
exclude := fc.matchPatterns(path, fc.excludePatterns)
|
||||
process := include && !exclude
|
||||
if !process {
|
||||
if d.IsDir() {
|
||||
if exclude {
|
||||
logVerbose("exclude dir %s", path)
|
||||
return filepath.SkipDir
|
||||
}
|
||||
// for a directory, if it is not excluded explicitly, we should walk into
|
||||
return nil
|
||||
}
|
||||
// for a file, we skip it if it shouldn't be processed
|
||||
logVerbose("skip process %s", path)
|
||||
return nil
|
||||
}
|
||||
if d.IsDir() {
|
||||
// skip dir, we don't add dirs to the file list now
|
||||
return nil
|
||||
}
|
||||
if len(batch) >= fc.batchSize {
|
||||
res = append(res, batch)
|
||||
batch = nil
|
||||
}
|
||||
batch = append(batch, path)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
res = append(res, batch)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// substArgFiles expands the {file-list} to a real file list for commands
|
||||
func substArgFiles(args []string, files []string) []string {
|
||||
for i, s := range args {
|
||||
if s == "{file-list}" {
|
||||
newArgs := append(args[:i], files...)
|
||||
newArgs = append(newArgs, args[i+1:]...)
|
||||
return newArgs
|
||||
}
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
func exitWithCmdErrors(subCmd string, subArgs []string, cmdErrors []error) {
|
||||
for _, err := range cmdErrors {
|
||||
if err != nil {
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
exitCode := exitError.ExitCode()
|
||||
log.Printf("run command failed (code=%d): %s %v", exitCode, subCmd, subArgs)
|
||||
os.Exit(exitCode)
|
||||
} else {
|
||||
log.Fatalf("run command failed (err=%s) %s %v", err, subCmd, subArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func parseArgs() (mainOptions map[string]string, subCmd string, subArgs []string) {
|
||||
mainOptions = map[string]string{}
|
||||
for i := 1; i < len(os.Args); i++ {
|
||||
arg := os.Args[i]
|
||||
if arg == "" {
|
||||
break
|
||||
}
|
||||
if arg[0] == '-' {
|
||||
arg = strings.TrimPrefix(arg, "-")
|
||||
arg = strings.TrimPrefix(arg, "-")
|
||||
fields := strings.SplitN(arg, "=", 2)
|
||||
if len(fields) == 1 {
|
||||
mainOptions[fields[0]] = "1"
|
||||
} else {
|
||||
mainOptions[fields[0]] = fields[1]
|
||||
}
|
||||
} else {
|
||||
subCmd = arg
|
||||
subArgs = os.Args[i+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func showUsage() {
|
||||
fmt.Printf(`Usage: %[1]s [options] {command} [arguments]
|
||||
|
||||
Options:
|
||||
--verbose
|
||||
--file-filter=go-own
|
||||
--batch-size=100
|
||||
|
||||
Commands:
|
||||
%[1]s gofmt ...
|
||||
%[1]s misspell ...
|
||||
|
||||
Arguments:
|
||||
{file-list} the file list
|
||||
|
||||
Example:
|
||||
%[1]s gofmt -s -d {file-list}
|
||||
|
||||
`, "file-batch-exec")
|
||||
}
|
||||
|
||||
func newFileCollectorFromMainOptions(mainOptions map[string]string) (fc *fileCollector, err error) {
|
||||
fileFilter := mainOptions["file-filter"]
|
||||
if fileFilter == "" {
|
||||
fileFilter = "go-own"
|
||||
}
|
||||
batchSize, _ := strconv.Atoi(mainOptions["batch-size"])
|
||||
if batchSize == 0 {
|
||||
batchSize = 100
|
||||
}
|
||||
|
||||
return newFileCollector(fileFilter, batchSize)
|
||||
}
|
||||
|
||||
func containsString(a []string, s string) bool {
|
||||
for _, v := range a {
|
||||
if v == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func giteaFormatGoImports(files []string) error {
|
||||
for _, file := range files {
|
||||
if err := codeformat.FormatGoImports(file); err != nil {
|
||||
log.Printf("failed to format go imports: %s, err=%v", file, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
mainOptions, subCmd, subArgs := parseArgs()
|
||||
if subCmd == "" {
|
||||
showUsage()
|
||||
os.Exit(1)
|
||||
}
|
||||
optionLogVerbose = mainOptions["verbose"] != ""
|
||||
|
||||
fc, err := newFileCollectorFromMainOptions(mainOptions)
|
||||
if err != nil {
|
||||
log.Fatalf("can not create file collector: %s", err.Error())
|
||||
}
|
||||
|
||||
fileBatches, err := fc.collectFiles()
|
||||
if err != nil {
|
||||
log.Fatalf("can not collect files: %s", err.Error())
|
||||
}
|
||||
|
||||
processed := 0
|
||||
var cmdErrors []error
|
||||
for _, files := range fileBatches {
|
||||
if len(files) == 0 {
|
||||
break
|
||||
}
|
||||
substArgs := substArgFiles(subArgs, files)
|
||||
logVerbose("batch cmd: %s %v", subCmd, substArgs)
|
||||
switch subCmd {
|
||||
case "gitea-fmt":
|
||||
if containsString(subArgs, "-w") {
|
||||
cmdErrors = append(cmdErrors, giteaFormatGoImports(files))
|
||||
}
|
||||
cmdErrors = append(cmdErrors, giteaFormatGoImports(files, containsString(subArgs, "-l"), containsString(subArgs, "-w")))
|
||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("GOFUMPT_PACKAGE"), "-extra", "-lang", "1.17"}, substArgs...)))
|
||||
case "misspell":
|
||||
cmdErrors = append(cmdErrors, passThroughCmd("go", append([]string{"run", os.Getenv("MISSPELL_PACKAGE")}, substArgs...)))
|
||||
default:
|
||||
log.Fatalf("unknown cmd: %s %v", subCmd, subArgs)
|
||||
}
|
||||
processed += len(files)
|
||||
}
|
||||
|
||||
logVerbose("processed %d files", processed)
|
||||
exitWithCmdErrors(subCmd, subArgs, cmdErrors)
|
||||
}
|
187
build/codeformat/formatimports.go
Normal file
187
build/codeformat/formatimports.go
Normal file
@@ -0,0 +1,187 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package codeformat
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var importPackageGroupOrders = map[string]int{
|
||||
"": 1, // internal
|
||||
"code.gitea.io/gitea/": 2,
|
||||
}
|
||||
|
||||
var errInvalidCommentBetweenImports = errors.New("comments between imported packages are invalid, please move comments to the end of the package line")
|
||||
|
||||
var importBlockBegin = []byte("\nimport (\n")
|
||||
var importBlockEnd = []byte("\n)")
|
||||
|
||||
type importLineParsed struct {
|
||||
group string
|
||||
pkg string
|
||||
content string
|
||||
}
|
||||
|
||||
func parseImportLine(line string) (*importLineParsed, error) {
|
||||
il := &importLineParsed{content: line}
|
||||
p1 := strings.IndexRune(line, '"')
|
||||
if p1 == -1 {
|
||||
return nil, errors.New("invalid import line: " + line)
|
||||
}
|
||||
p1++
|
||||
p := strings.IndexRune(line[p1:], '"')
|
||||
if p == -1 {
|
||||
return nil, errors.New("invalid import line: " + line)
|
||||
}
|
||||
p2 := p1 + p
|
||||
il.pkg = line[p1:p2]
|
||||
|
||||
pDot := strings.IndexRune(il.pkg, '.')
|
||||
pSlash := strings.IndexRune(il.pkg, '/')
|
||||
if pDot != -1 && pDot < pSlash {
|
||||
il.group = "domain-package"
|
||||
}
|
||||
for groupName := range importPackageGroupOrders {
|
||||
if groupName == "" {
|
||||
continue // skip internal
|
||||
}
|
||||
if strings.HasPrefix(il.pkg, groupName) {
|
||||
il.group = groupName
|
||||
}
|
||||
}
|
||||
return il, nil
|
||||
}
|
||||
|
||||
type importLineGroup []*importLineParsed
|
||||
type importLineGroupMap map[string]importLineGroup
|
||||
|
||||
func formatGoImports(contentBytes []byte) ([]byte, error) {
|
||||
p1 := bytes.Index(contentBytes, importBlockBegin)
|
||||
if p1 == -1 {
|
||||
return nil, nil
|
||||
}
|
||||
p1 += len(importBlockBegin)
|
||||
p := bytes.Index(contentBytes[p1:], importBlockEnd)
|
||||
if p == -1 {
|
||||
return nil, nil
|
||||
}
|
||||
p2 := p1 + p
|
||||
|
||||
importGroups := importLineGroupMap{}
|
||||
r := bytes.NewBuffer(contentBytes[p1:p2])
|
||||
eof := false
|
||||
for !eof {
|
||||
line, err := r.ReadString('\n')
|
||||
eof = err == io.EOF
|
||||
if err != nil && !eof {
|
||||
return nil, err
|
||||
}
|
||||
line = strings.TrimSpace(line)
|
||||
if line != "" {
|
||||
if strings.HasPrefix(line, "//") || strings.HasPrefix(line, "/*") {
|
||||
return nil, errInvalidCommentBetweenImports
|
||||
}
|
||||
importLine, err := parseImportLine(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
importGroups[importLine.group] = append(importGroups[importLine.group], importLine)
|
||||
}
|
||||
}
|
||||
|
||||
var groupNames []string
|
||||
for groupName, importLines := range importGroups {
|
||||
groupNames = append(groupNames, groupName)
|
||||
sort.Slice(importLines, func(i, j int) bool {
|
||||
return strings.Compare(importLines[i].pkg, importLines[j].pkg) < 0
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(groupNames, func(i, j int) bool {
|
||||
n1 := groupNames[i]
|
||||
n2 := groupNames[j]
|
||||
o1 := importPackageGroupOrders[n1]
|
||||
o2 := importPackageGroupOrders[n2]
|
||||
if o1 != 0 && o2 != 0 {
|
||||
return o1 < o2
|
||||
}
|
||||
if o1 == 0 && o2 == 0 {
|
||||
return strings.Compare(n1, n2) < 0
|
||||
}
|
||||
return o1 != 0
|
||||
})
|
||||
|
||||
formattedBlock := bytes.Buffer{}
|
||||
for _, groupName := range groupNames {
|
||||
hasNormalImports := false
|
||||
hasDummyImports := false
|
||||
// non-dummy import comes first
|
||||
for _, importLine := range importGroups[groupName] {
|
||||
if strings.HasPrefix(importLine.content, "_") {
|
||||
hasDummyImports = true
|
||||
} else {
|
||||
formattedBlock.WriteString("\t" + importLine.content + "\n")
|
||||
hasNormalImports = true
|
||||
}
|
||||
}
|
||||
// dummy (_ "pkg") comes later
|
||||
if hasDummyImports {
|
||||
if hasNormalImports {
|
||||
formattedBlock.WriteString("\n")
|
||||
}
|
||||
for _, importLine := range importGroups[groupName] {
|
||||
if strings.HasPrefix(importLine.content, "_") {
|
||||
formattedBlock.WriteString("\t" + importLine.content + "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
formattedBlock.WriteString("\n")
|
||||
}
|
||||
formattedBlockBytes := bytes.TrimRight(formattedBlock.Bytes(), "\n")
|
||||
|
||||
var formattedBytes []byte
|
||||
formattedBytes = append(formattedBytes, contentBytes[:p1]...)
|
||||
formattedBytes = append(formattedBytes, formattedBlockBytes...)
|
||||
formattedBytes = append(formattedBytes, contentBytes[p2:]...)
|
||||
return formattedBytes, nil
|
||||
}
|
||||
|
||||
//FormatGoImports format the imports by our rules (see unit tests)
|
||||
func FormatGoImports(file string) error {
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var contentBytes []byte
|
||||
{
|
||||
defer f.Close()
|
||||
contentBytes, err = io.ReadAll(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
formattedBytes, err := formatGoImports(contentBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if formattedBytes == nil {
|
||||
return nil
|
||||
}
|
||||
if bytes.Equal(contentBytes, formattedBytes) {
|
||||
return nil
|
||||
}
|
||||
f, err = os.OpenFile(file, os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.Write(formattedBytes)
|
||||
return err
|
||||
}
|
125
build/codeformat/formatimports_test.go
Normal file
125
build/codeformat/formatimports_test.go
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package codeformat
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFormatImportsSimple(t *testing.T) {
|
||||
formatted, err := formatGoImports([]byte(`
|
||||
package codeformat
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
`))
|
||||
|
||||
expected := `
|
||||
package codeformat
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
`
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, string(formatted))
|
||||
}
|
||||
|
||||
func TestFormatImportsGroup(t *testing.T) {
|
||||
// gofmt/goimports won't group the packages, for example, they produce such code:
|
||||
// "bytes"
|
||||
// "image"
|
||||
// (a blank line)
|
||||
// "fmt"
|
||||
// "image/color/palette"
|
||||
// our formatter does better, and these packages are grouped into one.
|
||||
|
||||
formatted, err := formatGoImports([]byte(`
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
|
||||
_ "image/gif" // for processing gif images
|
||||
_ "image/jpeg" // for processing jpeg images
|
||||
_ "image/png" // for processing png images
|
||||
|
||||
"code.gitea.io/other/package"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/the/package"
|
||||
|
||||
"github.com/issue9/identicon"
|
||||
"github.com/nfnt/resize"
|
||||
"github.com/oliamb/cutter"
|
||||
)
|
||||
`))
|
||||
|
||||
expected := `
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
|
||||
_ "image/gif" // for processing gif images
|
||||
_ "image/jpeg" // for processing jpeg images
|
||||
_ "image/png" // for processing png images
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"code.gitea.io/other/package"
|
||||
"github.com/issue9/identicon"
|
||||
"github.com/nfnt/resize"
|
||||
"github.com/oliamb/cutter"
|
||||
"xorm.io/the/package"
|
||||
)
|
||||
`
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, string(formatted))
|
||||
}
|
||||
|
||||
func TestFormatImportsInvalidComment(t *testing.T) {
|
||||
// why we shouldn't write comments between imports: it breaks the grouping of imports
|
||||
// for example:
|
||||
// "pkg1"
|
||||
// "pkg2"
|
||||
// // a comment
|
||||
// "pkgA"
|
||||
// "pkgB"
|
||||
// the comment splits the packages into two groups, pkg1/2 are sorted separately, pkgA/B are sorted separately
|
||||
// we don't want such code, so the code should be:
|
||||
// "pkg1"
|
||||
// "pkg2"
|
||||
// "pkgA" // a comment
|
||||
// "pkgB"
|
||||
|
||||
_, err := formatGoImports([]byte(`
|
||||
package test
|
||||
|
||||
import (
|
||||
"image/jpeg"
|
||||
// for processing gif images
|
||||
"image/gif"
|
||||
)
|
||||
`))
|
||||
assert.ErrorIs(t, err, errInvalidCommentBetweenImports)
|
||||
}
|
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -27,7 +27,7 @@ func needsUpdate(dir string, filename string) (bool, []byte) {
|
||||
needRegen = true
|
||||
}
|
||||
|
||||
oldHash, err := ioutil.ReadFile(filename + ".hash")
|
||||
oldHash, err := os.ReadFile(filename + ".hash")
|
||||
if err != nil {
|
||||
oldHash = []byte{}
|
||||
}
|
||||
@@ -58,11 +58,15 @@ func needsUpdate(dir string, filename string) (bool, []byte) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 4 {
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("Insufficient number of arguments. Need: directory packageName filename")
|
||||
}
|
||||
|
||||
dir, packageName, filename := os.Args[1], os.Args[2], os.Args[3]
|
||||
var useGlobalModTime bool
|
||||
if len(os.Args) == 5 {
|
||||
useGlobalModTime, _ = strconv.ParseBool(os.Args[4])
|
||||
}
|
||||
|
||||
update, newHash := needsUpdate(dir, filename)
|
||||
|
||||
@@ -74,13 +78,14 @@ func main() {
|
||||
fmt.Printf("generating bindata for %s\n", packageName)
|
||||
var fsTemplates http.FileSystem = http.Dir(dir)
|
||||
err := vfsgen.Generate(fsTemplates, vfsgen.Options{
|
||||
PackageName: packageName,
|
||||
BuildTags: "bindata",
|
||||
VariableName: "Assets",
|
||||
Filename: filename,
|
||||
PackageName: packageName,
|
||||
BuildTags: "bindata",
|
||||
VariableName: "Assets",
|
||||
Filename: filename,
|
||||
UseGlobalModTime: useGlobalModTime,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("%v\n", err)
|
||||
}
|
||||
_ = ioutil.WriteFile(filename+".hash", newHash, 0666)
|
||||
_ = os.WriteFile(filename+".hash", newHash, 0666)
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
@@ -11,16 +12,17 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -51,7 +53,6 @@ func (e Emoji) MarshalJSON() ([]byte, error) {
|
||||
x.UnicodeVersion = ""
|
||||
x.Description = ""
|
||||
x.SkinTones = false
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
return json.Marshal(x)
|
||||
}
|
||||
|
||||
@@ -67,7 +68,7 @@ func main() {
|
||||
}
|
||||
|
||||
// write
|
||||
err = ioutil.WriteFile(*flagOut, buf, 0644)
|
||||
err = os.WriteFile(*flagOut, buf, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -96,14 +97,13 @@ func generate() ([]byte, error) {
|
||||
defer res.Body.Close()
|
||||
|
||||
// read all
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// unmarshal
|
||||
var data Gemoji
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
err = json.Unmarshal(body, &data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -158,7 +158,7 @@ func generate() ([]byte, error) {
|
||||
|
||||
// write a JSON file to use with tribute (write before adding skin tones since we can't support them there yet)
|
||||
file, _ := json.Marshal(data)
|
||||
_ = ioutil.WriteFile("assets/emoji.json", file, 0644)
|
||||
_ = os.WriteFile("assets/emoji.json", file, 0644)
|
||||
|
||||
// Add skin tones to emoji that support it
|
||||
var (
|
||||
|
@@ -1,3 +1,4 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
@@ -8,7 +9,6 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -33,7 +33,7 @@ func main() {
|
||||
flag.StringVar(&githubApiToken, "token", "", "github api token")
|
||||
flag.Parse()
|
||||
|
||||
file, err := ioutil.TempFile(os.TempDir(), prefix)
|
||||
file, err := os.CreateTemp(os.TempDir(), prefix)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create temp file. %s", err)
|
||||
@@ -113,13 +113,13 @@ func main() {
|
||||
for dst, src := range filesToCopy {
|
||||
// Read all content of src to data
|
||||
src = path.Join(destination, src)
|
||||
data, err := ioutil.ReadFile(src)
|
||||
data, err := os.ReadFile(src)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read src file. %s", err)
|
||||
}
|
||||
// Write data to dst
|
||||
dst = path.Join(destination, dst)
|
||||
err = ioutil.WriteFile(dst, data, 0644)
|
||||
err = os.WriteFile(dst, data, 0644)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to write new file. %s", err)
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import imageminZopfli from 'imagemin-zopfli';
|
||||
import {optimize, extendDefaultPlugins} from 'svgo';
|
||||
import {optimize} from 'svgo';
|
||||
import {fabric} from 'fabric';
|
||||
import fs from 'fs';
|
||||
import {resolve, dirname} from 'path';
|
||||
@@ -25,13 +25,14 @@ function loadSvg(svg) {
|
||||
async function generate(svg, outputFile, {size, bg}) {
|
||||
if (outputFile.endsWith('.svg')) {
|
||||
const {data} = optimize(svg, {
|
||||
plugins: extendDefaultPlugins([
|
||||
plugins: [
|
||||
'preset-default',
|
||||
'removeDimensions',
|
||||
{
|
||||
name: 'addAttributesToSVGElement',
|
||||
params: {attributes: [{width: size}, {height: size}]}
|
||||
},
|
||||
]),
|
||||
],
|
||||
});
|
||||
await writeFile(outputFile, data);
|
||||
return;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
@@ -8,7 +9,6 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -33,7 +33,7 @@ func main() {
|
||||
flag.StringVar(&githubApiToken, "token", "", "github api token")
|
||||
flag.Parse()
|
||||
|
||||
file, err := ioutil.TempFile(os.TempDir(), prefix)
|
||||
file, err := os.CreateTemp(os.TempDir(), prefix)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create temp file. %s", err)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import fastGlob from 'fast-glob';
|
||||
import {optimize, extendDefaultPlugins} from 'svgo';
|
||||
import {optimize} from 'svgo';
|
||||
import {resolve, parse, dirname} from 'path';
|
||||
import fs from 'fs';
|
||||
import {fileURLToPath} from 'url';
|
||||
@@ -26,18 +26,14 @@ async function processFile(file, {prefix, fullName} = {}) {
|
||||
}
|
||||
|
||||
const {data} = optimize(await readFile(file, 'utf8'), {
|
||||
plugins: extendDefaultPlugins([
|
||||
'removeXMLNS',
|
||||
'removeDimensions',
|
||||
{
|
||||
name: 'addClassesToSVGElement',
|
||||
params: {classNames: ['svg', name]},
|
||||
},
|
||||
{
|
||||
name: 'addAttributesToSVGElement',
|
||||
params: {attributes: [{'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'}]},
|
||||
},
|
||||
]),
|
||||
plugins: [
|
||||
{name: 'preset-default'},
|
||||
{name: 'removeXMLNS'},
|
||||
{name: 'removeDimensions'},
|
||||
{name: 'prefixIds', params: {prefix: () => name}},
|
||||
{name: 'addClassesToSVGElement', params: {classNames: ['svg', name]}},
|
||||
{name: 'addAttributesToSVGElement', params: {attributes: [{'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'}]}},
|
||||
],
|
||||
});
|
||||
await writeFile(resolve(outputDir, `${name}.svg`), data);
|
||||
}
|
||||
|
27
build/gitea-format-imports.go
Normal file
27
build/gitea-format-imports.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"code.gitea.io/gitea/build/codeformat"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) <= 1 {
|
||||
log.Fatalf("Usage: gitea-format-imports [files...]")
|
||||
}
|
||||
|
||||
for _, file := range os.Args[1:] {
|
||||
if err := codeformat.FormatGoImports(file); err != nil {
|
||||
log.Fatalf("can not format file %s, err=%v", file, err)
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,6 +6,7 @@
|
||||
// gocovmerge takes the results from multiple `go test -coverprofile` runs and
|
||||
// merges them into one profile
|
||||
|
||||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
@@ -108,7 +109,7 @@ func main() {
|
||||
for _, file := range flag.Args() {
|
||||
profiles, err := cover.ParseProfiles(file)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to parse profiles: %v", err)
|
||||
log.Fatalf("failed to parse profile '%s': %v", file, err)
|
||||
}
|
||||
for _, p := range profiles {
|
||||
merged = addProfile(merged, p)
|
||||
|
24
build/test-env-check.sh
Executable file
24
build/test-env-check.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ ! -f ./build/test-env-check.sh ]; then
|
||||
echo "${0} can only be executed in gitea source root directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
echo "check uid ..."
|
||||
|
||||
# the uid of gitea defined in "https://gitea.com/gitea/test-env" is 1000
|
||||
gitea_uid=$(id -u gitea)
|
||||
if [ "$gitea_uid" != "1000" ]; then
|
||||
echo "The uid of linux user 'gitea' is expected to be 1000, but it is $gitea_uid"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cur_uid=$(id -u)
|
||||
if [ "$cur_uid" != "0" -a "$cur_uid" != "$gitea_uid" ]; then
|
||||
echo "The uid of current linux user is expected to be 0 or $gitea_uid, but it is $cur_uid"
|
||||
exit 1
|
||||
fi
|
11
build/test-env-prepare.sh
Executable file
11
build/test-env-prepare.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ ! -f ./build/test-env-prepare.sh ]; then
|
||||
echo "${0} can only be executed in gitea source root directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "change the owner of files to gitea ..."
|
||||
chown -R gitea:gitea .
|
390
cmd/admin.go
390
cmd/admin.go
@@ -14,7 +14,10 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/auth/oauth2"
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
"code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@@ -22,6 +25,12 @@ import (
|
||||
repo_module "code.gitea.io/gitea/modules/repository"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
auth_service "code.gitea.io/gitea/services/auth"
|
||||
"code.gitea.io/gitea/services/auth/source/oauth2"
|
||||
"code.gitea.io/gitea/services/auth/source/smtp"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
user_service "code.gitea.io/gitea/services/user"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@@ -105,6 +114,10 @@ var (
|
||||
Name: "access-token",
|
||||
Usage: "Generate access token for the user",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "restricted",
|
||||
Usage: "Make a restricted user account",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -183,6 +196,8 @@ var (
|
||||
cmdAuthUpdateLdapBindDn,
|
||||
cmdAuthAddLdapSimpleAuth,
|
||||
cmdAuthUpdateLdapSimpleAuth,
|
||||
microcmdAuthAddSMTP,
|
||||
microcmdAuthUpdateSMTP,
|
||||
microcmdAuthList,
|
||||
microcmdAuthDelete,
|
||||
},
|
||||
@@ -288,6 +303,40 @@ var (
|
||||
Value: "",
|
||||
Usage: "Custom icon URL for OAuth2 login source",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "skip-local-2fa",
|
||||
Usage: "Set to true to skip local 2fa for users authenticated by this source",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "scopes",
|
||||
Value: nil,
|
||||
Usage: "Scopes to request when to authenticate against this OAuth2 source",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "required-claim-name",
|
||||
Value: "",
|
||||
Usage: "Claim name that has to be set to allow users to login with this source",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "required-claim-value",
|
||||
Value: "",
|
||||
Usage: "Claim value that has to be set to allow users to login with this source",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "group-claim-name",
|
||||
Value: "",
|
||||
Usage: "Claim name providing group names for this source",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "admin-group",
|
||||
Value: "",
|
||||
Usage: "Group Claim value for administrator users",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "restricted-group",
|
||||
Value: "",
|
||||
Usage: "Group Claim value for restricted users",
|
||||
},
|
||||
}
|
||||
|
||||
microcmdAuthUpdateOauth = cli.Command{
|
||||
@@ -325,6 +374,72 @@ var (
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
smtpCLIFlags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "",
|
||||
Usage: "Application Name",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "auth-type",
|
||||
Value: "PLAIN",
|
||||
Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "host",
|
||||
Value: "",
|
||||
Usage: "SMTP Host",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "port",
|
||||
Usage: "SMTP Port",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "force-smtps",
|
||||
Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "skip-verify",
|
||||
Usage: "Skip TLS verify.",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "helo-hostname",
|
||||
Value: "",
|
||||
Usage: "Hostname sent with HELO. Leave blank to send current hostname",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "disable-helo",
|
||||
Usage: "Disable SMTP helo.",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "allowed-domains",
|
||||
Value: "",
|
||||
Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "skip-local-2fa",
|
||||
Usage: "Skip 2FA to log on.",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "active",
|
||||
Usage: "This Authentication Source is Activated.",
|
||||
},
|
||||
}
|
||||
|
||||
microcmdAuthAddSMTP = cli.Command{
|
||||
Name: "add-smtp",
|
||||
Usage: "Add new SMTP authentication source",
|
||||
Action: runAddSMTP,
|
||||
Flags: smtpCLIFlags,
|
||||
}
|
||||
|
||||
microcmdAuthUpdateSMTP = cli.Command{
|
||||
Name: "update-smtp",
|
||||
Usage: "Update existing SMTP authentication source",
|
||||
Action: runUpdateSMTP,
|
||||
Flags: append(smtpCLIFlags[:1], append([]cli.Flag{idFlag}, smtpCLIFlags[1:]...)...),
|
||||
}
|
||||
)
|
||||
|
||||
func runChangePassword(c *cli.Context) error {
|
||||
@@ -332,9 +447,16 @@ func runChangePassword(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(c.String("password")) < setting.MinPasswordLength {
|
||||
return fmt.Errorf("Password is not long enough. Needs to be at least %d", setting.MinPasswordLength)
|
||||
}
|
||||
|
||||
if !pwd.IsComplexEnough(c.String("password")) {
|
||||
return errors.New("Password does not meet complexity requirements")
|
||||
}
|
||||
@@ -346,7 +468,7 @@ func runChangePassword(c *cli.Context) error {
|
||||
return errors.New("The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password.\nFor more details, see https://haveibeenpwned.com/Passwords")
|
||||
}
|
||||
uname := c.String("username")
|
||||
user, err := models.GetUserByName(uname)
|
||||
user, err := user_model.GetUserByName(uname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -354,7 +476,7 @@ func runChangePassword(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = models.UpdateUserCols(user, "passwd", "passwd_hash_algo", "salt"); err != nil {
|
||||
if err = user_model.UpdateUserCols(db.DefaultContext, user, "passwd", "passwd_hash_algo", "salt"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -386,7 +508,10 @@ func runCreateUser(c *cli.Context) error {
|
||||
fmt.Fprintf(os.Stderr, "--name flag is deprecated. Use --username instead.\n")
|
||||
}
|
||||
|
||||
if err := initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -409,7 +534,7 @@ func runCreateUser(c *cli.Context) error {
|
||||
|
||||
// If this is the first user being created.
|
||||
// Take it as the admin and don't force a password update.
|
||||
if n := models.CountUsers(); n == 0 {
|
||||
if n := user_model.CountUsers(); n == 0 {
|
||||
changePassword = false
|
||||
}
|
||||
|
||||
@@ -417,17 +542,26 @@ func runCreateUser(c *cli.Context) error {
|
||||
changePassword = c.Bool("must-change-password")
|
||||
}
|
||||
|
||||
u := &models.User{
|
||||
restricted := util.OptionalBoolNone
|
||||
|
||||
if c.IsSet("restricted") {
|
||||
restricted = util.OptionalBoolOf(c.Bool("restricted"))
|
||||
}
|
||||
|
||||
u := &user_model.User{
|
||||
Name: username,
|
||||
Email: c.String("email"),
|
||||
Passwd: password,
|
||||
IsActive: true,
|
||||
IsAdmin: c.Bool("admin"),
|
||||
MustChangePassword: changePassword,
|
||||
Theme: setting.UI.DefaultTheme,
|
||||
}
|
||||
|
||||
if err := models.CreateUser(u); err != nil {
|
||||
overwriteDefault := &user_model.CreateUserOverwriteOptions{
|
||||
IsActive: util.OptionalBoolTrue,
|
||||
IsRestricted: restricted,
|
||||
}
|
||||
|
||||
if err := user_model.CreateUser(u, overwriteDefault); err != nil {
|
||||
return fmt.Errorf("CreateUser: %v", err)
|
||||
}
|
||||
|
||||
@@ -449,11 +583,14 @@ func runCreateUser(c *cli.Context) error {
|
||||
}
|
||||
|
||||
func runListUsers(c *cli.Context) error {
|
||||
if err := initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
users, err := models.GetAllUsers()
|
||||
users, err := user_model.GetAllUsers()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -486,7 +623,10 @@ func runDeleteUser(c *cli.Context) error {
|
||||
return fmt.Errorf("You must provide the id, username or email of a user to delete")
|
||||
}
|
||||
|
||||
if err := initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -495,13 +635,13 @@ func runDeleteUser(c *cli.Context) error {
|
||||
}
|
||||
|
||||
var err error
|
||||
var user *models.User
|
||||
var user *user_model.User
|
||||
if c.IsSet("email") {
|
||||
user, err = models.GetUserByEmail(c.String("email"))
|
||||
user, err = user_model.GetUserByEmail(c.String("email"))
|
||||
} else if c.IsSet("username") {
|
||||
user, err = models.GetUserByName(c.String("username"))
|
||||
user, err = user_model.GetUserByName(c.String("username"))
|
||||
} else {
|
||||
user, err = models.GetUserByID(c.Int64("id"))
|
||||
user, err = user_model.GetUserByID(c.Int64("id"))
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -514,18 +654,21 @@ func runDeleteUser(c *cli.Context) error {
|
||||
return fmt.Errorf("The user %s does not match the provided id %d", user.Name, c.Int64("id"))
|
||||
}
|
||||
|
||||
return models.DeleteUser(user)
|
||||
return user_service.DeleteUser(user)
|
||||
}
|
||||
|
||||
func runRepoSyncReleases(_ *cli.Context) error {
|
||||
if err := initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Trace("Synchronizing repository releases (this may take a while)")
|
||||
for page := 1; ; page++ {
|
||||
repos, count, err := models.SearchRepositoryByName(&models.SearchRepoOptions{
|
||||
ListOptions: models.ListOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
PageSize: models.RepositoryListDefaultPageSize,
|
||||
Page: page,
|
||||
},
|
||||
@@ -584,20 +727,26 @@ func getReleaseCount(id int64) (int64, error) {
|
||||
}
|
||||
|
||||
func runRegenerateHooks(_ *cli.Context) error {
|
||||
if err := initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return repo_module.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
|
||||
return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
|
||||
}
|
||||
|
||||
func runRegenerateKeys(_ *cli.Context) error {
|
||||
if err := initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return models.RewriteAllPublicKeys()
|
||||
return asymkey_model.RewriteAllPublicKeys()
|
||||
}
|
||||
|
||||
func parseOAuth2Config(c *cli.Context) *models.OAuth2Config {
|
||||
func parseOAuth2Config(c *cli.Context) *oauth2.Source {
|
||||
var customURLMapping *oauth2.CustomURLMapping
|
||||
if c.IsSet("use-custom-urls") {
|
||||
customURLMapping = &oauth2.CustomURLMapping{
|
||||
@@ -609,26 +758,36 @@ func parseOAuth2Config(c *cli.Context) *models.OAuth2Config {
|
||||
} else {
|
||||
customURLMapping = nil
|
||||
}
|
||||
return &models.OAuth2Config{
|
||||
return &oauth2.Source{
|
||||
Provider: c.String("provider"),
|
||||
ClientID: c.String("key"),
|
||||
ClientSecret: c.String("secret"),
|
||||
OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"),
|
||||
CustomURLMapping: customURLMapping,
|
||||
IconURL: c.String("icon-url"),
|
||||
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
|
||||
Scopes: c.StringSlice("scopes"),
|
||||
RequiredClaimName: c.String("required-claim-name"),
|
||||
RequiredClaimValue: c.String("required-claim-value"),
|
||||
GroupClaimName: c.String("group-claim-name"),
|
||||
AdminGroup: c.String("admin-group"),
|
||||
RestrictedGroup: c.String("restricted-group"),
|
||||
}
|
||||
}
|
||||
|
||||
func runAddOauth(c *cli.Context) error {
|
||||
if err := initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return models.CreateLoginSource(&models.LoginSource{
|
||||
Type: models.LoginOAuth2,
|
||||
Name: c.String("name"),
|
||||
IsActived: true,
|
||||
Cfg: parseOAuth2Config(c),
|
||||
return auth.CreateSource(&auth.Source{
|
||||
Type: auth.OAuth2,
|
||||
Name: c.String("name"),
|
||||
IsActive: true,
|
||||
Cfg: parseOAuth2Config(c),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -637,16 +796,19 @@ func runUpdateOauth(c *cli.Context) error {
|
||||
return fmt.Errorf("--id flag is missing")
|
||||
}
|
||||
|
||||
if err := initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
source, err := models.GetLoginSourceByID(c.Int64("id"))
|
||||
source, err := auth.GetSourceByID(c.Int64("id"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oAuth2Config := source.OAuth2()
|
||||
oAuth2Config := source.Cfg.(*oauth2.Source)
|
||||
|
||||
if c.IsSet("name") {
|
||||
source.Name = c.String("name")
|
||||
@@ -672,6 +834,28 @@ func runUpdateOauth(c *cli.Context) error {
|
||||
oAuth2Config.IconURL = c.String("icon-url")
|
||||
}
|
||||
|
||||
if c.IsSet("scopes") {
|
||||
oAuth2Config.Scopes = c.StringSlice("scopes")
|
||||
}
|
||||
|
||||
if c.IsSet("required-claim-name") {
|
||||
oAuth2Config.RequiredClaimName = c.String("required-claim-name")
|
||||
|
||||
}
|
||||
if c.IsSet("required-claim-value") {
|
||||
oAuth2Config.RequiredClaimValue = c.String("required-claim-value")
|
||||
}
|
||||
|
||||
if c.IsSet("group-claim-name") {
|
||||
oAuth2Config.GroupClaimName = c.String("group-claim-name")
|
||||
}
|
||||
if c.IsSet("admin-group") {
|
||||
oAuth2Config.AdminGroup = c.String("admin-group")
|
||||
}
|
||||
if c.IsSet("restricted-group") {
|
||||
oAuth2Config.RestrictedGroup = c.String("restricted-group")
|
||||
}
|
||||
|
||||
// update custom URL mapping
|
||||
var customURLMapping = &oauth2.CustomURLMapping{}
|
||||
|
||||
@@ -700,15 +884,130 @@ func runUpdateOauth(c *cli.Context) error {
|
||||
oAuth2Config.CustomURLMapping = customURLMapping
|
||||
source.Cfg = oAuth2Config
|
||||
|
||||
return models.UpdateSource(source)
|
||||
return auth.UpdateSource(source)
|
||||
}
|
||||
|
||||
func runListAuth(c *cli.Context) error {
|
||||
if err := initDB(); err != nil {
|
||||
func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error {
|
||||
if c.IsSet("auth-type") {
|
||||
conf.Auth = c.String("auth-type")
|
||||
validAuthTypes := []string{"PLAIN", "LOGIN", "CRAM-MD5"}
|
||||
if !contains(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
|
||||
return errors.New("Auth must be one of PLAIN/LOGIN/CRAM-MD5")
|
||||
}
|
||||
conf.Auth = c.String("auth-type")
|
||||
}
|
||||
if c.IsSet("host") {
|
||||
conf.Host = c.String("host")
|
||||
}
|
||||
if c.IsSet("port") {
|
||||
conf.Port = c.Int("port")
|
||||
}
|
||||
if c.IsSet("allowed-domains") {
|
||||
conf.AllowedDomains = c.String("allowed-domains")
|
||||
}
|
||||
if c.IsSet("force-smtps") {
|
||||
conf.ForceSMTPS = c.BoolT("force-smtps")
|
||||
}
|
||||
if c.IsSet("skip-verify") {
|
||||
conf.SkipVerify = c.BoolT("skip-verify")
|
||||
}
|
||||
if c.IsSet("helo-hostname") {
|
||||
conf.HeloHostname = c.String("helo-hostname")
|
||||
}
|
||||
if c.IsSet("disable-helo") {
|
||||
conf.DisableHelo = c.BoolT("disable-helo")
|
||||
}
|
||||
if c.IsSet("skip-local-2fa") {
|
||||
conf.SkipLocalTwoFA = c.BoolT("skip-local-2fa")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runAddSMTP(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
loginSources, err := models.LoginSources()
|
||||
if !c.IsSet("name") || len(c.String("name")) == 0 {
|
||||
return errors.New("name must be set")
|
||||
}
|
||||
if !c.IsSet("host") || len(c.String("host")) == 0 {
|
||||
return errors.New("host must be set")
|
||||
}
|
||||
if !c.IsSet("port") {
|
||||
return errors.New("port must be set")
|
||||
}
|
||||
var active = true
|
||||
if c.IsSet("active") {
|
||||
active = c.BoolT("active")
|
||||
}
|
||||
|
||||
var smtpConfig smtp.Source
|
||||
if err := parseSMTPConfig(c, &smtpConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If not set default to PLAIN
|
||||
if len(smtpConfig.Auth) == 0 {
|
||||
smtpConfig.Auth = "PLAIN"
|
||||
}
|
||||
|
||||
return auth.CreateSource(&auth.Source{
|
||||
Type: auth.SMTP,
|
||||
Name: c.String("name"),
|
||||
IsActive: active,
|
||||
Cfg: &smtpConfig,
|
||||
})
|
||||
}
|
||||
|
||||
func runUpdateSMTP(c *cli.Context) error {
|
||||
if !c.IsSet("id") {
|
||||
return fmt.Errorf("--id flag is missing")
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
source, err := auth.GetSourceByID(c.Int64("id"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
smtpConfig := source.Cfg.(*smtp.Source)
|
||||
|
||||
if err := parseSMTPConfig(c, smtpConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.IsSet("name") {
|
||||
source.Name = c.String("name")
|
||||
}
|
||||
|
||||
if c.IsSet("active") {
|
||||
source.IsActive = c.BoolT("active")
|
||||
}
|
||||
|
||||
source.Cfg = smtpConfig
|
||||
|
||||
return auth.UpdateSource(source)
|
||||
}
|
||||
|
||||
func runListAuth(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
authSources, err := auth.Sources()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -727,8 +1026,8 @@ func runListAuth(c *cli.Context) error {
|
||||
// loop through each source and print
|
||||
w := tabwriter.NewWriter(os.Stdout, c.Int("min-width"), c.Int("tab-width"), c.Int("padding"), padChar, flags)
|
||||
fmt.Fprintf(w, "ID\tName\tType\tEnabled\n")
|
||||
for _, source := range loginSources {
|
||||
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, models.LoginNames[source.Type], source.IsActived)
|
||||
for _, source := range authSources {
|
||||
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, source.Type.String(), source.IsActive)
|
||||
}
|
||||
w.Flush()
|
||||
|
||||
@@ -740,14 +1039,17 @@ func runDeleteAuth(c *cli.Context) error {
|
||||
return fmt.Errorf("--id flag is missing")
|
||||
}
|
||||
|
||||
if err := initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
source, err := models.GetLoginSourceByID(c.Int64("id"))
|
||||
source, err := auth.GetSourceByID(c.Int64("id"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return models.DeleteSource(source)
|
||||
return auth_service.DeleteSource(source)
|
||||
}
|
||||
|
@@ -5,21 +5,22 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/auth/ldap"
|
||||
"code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/services/auth/source/ldap"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
type (
|
||||
authService struct {
|
||||
initDB func() error
|
||||
createLoginSource func(loginSource *models.LoginSource) error
|
||||
updateLoginSource func(loginSource *models.LoginSource) error
|
||||
getLoginSourceByID func(id int64) (*models.LoginSource, error)
|
||||
initDB func(ctx context.Context) error
|
||||
createAuthSource func(*auth.Source) error
|
||||
updateAuthSource func(*auth.Source) error
|
||||
getAuthSourceByID func(id int64) (*auth.Source, error)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -89,6 +90,14 @@ var (
|
||||
Name: "public-ssh-key-attribute",
|
||||
Usage: "The attribute of the user’s LDAP record containing the user’s public ssh key.",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "skip-local-2fa",
|
||||
Usage: "Set to true to skip local 2fa for users authenticated by this source",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "avatar-attribute",
|
||||
Usage: "The attribute of the user’s LDAP record containing the user’s avatar.",
|
||||
},
|
||||
}
|
||||
|
||||
ldapBindDnCLIFlags = append(commonLdapCLIFlags,
|
||||
@@ -159,99 +168,106 @@ var (
|
||||
// newAuthService creates a service with default functions.
|
||||
func newAuthService() *authService {
|
||||
return &authService{
|
||||
initDB: initDB,
|
||||
createLoginSource: models.CreateLoginSource,
|
||||
updateLoginSource: models.UpdateSource,
|
||||
getLoginSourceByID: models.GetLoginSourceByID,
|
||||
initDB: initDB,
|
||||
createAuthSource: auth.CreateSource,
|
||||
updateAuthSource: auth.UpdateSource,
|
||||
getAuthSourceByID: auth.GetSourceByID,
|
||||
}
|
||||
}
|
||||
|
||||
// parseLoginSource assigns values on loginSource according to command line flags.
|
||||
func parseLoginSource(c *cli.Context, loginSource *models.LoginSource) {
|
||||
// parseAuthSource assigns values on authSource according to command line flags.
|
||||
func parseAuthSource(c *cli.Context, authSource *auth.Source) {
|
||||
if c.IsSet("name") {
|
||||
loginSource.Name = c.String("name")
|
||||
authSource.Name = c.String("name")
|
||||
}
|
||||
if c.IsSet("not-active") {
|
||||
loginSource.IsActived = !c.Bool("not-active")
|
||||
authSource.IsActive = !c.Bool("not-active")
|
||||
}
|
||||
if c.IsSet("synchronize-users") {
|
||||
loginSource.IsSyncEnabled = c.Bool("synchronize-users")
|
||||
authSource.IsSyncEnabled = c.Bool("synchronize-users")
|
||||
}
|
||||
}
|
||||
|
||||
// parseLdapConfig assigns values on config according to command line flags.
|
||||
func parseLdapConfig(c *cli.Context, config *models.LDAPConfig) error {
|
||||
func parseLdapConfig(c *cli.Context, config *ldap.Source) error {
|
||||
if c.IsSet("name") {
|
||||
config.Source.Name = c.String("name")
|
||||
config.Name = c.String("name")
|
||||
}
|
||||
if c.IsSet("host") {
|
||||
config.Source.Host = c.String("host")
|
||||
config.Host = c.String("host")
|
||||
}
|
||||
if c.IsSet("port") {
|
||||
config.Source.Port = c.Int("port")
|
||||
config.Port = c.Int("port")
|
||||
}
|
||||
if c.IsSet("security-protocol") {
|
||||
p, ok := findLdapSecurityProtocolByName(c.String("security-protocol"))
|
||||
if !ok {
|
||||
return fmt.Errorf("Unknown security protocol name: %s", c.String("security-protocol"))
|
||||
}
|
||||
config.Source.SecurityProtocol = p
|
||||
config.SecurityProtocol = p
|
||||
}
|
||||
if c.IsSet("skip-tls-verify") {
|
||||
config.Source.SkipVerify = c.Bool("skip-tls-verify")
|
||||
config.SkipVerify = c.Bool("skip-tls-verify")
|
||||
}
|
||||
if c.IsSet("bind-dn") {
|
||||
config.Source.BindDN = c.String("bind-dn")
|
||||
config.BindDN = c.String("bind-dn")
|
||||
}
|
||||
if c.IsSet("user-dn") {
|
||||
config.Source.UserDN = c.String("user-dn")
|
||||
config.UserDN = c.String("user-dn")
|
||||
}
|
||||
if c.IsSet("bind-password") {
|
||||
config.Source.BindPassword = c.String("bind-password")
|
||||
config.BindPassword = c.String("bind-password")
|
||||
}
|
||||
if c.IsSet("user-search-base") {
|
||||
config.Source.UserBase = c.String("user-search-base")
|
||||
config.UserBase = c.String("user-search-base")
|
||||
}
|
||||
if c.IsSet("username-attribute") {
|
||||
config.Source.AttributeUsername = c.String("username-attribute")
|
||||
config.AttributeUsername = c.String("username-attribute")
|
||||
}
|
||||
if c.IsSet("firstname-attribute") {
|
||||
config.Source.AttributeName = c.String("firstname-attribute")
|
||||
config.AttributeName = c.String("firstname-attribute")
|
||||
}
|
||||
if c.IsSet("surname-attribute") {
|
||||
config.Source.AttributeSurname = c.String("surname-attribute")
|
||||
config.AttributeSurname = c.String("surname-attribute")
|
||||
}
|
||||
if c.IsSet("email-attribute") {
|
||||
config.Source.AttributeMail = c.String("email-attribute")
|
||||
config.AttributeMail = c.String("email-attribute")
|
||||
}
|
||||
if c.IsSet("attributes-in-bind") {
|
||||
config.Source.AttributesInBind = c.Bool("attributes-in-bind")
|
||||
config.AttributesInBind = c.Bool("attributes-in-bind")
|
||||
}
|
||||
if c.IsSet("public-ssh-key-attribute") {
|
||||
config.Source.AttributeSSHPublicKey = c.String("public-ssh-key-attribute")
|
||||
config.AttributeSSHPublicKey = c.String("public-ssh-key-attribute")
|
||||
}
|
||||
if c.IsSet("avatar-attribute") {
|
||||
config.AttributeAvatar = c.String("avatar-attribute")
|
||||
}
|
||||
if c.IsSet("page-size") {
|
||||
config.Source.SearchPageSize = uint32(c.Uint("page-size"))
|
||||
config.SearchPageSize = uint32(c.Uint("page-size"))
|
||||
}
|
||||
if c.IsSet("user-filter") {
|
||||
config.Source.Filter = c.String("user-filter")
|
||||
config.Filter = c.String("user-filter")
|
||||
}
|
||||
if c.IsSet("admin-filter") {
|
||||
config.Source.AdminFilter = c.String("admin-filter")
|
||||
config.AdminFilter = c.String("admin-filter")
|
||||
}
|
||||
if c.IsSet("restricted-filter") {
|
||||
config.Source.RestrictedFilter = c.String("restricted-filter")
|
||||
config.RestrictedFilter = c.String("restricted-filter")
|
||||
}
|
||||
if c.IsSet("allow-deactivate-all") {
|
||||
config.Source.AllowDeactivateAll = c.Bool("allow-deactivate-all")
|
||||
config.AllowDeactivateAll = c.Bool("allow-deactivate-all")
|
||||
}
|
||||
if c.IsSet("skip-local-2fa") {
|
||||
config.SkipLocalTwoFA = c.Bool("skip-local-2fa")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// findLdapSecurityProtocolByName finds security protocol by its name ignoring case.
|
||||
// It returns the value of the security protocol and if it was found.
|
||||
func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) {
|
||||
for i, n := range models.SecurityProtocolNames {
|
||||
for i, n := range ldap.SecurityProtocolNames {
|
||||
if strings.EqualFold(name, n) {
|
||||
return i, true
|
||||
}
|
||||
@@ -259,23 +275,23 @@ func findLdapSecurityProtocolByName(name string) (ldap.SecurityProtocol, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// getLoginSource gets the login source by its id defined in the command line flags.
|
||||
// getAuthSource gets the login source by its id defined in the command line flags.
|
||||
// It returns an error if the id is not set, does not match any source or if the source is not of expected type.
|
||||
func (a *authService) getLoginSource(c *cli.Context, loginType models.LoginType) (*models.LoginSource, error) {
|
||||
func (a *authService) getAuthSource(c *cli.Context, authType auth.Type) (*auth.Source, error) {
|
||||
if err := argsSet(c, "id"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
loginSource, err := a.getLoginSourceByID(c.Int64("id"))
|
||||
authSource, err := a.getAuthSourceByID(c.Int64("id"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if loginSource.Type != loginType {
|
||||
return nil, fmt.Errorf("Invalid authentication type. expected: %s, actual: %s", models.LoginNames[loginType], models.LoginNames[loginSource.Type])
|
||||
if authSource.Type != authType {
|
||||
return nil, fmt.Errorf("Invalid authentication type. expected: %s, actual: %s", authType.String(), authSource.Type.String())
|
||||
}
|
||||
|
||||
return loginSource, nil
|
||||
return authSource, nil
|
||||
}
|
||||
|
||||
// addLdapBindDn adds a new LDAP via Bind DN authentication source.
|
||||
@@ -284,45 +300,49 @@ func (a *authService) addLdapBindDn(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := a.initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
loginSource := &models.LoginSource{
|
||||
Type: models.LoginLDAP,
|
||||
IsActived: true, // active by default
|
||||
Cfg: &models.LDAPConfig{
|
||||
Source: &ldap.Source{
|
||||
Enabled: true, // always true
|
||||
},
|
||||
authSource := &auth.Source{
|
||||
Type: auth.LDAP,
|
||||
IsActive: true, // active by default
|
||||
Cfg: &ldap.Source{
|
||||
Enabled: true, // always true
|
||||
},
|
||||
}
|
||||
|
||||
parseLoginSource(c, loginSource)
|
||||
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
|
||||
parseAuthSource(c, authSource)
|
||||
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return a.createLoginSource(loginSource)
|
||||
return a.createAuthSource(authSource)
|
||||
}
|
||||
|
||||
// updateLdapBindDn updates a new LDAP via Bind DN authentication source.
|
||||
func (a *authService) updateLdapBindDn(c *cli.Context) error {
|
||||
if err := a.initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := a.initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
loginSource, err := a.getLoginSource(c, models.LoginLDAP)
|
||||
authSource, err := a.getAuthSource(c, auth.LDAP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parseLoginSource(c, loginSource)
|
||||
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
|
||||
parseAuthSource(c, authSource)
|
||||
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return a.updateLoginSource(loginSource)
|
||||
return a.updateAuthSource(authSource)
|
||||
}
|
||||
|
||||
// addLdapSimpleAuth adds a new LDAP (simple auth) authentication source.
|
||||
@@ -331,43 +351,47 @@ func (a *authService) addLdapSimpleAuth(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := a.initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
loginSource := &models.LoginSource{
|
||||
Type: models.LoginDLDAP,
|
||||
IsActived: true, // active by default
|
||||
Cfg: &models.LDAPConfig{
|
||||
Source: &ldap.Source{
|
||||
Enabled: true, // always true
|
||||
},
|
||||
authSource := &auth.Source{
|
||||
Type: auth.DLDAP,
|
||||
IsActive: true, // active by default
|
||||
Cfg: &ldap.Source{
|
||||
Enabled: true, // always true
|
||||
},
|
||||
}
|
||||
|
||||
parseLoginSource(c, loginSource)
|
||||
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
|
||||
parseAuthSource(c, authSource)
|
||||
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return a.createLoginSource(loginSource)
|
||||
return a.createAuthSource(authSource)
|
||||
}
|
||||
|
||||
// updateLdapBindDn updates a new LDAP (simple auth) authentication source.
|
||||
func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
|
||||
if err := a.initDB(); err != nil {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := a.initDB(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
loginSource, err := a.getLoginSource(c, models.LoginDLDAP)
|
||||
authSource, err := a.getAuthSource(c, auth.DLDAP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parseLoginSource(c, loginSource)
|
||||
if err := parseLdapConfig(c, loginSource.LDAP()); err != nil {
|
||||
parseAuthSource(c, authSource)
|
||||
if err := parseLdapConfig(c, authSource.Cfg.(*ldap.Source)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return a.updateLoginSource(loginSource)
|
||||
return a.updateAuthSource(authSource)
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
24
cmd/cmd.go
24
cmd/cmd.go
@@ -15,7 +15,8 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
@@ -30,7 +31,7 @@ func argsSet(c *cli.Context, args ...string) error {
|
||||
return errors.New(a + " is not set")
|
||||
}
|
||||
|
||||
if util.IsEmptyString(a) {
|
||||
if util.IsEmptyString(c.String(a)) {
|
||||
return errors.New(a + " is required")
|
||||
}
|
||||
}
|
||||
@@ -56,17 +57,18 @@ func confirm() (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func initDB() error {
|
||||
return initDBDisableConsole(false)
|
||||
}
|
||||
|
||||
func initDBDisableConsole(disableConsole bool) error {
|
||||
setting.NewContext()
|
||||
func initDB(ctx context.Context) error {
|
||||
setting.LoadFromExisting()
|
||||
setting.InitDBConfig()
|
||||
setting.NewXORMLogService(false)
|
||||
|
||||
setting.NewXORMLogService(disableConsole)
|
||||
if err := models.SetEngine(); err != nil {
|
||||
return fmt.Errorf("models.SetEngine: %v", err)
|
||||
if setting.Database.Type == "" {
|
||||
log.Fatal(`Database settings are missing from the configuration file: %q.
|
||||
Ensure you are running in the correct environment or set the correct configuration file with -c.
|
||||
If this is the intended configuration file complete the [database] section.`, setting.CustomConf)
|
||||
}
|
||||
if err := db.InitEngine(ctx); err != nil {
|
||||
return fmt.Errorf("unable to initialise the database using the configuration in %q. Error: %v", setting.CustomConf, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
@@ -23,7 +23,10 @@ var CmdConvert = cli.Command{
|
||||
}
|
||||
|
||||
func runConvert(ctx *cli.Context) error {
|
||||
if err := initDB(); err != nil {
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(stdCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -31,14 +34,14 @@ func runConvert(ctx *cli.Context) error {
|
||||
log.Info("AppWorkPath: %s", setting.AppWorkPath)
|
||||
log.Info("Custom path: %s", setting.CustomPath)
|
||||
log.Info("Log path: %s", setting.LogRootPath)
|
||||
setting.InitDBConfig()
|
||||
log.Info("Configuration file: %s", setting.CustomConf)
|
||||
|
||||
if !setting.Database.UseMySQL {
|
||||
fmt.Println("This command can only be used with a MySQL database")
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := models.ConvertUtf8ToUtf8mb4(); err != nil {
|
||||
if err := db.ConvertUtf8ToUtf8mb4(); err != nil {
|
||||
log.Fatal("Failed to convert database from utf8 to utf8mb4: %v", err)
|
||||
return err
|
||||
}
|
||||
|
@@ -43,7 +43,11 @@ func runDocs(ctx *cli.Context) error {
|
||||
// Clean up markdown. The following bug was fixed in v2, but is present in v1.
|
||||
// It affects markdown output (even though the issue is referring to man pages)
|
||||
// https://github.com/urfave/cli/issues/1040
|
||||
docs = docs[strings.Index(docs, "#"):]
|
||||
firstHashtagIndex := strings.Index(docs, "#")
|
||||
|
||||
if firstHashtagIndex > 0 {
|
||||
docs = docs[firstHashtagIndex:]
|
||||
}
|
||||
}
|
||||
|
||||
out := os.Stdout
|
||||
|
@@ -12,15 +12,14 @@ import (
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/migrations"
|
||||
"code.gitea.io/gitea/modules/doctor"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// CmdDoctor represents the available doctor sub-command.
|
||||
@@ -88,7 +87,7 @@ func runRecreateTable(ctx *cli.Context) error {
|
||||
golog.SetPrefix("")
|
||||
golog.SetOutput(log.NewLoggerAsWriter("INFO", log.GetLogger(log.DEFAULT)))
|
||||
|
||||
setting.NewContext()
|
||||
setting.LoadFromExisting()
|
||||
setting.InitDBConfig()
|
||||
|
||||
setting.EnableXORMLog = ctx.Bool("debug")
|
||||
@@ -96,7 +95,10 @@ func runRecreateTable(ctx *cli.Context) error {
|
||||
setting.Cfg.Section("log").Key("XORM").SetValue(",")
|
||||
|
||||
setting.NewXORMLogService(!ctx.Bool("debug"))
|
||||
if err := models.SetEngine(); err != nil {
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := db.InitEngine(stdCtx); err != nil {
|
||||
fmt.Println(err)
|
||||
fmt.Println("Check if you are using the right config file. You can use a --config directive to specify one.")
|
||||
return nil
|
||||
@@ -108,13 +110,13 @@ func runRecreateTable(ctx *cli.Context) error {
|
||||
names = append(names, args.Get(i))
|
||||
}
|
||||
|
||||
beans, err := models.NamesToBean(names...)
|
||||
beans, err := db.NamesToBean(names...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recreateTables := migrations.RecreateTables(beans...)
|
||||
|
||||
return models.NewEngine(context.Background(), func(x *xorm.Engine) error {
|
||||
return db.InitEngineWithMigration(context.Background(), func(x *xorm.Engine) error {
|
||||
if err := migrations.EnsureUpToDate(x); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -124,11 +126,13 @@ func runRecreateTable(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
func runDoctor(ctx *cli.Context) error {
|
||||
|
||||
// Silence the default loggers
|
||||
log.DelNamedLogger("console")
|
||||
log.DelNamedLogger(log.DEFAULT)
|
||||
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
// Now setup our own
|
||||
logFile := ctx.String("log-file")
|
||||
if !ctx.IsSet("log-file") {
|
||||
@@ -211,5 +215,5 @@ func runDoctor(ctx *cli.Context) error {
|
||||
|
||||
logger := log.GetLogger("doctorouter")
|
||||
defer logger.Close()
|
||||
return doctor.RunChecks(logger, ctx.Bool("fix"), checks)
|
||||
return doctor.RunChecks(stdCtx, logger, ctx.Bool("fix"), checks)
|
||||
}
|
||||
|
34
cmd/dump.go
34
cmd/dump.go
@@ -7,26 +7,25 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"gitea.com/go-chi/session"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
archiver "github.com/mholt/archiver/v3"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func addFile(w archiver.Writer, filePath string, absPath string, verbose bool) error {
|
||||
func addFile(w archiver.Writer, filePath, absPath string, verbose bool) error {
|
||||
if verbose {
|
||||
log.Info("Adding file %s\n", filePath)
|
||||
}
|
||||
@@ -49,7 +48,7 @@ func addFile(w archiver.Writer, filePath string, absPath string, verbose bool) e
|
||||
})
|
||||
}
|
||||
|
||||
func isSubdir(upper string, lower string) (bool, error) {
|
||||
func isSubdir(upper, lower string) (bool, error) {
|
||||
if relPath, err := filepath.Rel(upper, lower); err != nil {
|
||||
return false, err
|
||||
} else if relPath == "." || !strings.HasPrefix(relPath, ".") {
|
||||
@@ -87,7 +86,7 @@ func (o outputType) String() string {
|
||||
}
|
||||
|
||||
var outputTypeEnum = &outputType{
|
||||
Enum: []string{"zip", "tar", "tar.gz", "tar.xz", "tar.bz2"},
|
||||
Enum: []string{"zip", "tar", "tar.sz", "tar.gz", "tar.xz", "tar.bz2", "tar.br", "tar.lz4"},
|
||||
Default: "zip",
|
||||
}
|
||||
|
||||
@@ -153,14 +152,24 @@ func fatal(format string, args ...interface{}) {
|
||||
func runDump(ctx *cli.Context) error {
|
||||
var file *os.File
|
||||
fileName := ctx.String("file")
|
||||
outType := ctx.String("type")
|
||||
if fileName == "-" {
|
||||
file = os.Stdout
|
||||
err := log.DelLogger("console")
|
||||
if err != nil {
|
||||
fatal("Deleting default logger failed. Can not write to stdout: %v", err)
|
||||
}
|
||||
} else {
|
||||
for _, suffix := range outputTypeEnum.Enum {
|
||||
if strings.HasSuffix(fileName, "."+suffix) {
|
||||
fileName = strings.TrimSuffix(fileName, "."+suffix)
|
||||
break
|
||||
}
|
||||
}
|
||||
fileName += "." + outType
|
||||
}
|
||||
setting.NewContext()
|
||||
setting.LoadFromExisting()
|
||||
|
||||
// make sure we are logging to the console no matter what the configuration tells us do to
|
||||
if _, err := setting.Cfg.Section("log").NewKey("MODE", "console"); err != nil {
|
||||
fatal("Setting logging mode to console failed: %v", err)
|
||||
@@ -174,7 +183,10 @@ func runDump(ctx *cli.Context) error {
|
||||
}
|
||||
setting.NewServices() // cannot access session settings otherwise
|
||||
|
||||
err := models.SetEngine()
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
err := db.InitEngine(stdCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -197,7 +209,6 @@ func runDump(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
verbose := ctx.Bool("verbose")
|
||||
outType := ctx.String("type")
|
||||
var iface interface{}
|
||||
if fileName == "-" {
|
||||
iface, err = archiver.ByExtension(fmt.Sprintf(".%s", outType))
|
||||
@@ -247,7 +258,7 @@ func runDump(ctx *cli.Context) error {
|
||||
fatal("Path does not exist: %s", tmpDir)
|
||||
}
|
||||
|
||||
dbDump, err := ioutil.TempFile(tmpDir, "gitea-db.sql")
|
||||
dbDump, err := os.CreateTemp(tmpDir, "gitea-db.sql")
|
||||
if err != nil {
|
||||
fatal("Failed to create tmp file: %v", err)
|
||||
}
|
||||
@@ -264,7 +275,7 @@ func runDump(ctx *cli.Context) error {
|
||||
log.Info("Dumping database...")
|
||||
}
|
||||
|
||||
if err := models.DumpDatabase(dbDump.Name(), targetDBType); err != nil {
|
||||
if err := db.DumpDatabase(dbDump.Name(), targetDBType); err != nil {
|
||||
fatal("Failed to dump database: %v", err)
|
||||
}
|
||||
|
||||
@@ -306,7 +317,6 @@ func runDump(ctx *cli.Context) error {
|
||||
var excludes []string
|
||||
if setting.Cfg.Section("session").Key("PROVIDER").Value() == "file" {
|
||||
var opts session.Options
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
if err = json.Unmarshal([]byte(setting.SessionConfig.ProviderConfig), &opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -11,10 +11,10 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/modules/convert"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/migrations"
|
||||
"code.gitea.io/gitea/modules/migrations/base"
|
||||
base "code.gitea.io/gitea/modules/migration"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/services/migrations"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@@ -76,7 +76,10 @@ wiki, issues, labels, releases, release_assets, milestones, pull_requests, comme
|
||||
}
|
||||
|
||||
func runDumpRepository(ctx *cli.Context) error {
|
||||
if err := initDB(); err != nil {
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(stdCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -84,7 +87,7 @@ func runDumpRepository(ctx *cli.Context) error {
|
||||
log.Info("AppWorkPath: %s", setting.AppWorkPath)
|
||||
log.Info("Custom path: %s", setting.CustomPath)
|
||||
log.Info("Log path: %s", setting.LogRootPath)
|
||||
setting.InitDBConfig()
|
||||
log.Info("Configuration file: %s", setting.CustomConf)
|
||||
|
||||
var (
|
||||
serviceType structs.GitServiceType
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build bindata
|
||||
// +build bindata
|
||||
|
||||
package cmd
|
||||
@@ -114,7 +115,7 @@ func initEmbeddedExtractor(c *cli.Context) error {
|
||||
log.DelNamedLogger(log.DEFAULT)
|
||||
|
||||
// Read configuration file
|
||||
setting.NewContext()
|
||||
setting.LoadAllowEmpty()
|
||||
|
||||
pats, err := getPatterns(c.Args())
|
||||
if err != nil {
|
||||
|
@@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !bindata
|
||||
// +build !bindata
|
||||
|
||||
package cmd
|
||||
|
353
cmd/hook.go
353
cmd/hook.go
@@ -38,6 +38,7 @@ var (
|
||||
subcmdHookPreReceive,
|
||||
subcmdHookUpdate,
|
||||
subcmdHookPostReceive,
|
||||
subcmdHookProcReceive,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -74,6 +75,18 @@ var (
|
||||
},
|
||||
},
|
||||
}
|
||||
// Note: new hook since git 2.29
|
||||
subcmdHookProcReceive = cli.Command{
|
||||
Name: "proc-receive",
|
||||
Usage: "Delegate proc-receive Git hook",
|
||||
Description: "This command should only be called by Git",
|
||||
Action: runHookProcReceive,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "debug",
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type delayWriter struct {
|
||||
@@ -172,7 +185,7 @@ Gitea or set your environment appropriately.`, "")
|
||||
reponame := os.Getenv(models.EnvRepoName)
|
||||
userID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
|
||||
prID, _ := strconv.ParseInt(os.Getenv(models.EnvPRID), 10, 64)
|
||||
isDeployKey, _ := strconv.ParseBool(os.Getenv(models.EnvIsDeployKey))
|
||||
deployKeyID, _ := strconv.ParseInt(os.Getenv(models.EnvDeployKeyID), 10, 64)
|
||||
|
||||
hookOptions := private.HookOptions{
|
||||
UserID: userID,
|
||||
@@ -181,7 +194,7 @@ Gitea or set your environment appropriately.`, "")
|
||||
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
|
||||
GitPushOptions: pushOptions(),
|
||||
PullRequestID: prID,
|
||||
IsDeployKey: isDeployKey,
|
||||
DeployKeyID: deployKeyID,
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
@@ -205,6 +218,11 @@ Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
}
|
||||
|
||||
supportProcRecive := false
|
||||
if git.CheckGitVersionAtLeast("2.29") == nil {
|
||||
supportProcRecive = true
|
||||
}
|
||||
|
||||
for scanner.Scan() {
|
||||
// TODO: support news feeds for wiki
|
||||
if isWiki {
|
||||
@@ -223,7 +241,9 @@ Gitea or set your environment appropriately.`, "")
|
||||
lastline++
|
||||
|
||||
// If the ref is a branch or tag, check if it's protected
|
||||
if strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) {
|
||||
// if supportProcRecive all ref should be checked because
|
||||
// permission check was delayed
|
||||
if supportProcRecive || strings.HasPrefix(refFullName, git.BranchPrefix) || strings.HasPrefix(refFullName, git.TagPrefix) {
|
||||
oldCommitIDs[count] = oldCommitID
|
||||
newCommitIDs[count] = newCommitID
|
||||
refFullNames[count] = refFullName
|
||||
@@ -273,7 +293,6 @@ Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
} else if lastline > 0 {
|
||||
fmt.Fprintf(out, "\n")
|
||||
lastline = 0
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, "Checked %d references in total\n", total)
|
||||
@@ -290,7 +309,7 @@ func runHookPostReceive(c *cli.Context) error {
|
||||
defer cancel()
|
||||
|
||||
// First of all run update-server-info no matter what
|
||||
if _, err := git.NewCommand("update-server-info").SetParentContext(ctx).Run(); err != nil {
|
||||
if _, err := git.NewCommandContext(ctx, "update-server-info").Run(); err != nil {
|
||||
return fmt.Errorf("Failed to call 'git update-server-info': %v", err)
|
||||
}
|
||||
|
||||
@@ -463,3 +482,327 @@ func pushOptions() map[string]string {
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func runHookProcReceive(c *cli.Context) error {
|
||||
setup("hooks/proc-receive.log", c.Bool("debug"))
|
||||
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
if setting.OnlyAllowPushIfGiteaEnvironmentSet {
|
||||
return fail(`Rejecting changes as Gitea environment not set.
|
||||
If you are pushing over SSH you must push with a key managed by
|
||||
Gitea or set your environment appropriately.`, "")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if git.CheckGitVersionAtLeast("2.29") != nil {
|
||||
return fail("Internal Server Error", "git not support proc-receive.")
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
repoUser := os.Getenv(models.EnvRepoUsername)
|
||||
repoName := os.Getenv(models.EnvRepoName)
|
||||
pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
|
||||
pusherName := os.Getenv(models.EnvPusherName)
|
||||
|
||||
// 1. Version and features negotiation.
|
||||
// S: PKT-LINE(version=1\0push-options atomic...) / PKT-LINE(version=1\n)
|
||||
// S: flush-pkt
|
||||
// H: PKT-LINE(version=1\0push-options...)
|
||||
// H: flush-pkt
|
||||
|
||||
rs, err := readPktLine(reader, pktLineTypeData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
const VersionHead string = "version=1"
|
||||
|
||||
var (
|
||||
hasPushOptions bool
|
||||
response = []byte(VersionHead)
|
||||
requestOptions []string
|
||||
)
|
||||
|
||||
index := bytes.IndexByte(rs.Data, byte(0))
|
||||
if index >= len(rs.Data) {
|
||||
return fail("Internal Server Error", "pkt-line: format error "+fmt.Sprint(rs.Data))
|
||||
}
|
||||
|
||||
if index < 0 {
|
||||
if len(rs.Data) == 10 && rs.Data[9] == '\n' {
|
||||
index = 9
|
||||
} else {
|
||||
return fail("Internal Server Error", "pkt-line: format error "+fmt.Sprint(rs.Data))
|
||||
}
|
||||
}
|
||||
|
||||
if string(rs.Data[0:index]) != VersionHead {
|
||||
return fail("Internal Server Error", "Received unsupported version: %s", string(rs.Data[0:index]))
|
||||
}
|
||||
requestOptions = strings.Split(string(rs.Data[index+1:]), " ")
|
||||
|
||||
for _, option := range requestOptions {
|
||||
if strings.HasPrefix(option, "push-options") {
|
||||
response = append(response, byte(0))
|
||||
response = append(response, []byte("push-options")...)
|
||||
hasPushOptions = true
|
||||
}
|
||||
}
|
||||
response = append(response, '\n')
|
||||
|
||||
_, err = readPktLine(reader, pktLineTypeFlush)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeDataPktLine(os.Stdout, response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeFlushPktLine(os.Stdout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. receive commands from server.
|
||||
// S: PKT-LINE(<old-oid> <new-oid> <ref>)
|
||||
// S: ... ...
|
||||
// S: flush-pkt
|
||||
// # [receive push-options]
|
||||
// S: PKT-LINE(push-option)
|
||||
// S: ... ...
|
||||
// S: flush-pkt
|
||||
hookOptions := private.HookOptions{
|
||||
UserName: pusherName,
|
||||
UserID: pusherID,
|
||||
}
|
||||
hookOptions.OldCommitIDs = make([]string, 0, hookBatchSize)
|
||||
hookOptions.NewCommitIDs = make([]string, 0, hookBatchSize)
|
||||
hookOptions.RefFullNames = make([]string, 0, hookBatchSize)
|
||||
|
||||
for {
|
||||
// note: pktLineTypeUnknow means pktLineTypeFlush and pktLineTypeData all allowed
|
||||
rs, err = readPktLine(reader, pktLineTypeUnknow)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if rs.Type == pktLineTypeFlush {
|
||||
break
|
||||
}
|
||||
t := strings.SplitN(string(rs.Data), " ", 3)
|
||||
if len(t) != 3 {
|
||||
continue
|
||||
}
|
||||
hookOptions.OldCommitIDs = append(hookOptions.OldCommitIDs, t[0])
|
||||
hookOptions.NewCommitIDs = append(hookOptions.NewCommitIDs, t[1])
|
||||
hookOptions.RefFullNames = append(hookOptions.RefFullNames, t[2])
|
||||
}
|
||||
|
||||
hookOptions.GitPushOptions = make(map[string]string)
|
||||
|
||||
if hasPushOptions {
|
||||
for {
|
||||
rs, err = readPktLine(reader, pktLineTypeUnknow)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if rs.Type == pktLineTypeFlush {
|
||||
break
|
||||
}
|
||||
|
||||
kv := strings.SplitN(string(rs.Data), "=", 2)
|
||||
if len(kv) == 2 {
|
||||
hookOptions.GitPushOptions[kv[0]] = kv[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. run hook
|
||||
resp, err := private.HookProcReceive(ctx, repoUser, repoName, hookOptions)
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "run proc-receive hook failed :%v", err)
|
||||
}
|
||||
|
||||
// 4. response result to service
|
||||
// # a. OK, but has an alternate reference. The alternate reference name
|
||||
// # and other status can be given in option directives.
|
||||
// H: PKT-LINE(ok <ref>)
|
||||
// H: PKT-LINE(option refname <refname>)
|
||||
// H: PKT-LINE(option old-oid <old-oid>)
|
||||
// H: PKT-LINE(option new-oid <new-oid>)
|
||||
// H: PKT-LINE(option forced-update)
|
||||
// H: ... ...
|
||||
// H: flush-pkt
|
||||
// # b. NO, I reject it.
|
||||
// H: PKT-LINE(ng <ref> <reason>)
|
||||
// # c. Fall through, let 'receive-pack' to execute it.
|
||||
// H: PKT-LINE(ok <ref>)
|
||||
// H: PKT-LINE(option fall-through)
|
||||
|
||||
for _, rs := range resp.Results {
|
||||
if len(rs.Err) > 0 {
|
||||
err = writeDataPktLine(os.Stdout, []byte("ng "+rs.OriginalRef+" "+rs.Err))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if rs.IsNotMatched {
|
||||
err = writeDataPktLine(os.Stdout, []byte("ok "+rs.OriginalRef))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = writeDataPktLine(os.Stdout, []byte("option fall-through"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
err = writeDataPktLine(os.Stdout, []byte("ok "+rs.OriginalRef))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = writeDataPktLine(os.Stdout, []byte("option refname "+rs.Ref))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rs.OldOID != git.EmptySHA {
|
||||
err = writeDataPktLine(os.Stdout, []byte("option old-oid "+rs.OldOID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = writeDataPktLine(os.Stdout, []byte("option new-oid "+rs.NewOID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rs.IsForcePush {
|
||||
err = writeDataPktLine(os.Stdout, []byte("option forced-update"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
err = writeFlushPktLine(os.Stdout)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// git PKT-Line api
|
||||
// pktLineType message type of pkt-line
|
||||
type pktLineType int64
|
||||
|
||||
const (
|
||||
// UnKnow type
|
||||
pktLineTypeUnknow pktLineType = 0
|
||||
// flush-pkt "0000"
|
||||
pktLineTypeFlush pktLineType = iota
|
||||
// data line
|
||||
pktLineTypeData
|
||||
)
|
||||
|
||||
// gitPktLine pkt-line api
|
||||
type gitPktLine struct {
|
||||
Type pktLineType
|
||||
Length uint64
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func readPktLine(in *bufio.Reader, requestType pktLineType) (*gitPktLine, error) {
|
||||
var (
|
||||
err error
|
||||
r *gitPktLine
|
||||
)
|
||||
|
||||
// read prefix
|
||||
lengthBytes := make([]byte, 4)
|
||||
for i := 0; i < 4; i++ {
|
||||
lengthBytes[i], err = in.ReadByte()
|
||||
if err != nil {
|
||||
return nil, fail("Internal Server Error", "Pkt-Line: read stdin failed : %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
r = new(gitPktLine)
|
||||
r.Length, err = strconv.ParseUint(string(lengthBytes), 16, 32)
|
||||
if err != nil {
|
||||
return nil, fail("Internal Server Error", "Pkt-Line format is wrong :%v", err)
|
||||
}
|
||||
|
||||
if r.Length == 0 {
|
||||
if requestType == pktLineTypeData {
|
||||
return nil, fail("Internal Server Error", "Pkt-Line format is wrong")
|
||||
}
|
||||
r.Type = pktLineTypeFlush
|
||||
return r, nil
|
||||
}
|
||||
|
||||
if r.Length <= 4 || r.Length > 65520 || requestType == pktLineTypeFlush {
|
||||
return nil, fail("Internal Server Error", "Pkt-Line format is wrong")
|
||||
}
|
||||
|
||||
r.Data = make([]byte, r.Length-4)
|
||||
for i := range r.Data {
|
||||
r.Data[i], err = in.ReadByte()
|
||||
if err != nil {
|
||||
return nil, fail("Internal Server Error", "Pkt-Line: read stdin failed : %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
r.Type = pktLineTypeData
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func writeFlushPktLine(out io.Writer) error {
|
||||
l, err := out.Write([]byte("0000"))
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
if l != 4 {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeDataPktLine(out io.Writer, data []byte) error {
|
||||
hexchar := []byte("0123456789abcdef")
|
||||
hex := func(n uint64) byte {
|
||||
return hexchar[(n)&15]
|
||||
}
|
||||
|
||||
length := uint64(len(data) + 4)
|
||||
tmp := make([]byte, 4)
|
||||
tmp[0] = hex(length >> 12)
|
||||
tmp[1] = hex(length >> 8)
|
||||
tmp[2] = hex(length >> 4)
|
||||
tmp[3] = hex(length)
|
||||
|
||||
lr, err := out.Write(tmp)
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
if 4 != lr {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
|
||||
lr, err = out.Write(data)
|
||||
if err != nil {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
if int(length-4) != lr {
|
||||
return fail("Internal Server Error", "Pkt-Line response failed: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
41
cmd/hook_test.go
Normal file
41
cmd/hook_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPktLine(t *testing.T) {
|
||||
// test read
|
||||
s := strings.NewReader("0000")
|
||||
r := bufio.NewReader(s)
|
||||
result, err := readPktLine(r, pktLineTypeFlush)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, pktLineTypeFlush, result.Type)
|
||||
|
||||
s = strings.NewReader("0006a\n")
|
||||
r = bufio.NewReader(s)
|
||||
result, err = readPktLine(r, pktLineTypeData)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, pktLineTypeData, result.Type)
|
||||
assert.Equal(t, []byte("a\n"), result.Data)
|
||||
|
||||
// test write
|
||||
w := bytes.NewBuffer([]byte{})
|
||||
err = writeFlushPktLine(w)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []byte("0000"), w.Bytes())
|
||||
|
||||
w.Reset()
|
||||
err = writeDataPktLine(w, []byte("a\nb"))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []byte("0007a\nb"), w.Bytes())
|
||||
}
|
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
@@ -17,7 +18,7 @@ func runSendMail(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setting.NewContext()
|
||||
setting.LoadFromExisting()
|
||||
|
||||
if err := argsSet(c, "title"); err != nil {
|
||||
return err
|
||||
|
@@ -7,7 +7,7 @@ package cmd
|
||||
import (
|
||||
"context"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/migrations"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@@ -24,7 +24,10 @@ var CmdMigrate = cli.Command{
|
||||
}
|
||||
|
||||
func runMigrate(ctx *cli.Context) error {
|
||||
if err := initDB(); err != nil {
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(stdCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -32,9 +35,9 @@ func runMigrate(ctx *cli.Context) error {
|
||||
log.Info("AppWorkPath: %s", setting.AppWorkPath)
|
||||
log.Info("Custom path: %s", setting.CustomPath)
|
||||
log.Info("Log path: %s", setting.LogRootPath)
|
||||
setting.InitDBConfig()
|
||||
log.Info("Configuration file: %s", setting.CustomConf)
|
||||
|
||||
if err := models.NewEngine(context.Background(), migrations.Migrate); err != nil {
|
||||
if err := db.InitEngineWithMigration(context.Background(), migrations.Migrate); err != nil {
|
||||
log.Fatal("Failed to initialize ORM engine: %v", err)
|
||||
return err
|
||||
}
|
||||
|
@@ -10,7 +10,10 @@ import (
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/migrations"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/storage"
|
||||
@@ -78,7 +81,7 @@ var CmdMigrateStorage = cli.Command{
|
||||
}
|
||||
|
||||
func migrateAttachments(dstStorage storage.ObjectStorage) error {
|
||||
return models.IterateAttachment(func(attach *models.Attachment) error {
|
||||
return repo_model.IterateAttachment(func(attach *repo_model.Attachment) error {
|
||||
_, err := storage.Copy(dstStorage, attach.RelativePath(), storage.Attachments, attach.RelativePath())
|
||||
return err
|
||||
})
|
||||
@@ -92,21 +95,24 @@ func migrateLFS(dstStorage storage.ObjectStorage) error {
|
||||
}
|
||||
|
||||
func migrateAvatars(dstStorage storage.ObjectStorage) error {
|
||||
return models.IterateUser(func(user *models.User) error {
|
||||
return user_model.IterateUser(func(user *user_model.User) error {
|
||||
_, err := storage.Copy(dstStorage, user.CustomAvatarRelativePath(), storage.Avatars, user.CustomAvatarRelativePath())
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func migrateRepoAvatars(dstStorage storage.ObjectStorage) error {
|
||||
return models.IterateRepository(func(repo *models.Repository) error {
|
||||
return repo_model.IterateRepository(func(repo *repo_model.Repository) error {
|
||||
_, err := storage.Copy(dstStorage, repo.CustomAvatarRelativePath(), storage.RepoAvatars, repo.CustomAvatarRelativePath())
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func runMigrateStorage(ctx *cli.Context) error {
|
||||
if err := initDB(); err != nil {
|
||||
stdCtx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
if err := initDB(stdCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -114,9 +120,9 @@ func runMigrateStorage(ctx *cli.Context) error {
|
||||
log.Info("AppWorkPath: %s", setting.AppWorkPath)
|
||||
log.Info("Custom path: %s", setting.CustomPath)
|
||||
log.Info("Log path: %s", setting.LogRootPath)
|
||||
setting.InitDBConfig()
|
||||
log.Info("Configuration file: %s", setting.CustomConf)
|
||||
|
||||
if err := models.NewEngine(context.Background(), migrations.Migrate); err != nil {
|
||||
if err := db.InitEngineWithMigration(context.Background(), migrations.Migrate); err != nil {
|
||||
log.Fatal("Failed to initialize ORM engine: %v", err)
|
||||
return err
|
||||
}
|
||||
|
@@ -50,7 +50,7 @@ func runRestoreRepository(c *cli.Context) error {
|
||||
ctx, cancel := installSignals()
|
||||
defer cancel()
|
||||
|
||||
setting.NewContext()
|
||||
setting.LoadFromExisting()
|
||||
|
||||
statusCode, errStr := private.RestoreRepo(
|
||||
ctx,
|
||||
|
59
cmd/serv.go
59
cmd/serv.go
@@ -17,14 +17,18 @@ import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/pprof"
|
||||
"code.gitea.io/gitea/modules/private"
|
||||
"code.gitea.io/gitea/modules/process"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/services/lfs"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/kballard/go-shellquote"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
@@ -56,18 +60,18 @@ func setup(logPath string, debug bool) {
|
||||
} else {
|
||||
_ = log.NewLogger(1000, "console", "console", `{"level":"fatal","stacktracelevel":"NONE","stderr":true}`)
|
||||
}
|
||||
setting.NewContext()
|
||||
setting.LoadFromExisting()
|
||||
if debug {
|
||||
setting.RunMode = "dev"
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
allowedCommands = map[string]models.AccessMode{
|
||||
"git-upload-pack": models.AccessModeRead,
|
||||
"git-upload-archive": models.AccessModeRead,
|
||||
"git-receive-pack": models.AccessModeWrite,
|
||||
lfsAuthenticateVerb: models.AccessModeNone,
|
||||
allowedCommands = map[string]perm.AccessMode{
|
||||
"git-upload-pack": perm.AccessModeRead,
|
||||
"git-upload-archive": perm.AccessModeRead,
|
||||
"git-receive-pack": perm.AccessModeWrite,
|
||||
lfsAuthenticateVerb: perm.AccessModeNone,
|
||||
}
|
||||
alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
|
||||
)
|
||||
@@ -79,7 +83,7 @@ func fail(userMessage, logMessage string, args ...interface{}) error {
|
||||
fmt.Fprintln(os.Stderr, "Gitea:", userMessage)
|
||||
|
||||
if len(logMessage) > 0 {
|
||||
if !setting.IsProd() {
|
||||
if !setting.IsProd {
|
||||
fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
|
||||
}
|
||||
}
|
||||
@@ -89,7 +93,7 @@ func fail(userMessage, logMessage string, args ...interface{}) error {
|
||||
if len(logMessage) > 0 {
|
||||
_ = private.SSHLog(ctx, true, fmt.Sprintf(logMessage+": ", args...))
|
||||
}
|
||||
return cli.NewExitError(fmt.Sprintf("Gitea: %s", userMessage), 1)
|
||||
return cli.NewExitError("", 1)
|
||||
}
|
||||
|
||||
func runServ(c *cli.Context) error {
|
||||
@@ -127,9 +131,9 @@ func runServ(c *cli.Context) error {
|
||||
return fail("Internal error", "Failed to check provided key: %v", err)
|
||||
}
|
||||
switch key.Type {
|
||||
case models.KeyTypeDeploy:
|
||||
case asymkey_model.KeyTypeDeploy:
|
||||
println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Gitea does not provide shell access.")
|
||||
case models.KeyTypePrincipal:
|
||||
case asymkey_model.KeyTypePrincipal:
|
||||
println("Hi there! You've successfully authenticated with the principal " + key.Content + ", but Gitea does not provide shell access.")
|
||||
default:
|
||||
println("Hi there, " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Gitea does not provide shell access.")
|
||||
@@ -146,6 +150,13 @@ func runServ(c *cli.Context) error {
|
||||
}
|
||||
|
||||
if len(words) < 2 {
|
||||
if git.CheckGitVersionAtLeast("2.29") == nil {
|
||||
// for AGit Flow
|
||||
if cmd == "ssh_info" {
|
||||
fmt.Print(`{"type":"gitea","version":1}`)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fail("Too few arguments", "Too few arguments in cmd: %s", cmd)
|
||||
}
|
||||
|
||||
@@ -181,7 +192,7 @@ func runServ(c *cli.Context) error {
|
||||
return fail("Invalid repo name", "Invalid repo name: %s", reponame)
|
||||
}
|
||||
|
||||
if setting.EnablePprof || c.Bool("enable-pprof") {
|
||||
if c.Bool("enable-pprof") {
|
||||
if err := os.MkdirAll(setting.PprofDataPath, os.ModePerm); err != nil {
|
||||
return fail("Error while trying to create PPROF_DATA_PATH", "Error while trying to create PPROF_DATA_PATH: %v", err)
|
||||
}
|
||||
@@ -206,9 +217,9 @@ func runServ(c *cli.Context) error {
|
||||
|
||||
if verb == lfsAuthenticateVerb {
|
||||
if lfsVerb == "upload" {
|
||||
requestedMode = models.AccessModeWrite
|
||||
requestedMode = perm.AccessModeWrite
|
||||
} else if lfsVerb == "download" {
|
||||
requestedMode = models.AccessModeRead
|
||||
requestedMode = perm.AccessModeRead
|
||||
} else {
|
||||
return fail("Unknown LFS verb", "Unknown lfs verb %s", lfsVerb)
|
||||
}
|
||||
@@ -233,17 +244,18 @@ func runServ(c *cli.Context) error {
|
||||
os.Setenv(models.EnvPusherID, strconv.FormatInt(results.UserID, 10))
|
||||
os.Setenv(models.EnvRepoID, strconv.FormatInt(results.RepoID, 10))
|
||||
os.Setenv(models.EnvPRID, fmt.Sprintf("%d", 0))
|
||||
os.Setenv(models.EnvIsDeployKey, fmt.Sprintf("%t", results.IsDeployKey))
|
||||
os.Setenv(models.EnvDeployKeyID, fmt.Sprintf("%d", results.DeployKeyID))
|
||||
os.Setenv(models.EnvKeyID, fmt.Sprintf("%d", results.KeyID))
|
||||
os.Setenv(models.EnvAppURL, setting.AppURL)
|
||||
|
||||
//LFS token authentication
|
||||
// LFS token authentication
|
||||
if verb == lfsAuthenticateVerb {
|
||||
url := fmt.Sprintf("%s%s/%s.git/info/lfs", setting.AppURL, url.PathEscape(results.OwnerName), url.PathEscape(results.RepoName))
|
||||
|
||||
now := time.Now()
|
||||
claims := lfs.Claims{
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
// FIXME: we need to migrate to RegisteredClaims
|
||||
StandardClaims: jwt.StandardClaims{ // nolint
|
||||
ExpiresAt: now.Add(setting.LFS.HTTPAuthExpiry).Unix(),
|
||||
NotBefore: now.Unix(),
|
||||
},
|
||||
@@ -265,7 +277,6 @@ func runServ(c *cli.Context) error {
|
||||
}
|
||||
tokenAuthentication.Header["Authorization"] = fmt.Sprintf("Bearer %s", tokenString)
|
||||
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
err = enc.Encode(tokenAuthentication)
|
||||
if err != nil {
|
||||
@@ -287,6 +298,16 @@ func runServ(c *cli.Context) error {
|
||||
gitcmd = exec.CommandContext(ctx, verb, repoPath)
|
||||
}
|
||||
|
||||
// Check if setting.RepoRootPath exists. It could be the case that it doesn't exist, this can happen when
|
||||
// `[repository]` `ROOT` is a relative path and $GITEA_WORK_DIR isn't passed to the SSH connection.
|
||||
if _, err := os.Stat(setting.RepoRootPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return fail("Incorrect configuration.",
|
||||
"Directory `[repository]` `ROOT` was not found, please check if $GITEA_WORK_DIR is passed to the SSH connection or make `[repository]` `ROOT` an absolute value.")
|
||||
}
|
||||
}
|
||||
|
||||
process.SetSysProcAttribute(gitcmd)
|
||||
gitcmd.Dir = setting.RepoRootPath
|
||||
gitcmd.Stdout = os.Stdout
|
||||
gitcmd.Stdin = os.Stdin
|
||||
|
47
cmd/web.go
47
cmd/web.go
@@ -9,17 +9,17 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
|
||||
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/routers"
|
||||
"code.gitea.io/gitea/routers/install"
|
||||
|
||||
context2 "github.com/gorilla/context"
|
||||
"github.com/urfave/cli"
|
||||
ini "gopkg.in/ini.v1"
|
||||
)
|
||||
@@ -71,7 +71,7 @@ func runHTTPRedirector() {
|
||||
http.Redirect(w, r, target, http.StatusTemporaryRedirect)
|
||||
})
|
||||
|
||||
var err = runHTTP("tcp", source, "HTTP Redirector", context2.ClearHandler(handler))
|
||||
var err = runHTTP("tcp", source, "HTTP Redirector", handler)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("Failed to start port redirection: %v", err)
|
||||
@@ -86,6 +86,11 @@ func runWeb(ctx *cli.Context) error {
|
||||
_ = log.DelLogger("console")
|
||||
log.NewLogger(0, "console", "console", fmt.Sprintf(`{"level": "fatal", "colorize": %t, "stacktraceLevel": "none"}`, log.CanColorStdout))
|
||||
}
|
||||
defer func() {
|
||||
if panicked := recover(); panicked != nil {
|
||||
log.Fatal("PANIC: %v\n%s", panicked, string(log.Stack(2)))
|
||||
}
|
||||
}()
|
||||
|
||||
managerCtx, cancel := context.WithCancel(context.Background())
|
||||
graceful.InitManager(managerCtx)
|
||||
@@ -119,6 +124,10 @@ func runWeb(ctx *cli.Context) error {
|
||||
}
|
||||
c := install.Routes()
|
||||
err := listen(c, false)
|
||||
if err != nil {
|
||||
log.Critical("Unable to open listener for installer. Is Gitea already running?")
|
||||
graceful.GetManager().DoGracefulShutdown()
|
||||
}
|
||||
select {
|
||||
case <-graceful.GetManager().IsShutdown():
|
||||
<-graceful.GetManager().Done()
|
||||
@@ -140,7 +149,15 @@ func runWeb(ctx *cli.Context) error {
|
||||
|
||||
log.Info("Global init")
|
||||
// Perform global initialization
|
||||
routers.GlobalInit(graceful.GetManager().HammerContext())
|
||||
setting.LoadFromExisting()
|
||||
routers.GlobalInitInstalled(graceful.GetManager().HammerContext())
|
||||
|
||||
// We check that AppDataPath exists here (it should have been created during installation)
|
||||
// We can't check it in `GlobalInitInstalled`, because some integration tests
|
||||
// use cmd -> GlobalInitInstalled, but the AppDataPath doesn't exist during those tests.
|
||||
if _, err := os.Stat(setting.AppDataPath); err != nil {
|
||||
log.Fatal("Can not find APP_DATA_PATH '%s'", setting.AppDataPath)
|
||||
}
|
||||
|
||||
// Override the provided port number within the configuration
|
||||
if ctx.IsSet("port") {
|
||||
@@ -163,7 +180,7 @@ func setPort(port string) error {
|
||||
setting.HTTPPort = port
|
||||
|
||||
switch setting.Protocol {
|
||||
case setting.UnixSocket:
|
||||
case setting.HTTPUnix:
|
||||
case setting.FCGI:
|
||||
case setting.FCGIUnix:
|
||||
default:
|
||||
@@ -185,10 +202,14 @@ func setPort(port string) error {
|
||||
|
||||
func listen(m http.Handler, handleRedirector bool) error {
|
||||
listenAddr := setting.HTTPAddr
|
||||
if setting.Protocol != setting.UnixSocket && setting.Protocol != setting.FCGIUnix {
|
||||
if setting.Protocol != setting.HTTPUnix && setting.Protocol != setting.FCGIUnix {
|
||||
listenAddr = net.JoinHostPort(listenAddr, setting.HTTPPort)
|
||||
}
|
||||
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
|
||||
// This can be useful for users, many users do wrong to their config and get strange behaviors behind a reverse-proxy.
|
||||
// A user may fix the configuration mistake when he sees this log.
|
||||
// And this is also very helpful to maintainers to provide help to users to resolve their configuration problems.
|
||||
log.Info("AppURL(ROOT_URL): %s", setting.AppURL)
|
||||
|
||||
if setting.LFS.StartServer {
|
||||
log.Info("LFS server enabled")
|
||||
@@ -200,10 +221,10 @@ func listen(m http.Handler, handleRedirector bool) error {
|
||||
if handleRedirector {
|
||||
NoHTTPRedirector()
|
||||
}
|
||||
err = runHTTP("tcp", listenAddr, "Web", context2.ClearHandler(m))
|
||||
err = runHTTP("tcp", listenAddr, "Web", m)
|
||||
case setting.HTTPS:
|
||||
if setting.EnableLetsEncrypt {
|
||||
err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, context2.ClearHandler(m))
|
||||
err = runLetsEncrypt(listenAddr, setting.Domain, setting.LetsEncryptDirectory, setting.LetsEncryptEmail, m)
|
||||
break
|
||||
}
|
||||
if handleRedirector {
|
||||
@@ -213,22 +234,22 @@ func listen(m http.Handler, handleRedirector bool) error {
|
||||
NoHTTPRedirector()
|
||||
}
|
||||
}
|
||||
err = runHTTPS("tcp", listenAddr, "Web", setting.CertFile, setting.KeyFile, context2.ClearHandler(m))
|
||||
err = runHTTPS("tcp", listenAddr, "Web", setting.CertFile, setting.KeyFile, m)
|
||||
case setting.FCGI:
|
||||
if handleRedirector {
|
||||
NoHTTPRedirector()
|
||||
}
|
||||
err = runFCGI("tcp", listenAddr, "FCGI Web", context2.ClearHandler(m))
|
||||
case setting.UnixSocket:
|
||||
err = runFCGI("tcp", listenAddr, "FCGI Web", m)
|
||||
case setting.HTTPUnix:
|
||||
if handleRedirector {
|
||||
NoHTTPRedirector()
|
||||
}
|
||||
err = runHTTP("unix", listenAddr, "Web", context2.ClearHandler(m))
|
||||
err = runHTTP("unix", listenAddr, "Web", m)
|
||||
case setting.FCGIUnix:
|
||||
if handleRedirector {
|
||||
NoHTTPRedirector()
|
||||
}
|
||||
err = runFCGI("unix", listenAddr, "Web", context2.ClearHandler(m))
|
||||
err = runFCGI("unix", listenAddr, "Web", m)
|
||||
default:
|
||||
log.Fatal("Invalid protocol: %s", setting.Protocol)
|
||||
}
|
||||
|
@@ -5,7 +5,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/fcgi"
|
||||
@@ -20,14 +19,6 @@ func runHTTP(network, listenAddr, name string, m http.Handler) error {
|
||||
return graceful.HTTPListenAndServe(network, listenAddr, name, m)
|
||||
}
|
||||
|
||||
func runHTTPS(network, listenAddr, name, certFile, keyFile string, m http.Handler) error {
|
||||
return graceful.HTTPListenAndServeTLS(network, listenAddr, name, certFile, keyFile, m)
|
||||
}
|
||||
|
||||
func runHTTPSWithTLSConfig(network, listenAddr, name string, tlsConfig *tls.Config, m http.Handler) error {
|
||||
return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m)
|
||||
}
|
||||
|
||||
// NoHTTPRedirector tells our cleanup routine that we will not be using a fallback http redirector
|
||||
func NoHTTPRedirector() {
|
||||
graceful.GetManager().InformCleanup()
|
||||
|
192
cmd/web_https.go
Normal file
192
cmd/web_https.go
Normal file
@@ -0,0 +1,192 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/klauspost/cpuid/v2"
|
||||
)
|
||||
|
||||
var tlsVersionStringMap = map[string]uint16{
|
||||
"": tls.VersionTLS12, // Default to tls.VersionTLS12
|
||||
"tlsv1.0": tls.VersionTLS10,
|
||||
"tlsv1.1": tls.VersionTLS11,
|
||||
"tlsv1.2": tls.VersionTLS12,
|
||||
"tlsv1.3": tls.VersionTLS13,
|
||||
}
|
||||
|
||||
func toTLSVersion(version string) uint16 {
|
||||
tlsVersion, ok := tlsVersionStringMap[strings.TrimSpace(strings.ToLower(version))]
|
||||
if !ok {
|
||||
log.Warn("Unknown tls version: %s", version)
|
||||
return 0
|
||||
}
|
||||
return tlsVersion
|
||||
}
|
||||
|
||||
var curveStringMap = map[string]tls.CurveID{
|
||||
"x25519": tls.X25519,
|
||||
"p256": tls.CurveP256,
|
||||
"p384": tls.CurveP384,
|
||||
"p521": tls.CurveP521,
|
||||
}
|
||||
|
||||
func toCurvePreferences(preferences []string) []tls.CurveID {
|
||||
ids := make([]tls.CurveID, 0, len(preferences))
|
||||
for _, pref := range preferences {
|
||||
id, ok := curveStringMap[strings.TrimSpace(strings.ToLower(pref))]
|
||||
if !ok {
|
||||
log.Warn("Unknown curve: %s", pref)
|
||||
}
|
||||
if id != 0 {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
var cipherStringMap = map[string]uint16{
|
||||
"rsa_with_rc4_128_sha": tls.TLS_RSA_WITH_RC4_128_SHA,
|
||||
"rsa_with_3des_ede_cbc_sha": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
"rsa_with_aes_128_cbc_sha": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
"rsa_with_aes_256_cbc_sha": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
"rsa_with_aes_128_cbc_sha256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256,
|
||||
"rsa_with_aes_128_gcm_sha256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
|
||||
"rsa_with_aes_256_gcm_sha384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
"ecdhe_ecdsa_with_rc4_128_sha": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
|
||||
"ecdhe_ecdsa_with_aes_128_cbc_sha": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
"ecdhe_ecdsa_with_aes_256_cbc_sha": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
"ecdhe_rsa_with_rc4_128_sha": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
|
||||
"ecdhe_rsa_with_3des_ede_cbc_sha": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
"ecdhe_rsa_with_aes_128_cbc_sha": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
"ecdhe_rsa_with_aes_256_cbc_sha": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
"ecdhe_ecdsa_with_aes_128_cbc_sha256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
"ecdhe_rsa_with_aes_128_cbc_sha256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
"ecdhe_rsa_with_aes_128_gcm_sha256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
"ecdhe_ecdsa_with_aes_128_gcm_sha256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
"ecdhe_rsa_with_aes_256_gcm_sha384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
"ecdhe_ecdsa_with_aes_256_gcm_sha384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
"ecdhe_rsa_with_chacha20_poly1305_sha256": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
"ecdhe_ecdsa_with_chacha20_poly1305_sha256": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
"ecdhe_rsa_with_chacha20_poly1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
"ecdhe_ecdsa_with_chacha20_poly1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
"aes_128_gcm_sha256": tls.TLS_AES_128_GCM_SHA256,
|
||||
"aes_256_gcm_sha384": tls.TLS_AES_256_GCM_SHA384,
|
||||
"chacha20_poly1305_sha256": tls.TLS_CHACHA20_POLY1305_SHA256,
|
||||
}
|
||||
|
||||
func toTLSCiphers(cipherStrings []string) []uint16 {
|
||||
ciphers := make([]uint16, 0, len(cipherStrings))
|
||||
for _, cipherString := range cipherStrings {
|
||||
cipher, ok := cipherStringMap[strings.TrimSpace(strings.ToLower(cipherString))]
|
||||
if !ok {
|
||||
log.Warn("Unknown cipher: %s", cipherString)
|
||||
}
|
||||
if cipher != 0 {
|
||||
ciphers = append(ciphers, cipher)
|
||||
}
|
||||
}
|
||||
|
||||
return ciphers
|
||||
}
|
||||
|
||||
// defaultCiphers uses hardware support to check if AES is specifically
|
||||
// supported by the CPU.
|
||||
//
|
||||
// If AES is supported AES ciphers will be preferred over ChaCha based ciphers
|
||||
// (This code is directly inspired by the certmagic code.)
|
||||
func defaultCiphers() []uint16 {
|
||||
if cpuid.CPU.Supports(cpuid.AESNI) {
|
||||
return defaultCiphersAESfirst
|
||||
}
|
||||
return defaultCiphersChaChaFirst
|
||||
}
|
||||
|
||||
var (
|
||||
defaultCiphersAES = []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
}
|
||||
|
||||
defaultCiphersChaCha = []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
}
|
||||
|
||||
defaultCiphersAESfirst = append(defaultCiphersAES, defaultCiphersChaCha...)
|
||||
defaultCiphersChaChaFirst = append(defaultCiphersChaCha, defaultCiphersAES...)
|
||||
)
|
||||
|
||||
// runHTTPs listens on the provided network address and then calls
|
||||
// Serve to handle requests on incoming TLS connections.
|
||||
//
|
||||
// Filenames containing a certificate and matching private key for the server must
|
||||
// be provided. If the certificate is signed by a certificate authority, the
|
||||
// certFile should be the concatenation of the server's certificate followed by the
|
||||
// CA's certificate.
|
||||
func runHTTPS(network, listenAddr, name, certFile, keyFile string, m http.Handler) error {
|
||||
tlsConfig := &tls.Config{}
|
||||
if tlsConfig.NextProtos == nil {
|
||||
tlsConfig.NextProtos = []string{"h2", "http/1.1"}
|
||||
}
|
||||
|
||||
if version := toTLSVersion(setting.SSLMinimumVersion); version != 0 {
|
||||
tlsConfig.MinVersion = version
|
||||
}
|
||||
if version := toTLSVersion(setting.SSLMaximumVersion); version != 0 {
|
||||
tlsConfig.MaxVersion = version
|
||||
}
|
||||
|
||||
// Set curve preferences
|
||||
tlsConfig.CurvePreferences = []tls.CurveID{
|
||||
tls.X25519,
|
||||
tls.CurveP256,
|
||||
}
|
||||
if curves := toCurvePreferences(setting.SSLCurvePreferences); len(curves) > 0 {
|
||||
tlsConfig.CurvePreferences = curves
|
||||
}
|
||||
|
||||
// Set cipher suites
|
||||
tlsConfig.CipherSuites = defaultCiphers()
|
||||
if ciphers := toTLSCiphers(setting.SSLCipherSuites); len(ciphers) > 0 {
|
||||
tlsConfig.CipherSuites = ciphers
|
||||
}
|
||||
|
||||
tlsConfig.Certificates = make([]tls.Certificate, 1)
|
||||
|
||||
certPEMBlock, err := os.ReadFile(certFile)
|
||||
if err != nil {
|
||||
log.Error("Failed to load https cert file %s for %s:%s: %v", certFile, network, listenAddr, err)
|
||||
return err
|
||||
}
|
||||
|
||||
keyPEMBlock, err := os.ReadFile(keyFile)
|
||||
if err != nil {
|
||||
log.Error("Failed to load https key file %s for %s:%s: %v", keyFile, network, listenAddr, err)
|
||||
return err
|
||||
}
|
||||
|
||||
tlsConfig.Certificates[0], err = tls.X509KeyPair(certPEMBlock, keyPEMBlock)
|
||||
if err != nil {
|
||||
log.Error("Failed to create certificate from cert file %s and key file %s for %s:%s: %v", certFile, keyFile, network, listenAddr, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m)
|
||||
}
|
||||
|
||||
func runHTTPSWithTLSConfig(network, listenAddr, name string, tlsConfig *tls.Config, m http.Handler) error {
|
||||
return graceful.HTTPListenAndServeTLSConfig(network, listenAddr, name, tlsConfig, m)
|
||||
}
|
@@ -9,11 +9,11 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/caddyserver/certmagic"
|
||||
context2 "github.com/gorilla/context"
|
||||
)
|
||||
|
||||
func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler) error {
|
||||
@@ -48,7 +48,7 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler)
|
||||
magic.Issuers = []certmagic.Issuer{myACME}
|
||||
|
||||
// this obtains certificates or renews them if necessary
|
||||
err := magic.ManageSync([]string{domain})
|
||||
err := magic.ManageSync(graceful.GetManager().HammerContext(), []string{domain})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -56,6 +56,23 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler)
|
||||
tlsConfig := magic.TLSConfig()
|
||||
tlsConfig.NextProtos = append(tlsConfig.NextProtos, "h2")
|
||||
|
||||
if version := toTLSVersion(setting.SSLMinimumVersion); version != 0 {
|
||||
tlsConfig.MinVersion = version
|
||||
}
|
||||
if version := toTLSVersion(setting.SSLMaximumVersion); version != 0 {
|
||||
tlsConfig.MaxVersion = version
|
||||
}
|
||||
|
||||
// Set curve preferences
|
||||
if curves := toCurvePreferences(setting.SSLCurvePreferences); len(curves) > 0 {
|
||||
tlsConfig.CurvePreferences = curves
|
||||
}
|
||||
|
||||
// Set cipher suites
|
||||
if ciphers := toTLSCiphers(setting.SSLCipherSuites); len(ciphers) > 0 {
|
||||
tlsConfig.CipherSuites = ciphers
|
||||
}
|
||||
|
||||
if enableHTTPChallenge {
|
||||
go func() {
|
||||
log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect)
|
||||
@@ -67,7 +84,7 @@ func runLetsEncrypt(listenAddr, domain, directory, email string, m http.Handler)
|
||||
}()
|
||||
}
|
||||
|
||||
return runHTTPSWithTLSConfig("tcp", listenAddr, "Web", tlsConfig, context2.ClearHandler(m))
|
||||
return runHTTPSWithTLSConfig("tcp", listenAddr, "Web", tlsConfig, m)
|
||||
}
|
||||
|
||||
func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@@ -156,6 +156,7 @@ func runEnvironmentToIni(c *cli.Context) error {
|
||||
destination = setting.CustomConf
|
||||
}
|
||||
if destination != setting.CustomConf || changed {
|
||||
log.Info("Settings saved to: %q", destination)
|
||||
err = cfg.SaveTo(destination)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -224,7 +225,6 @@ func DecodeSectionKey(encoded string) (string, string) {
|
||||
if !inKey {
|
||||
if splitter := strings.Index(remaining, "__"); splitter > -1 {
|
||||
section += remaining[:splitter]
|
||||
inKey = true
|
||||
key += remaining[splitter+2:]
|
||||
} else {
|
||||
section += remaining
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
########################################################################
|
||||
# This script some defaults for gitea to run in a FHS compliant manner #
|
||||
########################################################################
|
||||
#############################################################################
|
||||
# This script sets some defaults for gitea to run in a FHS compliant manner #
|
||||
#############################################################################
|
||||
|
||||
# It assumes that you place this script as gitea in /usr/bin
|
||||
#
|
||||
@@ -33,10 +33,8 @@ for i in "$@"; do
|
||||
done
|
||||
|
||||
if [ -z "$APP_INI_SET" ]; then
|
||||
CONF_ARG="-c \"$APP_INI\""
|
||||
CONF_ARG=("-c" "${GITEA_APP_INI:-$APP_INI}")
|
||||
fi
|
||||
|
||||
# Provide FHS compliant defaults to
|
||||
GITEA_WORK_DIR="${GITEA_WORK_DIR:-$WORK_DIR}" "$GITEA" $CONF_ARG "$@"
|
||||
|
||||
|
||||
# Provide FHS compliant defaults
|
||||
GITEA_WORK_DIR="${GITEA_WORK_DIR:-$WORK_DIR}" exec -a "$0" "$GITEA" "${CONF_ARG[@]}" "$@"
|
||||
|
@@ -6,11 +6,11 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
)
|
||||
|
||||
// To generate derivative fixtures, execute the following from Gitea's repository base dir:
|
||||
@@ -31,11 +31,13 @@ var (
|
||||
func main() {
|
||||
pathToGiteaRoot := "."
|
||||
fixturesDir = filepath.Join(pathToGiteaRoot, "models", "fixtures")
|
||||
if err := models.CreateTestEngine(fixturesDir); err != nil {
|
||||
if err := unittest.CreateTestEngine(unittest.FixturesOptions{
|
||||
Dir: fixturesDir,
|
||||
}); err != nil {
|
||||
fmt.Printf("CreateTestEngine: %+v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := models.PrepareTestDatabase(); err != nil {
|
||||
if err := unittest.PrepareTestDatabase(); err != nil {
|
||||
fmt.Printf("PrepareTestDatabase: %+v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
@@ -64,7 +66,7 @@ func generate(name string) error {
|
||||
return err
|
||||
}
|
||||
path := filepath.Join(fixturesDir, name+".yml")
|
||||
if err := ioutil.WriteFile(path, []byte(data), 0644); err != nil {
|
||||
if err := os.WriteFile(path, []byte(data), 0644); err != nil {
|
||||
return fmt.Errorf("%s: %+v", path, err)
|
||||
}
|
||||
fmt.Printf("%s created.\n", path)
|
||||
|
2
contrib/gitea-monitoring-mixin/.gitignore
vendored
Normal file
2
contrib/gitea-monitoring-mixin/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
dashboards_out
|
||||
vendor
|
31
contrib/gitea-monitoring-mixin/Makefile
Normal file
31
contrib/gitea-monitoring-mixin/Makefile
Normal file
@@ -0,0 +1,31 @@
|
||||
JSONNET_FMT := jsonnetfmt -n 2 --max-blank-lines 1 --string-style s --comment-style s
|
||||
|
||||
.PHONY: all
|
||||
all: build dashboards_out
|
||||
|
||||
vendor: jsonnetfile.json
|
||||
jb install
|
||||
|
||||
.PHONY: build
|
||||
build: vendor
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \
|
||||
xargs -n 1 -- $(JSONNET_FMT) -i
|
||||
|
||||
.PHONY: lint
|
||||
lint: build
|
||||
find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \
|
||||
while read f; do \
|
||||
$(JSONNET_FMT) "$$f" | diff -u "$$f" -; \
|
||||
done
|
||||
mixtool lint mixin.libsonnet
|
||||
|
||||
dashboards_out: mixin.libsonnet config.libsonnet $(wildcard dashboards/*)
|
||||
@mkdir -p dashboards_out
|
||||
jsonnet -J vendor -m dashboards_out lib/dashboards.jsonnet
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf dashboards_out
|
33
contrib/gitea-monitoring-mixin/README.md
Normal file
33
contrib/gitea-monitoring-mixin/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Gitea Mixin
|
||||
|
||||
Gitea Mixin is a set of configurable Grafana dashboards based on the metrics exported by the Gitea built-in metrics endpoint.
|
||||
|
||||
## Generate config files
|
||||
|
||||
You can manually generate dashboards, but first you should install some tools:
|
||||
|
||||
```bash
|
||||
go install github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@latest
|
||||
go install github.com/google/go-jsonnet/cmd/jsonnet@latest
|
||||
# or in brew: brew install go-jsonnet
|
||||
```
|
||||
|
||||
For linting and formatting, you would also need `mixtool` and `jsonnetfmt` installed. If you
|
||||
have a working Go development environment, it's easiest to run the following:
|
||||
|
||||
```bash
|
||||
go install github.com/monitoring-mixins/mixtool/cmd/mixtool@latest
|
||||
go install github.com/google/go-jsonnet/cmd/jsonnetfmt@latest
|
||||
```
|
||||
|
||||
The files in `dashboards_out` need to be imported
|
||||
into your Grafana server. The exact details will be depending on your environment.
|
||||
|
||||
Edit `config.libsonnet` if required and then build JSON dashboard files for Grafana:
|
||||
|
||||
```bash
|
||||
make
|
||||
```
|
||||
|
||||
For more advanced uses of mixins, see
|
||||
https://github.com/monitoring-mixins/docs.
|
99
contrib/gitea-monitoring-mixin/config.libsonnet
Normal file
99
contrib/gitea-monitoring-mixin/config.libsonnet
Normal file
@@ -0,0 +1,99 @@
|
||||
{
|
||||
_config+:: {
|
||||
local c = self,
|
||||
dashboardNamePrefix: 'Gitea',
|
||||
dashboardTags: ['gitea'],
|
||||
dashboardPeriod: 'now-1h',
|
||||
dashboardTimezone: 'default',
|
||||
dashboardRefresh: '1m',
|
||||
|
||||
// please see https://docs.gitea.io/en-us/config-cheat-sheet/#metrics-metrics
|
||||
// Show issue by repository metrics with format gitea_issues_by_repository{repository="org/repo"} 5.
|
||||
// Requires Gitea 1.16.0 with ENABLED_ISSUE_BY_REPOSITORY set to true.
|
||||
showIssuesByRepository: true,
|
||||
// Show graphs for issue by label metrics with format gitea_issues_by_label{label="bug"} 2.
|
||||
// Requires Gitea 1.16.0 with ENABLED_ISSUE_BY_LABEL set to true.
|
||||
showIssuesByLabel: true,
|
||||
|
||||
// Requires Gitea 1.16.0.
|
||||
showIssuesOpenClose: true,
|
||||
|
||||
// add or remove metrics from dashboard
|
||||
giteaStatMetrics:
|
||||
[
|
||||
{
|
||||
name: 'gitea_organizations',
|
||||
description: 'Organizations',
|
||||
},
|
||||
{
|
||||
name: 'gitea_teams',
|
||||
description: 'Teams',
|
||||
},
|
||||
{
|
||||
name: 'gitea_users',
|
||||
description: 'Users',
|
||||
},
|
||||
{
|
||||
name: 'gitea_repositories',
|
||||
description: 'Repositories',
|
||||
},
|
||||
{
|
||||
name: 'gitea_milestones',
|
||||
description: 'Milestones',
|
||||
},
|
||||
{
|
||||
name: 'gitea_stars',
|
||||
description: 'Stars',
|
||||
},
|
||||
{
|
||||
name: 'gitea_releases',
|
||||
description: 'Releases',
|
||||
},
|
||||
]
|
||||
+
|
||||
if c.showIssuesOpenClose then
|
||||
[
|
||||
{
|
||||
name: 'gitea_issues_open',
|
||||
description: 'Issues opened',
|
||||
},
|
||||
{
|
||||
name: 'gitea_issues_closed',
|
||||
description: 'Issues closed',
|
||||
},
|
||||
] else
|
||||
[
|
||||
{
|
||||
name: 'gitea_issues',
|
||||
description: 'Issues',
|
||||
},
|
||||
],
|
||||
//set this for using label colors on graphs
|
||||
issueLabels: [
|
||||
{
|
||||
label: 'bug',
|
||||
color: '#ee0701',
|
||||
},
|
||||
{
|
||||
label: 'duplicate',
|
||||
color: '#cccccc',
|
||||
},
|
||||
{
|
||||
label: 'invalid',
|
||||
color: '#e6e6e6',
|
||||
},
|
||||
{
|
||||
label: 'enhancement',
|
||||
color: '#84b6eb',
|
||||
},
|
||||
{
|
||||
label: 'help wanted',
|
||||
color: '#128a0c',
|
||||
},
|
||||
{
|
||||
label: 'question',
|
||||
color: '#cc317c',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
@@ -0,0 +1 @@
|
||||
(import 'overview.libsonnet')
|
461
contrib/gitea-monitoring-mixin/dashboards/overview.libsonnet
Normal file
461
contrib/gitea-monitoring-mixin/dashboards/overview.libsonnet
Normal file
@@ -0,0 +1,461 @@
|
||||
local grafana = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet';
|
||||
local prometheus = grafana.prometheus;
|
||||
|
||||
local addIssueLabelsOverrides(labels) =
|
||||
{
|
||||
fieldConfig+: {
|
||||
overrides+: [
|
||||
{
|
||||
matcher: {
|
||||
id: 'byRegexp',
|
||||
options: label.label,
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
id: 'color',
|
||||
value: {
|
||||
fixedColor: label.color,
|
||||
mode: 'fixed',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
for label in labels
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
{
|
||||
|
||||
grafanaDashboards+:: {
|
||||
|
||||
local giteaSelector = 'job="$job", instance="$instance"',
|
||||
local giteaStatsPanel =
|
||||
grafana.statPanel.new(
|
||||
'Gitea stats',
|
||||
datasource='$datasource',
|
||||
reducerFunction='lastNotNull',
|
||||
graphMode='none',
|
||||
colorMode='value',
|
||||
)
|
||||
.addTargets(
|
||||
[
|
||||
prometheus.target(expr='%s{%s}' % [metric.name, giteaSelector], legendFormat=metric.description, intervalFactor=10)
|
||||
for metric in $._config.giteaStatMetrics
|
||||
]
|
||||
)
|
||||
+ {
|
||||
fieldConfig+: {
|
||||
defaults+: {
|
||||
color: {
|
||||
fixedColor: 'blue',
|
||||
mode: 'fixed',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
local giteaUptimePanel =
|
||||
grafana.statPanel.new(
|
||||
'Uptime',
|
||||
datasource='$datasource',
|
||||
reducerFunction='last',
|
||||
graphMode='area',
|
||||
colorMode='value',
|
||||
)
|
||||
.addTarget(prometheus.target(expr='time()-process_start_time_seconds{%s}' % giteaSelector, intervalFactor=1))
|
||||
+ {
|
||||
fieldConfig+: {
|
||||
defaults+: {
|
||||
color: {
|
||||
fixedColor: 'blue',
|
||||
mode: 'fixed',
|
||||
},
|
||||
unit: 's',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
local giteaMemoryPanel =
|
||||
grafana.graphPanel.new(
|
||||
'Memory usage',
|
||||
datasource='$datasource'
|
||||
)
|
||||
.addTarget(prometheus.target(expr='process_resident_memory_bytes{%s}' % giteaSelector, intervalFactor=2))
|
||||
+ {
|
||||
type: 'timeseries',
|
||||
options+: {
|
||||
tooltip: {
|
||||
mode: 'multi',
|
||||
},
|
||||
legend+: {
|
||||
displayMode: 'hidden',
|
||||
},
|
||||
},
|
||||
fieldConfig+: {
|
||||
defaults+: {
|
||||
custom+: {
|
||||
lineInterpolation: 'smooth',
|
||||
fillOpacity: 15,
|
||||
},
|
||||
color: {
|
||||
fixedColor: 'green',
|
||||
mode: 'fixed',
|
||||
},
|
||||
unit: 'decbytes',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
local giteaCpuPanel =
|
||||
grafana.graphPanel.new(
|
||||
'CPU usage',
|
||||
datasource='$datasource'
|
||||
)
|
||||
.addTarget(prometheus.target(expr='rate(process_cpu_seconds_total{%s}[$__rate_interval])*100' % giteaSelector, intervalFactor=2))
|
||||
+ {
|
||||
type: 'timeseries',
|
||||
options+: {
|
||||
tooltip: {
|
||||
mode: 'multi',
|
||||
},
|
||||
legend+: {
|
||||
displayMode: 'hidden',
|
||||
},
|
||||
},
|
||||
fieldConfig+: {
|
||||
defaults+: {
|
||||
custom+: {
|
||||
lineInterpolation: 'smooth',
|
||||
gradientMode: 'scheme',
|
||||
fillOpacity: 15,
|
||||
axisSoftMin: 0,
|
||||
axisSoftMax: 0,
|
||||
},
|
||||
color: {
|
||||
mode: 'continuous-GrYlRd', // from green to red (100%)
|
||||
},
|
||||
unit: 'percent',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
matcher: {
|
||||
id: 'byRegexp',
|
||||
options: '.+',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
id: 'max',
|
||||
value: 100,
|
||||
},
|
||||
{
|
||||
id: 'min',
|
||||
value: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
local giteaFileDescriptorsPanel =
|
||||
grafana.graphPanel.new(
|
||||
'File descriptors usage',
|
||||
datasource='$datasource',
|
||||
)
|
||||
.addTarget(prometheus.target(expr='process_open_fds{%s}' % giteaSelector, intervalFactor=2))
|
||||
.addTarget(prometheus.target(expr='process_max_fds{%s}' % giteaSelector, intervalFactor=2))
|
||||
.addSeriesOverride(
|
||||
{
|
||||
alias: '/process_max_fds.+/',
|
||||
color: '#F2495C', // red
|
||||
dashes: true,
|
||||
fill: 0,
|
||||
},
|
||||
)
|
||||
+ {
|
||||
type: 'timeseries',
|
||||
options+: {
|
||||
tooltip: {
|
||||
mode: 'multi',
|
||||
},
|
||||
legend+: {
|
||||
displayMode: 'hidden',
|
||||
},
|
||||
},
|
||||
fieldConfig+: {
|
||||
defaults+: {
|
||||
custom+: {
|
||||
lineInterpolation: 'smooth',
|
||||
gradientMode: 'scheme',
|
||||
fillOpacity: 0,
|
||||
},
|
||||
color: {
|
||||
fixedColor: 'green',
|
||||
mode: 'fixed',
|
||||
},
|
||||
unit: '',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
matcher: {
|
||||
id: 'byFrameRefID',
|
||||
options: 'B',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
id: 'custom.lineStyle',
|
||||
value: {
|
||||
fill: 'dash',
|
||||
dash: [
|
||||
10,
|
||||
10,
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'color',
|
||||
value: {
|
||||
mode: 'fixed',
|
||||
fixedColor: 'red',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
local giteaChangesPanelPrototype =
|
||||
grafana.graphPanel.new(
|
||||
'',
|
||||
datasource='$datasource',
|
||||
interval='$agg_interval',
|
||||
maxDataPoints=10000,
|
||||
)
|
||||
+ {
|
||||
type: 'timeseries',
|
||||
options+: {
|
||||
tooltip: {
|
||||
mode: 'multi',
|
||||
},
|
||||
legend+: {
|
||||
calcs+: [
|
||||
'sum',
|
||||
],
|
||||
},
|
||||
},
|
||||
fieldConfig+: {
|
||||
defaults+: {
|
||||
noValue: '0',
|
||||
custom+: {
|
||||
drawStyle: 'bars',
|
||||
barAlignment: -1,
|
||||
fillOpacity: 50,
|
||||
gradientMode: 'hue',
|
||||
pointSize: 1,
|
||||
lineWidth: 0,
|
||||
stacking: {
|
||||
group: 'A',
|
||||
mode: 'normal',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
local giteaChangesPanelAll =
|
||||
giteaChangesPanelPrototype
|
||||
.addTarget(prometheus.target(expr='changes(process_start_time_seconds{%s}[$__interval]) > 0' % [giteaSelector], legendFormat='Restarts', intervalFactor=1))
|
||||
.addTargets(
|
||||
[
|
||||
prometheus.target(expr='floor(delta(%s{%s}[$__interval])) > 0' % [metric.name, giteaSelector], legendFormat=metric.description, intervalFactor=1)
|
||||
for metric in $._config.giteaStatMetrics
|
||||
]
|
||||
) + { id: 200 }, // some unique number, beyond the maximum number of panels in the dashboard,
|
||||
|
||||
local giteaChangesPanelTotal =
|
||||
grafana.statPanel.new(
|
||||
'Changes',
|
||||
datasource='-- Dashboard --',
|
||||
reducerFunction='sum',
|
||||
graphMode='none',
|
||||
textMode='value_and_name',
|
||||
colorMode='value',
|
||||
)
|
||||
+ {
|
||||
targets+: [
|
||||
{
|
||||
panelId: giteaChangesPanelAll.id,
|
||||
refId: 'A',
|
||||
},
|
||||
],
|
||||
}
|
||||
+ {
|
||||
fieldConfig+: {
|
||||
defaults+: {
|
||||
color: {
|
||||
mode: 'palette-classic',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
local giteaChangesByRepositories =
|
||||
giteaChangesPanelPrototype
|
||||
.addTarget(prometheus.target(expr='floor(increase(gitea_issues_by_repository{%s}[$__interval])) > 0' % [giteaSelector], legendFormat='{{ repository }}', intervalFactor=1))
|
||||
+ { id: 210 }, // some unique number, beyond the maximum number of panels in the dashboard,
|
||||
|
||||
local giteaChangesByRepositoriesTotal =
|
||||
grafana.statPanel.new(
|
||||
'Issues by repository',
|
||||
datasource='-- Dashboard --',
|
||||
reducerFunction='sum',
|
||||
graphMode='none',
|
||||
textMode='value_and_name',
|
||||
colorMode='value',
|
||||
)
|
||||
+ {
|
||||
id: 211,
|
||||
targets+: [
|
||||
{
|
||||
panelId: giteaChangesByRepositories.id,
|
||||
refId: 'A',
|
||||
},
|
||||
],
|
||||
}
|
||||
+ {
|
||||
fieldConfig+: {
|
||||
defaults+: {
|
||||
color: {
|
||||
mode: 'palette-classic',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
local giteaChangesByLabel =
|
||||
giteaChangesPanelPrototype
|
||||
.addTarget(prometheus.target(expr='floor(increase(gitea_issues_by_label{%s}[$__interval])) > 0' % [giteaSelector], legendFormat='{{ label }}', intervalFactor=1))
|
||||
+ addIssueLabelsOverrides($._config.issueLabels)
|
||||
+ { id: 220 }, // some unique number, beyond the maximum number of panels in the dashboard,
|
||||
|
||||
local giteaChangesByLabelTotal =
|
||||
grafana.statPanel.new(
|
||||
'Issues by labels',
|
||||
datasource='-- Dashboard --',
|
||||
reducerFunction='sum',
|
||||
graphMode='none',
|
||||
textMode='value_and_name',
|
||||
colorMode='value',
|
||||
)
|
||||
+ addIssueLabelsOverrides($._config.issueLabels)
|
||||
+ {
|
||||
id: 221,
|
||||
targets+: [
|
||||
{
|
||||
panelId: giteaChangesByLabel.id,
|
||||
refId: 'A',
|
||||
},
|
||||
],
|
||||
}
|
||||
+ {
|
||||
fieldConfig+: {
|
||||
defaults+: {
|
||||
color: {
|
||||
mode: 'palette-classic',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
'gitea-overview.json':
|
||||
grafana.dashboard.new(
|
||||
'%s Overview' % $._config.dashboardNamePrefix,
|
||||
time_from='%s' % $._config.dashboardPeriod,
|
||||
editable=false,
|
||||
tags=($._config.dashboardTags),
|
||||
timezone='%s' % $._config.dashboardTimezone,
|
||||
refresh='%s' % $._config.dashboardRefresh,
|
||||
graphTooltip='shared_crosshair',
|
||||
uid='gitea-overview'
|
||||
)
|
||||
.addTemplate(
|
||||
{
|
||||
current: {
|
||||
text: 'Prometheus',
|
||||
value: 'Prometheus',
|
||||
},
|
||||
hide: 0,
|
||||
label: 'Data Source',
|
||||
name: 'datasource',
|
||||
options: [],
|
||||
query: 'prometheus',
|
||||
refresh: 1,
|
||||
regex: '',
|
||||
type: 'datasource',
|
||||
},
|
||||
)
|
||||
.addTemplate(
|
||||
{
|
||||
hide: 0,
|
||||
label: null,
|
||||
name: 'job',
|
||||
options: [],
|
||||
query: 'label_values(gitea_organizations, job)',
|
||||
refresh: 1,
|
||||
regex: '',
|
||||
type: 'query',
|
||||
},
|
||||
)
|
||||
.addTemplate(
|
||||
{
|
||||
hide: 0,
|
||||
label: null,
|
||||
name: 'instance',
|
||||
options: [],
|
||||
query: 'label_values(gitea_organizations{job="$job"}, instance)',
|
||||
refresh: 1,
|
||||
regex: '',
|
||||
type: 'query',
|
||||
},
|
||||
)
|
||||
.addTemplate(
|
||||
{
|
||||
hide: 0,
|
||||
label: 'aggregation interval',
|
||||
name: 'agg_interval',
|
||||
auto_min: '1m',
|
||||
auto: true,
|
||||
query: '1m,10m,1h,1d,7d',
|
||||
type: 'interval',
|
||||
},
|
||||
)
|
||||
.addPanel(grafana.row.new(title='General'), gridPos={ x: 0, y: 0, w: 0, h: 0 },)
|
||||
.addPanel(giteaStatsPanel, gridPos={ x: 0, y: 0, w: 16, h: 4 })
|
||||
.addPanel(giteaUptimePanel, gridPos={ x: 16, y: 0, w: 8, h: 4 })
|
||||
.addPanel(giteaMemoryPanel, gridPos={ x: 0, y: 4, w: 8, h: 6 })
|
||||
.addPanel(giteaCpuPanel, gridPos={ x: 8, y: 4, w: 8, h: 6 })
|
||||
.addPanel(giteaFileDescriptorsPanel, gridPos={ x: 16, y: 4, w: 8, h: 6 })
|
||||
.addPanel(grafana.row.new(title='Changes', collapse=false), gridPos={ x: 0, y: 10, w: 24, h: 8 })
|
||||
.addPanel(giteaChangesPanelTotal, gridPos={ x: 0, y: 12, w: 6, h: 8 })
|
||||
+ // use patching instead of .addPanel() to keep static ids
|
||||
{
|
||||
panels+: std.flattenArrays([
|
||||
[
|
||||
giteaChangesPanelAll { gridPos: { x: 6, y: 12, w: 18, h: 8 } },
|
||||
],
|
||||
if $._config.showIssuesByRepository then
|
||||
[
|
||||
giteaChangesByRepositoriesTotal { gridPos: { x: 0, y: 20, w: 6, h: 8 } },
|
||||
giteaChangesByRepositories { gridPos: { x: 6, y: 20, w: 18, h: 8 } },
|
||||
] else [],
|
||||
if $._config.showIssuesByLabel then
|
||||
[
|
||||
giteaChangesByLabelTotal { gridPos: { x: 0, y: 28, w: 6, h: 8 } },
|
||||
giteaChangesByLabel { gridPos: { x: 6, y: 28, w: 18, h: 8 } },
|
||||
] else [],
|
||||
]),
|
||||
},
|
||||
},
|
||||
}
|
15
contrib/gitea-monitoring-mixin/jsonnetfile.json
Normal file
15
contrib/gitea-monitoring-mixin/jsonnetfile.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": [
|
||||
{
|
||||
"source": {
|
||||
"git": {
|
||||
"remote": "https://github.com/grafana/grafonnet-lib.git",
|
||||
"subdir": "grafonnet"
|
||||
}
|
||||
},
|
||||
"version": "master"
|
||||
}
|
||||
],
|
||||
"legacyImports": false
|
||||
}
|
16
contrib/gitea-monitoring-mixin/jsonnetfile.lock.json
Normal file
16
contrib/gitea-monitoring-mixin/jsonnetfile.lock.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": [
|
||||
{
|
||||
"source": {
|
||||
"git": {
|
||||
"remote": "https://github.com/grafana/grafonnet-lib.git",
|
||||
"subdir": "grafonnet"
|
||||
}
|
||||
},
|
||||
"version": "3626fc4dc2326931c530861ac5bebe39444f6cbf",
|
||||
"sum": "gF8foHByYcB25jcUOBqP6jxk0OPifQMjPvKY0HaCk6w="
|
||||
}
|
||||
],
|
||||
"legacyImports": false
|
||||
}
|
1
contrib/gitea-monitoring-mixin/lib/alerts.jsonnet
Normal file
1
contrib/gitea-monitoring-mixin/lib/alerts.jsonnet
Normal file
@@ -0,0 +1 @@
|
||||
std.manifestYamlDoc((import '../mixin.libsonnet').prometheusAlerts)
|
6
contrib/gitea-monitoring-mixin/lib/dashboards.jsonnet
Normal file
6
contrib/gitea-monitoring-mixin/lib/dashboards.jsonnet
Normal file
@@ -0,0 +1,6 @@
|
||||
local dashboards = (import '../mixin.libsonnet').grafanaDashboards;
|
||||
|
||||
{
|
||||
[name]: dashboards[name]
|
||||
for name in std.objectFields(dashboards)
|
||||
}
|
1
contrib/gitea-monitoring-mixin/lib/rules.jsonnet
Normal file
1
contrib/gitea-monitoring-mixin/lib/rules.jsonnet
Normal file
@@ -0,0 +1 @@
|
||||
std.manifestYamlDoc((import '../mixin.libsonnet').prometheusRules)
|
2
contrib/gitea-monitoring-mixin/mixin.libsonnet
Normal file
2
contrib/gitea-monitoring-mixin/mixin.libsonnet
Normal file
@@ -0,0 +1,2 @@
|
||||
(import 'dashboards/dashboards.libsonnet') +
|
||||
(import 'config.libsonnet')
|
@@ -12,7 +12,6 @@ import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -26,6 +25,8 @@ import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
gitea_git "code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/markup/external"
|
||||
@@ -36,7 +37,6 @@ import (
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/config"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
context2 "github.com/gorilla/context"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
@@ -49,13 +49,13 @@ func runPR() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
setting.SetCustomPathAndConf("", "", "")
|
||||
setting.NewContext()
|
||||
setting.LoadAllowEmpty()
|
||||
|
||||
setting.RepoRootPath, err = ioutil.TempDir(os.TempDir(), "repos")
|
||||
setting.RepoRootPath, err = os.MkdirTemp(os.TempDir(), "repos")
|
||||
if err != nil {
|
||||
log.Fatalf("TempDir: %v\n", err)
|
||||
}
|
||||
setting.AppDataPath, err = ioutil.TempDir(os.TempDir(), "appdata")
|
||||
setting.AppDataPath, err = os.MkdirTemp(os.TempDir(), "appdata")
|
||||
if err != nil {
|
||||
log.Fatalf("TempDir: %v\n", err)
|
||||
}
|
||||
@@ -87,27 +87,29 @@ func runPR() {
|
||||
setting.Database.Path = ":memory:"
|
||||
setting.Database.Timeout = 500
|
||||
*/
|
||||
db := setting.Cfg.Section("database")
|
||||
db.NewKey("DB_TYPE", "sqlite3")
|
||||
db.NewKey("PATH", ":memory:")
|
||||
dbCfg := setting.Cfg.Section("database")
|
||||
dbCfg.NewKey("DB_TYPE", "sqlite3")
|
||||
dbCfg.NewKey("PATH", ":memory:")
|
||||
|
||||
routers.NewServices()
|
||||
routers.InitGitServices()
|
||||
setting.Database.LogSQL = true
|
||||
//x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
|
||||
|
||||
models.NewEngine(context.Background(), func(_ *xorm.Engine) error {
|
||||
db.InitEngineWithMigration(context.Background(), func(_ *xorm.Engine) error {
|
||||
return nil
|
||||
})
|
||||
models.HasEngine = true
|
||||
db.HasEngine = true
|
||||
//x.ShowSQL(true)
|
||||
err = models.InitFixtures(
|
||||
path.Join(curDir, "models/fixtures/"),
|
||||
err = unittest.InitFixtures(
|
||||
unittest.FixturesOptions{
|
||||
Dir: path.Join(curDir, "models/fixtures/"),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("Error initializing test database: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
models.LoadFixtures()
|
||||
unittest.LoadFixtures()
|
||||
util.RemoveAll(setting.RepoRootPath)
|
||||
util.RemoveAll(models.LocalCopyPath())
|
||||
util.CopyDir(path.Join(curDir, "integrations/gitea-repositories-meta"), setting.RepoRootPath)
|
||||
@@ -136,7 +138,7 @@ func runPR() {
|
||||
*/
|
||||
|
||||
//Start the server
|
||||
http.ListenAndServe(":8080", context2.ClearHandler(c))
|
||||
http.ListenAndServe(":8080", c)
|
||||
|
||||
log.Printf("[PR] Cleaning up ...\n")
|
||||
/*
|
||||
@@ -180,7 +182,7 @@ func main() {
|
||||
codeFilePath = filepath.FromSlash(codeFilePath) //Convert to running OS
|
||||
|
||||
//Copy this file if it will not exist in the PR branch
|
||||
dat, err := ioutil.ReadFile(codeFilePath)
|
||||
dat, err := os.ReadFile(codeFilePath)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to cache this code file : %v", err)
|
||||
}
|
||||
@@ -213,7 +215,7 @@ func main() {
|
||||
//Use git cli command for windows
|
||||
runCmd("git", "fetch", remoteUpstream, fmt.Sprintf("pull/%s/head:%s", pr, branch))
|
||||
} else {
|
||||
ref := fmt.Sprintf("refs/pull/%s/head:%s", pr, branchRef)
|
||||
ref := fmt.Sprintf("%s%s/head:%s", gitea_git.PullPrefix, pr, branchRef)
|
||||
err = repo.Fetch(&git.FetchOptions{
|
||||
RemoteName: remoteUpstream,
|
||||
RefSpecs: []config.RefSpec{
|
||||
@@ -244,7 +246,7 @@ func main() {
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to duplicate this code file in PR : %v", err)
|
||||
}
|
||||
err = ioutil.WriteFile(codeFilePath, dat, 0644)
|
||||
err = os.WriteFile(codeFilePath, dat, 0644)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to duplicate this code file in PR : %v", err)
|
||||
}
|
||||
|
@@ -51,6 +51,16 @@ RUN_MODE = ; prod
|
||||
;REDIRECT_OTHER_PORT = false
|
||||
;PORT_TO_REDIRECT = 80
|
||||
;;
|
||||
;; Minimum and maximum supported TLS versions
|
||||
;SSL_MIN_VERSION=TLSv1.2
|
||||
;SSL_MAX_VERSION=
|
||||
;;
|
||||
;; SSL Curve Preferences
|
||||
;SSL_CURVE_PREFERENCES=X25519,P256
|
||||
;;
|
||||
;; SSL Cipher Suites
|
||||
;SSL_CIPHER_SUITES=; Will default to "ecdhe_ecdsa_with_aes_256_gcm_sha384,ecdhe_rsa_with_aes_256_gcm_sha384,ecdhe_ecdsa_with_aes_128_gcm_sha256,ecdhe_rsa_with_aes_128_gcm_sha256,ecdhe_ecdsa_with_chacha20_poly1305,ecdhe_rsa_with_chacha20_poly1305" if aes is supported by hardware, otherwise chacha will be first.
|
||||
;;
|
||||
;; Timeout for any write to the connection. (Set to 0 to disable all timeouts.)
|
||||
;PER_WRITE_TIMEOUT = 30s
|
||||
;;
|
||||
@@ -378,6 +388,10 @@ INTERNAL_TOKEN=
|
||||
;;
|
||||
;; Validate against https://haveibeenpwned.com/Passwords to see if a password has been exposed
|
||||
;PASSWORD_CHECK_PWN = false
|
||||
;;
|
||||
;; Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations.
|
||||
;; This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security.
|
||||
;SUCCESSFUL_TOKENS_CACHE_SIZE = 20
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -388,7 +402,7 @@ INTERNAL_TOKEN=
|
||||
;; Enables OAuth2 provider
|
||||
ENABLE = true
|
||||
;;
|
||||
;; Algorithm used to sign OAuth2 tokens. Valid values: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512
|
||||
;; Algorithm used to sign OAuth2 tokens. Valid values: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, EdDSA
|
||||
;JWT_SIGNING_ALGORITHM = RS256
|
||||
;;
|
||||
;; Private key file path used to sign OAuth2 tokens. The path is relative to APP_DATA_PATH.
|
||||
@@ -421,9 +435,10 @@ ENABLE = true
|
||||
;; NOTE: THE DEFAULT VALUES HERE WILL NEED TO BE CHANGED
|
||||
;; Two Factor authentication with security keys
|
||||
;; https://developers.yubico.com/U2F/App_ID.html
|
||||
;;
|
||||
;; DEPRECATED - this only applies to previously registered security keys using the U2F standard
|
||||
APP_ID = ; e.g. http://localhost:3000/
|
||||
;; Comma separated list of trusted facets
|
||||
TRUSTED_FACETS = ; e.g. http://localhost:3000/
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -576,6 +591,10 @@ PATH =
|
||||
;;
|
||||
;; (Go-Git only) Don't cache objects greater than this in memory. (Set to 0 to disable.)
|
||||
;LARGE_OBJECT_THRESHOLD = 1048576
|
||||
;; Set to true to forcibly set core.protectNTFS=false
|
||||
;DISABLE_CORE_PROTECT_NTFS=false
|
||||
;; Disable the usage of using partial clones for git.
|
||||
;DISABLE_PARTIAL_CLONE = false
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -652,6 +671,9 @@ PATH =
|
||||
;; Default value for AllowCreateOrganization
|
||||
;; Every new user will have rights set to create organizations depending on this setting
|
||||
;DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||
;; Default value for IsRestricted
|
||||
;; Every new user will have restricted permissions depending on this setting
|
||||
;DEFAULT_USER_IS_RESTRICTED = false
|
||||
;;
|
||||
;; Either "public", "limited" or "private", default is "public"
|
||||
;; Limited is for users visible only to signed users
|
||||
@@ -760,18 +782,18 @@ PATH =
|
||||
;; Global limit of repositories per user, applied at creation time. -1 means no limit
|
||||
;MAX_CREATION_LIMIT = -1
|
||||
;;
|
||||
;; Mirror sync queue length, increase if mirror syncing starts hanging
|
||||
;; Mirror sync queue length, increase if mirror syncing starts hanging (DEPRECATED: please use [queue.mirror] LENGTH instead)
|
||||
;MIRROR_QUEUE_LENGTH = 1000
|
||||
;;
|
||||
;; Patch test queue length, increase if pull request patch testing starts hanging
|
||||
;; Patch test queue length, increase if pull request patch testing starts hanging (DEPRECATED: please use [queue.pr_patch_checker] LENGTH instead)
|
||||
;PULL_REQUEST_QUEUE_LENGTH = 1000
|
||||
;;
|
||||
;; Preferred Licenses to place at the top of the List
|
||||
;; The name here must match the filename in conf/license or custom/conf/license
|
||||
;; The name here must match the filename in options/license or custom/options/license
|
||||
;PREFERRED_LICENSES = Apache License 2.0,MIT License
|
||||
;;
|
||||
;; Disable the ability to interact with repositories using the HTTP protocol
|
||||
;;DISABLE_HTTP_GIT = false
|
||||
;DISABLE_HTTP_GIT = false
|
||||
;;
|
||||
;; Value for Access-Control-Allow-Origin header, default is not to present
|
||||
;; WARNING: This may be harmful to your website if you do not give it a right value.
|
||||
@@ -793,9 +815,6 @@ PATH =
|
||||
;; Prefix archive files by placing them in a directory named after the repository
|
||||
;PREFIX_ARCHIVE_FILES = true
|
||||
;;
|
||||
;; Disable the creation of new mirrors. Pre-existing mirrors remain valid.
|
||||
;DISABLE_MIRRORS = false
|
||||
;;
|
||||
;; Disable migrating feature.
|
||||
;DISABLE_MIGRATIONS = false
|
||||
;;
|
||||
@@ -861,7 +880,7 @@ PATH =
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; List of prefixes used in Pull Request title to mark them as Work In Progress
|
||||
;; List of prefixes used in Pull Request title to mark them as Work In Progress (matched in a case-insensitive manner)
|
||||
;WORK_IN_PROGRESS_PREFIXES = WIP:,[WIP]
|
||||
;;
|
||||
;; List of keywords used in Pull Request comments to automatically close a related issue
|
||||
@@ -884,6 +903,9 @@ PATH =
|
||||
;;
|
||||
;; In default merge messages only include approvers who are official
|
||||
;DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY = true
|
||||
;;
|
||||
;; Add co-authored-by and co-committed-by trailers if committer does not match author
|
||||
;ADD_CO_COMMITTER_TRAILERS = true
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -900,6 +922,7 @@ PATH =
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
|
||||
;ALLOWED_TYPES =
|
||||
;DEFAULT_PAGING_NUM = 10
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -990,6 +1013,9 @@ PATH =
|
||||
;;
|
||||
;; allow request with credentials
|
||||
;ALLOW_CREDENTIALS = false
|
||||
;;
|
||||
;; set X-FRAME-OPTIONS header
|
||||
;X_FRAME_OPTIONS = SAMEORIGIN
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -1027,10 +1053,10 @@ PATH =
|
||||
;SHOW_USER_EMAIL = true
|
||||
;;
|
||||
;; Set the default theme for the Gitea install
|
||||
;DEFAULT_THEME = gitea
|
||||
;DEFAULT_THEME = auto
|
||||
;;
|
||||
;; All available themes. Allow users select personalized themes regardless of the value of `DEFAULT_THEME`.
|
||||
;THEMES = gitea,arc-green
|
||||
;THEMES = auto,gitea,arc-green
|
||||
;;
|
||||
;; All available reactions users can choose on issues/prs and comments.
|
||||
;; Values can be emoji alias (:smile:) or a unicode emoji.
|
||||
@@ -1049,7 +1075,7 @@ PATH =
|
||||
;SEARCH_REPO_DESCRIPTION = true
|
||||
;;
|
||||
;; Whether to enable a Service Worker to cache frontend assets
|
||||
;USE_SERVICE_WORKER = true
|
||||
;USE_SERVICE_WORKER = false
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -1386,6 +1412,13 @@ PATH =
|
||||
;; Deliver timeout in seconds
|
||||
;DELIVER_TIMEOUT = 5
|
||||
;;
|
||||
;; Webhook can only call allowed hosts for security reasons. Comma separated list, eg: external, 192.168.1.0/24, *.mydomain.com
|
||||
;; Built-in: loopback (for localhost), private (for LAN/intranet), external (for public hosts on internet), * (for all hosts)
|
||||
;; CIDR list: 1.2.3.0/8, 2001:db8::/32
|
||||
;; Wildcard hosts: *.mydomain.com, 192.168.100.*
|
||||
;; Since 1.15.7. Default to * for 1.15.x, external for 1.16 and later
|
||||
;ALLOWED_HOST_LIST = external
|
||||
;;
|
||||
;; Allow insecure certification
|
||||
;SKIP_TLS_VERIFY = false
|
||||
;;
|
||||
@@ -1440,6 +1473,9 @@ PATH =
|
||||
;; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format
|
||||
;FROM =
|
||||
;;
|
||||
;; Sometimes it is helpful to use a different address on the envelope. Set this to use ENVELOPE_FROM as the from on the envelope. Set to `<>` to send an empty address.
|
||||
;ENVELOPE_FROM =
|
||||
;;
|
||||
;; Mailer user name and password
|
||||
;; Please Note: Authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via STARTTLS) or `HOST=localhost`.
|
||||
;USER =
|
||||
@@ -1461,6 +1497,9 @@ PATH =
|
||||
;;
|
||||
;; Timeout for Sendmail
|
||||
;SENDMAIL_TIMEOUT = 5m
|
||||
;;
|
||||
;; convert \r\n to \n for Sendmail
|
||||
;SENDMAIL_CONVERT_CRLF = true
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -1554,6 +1593,10 @@ PATH =
|
||||
;AVATAR_MAX_WIDTH = 4096
|
||||
;AVATAR_MAX_HEIGHT = 3072
|
||||
;;
|
||||
;; The multiplication factor for rendered avatar images.
|
||||
;; Larger values result in finer rendering on HiDPI devices.
|
||||
;AVATAR_RENDERED_SIZE_FACTOR = 3
|
||||
;;
|
||||
;; Maximum allowed file size for uploaded avatars.
|
||||
;; This is to limit the amount of RAM used when resizing the image.
|
||||
;AVATAR_MAX_FILE_SIZE = 1048576
|
||||
@@ -1580,7 +1623,7 @@ PATH =
|
||||
;ENABLED = true
|
||||
;;
|
||||
;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
|
||||
;ALLOWED_TYPES = .docx,.gif,.gz,.jpeg,.jpg,.log,.pdf,.png,.pptx,.txt,.xlsx,.zip
|
||||
;ALLOWED_TYPES = .docx,.gif,.gz,.jpeg,.jpg,.mp4,.log,.pdf,.png,.pptx,.txt,.xlsx,.zip
|
||||
;;
|
||||
;; Max size of each file. Defaults to 4MB
|
||||
;MAX_SIZE = 4
|
||||
@@ -1671,7 +1714,7 @@ PATH =
|
||||
;; Notice if not success
|
||||
;NO_SUCCESS_NOTICE = false
|
||||
;; Time interval for job to run
|
||||
;SCHEDULE = @every 24h
|
||||
;SCHEDULE = @midnight
|
||||
;; Archives created more than OLDER_THAN ago are subject to deletion
|
||||
;OLDER_THAN = 24h
|
||||
|
||||
@@ -1689,6 +1732,12 @@ PATH =
|
||||
;RUN_AT_START = false
|
||||
;; Notice if not success
|
||||
;NO_SUCCESS_NOTICE = true
|
||||
;; Limit the number of mirrors added to the queue to this number
|
||||
;; (negative values mean no limit, 0 will result in no result in no mirrors being queued effectively disabling pull mirror updating.)
|
||||
;PULL_LIMIT=50
|
||||
;; Limit the number of mirrors added to the queue to this number
|
||||
;; (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating)
|
||||
;PUSH_LIMIT=50
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -1697,7 +1746,7 @@ PATH =
|
||||
;[cron.repo_health_check]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;SCHEDULE = @every 24h
|
||||
;SCHEDULE = @midnight
|
||||
;; Enable running Repository health check task periodically.
|
||||
;ENABLED = true
|
||||
;; Run Repository health check task when Gitea starts.
|
||||
@@ -1722,7 +1771,7 @@ PATH =
|
||||
;RUN_AT_START = true
|
||||
;; Notice if not success
|
||||
;NO_SUCCESS_NOTICE = false
|
||||
;SCHEDULE = @every 24h
|
||||
;SCHEDULE = @midnight
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -1736,7 +1785,7 @@ PATH =
|
||||
;; Notice if not success
|
||||
;NO_SUCCESS_NOTICE = false
|
||||
;; Interval as a duration between each synchronization. (default every 24h)
|
||||
;SCHEDULE = @every 24h
|
||||
;SCHEDULE = @midnight
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -1751,7 +1800,7 @@ PATH =
|
||||
;; Notice if not success
|
||||
;NO_SUCCESS_NOTICE = false
|
||||
;; Interval as a duration between each synchronization (default every 24h)
|
||||
;SCHEDULE = @every 24h
|
||||
;SCHEDULE = @midnight
|
||||
;; Create new users, update existing user data and disable users that are not in external source anymore (default)
|
||||
;; or only create new users if UPDATE_EXISTING is set to false
|
||||
;UPDATE_EXISTING = true
|
||||
@@ -1769,7 +1818,7 @@ PATH =
|
||||
;; Notice if not success
|
||||
;NO_SUCCESS_NOTICE = false
|
||||
;; Interval as a duration between each synchronization (default every 24h)
|
||||
;SCHEDULE = @every 24h
|
||||
;SCHEDULE = @midnight
|
||||
;; deleted branches than OLDER_THAN ago are subject to deletion
|
||||
;OLDER_THAN = 24h
|
||||
|
||||
@@ -1785,7 +1834,7 @@ PATH =
|
||||
;; Whether to always run at start up time (if ENABLED)
|
||||
;RUN_AT_START = false
|
||||
;; Time interval for job to run
|
||||
;SCHEDULE = @every 24h
|
||||
;SCHEDULE = @midnight
|
||||
;; OlderThan or PerWebhook. How the records are removed, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
|
||||
;CLEANUP_TYPE = OlderThan
|
||||
;; If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
|
||||
@@ -1875,7 +1924,7 @@ PATH =
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;ENABLED = false
|
||||
;RUN_AT_START = false
|
||||
;NO_SUCCESS_NOTICE = f;alse
|
||||
;NO_SUCCESS_NOTICE = false
|
||||
;SCHEDULE = @every 72h
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -1899,7 +1948,7 @@ PATH =
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;ENABLED = false
|
||||
;RUN_AT_START = false
|
||||
;NO_SUCCESS_NOTICE = f;alse
|
||||
;NO_SUCCESS_NOTICE = false
|
||||
;SCHEDULE = @every 72h
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -1915,6 +1964,19 @@ PATH =
|
||||
;SCHEDULE = @every 168h
|
||||
;OLDER_THAN = 8760h
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Check for new Gitea versions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[cron.update_checker]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;ENABLED = false
|
||||
;RUN_AT_START = false
|
||||
;ENABLE_SUCCESS_NOTICE = false
|
||||
;SCHEDULE = @every 168h
|
||||
;HTTP_ENDPOINT = https://dl.gitea.io/gitea/version.json
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Git Operation timeout in seconds
|
||||
@@ -1934,6 +1996,12 @@ PATH =
|
||||
;[mirror]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Enables the mirror functionality. Set to **false** to disable all mirrors.
|
||||
;ENABLED = true
|
||||
;; Disable the creation of **new** pull mirrors. Pre-existing mirrors remain valid. Will be ignored if `mirror.ENABLED` is `false`.
|
||||
;DISABLE_NEW_PULL = false
|
||||
;; Disable the creation of **new** push mirrors. Pre-existing mirrors remain valid. Will be ignored if `mirror.ENABLED` is `false`.
|
||||
;DISABLE_NEW_PUSH = false
|
||||
;; Default interval as a duration between each check
|
||||
;DEFAULT_INTERVAL = 8h
|
||||
;; Min interval as a duration must be > 1m
|
||||
@@ -1960,8 +2028,8 @@ PATH =
|
||||
;[i18n]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR
|
||||
;NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어
|
||||
;LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID,ml-IN
|
||||
;NAMES = English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,Українська,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어,ελληνικά,فارسی,magyar nyelv,bahasa Indonesia,മലയാളം
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -1982,6 +2050,15 @@ PATH =
|
||||
;; Show template execution time in the footer
|
||||
;SHOW_FOOTER_TEMPLATE_LOAD_TIME = true
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[markup]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Set the maximum number of characters in a mermaid source. (Set to -1 to disable limits)
|
||||
;MERMAID_MAX_SOURCE_CHARACTERS = 5000
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[markup.sanitizer.1]
|
||||
@@ -2018,6 +2095,10 @@ PATH =
|
||||
;ENABLED = false
|
||||
;; If you want to add authorization, specify a token here
|
||||
;TOKEN =
|
||||
;; Enable issue by label metrics; default is false
|
||||
;ENABLED_ISSUE_BY_LABEL = false
|
||||
;; Enable issue by repository metrics; default is false
|
||||
;ENABLED_ISSUE_BY_REPOSITORY = false
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -2052,12 +2133,21 @@ PATH =
|
||||
;ALLOWED_DOMAINS =
|
||||
;;
|
||||
;; Blocklist for migrating, default is blank. Multiple domains could be separated by commas.
|
||||
;; When ALLOWED_DOMAINS is not blank, this option will be ignored.
|
||||
;; When ALLOWED_DOMAINS is not blank, this option has a higher priority to deny domains.
|
||||
;BLOCKED_DOMAINS =
|
||||
;;
|
||||
;; Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291 (false by default)
|
||||
;ALLOW_LOCALNETWORKS = false
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;[federation]
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; Enable/Disable federation capabilities
|
||||
; ENABLED = true
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; default storage for attachments, lfs and avatars
|
||||
@@ -2108,3 +2198,11 @@ PATH =
|
||||
;;
|
||||
;; Minio enabled ssl only available when STORAGE_TYPE is `minio`
|
||||
;MINIO_USE_SSL = false
|
||||
|
||||
;[proxy]
|
||||
;; Enable the proxy, all requests to external via HTTP will be affected
|
||||
;PROXY_ENABLED = false
|
||||
;; Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy/no_proxy
|
||||
;PROXY_URL =
|
||||
;; Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
|
||||
;PROXY_HOSTS =
|
||||
|
@@ -1,19 +1,18 @@
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-rootless
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-rootless
|
||||
{{#if build.tags}}
|
||||
tags:
|
||||
{{#each build.tags}}
|
||||
- {{this}}-rootless
|
||||
{{/each}}
|
||||
- "latest-rootless"
|
||||
{{/if}}
|
||||
manifests:
|
||||
-
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-linux-amd64-rootless
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-amd64-rootless
|
||||
platform:
|
||||
architecture: amd64
|
||||
os: linux
|
||||
-
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}-linux-arm64-rootless
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-arm64-rootless
|
||||
platform:
|
||||
architecture: arm64
|
||||
os: linux
|
||||
|
@@ -1,20 +1,19 @@
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}dev{{/if}}
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}
|
||||
{{#if build.tags}}
|
||||
tags:
|
||||
{{#each build.tags}}
|
||||
- {{this}}
|
||||
{{/each}}
|
||||
- "latest"
|
||||
{{/if}}
|
||||
manifests:
|
||||
-
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-amd64
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-amd64
|
||||
platform:
|
||||
architecture: amd64
|
||||
os: linux
|
||||
-
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{else}}dev-{{/if}}linux-arm64
|
||||
image: gitea/gitea:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}{{#if (hasPrefix "refs/heads/release/v" build.ref)}}{{trimPrefix "refs/heads/release/v" build.ref}}-{{/if}}dev{{/if}}-linux-arm64
|
||||
platform:
|
||||
architecture: arm64
|
||||
os: linux
|
||||
variant: v8
|
||||
variant: v8
|
||||
|
@@ -2,5 +2,5 @@
|
||||
[[ -f ./setup ]] && source ./setup
|
||||
|
||||
pushd /app/gitea >/dev/null
|
||||
exec su-exec $USER /app/gitea/gitea web
|
||||
exec su-exec $USER /usr/local/bin/gitea web
|
||||
popd
|
||||
|
17
docker/root/usr/local/bin/gitea
Normal file
17
docker/root/usr/local/bin/gitea
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
###############################################################
|
||||
# This script sets defaults for gitea to run in the container #
|
||||
###############################################################
|
||||
|
||||
# It assumes that you place this script as gitea in /usr/local/bin
|
||||
#
|
||||
# And place the original in /usr/lib/gitea with working files in /data/gitea
|
||||
GITEA="/app/gitea/gitea"
|
||||
WORK_DIR="/app/gitea"
|
||||
CUSTOM_PATH="/data/gitea"
|
||||
|
||||
# Provide docker defaults
|
||||
GITEA_WORK_DIR="${GITEA_WORK_DIR:-$WORK_DIR}" GITEA_CUSTOM="${GITEA_CUSTOM:-$CUSTOM_PATH}" exec -a "$0" "$GITEA" $CONF_ARG "$@"
|
||||
|
||||
|
40
docker/rootless/usr/local/bin/gitea
Normal file
40
docker/rootless/usr/local/bin/gitea
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
###############################################################
|
||||
# This script sets defaults for gitea to run in the container #
|
||||
###############################################################
|
||||
|
||||
# It assumes that you place this script as gitea in /usr/local/bin
|
||||
#
|
||||
# And place the original in /usr/lib/gitea with working files in /data/gitea
|
||||
GITEA="/app/gitea/gitea"
|
||||
WORK_DIR="/var/lib/gitea"
|
||||
APP_INI="/etc/gitea/app.ini"
|
||||
|
||||
APP_INI_SET=""
|
||||
for i in "$@"; do
|
||||
case "$i" in
|
||||
"-c")
|
||||
APP_INI_SET=1
|
||||
;;
|
||||
"-c="*)
|
||||
APP_INI_SET=1
|
||||
;;
|
||||
"--config")
|
||||
APP_INI_SET=1
|
||||
;;
|
||||
"--config="*)
|
||||
APP_INI_SET=1
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$APP_INI_SET" ]; then
|
||||
CONF_ARG=("-c" "${GITEA_APP_INI:-$APP_INI}")
|
||||
fi
|
||||
|
||||
|
||||
# Provide docker defaults
|
||||
GITEA_WORK_DIR="${GITEA_WORK_DIR:-$WORK_DIR}" exec -a "$0" "$GITEA" "${CONF_ARG[@]}" "$@"
|
@@ -15,7 +15,7 @@ const fuseOptions = {
|
||||
shouldSort: true,
|
||||
includeMatches: true,
|
||||
matchAllTokens: true,
|
||||
threshold: 0.0, // for parsing diacritics
|
||||
threshold: 0, // for parsing diacritics
|
||||
tokenize: true,
|
||||
location: 0,
|
||||
distance: 100,
|
||||
@@ -52,7 +52,7 @@ function doSearch() {
|
||||
executeSearch(searchQuery);
|
||||
} else {
|
||||
const para = document.createElement('P');
|
||||
para.innerText = 'Please enter a word or phrase above';
|
||||
para.textContent = 'Please enter a word or phrase above';
|
||||
document.getElementById('search-results').appendChild(para);
|
||||
}
|
||||
}
|
||||
@@ -60,17 +60,17 @@ function doSearch() {
|
||||
function getJSON(url, fn) {
|
||||
const request = new XMLHttpRequest();
|
||||
request.open('GET', url, true);
|
||||
request.onload = function () {
|
||||
request.addEventListener('load', () => {
|
||||
if (request.status >= 200 && request.status < 400) {
|
||||
const data = JSON.parse(request.responseText);
|
||||
fn(data);
|
||||
} else {
|
||||
console.error(`Target reached on ${url} with error ${request.status}`);
|
||||
}
|
||||
};
|
||||
request.onerror = function () {
|
||||
});
|
||||
request.addEventListener('error', () => {
|
||||
console.error(`Connection error ${request.status}`);
|
||||
};
|
||||
});
|
||||
request.send();
|
||||
}
|
||||
|
||||
@@ -84,20 +84,20 @@ function executeSearch(searchQuery) {
|
||||
populateResults(result);
|
||||
} else {
|
||||
const para = document.createElement('P');
|
||||
para.innerText = 'No matches found';
|
||||
para.textContent = 'No matches found';
|
||||
document.getElementById('search-results').appendChild(para);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function populateResults(result) {
|
||||
result.forEach((value, key) => {
|
||||
for (const [key, value] of result.entries()) {
|
||||
const content = value.item.contents;
|
||||
let snippet = '';
|
||||
const snippetHighlights = [];
|
||||
if (fuseOptions.tokenize) {
|
||||
snippetHighlights.push(searchQuery);
|
||||
value.matches.forEach((mvalue) => {
|
||||
for (const mvalue of value.matches) {
|
||||
if (mvalue.key === 'tags' || mvalue.key === 'categories') {
|
||||
snippetHighlights.push(mvalue.value);
|
||||
} else if (mvalue.key === 'contents') {
|
||||
@@ -111,7 +111,7 @@ function populateResults(result) {
|
||||
snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0], mvalue.indices[0][1] - mvalue.indices[0][0] + 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (snippet.length < 1) {
|
||||
@@ -130,10 +130,10 @@ function populateResults(result) {
|
||||
});
|
||||
document.getElementById('search-results').appendChild(htmlToElement(output));
|
||||
|
||||
snippetHighlights.forEach((snipvalue) => {
|
||||
for (const snipvalue of snippetHighlights) {
|
||||
new Mark(document.getElementById(`summary-${key}`)).mark(snipvalue);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function render(templateString, data) {
|
||||
|
@@ -18,9 +18,9 @@ params:
|
||||
description: Git with a cup of tea
|
||||
author: The Gitea Authors
|
||||
website: https://docs.gitea.io
|
||||
version: 1.14.4
|
||||
minGoVersion: 1.14
|
||||
goVersion: 1.16
|
||||
version: 1.16.4
|
||||
minGoVersion: 1.16
|
||||
goVersion: 1.18
|
||||
minNodeVersion: 12.17
|
||||
|
||||
outputs:
|
||||
|
@@ -20,19 +20,19 @@ Some jurisdictions (such as EU), requires certain legal pages (e.g. Privacy Poli
|
||||
Gitea source code ships with sample pages, available in `contrib/legal` directory. Copy them to `custom/public/`. For example, to add Privacy Policy:
|
||||
|
||||
```
|
||||
wget -O /path/to/custom/public/privacy.html https://raw.githubusercontent.com/go-gitea/gitea/master/contrib/legal/privacy.html.sample
|
||||
wget -O /path/to/custom/public/privacy.html https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/legal/privacy.html.sample
|
||||
```
|
||||
|
||||
Now you need to edit the page to meet your requirements. In particular you must change the email addresses, web addresses and references to "Your Gitea Instance" to match your situation.
|
||||
|
||||
You absolutely must not place a general ToS or privacy statement that implies that the gitea project is responsible for your server.
|
||||
You absolutely must not place a general ToS or privacy statement that implies that the Gitea project is responsible for your server.
|
||||
|
||||
## Make it Visible
|
||||
|
||||
Create or append to `/path/to/custom/templates/custom/extra_links_footer.tmpl`:
|
||||
|
||||
```go
|
||||
<a class="item" href="{{AppSubUrl}}/privacy.html">Privacy Policy</a>
|
||||
<a class="item" href="{{AppSubUrl}}/assets/privacy.html">Privacy Policy</a>
|
||||
```
|
||||
|
||||
Restart Gitea to see the changes.
|
||||
|
@@ -27,39 +27,12 @@ on the client is at least the same as on the server (or later). Login to
|
||||
Gitea server as admin and head to Site Administration -> Configuration to
|
||||
see Git version of the server.
|
||||
|
||||
By default, clone filters are disabled, which cause the server to ignore
|
||||
`--filter` option.
|
||||
By default, clone filters are enabled, unless `DISABLE_PARTIAL_CLONE` under
|
||||
`[git]` is set to `true`.
|
||||
|
||||
To enable clone filters on per-repo basis, edit the repo's `config` on
|
||||
repository location. Consult `ROOT` option on `repository` section of
|
||||
Gitea configuration (`app.ini`) for the exact location. For example, to
|
||||
enable clone filters for `some-repo`, edit
|
||||
`/var/gitea/data/gitea-repositories/some-user/some-repo.git/config` and add:
|
||||
|
||||
```ini
|
||||
[uploadpack]
|
||||
allowfilter = true
|
||||
```
|
||||
|
||||
To enable clone filters globally, add that config above to `~/.gitconfig`
|
||||
of user that run Gitea (for example `git`).
|
||||
|
||||
Alternatively, you can use `git config` to set the option.
|
||||
|
||||
To enable for a specific repo:
|
||||
|
||||
```bash
|
||||
cd /var/gitea/data/gitea-repositories/some-user/some-repo.git
|
||||
git config --local uploadpack.allowfilter true
|
||||
```
|
||||
To enable globally, login as user that run Gitea and:
|
||||
|
||||
```bash
|
||||
git config --global uploadpack.allowfilter true
|
||||
```
|
||||
|
||||
See [GitHub blog post: Get up to speed with partial clone](https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/)
|
||||
for common use cases of clone filters (blobless and treeless clones), and
|
||||
[Gitlab docs for partial clone](https://docs.gitlab.com/ee/topics/git/partial_clone.html)
|
||||
[GitLab docs for partial clone](https://docs.gitlab.com/ee/topics/git/partial_clone.html)
|
||||
for more advanced use cases (such as filter by file size and remove
|
||||
filters to turn partial clone into full clone).
|
||||
|
@@ -76,20 +76,20 @@ To extract resources embedded in Gitea's executable, use the following syntax:
|
||||
gitea [--config {file}] embedded extract [--destination {dir}|--custom] [--overwrite|--rename] [--include-vendored] {patterns...}
|
||||
```
|
||||
|
||||
The `--config` option tells gitea the location of the `app.ini` configuration file if
|
||||
The `--config` option tells Gitea the location of the `app.ini` configuration file if
|
||||
it's not in its default location. This option is only used with the `--custom` flag.
|
||||
|
||||
The `--destination` option tells gitea the directory where the files must be extracted to.
|
||||
The `--destination` option tells Gitea the directory where the files must be extracted to.
|
||||
The default is the current directory.
|
||||
|
||||
The `--custom` flag tells gitea to extract the files directly into the `custom` directory.
|
||||
The `--custom` flag tells Gitea to extract the files directly into the `custom` directory.
|
||||
For this to work, the command needs to know the location of the `app.ini` configuration
|
||||
file (`--config`) and, depending of the configuration, be ran from the directory where
|
||||
gitea normally starts. See [Customizing Gitea]({{< relref "doc/advanced/customizing-gitea.en-us.md" >}}) for details.
|
||||
Gitea normally starts. See [Customizing Gitea]({{< relref "doc/advanced/customizing-gitea.en-us.md" >}}) for details.
|
||||
|
||||
The `--overwrite` flag allows any existing files in the destination directory to be overwritten.
|
||||
|
||||
The `--rename` flag tells gitea to rename any existing files in the destination directory
|
||||
The `--rename` flag tells Gitea to rename any existing files in the destination directory
|
||||
as `filename.bak`. Previous `.bak` files are overwritten.
|
||||
|
||||
At least one file search pattern must be provided; see `list` subcomand above for pattern
|
||||
|
@@ -23,8 +23,8 @@ or any corresponding location. When installing from a distribution, this will
|
||||
typically be found at `/etc/gitea/conf/app.ini`.
|
||||
|
||||
The defaults provided here are best-effort (not built automatically). They are
|
||||
accurately recorded in [app.example.ini](https://github.com/go-gitea/gitea/blob/master/custom/conf/app.example.ini)
|
||||
(s/master/\<tag|release\>). Any string in the format `%(X)s` is a feature powered
|
||||
accurately recorded in [app.example.ini](https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini)
|
||||
(s/main/\<tag|release\>). Any string in the format `%(X)s` is a feature powered
|
||||
by [ini](https://github.com/go-ini/ini/#recursive-values), for reading values recursively.
|
||||
|
||||
Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
@@ -54,10 +54,10 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
- `DEFAULT_PUSH_CREATE_PRIVATE`: **true**: Default private when creating a new repository with push-to-create.
|
||||
- `MAX_CREATION_LIMIT`: **-1**: Global maximum creation limit of repositories per user,
|
||||
`-1` means no limit.
|
||||
- `PULL_REQUEST_QUEUE_LENGTH`: **1000**: Length of pull request patch test queue, make it
|
||||
- `PULL_REQUEST_QUEUE_LENGTH`: **1000**: Length of pull request patch test queue, make it. **DEPRECATED** use `LENGTH` in `[queue.pr_patch_checker]`.
|
||||
as large as possible. Use caution when editing this value.
|
||||
- `MIRROR_QUEUE_LENGTH`: **1000**: Patch test queue length, increase if pull request patch
|
||||
testing starts hanging.
|
||||
testing starts hanging. **DEPRECATED** use `LENGTH` in `[queue.mirror]`.
|
||||
- `PREFERRED_LICENSES`: **Apache License 2.0,MIT License**: Preferred Licenses to place at
|
||||
the top of the list. Name must match file name in options/license or custom/options/license.
|
||||
- `DISABLE_HTTP_GIT`: **false**: Disable the ability to interact with repositories over the
|
||||
@@ -73,7 +73,6 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
- `DISABLED_REPO_UNITS`: **_empty_**: Comma separated list of globally disabled repo units. Allowed values: \[repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki, repo.projects\]
|
||||
- `DEFAULT_REPO_UNITS`: **repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects**: Comma separated list of default repo units. Allowed values: \[repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki, repo.projects\]. Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility. External wiki and issue tracker can't be enabled by default as it requires additional settings. Disabled repo units will not be added to new repositories regardless if it is in the default list.
|
||||
- `PREFIX_ARCHIVE_FILES`: **true**: Prefix archive files by placing them in a directory named after the repository.
|
||||
- `DISABLE_MIRRORS`: **false**: Disable the creation of **new** mirrors. Pre-existing mirrors remain valid.
|
||||
- `DISABLE_MIGRATIONS`: **false**: Disable migrating feature.
|
||||
- `DISABLE_STARS`: **false**: Disable stars feature.
|
||||
- `DEFAULT_BRANCH`: **master**: Default branch name of all repositories.
|
||||
@@ -88,7 +87,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
### Repository - Pull Request (`repository.pull-request`)
|
||||
|
||||
- `WORK_IN_PROGRESS_PREFIXES`: **WIP:,\[WIP\]**: List of prefixes used in Pull Request
|
||||
title to mark them as Work In Progress
|
||||
title to mark them as Work In Progress. These are matched in a case-insensitive manner.
|
||||
- `CLOSE_KEYWORDS`: **close**, **closes**, **closed**, **fix**, **fixes**, **fixed**, **resolve**, **resolves**, **resolved**: List of
|
||||
keywords used in Pull Request comments to automatically close a related issue
|
||||
- `REOPEN_KEYWORDS`: **reopen**, **reopens**, **reopened**: List of keywords used in Pull Request comments to automatically reopen
|
||||
@@ -99,6 +98,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
- `DEFAULT_MERGE_MESSAGE_MAX_APPROVERS`: **10**: In default merge messages limit the number of approvers listed as `Reviewed-by:`. Set to `-1` to include all.
|
||||
- `DEFAULT_MERGE_MESSAGE_OFFICIAL_APPROVERS_ONLY`: **true**: In default merge messages only include approvers who are officially allowed to review.
|
||||
- `POPULATE_SQUASH_COMMENT_WITH_COMMIT_MESSAGES`: **false**: In default squash-merge messages include the commit message of all commits comprising the pull request.
|
||||
- `ADD_CO_COMMITTER_TRAILERS`: **true**: Add co-authored-by and co-committed-by trailers to merge commit messages if committer does not match author.
|
||||
|
||||
### Repository - Issue (`repository.issue`)
|
||||
|
||||
@@ -107,7 +107,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
### Repository - Upload (`repository.upload`)
|
||||
|
||||
- `ENABLED`: **true**: Whether repository file uploads are enabled
|
||||
- `TEMP_PATH`: **data/tmp/uploads**: Path for uploads (tmp gets deleted on gitea restart)
|
||||
- `TEMP_PATH`: **data/tmp/uploads**: Path for uploads (tmp gets deleted on Gitea restart)
|
||||
- `ALLOWED_TYPES`: **\<empty\>**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
|
||||
- `FILE_MAX_SIZE`: **3**: Max size of each file in megabytes.
|
||||
- `MAX_FILES`: **5**: Max number of files per upload
|
||||
@@ -115,6 +115,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||
### Repository - Release (`repository.release`)
|
||||
|
||||
- `ALLOWED_TYPES`: **\<empty\>**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
|
||||
- `DEFAULT_PAGING_NUM`: **10**: The default paging number of releases user interface
|
||||
- For settings related to file attachments on releases, see the `attachment` section.
|
||||
|
||||
### Repository - Signing (`repository.signing`)
|
||||
|
||||
@@ -162,6 +164,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
- `METHODS`: **GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS**: list of methods allowed to request
|
||||
- `MAX_AGE`: **10m**: max time to cache response
|
||||
- `ALLOW_CREDENTIALS`: **false**: allow request with credentials
|
||||
- `X_FRAME_OPTIONS`: **SAMEORIGIN**: Set the `X-Frame-Options` header value.
|
||||
|
||||
## UI (`ui`)
|
||||
|
||||
@@ -172,9 +175,9 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
- `FEED_PAGING_NUM`: **20**: Number of items that are displayed in home feed.
|
||||
- `GRAPH_MAX_COMMIT_NUM`: **100**: Number of maximum commits shown in the commit graph.
|
||||
- `CODE_COMMENT_LINES`: **4**: Number of line of codes shown for a code comment.
|
||||
- `DEFAULT_THEME`: **gitea**: \[gitea, arc-green\]: Set the default theme for the Gitea install.
|
||||
- `DEFAULT_THEME`: **auto**: \[auto, gitea, arc-green\]: Set the default theme for the Gitea install.
|
||||
- `SHOW_USER_EMAIL`: **true**: Whether the email of the user should be shown in the Explore Users page.
|
||||
- `THEMES`: **gitea,arc-green**: All available themes. Allow users select personalized themes.
|
||||
- `THEMES`: **auto,gitea,arc-green**: All available themes. Allow users select personalized themes.
|
||||
regardless of the value of `DEFAULT_THEME`.
|
||||
- `THEME_COLOR_META_TAG`: **#6cc644**: Value of `theme-color` meta tag, used by Android >= 5.0. An invalid color like "none" or "disable" will have the default style. More info: https://developers.google.com/web/updates/2014/11/Support-for-theme-color-in-Chrome-39-for-Android
|
||||
- `MAX_DISPLAY_FILE_SIZE`: **8388608**: Max size of files to be displayed (default is 8MiB)
|
||||
@@ -182,11 +185,11 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
Values can be emoji alias (:smile:) or a unicode emoji.
|
||||
For custom reactions, add a tightly cropped square image to public/img/emoji/reaction_name.png
|
||||
- `CUSTOM_EMOJIS`: **gitea, codeberg, gitlab, git, github, gogs**: Additional Emojis not defined in the utf8 standard.
|
||||
By default we support gitea (:gitea:), to add more copy them to public/img/emoji/emoji_name.png and
|
||||
By default we support Gitea (:gitea:), to add more copy them to public/img/emoji/emoji_name.png and
|
||||
add it to this config.
|
||||
- `DEFAULT_SHOW_FULL_NAME`: **false**: Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used.
|
||||
- `SEARCH_REPO_DESCRIPTION`: **true**: Whether to search within description at repository search on explore page.
|
||||
- `USE_SERVICE_WORKER`: **true**: Whether to enable a Service Worker to cache frontend assets.
|
||||
- `USE_SERVICE_WORKER`: **false**: Whether to enable a Service Worker to cache frontend assets.
|
||||
|
||||
### UI - Admin (`ui.admin`)
|
||||
|
||||
@@ -230,7 +233,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
|
||||
## Server (`server`)
|
||||
|
||||
- `PROTOCOL`: **http**: \[http, https, fcgi, unix, fcgi+unix\]
|
||||
- `PROTOCOL`: **http**: \[http, https, fcgi, http+unix, fcgi+unix\]
|
||||
- `DOMAIN`: **localhost**: Domain name of this server.
|
||||
- `ROOT_URL`: **%(PROTOCOL)s://%(DOMAIN)s:%(HTTP\_PORT)s/**:
|
||||
Overwrite the automatically generated public URL.
|
||||
@@ -238,14 +241,14 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
- `STATIC_URL_PREFIX`: **\<empty\>**:
|
||||
Overwrite this option to request static resources from a different URL.
|
||||
This includes CSS files, images, JS files and web fonts.
|
||||
Avatar images are dynamic resources and still served by gitea.
|
||||
Avatar images are dynamic resources and still served by Gitea.
|
||||
The option can be just a different path, as in `/static`, or another domain, as in `https://cdn.example.com`.
|
||||
Requests are then made as `%(ROOT_URL)s/static/css/index.css` and `https://cdn.example.com/css/index.css` respective.
|
||||
The static files are located in the `public/` directory of the gitea source repository.
|
||||
The static files are located in the `public/` directory of the Gitea source repository.
|
||||
- `HTTP_ADDR`: **0.0.0.0**: HTTP listen address.
|
||||
- If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket
|
||||
defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings.
|
||||
- If `PROTOCOL` is set to `unix` or `fcgi+unix`, this should be the name of the Unix socket file to use.
|
||||
- If `PROTOCOL` is set to `http+unix` or `fcgi+unix`, this should be the name of the Unix socket file to use. Relative paths will be made absolute against the AppWorkPath.
|
||||
- `HTTP_PORT`: **3000**: HTTP listen port.
|
||||
- If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket
|
||||
defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings.
|
||||
@@ -254,7 +257,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
(DMZ) URL for Gitea workers (such as SSH update) accessing web service. In
|
||||
most cases you do not need to change the default value. Alter it only if
|
||||
your SSH server node is not the same as HTTP node. Do not set this variable
|
||||
if `PROTOCOL` is set to `unix`.
|
||||
if `PROTOCOL` is set to `http+unix`.
|
||||
- `PER_WRITE_TIMEOUT`: **30s**: Timeout for any write to the connection. (Set to 0 to
|
||||
disable all timeouts.)
|
||||
- `PER_WRITE_PER_KB_TIMEOUT`: **10s**: Timeout per Kb written to connections.
|
||||
@@ -270,11 +273,11 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
- `SSH_CREATE_AUTHORIZED_KEYS_FILE`: **true**: Gitea will create a authorized_keys file by default when it is not using the internal ssh server. If you intend to use the AuthorizedKeysCommand functionality then you should turn this off.
|
||||
- `SSH_AUTHORIZED_KEYS_BACKUP`: **true**: Enable SSH Authorized Key Backup when rewriting all keys, default is true.
|
||||
- `SSH_TRUSTED_USER_CA_KEYS`: **\<empty\>**: Specifies the public keys of certificate authorities that are trusted to sign user certificates for authentication. Multiple keys should be comma separated. E.g.`ssh-<algorithm> <key>` or `ssh-<algorithm> <key1>, ssh-<algorithm> <key2>`. For more information see `TrustedUserCAKeys` in the sshd config man pages. When empty no file will be created and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` will default to `off`.
|
||||
- `SSH_TRUSTED_USER_CA_KEYS_FILENAME`: **`RUN_USER`/.ssh/gitea-trusted-user-ca-keys.pem**: Absolute path of the `TrustedUserCaKeys` file gitea will manage. If you're running your own ssh server and you want to use the gitea managed file you'll also need to modify your sshd_config to point to this file. The official docker image will automatically work without further configuration.
|
||||
- `SSH_TRUSTED_USER_CA_KEYS_FILENAME`: **`RUN_USER`/.ssh/gitea-trusted-user-ca-keys.pem**: Absolute path of the `TrustedUserCaKeys` file Gitea will manage. If you're running your own ssh server and you want to use the Gitea managed file you'll also need to modify your sshd_config to point to this file. The official docker image will automatically work without further configuration.
|
||||
- `SSH_AUTHORIZED_PRINCIPALS_ALLOW`: **off** or **username, email**: \[off, username, email, anything\]: Specify the principals values that users are allowed to use as principal. When set to `anything` no checks are done on the principal string. When set to `off` authorized principal are not allowed to be set.
|
||||
- `SSH_CREATE_AUTHORIZED_PRINCIPALS_FILE`: **false/true**: Gitea will create a authorized_principals file by default when it is not using the internal ssh server and `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
|
||||
- `SSH_AUTHORIZED_PRINCIPALS_BACKUP`: **false/true**: Enable SSH Authorized Principals Backup when rewriting all keys, default is true if `SSH_AUTHORIZED_PRINCIPALS_ALLOW` is not `off`.
|
||||
- `SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE`: **{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}**: Set the template for the command to passed on authorized keys. Possible keys are: AppPath, AppWorkPath, CustomConf, CustomPath, Key - where Key is a `models.PublicKey` and the others are strings which are shellquoted.
|
||||
- `SSH_AUTHORIZED_KEYS_COMMAND_TEMPLATE`: **{{.AppPath}} --config={{.CustomConf}} serv key-{{.Key.ID}}**: Set the template for the command to passed on authorized keys. Possible keys are: AppPath, AppWorkPath, CustomConf, CustomPath, Key - where Key is a `models/asymkey.PublicKey` and the others are strings which are shellquoted.
|
||||
- `SSH_SERVER_CIPHERS`: **aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128**: For the built-in SSH server, choose the ciphers to support for SSH connections, for system SSH this setting has no effect.
|
||||
- `SSH_SERVER_KEY_EXCHANGES`: **diffie-hellman-group1-sha1, diffie-hellman-group14-sha1, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, curve25519-sha256@libssh.org**: For the built-in SSH server, choose the key exchange algorithms to support for SSH connections, for system SSH this setting has no effect.
|
||||
- `SSH_SERVER_MACS`: **hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1, hmac-sha1-96**: For the built-in SSH server, choose the MACs to support for SSH connections, for system SSH this setting has no effect
|
||||
@@ -296,11 +299,11 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
- `STATIC_CACHE_TIME`: **6h**: Web browser cache time for static resources on `custom/`, `public/` and all uploaded avatars. Note that this cache is disabled when `RUN_MODE` is "dev".
|
||||
- `ENABLE_GZIP`: **false**: Enable gzip compression for runtime-generated content, static resources excluded.
|
||||
- `ENABLE_PPROF`: **false**: Application profiling (memory and cpu). For "web" command it listens on localhost:6060. For "serv" command it dumps to disk at `PPROF_DATA_PATH` as `(cpuprofile|memprofile)_<username>_<temporary id>`
|
||||
- `PPROF_DATA_PATH`: **data/tmp/pprof**: `PPROF_DATA_PATH`, use an absolute path when you start gitea as service
|
||||
- `PPROF_DATA_PATH`: **data/tmp/pprof**: `PPROF_DATA_PATH`, use an absolute path when you start Gitea as service
|
||||
- `LANDING_PAGE`: **home**: Landing page for unauthenticated users \[home, explore, organizations, login\].
|
||||
|
||||
- `LFS_START_SERVER`: **false**: Enables git-lfs support.
|
||||
- `LFS_CONTENT_PATH`: **%(APP_DATA_PATH)/lfs**: DEPRECATED: Default LFS content path. (if it is on local storage.)
|
||||
- `LFS_START_SERVER`: **false**: Enables Git LFS support.
|
||||
- `LFS_CONTENT_PATH`: **%(APP_DATA_PATH)/lfs**: Default LFS content path. (if it is on local storage.) **DEPRECATED** use settings in `[lfs]`.
|
||||
- `LFS_JWT_SECRET`: **\<empty\>**: LFS authentication secret, change this a unique string.
|
||||
- `LFS_HTTP_AUTH_EXPIRY`: **20m**: LFS authentication validity period in time.Duration, pushes taking longer than this may fail.
|
||||
- `LFS_MAX_FILE_SIZE`: **0**: Maximum allowed LFS file size in bytes (Set to 0 for no limit).
|
||||
@@ -308,6 +311,42 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
|
||||
- `REDIRECT_OTHER_PORT`: **false**: If true and `PROTOCOL` is https, allows redirecting http requests on `PORT_TO_REDIRECT` to the https port Gitea listens on.
|
||||
- `PORT_TO_REDIRECT`: **80**: Port for the http redirection service to listen on. Used when `REDIRECT_OTHER_PORT` is true.
|
||||
- `SSL_MIN_VERSION`: **TLSv1.2**: Set the minimum version of ssl support.
|
||||
- `SSL_MAX_VERSION`: **\<empty\>**: Set the maximum version of ssl support.
|
||||
- `SSL_CURVE_PREFERENCES`: **X25519,P256**: Set the preferred curves,
|
||||
- `SSL_CIPHER_SUITES`: **ecdhe_ecdsa_with_aes_256_gcm_sha384,ecdhe_rsa_with_aes_256_gcm_sha384,ecdhe_ecdsa_with_aes_128_gcm_sha256,ecdhe_rsa_with_aes_128_gcm_sha256,ecdhe_ecdsa_with_chacha20_poly1305,ecdhe_rsa_with_chacha20_poly1305**: Set the preferred cipher suites.
|
||||
- If there is not hardware support for AES suites by default the cha cha suites will be preferred over the AES suites
|
||||
- supported suites as of go 1.17 are:
|
||||
- TLS 1.0 - 1.2 cipher suites
|
||||
- "rsa_with_rc4_128_sha"
|
||||
- "rsa_with_3des_ede_cbc_sha"
|
||||
- "rsa_with_aes_128_cbc_sha"
|
||||
- "rsa_with_aes_256_cbc_sha"
|
||||
- "rsa_with_aes_128_cbc_sha256"
|
||||
- "rsa_with_aes_128_gcm_sha256"
|
||||
- "rsa_with_aes_256_gcm_sha384"
|
||||
- "ecdhe_ecdsa_with_rc4_128_sha"
|
||||
- "ecdhe_ecdsa_with_aes_128_cbc_sha"
|
||||
- "ecdhe_ecdsa_with_aes_256_cbc_sha"
|
||||
- "ecdhe_rsa_with_rc4_128_sha"
|
||||
- "ecdhe_rsa_with_3des_ede_cbc_sha"
|
||||
- "ecdhe_rsa_with_aes_128_cbc_sha"
|
||||
- "ecdhe_rsa_with_aes_256_cbc_sha"
|
||||
- "ecdhe_ecdsa_with_aes_128_cbc_sha256"
|
||||
- "ecdhe_rsa_with_aes_128_cbc_sha256"
|
||||
- "ecdhe_rsa_with_aes_128_gcm_sha256"
|
||||
- "ecdhe_ecdsa_with_aes_128_gcm_sha256"
|
||||
- "ecdhe_rsa_with_aes_256_gcm_sha384"
|
||||
- "ecdhe_ecdsa_with_aes_256_gcm_sha384"
|
||||
- "ecdhe_rsa_with_chacha20_poly1305_sha256"
|
||||
- "ecdhe_ecdsa_with_chacha20_poly1305_sha256"
|
||||
- TLS 1.3 cipher suites
|
||||
- "aes_128_gcm_sha256"
|
||||
- "aes_256_gcm_sha384"
|
||||
- "chacha20_poly1305_sha256"
|
||||
- Aliased names
|
||||
- "ecdhe_rsa_with_chacha20_poly1305" is an alias for "ecdhe_rsa_with_chacha20_poly1305_sha256"
|
||||
- "ecdhe_ecdsa_with_chacha20_poly1305" is alias for "ecdhe_ecdsa_with_chacha20_poly1305_sha256"
|
||||
- `ENABLE_LETSENCRYPT`: **false**: If enabled you must set `DOMAIN` to valid internet facing domain (ensure DNS is set and port 80 is accessible by letsencrypt validation server).
|
||||
By using Lets Encrypt **you must consent** to their [terms of service](https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf).
|
||||
- `LETSENCRYPT_ACCEPTTOS`: **false**: This is an explicit check that you accept the terms of service for Let's Encrypt.
|
||||
@@ -339,7 +378,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
||||
- `require`: Enable TLS without any verifications.
|
||||
- `verify-ca`: Enable TLS with verification of the database server certificate against its root certificate.
|
||||
- `verify-full`: Enable TLS and verify the database server name matches the given certificate in either the `Common Name` or `Subject Alternative Name` fields.
|
||||
- `SQLITE_TIMEOUT`: **500**: Query timeout for sqlite3 only.
|
||||
- `SQLITE_TIMEOUT`: **500**: Query timeout for SQLite3 only.
|
||||
- `ITERATE_BUFFER_SIZE`: **50**: Internal buffer size for iterating.
|
||||
- `CHARSET`: **utf8mb4**: For MySQL only, either "utf8" or "utf8mb4". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
|
||||
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
|
||||
@@ -380,6 +419,8 @@ relation to port exhaustion.
|
||||
|
||||
## Queue (`queue` and `queue.*`)
|
||||
|
||||
Configuration at `[queue]` will set defaults for queues with overrides for individual queues at `[queue.*]`. (However see below.)
|
||||
|
||||
- `TYPE`: **persistable-channel**: General queue type, currently support: `persistable-channel` (uses a LevelDB internally), `channel`, `level`, `redis`, `dummy`
|
||||
- `DATADIR`: **queues/**: Base DataDir for storing persistent and level queues. `DATADIR` for individual queues can be set in `queue.name` sections but will default to `DATADIR/`**`common`**. (Previously each queue would default to `DATADIR/`**`name`**.)
|
||||
- `LENGTH`: **20**: Maximal queue size before channel queues block
|
||||
@@ -398,6 +439,37 @@ relation to port exhaustion.
|
||||
- `BOOST_TIMEOUT`: **5m**: Boost workers will timeout after this long.
|
||||
- `BOOST_WORKERS`: **1** (v1.14 and before: **5**): This many workers will be added to the worker pool if there is a boost.
|
||||
|
||||
Gitea creates the following non-unique queues:
|
||||
|
||||
- `code_indexer`
|
||||
- `issue_indexer`
|
||||
- `notification-service`
|
||||
- `task`
|
||||
- `mail`
|
||||
- `push_update`
|
||||
|
||||
And the following unique queues:
|
||||
|
||||
- `repo_stats_update`
|
||||
- `repo-archive`
|
||||
- `mirror`
|
||||
- `pr_patch_checker`
|
||||
|
||||
Certain queues have defaults that override the defaults set in `[queue]` (this occurs mostly to support older configuration):
|
||||
|
||||
- `[queue.issue_indexer]`
|
||||
- `TYPE` this will default to `[queue]` `TYPE` if it is set but if not it will appropriately convert `[indexer]` `ISSUE_INDEXER_QUEUE_TYPE` if that is set.
|
||||
- `LENGTH` will default to `[indexer]` `UPDATE_BUFFER_LEN` if that is set.
|
||||
- `BATCH_LENGTH` will default to `[indexer]` `ISSUE_INDEXER_QUEUE_BATCH_NUMBER` if that is set.
|
||||
- `DATADIR` will default to `[indexer]` `ISSUE_INDEXER_QUEUE_DIR` if that is set.
|
||||
- `CONN_STR` will default to `[indexer]` `ISSUE_INDEXER_QUEUE_CONN_STR` if that is set.
|
||||
- `[queue.mailer]`
|
||||
- `LENGTH` will default to **100** or whatever `[mailer]` `SEND_BUFFER_LEN` is.
|
||||
- `[queue.pr_patch_checker]`
|
||||
- `LENGTH` will default to **1000** or whatever `[repository]` `PULL_REQUEST_QUEUE_LENGTH` is.
|
||||
- `[queue.mirror]`
|
||||
- `LENGTH` will default to **1000** or whatever `[repository]` `MIRROR_QUEUE_LENGTH` is.
|
||||
|
||||
## Admin (`admin`)
|
||||
|
||||
- `DEFAULT_EMAIL_NOTIFICATIONS`: **enabled**: Default configuration for email notifications for users (user configurable). Options: enabled, onmention, disabled
|
||||
@@ -405,7 +477,7 @@ relation to port exhaustion.
|
||||
|
||||
## Security (`security`)
|
||||
|
||||
- `INSTALL_LOCK`: **false**: Disallow access to the install page.
|
||||
- `INSTALL_LOCK`: **false**: Controls access to the installation page. When set to "true", the installation page is not accessible.
|
||||
- `SECRET_KEY`: **\<random at every install\>**: Global secret key. This should be changed.
|
||||
- `LOGIN_REMEMBER_DAYS`: **7**: Cookie lifetime, in days.
|
||||
- `COOKIE_USERNAME`: **gitea\_awesome**: Name of the cookie used to store the current username.
|
||||
@@ -418,15 +490,15 @@ relation to port exhaustion.
|
||||
- `REVERSE_PROXY_LIMIT`: **1**: Interpret X-Forwarded-For header or the X-Real-IP header and set this as the remote IP for the request.
|
||||
Number of trusted proxy count. Set to zero to not use these headers.
|
||||
- `REVERSE_PROXY_TRUSTED_PROXIES`: **127.0.0.0/8,::1/128**: List of IP addresses and networks separated by comma of trusted proxy servers. Use `*` to trust all.
|
||||
- `DISABLE_GIT_HOOKS`: **true**: Set to `false` to enable users with git hook privilege to create custom git hooks.
|
||||
WARNING: Custom git hooks can be used to perform arbitrary code execution on the host operating system.
|
||||
- `DISABLE_GIT_HOOKS`: **true**: Set to `false` to enable users with Git Hook privilege to create custom Git Hooks.
|
||||
WARNING: Custom Git Hooks can be used to perform arbitrary code execution on the host operating system.
|
||||
This enables the users to access and modify this config file and the Gitea database and interrupt the Gitea service.
|
||||
By modifying the Gitea database, users can gain Gitea administrator privileges.
|
||||
It also enables them to access other resources available to the user on the operating system that is running the
|
||||
Gitea instance and perform arbitrary actions in the name of the Gitea OS user.
|
||||
This maybe harmful to you website or your operating system.
|
||||
- `DISABLE_WEBHOOKS`: **false**: Set to `true` to disable webhooks feature.
|
||||
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to gitea repositories you should set the environment appropriately.
|
||||
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to Gitea repositories you should set the environment appropriately.
|
||||
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
|
||||
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.
|
||||
- `INTERNAL_TOKEN_URI`: **<empty>**: Instead of defining internal token in the configuration, this configuration option can be used to give Gitea a path to a file that contains the internal token (example value: `file:/etc/gitea/internal_token`)
|
||||
@@ -440,6 +512,7 @@ relation to port exhaustion.
|
||||
- spec - use one or more special characters as ``!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~``
|
||||
- off - do not check password complexity
|
||||
- `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed.
|
||||
- `SUCCESSFUL_TOKENS_CACHE_SIZE`: **20**: Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security.
|
||||
|
||||
## OpenID (`openid`)
|
||||
|
||||
@@ -502,11 +575,12 @@ relation to port exhaustion.
|
||||
- `HCAPTCHA_SITEKEY`: **""**: Sign up at https://www.hcaptcha.com/ to get a sitekey for hcaptcha.
|
||||
- `DEFAULT_KEEP_EMAIL_PRIVATE`: **false**: By default set users to keep their email address private.
|
||||
- `DEFAULT_ALLOW_CREATE_ORGANIZATION`: **true**: Allow new users to create organizations by default.
|
||||
- `DEFAULT_USER_IS_RESTRICTED`: **false**: Give new users restricted permissions by default
|
||||
- `DEFAULT_ENABLE_DEPENDENCIES`: **true**: Enable this to have dependencies enabled by default.
|
||||
- `ALLOW_CROSS_REPOSITORY_DEPENDENCIES` : **true** Enable this to allow dependencies on issues from any repository where the user is granted access.
|
||||
- `ENABLE_USER_HEATMAP`: **true**: Enable this to display the heatmap on users profiles.
|
||||
- `ENABLE_TIMETRACKING`: **true**: Enable Timetracking feature.
|
||||
- `DEFAULT_ENABLE_TIMETRACKING`: **true**: Allow repositories to use timetracking by deault.
|
||||
- `DEFAULT_ENABLE_TIMETRACKING`: **true**: Allow repositories to use timetracking by default.
|
||||
- `DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME`: **true**: Only allow users with write permissions to track time.
|
||||
- `EMAIL_DOMAIN_WHITELIST`: **\<empty\>**: If non-empty, list of domain names that can only be used to register
|
||||
on this instance.
|
||||
@@ -519,19 +593,18 @@ relation to port exhaustion.
|
||||
- `ALLOWED_USER_VISIBILITY_MODES`: **public,limited,private**: Set which visibility modes a user can have
|
||||
- `DEFAULT_ORG_VISIBILITY`: **public**: Set default visibility mode for organisations, either "public", "limited" or "private".
|
||||
- `DEFAULT_ORG_MEMBER_VISIBLE`: **false** True will make the membership of the users visible when added to the organisation.
|
||||
- `ALLOW_ONLY_INTERNAL_REGISTRATION`: **false** Set to true to force registration only via gitea.
|
||||
- `ALLOW_ONLY_INTERNAL_REGISTRATION`: **false** Set to true to force registration only via Gitea.
|
||||
- `ALLOW_ONLY_EXTERNAL_REGISTRATION`: **false** Set to true to force registration only using third-party services.
|
||||
- `NO_REPLY_ADDRESS`: **noreply.DOMAIN** Value for the domain part of the user's email address in the git log if user has set KeepEmailPrivate to true. DOMAIN resolves to the value in server.DOMAIN.
|
||||
- `NO_REPLY_ADDRESS`: **noreply.DOMAIN** Value for the domain part of the user's email address in the Git log if user has set KeepEmailPrivate to true. DOMAIN resolves to the value in server.DOMAIN.
|
||||
The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS.
|
||||
- `USER_DELETE_WITH_COMMENTS_MAX_TIME`: **0** Minimum amount of time a user must exist before comments are kept when the user is deleted.
|
||||
- `VALID_SITE_URL_SCHEMES`: **http, https**: Valid site url schemes for user profiles
|
||||
|
||||
### Service - Expore (`service.explore`)
|
||||
### Service - Explore (`service.explore`)
|
||||
|
||||
- `REQUIRE_SIGNIN_VIEW`: **false**: Only allow signed in users to view the explore pages.
|
||||
- `DISABLE_USERS_PAGE`: **false**: Disable the users explore page.
|
||||
|
||||
|
||||
## SSH Minimum Key Sizes (`ssh.minimum_key_sizes`)
|
||||
|
||||
Define allowed algorithms and their minimum key length (use -1 to disable a type):
|
||||
@@ -545,10 +618,18 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||
|
||||
- `QUEUE_LENGTH`: **1000**: Hook task queue length. Use caution when editing this value.
|
||||
- `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks.
|
||||
- `ALLOWED_HOST_LIST`: **external**: Since 1.15.7. Default to `*` for 1.15.x, `external` for 1.16 and later. Webhook can only call allowed hosts for security reasons. Comma separated list.
|
||||
- Built-in networks:
|
||||
- `loopback`: 127.0.0.0/8 for IPv4 and ::1/128 for IPv6, localhost is included.
|
||||
- `private`: RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and RFC 4193 (FC00::/7). Also called LAN/Intranet.
|
||||
- `external`: A valid non-private unicast IP, you can access all hosts on public internet.
|
||||
- `*`: All hosts are allowed.
|
||||
- CIDR list: `1.2.3.0/8` for IPv4 and `2001:db8::/32` for IPv6
|
||||
- Wildcard hosts: `*.mydomain.com`, `192.168.100.*`
|
||||
- `SKIP_TLS_VERIFY`: **false**: Allow insecure certification.
|
||||
- `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page.
|
||||
- `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
|
||||
- `PROXY_HOSTS`: ****: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
|
||||
- `PROXY_URL`: **\<empty\>**: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy. If not given, will use global proxy setting.
|
||||
- `PROXY_HOSTS`: **\<empty\>`**: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts. If not given, will use global proxy setting.
|
||||
|
||||
## Mailer (`mailer`)
|
||||
|
||||
@@ -562,6 +643,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||
- Otherwise if `IS_TLS_ENABLED=false` and the server supports `STARTTLS` this will be used. Thus if `STARTTLS` is preferred you should set `IS_TLS_ENABLED=false`.
|
||||
- `FROM`: **\<empty\>**: Mail from address, RFC 5322. This can be just an email address, or
|
||||
the "Name" \<email@example.com\> format.
|
||||
- `ENVELOPE_FROM`: **\<empty\>**: Address set as the From address on the SMTP mail envelope. Set to `<>` to send an empty address.
|
||||
- `USER`: **\<empty\>**: Username of mailing user (usually the sender's e-mail address).
|
||||
- `PASSWD`: **\<empty\>**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password.
|
||||
- Please note: authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via `STARTTLS`) or `HOST=localhost`. See [Email Setup]({{< relref "doc/usage/email-setup.en-us.md" >}}) for more information.
|
||||
@@ -576,7 +658,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||
- `MAILER_TYPE`: **smtp**: \[smtp, sendmail, dummy\]
|
||||
- **smtp** Use SMTP to send mail
|
||||
- **sendmail** Use the operating system's `sendmail` command instead of SMTP.
|
||||
This is common on linux systems.
|
||||
This is common on Linux systems.
|
||||
- **dummy** Send email messages to the log as a testing phase.
|
||||
- Note that enabling sendmail will ignore all other `mailer` settings except `ENABLED`,
|
||||
`FROM`, `SUBJECT_PREFIX` and `SENDMAIL_PATH`.
|
||||
@@ -585,7 +667,8 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||
command or full path).
|
||||
- `SENDMAIL_ARGS`: **_empty_**: Specify any extra sendmail arguments.
|
||||
- `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail
|
||||
- `SEND_BUFFER_LEN`: **100**: Buffer length of mailing queue.
|
||||
- `SENDMAIL_CONVERT_CRLF`: **true**: Most versions of sendmail prefer LF line endings rather than CRLF line endings. Set this to false if your version of sendmail requires CRLF line endings.
|
||||
- `SEND_BUFFER_LEN`: **100**: Buffer length of mailing queue. **DEPRECATED** use `LENGTH` in `[queue.mailer]`
|
||||
|
||||
## Cache (`cache`)
|
||||
|
||||
@@ -628,6 +711,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||
- `AVATAR_MAX_WIDTH`: **4096**: Maximum avatar image width in pixels.
|
||||
- `AVATAR_MAX_HEIGHT`: **3072**: Maximum avatar image height in pixels.
|
||||
- `AVATAR_MAX_FILE_SIZE`: **1048576** (1Mb): Maximum avatar image file size in bytes.
|
||||
- `AVATAR_RENDERED_SIZE_FACTOR`: **3**: The multiplication factor for rendered avatar images. Larger values result in finer rendering on HiDPI devices.
|
||||
|
||||
- `REPOSITORY_AVATAR_STORAGE_TYPE`: **default**: Storage type defined in `[storage.xxx]`. Default is `default` which will read `[storage]` if no section `[storage]` will be a type `local`.
|
||||
- `REPOSITORY_AVATAR_UPLOAD_PATH`: **data/repo-avatars**: Path to store repository avatar image files.
|
||||
@@ -648,7 +732,7 @@ Default templates for project boards:
|
||||
## Issue and pull request attachments (`attachment`)
|
||||
|
||||
- `ENABLED`: **true**: Whether issue and pull request attachments are enabled.
|
||||
- `ALLOWED_TYPES`: **.docx,.gif,.gz,.jpeg,.jpg,.log,.pdf,.png,.pptx,.txt,.xlsx,.zip**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
|
||||
- `ALLOWED_TYPES`: **.docx,.gif,.gz,.jpeg,.jpg,mp4,.log,.pdf,.png,.pptx,.txt,.xlsx,.zip**: Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
|
||||
- `MAX_SIZE`: **4**: Maximum size (MB).
|
||||
- `MAX_FILES`: **5**: Maximum number of attachments that can be uploaded at once.
|
||||
- `STORAGE_TYPE`: **local**: Storage type for attachments, `local` for local disk or `minio` for s3 compatible object storage service, default is `local` or other name defined with `[storage.xxx]`
|
||||
@@ -669,11 +753,11 @@ Default templates for project boards:
|
||||
- `LEVEL`: **Info**: General log level. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
|
||||
- `STACKTRACE_LEVEL`: **None**: Default log level at which to log create stack traces. \[Trace, Debug, Info, Warn, Error, Critical, Fatal, None\]
|
||||
- `ROUTER_LOG_LEVEL`: **Info**: The log level that the router should log at. (If you are setting the access log, its recommended to place this at Debug.)
|
||||
- `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default gitea logger.)
|
||||
- `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default Gitea logger.)
|
||||
NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`.
|
||||
- `ENABLE_ACCESS_LOG`: **false**: Creates an access.log in NCSA common log format, or as per the following template
|
||||
- `ENABLE_SSH_LOG`: **false**: save ssh log to log file
|
||||
- `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default gitea logger.)
|
||||
- `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default Gitea logger.)
|
||||
- `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log.
|
||||
- The following variables are available:
|
||||
- `Ctx`: the `context.Context` of the request.
|
||||
@@ -740,41 +824,43 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||
|
||||
- `ENABLED`: **true**: Enable service.
|
||||
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
|
||||
- `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`.
|
||||
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`.
|
||||
- `OLDER_THAN`: **24h**: Archives created more than `OLDER_THAN` ago are subject to deletion, e.g. `12h`.
|
||||
|
||||
#### Cron - Update Mirrors (`cron.update_mirrors`)
|
||||
|
||||
- `SCHEDULE`: **@every 10m**: Cron syntax for scheduling update mirrors, e.g. `@every 3h`.
|
||||
- `NO_SUCCESS_NOTICE`: **true**: The cron task for update mirrors success report is not very useful - as it just means that the mirrors have been queued. Therefore this is turned off by default.
|
||||
- `PULL_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling pull mirror updating).
|
||||
- `PUSH_LIMIT`: **50**: Limit the number of mirrors added to the queue to this number (negative values mean no limit, 0 will result in no mirrors being queued effectively disabling push mirror updating).
|
||||
|
||||
#### Cron - Repository Health Check (`cron.repo_health_check`)
|
||||
|
||||
- `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository health check.
|
||||
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check.
|
||||
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
|
||||
- `ARGS`: **\<empty\>**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
|
||||
|
||||
#### Cron - Repository Statistics Check (`cron.check_repo_stats`)
|
||||
|
||||
- `RUN_AT_START`: **true**: Run repository statistics check at start time.
|
||||
- `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository statistics check.
|
||||
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check.
|
||||
|
||||
### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
|
||||
|
||||
- `ENABLED`: **true**: Enable cleanup hook_task job.
|
||||
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
|
||||
- `SCHEDULE`: **@every 24h**: Cron syntax for cleaning hook_task table.
|
||||
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table.
|
||||
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
|
||||
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
|
||||
- `NUMBER_TO_KEEP`: **10**: If CLEANUP_TYPE is set to PerWebhook, this is number of hook_task records to keep for a webhook (i.e. keep the most recent x deliveries).
|
||||
|
||||
#### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`)
|
||||
|
||||
- `SCHEDULE`: **@every 24h** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
|
||||
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
|
||||
|
||||
#### Cron - Sync External Users (`cron.sync_external_users`)
|
||||
|
||||
- `SCHEDULE`: **@every 24h** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
|
||||
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
|
||||
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
|
||||
|
||||
### Extended cron tasks (not enabled by default)
|
||||
@@ -821,12 +907,19 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||
- `ENABLED`: **false**: Enable service.
|
||||
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
|
||||
- `NO_SUCCESS_NOTICE`: **false**: Set to true to switch off success notices.
|
||||
- `SCHEDULE`: **@every 128h**: Cron syntax for scheduling a work, e.g. `@every 128h`.
|
||||
- `SCHEDULE`: **@every 168h**: Cron syntax to set how often to check.
|
||||
- `OLDER_THAN`: **@every 8760h**: any action older than this expression will be deleted from database, suggest using `8760h` (1 year) because that's the max length of heatmap.
|
||||
|
||||
#### Cron - Check for new Gitea versions ('cron.update_checker')
|
||||
- `ENABLED`: **false**: Enable service.
|
||||
- `RUN_AT_START`: **false**: Run tasks at start up time (if ENABLED).
|
||||
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
|
||||
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
|
||||
- `HTTP_ENDPOINT`: **https://dl.gitea.io/gitea/version.json**: the endpoint that Gitea will check for newer versions
|
||||
|
||||
## Git (`git`)
|
||||
|
||||
- `PATH`: **""**: The path of git executable. If empty, Gitea searches through the PATH environment.
|
||||
- `PATH`: **""**: The path of Git executable. If empty, Gitea searches through the PATH environment.
|
||||
- `DISABLE_DIFF_HIGHLIGHT`: **false**: Disables highlight of added and removed changes.
|
||||
- `MAX_GIT_DIFF_LINES`: **1000**: Max number of lines allowed of a single file in diff view.
|
||||
- `MAX_GIT_DIFF_LINE_CHARACTERS`: **5000**: Max character count per line highlighted in diff view.
|
||||
@@ -834,11 +927,14 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||
- `COMMITS_RANGE_SIZE`: **50**: Set the default commits range size
|
||||
- `BRANCHES_RANGE_SIZE`: **20**: Set the default branches range size
|
||||
- `GC_ARGS`: **\<empty\>**: Arguments for command `git gc`, e.g. `--aggressive --auto`. See more on http://git-scm.com/docs/git-gc/
|
||||
- `ENABLE_AUTO_GIT_WIRE_PROTOCOL`: **true**: If use git wire protocol version 2 when git version >= 2.18, default is true, set to false when you always want git wire protocol version 1
|
||||
- `ENABLE_AUTO_GIT_WIRE_PROTOCOL`: **true**: If use Git wire protocol version 2 when Git version >= 2.18, default is true, set to false when you always want Git wire protocol version 1
|
||||
- `PULL_REQUEST_PUSH_MESSAGE`: **true**: Respond to pushes to a non-default branch with a URL for creating a Pull Request (if the repository has them enabled)
|
||||
- `VERBOSE_PUSH`: **true**: Print status information about pushes as they are being processed.
|
||||
- `VERBOSE_PUSH_DELAY`: **5s**: Only print verbose information if push takes longer than this delay.
|
||||
- `LARGE_OBJECT_THRESHOLD`: **1048576**: (Go-Git only), don't cache objects greater than this in memory. (Set to 0 to disable.)
|
||||
- `DISABLE_CORE_PROTECT_NTFS`: **false** Set to true to forcibly set `core.protectNTFS` to false.
|
||||
- `DISABLE_PARTIAL_CLONE`: **false** Disable the usage of using partial clones for git.
|
||||
|
||||
## Git - Timeout settings (`git.timeout`)
|
||||
- `DEFAUlT`: **360**: Git operations default timeout seconds.
|
||||
- `MIGRATE`: **600**: Migrate external repositories timeout seconds.
|
||||
@@ -850,6 +946,8 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||
## Metrics (`metrics`)
|
||||
|
||||
- `ENABLED`: **false**: Enables /metrics endpoint for prometheus.
|
||||
- `ENABLED_ISSUE_BY_LABEL`: **false**: Enable issue by label metrics with format `gitea_issues_by_label{label="bug"} 2`.
|
||||
- `ENABLED_ISSUE_BY_REPOSITORY`: **false**: Enable issue by repository metrics with format `gitea_issues_by_repository{repository="org/repo"} 5`.
|
||||
- `TOKEN`: **\<empty\>**: You need to specify the token, if you want to include in the authorization the metrics . The same token need to be used in prometheus parameters `bearer_token` or `bearer_token_file`.
|
||||
|
||||
## API (`api`)
|
||||
@@ -857,7 +955,7 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||
- `ENABLE_SWAGGER`: **true**: Enables /api/swagger, /api/v1/swagger etc. endpoints. True or false; default is true.
|
||||
- `MAX_RESPONSE_ITEMS`: **50**: Max number of items in a page.
|
||||
- `DEFAULT_PAGING_NUM`: **30**: Default paging number of API.
|
||||
- `DEFAULT_GIT_TREES_PER_PAGE`: **1000**: Default and maximum number of items per page for git trees API.
|
||||
- `DEFAULT_GIT_TREES_PER_PAGE`: **1000**: Default and maximum number of items per page for Git trees API.
|
||||
- `DEFAULT_MAX_BLOB_SIZE`: **10485760**: Default max size of a blob that can be return by the blobs API.
|
||||
|
||||
## OAuth2 (`oauth2`)
|
||||
@@ -873,15 +971,16 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
|
||||
|
||||
## i18n (`i18n`)
|
||||
|
||||
- `LANGS`: **en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR**: List of locales shown in language selector
|
||||
- `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어**: Visible names corresponding to the locales
|
||||
- `LANGS`: **en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID,ml-IN**: List of locales shown in language selector
|
||||
- `NAMES`: **English,简体中文,繁體中文(香港),繁體中文(台灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,Português de Portugal,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어,ελληνικά,فارسی,magyar nyelv,bahasa Indonesia,മലയാളം**: Visible names corresponding to the locales
|
||||
|
||||
## U2F (`U2F`)
|
||||
- `APP_ID`: **`ROOT_URL`**: Declares the facet of the application. Requires HTTPS.
|
||||
- `TRUSTED_FACETS`: List of additional facets which are trusted. This is not support by all browsers.
|
||||
## U2F (`U2F`) **DEPRECATED**
|
||||
- `APP_ID`: **`ROOT_URL`**: Declares the facet of the application which is used for authentication of previously registered U2F keys. Requires HTTPS.
|
||||
|
||||
## Markup (`markup`)
|
||||
|
||||
- `MERMAID_MAX_SOURCE_CHARACTERS`: **5000**: Set the maximum size of a Mermaid source. (Set to -1 to disable)
|
||||
|
||||
Gitea can support Markup using external tools. The example below will add a markup named `asciidoc`.
|
||||
|
||||
```ini
|
||||
@@ -926,6 +1025,14 @@ Multiple sanitisation rules can be defined by adding unique subsections, e.g. `[
|
||||
To apply a sanitisation rules only for a specify external renderer they must use the renderer name, e.g. `[markup.sanitizer.asciidoc.rule-1]`.
|
||||
If the rule is defined above the renderer ini section or the name does not match a renderer it is applied to every renderer.
|
||||
|
||||
## Highlight Mappings (`highlight.mapping`)
|
||||
|
||||
- `file_extension e.g. .toml`: **language e.g. ini**. File extension to language mapping overrides.
|
||||
|
||||
- Gitea will highlight files using the `linguist-language` or `gitlab-language` attribute from the `.gitattributes` file
|
||||
if available. If this is not set or the language is unavailable, the file extension will be looked up
|
||||
in this mapping or the filetype using heuristics.
|
||||
|
||||
## Time (`time`)
|
||||
|
||||
- `FORMAT`: Time format to display on UI. i.e. RFC1123 or 2006-01-02 15:04:05
|
||||
@@ -944,11 +1051,19 @@ Task queue configuration has been moved to `queue.task`. However, the below conf
|
||||
- `MAX_ATTEMPTS`: **3**: Max attempts per http/https request on migrations.
|
||||
- `RETRY_BACKOFF`: **3**: Backoff time per http/https request retry (seconds)
|
||||
- `ALLOWED_DOMAINS`: **\<empty\>**: Domains allowlist for migrating repositories, default is blank. It means everything will be allowed. Multiple domains could be separated by commas.
|
||||
- `BLOCKED_DOMAINS`: **\<empty\>**: Domains blocklist for migrating repositories, default is blank. Multiple domains could be separated by commas. When `ALLOWED_DOMAINS` is not blank, this option will be ignored.
|
||||
- `BLOCKED_DOMAINS`: **\<empty\>**: Domains blocklist for migrating repositories, default is blank. Multiple domains could be separated by commas. When `ALLOWED_DOMAINS` is not blank, this option has a higher priority to deny domains.
|
||||
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918, RFC 1122, RFC 4632 and RFC 4291
|
||||
- `SKIP_TLS_VERIFY`: **false**: Allow skip tls verify
|
||||
|
||||
## Federation (`federation`)
|
||||
|
||||
- `ENABLED`: **true**: Enable/Disable federation capabilities
|
||||
|
||||
## Mirror (`mirror`)
|
||||
|
||||
- `ENABLED`: **true**: Enables the mirror functionality. Set to **false** to disable all mirrors.
|
||||
- `DISABLE_NEW_PULL`: **false**: Disable the creation of **new** pull mirrors. Pre-existing mirrors remain valid. Will be ignored if `mirror.ENABLED` is `false`.
|
||||
- `DISABLE_NEW_PUSH`: **false**: Disable the creation of **new** push mirrors. Pre-existing mirrors remain valid. Will be ignored if `mirror.ENABLED` is `false`.
|
||||
- `DEFAULT_INTERVAL`: **8h**: Default interval between each check
|
||||
- `MIN_INTERVAL`: **10m**: Minimum interval for checking. (Must be >1m).
|
||||
|
||||
@@ -1019,6 +1134,19 @@ is `data/repo-archive` and the default of `MINIO_BASE_PATH` is `repo-archive/`.
|
||||
- `MINIO_BASE_PATH`: **repo-archive/**: Minio base path on the bucket only available when `STORAGE_TYPE` is `minio`
|
||||
- `MINIO_USE_SSL`: **false**: Minio enabled ssl only available when `STORAGE_TYPE` is `minio`
|
||||
|
||||
## Proxy (`proxy`)
|
||||
|
||||
- `PROXY_ENABLED`: **false**: Enable the proxy if true, all requests to external via HTTP will be affected, if false, no proxy will be used even environment http_proxy/https_proxy
|
||||
- `PROXY_URL`: **\<empty\>**: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy
|
||||
- `PROXY_HOSTS`: **\<empty\>**: Comma separated list of host names requiring proxy. Glob patterns (*) are accepted; use ** to match all hosts.
|
||||
|
||||
i.e.
|
||||
```ini
|
||||
PROXY_ENABLED = true
|
||||
PROXY_URL = socks://127.0.0.1:1080
|
||||
PROXY_HOSTS = *.github.com
|
||||
```
|
||||
|
||||
## Other (`other`)
|
||||
|
||||
- `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer.
|
||||
|
@@ -36,6 +36,11 @@ menu:
|
||||
- `MAX_CREATION_LIMIT`: 全局最大每个用户创建的git工程数目, `-1` 表示没限制。
|
||||
- `PULL_REQUEST_QUEUE_LENGTH`: 小心:合并请求测试队列的长度,尽量放大。
|
||||
|
||||
### Repository - Release (`repository.release`)
|
||||
|
||||
- `ALLOWED_TYPES`: **\<empty\>**: 允许扩展名的列表,用逗号分隔 (`.zip`), mime 类型 (`text/plain`) 或者匹配符号 (`image/*`, `audio/*`, `video/*`). 空值或者 `*/*` 允许所有类型。
|
||||
- `DEFAULT_PAGING_NUM`: **10**: 默认的发布版本页面分页。
|
||||
|
||||
## UI (`ui`)
|
||||
|
||||
- `EXPLORE_PAGING_NUM`: 探索页面每页显示的仓库数量。
|
||||
@@ -79,14 +84,14 @@ menu:
|
||||
|
||||
## Database (`database`)
|
||||
|
||||
- `DB_TYPE`: 数据库类型,可选 `mysql`, `postgres`, `mssql`, `tidb` 或 `sqlite3`。
|
||||
- `DB_TYPE`: 数据库类型,可选 `mysql`, `postgres`, `mssql` 或 `sqlite3`。
|
||||
- `HOST`: 数据库服务器地址和端口。
|
||||
- `NAME`: 数据库名称。
|
||||
- `USER`: 数据库用户名。
|
||||
- `PASSWD`: 数据库用户密码。
|
||||
- `SSL_MODE`: MySQL 或 PostgreSQL数据库是否启用SSL模式。
|
||||
- `CHARSET`: **utf8mb4**: 仅当数据库为 MySQL 时有效, 可以为 "utf8" 或 "utf8mb4"。注意:如果使用 "utf8mb4",你的 MySQL InnoDB 版本必须在 5.6 以上。
|
||||
- `PATH`: Tidb 或者 SQLite3 数据文件存放路径。
|
||||
- `PATH`: SQLite3 数据文件存放路径。
|
||||
- `LOG_SQL`: **true**: 显示生成的SQL,默认为真。
|
||||
- `MAX_IDLE_CONNS` **0**: 最大空闲数据库连接
|
||||
- `CONN_MAX_LIFETIME` **3s**: 数据库连接最大存活时间
|
||||
@@ -257,18 +262,18 @@ test01.xls: application/vnd.ms-excel; charset=binary
|
||||
|
||||
### Cron - Repository Health Check (`cron.repo_health_check`)
|
||||
|
||||
- `SCHEDULE`: 仓库健康监测的Cron语法,比如:`@every 24h`。
|
||||
- `SCHEDULE`: 仓库健康监测的Cron语法,比如:`@midnight`。
|
||||
- `TIMEOUT`: 仓库健康监测的超时时间,比如:`60s`.
|
||||
- `ARGS`: 执行 `git fsck` 命令的参数,比如:`--unreachable --tags`。
|
||||
|
||||
### Cron - Repository Statistics Check (`cron.check_repo_stats`)
|
||||
|
||||
- `RUN_AT_START`: 是否启动时自动运行仓库统计。
|
||||
- `SCHEDULE`: 仓库统计时的Cron 语法,比如:`@every 24h`.
|
||||
- `SCHEDULE`: 仓库统计时的Cron 语法,比如:`@midnight`.
|
||||
|
||||
### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`)
|
||||
|
||||
- `SCHEDULE`: **@every 24h** : 每次同步的间隔时间。此任务总是在启动时自动进行。
|
||||
- `SCHEDULE`: **@midnight** : 每次同步的间隔时间。此任务总是在启动时自动进行。
|
||||
|
||||
## Git (`git`)
|
||||
|
||||
@@ -330,8 +335,9 @@ IS_INPUT_FILE = false
|
||||
- `MAX_ATTEMPTS`: **3**: 在迁移过程中的 http/https 请求重试次数。
|
||||
- `RETRY_BACKOFF`: **3**: 等待下一次重试的时间,单位秒。
|
||||
- `ALLOWED_DOMAINS`: **\<empty\>**: 迁移仓库的域名白名单,默认为空,表示允许从任意域名迁移仓库,多个域名用逗号分隔。
|
||||
- `BLOCKED_DOMAINS`: **\<empty\>**: 迁移仓库的域名黑名单,默认为空,多个域名用逗号分隔。如果 `ALLOWED_DOMAINS` 不为空,此选项将会被忽略。
|
||||
- `BLOCKED_DOMAINS`: **\<empty\>**: 迁移仓库的域名黑名单,默认为空,多个域名用逗号分隔。如果 `ALLOWED_DOMAINS` 不为空,此选项有更高的优先级拒绝这里的域名。
|
||||
- `ALLOW_LOCALNETWORKS`: **false**: Allow private addresses defined by RFC 1918
|
||||
- `SKIP_TLS_VERIFY`: **false**: 允许忽略 TLS 认证
|
||||
|
||||
## LFS (`lfs`)
|
||||
|
||||
@@ -397,6 +403,19 @@ Repository archive 的存储配置。 如果 `STORAGE_TYPE` 为空,则此配
|
||||
- `MINIO_BASE_PATH`: **repo-archive/**: Minio base path ,仅当 `STORAGE_TYPE` 为 `minio` 时有效。
|
||||
- `MINIO_USE_SSL`: **false**: Minio 是否启用 ssl ,仅当 `STORAGE_TYPE` 为 `minio` 时有效。
|
||||
|
||||
## Proxy (`proxy`)
|
||||
|
||||
- `PROXY_ENABLED`: **false**: 是否启用全局代理。如果为否,则不使用代理,环境变量中的代理也不使用
|
||||
- `PROXY_URL`: **\<empty\>**: 代理服务器地址,支持 http://, https//, socks://,为空则不启用代理而使用环境变量中的 http_proxy/https_proxy
|
||||
- `PROXY_HOSTS`: **\<empty\>**: 逗号分隔的多个需要代理的网址,支持 * 号匹配符号, ** 表示匹配所有网站
|
||||
|
||||
i.e.
|
||||
```ini
|
||||
PROXY_ENABLED = true
|
||||
PROXY_URL = socks://127.0.0.1:1080
|
||||
PROXY_HOSTS = *.github.com
|
||||
```
|
||||
|
||||
## Other (`other`)
|
||||
|
||||
- `SHOW_FOOTER_BRANDING`: 为真则在页面底部显示Gitea的字样。
|
||||
|
@@ -92,7 +92,7 @@ shouldn't be touched without fully understanding these components.
|
||||
|
||||
Copy [`home.tmpl`](https://github.com/go-gitea/gitea/blob/main/templates/home.tmpl) for your version of Gitea from `templates` to `$GITEA_CUSTOM/templates`.
|
||||
Edit as you wish.
|
||||
Dont forget to restart your gitea to apply the changes.
|
||||
Dont forget to restart your Gitea to apply the changes.
|
||||
|
||||
### Adding links and tabs
|
||||
|
||||
@@ -102,7 +102,7 @@ For instance, let's say you are in Germany and must add the famously legally-req
|
||||
just place it under your "$GITEA_CUSTOM/public/" directory (for instance `$GITEA_CUSTOM/public/impressum.html`) and put a link to it in either `$GITEA_CUSTOM/templates/custom/extra_links.tmpl` or `$GITEA_CUSTOM/templates/custom/extra_links_footer.tmpl`.
|
||||
|
||||
To match the current style, the link should have the class name "item", and you can use `{{AppSubUrl}}` to get the base URL:
|
||||
`<a class="item" href="{{AppSubUrl}}/impressum.html">Impressum</a>`
|
||||
`<a class="item" href="{{AppSubUrl}}/assets/impressum.html">Impressum</a>`
|
||||
|
||||
For more information, see [Adding Legal Pages](https://docs.gitea.io/en-us/adding-legal-pages).
|
||||
|
||||
@@ -174,13 +174,13 @@ You can display STL file directly in Gitea by adding:
|
||||
|
||||
if ($('.view-raw>a[href$=".stl" i]').length) {
|
||||
$("body").append(
|
||||
'<link href="/Madeleine.js/src/css/Madeleine.css" rel="stylesheet">'
|
||||
'<link href="/assets/Madeleine.js/src/css/Madeleine.css" rel="stylesheet">'
|
||||
);
|
||||
Promise.all([
|
||||
lS("/Madeleine.js/src/lib/stats.js"),
|
||||
lS("/Madeleine.js/src/lib/detector.js"),
|
||||
lS("/Madeleine.js/src/lib/three.min.js"),
|
||||
lS("/Madeleine.js/src/Madeleine.js"),
|
||||
lS("/assets/Madeleine.js/src/lib/stats.js"),
|
||||
lS("/assets/Madeleine.js/src/lib/detector.js"),
|
||||
lS("/assets/Madeleine.js/src/lib/three.min.js"),
|
||||
lS("/assets/Madeleine.js/src/Madeleine.js"),
|
||||
]).then(function () {
|
||||
$(".view-raw")
|
||||
.attr("id", "view-raw")
|
||||
@@ -188,7 +188,7 @@ You can display STL file directly in Gitea by adding:
|
||||
new Madeleine({
|
||||
target: "view-raw",
|
||||
data: $('.view-raw>a[href$=".stl" i]').attr("href"),
|
||||
path: "/Madeleine.js/src",
|
||||
path: "/assets/Madeleine.js/src",
|
||||
});
|
||||
$('.view-raw>a[href$=".stl"]').remove();
|
||||
});
|
||||
@@ -200,7 +200,7 @@ to the file `templates/custom/footer.tmpl`
|
||||
|
||||
You also need to download the content of the library [Madeleine.js](https://jinjunho.github.io/Madeleine.js/) and place it under `$GITEA_CUSTOM/public/` folder.
|
||||
|
||||
You should end-up with a folder structucture similar to:
|
||||
You should end-up with a folder structure similar to:
|
||||
|
||||
```
|
||||
$GITEA_CUSTOM/templates
|
||||
@@ -248,7 +248,7 @@ $GITEA_CUSTOM/public
|
||||
`-- three.min.js
|
||||
```
|
||||
|
||||
Then restart gitea and open a STL file on your gitea instance.
|
||||
Then restart Gitea and open a STL file on your Gitea instance.
|
||||
|
||||
## Customizing Gitea mails
|
||||
|
||||
@@ -287,7 +287,7 @@ To add a custom license, add a file with the license text to `$GITEA_CUSTOM/opti
|
||||
|
||||
### Locales
|
||||
|
||||
Locales are managed via our [crowdin](https://crowdin.com/project/gitea).
|
||||
Locales are managed via our [Crowdin](https://crowdin.com/project/gitea).
|
||||
You can override a locale by placing an altered locale file in `$GITEA_CUSTOM/options/locale`.
|
||||
Gitea's default locale files can be found in the [`options/locale`](https://github.com/go-gitea/gitea/tree/main/options/locale) source folder and these should be used as examples for your changes.
|
||||
|
||||
@@ -321,8 +321,24 @@ A full list of supported emoji's is at [emoji list](https://gitea.com/gitea/gite
|
||||
|
||||
## Customizing the look of Gitea
|
||||
|
||||
As of version 1.6.0 Gitea has built-in themes. The two built-in themes are, the default theme `gitea`, and a dark theme `arc-green`. To change the look of your Gitea install change the value of `DEFAULT_THEME` in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini` to another one of the available options.
|
||||
As of version 1.8.0 Gitea also has per-user themes. The list of themes a user can choose from can be configured with the `THEMES` value in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini` (defaults to `gitea` and `arc-green`, light and dark respectively)
|
||||
The default built-in themes are `gitea` (light), `arc-green` (dark), and `auto` (chooses light or dark depending on operating system settings).
|
||||
The default theme can be changed via `DEFAULT_THEME` in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini`.
|
||||
|
||||
Gitea also has support for user themes, which means every user can select which theme should be used.
|
||||
The list of themes a user can choose from can be configured with the `THEMES` value in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini`.
|
||||
|
||||
To make a custom theme available to all users:
|
||||
|
||||
1. Add a CSS file to `$GITEA_PUBLIC/public/css/theme-<theme-name>.css`.
|
||||
The value of `$GITEA_PUBLIC` of your instance can be queried by calling `gitea help` and looking up the value of "CustomPath".
|
||||
2. Add `<theme-name>` to the comma-separated list of setting `THEMES` in `app.ini`
|
||||
|
||||
Community themes are listed in [gitea/awesome-gitea#themes](https://gitea.com/gitea/awesome-gitea#themes).
|
||||
|
||||
The `arc-green` theme source can be found [here](https://github.com/go-gitea/gitea/blob/main/web_src/less/themes/theme-arc-green.less).
|
||||
|
||||
If your custom theme is considered a dark theme, set the global css variable `--is-dark-theme` to `true`.
|
||||
This allows Gitea to adjust the Monaco code editor's theme accordingly.
|
||||
|
||||
## Customizing fonts
|
||||
|
||||
|
@@ -61,7 +61,7 @@ Gitea 引用 `custom` 目录中的自定义配置文件来覆盖配置、模板
|
||||
"custom/public/"目录下(比如 `custom/public/impressum.html`)并且将它与 `custom/templates/custom/extra_links.tmpl` 链接起来即可。
|
||||
|
||||
这个链接应当使用一个名为“item”的 class 来匹配当前样式,您可以使用 `{{AppSubUrl}}` 来获取 base URL:
|
||||
`<a class="item" href="{{AppSubUrl}}/impressum.html">Impressum</a>`
|
||||
`<a class="item" href="{{AppSubUrl}}/assets/impressum.html">Impressum</a>`
|
||||
|
||||
同理,您可以将页签添加到 `extra_tabs.tmpl` 中,使用同样的方式来添加页签。它的具体样式需要与
|
||||
`templates/repo/header.tmpl` 中已有的其他选项卡的样式匹配
|
||||
|
@@ -164,5 +164,5 @@ And so you could write some CSS:
|
||||
|
||||
Add your stylesheet to your custom directory e.g `custom/public/css/my-style-XXXXX.css` and import it using a custom header file `custom/templates/custom/header.tmpl`:
|
||||
```html
|
||||
<link type="text/css" href="{{AppSubUrl}}/css/my-style-XXXXX.css" />
|
||||
<link type="text/css" href="{{AppSubUrl}}/assets/css/my-style-XXXXX.css" />
|
||||
```
|
||||
|
@@ -328,13 +328,13 @@ This is equivalent to sending all logs to the console, with default go log being
|
||||
## Releasing-and-Reopening, Pausing and Resuming logging
|
||||
|
||||
If you are running on Unix you may wish to release-and-reopen logs in order to use `logrotate` or other tools.
|
||||
It is possible force gitea to release and reopen it's logging files and connections by sending `SIGUSR1` to the
|
||||
It is possible force Gitea to release and reopen it's logging files and connections by sending `SIGUSR1` to the
|
||||
running process, or running `gitea manager logging release-and-reopen`.
|
||||
|
||||
Alternatively, you may wish to pause and resume logging - this can be accomplished through the use of the
|
||||
`gitea manager logging pause` and `gitea manager logging resume` commands. Please note that whilst logging
|
||||
is paused log events below INFO level will not be stored and only a limited number of events will be stored.
|
||||
Logging may block, albeit temporarily, slowing gitea considerably whilst paused - therefore it is
|
||||
Logging may block, albeit temporarily, slowing Gitea considerably whilst paused - therefore it is
|
||||
recommended that pausing only done for a very short period of time.
|
||||
|
||||
## Adding and removing logging whilst Gitea is running
|
||||
@@ -439,6 +439,6 @@ Gitea includes built-in log rotation, which should be enough for most deployment
|
||||
- Install `logrotate`.
|
||||
- Configure `logrotate` to match your deployment requirements, see `man 8 logrotate` for configuration syntax details. In the `postrotate/endscript` block send Gitea a `USR1` signal via `kill -USR1` or `kill -10` to the `gitea` process itself, or run `gitea manager logging release-and-reopen` (with the appropriate environment). Ensure that your configurations apply to all files emitted by Gitea loggers as described in the above sections.
|
||||
- Always do `logrotate /etc/logrotate.conf --debug` to test your configurations.
|
||||
- If you are using docker and are running from outside of the container you can use `docker exec -u $OS_USER $CONTAINER_NAME sh -c 'gitea manager logging release-and-reopen'` or `docker exec $CONTAINER_NAME sh -c '/bin/s6-svc -1 /etc/s6/gitea/'` or send `USR1` directly to the gitea process itself.
|
||||
- If you are using docker and are running from outside of the container you can use `docker exec -u $OS_USER $CONTAINER_NAME sh -c 'gitea manager logging release-and-reopen'` or `docker exec $CONTAINER_NAME sh -c '/bin/s6-svc -1 /etc/s6/gitea/'` or send `USR1` directly to the Gitea process itself.
|
||||
|
||||
The next `logrotate` jobs will include your configurations, so no restart is needed. You can also immediately reload `logrotate` with `logrotate /etc/logrotate.conf --force`.
|
||||
|
@@ -208,7 +208,7 @@ Please check [Gitea's logs](https://docs.gitea.io/en-us/logging-configuration/)
|
||||
{{end}}
|
||||
<p>
|
||||
<p>
|
||||
<a href="{{AppURL}}/{{.Doer.LowerName}}">@{{.Doer.Name}}</a>
|
||||
<a href="{{AppUrl}}/{{.Doer.LowerName}}">@{{.Doer.Name}}</a>
|
||||
{{if not (eq .Doer.FullName "")}}
|
||||
({{.Doer.FullName}})
|
||||
{{end}}
|
||||
|
@@ -37,8 +37,8 @@ sudo yum install make
|
||||
|
||||
Si vous utilisez Windows, vous pouvez télécharger une des versions suivantes de Make:
|
||||
|
||||
- [Simple binaire](http://www.equation.com/servlet/equation.cmd?fa=make). Copiez le quelque part et mettez à jour `PATH`.
|
||||
- [Simple binaire](http://www.equation.com/servlet/equation.cmd?fa=make). Copiez-le quelque part et mettez à jour `PATH`.
|
||||
- [32-bits version](ftp://ftp.equation.com/make/32/make.exe)
|
||||
- [64-bits version](ftp://ftp.equation.com/make/64/make.exe)
|
||||
- [MinGW](http://www.mingw.org/) includes a build. The binary is called `mingw32-make.exe` instead of `make.exe`. Add the `bin` folder to your `PATH`.
|
||||
- [Chocolatey package](https://chocolatey.org/packages/make). Run `choco install make`
|
||||
- [MinGW](http://www.mingw.org/) inclut un _build_. Le fichier binaire est nommé `mingw32-make.exe` plutôt que `make.exe`. Ajoutez le dossier `bin` à votre `PATH`.
|
||||
- [Chocolatey package](https://chocolatey.org/packages/make). Exécutez `choco install make`.
|
||||
|
@@ -15,7 +15,7 @@ menu:
|
||||
|
||||
# Protected tags
|
||||
|
||||
Protected tags allow control over who has permission to create or update git tags. Each rule allows you to match either an individual tag name, or use an appropriate pattern to control multiple tags at once.
|
||||
Protected tags allow control over who has permission to create or update Git tags. Each rule allows you to match either an individual tag name, or use an appropriate pattern to control multiple tags at once.
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
|
@@ -20,8 +20,8 @@ menu:
|
||||
{{< toc >}}
|
||||
|
||||
Gitea will verify GPG commit signatures in the provided tree by
|
||||
checking if the commits are signed by a key within the gitea database,
|
||||
or if the commit matches the default key for git.
|
||||
checking if the commits are signed by a key within the Gitea database,
|
||||
or if the commit matches the default key for Git.
|
||||
|
||||
Keys are not checked to determine if they have expired or revoked.
|
||||
Keys are also not checked with keyservers.
|
||||
@@ -33,8 +33,8 @@ it is reported to be signed with a key with an id.
|
||||
Please note: The signer of a commit does not have to be an author or
|
||||
committer of a commit.
|
||||
|
||||
This functionality requires git >= 1.7.9 but for full functionality
|
||||
this requires git >= 2.0.0.
|
||||
This functionality requires Git >= 1.7.9 but for full functionality
|
||||
this requires Git >= 2.0.0.
|
||||
|
||||
## Automatic Signing
|
||||
|
||||
@@ -54,7 +54,7 @@ It is up to a server administrator to determine how best to install
|
||||
a signing key. Gitea generates all its commits using the server `git`
|
||||
command at present - and therefore the server `gpg` will be used for
|
||||
signing (if configured.) Administrators should review best-practices
|
||||
for gpg - in particular it is probably advisable to only install a
|
||||
for GPG - in particular it is probably advisable to only install a
|
||||
signing secret subkey without the master signing and certifying secret
|
||||
key.
|
||||
|
||||
@@ -93,7 +93,7 @@ The `default` option will interrogate `git config` for
|
||||
`commit.gpgsign` option - if this is set, then it will use the results
|
||||
of the `user.signingkey`, `user.name` and `user.email` as appropriate.
|
||||
|
||||
Please note: by adjusting git's `config` file within Gitea's
|
||||
Please note: by adjusting Git's `config` file within Gitea's
|
||||
repositories, `SIGNING_KEY=default` could be used to provide different
|
||||
signing keys on a per-repository basis. However, this is clearly not an
|
||||
ideal UI and therefore subject to change.
|
||||
|
13
docs/content/doc/developers.zh-cn.md
Normal file
13
docs/content/doc/developers.zh-cn.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
date: "2016-12-01T16:00:00+02:00"
|
||||
title: "开发者"
|
||||
slug: "developers"
|
||||
weight: 40
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
name: "开发者"
|
||||
weight: 50
|
||||
identifier: "developers"
|
||||
---
|
@@ -110,8 +110,8 @@ the `token=` string in a GET request.
|
||||
|
||||
API Reference guide is auto-generated by swagger and available on:
|
||||
`https://gitea.your.host/api/swagger`
|
||||
or on
|
||||
[gitea demo instance](https://try.gitea.io/api/swagger)
|
||||
or on the
|
||||
[Gitea demo instance](https://try.gitea.io/api/swagger)
|
||||
|
||||
The OpenAPI document is at:
|
||||
`https://gitea.your.host/swagger.v1.json`
|
||||
|
125
docs/content/doc/developers/guidelines-backend.md
Normal file
125
docs/content/doc/developers/guidelines-backend.md
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
date: "2021-11-01T23:41:00+08:00"
|
||||
title: "Guidelines for Backend Development"
|
||||
slug: "guidelines-backend"
|
||||
weight: 20
|
||||
toc: false
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "developers"
|
||||
name: "Guidelines for Backend"
|
||||
weight: 20
|
||||
identifier: "guidelines-backend"
|
||||
---
|
||||
|
||||
# Guidelines for Backend Development
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Background
|
||||
|
||||
Gitea uses Golang as the backend programming language. It uses many third-party packages and also write some itself.
|
||||
For example, Gitea uses [Chi](https://github.com/go-chi/chi) as basic web framework. [Xorm](https://xorm.io) is an ORM framework that is used to interact with the database.
|
||||
So it's very important to manage these packages. Please take the below guidelines before you start to write backend code.
|
||||
|
||||
## Package Design Guideline
|
||||
|
||||
### Packages List
|
||||
|
||||
To maintain understandable code and avoid circular dependencies it is important to have a good code structure. The Gitea backend is divided into the following parts:
|
||||
|
||||
- `build`: Scripts to help build Gitea.
|
||||
- `cmd`: All Gitea actual sub commands includes web, doctor, serv, hooks, admin and etc. `web` will start the web service. `serv` and `hooks` will be invoked by Git or OpenSSH. Other sub commands could help to maintain Gitea.
|
||||
- `integrations`: Integration tests
|
||||
- `models`: Contains the data structures used by xorm to construct database tables. It also contains functions to query and update the database. Dependencies to other Gitea code should be avoided. You can make exceptions in cases such as logging.
|
||||
- `models/db`: Basic database operations. All other `models/xxx` packages should depend on this package. The `GetEngine` function should only be invoked from `models/`.
|
||||
- `models/fixtures`: Sample data used in unit tests and integration tests. One `yml` file means one table which will be loaded into database when beginning the tests.
|
||||
- `models/migrations`: Stores database migrations between versions. PRs that change a database structure **MUST** also have a migration step.
|
||||
- `modules`: Different modules to handle specific functionality in Gitea. Work in Progress: Some of them should be moved to `services`, in particular those that depend on models because they rely on the database.
|
||||
- `modules/setting`: Store all system configurations read from ini files and has been referenced by everywhere. But they should be used as function parameters when possible.
|
||||
- `modules/git`: Package to interactive with `Git` command line or Gogit package.
|
||||
- `public`: Compiled frontend files (javascript, images, css, etc.)
|
||||
- `routers`: Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) must not depend on routers.
|
||||
- `routers/api` Contains routers for `/api/v1` aims to handle RESTful API requests.
|
||||
- `routers/install` Could only respond when system is in INSTALL mode (INSTALL_LOCK=false).
|
||||
- `routers/private` will only be invoked by internal sub commands, especially `serv` and `hooks`.
|
||||
- `routers/web` will handle HTTP requests from web browsers or Git SMART HTTP protocols.
|
||||
- `services`: Support functions for common routing operations or command executions. Uses `models` and `modules` to handle the requests.
|
||||
- `templates`: Golang templates for generating the html output.
|
||||
|
||||
### Package Dependencies
|
||||
|
||||
Since Golang don't support import cycles, we have to decide the package dependencies carefully. There are some levels between those packages. Below is the ideal package dependencies direction.
|
||||
|
||||
`cmd` -> `routers` -> `services` -> `models` -> `modules`
|
||||
|
||||
From left to right, left packages could depend on right packages, but right packages MUST not depend on left packages. The sub packages on the same level could depend on according this level's rules.
|
||||
|
||||
**NOTICE**
|
||||
|
||||
Why do we need database transactions outside of `models`? And how?
|
||||
Some actions should allow for rollback when database record insertion/update/deletion failed.
|
||||
So services must be allowed to create a database transaction. Here is some example,
|
||||
|
||||
```go
|
||||
// servcies/repository/repo.go
|
||||
func CreateXXXX() error {\
|
||||
ctx, committer, err := db.TxContext()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
// do something, if return err, it will rollback automatically when `committer.Close()` is invoked.
|
||||
if err := issues.UpdateIssue(ctx, repoID); err != nil {
|
||||
// ...
|
||||
}
|
||||
|
||||
// ......
|
||||
|
||||
return committer.Commit()
|
||||
}
|
||||
```
|
||||
|
||||
You should **not** use `db.GetEngine(ctx)` in `services` directly, but just write a function under `models/`.
|
||||
If the function will be used in the transaction, just let `context.Context` as the function's first parameter.
|
||||
|
||||
```go
|
||||
// models/issues/issue.go
|
||||
func UpdateIssue(ctx context.Context, repoID int64) error {
|
||||
e := db.GetEngine(ctx)
|
||||
|
||||
// ......
|
||||
}
|
||||
```
|
||||
|
||||
### Package Name
|
||||
|
||||
For the top level package, use a plural as package name, i.e. `services`, `models`, for sub packages, use singular,
|
||||
i.e. `servcies/user`, `models/repository`.
|
||||
|
||||
### Import Alias
|
||||
|
||||
Since there are some packages which use the same package name, it is possible that you find packages like `modules/user`, `models/user`, and `services/user`. When these packages are imported in one Go file, it's difficult to know which package we are using and if it's a variable name or an import name. So, we always recommend to use import aliases. To differ from package variables which are commonly in camelCase, just use **snake_case** for import aliases.
|
||||
i.e. `import user_service "code.gitea.io/gitea/services/user"`
|
||||
|
||||
### Important Gotchas
|
||||
|
||||
- Never write `x.Update(exemplar)` without an explicit `WHERE` clause:
|
||||
- This will cause all rows in the table to be updated with the non-zero values of the exemplar - including IDs.
|
||||
- You should usually write `x.ID(id).Update(exemplar)`.
|
||||
- If during a migration you are inserting into a table using `x.Insert(exemplar)` where the ID is preset:
|
||||
- You will need to ``SET IDENTITY_INSERT `table` ON`` for the MSSQL variant (the migration will fail otherwise)
|
||||
- However, you will also need to update the id sequence for postgres - the migration will silently pass here but later insertions will fail:
|
||||
``SELECT setval('table_name_id_seq', COALESCE((SELECT MAX(id)+1 FROM `table_name`), 1), false)``
|
||||
|
||||
### Future Tasks
|
||||
|
||||
Currently, we are creating some refactors to do the following things:
|
||||
|
||||
- Correct that codes which doesn't follow the rules.
|
||||
- There are too many files in `models`, so we are moving some of them into a sub package `models/xxx`.
|
||||
- Some `modules` sub packages should be moved to `services` because they depend on `models`.
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user