mirror of
https://github.com/gogs/gogs.git
synced 2026-02-28 17:20:59 +01:00
Compare commits
2046 Commits
v0.9.97
...
latest-com
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df467d8ff1 | ||
|
|
36d56d5525 | ||
|
|
5f17b670b3 | ||
|
|
ea682c5bbc | ||
|
|
9001a68cdd | ||
|
|
295bfba729 | ||
|
|
ac21150a53 | ||
|
|
a000f0c7a6 | ||
|
|
a976fd2f9c | ||
|
|
441c64d7bd | ||
|
|
5c67d47512 | ||
|
|
94d6e53dc2 | ||
|
|
a1fa62b270 | ||
|
|
317e28b908 | ||
|
|
069d3535d6 | ||
|
|
81ee883644 | ||
|
|
400ae7bd28 | ||
|
|
630ae0b3b0 | ||
|
|
3c358ede6d | ||
|
|
48500aa2b0 | ||
|
|
785157ba1f | ||
|
|
1c8016a27b | ||
|
|
00c36d8d8a | ||
|
|
3747cd9058 | ||
|
|
08e7cfd76c | ||
|
|
9dd3e58f7b | ||
|
|
edc1478f6b | ||
|
|
bb86d12c36 | ||
|
|
bf17cc6c69 | ||
|
|
6d56105f8f | ||
|
|
ed5d02e036 | ||
|
|
5874791a57 | ||
|
|
17ad3d3425 | ||
|
|
9b2a967e45 | ||
|
|
e80635a449 | ||
|
|
47bccf292d | ||
|
|
38def73489 | ||
|
|
6cf6422b88 | ||
|
|
8d8d66ec1d | ||
|
|
7ea2c4093f | ||
|
|
7ebfb202e4 | ||
|
|
7b8c560f15 | ||
|
|
a636dcf678 | ||
|
|
3dcb74be39 | ||
|
|
7ad425025e | ||
|
|
85abee4b9b | ||
|
|
997c3c5eab | ||
|
|
a5ddb2665e | ||
|
|
b68e6886c6 | ||
|
|
ac7ba9c8a7 | ||
|
|
dd862ee058 | ||
|
|
f94042ce6f | ||
|
|
628216d588 | ||
|
|
7306b955a9 | ||
|
|
fc6d1e2055 | ||
|
|
3b01892d85 | ||
|
|
7b7e38c880 | ||
|
|
bb68c0a042 | ||
|
|
68271e6af0 | ||
|
|
4f5b00f8c4 | ||
|
|
5d3ffd132b | ||
|
|
ee65aa89ca | ||
|
|
a1a97de76f | ||
|
|
9963268267 | ||
|
|
49a45290ae | ||
|
|
3cc8e7aa6d | ||
|
|
9f1499f3ab | ||
|
|
77dba1b5ea | ||
|
|
f70f29fdb0 | ||
|
|
ed6109d35d | ||
|
|
54e08ba678 | ||
|
|
87c8faaf08 | ||
|
|
1b226ca48d | ||
|
|
e3bb4165dc | ||
|
|
df3d945a2c | ||
|
|
ae41bab5f2 | ||
|
|
2316b09eaf | ||
|
|
3477bbac0e | ||
|
|
bb3cab921b | ||
|
|
1cdeef2ce8 | ||
|
|
a7bc1637db | ||
|
|
f1102a7a7c | ||
|
|
26ef07f60d | ||
|
|
ca59e76a53 | ||
|
|
27f1250d00 | ||
|
|
560f92ec5f | ||
|
|
1bbc36149a | ||
|
|
4ee706b2bf | ||
|
|
ae59787ff5 | ||
|
|
389ec54b2c | ||
|
|
5544212adb | ||
|
|
6e1e4cb848 | ||
|
|
8e08450182 | ||
|
|
beeeb64969 | ||
|
|
3ef71a43d9 | ||
|
|
e44284fada | ||
|
|
b7010084b7 | ||
|
|
b8ab712819 | ||
|
|
59e9fa191b | ||
|
|
553707f3fd | ||
|
|
b6030ba713 | ||
|
|
e68949dd13 | ||
|
|
f813c17565 | ||
|
|
5e7c599755 | ||
|
|
2c88cd4d9f | ||
|
|
04cc48339f | ||
|
|
3666718ec5 | ||
|
|
4cc83c498b | ||
|
|
332c0895e6 | ||
|
|
16f466d1c1 | ||
|
|
5e3f45e7f5 | ||
|
|
994b769d9d | ||
|
|
3488e22a40 | ||
|
|
d0d4de70ca | ||
|
|
79cc921892 | ||
|
|
1347c7802f | ||
|
|
89f0f86c7e | ||
|
|
6a6364bb5d | ||
|
|
35c047dc9d | ||
|
|
e4923af32d | ||
|
|
0533fb7744 | ||
|
|
28810f7db7 | ||
|
|
cfe38e0a08 | ||
|
|
110da379c1 | ||
|
|
37962fcc0b | ||
|
|
7265a7cd26 | ||
|
|
521fbe34f6 | ||
|
|
1375bc401a | ||
|
|
28f83626d4 | ||
|
|
dcf8d9340e | ||
|
|
76b5d75d79 | ||
|
|
454175ece2 | ||
|
|
d940e692ec | ||
|
|
7fc19d094c | ||
|
|
4e3bf27fe2 | ||
|
|
16b8b0974e | ||
|
|
f004b5b472 | ||
|
|
591810e405 | ||
|
|
3c2112215f | ||
|
|
9db5c30c36 | ||
|
|
49f4d4312b | ||
|
|
0cf12eccae | ||
|
|
495c38825a | ||
|
|
60b912ddda | ||
|
|
4d6a0ebaac | ||
|
|
54fa465da5 | ||
|
|
54cd8fd160 | ||
|
|
7abc81c4d2 | ||
|
|
493834861d | ||
|
|
9a539393bd | ||
|
|
139ea3ce7d | ||
|
|
4acaaac85a | ||
|
|
e93ced2163 | ||
|
|
9672b6dd6c | ||
|
|
7a12c8418e | ||
|
|
2208f17e8e | ||
|
|
46a84fdad5 | ||
|
|
9c80e6d922 | ||
|
|
3a952bd248 | ||
|
|
96d5d622b8 | ||
|
|
b59e943aa6 | ||
|
|
371a6092de | ||
|
|
e6896eb393 | ||
|
|
6c04a1ce7c | ||
|
|
6bdbb88fb8 | ||
|
|
6b4e8668a1 | ||
|
|
d8f562b6ad | ||
|
|
f1e64008fb | ||
|
|
cfde357824 | ||
|
|
3459f8df49 | ||
|
|
c0332ff856 | ||
|
|
e1042e7d47 | ||
|
|
76831d0d06 | ||
|
|
68b3c8f339 | ||
|
|
77a4a945ae | ||
|
|
b09f317aa0 | ||
|
|
009a1855aa | ||
|
|
fb7812b194 | ||
|
|
00bd6081a5 | ||
|
|
5326b4113a | ||
|
|
7adac94f1e | ||
|
|
c5dff8cdad | ||
|
|
8a39d529d0 | ||
|
|
740eba4f70 | ||
|
|
9a9388ace2 | ||
|
|
8a3b8198af | ||
|
|
c94baec9ca | ||
|
|
25a799ad63 | ||
|
|
f518abaff1 | ||
|
|
58fa30c7be | ||
|
|
a02d6a22d6 | ||
|
|
7a2dffa95a | ||
|
|
2541348408 | ||
|
|
f037c58eee | ||
|
|
e5e03cba24 | ||
|
|
07380780c6 | ||
|
|
3a8bd73901 | ||
|
|
79bd350ad6 | ||
|
|
0700cef63e | ||
|
|
e34ebac459 | ||
|
|
03d26b0482 | ||
|
|
e6d4db0b4c | ||
|
|
69d74485f0 | ||
|
|
9401784421 | ||
|
|
93aba5a6b7 | ||
|
|
9108970e45 | ||
|
|
0965db473f | ||
|
|
f1f6d3f37d | ||
|
|
8e195067df | ||
|
|
5d6bc5c9fd | ||
|
|
8869354d21 | ||
|
|
5bdf91e73c | ||
|
|
54776c776a | ||
|
|
f2ff885f33 | ||
|
|
6cb018df2f | ||
|
|
f4a78e5cfb | ||
|
|
1815fd5c36 | ||
|
|
15d64e0f23 | ||
|
|
15077b13e3 | ||
|
|
87f47166ac | ||
|
|
c8cd3e7125 | ||
|
|
ce350e768a | ||
|
|
56a1712275 | ||
|
|
f8a3e7153f | ||
|
|
6f9b63517d | ||
|
|
1eae0b2fce | ||
|
|
24f06bb088 | ||
|
|
015589cdd9 | ||
|
|
ba17b9b56b | ||
|
|
3b8c9ba7ab | ||
|
|
f915eb3a40 | ||
|
|
c036214c45 | ||
|
|
b8ed5d8d91 | ||
|
|
d9ecdcaef0 | ||
|
|
202012887a | ||
|
|
4d05804729 | ||
|
|
e1e75ed36b | ||
|
|
895e553e68 | ||
|
|
5cf0189df1 | ||
|
|
8d2386b4db | ||
|
|
dd49412edd | ||
|
|
b89f20e02d | ||
|
|
e634aa6277 | ||
|
|
3a5132b6f7 | ||
|
|
b9e41f28c3 | ||
|
|
6d77d6204d | ||
|
|
f73edbd172 | ||
|
|
fa84482d98 | ||
|
|
6c63a88ef0 | ||
|
|
35c59d2c24 | ||
|
|
6d77bcebaa | ||
|
|
605c751926 | ||
|
|
8054ffc12f | ||
|
|
917c14f2ce | ||
|
|
dfe27ad556 | ||
|
|
3616bc03c9 | ||
|
|
10cd022e08 | ||
|
|
3650b32ec5 | ||
|
|
cad79a31d8 | ||
|
|
077141d2ba | ||
|
|
cd3f132844 | ||
|
|
ff7dc29ad3 | ||
|
|
87a5ae3f61 | ||
|
|
6bd09e75fe | ||
|
|
7b06bf642a | ||
|
|
b6e4b379c1 | ||
|
|
5e96f64b83 | ||
|
|
41d473e999 | ||
|
|
25fdeaac49 | ||
|
|
0c7b45ad1f | ||
|
|
5293781c0d | ||
|
|
7a2c691c5b | ||
|
|
dfc129ee98 | ||
|
|
1c711bc8d4 | ||
|
|
31a0964e12 | ||
|
|
b644d797b4 | ||
|
|
61940ca879 | ||
|
|
16b185f97d | ||
|
|
c531da02ca | ||
|
|
bc1b5e52a9 | ||
|
|
0b5257425f | ||
|
|
7fb3dcb1eb | ||
|
|
5c3fde8531 | ||
|
|
7bffc0d0e3 | ||
|
|
748c67df8b | ||
|
|
2d9be6c06b | ||
|
|
493a56b262 | ||
|
|
3350740563 | ||
|
|
89b123f9d1 | ||
|
|
4821e89780 | ||
|
|
e989093129 | ||
|
|
018337ddfb | ||
|
|
fde10f1236 | ||
|
|
48710b9793 | ||
|
|
069f1ed9a4 | ||
|
|
1112a71ea5 | ||
|
|
9d86838fa7 | ||
|
|
f187005581 | ||
|
|
7efda8e8fc | ||
|
|
2620cc3e8d | ||
|
|
af77cbb759 | ||
|
|
65e14b18ec | ||
|
|
738ac3c03b | ||
|
|
7a0a07628d | ||
|
|
c373a92da6 | ||
|
|
23ea4863f1 | ||
|
|
8940778bb8 | ||
|
|
53c009288c | ||
|
|
3be3ae500b | ||
|
|
9ab8bd6785 | ||
|
|
9e91602b42 | ||
|
|
b13cb438d1 | ||
|
|
69802f07b7 | ||
|
|
c426e9b8ad | ||
|
|
97ccf329b1 | ||
|
|
89b759e2ed | ||
|
|
1fb33bd586 | ||
|
|
0ca017d0a8 | ||
|
|
75767078aa | ||
|
|
22bf85b6f5 | ||
|
|
b2ea82c8d8 | ||
|
|
7fae076155 | ||
|
|
ed825c6273 | ||
|
|
795cac1dd0 | ||
|
|
ad3f9ac068 | ||
|
|
0721ef2399 | ||
|
|
9ac93067f6 | ||
|
|
167cdb09e3 | ||
|
|
ada1083462 | ||
|
|
5df9668063 | ||
|
|
249668a2b9 | ||
|
|
66364d9c02 | ||
|
|
077c80d258 | ||
|
|
79bda9df35 | ||
|
|
6e5f9e8a1b | ||
|
|
7e5db4ba42 | ||
|
|
7be3ea194f | ||
|
|
d119526bde | ||
|
|
c3f1331a5e | ||
|
|
8de873be86 | ||
|
|
eeb397a0ac | ||
|
|
5432293224 | ||
|
|
5da1e62426 | ||
|
|
057ae983a0 | ||
|
|
f473643d29 | ||
|
|
b96b8eb389 | ||
|
|
70777899f8 | ||
|
|
cdde49978b | ||
|
|
0ddab94774 | ||
|
|
5483d97f73 | ||
|
|
6fa552994a | ||
|
|
bd0ab704af | ||
|
|
cd7b3cf971 | ||
|
|
fb6693f612 | ||
|
|
a98968436c | ||
|
|
540134d443 | ||
|
|
6244daa3ea | ||
|
|
689e71ff2c | ||
|
|
361a681225 | ||
|
|
73ae88badf | ||
|
|
72d51347ec | ||
|
|
dc37bf5794 | ||
|
|
9e5fa984f8 | ||
|
|
3e3d6eda12 | ||
|
|
9110059797 | ||
|
|
15d0d6a94b | ||
|
|
0f8c71d3b3 | ||
|
|
8f9895acaf | ||
|
|
2a375007ee | ||
|
|
c63448e357 | ||
|
|
5db49a8892 | ||
|
|
1a1b50d786 | ||
|
|
b34ee73497 | ||
|
|
92f66c9eac | ||
|
|
3a28168d41 | ||
|
|
ef1fe1bb3b | ||
|
|
8350daf505 | ||
|
|
133b9d9044 | ||
|
|
7c453d5b36 | ||
|
|
b6df33fa72 | ||
|
|
8d6b964099 | ||
|
|
7ff09cf359 | ||
|
|
3c43b9b21c | ||
|
|
5887bc116f | ||
|
|
6d220540c1 | ||
|
|
ed51686240 | ||
|
|
cc4d4eacad | ||
|
|
c53a1998c5 | ||
|
|
614382fec0 | ||
|
|
9df10cb8cc | ||
|
|
5c47ecfcb8 | ||
|
|
3d8004cf6f | ||
|
|
a3e2adeda2 | ||
|
|
63117f46ee | ||
|
|
cf70284de9 | ||
|
|
367f2907df | ||
|
|
16aded2743 | ||
|
|
12b46b7757 | ||
|
|
6133415f6d | ||
|
|
c53b7e9698 | ||
|
|
c5d07b8bf9 | ||
|
|
2fc1e35943 | ||
|
|
83335043e2 | ||
|
|
a5ad63a005 | ||
|
|
ae20d03aec | ||
|
|
44333afd20 | ||
|
|
13099a7e4f | ||
|
|
a7dbc970df | ||
|
|
644a3a9d78 | ||
|
|
93736cbc12 | ||
|
|
b157cc8b06 | ||
|
|
1d65c8e3ef | ||
|
|
cdf4f59cb4 | ||
|
|
5fb29db2db | ||
|
|
b5d47b9692 | ||
|
|
fd798b4197 | ||
|
|
a66c90462d | ||
|
|
3af5a424f0 | ||
|
|
a9e3fa3ce5 | ||
|
|
75ee18f87e | ||
|
|
d44978c940 | ||
|
|
516cf7d077 | ||
|
|
1905b19ee7 | ||
|
|
131be6e074 | ||
|
|
49be63abbf | ||
|
|
f2b158159c | ||
|
|
f6acc4763e | ||
|
|
3265abfbc2 | ||
|
|
d0a4a3401c | ||
|
|
c58c893621 | ||
|
|
ef0388045f | ||
|
|
b1fefcbe50 | ||
|
|
8077360cf6 | ||
|
|
2e020b1cf6 | ||
|
|
742bc36edd | ||
|
|
a7299bbb8d | ||
|
|
11edc09681 | ||
|
|
b9f5cfddc1 | ||
|
|
fd5874b07b | ||
|
|
ce25881c88 | ||
|
|
7cbd84d5b3 | ||
|
|
c502dc6ed8 | ||
|
|
260e990be7 | ||
|
|
2df4b61eb2 | ||
|
|
689991578e | ||
|
|
a9bce79c6b | ||
|
|
ac86936797 | ||
|
|
dcf9c111b6 | ||
|
|
50e5766867 | ||
|
|
8982a42d38 | ||
|
|
fb00e3e56f | ||
|
|
a0b8f5464e | ||
|
|
777fb14fc9 | ||
|
|
25d6b168c5 | ||
|
|
c9fd177998 | ||
|
|
02973f7f80 | ||
|
|
360280b0ea | ||
|
|
82e29c6bd3 | ||
|
|
cefbaa08d9 | ||
|
|
87def3de5f | ||
|
|
9ea258e97f | ||
|
|
7e6fc2603e | ||
|
|
4487890979 | ||
|
|
be775e2ffa | ||
|
|
cee6ef39ee | ||
|
|
5910265e13 | ||
|
|
a43b933c90 | ||
|
|
cfa5ddbde8 | ||
|
|
a21f0b0540 | ||
|
|
ad796b8ba5 | ||
|
|
db82024fc7 | ||
|
|
780b33c639 | ||
|
|
a5d3e1900e | ||
|
|
ab7133b35a | ||
|
|
75cc3ce172 | ||
|
|
05a6a9d6e9 | ||
|
|
25a2b716ad | ||
|
|
1d48df3fd1 | ||
|
|
b8294a460e | ||
|
|
6043bf20fe | ||
|
|
1cd501b107 | ||
|
|
0022566a3a | ||
|
|
5f3d44ec00 | ||
|
|
25b49294b2 | ||
|
|
a8e43f63a1 | ||
|
|
fb52bd6fea | ||
|
|
bc5c739047 | ||
|
|
97ccb365ec | ||
|
|
083c3ee659 | ||
|
|
9df4e3ae3c | ||
|
|
4a3dc6c774 | ||
|
|
c0db4a7f1b | ||
|
|
04fe4c86ec | ||
|
|
b772603d78 | ||
|
|
2e19f5a3c8 | ||
|
|
63cb76106a | ||
|
|
1df62fafb9 | ||
|
|
5e32058c13 | ||
|
|
75fbb82440 | ||
|
|
f837ea6346 | ||
|
|
9776bdc9b8 | ||
|
|
94059f291d | ||
|
|
318fb25761 | ||
|
|
577621d463 | ||
|
|
7229dd893f | ||
|
|
0918d8758b | ||
|
|
fe1d07f29c | ||
|
|
390fd3d283 | ||
|
|
8304574738 | ||
|
|
727d4dbbe0 | ||
|
|
d6c6b901f0 | ||
|
|
9bf748b6c4 | ||
|
|
e3706575d5 | ||
|
|
2ca014250f | ||
|
|
325904ce5a | ||
|
|
fa36765373 | ||
|
|
55a8079c83 | ||
|
|
0a92ad27ef | ||
|
|
4cc3000b07 | ||
|
|
a328e7ccc4 | ||
|
|
155cae1de8 | ||
|
|
64e09476c7 | ||
|
|
4455cc1244 | ||
|
|
38aff73251 | ||
|
|
69827490e0 | ||
|
|
75e10445ca | ||
|
|
5f0999243a | ||
|
|
09ddb8761f | ||
|
|
ccdcb1c45b | ||
|
|
5f34265db6 | ||
|
|
05cdf8616b | ||
|
|
c0941f4631 | ||
|
|
5414ae14a9 | ||
|
|
b782400b92 | ||
|
|
7885f454a4 | ||
|
|
90bc752297 | ||
|
|
519aeefbd9 | ||
|
|
649e9e7f8c | ||
|
|
d466c96229 | ||
|
|
38dbfee56c | ||
|
|
069d832a51 | ||
|
|
04d3946511 | ||
|
|
d7bda9ac0e | ||
|
|
8356dc7774 | ||
|
|
1496988ac1 | ||
|
|
d54e153fc8 | ||
|
|
e65071d3aa | ||
|
|
b4624bd468 | ||
|
|
bdff033492 | ||
|
|
e01b0ce0d1 | ||
|
|
c4b770f305 | ||
|
|
a6c53eb068 | ||
|
|
705126cac8 | ||
|
|
cdc904e49e | ||
|
|
7ca5c8ca72 | ||
|
|
e51e016834 | ||
|
|
f7802b9227 | ||
|
|
a76aff36d0 | ||
|
|
f45dbf3e76 | ||
|
|
cb35b73048 | ||
|
|
a61a4389ec | ||
|
|
f1755f5bc5 | ||
|
|
71fc57f8a0 | ||
|
|
f2c3027f50 | ||
|
|
39adf6e55a | ||
|
|
4d33a5b5a8 | ||
|
|
26fce15bcf | ||
|
|
a230b3de22 | ||
|
|
e5350b9627 | ||
|
|
a7693cbc86 | ||
|
|
69514d2fc8 | ||
|
|
0778db4228 | ||
|
|
5911b0296b | ||
|
|
8acbc2d1de | ||
|
|
f37a8d82c1 | ||
|
|
2601b40ffa | ||
|
|
5acbd7bcc3 | ||
|
|
5910f77e42 | ||
|
|
efa572162f | ||
|
|
5c4db08968 | ||
|
|
f44a693bbd | ||
|
|
3f439f15c3 | ||
|
|
6dbeb16d21 | ||
|
|
c5549b442b | ||
|
|
70c6f0a490 | ||
|
|
f37cd9672c | ||
|
|
9bce320160 | ||
|
|
22fb91cff9 | ||
|
|
3c49a6173d | ||
|
|
d66fe583d5 | ||
|
|
72c2d6ab70 | ||
|
|
70ff8d787a | ||
|
|
0300f88602 | ||
|
|
f36eeedbf8 | ||
|
|
e10ec6f3b8 | ||
|
|
d753a48a7d | ||
|
|
32c454ba5f | ||
|
|
39f64a1371 | ||
|
|
3539de754d | ||
|
|
1791665f74 | ||
|
|
def6fcc4dc | ||
|
|
d392bc6e9a | ||
|
|
714383a063 | ||
|
|
a2c6325261 | ||
|
|
aeb5e34490 | ||
|
|
775901058d | ||
|
|
3e35371754 | ||
|
|
bd12d46e79 | ||
|
|
82ee089088 | ||
|
|
61529fd780 | ||
|
|
aac91b3611 | ||
|
|
4ca87057f3 | ||
|
|
553d32ce7d | ||
|
|
940a7da9d1 | ||
|
|
242deca524 | ||
|
|
bb19f52c05 | ||
|
|
e75ee730b8 | ||
|
|
36102f1689 | ||
|
|
e452d94fc8 | ||
|
|
2466da4e82 | ||
|
|
09dbbf9a69 | ||
|
|
b7372b1f32 | ||
|
|
5afca6ca8e | ||
|
|
deec3516d5 | ||
|
|
65526f84e1 | ||
|
|
442609fa17 | ||
|
|
2d609b8b31 | ||
|
|
3acc13038d | ||
|
|
ab96a4f0d8 | ||
|
|
7c893a58da | ||
|
|
ed81fc5a01 | ||
|
|
8f6c4341f7 | ||
|
|
175e4f228d | ||
|
|
325f4f9560 | ||
|
|
c7e8c145d1 | ||
|
|
6d77712b1b | ||
|
|
8442d8530a | ||
|
|
9a164bcb45 | ||
|
|
8a1a40ce6a | ||
|
|
f6494d22ee | ||
|
|
3d24360f20 | ||
|
|
815624c88a | ||
|
|
47a996ba4b | ||
|
|
5e8444ed0f | ||
|
|
dfe8fbde84 | ||
|
|
3a5ccc18cf | ||
|
|
82e5fd018b | ||
|
|
2071eb634f | ||
|
|
e6c5633f58 | ||
|
|
6ccc1ce804 | ||
|
|
74886d95d0 | ||
|
|
acf2df3688 | ||
|
|
9ae80a6173 | ||
|
|
c8476b1c2e | ||
|
|
cbe775aee2 | ||
|
|
5e43fa92ff | ||
|
|
539e2a8b42 | ||
|
|
5f250de8ad | ||
|
|
2e625a051d | ||
|
|
3e948fd792 | ||
|
|
b52bea7503 | ||
|
|
a9be4de5a5 | ||
|
|
14481533b8 | ||
|
|
2519f28632 | ||
|
|
22caf7b659 | ||
|
|
ee9ab396dc | ||
|
|
dc07fbe753 | ||
|
|
d19af039e7 | ||
|
|
37383d9a1f | ||
|
|
165d5051b5 | ||
|
|
8d9f61c467 | ||
|
|
a72bac54d5 | ||
|
|
7878465567 | ||
|
|
c82dc04cbb | ||
|
|
69380e4934 | ||
|
|
b6ab8cd68d | ||
|
|
0d0dc67141 | ||
|
|
f0b21aff91 | ||
|
|
160a0b77cf | ||
|
|
6528bf35dc | ||
|
|
da56873d37 | ||
|
|
c6968105e5 | ||
|
|
f1f3e970b9 | ||
|
|
b827a2f342 | ||
|
|
5f4e07eb4f | ||
|
|
b1193607c2 | ||
|
|
eeef90a475 | ||
|
|
a523138e51 | ||
|
|
6ec001f944 | ||
|
|
55070da239 | ||
|
|
6f2b7fb853 | ||
|
|
899ec7ed54 | ||
|
|
8ee734b1df | ||
|
|
7867163bfd | ||
|
|
82652f0f08 | ||
|
|
d60d9cf985 | ||
|
|
63bd4bb4b1 | ||
|
|
de3161155b | ||
|
|
8938855b40 | ||
|
|
55e5a7c25a | ||
|
|
fa3d011415 | ||
|
|
b9a3626cad | ||
|
|
b3eb33be0f | ||
|
|
4a89438454 | ||
|
|
f524e4f932 | ||
|
|
156b91baff | ||
|
|
764e901689 | ||
|
|
8f6757cc7b | ||
|
|
7445dec1b4 | ||
|
|
ba8be9489e | ||
|
|
12ab7efdb0 | ||
|
|
3993b65bbf | ||
|
|
fb969f8492 | ||
|
|
8f8a27c904 | ||
|
|
d8fa08111b | ||
|
|
4077f27592 | ||
|
|
1a1a01a842 | ||
|
|
c4cf659e32 | ||
|
|
d6987ee05b | ||
|
|
509a392272 | ||
|
|
af6510fd17 | ||
|
|
cd4d79cf99 | ||
|
|
10e7c42a83 | ||
|
|
7676b59b02 | ||
|
|
0ff888c989 | ||
|
|
6b4a5b5e91 | ||
|
|
72af17bbbe | ||
|
|
c875950c43 | ||
|
|
71eeb2f0c0 | ||
|
|
99f1b9899f | ||
|
|
bee3bebb4e | ||
|
|
efcb8bbca6 | ||
|
|
cd469f7a1d | ||
|
|
c7f58ca870 | ||
|
|
b34d040c78 | ||
|
|
afaf6da405 | ||
|
|
7bef64a0d6 | ||
|
|
146960368f | ||
|
|
997ba0fef0 | ||
|
|
6f735cc2da | ||
|
|
8b35485ee5 | ||
|
|
428276d7a8 | ||
|
|
053695b63d | ||
|
|
b4bb83e68f | ||
|
|
2989a5e0f5 | ||
|
|
9844d2c96a | ||
|
|
ab16ca0580 | ||
|
|
f0a9ec21cd | ||
|
|
6c5fd05a31 | ||
|
|
1744f238e1 | ||
|
|
fd765bd88f | ||
|
|
533b6b0de2 | ||
|
|
bf3c9061a2 | ||
|
|
b60e2c65d3 | ||
|
|
e44ac3c20a | ||
|
|
2eaf1d693a | ||
|
|
a92d818aa3 | ||
|
|
ca3330cecd | ||
|
|
cf86546dff | ||
|
|
8e028c32d4 | ||
|
|
c082bf72af | ||
|
|
906c6a5ba0 | ||
|
|
a6bd00f807 | ||
|
|
7797efe1bb | ||
|
|
be86d67e81 | ||
|
|
23823e9698 | ||
|
|
7bc3ee49aa | ||
|
|
8fc4013240 | ||
|
|
211a1394b8 | ||
|
|
73e5936220 | ||
|
|
e4e46d8fbc | ||
|
|
b4abbf3ac8 | ||
|
|
83a89127fd | ||
|
|
6ed98ca8f6 | ||
|
|
3af91d7cfd | ||
|
|
b836a56e6e | ||
|
|
c56db8f2c4 | ||
|
|
dda1092e74 | ||
|
|
8b75e9a442 | ||
|
|
1da1e90d1e | ||
|
|
9a268ca7f5 | ||
|
|
d85504a9d1 | ||
|
|
8658ded190 | ||
|
|
04b11d3a07 | ||
|
|
56eac57222 | ||
|
|
594a2dc41f | ||
|
|
06193ed825 | ||
|
|
519e59b577 | ||
|
|
771d3673f5 | ||
|
|
2cb83f13fd | ||
|
|
2665b5968c | ||
|
|
7a649ada09 | ||
|
|
a533e8fb52 | ||
|
|
bb93cabd39 | ||
|
|
c4360747a3 | ||
|
|
23ff182d1f | ||
|
|
cb88caa2d2 | ||
|
|
cf216f12a1 | ||
|
|
a22fd01959 | ||
|
|
b38139a855 | ||
|
|
1a681ad022 | ||
|
|
f6d672a3cd | ||
|
|
016d9d8c88 | ||
|
|
c769f2566a | ||
|
|
423f9e6de7 | ||
|
|
bbef32b1ef | ||
|
|
92953007de | ||
|
|
4ecd588776 | ||
|
|
4e5b7c5d24 | ||
|
|
c1db31c130 | ||
|
|
a02b3e1258 | ||
|
|
afb445bb57 | ||
|
|
92c5f94fe7 | ||
|
|
a840ae9035 | ||
|
|
0a5977e951 | ||
|
|
a7fb211827 | ||
|
|
3ed8c292c2 | ||
|
|
13ae25b785 | ||
|
|
40513a117f | ||
|
|
f0761eb7ec | ||
|
|
05477f1d29 | ||
|
|
ac4a708307 | ||
|
|
720cb5fcb1 | ||
|
|
c7a10dd90d | ||
|
|
178b73fecd | ||
|
|
bc8428ca42 | ||
|
|
90b1ee1dfa | ||
|
|
7f9a4b7578 | ||
|
|
e789f82979 | ||
|
|
c6143edb44 | ||
|
|
252d0fd977 | ||
|
|
d1caae3f79 | ||
|
|
874d2fd602 | ||
|
|
32adb0f2da | ||
|
|
f3993b9cdb | ||
|
|
a961afe52b | ||
|
|
f667d139bc | ||
|
|
90904b3f42 | ||
|
|
a7afa11610 | ||
|
|
2fe4d07599 | ||
|
|
da4f5d79f5 | ||
|
|
2af4114d64 | ||
|
|
8366bd1cbe | ||
|
|
79d8aa0cb8 | ||
|
|
e62bccde9e | ||
|
|
516c7ab505 | ||
|
|
158dd33a25 | ||
|
|
7e99a6ce42 | ||
|
|
cb406bb350 | ||
|
|
9bbe029c28 | ||
|
|
280b06485f | ||
|
|
50797d8fa1 | ||
|
|
2003864615 | ||
|
|
1125bb5848 | ||
|
|
44ea9604ed | ||
|
|
d28101ee66 | ||
|
|
9fd4f5562d | ||
|
|
9bb218734c | ||
|
|
82ffca3fc9 | ||
|
|
d9f8efa9c3 | ||
|
|
f26eb2a192 | ||
|
|
dbe373af6f | ||
|
|
4e1f38ce28 | ||
|
|
60273d3d6d | ||
|
|
5a52ee75e3 | ||
|
|
c0fd6042fd | ||
|
|
fc57c921b1 | ||
|
|
7b295378e4 | ||
|
|
9d64d222a8 | ||
|
|
fa497b1633 | ||
|
|
e131a45646 | ||
|
|
28d74a9844 | ||
|
|
5637706e46 | ||
|
|
614aba6007 | ||
|
|
440b1ecbfd | ||
|
|
cdafe21661 | ||
|
|
844d2f49ce | ||
|
|
cb439a126a | ||
|
|
659acd48b1 | ||
|
|
d19287d5b7 | ||
|
|
26a2d0b2a1 | ||
|
|
ae107b2e6e | ||
|
|
41f56ad05d | ||
|
|
76bb647d24 | ||
|
|
e077ecdd9d | ||
|
|
62dda96159 | ||
|
|
5753d4cb87 | ||
|
|
e186a3d2c9 | ||
|
|
9a5b227f3e | ||
|
|
3e055e329c | ||
|
|
5b36ba66c2 | ||
|
|
e79aebb3e1 | ||
|
|
6a096811ff | ||
|
|
cac1054acb | ||
|
|
f3b05961aa | ||
|
|
4ebdcb719a | ||
|
|
571be84e26 | ||
|
|
2b3655fa11 | ||
|
|
ca2f7a7e16 | ||
|
|
ee0ea2c5fc | ||
|
|
4d7db6e1c1 | ||
|
|
559af54e66 | ||
|
|
083ecb7244 | ||
|
|
07818d5fa5 | ||
|
|
bae1d6ccd8 | ||
|
|
3a5c93eeff | ||
|
|
4aff4d66ec | ||
|
|
53b91ef306 | ||
|
|
34145c990d | ||
|
|
2bd9d0b9c8 | ||
|
|
a603c0f1fc | ||
|
|
5b8ed0add9 | ||
|
|
fd7931cd2b | ||
|
|
72111e698e | ||
|
|
dce70fe6d1 | ||
|
|
63ab497f6f | ||
|
|
afe226cd16 | ||
|
|
efa9ef78c8 | ||
|
|
b5a06618fa | ||
|
|
f0f3b8707b | ||
|
|
045e1670a4 | ||
|
|
6298e33b8b | ||
|
|
a8a6325054 | ||
|
|
4cbb43b860 | ||
|
|
933206f1fe | ||
|
|
9356231e64 | ||
|
|
a0651b62a7 | ||
|
|
470274204e | ||
|
|
af0cfe112b | ||
|
|
0b80578e62 | ||
|
|
f58ffb3fd4 | ||
|
|
a0f239495d | ||
|
|
870746791a | ||
|
|
71edd615ce | ||
|
|
a9dcf4ce74 | ||
|
|
30c047fedd | ||
|
|
bc309b3ddd | ||
|
|
a041601f1f | ||
|
|
60e93521d5 | ||
|
|
14cd16f1f8 | ||
|
|
5800d78b99 | ||
|
|
87053c5369 | ||
|
|
e14b6abf9d | ||
|
|
740f814ce0 | ||
|
|
5bcf4292b6 | ||
|
|
ad7d1d4f29 | ||
|
|
22717a1c06 | ||
|
|
82e511ddb1 | ||
|
|
5843038a08 | ||
|
|
958d8b6bb4 | ||
|
|
a43fc9ad17 | ||
|
|
c69a38652d | ||
|
|
a4de85dc80 | ||
|
|
9e9ca66467 | ||
|
|
82ff0c5852 | ||
|
|
07f71e2034 | ||
|
|
328c23c5d4 | ||
|
|
268c692efd | ||
|
|
434f1ec542 | ||
|
|
927ffef864 | ||
|
|
047bf94908 | ||
|
|
880d0ec19f | ||
|
|
2430612ad4 | ||
|
|
e87f1107ca | ||
|
|
bebaf4c112 | ||
|
|
d32add9938 | ||
|
|
975a2b3f59 | ||
|
|
6437d0180b | ||
|
|
c65b5b9f84 | ||
|
|
bf373f9da1 | ||
|
|
2064fc89c0 | ||
|
|
5a4c7c75c0 | ||
|
|
5ad2fdcf0b | ||
|
|
8d37d418e7 | ||
|
|
8df3350252 | ||
|
|
931da04dc2 | ||
|
|
7efa946b02 | ||
|
|
fe7b094b9e | ||
|
|
7382c23a17 | ||
|
|
0b86aa5d29 | ||
|
|
f04b2d4350 | ||
|
|
9c65798902 | ||
|
|
d8f56de258 | ||
|
|
18e45aab98 | ||
|
|
344b784d69 | ||
|
|
333998509f | ||
|
|
8796df8218 | ||
|
|
17ae0ed3ee | ||
|
|
d59b0f6ff7 | ||
|
|
1898201b8b | ||
|
|
40214ef109 | ||
|
|
4f70ab8e27 | ||
|
|
416f245e6c | ||
|
|
177806068d | ||
|
|
7950f2d17d | ||
|
|
cf3d55fa10 | ||
|
|
85f94676ba | ||
|
|
52ffb67b33 | ||
|
|
0d6c405ccb | ||
|
|
0c064b1b79 | ||
|
|
63e56facbf | ||
|
|
f2dc0d3115 | ||
|
|
286fbc07e9 | ||
|
|
a7e53b8134 | ||
|
|
afc2500aee | ||
|
|
c4062f495a | ||
|
|
d3ecd22dba | ||
|
|
5efbde4fe9 | ||
|
|
c4a0a40473 | ||
|
|
f59a68c531 | ||
|
|
5282699f19 | ||
|
|
648d9e253c | ||
|
|
5b14cc6f0b | ||
|
|
e575405d7b | ||
|
|
2e819a360c | ||
|
|
1c09373b4f | ||
|
|
422a206484 | ||
|
|
e545c310ee | ||
|
|
ce1ec81d6f | ||
|
|
33c6341ccd | ||
|
|
b74ecd8a75 | ||
|
|
bcc1ec65f9 | ||
|
|
e82c96dab1 | ||
|
|
ea75f01ba2 | ||
|
|
3a2b2de814 | ||
|
|
7b5b070900 | ||
|
|
8d73608672 | ||
|
|
9f7433d4f3 | ||
|
|
bbffd1b5b6 | ||
|
|
31d17de26c | ||
|
|
3797a4839d | ||
|
|
f85b17a00e | ||
|
|
33b6478cc7 | ||
|
|
317bca1008 | ||
|
|
4d83fd4238 | ||
|
|
fd14ad6ce9 | ||
|
|
31590afc5f | ||
|
|
85281d8efa | ||
|
|
7a2af4a2a2 | ||
|
|
465be9b16e | ||
|
|
19ae04da66 | ||
|
|
2e00f00ab0 | ||
|
|
e99f43f59c | ||
|
|
2637931102 | ||
|
|
54067d105b | ||
|
|
4c415aefed | ||
|
|
b28fb90851 | ||
|
|
8b7fa6627f | ||
|
|
f148b7bfc0 | ||
|
|
a0342d9527 | ||
|
|
2f4cc5480e | ||
|
|
5e6c3b9d0e | ||
|
|
0a461b829a | ||
|
|
91e9495148 | ||
|
|
873966aa86 | ||
|
|
6bd08a0b6f | ||
|
|
76b87b1bbd | ||
|
|
1b929e3afc | ||
|
|
6b9b42bbdf | ||
|
|
67cc242820 | ||
|
|
b5a85b51b6 | ||
|
|
2b5639d503 | ||
|
|
db4bf20df3 | ||
|
|
59e9a87d95 | ||
|
|
bbc12378d4 | ||
|
|
5bec61b824 | ||
|
|
7a0fbd0eb1 | ||
|
|
53d30ccde9 | ||
|
|
7d9f408d3a | ||
|
|
260c4e8503 | ||
|
|
dbc66d0405 | ||
|
|
9578a3cc31 | ||
|
|
83b480761f | ||
|
|
b40b85e006 | ||
|
|
97772f406d | ||
|
|
8c75b65475 | ||
|
|
0f81490830 | ||
|
|
7da5d83d6e | ||
|
|
1cfdd1283a | ||
|
|
762e1167c7 | ||
|
|
2d55c94c7b | ||
|
|
c9e712d07b | ||
|
|
a887bed25b | ||
|
|
3fc783617a | ||
|
|
34d9a17aad | ||
|
|
40ee8de171 | ||
|
|
feb7d57333 | ||
|
|
390b903c55 | ||
|
|
1ba27853bd | ||
|
|
de61bb6a35 | ||
|
|
01c8df01ec | ||
|
|
613139e7be | ||
|
|
fb100dbf98 | ||
|
|
ecf61be633 | ||
|
|
1619317c3b | ||
|
|
76fabe8785 | ||
|
|
1a17c2ba1f | ||
|
|
a04de87584 | ||
|
|
ffbb0f6a60 | ||
|
|
1c82c42cb3 | ||
|
|
11f79a2095 | ||
|
|
847c06d88b | ||
|
|
209569a035 | ||
|
|
0852e83eec | ||
|
|
ca084ab1a2 | ||
|
|
cab2b96871 | ||
|
|
8675dff045 | ||
|
|
ed2adc7025 | ||
|
|
ddc7a2dd4d | ||
|
|
2f0cdfd564 | ||
|
|
c154721f4a | ||
|
|
48cdae2829 | ||
|
|
9571a9b53d | ||
|
|
f1e0ebfe93 | ||
|
|
c7ba519af2 | ||
|
|
04de977855 | ||
|
|
591a05caa3 | ||
|
|
82700ea95a | ||
|
|
a36b29c25c | ||
|
|
c3af3ff1d0 | ||
|
|
1592e578ed | ||
|
|
e640683c97 | ||
|
|
e6bddd3ed2 | ||
|
|
bd0549caea | ||
|
|
08a53e5eca | ||
|
|
025972ef64 | ||
|
|
00a3e368b4 | ||
|
|
6b2465746a | ||
|
|
35e2cee5c5 | ||
|
|
d775fe7936 | ||
|
|
dc13eb6df0 | ||
|
|
798636c95b | ||
|
|
25fdf6cb16 | ||
|
|
044a45db2e | ||
|
|
0aec2df74f | ||
|
|
4f9c5b60c5 | ||
|
|
bd13df972e | ||
|
|
a971910723 | ||
|
|
b8a6fee6d6 | ||
|
|
0bfa981e70 | ||
|
|
070bdda011 | ||
|
|
e19c026083 | ||
|
|
8b383f86de | ||
|
|
9ebd62f676 | ||
|
|
2c3e2b701e | ||
|
|
16f95123cd | ||
|
|
0a176df6fb | ||
|
|
d862c43be0 | ||
|
|
a452767e34 | ||
|
|
f0aeef82a1 | ||
|
|
06b6eaba06 | ||
|
|
713a7d518d | ||
|
|
5702e4bc24 | ||
|
|
9b37b1569c | ||
|
|
5f1f1bb5ed | ||
|
|
9ff2df78f0 | ||
|
|
74f26bb667 | ||
|
|
1f11c1f71a | ||
|
|
8c8c37a66b | ||
|
|
d4f9fd7204 | ||
|
|
e70e72e025 | ||
|
|
e2ce6a0dab | ||
|
|
657ea2686f | ||
|
|
311df9c521 | ||
|
|
ff93d9dbda | ||
|
|
86ada87529 | ||
|
|
d74437af57 | ||
|
|
c82ac420fc | ||
|
|
f91cb9321e | ||
|
|
cc1a168aa0 | ||
|
|
ee82d35ed8 | ||
|
|
8bca30cfe4 | ||
|
|
fe9a5d3159 | ||
|
|
f43d21d0af | ||
|
|
8e2c3b315b | ||
|
|
9079fb6a0d | ||
|
|
db3f0048d8 | ||
|
|
d3d8284985 | ||
|
|
f545faa06d | ||
|
|
458aadbb10 | ||
|
|
f2ec0d80a8 | ||
|
|
be6bb5314e | ||
|
|
98114944fc | ||
|
|
6690023555 | ||
|
|
a7e8187a0d | ||
|
|
0c1b72616a | ||
|
|
945a378e55 | ||
|
|
29c5be47ed | ||
|
|
e0f18b2255 | ||
|
|
e755aafe29 | ||
|
|
e1b3a25008 | ||
|
|
69c1cd3f38 | ||
|
|
ce13fbb98a | ||
|
|
084d9e0009 | ||
|
|
3db9b06a6e | ||
|
|
e9be8016e6 | ||
|
|
1f9e21ebd5 | ||
|
|
a91d9054ad | ||
|
|
6c90d12a0c | ||
|
|
38e8ccac92 | ||
|
|
1d19a58424 | ||
|
|
f47f9ceade | ||
|
|
81effe674d | ||
|
|
831251bcaa | ||
|
|
f4630f9044 | ||
|
|
dae311ea9d | ||
|
|
4677b46904 | ||
|
|
a4dd2b1916 | ||
|
|
3d117b8964 | ||
|
|
6a083e9561 | ||
|
|
044d359a7e | ||
|
|
f35d4164d6 | ||
|
|
3058f8fd69 | ||
|
|
5129ed215e | ||
|
|
b93079f1c1 | ||
|
|
a1098384c0 | ||
|
|
43bca4df40 | ||
|
|
82269e4b8c | ||
|
|
14e49614e6 | ||
|
|
a221b2807f | ||
|
|
0d66b1cc1c | ||
|
|
1843354d88 | ||
|
|
bd7d1e2f16 | ||
|
|
aff0bbcc32 | ||
|
|
33e009bedb | ||
|
|
f94dc67a43 | ||
|
|
091f63fd4e | ||
|
|
3a4c981e31 | ||
|
|
0d48344f93 | ||
|
|
21ceba6cfd | ||
|
|
f8302c5470 | ||
|
|
7a7e07a57c | ||
|
|
520530dfcf | ||
|
|
31c18b4bc7 | ||
|
|
1ec365de25 | ||
|
|
99f3eabb1b | ||
|
|
32479744f6 | ||
|
|
b68de2330d | ||
|
|
68a6579852 | ||
|
|
798798f7ab | ||
|
|
54e9442a14 | ||
|
|
f7b9f35ce1 | ||
|
|
068e6ce2c9 | ||
|
|
5d4bb4d6f8 | ||
|
|
a05c19682e | ||
|
|
5caa7436d8 | ||
|
|
512a900202 | ||
|
|
ba7b2cc1f6 | ||
|
|
ac73d43444 | ||
|
|
33434a40d7 | ||
|
|
844d69143f | ||
|
|
77275a9b31 | ||
|
|
de10d9be08 | ||
|
|
3c227af508 | ||
|
|
4c1a479a60 | ||
|
|
cc95d251d6 | ||
|
|
1f247cf813 | ||
|
|
c9bb33afc3 | ||
|
|
97fb9d283f | ||
|
|
66016b8499 | ||
|
|
8bbf0293f5 | ||
|
|
87b229d280 | ||
|
|
2a86b3e31d | ||
|
|
436dd6c0a4 | ||
|
|
f6bdefe3f3 | ||
|
|
cd71077c6a | ||
|
|
029b33c650 | ||
|
|
f4f4edf276 | ||
|
|
992ea5802a | ||
|
|
376a629c9f | ||
|
|
303fa37b60 | ||
|
|
ef02414d7e | ||
|
|
bcf83ea792 | ||
|
|
86a27cf16d | ||
|
|
08ae0dd74b | ||
|
|
93f3a7f96a | ||
|
|
7856b1202d | ||
|
|
e5ddbcab7d | ||
|
|
f9bc980b0b | ||
|
|
806754b512 | ||
|
|
4d18df204a | ||
|
|
04b4431bc0 | ||
|
|
dfd494c113 | ||
|
|
57897cc8c2 | ||
|
|
459c8be94f | ||
|
|
5e158b51db | ||
|
|
fbecc18e2e | ||
|
|
b538c5345e | ||
|
|
694208865b | ||
|
|
a75c435245 | ||
|
|
53c8e4263b | ||
|
|
078549518d | ||
|
|
4c844081f3 | ||
|
|
91441c3fb2 | ||
|
|
b152cbe45a | ||
|
|
c08aab90ec | ||
|
|
8d091ec062 | ||
|
|
0376e59520 | ||
|
|
e25fe22f9d | ||
|
|
bef7f6745c | ||
|
|
775919c129 | ||
|
|
702acc06d8 | ||
|
|
b5a1daa756 | ||
|
|
5a47301dbd | ||
|
|
e33d9e77f4 | ||
|
|
aff4208244 | ||
|
|
73dbaefec5 | ||
|
|
05edcde6c9 | ||
|
|
01ccc2cc96 | ||
|
|
cd093a07a3 | ||
|
|
7e450542d9 | ||
|
|
45545e897c | ||
|
|
eccc8109c1 | ||
|
|
2fabcd0455 | ||
|
|
e3ce295215 | ||
|
|
8df59c01d5 | ||
|
|
15f9a83618 | ||
|
|
d572381a37 | ||
|
|
9127001f11 | ||
|
|
742420a5e2 | ||
|
|
f439df4441 | ||
|
|
c92e8940dc | ||
|
|
c68fc4f31a | ||
|
|
0e80e47592 | ||
|
|
54b9311344 | ||
|
|
9387b79b98 | ||
|
|
5c2de3a9ea | ||
|
|
eac5b48da0 | ||
|
|
f89d948c06 | ||
|
|
45a0988833 | ||
|
|
afbb31c05e | ||
|
|
e6af6487e1 | ||
|
|
c0b45fa36f | ||
|
|
cb47595f13 | ||
|
|
c59704a24b | ||
|
|
f2ecfdc96a | ||
|
|
717d409b72 | ||
|
|
6e207c823e | ||
|
|
b69294b6d6 | ||
|
|
6cbaa4787b | ||
|
|
8b66c433c5 | ||
|
|
3329bfa5b2 | ||
|
|
f41f5785bf | ||
|
|
55f148f499 | ||
|
|
2978bb1773 | ||
|
|
0152e12172 | ||
|
|
38d73a4be6 | ||
|
|
34bd04f925 | ||
|
|
17d789a785 | ||
|
|
63a263f542 | ||
|
|
932490d7f1 | ||
|
|
a855abf8c0 | ||
|
|
0d2398aaff | ||
|
|
c17a6ff533 | ||
|
|
c3c7944d79 | ||
|
|
75555585e8 | ||
|
|
28e0003a9a | ||
|
|
2818ce4632 | ||
|
|
52ee796d6d | ||
|
|
0f737f2999 | ||
|
|
6a185e94b9 | ||
|
|
ba0a78da2a | ||
|
|
f0bbcef3a4 | ||
|
|
d7280f82ac | ||
|
|
aa53d0978c | ||
|
|
ffdd8b3afa | ||
|
|
86d249eb16 | ||
|
|
28f74cf1c6 | ||
|
|
83655d5c00 | ||
|
|
63eaac67a6 | ||
|
|
1f7983059a | ||
|
|
51e087fd87 | ||
|
|
679147cd5d | ||
|
|
40eb652cfa | ||
|
|
f4e4ea1374 | ||
|
|
199d67581a | ||
|
|
49bd893a77 | ||
|
|
8729a60c1d | ||
|
|
e4f187cd3d | ||
|
|
f9c706e31b | ||
|
|
c5728291ba | ||
|
|
68d22e78bf | ||
|
|
0bfce7aca4 | ||
|
|
7faa2356d8 | ||
|
|
2a8a293c7c | ||
|
|
f3e8352193 | ||
|
|
ca874ba8c7 | ||
|
|
f274f76607 | ||
|
|
a8b9cefa73 | ||
|
|
b9e4a052b8 | ||
|
|
4a669f5478 | ||
|
|
ade8aab43f | ||
|
|
17d2a9c435 | ||
|
|
6f2347fc71 | ||
|
|
dd245fe8bd | ||
|
|
f12c058b78 | ||
|
|
3cba8778b2 | ||
|
|
1c33c936e6 | ||
|
|
67d67289c7 | ||
|
|
f4ab9f9932 | ||
|
|
b752fe6808 | ||
|
|
114677b747 | ||
|
|
9362b9fdfe | ||
|
|
f48921c256 | ||
|
|
51e0eef11e | ||
|
|
925c2a2ca2 | ||
|
|
f1465b6847 | ||
|
|
5260d70b19 | ||
|
|
339fd9c5a4 | ||
|
|
0f14b92bce | ||
|
|
43d6ad5fda | ||
|
|
667c40c3de | ||
|
|
3b8b8a2ee3 | ||
|
|
6f04ee879c | ||
|
|
e1e76d3f88 | ||
|
|
221aa8968a | ||
|
|
86931f546f | ||
|
|
ae40bb00b3 | ||
|
|
3dd93f5533 | ||
|
|
181dc5d75e | ||
|
|
ae4c4708ad | ||
|
|
34c2e52bd5 | ||
|
|
5cd1fdeb9e | ||
|
|
dbe6de313e | ||
|
|
77c77fbd42 | ||
|
|
9b4054f1fc | ||
|
|
af3911b833 | ||
|
|
4258bf3d54 | ||
|
|
4d1d66d906 | ||
|
|
b727e0be71 | ||
|
|
ea313d0c1e | ||
|
|
c1507eda45 | ||
|
|
ce7496aec9 | ||
|
|
b16c12f67b | ||
|
|
1b24e6ed76 | ||
|
|
52f3833811 | ||
|
|
b1100b5e34 | ||
|
|
ab2c6cb008 | ||
|
|
f2c3f4a944 | ||
|
|
6bc11c4450 | ||
|
|
643c85e9c8 | ||
|
|
ee9950ec2f | ||
|
|
dc10594d7b | ||
|
|
e02fac4968 | ||
|
|
5a88546a80 | ||
|
|
f67d6bbca3 | ||
|
|
c970c4ee41 | ||
|
|
3a6623104f | ||
|
|
b18a2bdcd3 | ||
|
|
d09eaef542 | ||
|
|
13cca8a66a | ||
|
|
8ed2330d6e | ||
|
|
261237745f | ||
|
|
c9d76a381b | ||
|
|
2961afe8fb | ||
|
|
ea03bee1b9 | ||
|
|
d1a96c2543 | ||
|
|
11b1498a6e | ||
|
|
f59500a90b | ||
|
|
3df25fadfa | ||
|
|
0e6a6bf880 | ||
|
|
e1f01305d8 | ||
|
|
23b83cb736 | ||
|
|
e16196124e | ||
|
|
ab2197bc75 | ||
|
|
a887e475e3 | ||
|
|
4400d2fdd9 | ||
|
|
6197a7639a | ||
|
|
91f65cedc8 | ||
|
|
7b85ee4954 | ||
|
|
1af01f5e30 | ||
|
|
3efc0d8681 | ||
|
|
09f2cbfb18 | ||
|
|
88791089ed | ||
|
|
089eb1a099 | ||
|
|
b40dc550ed | ||
|
|
c210984b40 | ||
|
|
455dc072ba | ||
|
|
a851b77ac9 | ||
|
|
e9a2b72ddb | ||
|
|
c0be055541 | ||
|
|
51d7f1264b | ||
|
|
3359b942b3 | ||
|
|
2155ef0208 | ||
|
|
36d6450977 | ||
|
|
02a576a6a0 | ||
|
|
2478b87432 | ||
|
|
e33c714073 | ||
|
|
f4d61ac6d2 | ||
|
|
5c10eff67f | ||
|
|
239dd978ff | ||
|
|
af4cf463f5 | ||
|
|
21c1b8d834 | ||
|
|
16913ba814 | ||
|
|
6bb9c442b2 | ||
|
|
c407921644 | ||
|
|
a1411c36de | ||
|
|
c69fa18434 | ||
|
|
4cb01fe332 | ||
|
|
612a7e76f1 | ||
|
|
bf060387af | ||
|
|
0778d7de80 | ||
|
|
9085c3b73d | ||
|
|
306ba917ea | ||
|
|
1a3a303f8d | ||
|
|
5906268917 | ||
|
|
a1d411a018 | ||
|
|
dbb7e5464b | ||
|
|
11ad64f6cb | ||
|
|
4e87e62d5c | ||
|
|
a5bd095c30 | ||
|
|
b17995a332 | ||
|
|
ce6e8ed8fe | ||
|
|
1755025e7f | ||
|
|
1a4ba4c390 | ||
|
|
0a6ceabb9b | ||
|
|
d71a8fece8 | ||
|
|
5202b7da48 | ||
|
|
1b5a418fd3 | ||
|
|
a11044f789 | ||
|
|
4b2bf41381 | ||
|
|
07d5badfed | ||
|
|
10ee2e0dad | ||
|
|
6500aafcb8 | ||
|
|
6ebdf91b32 | ||
|
|
91cd350b63 | ||
|
|
6ea9642d64 | ||
|
|
65277e47c5 | ||
|
|
9e3c83372f | ||
|
|
809db853fa | ||
|
|
62a20b8a2d | ||
|
|
d0612be402 | ||
|
|
5f8ec0dc8b | ||
|
|
fda4b1106e | ||
|
|
ac43eab51f | ||
|
|
8d0417497b | ||
|
|
90b9f7e08c | ||
|
|
2c404daca6 | ||
|
|
0e271799f2 | ||
|
|
3c0de17133 | ||
|
|
bd1f2ccaf8 | ||
|
|
ec491b023f | ||
|
|
f191bff0b9 | ||
|
|
1a04da864f | ||
|
|
c8c975c99b | ||
|
|
a617d52374 | ||
|
|
624474386a | ||
|
|
e0a787b5ee | ||
|
|
63598688e4 | ||
|
|
497cdc9250 | ||
|
|
edaf14f2b6 | ||
|
|
6fbb984ebf | ||
|
|
ba151eda0a | ||
|
|
c05717a5f0 | ||
|
|
5a488b6517 | ||
|
|
ae1d50d19a | ||
|
|
fe25effe7c | ||
|
|
d05395fe90 | ||
|
|
37b10666de | ||
|
|
41c8e87be8 | ||
|
|
55afc1ad21 | ||
|
|
16c6ca72cd | ||
|
|
b873ec2bce | ||
|
|
1bc805bb4b | ||
|
|
348c75c91b | ||
|
|
76ebdb265b | ||
|
|
88ae3510ff | ||
|
|
c07899701a | ||
|
|
ab42671c63 | ||
|
|
b3ac33cbcf | ||
|
|
3b94162803 | ||
|
|
52aade232d | ||
|
|
3a9276307c | ||
|
|
ca6326c937 | ||
|
|
8da16ac302 | ||
|
|
761bb3cf53 | ||
|
|
c1c269d9ef | ||
|
|
9edac05e05 | ||
|
|
9c1620d49c | ||
|
|
65bb6eb284 | ||
|
|
aff55ff105 | ||
|
|
4a67bb5806 | ||
|
|
1afafde3b3 | ||
|
|
ab634ce61a | ||
|
|
9d06ebd01a | ||
|
|
09723ec0e5 | ||
|
|
864761c2d0 | ||
|
|
abe7f7bc36 | ||
|
|
717bcc4ad8 | ||
|
|
11ffdac3f8 | ||
|
|
cf7d5d0c56 | ||
|
|
375f1b1fde | ||
|
|
ad3c6ef205 | ||
|
|
30d9e2ee3c | ||
|
|
1038916460 | ||
|
|
73de9f9d6a | ||
|
|
f40eb9774e | ||
|
|
496e07c1c9 | ||
|
|
c238647020 | ||
|
|
78f94986e3 | ||
|
|
8f52ab8201 | ||
|
|
260ebcc1ca | ||
|
|
09cb48e41c | ||
|
|
674106c7b6 | ||
|
|
8196430f47 | ||
|
|
7a99e56893 | ||
|
|
79ba0314e9 | ||
|
|
c441f8080e | ||
|
|
bd1e757350 | ||
|
|
3144be5c81 | ||
|
|
fdc7cb565d | ||
|
|
a6dbde4c46 | ||
|
|
8ce23e2c71 | ||
|
|
8a3f4fc616 | ||
|
|
66c1e6b0e8 | ||
|
|
beee6e03b1 | ||
|
|
902372067c | ||
|
|
7adaf8f812 | ||
|
|
71753cdd46 | ||
|
|
d3363430dc | ||
|
|
945e65eedf | ||
|
|
85a050fca7 | ||
|
|
bb86d66496 | ||
|
|
aba8789542 | ||
|
|
5f1bbbde49 | ||
|
|
0203eaab00 | ||
|
|
2807274e2d | ||
|
|
55a5ad5cdc | ||
|
|
b3c4a39208 | ||
|
|
cac7af2c78 | ||
|
|
2d4dc544be | ||
|
|
171f97868d | ||
|
|
becaec19a7 | ||
|
|
bc630cc52b | ||
|
|
d591cb0dfb | ||
|
|
07a9cbe0a9 | ||
|
|
7c802f6d83 | ||
|
|
431e930367 | ||
|
|
9e8ffa14cb | ||
|
|
0ccd7c97ab | ||
|
|
4e64e71e28 | ||
|
|
86c7f45383 | ||
|
|
50b36a732c | ||
|
|
f54bcba339 | ||
|
|
f0209ac2f6 | ||
|
|
e1dcd11051 | ||
|
|
24734a33e7 | ||
|
|
1df54ea0cd | ||
|
|
e6df2259ab | ||
|
|
96ae0129ef | ||
|
|
aaadc61ee8 | ||
|
|
44a6b63316 | ||
|
|
5f058c3f07 | ||
|
|
b116dc506b | ||
|
|
bf58f26305 | ||
|
|
601f174ea0 | ||
|
|
a34c21cde3 | ||
|
|
bb19bb601e | ||
|
|
05dbd3f7d7 | ||
|
|
dee76e4189 | ||
|
|
b615d670b3 | ||
|
|
b9bb4a62d6 | ||
|
|
61e2bff757 | ||
|
|
9713016637 | ||
|
|
5c7cb1594b | ||
|
|
3eb57370a6 | ||
|
|
ac8b1e595f | ||
|
|
31c55213ff | ||
|
|
23da90e25d | ||
|
|
60ee79363d | ||
|
|
8fa6d0d302 | ||
|
|
a534f9f9b6 | ||
|
|
aa99e805c8 | ||
|
|
0049c80cd9 | ||
|
|
ebc0943713 | ||
|
|
451aef7a1c | ||
|
|
22882d7c04 | ||
|
|
c3cde864f8 | ||
|
|
f860ddbbb7 | ||
|
|
89cc6aa430 | ||
|
|
c93731339f | ||
|
|
bab448681d | ||
|
|
de2d3e3fd8 | ||
|
|
295d251232 | ||
|
|
83f6b8e847 | ||
|
|
e38fef0009 | ||
|
|
6c3424dc3f | ||
|
|
d1f0bc48ce | ||
|
|
bb005f3f9a | ||
|
|
e6dbfd918c | ||
|
|
c2f0711db0 | ||
|
|
92153fd898 | ||
|
|
a9d2480c7f | ||
|
|
fd70d503e0 | ||
|
|
8b73c8076f | ||
|
|
971a96a962 | ||
|
|
e9838a83ce | ||
|
|
837fc9847d | ||
|
|
7e883f891a | ||
|
|
e19a69442d | ||
|
|
ebd95dd082 | ||
|
|
f7b7d008b6 | ||
|
|
b39454ca16 | ||
|
|
00943a025f | ||
|
|
600f748cb0 | ||
|
|
038b107c3d | ||
|
|
c6e08d76fd | ||
|
|
6daac151b8 | ||
|
|
e08161a302 | ||
|
|
341eafcf04 | ||
|
|
dd649eb4cc | ||
|
|
d43f5f17fd | ||
|
|
193cc3ba9a | ||
|
|
fd667ca1d8 | ||
|
|
9d40b8a83c | ||
|
|
b0169ba064 | ||
|
|
9ace35ee8b | ||
|
|
ca2cfaf71e | ||
|
|
b06f299748 | ||
|
|
beea014343 | ||
|
|
70072e2842 | ||
|
|
f0086e66ae | ||
|
|
7fe13e72d8 | ||
|
|
87f0ce793d | ||
|
|
25cf755f30 | ||
|
|
c7a8051a71 | ||
|
|
a47553b7aa | ||
|
|
d7954014a4 | ||
|
|
429345b9df | ||
|
|
eaab01fa49 | ||
|
|
4f9c5981a9 | ||
|
|
b3757e424f | ||
|
|
2381fe72cb | ||
|
|
e28bc7023f | ||
|
|
aff8fb28bd | ||
|
|
6a543c8066 | ||
|
|
4d90527a6e | ||
|
|
c64b842df9 | ||
|
|
27c4252548 | ||
|
|
10b93efc4a | ||
|
|
0696d430c9 | ||
|
|
68b231bd89 | ||
|
|
6ec859f2b0 | ||
|
|
452551fa23 | ||
|
|
ec05c64ead | ||
|
|
cd15a17970 | ||
|
|
6072e9a52c | ||
|
|
b78e03934d | ||
|
|
3c0d162961 | ||
|
|
48cf9edcf5 | ||
|
|
0c8c1ee96f | ||
|
|
7d80c5a722 | ||
|
|
5ec21d56ef | ||
|
|
266c8f5a85 | ||
|
|
162504e90c | ||
|
|
5ea0592f61 | ||
|
|
054e97d614 | ||
|
|
28983c94ff | ||
|
|
0cfa489cf0 | ||
|
|
e0af5c280d | ||
|
|
d21dc0da78 | ||
|
|
60aca9ea18 | ||
|
|
6a8ad0b357 | ||
|
|
bd970b8b27 | ||
|
|
0f3155660e | ||
|
|
437df04d8c | ||
|
|
8216360da8 | ||
|
|
c5b85f2733 | ||
|
|
ba88bb5f5f | ||
|
|
5895d43574 | ||
|
|
e78f252713 | ||
|
|
6a78580429 | ||
|
|
6002d72603 | ||
|
|
934734a85a | ||
|
|
491934784f | ||
|
|
fe69a7b116 | ||
|
|
0bef74d499 | ||
|
|
2322de653c | ||
|
|
95b94b2166 | ||
|
|
dd4d623612 | ||
|
|
41a2632ae7 | ||
|
|
f3a228ed61 | ||
|
|
c4fdc26fa5 | ||
|
|
7de71333c6 | ||
|
|
cd9b29ff3f | ||
|
|
50a7c3c20d | ||
|
|
c3f52ab52d | ||
|
|
40fbe7fa8e | ||
|
|
ef922ff757 | ||
|
|
1841316f18 | ||
|
|
0a2f87f941 | ||
|
|
c69900325d | ||
|
|
685737b816 | ||
|
|
5d766bc4d6 | ||
|
|
1083c0cd9a | ||
|
|
7b8f086f72 | ||
|
|
21d538a738 | ||
|
|
36f448f47f | ||
|
|
dbd9f05c06 | ||
|
|
77757f6d39 | ||
|
|
018614cdf0 | ||
|
|
5d9680b00d | ||
|
|
c8982f4165 | ||
|
|
71f0dd858b | ||
|
|
956bdb18c9 | ||
|
|
a07b1f630a | ||
|
|
266586e866 | ||
|
|
b481927d5e | ||
|
|
7bd6052efe | ||
|
|
07801cbf09 | ||
|
|
81e74858d8 | ||
|
|
f4e714d54a | ||
|
|
edccbc0481 | ||
|
|
7e09d210ba | ||
|
|
dab768212a | ||
|
|
c033cfc684 | ||
|
|
89593a82c1 | ||
|
|
ba93504804 | ||
|
|
57cb23ac81 | ||
|
|
5155f026b4 | ||
|
|
d521e716dd | ||
|
|
3b49a99b60 | ||
|
|
f129e0ecb5 | ||
|
|
88143f1934 | ||
|
|
3137665e6e | ||
|
|
f35bd34002 | ||
|
|
b9560ec9cb | ||
|
|
189924cabf | ||
|
|
c2277796e4 | ||
|
|
f97b250509 | ||
|
|
59981b8818 | ||
|
|
40bce6310c | ||
|
|
a4f9e5031f | ||
|
|
4da325a45c | ||
|
|
fd5881fb64 | ||
|
|
0f6e464126 | ||
|
|
6132a82287 | ||
|
|
32a868d431 | ||
|
|
94f91543b6 | ||
|
|
3d52ef6e39 | ||
|
|
a45205b988 | ||
|
|
ec9c14c09d | ||
|
|
b6fc35f637 | ||
|
|
e24d62e583 | ||
|
|
0386b5ae54 | ||
|
|
a0253cab62 | ||
|
|
0f32aeec70 | ||
|
|
78145cd166 | ||
|
|
904f0ebec3 | ||
|
|
039dc33367 | ||
|
|
859009259a | ||
|
|
4c5255f5ad | ||
|
|
279e475b89 | ||
|
|
f4aedda13a | ||
|
|
1381f0f28e | ||
|
|
f967e9d021 | ||
|
|
5179063e71 | ||
|
|
ad4bbf5173 | ||
|
|
35f30a306b | ||
|
|
c37d3f6486 | ||
|
|
bd786b8ef0 | ||
|
|
d02e7d9e6a | ||
|
|
1c87b082c1 | ||
|
|
99d86c7175 | ||
|
|
68ead67a63 | ||
|
|
2d38b75400 | ||
|
|
f59a607361 | ||
|
|
d21767dc9f | ||
|
|
ab78d4e2b7 | ||
|
|
127005d733 | ||
|
|
0ae666f3e6 | ||
|
|
23f2efa8c1 | ||
|
|
5791e1398c | ||
|
|
9b72661767 | ||
|
|
0958fe5a4e | ||
|
|
4a1dc29e23 | ||
|
|
2ca668e79e | ||
|
|
ee59016585 | ||
|
|
7ac09681a2 | ||
|
|
1863f38286 | ||
|
|
6b6f54b79b | ||
|
|
b67ec01d41 | ||
|
|
2c154ccbe7 | ||
|
|
3f95824e65 | ||
|
|
29722af1ae | ||
|
|
563fc7c6d7 | ||
|
|
9b8fa69c15 | ||
|
|
f5dc436441 | ||
|
|
d9d329bec8 | ||
|
|
76879e977b | ||
|
|
9c3c9a8eb9 | ||
|
|
2fd69f13d9 | ||
|
|
eb66060cd7 | ||
|
|
8a19f8a63c | ||
|
|
f7c11a27d0 | ||
|
|
418dab9b96 | ||
|
|
09ad42b918 | ||
|
|
074c92b0a3 | ||
|
|
e893e1fc63 | ||
|
|
6622b7b49a | ||
|
|
afab38b0d7 | ||
|
|
ede58ade4c | ||
|
|
a2dd9ec2e1 | ||
|
|
591c333dcd | ||
|
|
6971143dc5 | ||
|
|
5d6ea4a81b | ||
|
|
2374a3ef64 | ||
|
|
0d9e435bfe | ||
|
|
9af0dd23dd | ||
|
|
39eb6df769 | ||
|
|
c0f25d24b2 | ||
|
|
4f778da35e | ||
|
|
f0f8205b8b | ||
|
|
2bb1de1805 | ||
|
|
0081c6911d | ||
|
|
2527037973 | ||
|
|
1d951cfc49 | ||
|
|
32a0255ce3 | ||
|
|
be3a13a0d6 | ||
|
|
d293aa9ced | ||
|
|
0cfcaca351 | ||
|
|
412ba5b2a9 | ||
|
|
c17f93e6c0 | ||
|
|
a5afa37203 | ||
|
|
6bfbed0616 | ||
|
|
185c90df12 | ||
|
|
7463d9c51d | ||
|
|
ec5a967937 | ||
|
|
4bc98f7aa2 | ||
|
|
207960b459 | ||
|
|
7b3b46c675 | ||
|
|
5e01ecbc05 | ||
|
|
c98aa0e895 | ||
|
|
263203ec28 | ||
|
|
84f28fc5d6 | ||
|
|
9144ea2b1d | ||
|
|
0d73dcaf0f | ||
|
|
a6a3afd130 | ||
|
|
7aa53635fe | ||
|
|
2ee0c61e62 | ||
|
|
3d23c13160 | ||
|
|
e2afd886fd | ||
|
|
aa682b3b7e | ||
|
|
e43479d948 | ||
|
|
a2f2f7717a | ||
|
|
740192564b | ||
|
|
8bcc0e392e | ||
|
|
ae319da5fd | ||
|
|
6d6848af5c | ||
|
|
0d60b58434 | ||
|
|
ad57f18894 | ||
|
|
80cd8f6a29 | ||
|
|
8cb903fbbb | ||
|
|
d1c327d508 | ||
|
|
eaf57229d3 | ||
|
|
4e967bc765 | ||
|
|
64788ffff6 | ||
|
|
3143e35d83 | ||
|
|
8d5a693382 | ||
|
|
1e185787a9 | ||
|
|
1b2ecde1c9 | ||
|
|
e8c3e9bcf8 | ||
|
|
cdfcef04a1 | ||
|
|
8aa35577b3 | ||
|
|
c4086d43db | ||
|
|
8059175a5c | ||
|
|
f8fd084bd2 | ||
|
|
d528704503 | ||
|
|
98076ee72d | ||
|
|
e6ef75204b | ||
|
|
d674cb7f20 | ||
|
|
114c179e5a | ||
|
|
598e062241 | ||
|
|
bf70082c22 | ||
|
|
2994272e91 | ||
|
|
cdedc2d188 | ||
|
|
42a3bbb0f4 | ||
|
|
eb79532812 | ||
|
|
5feb68a589 | ||
|
|
03f7f3ee67 | ||
|
|
6383bf7480 | ||
|
|
f471ef1bc7 | ||
|
|
7ebe0a9916 | ||
|
|
89e93fe01e | ||
|
|
0f8a5fdf49 | ||
|
|
3c91c9063b | ||
|
|
e629c7583b | ||
|
|
539b07e205 | ||
|
|
16d3e7085e | ||
|
|
c47fbc629b | ||
|
|
d04b19545d | ||
|
|
3b0e2c1c3f | ||
|
|
79a2745b4a | ||
|
|
6cc992ea54 | ||
|
|
3376354ed8 | ||
|
|
c2e1370588 | ||
|
|
93616fe776 | ||
|
|
e5972bbcde | ||
|
|
952e510dfa | ||
|
|
8f442dde03 | ||
|
|
c1e53cdc72 | ||
|
|
e9f6a43073 | ||
|
|
67380cf47b | ||
|
|
39fdb0f9c4 | ||
|
|
85fbd6e9c6 | ||
|
|
2cfdce88e0 | ||
|
|
ca6cbb95cc | ||
|
|
7cb440273c | ||
|
|
d96f2a7184 | ||
|
|
adcb1d7c65 | ||
|
|
04fbfad2d4 | ||
|
|
bab051a8c1 | ||
|
|
ad6de46ce4 | ||
|
|
282f7fb8fa | ||
|
|
5034ef787c | ||
|
|
3925166d31 | ||
|
|
7358e46815 | ||
|
|
8f09fc64bd | ||
|
|
b2de3d71c5 | ||
|
|
44ed991726 | ||
|
|
34b92cdb44 | ||
|
|
d3b2ff17d6 | ||
|
|
cc45a8ab06 | ||
|
|
105c528369 | ||
|
|
5d0b334d56 | ||
|
|
b092733c2e | ||
|
|
baeccdb161 | ||
|
|
394fc61129 | ||
|
|
55dc9d898f | ||
|
|
552d5c7ceb | ||
|
|
95065de39a | ||
|
|
a3ea4b8802 | ||
|
|
6bcff7828f | ||
|
|
2cb5ec5983 | ||
|
|
2bec8a4f1e | ||
|
|
7e15ff9486 | ||
|
|
12445fe2ed | ||
|
|
491407ddf8 | ||
|
|
6da55159a2 | ||
|
|
73fedc7275 | ||
|
|
c50d59874d | ||
|
|
b3d9ca4ccd | ||
|
|
4efaf8e882 | ||
|
|
178556142a | ||
|
|
7c1fbed057 | ||
|
|
bc902b8f74 |
19
.bra.toml
19
.bra.toml
@@ -1,19 +0,0 @@
|
||||
[run]
|
||||
init_cmds = [
|
||||
["make", "build-dev"],
|
||||
["./gogs", "web"]
|
||||
]
|
||||
watch_all = true
|
||||
watch_dirs = [
|
||||
"$WORKDIR/cmd",
|
||||
"$WORKDIR/models",
|
||||
"$WORKDIR/modules",
|
||||
"$WORKDIR/routers"
|
||||
]
|
||||
watch_exts = [".go"]
|
||||
ignore_files = [".+_test.go"]
|
||||
build_delay = 1500
|
||||
cmds = [
|
||||
["make", "build-dev"], # TAGS=sqlite cert pam tidb
|
||||
["./gogs", "web"]
|
||||
]
|
||||
13
.claude/commands/ghsa.md
Normal file
13
.claude/commands/ghsa.md
Normal file
@@ -0,0 +1,13 @@
|
||||
Analyze and help fix the GitHub Security Advisory (GHSA) at: $ARGUMENTS
|
||||
|
||||
Steps:
|
||||
1. Fetch the GHSA page using `gh api repos/gogs/gogs/security-advisories` and understand the vulnerability details (description, severity, affected versions, CWE).
|
||||
2. Verify the reported vulnerability actually exists, and why.
|
||||
3. Identify the affected code in this repository.
|
||||
4. Propose a fix with a clear explanation of the root cause and how the fix addresses it. Check for prior art in the codebase to stay consistent with existing patterns.
|
||||
5. Implement the fix. Only add tests when there is something meaningful to test at our layer.
|
||||
6. Run all the usual build and test commands.
|
||||
7. If a changelog entry is warranted (user will specify), add it to CHANGELOG.md with a placeholder for the PR link.
|
||||
8. Create a branch named after the GHSA ID, commit, and push.
|
||||
9. Create a pull request with a proper title and description, do not reveal too much detail and link the GHSA.
|
||||
10. If a changelog entry was added, update it with the PR link, then commit and push again.
|
||||
@@ -1,7 +0,0 @@
|
||||
conf/**
|
||||
docker/**
|
||||
modules/bindata/**
|
||||
packager/**
|
||||
public/**
|
||||
scripts/**
|
||||
templates/**
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"GOLANG": {
|
||||
"TOTAL_LOC": [500, 999, 1999, 9999],
|
||||
"TOO_MANY_FUNCTIONS": [50, 99, 199, 999],
|
||||
"TOO_MANY_IVARS": [20, 50, 70, 99]
|
||||
}
|
||||
}
|
||||
26
.deepsource.toml
Normal file
26
.deepsource.toml
Normal file
@@ -0,0 +1,26 @@
|
||||
version = 1
|
||||
|
||||
exclude_patterns = ["**/mocks_test.go"]
|
||||
|
||||
[[analyzers]]
|
||||
name = "docker"
|
||||
enabled = true
|
||||
|
||||
[[analyzers]]
|
||||
name = "shell"
|
||||
enabled = true
|
||||
|
||||
[[analyzers]]
|
||||
name = "go"
|
||||
enabled = true
|
||||
|
||||
[analyzers.meta]
|
||||
import_root = "github.com/gogs/gogs"
|
||||
|
||||
[[transformers]]
|
||||
name = "gofumpt"
|
||||
enabled = true
|
||||
|
||||
[[transformers]]
|
||||
name = "gofmt"
|
||||
enabled = true
|
||||
@@ -1,19 +1,15 @@
|
||||
.git
|
||||
.git/**
|
||||
packager
|
||||
packager/**
|
||||
.packager
|
||||
.packager/**
|
||||
scripts
|
||||
scripts/**
|
||||
.github/
|
||||
.github/**
|
||||
config.codekit
|
||||
.dockerignore
|
||||
*.yml
|
||||
*.md
|
||||
.bra.toml
|
||||
.editorconfig
|
||||
.gitignore
|
||||
Dockerfile*
|
||||
vendor
|
||||
vendor/**
|
||||
gogs
|
||||
|
||||
!Taskfile.yml
|
||||
|
||||
@@ -4,7 +4,6 @@ root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
@@ -16,10 +15,9 @@ indent_size = 4
|
||||
indent_style = tab
|
||||
indent_size = 2
|
||||
|
||||
[*.{less,yml}]
|
||||
[*.{less, yml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.js]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
indent_size = 2
|
||||
|
||||
19
.gitattributes
vendored
19
.gitattributes
vendored
@@ -1,11 +1,8 @@
|
||||
public/conf/gitignore/* linguist-vendored
|
||||
public/conf/license/* linguist-vendored
|
||||
public/assets/* linguist-vendored
|
||||
public/plugins/* linguist-vendored
|
||||
public/plugins/* linguist-vendored
|
||||
public/css/themes/* linguist-vendored
|
||||
public/css/github.min.css linguist-vendored
|
||||
public/css/semantic-2.2.1.min.css linguist-vendored
|
||||
public/js/libs/* linguist-vendored
|
||||
public/js/jquery-1.11.3.min.js linguist-vendored
|
||||
public/js/semantic-2.2.1.min.js linguist-vendored
|
||||
conf/gitignore/** linguist-vendored
|
||||
conf/license/** linguist-vendored
|
||||
public/assets/** linguist-vendored
|
||||
public/plugins/** linguist-vendored
|
||||
public/css/themes/** linguist-vendored
|
||||
public/css/semantic-* linguist-vendored
|
||||
public/js/libs/** linguist-vendored
|
||||
public/js/semantic-* linguist-vendored
|
||||
|
||||
2
.github/CODEOWNERS
vendored
Normal file
2
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Default
|
||||
* @unknwon
|
||||
89
.github/CONTRIBUTING.md
vendored
89
.github/CONTRIBUTING.md
vendored
@@ -1,63 +1,78 @@
|
||||
# Contributing to Gogs
|
||||
# Welcome to Gogs contributing guide
|
||||
|
||||
> This guidelines sheet is forked from [CONTRIBUTING.md](https://github.com/drone/drone/blob/8d9c7cee56d6c2eac81dc156ce27be6716d97e68/CONTRIBUTING.md).
|
||||
Thank you for investing your time in contributing to our projects!
|
||||
|
||||
Gogs is not perfect, and it has bugs or incomplete features in rare cases. You're welcome to tell us, or to contribute some code. This document describes details about how can you contribute to Gogs project.
|
||||
Read our [Code of Conduct](https://go.dev/conduct) to keep our community approachable and respectable.
|
||||
|
||||
## Contribution guidelines
|
||||
In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR.
|
||||
|
||||
Depends on the situation, you will:
|
||||
Use the table of contents icon <img src="https://github.com/github/docs/raw/50561895328b8f369694973252127b7d93899d83/assets/images/table-of-contents.png" width="25" height="25" /> on the top left corner of this document to get to a specific section of this guide quickly.
|
||||
|
||||
- Find a bug and create an issue
|
||||
- Need more functionality and make a feature request
|
||||
- Want to contribute code and open a pull request
|
||||
- Run into issue and need help
|
||||
## New contributor guide
|
||||
|
||||
### Bug Report
|
||||
To get an overview of the project, read the [README](/README.md). Here are some resources to help you get started with open source contributions:
|
||||
|
||||
If you find something you consider a bug, please create a issue on [GitHub](https://github.com/gogits/gogs/issues). To avoid wasting time and reduce back-and-forth communication with team members, please include at least the following information in a form comfortable for you:
|
||||
- [Finding ways to contribute to open source on GitHub](https://docs.github.com/en/get-started/exploring-projects-on-github/finding-ways-to-contribute-to-open-source-on-github)
|
||||
- [Set up Git](https://docs.github.com/en/get-started/quickstart/set-up-git)
|
||||
- [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow)
|
||||
- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests)
|
||||
- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
|
||||
- [Talk, then code](https://www.craft.do/s/kyHVs6OoE4Dj5V)
|
||||
|
||||
- Bug Description
|
||||
- Gogs Version
|
||||
- Git Version
|
||||
- System Type
|
||||
- Error Log
|
||||
- Other information
|
||||
In addition to the general guides with open source contributions, you would also need to:
|
||||
|
||||
Please take a moment to check that an issue on [GitHub](https://github.com/gogits/gogs/issues) doesn't already exist documenting your bug report or improvement proposal. If it does, it never hurts to add a quick "+1" or "I have this problem too". This will help prioritize the most common problems and requests.
|
||||
- Have basic knowledge about web applications development, database management systems and programming in [Go](https://go.dev/).
|
||||
- Have a working local development setup with a reasonable good IDE or editor like [Visual Studio Code](https://code.visualstudio.com/docs/languages/go), [GoLand](https://www.jetbrains.com/go/) or [Vim](https://github.com/fatih/vim-go).
|
||||
- [Set up your development environment](/docs/dev/local_development.md).
|
||||
|
||||
#### Bug Report Example
|
||||
## Issues
|
||||
|
||||
Gogs crashed when creating a repository with a license, using v0.5.13.0207, SQLite3, Git 1.9.0, Ubuntu 12.04.
|
||||
### Ask for help
|
||||
|
||||
Error log:
|
||||
Before opening an issue, please make sure the problem you're encountering isn't already addressed on the [Troubleshooting](https://gogs.io/asking/troubleshooting) and [FAQs](https://gogs.io/asking/faq) pages.
|
||||
|
||||
```
|
||||
2014/09/01 07:21:49 [E] nil pointer
|
||||
```
|
||||
### Create a new issue
|
||||
|
||||
### Feature Request
|
||||
- For questions, ask in [Discussions](https://github.com/gogs/gogs/discussions).
|
||||
- [Check to make sure](https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-issues-and-pull-requests#search-by-the-title-body-or-comments) someone hasn't already opened a similar [issue](https://github.com/gogs/gogs/issues).
|
||||
- If a similar issue doesn't exist, open a new issue using a relevant [issue form](https://github.com/gogs/gogs/issues/new/choose).
|
||||
- Blank issues that are not coming from maintainers will be closed without a response.
|
||||
|
||||
There is no standard form of making a feature request. Just try to describe the feature as clearly as possible, because team members may not have experience with the functionality you're talking about.
|
||||
### Pick up an issue to solve
|
||||
|
||||
### Pull Request
|
||||
- Scan through our [existing issues](https://github.com/gogs/gogs/issues) to find one that interests you.
|
||||
- The [👋 good first issue](https://github.com/gogs/gogs/issues?q=is%3Aissue+is%3Aopen+label%3A%22%F0%9F%91%8B+good+first+issue%22) is a good place to start exploring issues that are well-groomed for newcomers.
|
||||
- Do not hesitate to ask for more details or clarifying questions on the issue!
|
||||
- Communicate on the issue you are intended to pick up _before_ starting working on it.
|
||||
- Every issue that gets picked up will have an expected timeline for the implementation, the issue may be reassigned after the expected timeline. Please be responsible and proactive on the communication 🙇♂️
|
||||
|
||||
Please read detailed information on [Wiki](https://github.com/gogits/gogs/wiki/Contributing-Code).
|
||||
## Add new features or make big changes
|
||||
|
||||
### Ask For Help
|
||||
New features or big changes require proposals before we may be able to accept any contribution. Proposals should be posted to the [Discussions - Proposal](https://github.com/gogs/gogs/discussions/categories/proposal) category for review and discussions. GitHub Discussions provides sub-threading which is much more suitable than GitHub Issues for discussions to happen. Please read [Write a proposal for open source contributions](https://unknwon.io/posts/220210-write-a-proposal-for-open-source-contributions/) to begin with.
|
||||
|
||||
Before opening an issue, please make sure your problem isn't already addressed on the [Troubleshooting](https://gogs.io/docs/intro/troubleshooting.html) and [FAQs](https://gogs.io/docs/intro/faqs.html) pages.
|
||||
## Pull requests
|
||||
|
||||
## Code of conduct
|
||||
When you're finished with the changes, create a pull request, or a series of pull requests if necessary.
|
||||
|
||||
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
Contributing to another codebase is not as simple as code changes, it is also about contributing influence to the design. Therefore, we kindly ask you that:
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
|
||||
- Please acknowledge that no pull request is guaranteed to be merged.
|
||||
- Please always do a self-review before requesting reviews from others.
|
||||
- Please expect code review to be strict and may have multiple rounds.
|
||||
- Please make self-contained incremental changes, pull requests with huge diff may be rejected for review.
|
||||
- Please use English in code comments and docstring.
|
||||
- Please do not force push unless absolutely necessary. Force pushes make review much harder in multiple rounds, and we use [Squash and merge](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-pull-request-commits) so you don't need to worry about messy commits and just focus on the changes.
|
||||
|
||||
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
||||
### Things we do not accept
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
||||
1. Updates to locale files (`conf/locale_xx-XX.ini`) other than the `conf/locale_en-US.ini`. Please read the [guide for localizing Gogs](https://gogs.io/advancing/localization).
|
||||
1. Docker compose files.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior can be reported by emailing u@gogs.io
|
||||
### Coding guidelines
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
||||
1. Please read the Sourcegraph's [Go style guide](https://github.com/sourcegraph/sourcegraph-public-snapshot/blob/main/doc/dev/background-information/languages/go.md).
|
||||
1. **NO** direct modifications to `.css` files, `.css` files are all generated by `.less` files. You can regenerate `.css` files by executing `task less`.
|
||||
|
||||
## Your PR is merged!
|
||||
|
||||
Congratulations 🎉🎉 Thanks again for taking the effort to have this journey with us 🌟
|
||||
|
||||
25
.github/ISSUE_TEMPLATE.md
vendored
25
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,25 +0,0 @@
|
||||
The issue will be closed without any reasons if it does not satisfy any of following requirements:
|
||||
|
||||
1. Please speak English, we have forum in [Chinese](https://discuss.gogs.io/c/getting-help/getting-help-chinese).
|
||||
2. Please post questions or config/deploy problems on our forum: https://discuss.gogs.io, here are bugs and feature requests only.
|
||||
3. Please take a moment to search that an issue doesn't already exist.
|
||||
4. Please give all relevant information below for bug reports; incomplete details considered invalid report.
|
||||
|
||||
**You MUST delete above content including this line before posting; too lazy to take this action considered invalid report.**
|
||||
|
||||
- Gogs version (or commit ref):
|
||||
- Git version:
|
||||
- Operating system:
|
||||
- Database (use `[x]`):
|
||||
- [ ] PostgreSQL
|
||||
- [ ] MySQL
|
||||
- [ ] SQLite
|
||||
- Can you reproduce the bug at https://try.gogs.io:
|
||||
- [ ] Yes (provide example URL)
|
||||
- [ ] No
|
||||
- [ ] Not relevant
|
||||
- Log gist:
|
||||
|
||||
## Description
|
||||
|
||||
...
|
||||
82
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
82
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
name: Bug report
|
||||
description: File a bug report to help us improve
|
||||
labels: ["\U0001F48A bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
- Please use English :)
|
||||
- For questions, ask in [Discussions](https://github.com/gogs/gogs/discussions).
|
||||
- Before you file an issue read the [Contributing guide](https://github.com/gogs/gogs/blob/main/.github/CONTRIBUTING.md).
|
||||
- Check to make sure someone hasn't already opened a similar [issue](https://github.com/gogs/gogs/issues).
|
||||
- type: input
|
||||
attributes:
|
||||
label: Gogs version
|
||||
description: |
|
||||
Please specify the exact Gogs version you're reporting for, e.g. "0.12.3". You can find the version information in the admin dashboard (`/admin`).
|
||||
|
||||
_Note that "gogs/gogs:latest" is not a Gogs version, it does not mean anything._
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Git version
|
||||
description: |
|
||||
Please specify the exact Git version you're using of both server and client. You can find the version information by running `git version`.
|
||||
value: |
|
||||
- Server:
|
||||
- Client:
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Operating system
|
||||
description: |
|
||||
Please specify the exact operating system name and version you're reporting for, e.g. "Windows 10", "CentOS 7", "Ubuntu 20.04".
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Database
|
||||
description: |
|
||||
Please specify the exact database and version you're reporting for, e.g. "PostgreSQL 9.6", "MySQL 5.7", "SQLite 3".
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: To reproduce
|
||||
description: The steps to reproduce the problem described above.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: |
|
||||
Links? References? Suggestions? Anything that will give us more context about the issue you are encountering!
|
||||
|
||||
Please include any error logs found in the `log/gogs.log` file. Otherwise, we probably won't be able to help you much.
|
||||
|
||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our [Code of Conduct](https://go.dev/conduct)
|
||||
options:
|
||||
- label: I agree to follow this project's Code of Conduct
|
||||
required: true
|
||||
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Ask questions
|
||||
url: https://github.com/gogs/gogs/discussions
|
||||
about: Please ask questions in Discussions.
|
||||
- name: Make a proposal
|
||||
url: https://github.com/gogs/gogs/discussions/categories/proposal
|
||||
about: Please make proposals in Discussions.
|
||||
46
.github/ISSUE_TEMPLATE/dev_release_minor_version.md
vendored
Normal file
46
.github/ISSUE_TEMPLATE/dev_release_minor_version.md
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: "Dev: Release a minor version"
|
||||
about: ONLY USED BY MAINTAINERS.
|
||||
assignees: "unknwon"
|
||||
title: "Release [VERSION]"
|
||||
labels: 📸 release
|
||||
---
|
||||
|
||||
_This is generated from the [minor release template](https://github.com/gogs/gogs/blob/main/.github/ISSUE_TEMPLATE/dev_release_minor_version.md)._
|
||||
|
||||
## Before release
|
||||
|
||||
On the `main` branch:
|
||||
|
||||
- [ ] Close stale issues with the label [status: needs feedback](https://github.com/gogs/gogs/issues?q=is%3Aissue+is%3Aopen+label%3A%22status%3A+needs+feedback%22).
|
||||
- [ ] [Sync locales from Crowdin](https://github.com/gogs/gogs/blob/main/docs/dev/import_locale.md).
|
||||
- [ ] [Update CHANGELOG](https://github.com/gogs/gogs/commit/f1102a7a7c545ec221d2906f02fa19170d96f96d) to include entries for the current minor release.
|
||||
- Do not forget adding entries for GHSA patches.
|
||||
- [ ] Cut a new release branch `release/<MAJOR>.<MINOR>`, e.g. `release/0.14`.
|
||||
|
||||
## During release
|
||||
|
||||
On the release branch:
|
||||
|
||||
- [ ] [Update the hard-coded version](https://github.com/gogs/gogs/commit/f0e3cd90f8d7695960eeef2e4e54b2e717302f6c) to the current release, e.g. `0.14.0+dev` -> `0.14.0`.
|
||||
- [ ] Wait for GitHub Actions to complete and no failed jobs.
|
||||
- [ ] Publish new RC releases (e.g. `v0.14.0-rc.1`, `v0.14.0-rc.2`) ⚠️ **on the release branch** ⚠️ and ensure Docker and release workflows both succeed.
|
||||
- [ ] Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up.
|
||||
- [ ] Download one of the release archives and run through application setup to make sure nothing blows up.
|
||||
- [ ] Publish a new [GitHub release](https://github.com/gogs/gogs/releases) ⚠️ **on the release branch** ⚠️ with entries from [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md) for the current minor release.
|
||||
- [ ] [Wait for new image tags for the current release](https://github.com/gogs/gogs/actions/workflows/docker.yml?query=event%3Arelease) to be created automatically on both [Docker Hub](https://hub.docker.com/r/gogs/gogs/tags) and [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs).
|
||||
- Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up.
|
||||
- [ ] Download all release archives and [generate SHA256 checksum](https://github.com/gogs/gogs/blob/main/docs/dev/release/sha256.sh) for all binaries to the file `checksum_sha256.txt`.
|
||||
- [ ] Upload all archives and `checksum_sha256.txt` to https://dl.gogs.io.
|
||||
|
||||
## After release
|
||||
|
||||
On the `main` branch:
|
||||
|
||||
- [ ] Update the repository mirror on [Gitee](https://gitee.com/unknwon/gogs).
|
||||
- [ ] Create a new release announcement in [Discussions](https://github.com/gogs/gogs/discussions/categories/announcements).
|
||||
- [ ] Send a tweet on the [official Twitter account](https://twitter.com/GogsHQ) for the minor release.
|
||||
- [ ] Close the milestone for the minor release.
|
||||
- [ ] [Bump the hard-coded version](https://github.com/gogs/gogs/commit/a98968436cd5841cf691bb0b80c54c81470d1676) to the new develop version, e.g. `0.14.0+dev` -> `0.15.0+dev`.
|
||||
- [ ] Run `task legacy` to identify deprecated code that is aimed to be removed in current develop version.
|
||||
- [ ] **After 14 days**, publish [GitHub security advisories](https://github.com/gogs/gogs/security) for security patches included in the release.
|
||||
49
.github/ISSUE_TEMPLATE/dev_release_patch_version.md
vendored
Normal file
49
.github/ISSUE_TEMPLATE/dev_release_patch_version.md
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
name: "Dev: Release a patch version"
|
||||
about: ONLY USED BY MAINTAINERS.
|
||||
assignees: "unknwon"
|
||||
title: "Release [VERSION]"
|
||||
labels: 📸 release
|
||||
---
|
||||
|
||||
_This is generated from the [patch release template](https://github.com/gogs/gogs/blob/main/.github/ISSUE_TEMPLATE/dev_release_patch_version.md)._
|
||||
|
||||
## Before release
|
||||
|
||||
On the release branch:
|
||||
|
||||
- [ ] Make sure all commits are cherry-picked from the `main` branch by checking the patch milestone.
|
||||
- Run `task build` for every cherry-picked commit to make sure there is no compilation error.
|
||||
- [ ] [Update CHANGELOG on the `main` branch](https://github.com/gogs/gogs/commit/f1102a7a7c545ec221d2906f02fa19170d96f96d) to include entries for the current patch release.
|
||||
|
||||
## During release
|
||||
|
||||
On the release branch:
|
||||
|
||||
- [ ] [Update the hard-coded version](https://github.com/gogs/gogs/commit/f0e3cd90f8d7695960eeef2e4e54b2e717302f6c) to the current release, e.g. `0.12.0` -> `0.12.1`.
|
||||
- [ ] Wait for GitHub Actions to complete and no failed jobs.
|
||||
- [ ] Publish new RC releases in [GitHub release](https://github.com/gogs/gogs/releases) (e.g. `v0.12.0-rc.1`, `v0.12.0-rc.2`) ⚠️ **on the release branch** ⚠️ and ensure Docker workflow succeeds.
|
||||
- [ ] Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up.
|
||||
- [ ] Download one of the release archives and run through application setup to make sure nothing blows up.
|
||||
- [ ] Publish a new [GitHub release](https://github.com/gogs/gogs/releases) ⚠️ **on the release branch** ⚠️ with entries from [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md) for the current patch release and all previous releases with same minor version.
|
||||
- [ ] Update all previous GitHub releases with same minor version with the warning:
|
||||
```
|
||||
**ℹ️ Heads up! There is a new patch release [0.12.1](https://github.com/gogs/gogs/releases/tag/v0.12.1) available, we recommend directly installing or upgrading to that version.**
|
||||
```
|
||||
- [ ] [Wait for new image tags for the current release](https://github.com/gogs/gogs/actions/workflows/docker.yml?query=event%3Arelease) to be created automatically on both [Docker Hub](https://hub.docker.com/r/gogs/gogs/tags) and [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs).
|
||||
- Pull down the Docker image and [run through application setup](https://github.com/gogs/gogs/blob/main/docker/README.md) to make sure nothing blows up.
|
||||
- [ ] Download all release archives and [generate SHA256 checksum](https://github.com/gogs/gogs/blob/main/docs/dev/release/sha256.sh) for all binaries to the file `checksum_sha256.txt`.
|
||||
- [ ] Upload all archives and `checksum_sha256.txt` to https://dl.gogs.io.
|
||||
|
||||
## After release
|
||||
|
||||
On the `main` branch:
|
||||
|
||||
- [ ] Post the following message on issues that are included in the patch milestone:
|
||||
```
|
||||
The <MAJOR>.<MINOR>.<PATCH> has been released that includes the patch of the reported issue.
|
||||
```
|
||||
- [ ] Create a new release announcement in [Discussions](https://github.com/gogs/gogs/discussions/categories/announcements).
|
||||
- [ ] Send a tweet on the [official Twitter account](https://twitter.com/GogsHQ) for the patch release.
|
||||
- [ ] Close the milestone for the patch release.
|
||||
- [ ] **After 14 days**, publish [GitHub security advisories](https://github.com/gogs/gogs/security) for security patches included in the release.
|
||||
32
.github/ISSUE_TEMPLATE/documentation.yml
vendored
Normal file
32
.github/ISSUE_TEMPLATE/documentation.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: Improve documentation
|
||||
description: Suggest an idea or a patch for documentation
|
||||
labels: ["📖 documentation"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this form!
|
||||
|
||||
- Please use English :)
|
||||
- For questions, ask in [Discussions](https://github.com/gogs/gogs/discussions).
|
||||
- Before you file an issue read the [Contributing guide](https://github.com/gogs/gogs/blob/main/.github/CONTRIBUTING.md).
|
||||
- Check to make sure someone hasn't already opened a similar [issue](https://github.com/gogs/gogs/issues).
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What needs to be improved? Please describe
|
||||
description: A clear and concise description of what is wrong or missing.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Why do you think it is important?
|
||||
description: A clear and concise explanation of the rationale.
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our [Code of Conduct](https://go.dev/conduct)
|
||||
options:
|
||||
- label: I agree to follow this project's Code of Conduct
|
||||
required: true
|
||||
47
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
47
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
name: Feature request
|
||||
description: Suggest an idea for this project
|
||||
labels: ["\U0001F3AF feature"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this form!
|
||||
|
||||
- Please use English :)
|
||||
- For questions, ask in [Discussions](https://github.com/gogs/gogs/discussions).
|
||||
- Before you file an issue read the [Contributing guide](https://github.com/gogs/gogs/blob/main/.github/CONTRIBUTING.md).
|
||||
- Check to make sure someone hasn't already opened a similar [issue](https://github.com/gogs/gogs/issues).
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the feature
|
||||
description: A clear and concise description of what the feature is, e.g. I think it is reasonable to have [...]
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: |
|
||||
Links? References? Suggestions? Anything that will give us more context about the feature you are requesting!
|
||||
|
||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Code of Conduct
|
||||
description: By submitting this issue, you agree to follow our [Code of Conduct](https://go.dev/conduct)
|
||||
options:
|
||||
- label: I agree to follow this project's Code of Conduct
|
||||
required: true
|
||||
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,9 +0,0 @@
|
||||
The pull request will be closed without any reasons if it does not satisfy any of following requirements:
|
||||
|
||||
1. Please make sure you are targeting the `develop` branch.
|
||||
2. Please read contributing guidelines:
|
||||
https://github.com/gogits/gogs/wiki/Contributing-Code
|
||||
3. Please describe what your pull request does and which issue you're targeting
|
||||
4. ... if it is not related to any particular issues, explain why we should not reject your pull request.
|
||||
|
||||
**You MUST delete above content including this line before posting; too lazy to take this action considered invalid pull request.**
|
||||
9
.github/dependabot.yml
vendored
Normal file
9
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Docs: https://git.io/JCUAY
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gomod"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
commit-message:
|
||||
prefix: "mod:"
|
||||
16
.github/pull_request_template.md
vendored
Normal file
16
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
## Describe the pull request
|
||||
|
||||
A clear and concise description of what the pull request is about, i.e. what problem should be fixed?
|
||||
|
||||
Link to the issue: <!-- paste the issue link here, or put "n/a" if not applicable -->
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] I agree to follow the [Code of Conduct](https://go.dev/conduct) by submitting this pull request.
|
||||
- [ ] I have read and acknowledge the [Contributing guide](https://github.com/gogs/gogs/blob/main/.github/CONTRIBUTING.md).
|
||||
- [ ] I have added test cases to cover the new code or have provided the test plan. (if applicable)
|
||||
- [ ] I have added an entry to [CHANGELOG](https://github.com/gogs/gogs/blob/main/CHANGELOG.md). (if applicable)
|
||||
|
||||
## Test plan
|
||||
|
||||
<!-- Please provide concrete but concise steps to proof things are working as stated, see an example in https://github.com/gogs/gogs/pull/7345 -->
|
||||
75
.github/workflows/codeql.yml
vendored
Normal file
75
.github/workflows/codeql.yml
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/codeql.yml'
|
||||
schedule:
|
||||
- cron: '0 19 * * 0'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'go' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@fdbfb4d2750291e159f0156def62b853c2798ca2 # v3.28.3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@fdbfb4d2750291e159f0156def62b853c2798ca2 # v3.28.3
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@fdbfb4d2750291e159f0156def62b853c2798ca2 # v3.28.3
|
||||
26
.github/workflows/digitalocean_gc.yml
vendored
Normal file
26
.github/workflows/digitalocean_gc.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: DigitalOcean
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
garbage-collection:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Install doctl
|
||||
uses: digitalocean/action-doctl@5727c67aa3c2c34ae9462d5a0ecfea8a1b31e5ce # v2
|
||||
with:
|
||||
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
||||
- name: Run garbage collection
|
||||
run: |
|
||||
# --force: Required for CI to skip confirmation prompts
|
||||
# --include-untagged-manifests: Deletes unreferenced manifests to maximize space
|
||||
doctl registry garbage-collection start --force --include-untagged-manifests
|
||||
- name: Send email on failure
|
||||
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
smtp_username: ${{ secrets.SMTP_USERNAME }}
|
||||
smtp_password: ${{ secrets.SMTP_PASSWORD }}
|
||||
402
.github/workflows/docker.yml
vendored
Normal file
402
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
name: Docker
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
paths:
|
||||
- '.trivy.yaml'
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile.next'
|
||||
- 'docker/**'
|
||||
- 'docker-next/**'
|
||||
- '.github/workflows/docker.yml'
|
||||
release:
|
||||
types: [ published ]
|
||||
|
||||
jobs:
|
||||
buildx:
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }}
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
- name: Inspect builder
|
||||
run: |
|
||||
echo "Name: ${{ steps.buildx.outputs.name }}"
|
||||
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
|
||||
echo "Status: ${{ steps.buildx.outputs.status }}"
|
||||
echo "Flags: ${{ steps.buildx.outputs.flags }}"
|
||||
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Login to GitHub Container registry
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
tags: |
|
||||
gogs/gogs:latest
|
||||
ghcr.io/gogs/gogs:latest
|
||||
- name: Scan for container vulnerabilities
|
||||
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1
|
||||
with:
|
||||
image-ref: gogs/gogs:latest
|
||||
exit-code: '1'
|
||||
- name: Send email on failure
|
||||
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
smtp_username: ${{ secrets.SMTP_USERNAME }}
|
||||
smtp_password: ${{ secrets.SMTP_PASSWORD }}
|
||||
|
||||
buildx-next:
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }}
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-next-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
- name: Inspect builder
|
||||
run: |
|
||||
echo "Name: ${{ steps.buildx.outputs.name }}"
|
||||
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
|
||||
echo "Status: ${{ steps.buildx.outputs.status }}"
|
||||
echo "Flags: ${{ steps.buildx.outputs.flags }}"
|
||||
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Login to GitHub Container registry
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Login to DigitalOcean Container registry
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: registry.digitalocean.com
|
||||
username: ${{ secrets.DIGITALOCEAN_USERNAME }}
|
||||
password: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
||||
- name: Build and push next-gen images
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.next
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
tags: |
|
||||
gogs/gogs:next-latest
|
||||
ghcr.io/gogs/gogs:next-latest
|
||||
registry.digitalocean.com/gogs/gogs:next-latest
|
||||
- name: Scan for container vulnerabilities
|
||||
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1
|
||||
with:
|
||||
image-ref: gogs/gogs:next-latest
|
||||
exit-code: '1'
|
||||
- name: Send email on failure
|
||||
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
smtp_username: ${{ secrets.SMTP_USERNAME }}
|
||||
smtp_password: ${{ secrets.SMTP_PASSWORD }}
|
||||
|
||||
deploy-demo:
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }}
|
||||
needs: buildx-next
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Configure kubectl
|
||||
run: |
|
||||
mkdir -p ~/.kube
|
||||
echo "${KUBECONFIG}" | base64 -d > ~/.kube/config
|
||||
env:
|
||||
KUBECONFIG: ${{ secrets.DIGITALOCEAN_K8S_CLUSTER_KUBECONFIG }}
|
||||
- name: Restart gogs-demo deployment
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
set -ex
|
||||
kubectl rollout restart deployment gogs-demo -n gogs
|
||||
kubectl rollout status deployment gogs-demo -n gogs
|
||||
- name: Send email on failure
|
||||
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
smtp_username: ${{ secrets.SMTP_USERNAME }}
|
||||
smtp_password: ${{ secrets.SMTP_PASSWORD }}
|
||||
|
||||
buildx-pull-request:
|
||||
if: ${{ github.event_name == 'pull_request'}}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
with:
|
||||
config-inline: |
|
||||
[worker.oci]
|
||||
max-parallelism = 2
|
||||
- name: Inspect builder
|
||||
run: |
|
||||
echo "Name: ${{ steps.buildx.outputs.name }}"
|
||||
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
|
||||
echo "Status: ${{ steps.buildx.outputs.status }}"
|
||||
echo "Flags: ${{ steps.buildx.outputs.flags }}"
|
||||
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
|
||||
- name: Compute short commit SHA
|
||||
id: short-sha
|
||||
uses: benjlevesque/short-sha@599815c8ee942a9616c92bcfb4f947a3b670ab0b # v3.0
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
ttl.sh/gogs/gogs-${{ steps.short-sha.outputs.sha }}:7d
|
||||
- name: Scan for container vulnerabilities
|
||||
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1
|
||||
with:
|
||||
image-ref: ttl.sh/gogs/gogs-${{ steps.short-sha.outputs.sha }}:7d
|
||||
exit-code: '1'
|
||||
|
||||
buildx-next-pull-request:
|
||||
if: ${{ github.event_name == 'pull_request'}}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
with:
|
||||
config-inline: |
|
||||
[worker.oci]
|
||||
max-parallelism = 2
|
||||
- name: Inspect builder
|
||||
run: |
|
||||
echo "Name: ${{ steps.buildx.outputs.name }}"
|
||||
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
|
||||
echo "Status: ${{ steps.buildx.outputs.status }}"
|
||||
echo "Flags: ${{ steps.buildx.outputs.flags }}"
|
||||
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
|
||||
- name: Compute short commit SHA
|
||||
id: short-sha
|
||||
uses: benjlevesque/short-sha@599815c8ee942a9616c92bcfb4f947a3b670ab0b # v3.0
|
||||
- name: Build and push next-gen images
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.next
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
ttl.sh/gogs/gogs-next-${{ steps.short-sha.outputs.sha }}:7d
|
||||
- name: Scan for container vulnerabilities
|
||||
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1
|
||||
with:
|
||||
image-ref: ttl.sh/gogs/gogs-next-${{ steps.short-sha.outputs.sha }}:7d
|
||||
exit-code: '1'
|
||||
|
||||
# Updates to the following section needs to be synced to all release branches within their lifecycles.
|
||||
buildx-release:
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Compute image tags
|
||||
run: |
|
||||
IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)
|
||||
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
|
||||
|
||||
TAGS="gogs/gogs:$IMAGE_TAG
|
||||
ghcr.io/gogs/gogs:$IMAGE_TAG"
|
||||
|
||||
# Add minor version tag for stable releases (no prerelease suffix per semver).
|
||||
if [[ ! "$IMAGE_TAG" =~ - ]]; then
|
||||
MINOR_TAG=$(echo "$IMAGE_TAG" | cut -d. -f1,2)
|
||||
TAGS="$TAGS
|
||||
gogs/gogs:$MINOR_TAG
|
||||
ghcr.io/gogs/gogs:$MINOR_TAG"
|
||||
fi
|
||||
|
||||
echo "TAGS<<EOF" >> $GITHUB_ENV
|
||||
echo "$TAGS" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
- name: Inspect builder
|
||||
run: |
|
||||
echo "Name: ${{ steps.buildx.outputs.name }}"
|
||||
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
|
||||
echo "Status: ${{ steps.buildx.outputs.status }}"
|
||||
echo "Flags: ${{ steps.buildx.outputs.flags }}"
|
||||
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Login to GitHub Container registry
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
tags: ${{ env.TAGS }}
|
||||
- name: Send email on failure
|
||||
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
smtp_username: ${{ secrets.SMTP_USERNAME }}
|
||||
smtp_password: ${{ secrets.SMTP_PASSWORD }}
|
||||
|
||||
# Updates to the following section needs to be synced to all release branches within their lifecycles.
|
||||
buildx-next-release:
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Compute image tags
|
||||
run: |
|
||||
IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)
|
||||
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
|
||||
|
||||
TAGS="gogs/gogs:next-$IMAGE_TAG
|
||||
ghcr.io/gogs/gogs:next-$IMAGE_TAG"
|
||||
|
||||
# Add minor version tag for stable releases (no prerelease suffix per semver).
|
||||
if [[ ! "$IMAGE_TAG" =~ - ]]; then
|
||||
MINOR_TAG=$(echo "$IMAGE_TAG" | cut -d. -f1,2)
|
||||
TAGS="$TAGS
|
||||
gogs/gogs:next-$MINOR_TAG
|
||||
ghcr.io/gogs/gogs:next-$MINOR_TAG"
|
||||
fi
|
||||
|
||||
echo "TAGS<<EOF" >> $GITHUB_ENV
|
||||
echo "$TAGS" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||
- name: Inspect builder
|
||||
run: |
|
||||
echo "Name: ${{ steps.buildx.outputs.name }}"
|
||||
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
|
||||
echo "Status: ${{ steps.buildx.outputs.status }}"
|
||||
echo "Flags: ${{ steps.buildx.outputs.flags }}"
|
||||
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Login to GitHub Container registry
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push next-gen images
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.next
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
tags: ${{ env.TAGS }}
|
||||
- name: Send email on failure
|
||||
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
smtp_username: ${{ secrets.SMTP_USERNAME }}
|
||||
smtp_password: ${{ secrets.SMTP_PASSWORD }}
|
||||
|
||||
digitalocean-gc:
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'gogs/gogs' }}
|
||||
needs: buildx-next
|
||||
permissions:
|
||||
contents: read
|
||||
uses: ./.github/workflows/digitalocean_gc.yml
|
||||
secrets: inherit
|
||||
|
||||
digitalocean-gc-pull-request:
|
||||
if: ${{ github.event_name == 'pull_request' && github.repository == 'gogs/gogs' }}
|
||||
needs: buildx-next-pull-request
|
||||
permissions:
|
||||
contents: read
|
||||
uses: ./.github/workflows/digitalocean_gc.yml
|
||||
secrets: inherit
|
||||
176
.github/workflows/go.yml
vendored
Normal file
176
.github/workflows/go.yml
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
name: Go
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- 'release/**'
|
||||
paths:
|
||||
- '**.go'
|
||||
- 'go.mod'
|
||||
- '.golangci.yml'
|
||||
- '.github/workflows/go.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.go'
|
||||
- 'go.mod'
|
||||
- '.golangci.yml'
|
||||
- '.github/workflows/go.yml'
|
||||
env:
|
||||
GOPROXY: "https://proxy.golang.org"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version: 1.26.x
|
||||
- name: Install Task
|
||||
uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 # v2.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Check Go module tidiness and generated files
|
||||
shell: bash
|
||||
run: |
|
||||
go mod tidy
|
||||
task generate
|
||||
STATUS=$(git status --porcelain)
|
||||
if [ ! -z "$STATUS" ]; then
|
||||
echo "Unstaged files:"
|
||||
echo $STATUS
|
||||
echo "Run 'go mod tidy' or 'task generate' commit them"
|
||||
exit 1
|
||||
fi
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/golangci-lint-action@9fae48acfc02a90574d7c304a1758ef9895495fa # v7.0.1
|
||||
with:
|
||||
version: latest
|
||||
args: --timeout=30m
|
||||
|
||||
test:
|
||||
name: Test
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.26.x ]
|
||||
platform: [ ubuntu-latest, macos-latest ]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Run tests with coverage
|
||||
run: |
|
||||
go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic -json ./... > test-report.json
|
||||
go install github.com/mfridman/tparse@latest
|
||||
tparse -all -file=test-report.json
|
||||
- name: Send email on failure
|
||||
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
|
||||
if: ${{ failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
with:
|
||||
smtp_username: ${{ secrets.SMTP_USERNAME }}
|
||||
smtp_password: ${{ secrets.SMTP_PASSWORD }}
|
||||
|
||||
# Running tests with race detection consumes too much memory on Windows,
|
||||
# see https://github.com/golang/go/issues/46099 for details.
|
||||
test-windows:
|
||||
name: Test Windows
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.26.x ]
|
||||
platform: [ windows-latest ]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Run tests with coverage
|
||||
run: go test -shuffle=on -v -coverprofile=coverage -covermode=atomic ./...
|
||||
- name: Send email on failure
|
||||
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
|
||||
if: ${{ failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
with:
|
||||
smtp_username: ${{ secrets.SMTP_USERNAME }}
|
||||
smtp_password: ${{ secrets.SMTP_PASSWORD }}
|
||||
|
||||
postgres:
|
||||
name: Postgres
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.26.x ]
|
||||
platform: [ ubuntu-latest ]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:9.6
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Run tests with coverage
|
||||
run: |
|
||||
go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic -json ./internal/database/... > test-report.json
|
||||
go install github.com/mfridman/tparse@latest
|
||||
tparse -all -file=test-report.json
|
||||
env:
|
||||
GOGS_DATABASE_TYPE: postgres
|
||||
PGPORT: 5432
|
||||
PGHOST: localhost
|
||||
PGUSER: postgres
|
||||
PGPASSWORD: postgres
|
||||
PGSSLMODE: disable
|
||||
|
||||
mysql:
|
||||
name: MySQL
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [ 1.26.x ]
|
||||
platform: [ ubuntu-22.04 ] # Use the lowest version possible for backwards compatibility
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- name: Start MySQL server
|
||||
run: sudo systemctl start mysql
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Run tests with coverage
|
||||
run: |
|
||||
go test -shuffle=on -v -race -coverprofile=coverage -covermode=atomic -json ./internal/database/... > test-report.json
|
||||
go install github.com/mfridman/tparse@latest
|
||||
tparse -all -file=test-report.json
|
||||
env:
|
||||
GOGS_DATABASE_TYPE: mysql
|
||||
MYSQL_USER: root
|
||||
MYSQL_PASSWORD: root
|
||||
MYSQL_HOST: localhost
|
||||
MYSQL_PORT: 3306
|
||||
25
.github/workflows/lock.yml
vendored
Normal file
25
.github/workflows/lock.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: 'Lock Threads'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: lock
|
||||
|
||||
jobs:
|
||||
action:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-inactive-days: '90'
|
||||
issue-lock-reason: 'resolved'
|
||||
pr-inactive-days: '365'
|
||||
pr-lock-reason: 'resolved'
|
||||
146
.github/workflows/release.yml
vendored
Normal file
146
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/release.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
GOPROXY: "https://proxy.golang.org"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build ${{ matrix.goos }}/${{ matrix.goarch }}${{ matrix.suffix }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- {goos: linux, goarch: amd64}
|
||||
- {goos: linux, goarch: arm64}
|
||||
- {goos: linux, goarch: "386"}
|
||||
- {goos: darwin, goarch: amd64}
|
||||
- {goos: darwin, goarch: arm64}
|
||||
- {goos: windows, goarch: amd64}
|
||||
- {goos: windows, goarch: arm64}
|
||||
- {goos: windows, goarch: "386"}
|
||||
- {goos: windows, goarch: amd64, suffix: "_mws", tags: minwinsvc}
|
||||
- {goos: windows, goarch: arm64, suffix: "_mws", tags: minwinsvc}
|
||||
- {goos: windows, goarch: "386", suffix: "_mws", tags: minwinsvc}
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
|
||||
with:
|
||||
go-version: 1.26.x
|
||||
- name: Determine version
|
||||
id: version
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "release" ]; then
|
||||
echo "version=${{ github.event.release.tag_name }}" | sed 's/version=v/version=/' >> "$GITHUB_OUTPUT"
|
||||
echo "release_tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
|
||||
elif [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref }}" = "refs/heads/main" ]; then
|
||||
echo "version=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
|
||||
echo "release_tag=latest-commit-build" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "version=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
|
||||
echo "release_tag=release-archive-testing" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Build binary
|
||||
env:
|
||||
GOOS: ${{ matrix.goos }}
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
CGO_ENABLED: "0"
|
||||
run: |
|
||||
BINARY_NAME="gogs"
|
||||
if [ "${{ matrix.goos }}" = "windows" ]; then
|
||||
BINARY_NAME="gogs.exe"
|
||||
fi
|
||||
|
||||
TAGS_FLAG=""
|
||||
if [ -n "${{ matrix.tags }}" ]; then
|
||||
TAGS_FLAG="-tags ${{ matrix.tags }}"
|
||||
fi
|
||||
|
||||
go build -v \
|
||||
-ldflags "
|
||||
-X \"gogs.io/gogs/internal/conf.BuildTime=$(date -u '+%Y-%m-%d %I:%M:%S %Z')\"
|
||||
-X \"gogs.io/gogs/internal/conf.BuildCommit=$(git rev-parse HEAD)\"
|
||||
" \
|
||||
$TAGS_FLAG \
|
||||
-trimpath -o "$BINARY_NAME" ./cmd/gogs
|
||||
- name: Prepare archive contents
|
||||
run: |
|
||||
mkdir -p dist/gogs
|
||||
BINARY_NAME="gogs"
|
||||
if [ "${{ matrix.goos }}" = "windows" ]; then
|
||||
BINARY_NAME="gogs.exe"
|
||||
fi
|
||||
cp "$BINARY_NAME" dist/gogs/
|
||||
cp LICENSE README.md dist/gogs/
|
||||
cp -r scripts dist/gogs/
|
||||
- name: Create archives
|
||||
working-directory: dist
|
||||
run: |
|
||||
VERSION="${{ steps.version.outputs.version }}"
|
||||
ARCHIVE_BASE="gogs_${VERSION}_${{ matrix.goos }}_${{ matrix.goarch }}${{ matrix.suffix }}"
|
||||
|
||||
zip -r "${ARCHIVE_BASE}.zip" gogs
|
||||
|
||||
if [ "${{ matrix.goos }}" = "linux" ]; then
|
||||
tar -czvf "${ARCHIVE_BASE}.tar.gz" gogs
|
||||
fi
|
||||
- name: Upload to release
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
|
||||
|
||||
if [ "${{ github.event_name }}" != "release" ]; then
|
||||
git tag -f "$RELEASE_TAG"
|
||||
git push origin "$RELEASE_TAG" --force || true
|
||||
|
||||
RELEASE_TITLE="Release Archive Testing"
|
||||
RELEASE_NOTES="Automated testing release for workflow development."
|
||||
if [ "$RELEASE_TAG" = "latest-commit-build" ]; then
|
||||
RELEASE_TITLE="Latest Commit Build"
|
||||
RELEASE_NOTES="Automated build from the latest commit on main branch. This release is updated automatically with every push to main."
|
||||
fi
|
||||
|
||||
gh release view "$RELEASE_TAG" || gh release create "$RELEASE_TAG" --title "$RELEASE_TITLE" --notes "$RELEASE_NOTES" --prerelease
|
||||
fi
|
||||
|
||||
PATTERN="_${{ matrix.goos }}_${{ matrix.goarch }}${{ matrix.suffix }}\."
|
||||
gh release view "$RELEASE_TAG" --json assets --jq ".assets[].name" | grep "$PATTERN" | while read -r asset; do
|
||||
gh release delete-asset "$RELEASE_TAG" "$asset" --yes || true
|
||||
done
|
||||
|
||||
gh release upload "$RELEASE_TAG" dist/gogs_*.zip --clobber
|
||||
if [ "${{ matrix.goos }}" = "linux" ]; then
|
||||
gh release upload "$RELEASE_TAG" dist/gogs_*.tar.gz --clobber
|
||||
fi
|
||||
|
||||
notify-failure:
|
||||
name: Notify on failure
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build]
|
||||
if: ${{ failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
steps:
|
||||
- name: Send email on failure
|
||||
uses: unknwon/send-email-on-failure@89339a1bc93f4ad1d30f3b7e4911fcba985c9adb # v1
|
||||
with:
|
||||
smtp_username: ${{ secrets.SMTP_USERNAME }}
|
||||
smtp_password: ${{ secrets.SMTP_PASSWORD }}
|
||||
17
.github/workflows/shell.yml
vendored
Normal file
17
.github/workflows/shell.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
name: Shell
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
shellcheck:
|
||||
name: Shellcheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
- name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0
|
||||
28
.gitignore
vendored
28
.gitignore
vendored
@@ -1,20 +1,16 @@
|
||||
.DS_Store
|
||||
*.db
|
||||
*.log
|
||||
# Build artifacts
|
||||
.bin/
|
||||
dist/
|
||||
|
||||
# Runtime data
|
||||
log/
|
||||
custom/
|
||||
data/
|
||||
.vendor/
|
||||
|
||||
# Configuration and application files
|
||||
.idea/
|
||||
*.iml
|
||||
public/img/avatar/
|
||||
*.exe
|
||||
*.exe~
|
||||
/gogs
|
||||
profile/
|
||||
*.pem
|
||||
output*
|
||||
gogs.sublime-project
|
||||
gogs.sublime-workspace
|
||||
/release
|
||||
vendor
|
||||
.task/
|
||||
.envrc
|
||||
|
||||
# System junk
|
||||
.DS_Store
|
||||
|
||||
42
.golangci.yml
Normal file
42
.golangci.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
version: "2"
|
||||
linters:
|
||||
enable:
|
||||
- nakedret
|
||||
- rowserrcheck
|
||||
- unconvert
|
||||
- unparam
|
||||
settings:
|
||||
govet:
|
||||
disable:
|
||||
# printf: non-constant format string in call to fmt.Errorf (govet)
|
||||
# showing up since golangci-lint version 1.60.1
|
||||
- printf
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
- "-SA1019" # This project is under active refactoring and not all code is up to date.
|
||||
- "-QF1001" # I'm a math noob
|
||||
- "-ST1016" # Some legit code uses this pattern
|
||||
nakedret:
|
||||
max-func-lines: 0 # Disallow any unnamed return statement
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
59
.gopmfile
59
.gopmfile
@@ -1,59 +0,0 @@
|
||||
[target]
|
||||
path = github.com/gogits/gogs
|
||||
|
||||
[deps]
|
||||
github.com/bradfitz/gomemcache = commit:fb1f79c
|
||||
github.com/urfave/cli = commit:1efa31f
|
||||
github.com/go-macaron/binding = commit:9440f33
|
||||
github.com/go-macaron/cache = commit:5617353
|
||||
github.com/go-macaron/captcha = commit:8aa5919
|
||||
github.com/go-macaron/csrf = commit:6a9a7df
|
||||
github.com/go-macaron/gzip = commit:cad1c65
|
||||
github.com/go-macaron/i18n = commit:ef57533
|
||||
github.com/go-macaron/inject = commit:c5ab7bf
|
||||
github.com/go-macaron/session = commit:66031fc
|
||||
github.com/go-macaron/toolbox = commit:82b5115
|
||||
github.com/go-sql-driver/mysql = commit:0b58b37
|
||||
github.com/go-xorm/core = commit:5bf745d
|
||||
github.com/go-xorm/xorm = commit:c6c7056
|
||||
github.com/gogits/chardet = commit:2404f77
|
||||
github.com/gogits/cron = commit:7f3990a
|
||||
github.com/gogits/git-module = commit:5e0c133
|
||||
github.com/gogits/go-gogs-client = commit:c52f7ee
|
||||
github.com/issue9/identicon = commit:d36b545
|
||||
github.com/jaytaylor/html2text = commit:52d9b78
|
||||
github.com/kardianos/minwinsvc = commit:cad6b2b
|
||||
github.com/klauspost/compress = commit:14eb9c4
|
||||
github.com/klauspost/cpuid = commit:09cded8
|
||||
github.com/klauspost/crc32 = commit:19b0b33
|
||||
github.com/lib/pq = commit:80f8150
|
||||
github.com/mattn/go-sqlite3 = commit:e118d44
|
||||
github.com/mcuadros/go-version = commit:d52711f
|
||||
github.com/microcosm-cc/bluemonday = commit:9dc1992
|
||||
github.com/msteinert/pam = commit:02ccfbf
|
||||
github.com/nfnt/resize = commit:891127d
|
||||
github.com/russross/blackfriday = commit:93622da
|
||||
github.com/satori/go.uuid = commit:0aa62d5
|
||||
github.com/sergi/go-diff = commit:ec7fdbb
|
||||
github.com/strk/go-libravatar = commit:5eed7bf
|
||||
github.com/shurcooL/sanitized_anchor_name = commit:10ef21a
|
||||
github.com/Unknwon/cae = commit:7f5e046
|
||||
github.com/Unknwon/com = commit:28b053d
|
||||
github.com/Unknwon/i18n = commit:39d6f27
|
||||
github.com/Unknwon/paginater = commit:7748a72
|
||||
golang.org/x/crypto = commit:bc89c49
|
||||
golang.org/x/net = commit:57bfaa8
|
||||
golang.org/x/sys = commit:a646d33
|
||||
golang.org/x/text = commit:2910a50
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 = commit:2caba25
|
||||
gopkg.in/asn1-ber.v1 = commit:4e86f43
|
||||
gopkg.in/bufio.v1 = commit:567b2bf
|
||||
gopkg.in/editorconfig/editorconfig-core-go.v1 = commit:a872f05
|
||||
gopkg.in/gomail.v2 = commit:81ebce5
|
||||
gopkg.in/ini.v1 = commit:cf53f92
|
||||
gopkg.in/ldap.v2 = commit:d0a5ced
|
||||
gopkg.in/macaron.v1 = commit:7564489
|
||||
gopkg.in/redis.v2 = commit:e617904
|
||||
|
||||
[res]
|
||||
include = public|scripts|templates
|
||||
6
.mailmap
6
.mailmap
@@ -1,2 +1,4 @@
|
||||
Unknwon <u@gogs.io> <joe2010xtmf@163.com>
|
||||
Unknwon <u@gogs.io> 无闻 <u@gogs.io>
|
||||
Joe Chen <jc@unknwon.io> Unknwon <u@gogs.io>
|
||||
Joe Chen <jc@unknwon.io> 无闻 <u@gogs.io>
|
||||
Joe Chen <jc@unknwon.io> ᴜɴᴋɴᴡᴏɴ <u@gogs.io>
|
||||
Joe Chen <jc@unknwon.io> ᴜɴᴋɴᴡᴏɴ <jc@unknwon.io>
|
||||
|
||||
1
.packager/Procfile
Normal file
1
.packager/Procfile
Normal file
@@ -0,0 +1 @@
|
||||
web: ./gogs web -p ${PORT:=3000}
|
||||
@@ -8,10 +8,10 @@ APP_USER=$(${CLI} config:get APP_USER)
|
||||
APP_GROUP=$(${CLI} config:get APP_GROUP)
|
||||
APP_CONFIG="/etc/${APP_NAME}/conf/app.ini"
|
||||
|
||||
mkdir -p $(dirname ${APP_CONFIG})
|
||||
chown ${APP_USER}.${APP_GROUP} $(dirname ${APP_CONFIG})
|
||||
mkdir -p "$(dirname ${APP_CONFIG})"
|
||||
chown "${APP_USER}"."${APP_GROUP}" "$(dirname ${APP_CONFIG})"
|
||||
[ -f ${APP_CONFIG} ] || ${CLI} run cp conf/app.ini ${APP_CONFIG}
|
||||
${CLI} config:set USER=${APP_USER}
|
||||
${CLI} config:set USER="${APP_USER}"
|
||||
sed -i "s|RUN_USER = git|RUN_USER = ${APP_USER}|" ${APP_CONFIG}
|
||||
sed -i "s|RUN_MODE = dev|RUN_MODE = prod|" ${APP_CONFIG}
|
||||
|
||||
30
.pkgr.yml
30
.pkgr.yml
@@ -1,27 +1,35 @@
|
||||
targets:
|
||||
debian-7: &debian
|
||||
debian-11: &debian
|
||||
build_dependencies:
|
||||
- libpam0g-dev
|
||||
dependencies:
|
||||
- libpam0g
|
||||
- git
|
||||
debian-8:
|
||||
debian-12:
|
||||
<<: *debian
|
||||
ubuntu-14.04:
|
||||
debian-13:
|
||||
<<: *debian
|
||||
ubuntu-12.04:
|
||||
debian-14:
|
||||
<<: *debian
|
||||
centos-6: &el
|
||||
ubuntu-18.04:
|
||||
<<: *debian
|
||||
ubuntu-20.04:
|
||||
<<: *debian
|
||||
ubuntu-22.04:
|
||||
<<: *debian
|
||||
ubuntu-24.04:
|
||||
<<: *debian
|
||||
centos-9:
|
||||
build_dependencies:
|
||||
- pam-devel
|
||||
# required for Go buildpack
|
||||
- perl-Digest-SHA
|
||||
dependencies:
|
||||
- pam
|
||||
- git
|
||||
centos-7:
|
||||
<<: *el
|
||||
before:
|
||||
- mv packager/Procfile .
|
||||
- mv packager/.godir .
|
||||
- mv .packager/Procfile .
|
||||
after:
|
||||
- mv bin/main gogs
|
||||
after_install: ./packager/hooks/postinst
|
||||
- mv bin/gogs gogs
|
||||
after_install: ./.packager/hooks/postinst
|
||||
buildpack: https://github.com/heroku/heroku-buildpack-go.git#main
|
||||
|
||||
30
.travis.yml
30
.travis.yml
@@ -1,30 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -y libpam-dev
|
||||
- go get github.com/msteinert/pam
|
||||
|
||||
install:
|
||||
- go get -t -v ./...
|
||||
|
||||
script:
|
||||
- go build -v -tags "pam"
|
||||
- go test -v -cover -race ./...
|
||||
|
||||
notifications:
|
||||
email:
|
||||
- u@gogs.io
|
||||
slack: gophercn:o5pSanyTeNhnfYc3QnG0X7Wx
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/b590f8e03882f7aedc3e
|
||||
on_success: change
|
||||
on_failure: always
|
||||
on_start: never
|
||||
33
AGENTS.md
Normal file
33
AGENTS.md
Normal file
@@ -0,0 +1,33 @@
|
||||
## Core principles
|
||||
|
||||
- Stop telling me "You're right", it just shows how incompetent you are. Do it right on your first try, fact-check and review after changes. If you are not sure, ask for help.
|
||||
- When you see changes made outside your knowledge, use the current version as your new starting point. Do not blindly overwrite those changes or you suck. Even if you have to update the code, always respect the pattern in the surrounding context!
|
||||
|
||||
## Style and mechanics
|
||||
|
||||
This applies to all texts, including but not limited to UI, documentation, code comments.
|
||||
|
||||
- Use sentence case. Preserve original casing for brand names.
|
||||
- End with a period for a full sentence.
|
||||
- Do not add comments that repeat what the code is doing, always prefer more descriptive names. Do add comments for intentions that aren't obvious via reading the code alone. This rule takes precedence over matching existing patterns.
|
||||
|
||||
## Coding guidelines
|
||||
|
||||
- Use `github.com/cockroachdb/errors` for error handling.
|
||||
- Use `github.com/stretchr/testify` for assertions in tests. Be mindful about the choice of `require` and `assert`, the former should be used when the test cannot proceed meaningfully after a failed assertion.
|
||||
|
||||
## Build instructions
|
||||
|
||||
- Prefer `task` command over vanilla `go` command when available. Use `--force` flag when necessary.
|
||||
- Run `task lint` after every time you finish changing code, and fix all linter errors.
|
||||
- Run `go mod tidy` after every time you change `go.mod`, do not manually edit `go.sum` file.
|
||||
|
||||
## Tool-use guidance
|
||||
|
||||
- Use `gh` CLI to access information on github.com that is not publicly available.
|
||||
|
||||
## Source code control
|
||||
|
||||
- When pushing changes to a pull request from a fork, use SSH address and do not add remote.
|
||||
- Never commit on the `main` branch directly unless being explicitly asked to do so. A single ask only grants a single commit action on the `main` branch.
|
||||
- Never amend commits unless being explicitly asked to do so.
|
||||
311
CHANGELOG.md
Normal file
311
CHANGELOG.md
Normal file
@@ -0,0 +1,311 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to Gogs are documented in this file.
|
||||
|
||||
## 0.15.0+dev (`main`)
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ Cross-repository LFS object overwrite via missing content hash verification. [#8166](https://github.com/gogs/gogs/pull/8166) - [GHSA-gmf8-978x-2fg2](https://github.com/gogs/gogs/security/advisories/GHSA-gmf8-978x-2fg2)
|
||||
- _Security:_ DOM-based XSS via issue meta selection on the issue page. [#8178](https://github.com/gogs/gogs/pull/8178) - [GHSA-vgjm-2cpf-4g7c](https://github.com/gogs/gogs/security/advisories/GHSA-vgjm-2cpf-4g7c)
|
||||
- Unable to update files via web editor and API. [#8184](https://github.com/gogs/gogs/pull/8184)
|
||||
|
||||
### Removed
|
||||
|
||||
- Support for passing API access tokens via URL query parameters (`token`, `access_token`). Use the `Authorization` header instead. [#8177](https://github.com/gogs/gogs/pull/8177) - [GHSA-x9p5-w45c-7ffc](https://github.com/gogs/gogs/security/advisories/GHSA-x9p5-w45c-7ffc)
|
||||
- The `gogs cert` subcommand. [#8153](https://github.com/gogs/gogs/pull/8153)
|
||||
- The `[email] DISABLE_HELO` configuration option. HELO/EHLO is now always sent during SMTP handshake. [#8164](https://github.com/gogs/gogs/pull/8164)
|
||||
- Support for MSSQL as a database backend. Stay on 0.14 for continued usage. [#8173](https://github.com/gogs/gogs/pull/8173)
|
||||
|
||||
## 0.14.1
|
||||
|
||||
### Added
|
||||
|
||||
- Support comparing tags in addition to branches. [#6141](https://github.com/gogs/gogs/issues/6141)
|
||||
- Show file name in browser tab title when viewing files. [#5896](https://github.com/gogs/gogs/pull/5896)
|
||||
- Support using TLS for Redis session provider using `[session] PROVIDER_CONFIG = ...,tls=true`. [#7860](https://github.com/gogs/gogs/pull/7860)
|
||||
- Support expanading values in `app.ini` from environment variables, e.g. `[database] PASSWORD = ${DATABASE_PASSWORD}`. [#8057](https://github.com/gogs/gogs/pull/8057)
|
||||
- Support custom logout URL that users get redirected to after sign out using `[auth] CUSTOM_LOGOUT_URL`. [#8089](https://github.com/gogs/gogs/pull/8089)
|
||||
- Start publishing next-generation, security-focused Docker image via `gogs/gogs:next-latest`, which will become the default image distribution (`gogs/gogs:latest`) starting 0.16.0. While not all container options support have been added in the next-generation image, the use of current legacy Docker image is deprecated, it will be published as `gogs/gogs:legacy-latest` starting 0.16.0, and be completely removed no earlier than 0.17.0. [#8061](https://github.com/gogs/gogs/pull/8061)
|
||||
|
||||
### Changed
|
||||
|
||||
- The required Go version to compile source code changed to 1.25.
|
||||
- The build tag `cert` has been removed, and the `gogs cert` subcommand is now always available. [#7883](https://github.com/gogs/gogs/pull/7883)
|
||||
- Switched to pure-Go SQLite driver, CGO is no longer required to compile Gogs. [#7882](https://github.com/gogs/gogs/issues/7882)
|
||||
- Updated Mermaid JS to 11.9.0. [#8009](https://github.com/gogs/gogs/pull/8009)
|
||||
- Halt the repository creation and leave the directory untouched if the repository root already exists. [#8091](https://github.com/gogs/gogs/pull/8091)
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ Unauthenticated file upload. [#8128](https://github.com/gogs/gogs/pull/8128) - [GHSA-fc3h-92p8-h36f](https://github.com/gogs/gogs/security/advisories/GHSA-fc3h-92p8-h36f)
|
||||
- _Security:_ Protected branch bypass in web UI. [#8124](https://github.com/gogs/gogs/pull/8124) - [GHSA-2c6v-8r3v-gh6p](https://github.com/gogs/gogs/security/advisories/GHSA-2c6v-8r3v-gh6p)
|
||||
- _Security:_ Authorization bypass allows cross-repository label modification. [#8123](https://github.com/gogs/gogs/pull/8123) - [GHSA-cv22-72px-f4gh](https://github.com/gogs/gogs/security/advisories/GHSA-cv22-72px-f4gh)
|
||||
- _Security:_ Cross-repository comment deletion. [#8119](https://github.com/gogs/gogs/pull/8119) - [GHSA-jj5m-h57j-5gv7](https://github.com/gogs/gogs/security/advisories/GHSA-jj5m-h57j-5gv7)
|
||||
- 500 error on repository watchers and stargazers pages when using MSSQL. [#5482](https://github.com/gogs/gogs/issues/5482)
|
||||
- Submodules using `ssh://` protocol and a port number are not rendered correctly. [#4941](https://github.com/gogs/gogs/issues/4941)
|
||||
- Missing link to user profile on the first commit in commits history page. [#7404](https://github.com/gogs/gogs/issues/7404)
|
||||
- Unable to delete or display files with special characters in their names. [#7596](https://github.com/gogs/gogs/issues/7596)
|
||||
- Docker healthcheck fails when `HTTP_PROXY` or `HTTPS_PROXY` environment variables are set. [#7529](https://github.com/gogs/gogs/issues/7529)
|
||||
|
||||
## 0.13.4
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ DoS in repository mirror sync. [#8065](https://github.com/gogs/gogs/pull/8065) - [GHSA-cr88-6mqm-4g57](https://github.com/gogs/gogs/security/advisories/GHSA-cr88-6mqm-4g57)
|
||||
- _Security:_ RCE in repository put contents API. [#8082](https://github.com/gogs/gogs/pull/8082) - [GHSA-gg64-xxr9-qhjp](https://github.com/gogs/gogs/security/advisories/GHSA-gg64-xxr9-qhjp)
|
||||
- _Security:_ Arbitrary file deletion via path traversal in wiki page update. [#8099](https://github.com/gogs/gogs/pull/8099) - [GHSA-jp7c-wj6q-3qf2](https://github.com/gogs/gogs/security/advisories/GHSA-jp7c-wj6q-3qf2)
|
||||
- _Security:_ 2FA bypass via recovery code. [#8100](https://github.com/gogs/gogs/pull/8100) - [GHSA-p6x6-9mx6-26wj](https://github.com/gogs/gogs/security/advisories/GHSA-p6x6-9mx6-26wj)
|
||||
- _Security:_ Authorization bypass in repository deletion API. [#8101](https://github.com/gogs/gogs/pull/8101) - [GHSA-rjv5-9px2-fqw6](https://github.com/gogs/gogs/security/advisories/GHSA-rjv5-9px2-fqw6)
|
||||
- _Security:_ Update repository content via API with read-only permission. [#8102](https://github.com/gogs/gogs/pull/8102) - [GHSA-5qhx-gwfj-6jqr](https://github.com/gogs/gogs/security/advisories/GHSA-5qhx-gwfj-6jqr)
|
||||
- _Security:_ Arbitrary file read/write via path traversal in Git hook editing. [#8103](https://github.com/gogs/gogs/pull/8103) - [GHSA-mrph-w4hh-gx3g](https://github.com/gogs/gogs/security/advisories/GHSA-mrph-w4hh-gx3g)
|
||||
- _Security:_ Stored XSS via Mermaid diagrams. [`2c88cd4`](https://github.com/gogs/gogs/commit/2c88cd4d9fdc346d8e06d82f5368d657c10e79c2) - [GHSA-26gq-grmh-6xm6](https://github.com/gogs/gogs/security/advisories/GHSA-26gq-grmh-6xm6)
|
||||
- Route `GET /api/v1/user/repos` responses 500 when accessible repositories contain forks. [#8069](https://github.com/gogs/gogs/pull/8069)
|
||||
- Newer Git versions that uses default branch `main` cause wiki initialization to fail. [#8094](https://github.com/gogs/gogs/pull/8094)
|
||||
|
||||
## 0.13.3
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ Stored XSS in PDF renderer. [GHSA-xh32-cx6c-cp4v](https://github.com/gogs/gogs/security/advisories/GHSA-xh32-cx6c-cp4v)
|
||||
- _Security:_ Path Traversal in file editing UI. [GHSA-wj44-9vcg-wjq7](https://github.com/gogs/gogs/security/advisories/GHSA-wj44-9vcg-wjq7)
|
||||
- Randomly timeout on repository file uploads. [#7890](https://github.com/gogs/gogs/pull/7890)
|
||||
- Unable to override email templates in custom directory. [#7905](https://github.com/gogs/gogs/pull/7905)
|
||||
|
||||
## 0.13.2
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ Path Traversal in file editing UI. [GHSA-r7j8-5h9c-f6fx](https://github.com/gogs/gogs/security/advisories/GHSA-r7j8-5h9c-f6fx)
|
||||
- _Security:_ Path Traversal in file update API. [GHSA-qf5v-rp47-55gg](https://github.com/gogs/gogs/security/advisories/GHSA-qf5v-rp47-55gg)
|
||||
- _Security:_ Argument Injection in the built-in SSH server. [GHSA-vm62-9jw3-c8w3](https://github.com/gogs/gogs/security/advisories/GHSA-vm62-9jw3-c8w3)
|
||||
- _Security:_ Deletion of internal files. [GHSA-ccqv-43vm-4f3w](https://github.com/gogs/gogs/security/advisories/GHSA-ccqv-43vm-4f3w)
|
||||
- _Security:_ Argument Injection during changes preview. [GHSA-9pp6-wq8c-3w2c](https://github.com/gogs/gogs/security/advisories/GHSA-9pp6-wq8c-3w2c)
|
||||
- _Security:_ Argument Injection when tagging new releases. [GHSA-m27m-h5gj-wwmg](https://github.com/gogs/gogs/security/advisories/GHSA-m27m-h5gj-wwmg)
|
||||
- Use the non-deprecated section name `[email]` during installation for email settings. [#7704](https://github.com/gogs/gogs/pull/7704)
|
||||
- Use the non-deprecated section name `[email] PASSWORD` during installation for email password. [#7807](https://github.com/gogs/gogs/pull/7807)
|
||||
- Make purple template label color to actually use the hexcode of purple. [#7722](https://github.com/gogs/gogs/pull/7722)
|
||||
|
||||
## 0.13.0
|
||||
|
||||
### Added
|
||||
|
||||
- Support using personal access token in the password field. [#3866](https://github.com/gogs/gogs/issues/3866)
|
||||
- An unlisted option is added when create or migrate a repository. Unlisted repositories are public but not being listed for users without direct access in the UI. [#5733](https://github.com/gogs/gogs/issues/5733)
|
||||
- New API endpoint `PUT /repos/:owner/:repo/contents/:path` for creating and update repository contents. [#5967](https://github.com/gogs/gogs/issues/5967)
|
||||
- New configuration option `[git.timeout] DIFF` for customizing operation timeout of `git diff`. [#6315](https://github.com/gogs/gogs/issues/6315)
|
||||
- New configuration option `[server] SSH_SERVER_MACS` for setting list of accepted MACs for connections to builtin SSH server. [#6434](https://github.com/gogs/gogs/issues/6434)
|
||||
- New configuration option `[repository] DEFAULT_BRANCH` for setting default branch name for new repositories. [#7291](https://github.com/gogs/gogs/issues/7291)
|
||||
- New configuration option `[server] SSH_SERVER_ALGORITHMS` for specifying the list of accepted key exchange algorithms for connections to builtin SSH server. [#7345](https://github.com/gogs/gogs/pull/7345)
|
||||
- Support specifying custom schema for PostgreSQL. [#6695](https://github.com/gogs/gogs/pull/6695)
|
||||
- Support rendering Mermaid diagrams in Markdown. [#6776](https://github.com/gogs/gogs/pull/6776)
|
||||
- Docker: Allow passing extra arguments to the `backup` command. [#7060](https://github.com/gogs/gogs/pull/7060)
|
||||
- New languages support: Mongolian, Romanian. [#6510](https://github.com/gogs/gogs/pull/6510) [#7082](https://github.com/gogs/gogs/pull/7082)
|
||||
|
||||
### Changed
|
||||
|
||||
- The default branch has been changed to `main`. [#6285](https://github.com/gogs/gogs/pull/6285)
|
||||
- MSSQL as database backend is deprecated, installation page no longer shows it as an option. Existing installations and manually craft configuration file continue to work. [#6295](https://github.com/gogs/gogs/pull/6295)
|
||||
- Use [Task](https://github.com/go-task/task) as the build tool. [#6297](https://github.com/gogs/gogs/pull/6297)
|
||||
- The required Go version to compile source code changed to 1.18.
|
||||
- Access tokens are now stored using their SHA256 hashes instead of raw values. [#7008](https://github.com/gogs/gogs/pull/7008)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Unable to use LDAP authentication on ARM machines. [#6761](https://github.com/gogs/gogs/issues/6761)
|
||||
- Unable to choose "Lookup Avatar by mail" in user settings without deleting custom avatar. [#7267](https://github.com/gogs/gogs/pull/7267)
|
||||
- Mistakenly include the "data" directory under the custom directory in the Docker setup. [#7343](https://github.com/gogs/gogs/pull/7343)
|
||||
- Unable to start after data recovery with an outdated migration version. [#7125](https://github.com/gogs/gogs/issues/7125)
|
||||
|
||||
### Removed
|
||||
|
||||
- ⚠️ Migrations before 0.12 are removed, installations not on 0.12 should upgrade to it to run the migrations and then upgrade to 0.13.
|
||||
- Configuration section `[mailer]` is no longer used, please use `[email]`.
|
||||
- Configuration section `[service]` is no longer used, please use `[auth]`.
|
||||
- Configuration option `APP_NAME` is no longer used, please use `BRAND_NAME`.
|
||||
- Configuration option `[security] REVERSE_PROXY_AUTHENTICATION_USER` is no longer used, please use `[auth] REVERSE_PROXY_AUTHENTICATION_HEADER`.
|
||||
- Configuration option `[auth] ACTIVE_CODE_LIVE_MINUTES` is no longer used, please use `[auth] ACTIVATE_CODE_LIVES`.
|
||||
- Configuration option `[auth] RESET_PASSWD_CODE_LIVE_MINUTES` is no longer used, please use `[auth] RESET_PASSWORD_CODE_LIVES`.
|
||||
- Configuration option `[auth] ENABLE_CAPTCHA` is no longer used, please use `[auth] ENABLE_REGISTRATION_CAPTCHA`.
|
||||
- Configuration option `[auth] ENABLE_NOTIFY_MAIL` is no longer used, please use `[user] ENABLE_EMAIL_NOTIFICATION`.
|
||||
- Configuration option `[auth] REGISTER_EMAIL_CONFIRM` is no longer used, please use `[auth] REQUIRE_EMAIL_CONFIRMATION`.
|
||||
- Configuration option `[session] GC_INTERVAL_TIME` is no longer used, please use `[session] GC_INTERVAL`.
|
||||
- Configuration option `[session] SESSION_LIFE_TIME` is no longer used, please use `[session] MAX_LIFE_TIME`.
|
||||
- Configuration option `[server] ROOT_URL` is no longer used, please use `[server] EXTERNAL_URL`.
|
||||
- Configuration option `[server] LANDING_PAGE` is no longer used, please use `[server] LANDING_URL`.
|
||||
- Configuration option `[database] DB_TYPE` is no longer used, please use `[database] TYPE`.
|
||||
- Configuration option `[database] PASSWD` is no longer used, please use `[database] PASSWORD`.
|
||||
- Remove option to use Makefile as the build tool. [#6980](https://github.com/gogs/gogs/pull/6980)
|
||||
|
||||
## 0.12.11
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ Stored XSS for issue assignees. [#7145](https://github.com/gogs/gogs/issues/7145)
|
||||
- _Security:_ OS Command Injection in repo editor on case-insensitive file systems. [#7030](https://github.com/gogs/gogs/issues/7030)
|
||||
- Unable to render repository pages with implicit submodules (e.g. `get submodule "REDACTED": revision does not exist`). [#6436](https://github.com/gogs/gogs/issues/6436)
|
||||
|
||||
## 0.12.10
|
||||
|
||||
### Changed
|
||||
|
||||
- Support using `[security] LOCAL_NETWORK_ALLOWLIST = *` to allow all hostnames. [#7111](https://github.com/gogs/gogs/pull/7111)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Unable to send webhooks to local network addresses after configured `[security] LOCAL_NETWORK_ALLOWLIST`. [#7074](https://github.com/gogs/gogs/issues/7074)
|
||||
|
||||
## 0.12.9
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ OS Command Injection in file editor. [#7000](https://github.com/gogs/gogs/issues/7000)
|
||||
- _Security:_ Sanitize `DisplayName` in repository issue list. [#7009](https://github.com/gogs/gogs/pull/7009)
|
||||
- _Security:_ Path Traversal in file editor on Windows. [#7001](https://github.com/gogs/gogs/issues/7001)
|
||||
- _Security:_ Path Traversal in Git HTTP endpoints. [#7002](https://github.com/gogs/gogs/issues/7002)
|
||||
- Unable to init repository during creation on Windows. [#6967](https://github.com/gogs/gogs/issues/6967)
|
||||
- Mysterious panic on `Value not found for type *repo.HTTPContext`. [#6963](https://github.com/gogs/gogs/issues/6963)
|
||||
|
||||
## 0.12.8
|
||||
|
||||
### Changed
|
||||
|
||||
- All users (including admins) need to use the configuration option `[security] LOCAL_NETWORK_ALLOWLIST` to allow repository migration and webhooks to be able to access local network addresses, which is a comma separated list of hostnames. [#6988](https://github.com/gogs/gogs/pull/6988)
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ SSRF in webhook. [#6901](https://github.com/gogs/gogs/issues/6901)
|
||||
- _Security:_ XSS in cookies. [#6953](https://github.com/gogs/gogs/issues/6953)
|
||||
- _Security:_ OS Command Injection in file uploading. [#6968](https://github.com/gogs/gogs/issues/6968)
|
||||
- _Security:_ Remote Command Execution in file editing. [#6555](https://github.com/gogs/gogs/issues/6555)
|
||||
|
||||
## 0.12.7
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ Stored XSS in issues. [#6919](https://github.com/gogs/gogs/issues/6919)
|
||||
- Invalid character in `Access-Control-Allow-Credentials` response header. [#4983](https://github.com/gogs/gogs/issues/4983)
|
||||
- Mysterious `ssh: overflow reading version string` errors from builtin SSH server. [#6882](https://github.com/gogs/gogs/issues/6882)
|
||||
|
||||
## 0.12.6
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ Remote command execution in file uploading. [#6833](https://github.com/gogs/gogs/issues/6833)
|
||||
- _Regression:_ Unable to migrate repository from other local Git hosting. Added a new configuration option `[security] LOCAL_NETWORK_ALLOWLIST`, which is a comma separated list of hostnames that are explicitly allowed to be accessed within the local network. [#6841](https://github.com/gogs/gogs/issues/6841)
|
||||
- Slow start of Docker containers using NAS devices. [#6554](https://github.com/gogs/gogs/issues/6554)
|
||||
|
||||
## 0.12.5
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ Potential SSRF in repository migration. [#6754](https://github.com/gogs/gogs/issues/6754)
|
||||
- _Security:_ Improper PAM authorization handling. [#6810](https://github.com/gogs/gogs/issues/6810)
|
||||
|
||||
## 0.12.4
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Security:_ Potential SSRF attack by CRLF injection via repository migration. [#6413](https://github.com/gogs/gogs/issues/6413)
|
||||
- _Regression:_ Fixed smart links for issues stops rendering. [#6506](https://github.com/gogs/gogs/issues/6506)
|
||||
- Added `X-Frame-Options` header to prevent Clickjacking. [#6409](https://github.com/gogs/gogs/issues/6409)
|
||||
|
||||
## 0.12.3
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Regression:_ When running Gogs on Windows, push commits no longer fail on a daily basis with the error "pre-receive hook declined". [#6316](https://github.com/gogs/gogs/issues/6316)
|
||||
- Auto-linked commit SHAs now have correct links. [#6300](https://github.com/gogs/gogs/issues/6300)
|
||||
- Git LFS client (with version >= 2.5.0) wasn't able to upload files with known format (e.g. PNG, JPEG), and the server is expecting the HTTP Header `Content-Type` to be `application/octet-stream`. The server now tells the LFS client to always use `Content-Type: application/octet-stream` when upload files.
|
||||
|
||||
## 0.12.2
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Regression:_ Pages are correctly rendered when requesting `?go-get=1` for subdirectories. [#6314](https://github.com/gogs/gogs/issues/6314)
|
||||
- _Regression:_ Submodule with a relative path is linked correctly. [#6319](https://github.com/gogs/gogs/issues/6319)
|
||||
- Backup can be processed when `--target` is specified on Windows. [#6339](https://github.com/gogs/gogs/issues/6339)
|
||||
- Commit message contains keywords look like an issue reference no longer fails the push entirely. [#6289](https://github.com/gogs/gogs/issues/6289)
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Fixed
|
||||
|
||||
- The `updated_at` field is now correctly updated when updates an issue. [#6209](https://github.com/gogs/gogs/issues/6209)
|
||||
- Fixed a regression which created `login_source.cfg` column to have `VARCHAR(255)` instead of `TEXT` in MySQL. [#6280](https://github.com/gogs/gogs/issues/6280)
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Added
|
||||
|
||||
- Support for Git LFS, you can read documentation for both [user](https://github.com/gogs/gogs/blob/main/docs/user/lfs.md) and [admin](https://github.com/gogs/gogs/blob/main/docs/admin/lfs.md). [#1322](https://github.com/gogs/gogs/issues/1322)
|
||||
- Allow admin to remove observers from the repository. [#5803](https://github.com/gogs/gogs/pull/5803)
|
||||
- Use `Last-Modified` HTTP header for raw files. [#5811](https://github.com/gogs/gogs/issues/5811)
|
||||
- Support syntax highlighting for SAS code files (i.e. `.r`, `.sas`, `.tex`, `.yaml`). [#5856](https://github.com/gogs/gogs/pull/5856)
|
||||
- Able to fill in pull request title with a template. [#5901](https://github.com/gogs/gogs/pull/5901)
|
||||
- Able to override static files under `public/` directory, please refer to [documentation](https://gogs.io/docs/features/custom_template) for usage. [#5920](https://github.com/gogs/gogs/pull/5920)
|
||||
- New API endpoint `GET /admin/teams/:teamid/members` to list members of a team. [#5877](https://github.com/gogs/gogs/issues/5877)
|
||||
- Support backup with retention policy for Docker deployments. [#6140](https://github.com/gogs/gogs/pull/6140)
|
||||
|
||||
### Changed
|
||||
|
||||
- The organization profile page has changed to display at most 12 members. [#5506](https://github.com/gogs/gogs/issues/5506)
|
||||
- The required Go version to compile source code changed to 1.14.
|
||||
- All assets are now embedded into binary and served from memory by default. Set `[server] LOAD_ASSETS_FROM_DISK = true` to load them from disk. [#5920](https://github.com/gogs/gogs/pull/5920)
|
||||
- Application and Go versions are removed from page footer and only show in the admin dashboard.
|
||||
- Build tag for running as Windows Service has been changed from `miniwinsvc` to `minwinsvc`.
|
||||
- Configuration option `APP_NAME` is deprecated and will end support in 0.13.0, please start using `BRAND_NAME`.
|
||||
- Configuration option `[server] ROOT_URL` is deprecated and will end support in 0.13.0, please start using `[server] EXTERNAL_URL`.
|
||||
- Configuration option `[server] LANDING_PAGE` is deprecated and will end support in 0.13.0, please start using `[server] LANDING_URL`.
|
||||
- Configuration option `[database] DB_TYPE` is deprecated and will end support in 0.13.0, please start using `[database] TYPE`.
|
||||
- Configuration option `[database] PASSWD` is deprecated and will end support in 0.13.0, please start using `[database] PASSWORD`.
|
||||
- Configuration option `[security] REVERSE_PROXY_AUTHENTICATION_USER` is deprecated and will end support in 0.13.0, please start using `[auth] REVERSE_PROXY_AUTHENTICATION_HEADER`.
|
||||
- Configuration section `[mailer]` is deprecated and will end support in 0.13.0, please start using `[email]`.
|
||||
- Configuration section `[service]` is deprecated and will end support in 0.13.0, please start using `[auth]`.
|
||||
- Configuration option `[auth] ACTIVE_CODE_LIVE_MINUTES` is deprecated and will end support in 0.13.0, please start using `[auth] ACTIVATE_CODE_LIVES`.
|
||||
- Configuration option `[auth] RESET_PASSWD_CODE_LIVE_MINUTES` is deprecated and will end support in 0.13.0, please start using `[auth] RESET_PASSWORD_CODE_LIVES`.
|
||||
- Configuration option `[auth] REGISTER_EMAIL_CONFIRM` is deprecated and will end support in 0.13.0, please start using `[auth] REQUIRE_EMAIL_CONFIRMATION`.
|
||||
- Configuration option `[auth] ENABLE_CAPTCHA` is deprecated and will end support in 0.13.0, please start using `[auth] ENABLE_REGISTRATION_CAPTCHA`.
|
||||
- Configuration option `[auth] ENABLE_NOTIFY_MAIL` is deprecated and will end support in 0.13.0, please start using `[user] ENABLE_EMAIL_NOTIFICATION`.
|
||||
- Configuration option `[session] GC_INTERVAL_TIME` is deprecated and will end support in 0.13.0, please start using `[session] GC_INTERVAL`.
|
||||
- Configuration option `[session] SESSION_LIFE_TIME` is deprecated and will end support in 0.13.0, please start using `[session] MAX_LIFE_TIME`.
|
||||
- The name `-` is reserved and cannot be used for users or organizations.
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Security] Potential open redirection with i18n.
|
||||
- [Security] Potential ability to delete files outside a repository.
|
||||
- [Security] Potential ability to set primary email on others' behalf from their verified emails.
|
||||
- [Security] Potential XSS attack via `.ipynb`. [#5170](https://github.com/gogs/gogs/issues/5170)
|
||||
- [Security] Potential SSRF attack via webhooks. [#5366](https://github.com/gogs/gogs/issues/5366)
|
||||
- [Security] Potential CSRF attack in admin panel. [#5367](https://github.com/gogs/gogs/issues/5367)
|
||||
- [Security] Potential stored XSS attack in some browsers. [#5397](https://github.com/gogs/gogs/issues/5397)
|
||||
- [Security] Potential RCE on mirror repositories. [#5767](https://github.com/gogs/gogs/issues/5767)
|
||||
- [Security] Potential XSS attack with raw markdown API. [#5907](https://github.com/gogs/gogs/pull/5907)
|
||||
- File both modified and renamed within a commit treated as separate files. [#5056](https://github.com/gogs/gogs/issues/5056)
|
||||
- Unable to restore the database backup to MySQL 8.0 with syntax error. [#5602](https://github.com/gogs/gogs/issues/5602)
|
||||
- Open/close milestone redirects to a 404 page. [#5677](https://github.com/gogs/gogs/issues/5677)
|
||||
- Disallow multiple tokens with same name. [#5587](https://github.com/gogs/gogs/issues/5587) [#5820](https://github.com/gogs/gogs/pull/5820)
|
||||
- Enable Federated Avatar Lookup could cause server to crash. [#5848](https://github.com/gogs/gogs/issues/5848)
|
||||
- Private repositories are hidden in the organization's view. [#5869](https://github.com/gogs/gogs/issues/5869)
|
||||
- Users have access to base repository cannot view commits in forks. [#5878](https://github.com/gogs/gogs/issues/5878)
|
||||
- Server error when changing email address in user settings page. [#5899](https://github.com/gogs/gogs/issues/5899)
|
||||
- Fall back to use RFC 3339 as time layout when misconfigured. [#6098](https://github.com/gogs/gogs/issues/6098)
|
||||
- Unable to update team with server error. [#6185](https://github.com/gogs/gogs/issues/6185)
|
||||
- Webhooks are not fired after push when `[service] REQUIRE_SIGNIN_VIEW = true`.
|
||||
- Files with identical content are randomly displayed one of them.
|
||||
|
||||
### Removed
|
||||
|
||||
- Configuration option `[other] SHOW_FOOTER_VERSION`
|
||||
- Configuration option `[server] STATIC_ROOT_PATH`
|
||||
- Configuration option `[repository] MIRROR_QUEUE_LENGTH`
|
||||
- Configuration option `[repository] PULL_REQUEST_QUEUE_LENGTH`
|
||||
- Configuration option `[session] ENABLE_SET_COOKIE`
|
||||
- Configuration option `[release.attachment] PATH`
|
||||
- Configuration option `[webhook] QUEUE_LENGTH`
|
||||
- Build tag `sqlite`, which means CGO is now required.
|
||||
|
||||
---
|
||||
|
||||
**Older change logs can be found on [GitHub](https://github.com/gogs/gogs/releases?after=v0.12.0).**
|
||||
2
CODEOWNERS
Normal file
2
CODEOWNERS
Normal file
@@ -0,0 +1,2 @@
|
||||
# Default
|
||||
* @gogs/core
|
||||
52
Dockerfile
52
Dockerfile
@@ -1,22 +1,44 @@
|
||||
FROM alpine:3.3
|
||||
MAINTAINER jp@roemer.im
|
||||
FROM golang:1.26-alpine3.23 AS binarybuilder
|
||||
RUN apk --no-cache --no-progress add --virtual \
|
||||
build-deps \
|
||||
build-base \
|
||||
git \
|
||||
linux-pam-dev
|
||||
|
||||
# Install system utils & Gogs runtime dependencies
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-amd64 /usr/sbin/gosu
|
||||
RUN chmod +x /usr/sbin/gosu \
|
||||
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat tzdata
|
||||
WORKDIR /gogs.io/gogs
|
||||
COPY . .
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
RUN ./docker/build/install-task.sh
|
||||
RUN TAGS="cert pam" task build
|
||||
|
||||
COPY . /app/gogs/
|
||||
WORKDIR /app/gogs/
|
||||
RUN ./docker/build.sh
|
||||
FROM alpine:3.23
|
||||
RUN apk --no-cache --no-progress add \
|
||||
bash \
|
||||
ca-certificates \
|
||||
curl \
|
||||
git \
|
||||
linux-pam \
|
||||
openssh \
|
||||
s6 \
|
||||
shadow \
|
||||
socat \
|
||||
tzdata \
|
||||
rsync
|
||||
|
||||
# Configure LibC Name Service
|
||||
ENV GOGS_CUSTOM=/data/gogs
|
||||
|
||||
# Configure LibC Name Service
|
||||
COPY docker/nsswitch.conf /etc/nsswitch.conf
|
||||
|
||||
# Configure Docker Container
|
||||
VOLUME ["/data"]
|
||||
WORKDIR /app/gogs
|
||||
COPY docker ./docker
|
||||
COPY --from=binarybuilder /gogs.io/gogs/.bin/gogs .
|
||||
|
||||
RUN ./docker/build/finalize.sh
|
||||
|
||||
# Configure Docker Container
|
||||
VOLUME ["/data", "/backup"]
|
||||
EXPOSE 22 3000
|
||||
ENTRYPOINT ["docker/start.sh"]
|
||||
CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]
|
||||
HEALTHCHECK CMD (curl --noproxy localhost -o /dev/null -sS http://localhost:3000/healthcheck) || exit 1
|
||||
ENTRYPOINT ["/app/gogs/docker/start.sh"]
|
||||
CMD ["/usr/bin/s6-svscan", "/app/gogs/docker/s6/"]
|
||||
|
||||
50
Dockerfile.next
Normal file
50
Dockerfile.next
Normal file
@@ -0,0 +1,50 @@
|
||||
FROM golang:1.26-alpine3.23 AS binarybuilder
|
||||
RUN apk --no-cache --no-progress add --virtual \
|
||||
build-deps \
|
||||
build-base \
|
||||
git \
|
||||
linux-pam-dev
|
||||
|
||||
WORKDIR /gogs.io/gogs
|
||||
COPY . .
|
||||
|
||||
RUN ./docker/build/install-task.sh
|
||||
RUN TAGS="cert pam" task build
|
||||
|
||||
FROM alpine:3.23
|
||||
|
||||
# Create git user and group with fixed UID/GID at build time for better K8s security context support.
|
||||
# Using 1000:1000 as it's a common non-root UID/GID that works well with most volume permission setups.
|
||||
ARG GOGS_UID=1000
|
||||
ARG GOGS_GID=1000
|
||||
RUN addgroup -g ${GOGS_GID} -S git && \
|
||||
adduser -u ${GOGS_UID} -G git -H -D -g 'Gogs Git User' -h /data/git -s /bin/sh git
|
||||
|
||||
RUN apk --no-cache --no-progress add \
|
||||
bash \
|
||||
ca-certificates \
|
||||
curl \
|
||||
git \
|
||||
linux-pam \
|
||||
openssh-keygen
|
||||
|
||||
ENV GOGS_CUSTOM=/data/gogs
|
||||
|
||||
WORKDIR /app/gogs
|
||||
COPY --from=binarybuilder /gogs.io/gogs/.bin/gogs .
|
||||
COPY docker-next/start.sh .
|
||||
RUN chmod +x start.sh && \
|
||||
mkdir -p /data && \
|
||||
ln -s /data/git /home/git && \
|
||||
chown -R git:git /app/gogs /data
|
||||
|
||||
# Configure Docker Container
|
||||
VOLUME ["/data", "/backup"]
|
||||
EXPOSE 22 3000
|
||||
HEALTHCHECK CMD (curl --noproxy localhost -o /dev/null -sS http://localhost:3000/healthcheck) || exit 1
|
||||
|
||||
# Run as non-root user by default for better K8s security context support.
|
||||
USER git:git
|
||||
|
||||
ENTRYPOINT ["/app/gogs/start.sh"]
|
||||
CMD ["/app/gogs/gogs", "web"]
|
||||
@@ -1,25 +0,0 @@
|
||||
FROM hypriot/rpi-alpine-scratch:v3.2
|
||||
MAINTAINER jp@roemer.im, raxetul@gmail.com
|
||||
|
||||
# Install system utils & Gogs runtime dependencies
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-armhf /usr/sbin/gosu
|
||||
RUN chmod +x /usr/sbin/gosu \
|
||||
&& echo "http://dl-4.alpinelinux.org/alpine/v3.3/main/" | tee /etc/apk/repositories \
|
||||
&& echo "http://dl-4.alpinelinux.org/alpine/v3.3/community/" | tee -a /etc/apk/repositories \
|
||||
&& apk -U --no-progress upgrade && rm -f /var/cache/apk/APKINDEX.* \
|
||||
&& apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat tzdata
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
COPY . /app/gogs/
|
||||
WORKDIR /app/gogs/
|
||||
RUN ./docker/build.sh
|
||||
|
||||
# Configure LibC Name Service
|
||||
COPY docker/nsswitch.conf /etc/nsswitch.conf
|
||||
|
||||
# Configure Docker Container
|
||||
VOLUME ["/data"]
|
||||
EXPOSE 22 3000
|
||||
ENTRYPOINT ["docker/start.sh"]
|
||||
CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]
|
||||
74
Makefile
74
Makefile
@@ -1,74 +0,0 @@
|
||||
LDFLAGS += -X "github.com/gogits/gogs/modules/setting.BuildTime=$(shell date -u '+%Y-%m-%d %I:%M:%S %Z')"
|
||||
LDFLAGS += -X "github.com/gogits/gogs/modules/setting.BuildGitHash=$(shell git rev-parse HEAD)"
|
||||
|
||||
DATA_FILES := $(shell find conf | sed 's/ /\\ /g')
|
||||
LESS_FILES := $(wildcard public/less/gogs.less public/less/_*.less)
|
||||
GENERATED := modules/bindata/bindata.go public/css/gogs.css
|
||||
|
||||
TAGS = ""
|
||||
BUILD_FLAGS = "-v"
|
||||
|
||||
RELEASE_ROOT = "release"
|
||||
RELEASE_GOGS = "release/gogs"
|
||||
NOW = $(shell date -u '+%Y%m%d%I%M%S')
|
||||
GOVET = go tool vet -composites=false -methods=false -structtags=false
|
||||
|
||||
.PHONY: build pack release bindata clean
|
||||
|
||||
.IGNORE: public/css/gogs.css
|
||||
|
||||
all: build
|
||||
|
||||
check: test
|
||||
|
||||
dist: release
|
||||
|
||||
govet:
|
||||
$(GOVET) gogs.go
|
||||
$(GOVET) models modules routers
|
||||
|
||||
build: $(GENERATED)
|
||||
go install $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)'
|
||||
cp '$(GOPATH)/bin/gogs' .
|
||||
|
||||
build-dev: $(GENERATED) govet
|
||||
go install $(BUILD_FLAGS) -tags '$(TAGS)'
|
||||
cp '$(GOPATH)/bin/gogs' .
|
||||
|
||||
build-dev-race: $(GENERATED) govet
|
||||
go install $(BUILD_FLAGS) -race -tags '$(TAGS)'
|
||||
cp '$(GOPATH)/bin/gogs' .
|
||||
|
||||
pack:
|
||||
rm -rf $(RELEASE_GOGS)
|
||||
mkdir -p $(RELEASE_GOGS)
|
||||
cp -r gogs LICENSE README.md README_ZH.md templates public scripts $(RELEASE_GOGS)
|
||||
rm -rf $(RELEASE_GOGS)/public/config.codekit $(RELEASE_GOGS)/public/less
|
||||
cd $(RELEASE_ROOT) && zip -r gogs.$(NOW).zip "gogs"
|
||||
|
||||
release: build pack
|
||||
|
||||
bindata: modules/bindata/bindata.go
|
||||
|
||||
modules/bindata/bindata.go: $(DATA_FILES)
|
||||
go-bindata -o=$@ -ignore="\\.DS_Store|README.md|TRANSLATORS" -pkg=bindata conf/...
|
||||
|
||||
less: public/css/gogs.css
|
||||
|
||||
public/css/gogs.css: $(LESS_FILES)
|
||||
lessc $< $@
|
||||
|
||||
clean:
|
||||
go clean -i ./...
|
||||
|
||||
clean-mac: clean
|
||||
find . -name ".DS_Store" -print0 | xargs -0 rm
|
||||
|
||||
test:
|
||||
go test -cover -race ./...
|
||||
|
||||
fixme:
|
||||
grep -rnw "FIXME" routers models modules
|
||||
|
||||
todo:
|
||||
grep -rnw "TODO" routers models modules
|
||||
170
README.md
170
README.md
@@ -1,138 +1,100 @@
|
||||
Gogs - Go Git Service [](https://travis-ci.org/gogits/gogs) [](https://crowdin.com/project/gogs) [](https://gitter.im/gogits/gogs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
=====================
|
||||

|
||||
|
||||

|
||||
[](https://github.com/gogs/gogs/actions?query=branch%3Amain) [](https://sourcegraph.com/github.com/gogs/gogs)
|
||||
|
||||
##### Current tip version: 0.9.97 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions)
|
||||
👉 Deploy on DigitalOcean and [get $200 in free credits](https://m.do.co/c/5aeb02268b55)!
|
||||
|
||||
| Web | UI | Preview |
|
||||
|:-------------:|:-------:|:-------:|
|
||||
||||
|
||||
||||
|
||||
||||
|
||||
## 🔮 Vision
|
||||
|
||||
### Important Notes
|
||||
The Gogs (`/gɑgz/`) project aims to build a simple, stable and extensible self-hosted Git service that can be set up in the most painless way. With Go, this can be done with an independent binary distribution across all platforms that Go supports, including Linux, macOS, Windows and ARM-based systems.
|
||||
|
||||
1. **YOU MUST READ [Contributing Code](https://github.com/gogits/gogs/wiki/Contributing-Code) BEFORE STARTING TO WORK ON A PULL REQUEST**.
|
||||
2. Due to testing purpose, data of [try.gogs.io](https://try.gogs.io) was reset in **Jan 28, 2015** and will reset multiple times after. Please do **NOT** put your important data on the site.
|
||||
3. The demo site [try.gogs.io](https://try.gogs.io) is running under `develop` branch.
|
||||
4. If you think there are vulnerabilities in the project, please talk privately to **u@gogs.io**. Thanks!
|
||||
5. If you're interested in using APIs, we have experimental support with [documentation](https://github.com/gogits/go-gogs-client/wiki).
|
||||
6. If your team/company is using Gogs and would like to put your logo on [our website](https://gogs.io), contact us by any means.
|
||||
## 📡 Overview
|
||||
|
||||
[简体中文](README_ZH.md)
|
||||
|
||||
## Purpose
|
||||
|
||||
The goal of this project is to make the easiest, fastest, and most painless way of setting up a self-hosted Git service. With Go, this can be done with an independent binary distribution across **ALL platforms** that Go supports, including Linux, Mac OS X, Windows and ARM.
|
||||
|
||||
## Overview
|
||||
|
||||
- Please see the [Documentation](https://gogs.io/docs/intro) for common usages and change log.
|
||||
- See the [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) to follow the develop team.
|
||||
- Please visit [our home page](https://gogs.io) for user documentation.
|
||||
- Please refer to [CHANGELOG.md](CHANGELOG.md) for list of changes in each releases.
|
||||
- Want to try it before doing anything else? Do it [online](https://try.gogs.io/gogs/gogs)!
|
||||
- Having trouble? Get help with [Troubleshooting](https://gogs.io/docs/intro/troubleshooting.html) or [User Forum](https://discuss.gogs.io/).
|
||||
- Want to help with localization? Check out the [guide](https://gogs.io/docs/features/i18n.html)!
|
||||
- Having trouble? Help yourself with [troubleshooting](https://gogs.io/asking/troubleshooting) or ask questions in [Discussions](https://github.com/gogs/gogs/discussions).
|
||||
- Want to help with localization? Check out the [localization documentation](https://gogs.io/advancing/localization).
|
||||
- Ready to get hands dirty? Read our [contributing guide](.github/CONTRIBUTING.md).
|
||||
- Hmm... What about APIs? We have experimental support with [documentation](https://gogs.io/api-reference).
|
||||
|
||||
## Features
|
||||
## 💌 Features
|
||||
|
||||
- Activity timeline
|
||||
- SSH and HTTP/HTTPS protocols
|
||||
- SMTP/LDAP/Reverse proxy authentication
|
||||
- Reverse proxy with sub-path
|
||||
- Account/Organization/Repository management
|
||||
- Add/Remove repository collaborators
|
||||
- Repository/Organization webhooks (including Slack)
|
||||
- Repository Git hooks/deploy keys
|
||||
- Repository issues, pull requests and wiki
|
||||
- Migrate and mirror repository and its wiki
|
||||
- Web editor for repository files and wiki
|
||||
- Gravatar and Federated avatar with custom source
|
||||
- Mail service
|
||||
- Administration panel
|
||||
- Supports MySQL, PostgreSQL, SQLite3 and [TiDB](https://github.com/pingcap/tidb) (experimental)
|
||||
- Multi-language support ([18 languages](https://crowdin.com/project/gogs))
|
||||
- User dashboard, user profile and activity timeline.
|
||||
- Access repositories via SSH, HTTP and HTTPS protocols.
|
||||
- User, organization and repository management.
|
||||
- Repository and organization webhooks, including Slack, Discord and Dingtalk.
|
||||
- Repository Git hooks, deploy keys and Git LFS.
|
||||
- Repository issues, pull requests, wiki, protected branches and collaboration.
|
||||
- Migrate and mirror repositories with wiki from other code hosts.
|
||||
- Web editor for quick editing repository files and wiki.
|
||||
- Jupyter Notebook and PDF rendering.
|
||||
- Authentication via SMTP, LDAP, reverse proxy, GitHub.com and GitHub Enterprise with 2FA.
|
||||
- Customize HTML templates, static files and many others.
|
||||
- Rich database backend support, including PostgreSQL, MySQL, SQLite3 or any database backend that speaks one of those protocols.
|
||||
- Have localization over [31 languages](https://crowdin.com/project/gogs).
|
||||
|
||||
## System Requirements
|
||||
## 💾 Hardware requirements
|
||||
|
||||
- A cheap Raspberry Pi is powerful enough for basic functionality.
|
||||
- 2 CPU cores and 1GB RAM would be the baseline for teamwork.
|
||||
- A Raspberry Pi or $5 Digital Ocean Droplet is more than enough to get you started. Some even use 64MB RAM Docker [CaaS](https://www.docker.com/blog/containers-as-a-service-caas/).
|
||||
- 2 CPU cores and 512MB RAM would be the baseline for teamwork.
|
||||
- Increase CPU cores when your team size gets significantly larger, memory footprint remains low.
|
||||
|
||||
## Browser Support
|
||||
## 💻 Browser support
|
||||
|
||||
- Please see [Semantic UI](https://github.com/Semantic-Org/Semantic-UI#browser-support) for specific versions of supported browsers.
|
||||
- The official support minimal size is **1024*768**, UI may still looks right in smaller size but no promises and fixes.
|
||||
- The smallest resolution officially supported is **1024*768**, however the UI may still look right in smaller resolutions, but no promises or fixes.
|
||||
|
||||
## Installation
|
||||
## 📜 Installation
|
||||
|
||||
Make sure you install the [prerequisites](https://gogs.io/docs/installation) first.
|
||||
Please follow [the guide in our documentation](https://gogs.io/getting-started/installation).
|
||||
|
||||
There are 5 ways to install Gogs:
|
||||
### Deploy to cloud
|
||||
|
||||
- [Install from binary](https://gogs.io/docs/installation/install_from_binary.html)
|
||||
- [Install from source](https://gogs.io/docs/installation/install_from_source.html)
|
||||
- [Install from packages](https://gogs.io/docs/installation/install_from_packages.html)
|
||||
- [Ship with Docker](https://github.com/gogits/gogs/tree/master/docker)
|
||||
- [Install with Vagrant](https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs)
|
||||
- [Cloudron](https://www.cloudron.io/store/io.gogs.cloudronapp.html)
|
||||
- [YunoHost](https://github.com/YunoHost-Apps/gogs_ynh)
|
||||
- [alwaysdata](https://www.alwaysdata.com/en/marketplace/gogs/)
|
||||
|
||||
### Tutorials
|
||||
|
||||
- [Private Git Web Portal in Raspberry PI With Gogs](https://peppe8o.com/private-git-web-portal-in-raspberry-pi-with-gogs/)
|
||||
- [How To Set Up Gogs on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-gogs-on-ubuntu-14-04)
|
||||
- [Run your own GitHub-like service with the help of Docker](http://blog.hypriot.com/post/run-your-own-github-like-service-with-docker/)
|
||||
- [Dockerized Gogs git server and alpine postgres in 20 minutes or less](http://garthwaite.org/docker-gogs.html)
|
||||
- [Host Your Own Private GitHub with Gogs.io](https://eladnava.com/host-your-own-private-github-with-gogs-io/)
|
||||
- [使用 Gogs 搭建自己的 Git 服务器](https://mynook.info/blog/post/host-your-own-git-server-using-gogs) (Chinese)
|
||||
- [阿里云上 Ubuntu 14.04 64 位安装 Gogs](http://my.oschina.net/luyao/blog/375654) (Chinese)
|
||||
- [Run your own GitHub-like service with the help of Docker](https://blog.hypriot.com/post/run-your-own-github-like-service-with-docker/)
|
||||
- [Dockerized Gogs git server and alpine postgres in 20 minutes or less](https://garthwaite.org/docker-gogs.html)
|
||||
- [Host Your Own Private GitHub with Gogs](https://eladnava.com/host-your-own-private-github-with-gogs-io/)
|
||||
- [使用 Gogs 搭建自己的 Git 服务器](https://blog.mynook.info/post/host-your-own-git-server-using-gogs/) (Chinese)
|
||||
- [阿里云上 Ubuntu 14.04 64 位安装 Gogs](https://my.oschina.net/luyao/blog/375654) (Chinese)
|
||||
- [Installing Gogs on FreeBSD](https://www.codejam.info/2015/03/installing-gogs-on-freebsd.html)
|
||||
- [Gogs on Raspberry Pi](http://blog.meinside.pe.kr/Gogs-on-Raspberry-Pi/)
|
||||
- [Cloudflare Full SSL with GOGS (Go Git Service) using NGINX](http://www.listekconsulting.com/articles/cloudflare-full-ssl-with-gogs-go-git-service-using-nginx/)
|
||||
|
||||
### Screencasts
|
||||
|
||||
- [How to install Gogs on a Linux Server (DigitalOcean)](https://www.youtube.com/watch?v=deSfX0gqefE)
|
||||
- [Instalando Gogs no Ubuntu](https://www.youtube.com/watch?v=4UkHAR1F7ZA) (Português)
|
||||
|
||||
### Deploy to Cloud
|
||||
|
||||
- [OpenShift](https://github.com/tkisme/gogs-openshift)
|
||||
- [Cloudron](https://cloudron.io/appstore.html#io.gogs.cloudronapp)
|
||||
- [Scaleway](https://www.scaleway.com/imagehub/gogs/)
|
||||
- [Portal](https://portaldemo.xyz/cloud/)
|
||||
- [Sandstorm](https://github.com/cem/gogs-sandstorm)
|
||||
- [sloppy.io](https://github.com/sloppyio/quickstarters/tree/master/gogs)
|
||||
- [YunoHost](https://github.com/mbugeia/gogs_ynh)
|
||||
- [DPlatform](https://github.com/j8r/DPlatform)
|
||||
|
||||
## Software and Service Support
|
||||
|
||||
- [Drone](https://github.com/drone/drone) (CI)
|
||||
- [Fabric8](http://fabric8.io/) (DevOps)
|
||||
- [Taiga](https://taiga.io/) (Project Management)
|
||||
- [Puppet](https://forge.puppetlabs.com/Siteminds/gogs) (IT)
|
||||
- [Kanboard](http://kanboard.net/plugin/gogs-webhook) (Project Management)
|
||||
- [BearyChat](https://bearychat.com/) (Team Communication)
|
||||
- [HiWork](http://www.hiwork.cc/) (Team Communication)
|
||||
|
||||
### Product Support
|
||||
## 📦 Software, service and product support
|
||||
|
||||
- [Jenkins](https://plugins.jenkins.io/gogs-webhook/) (CI)
|
||||
- [Puppet](https://forge.puppet.com/modules/Siteminds/gogs) (IT)
|
||||
- [Synology](https://www.synology.com) (Docker)
|
||||
- [One Space](http://www.onespace.cc) (App Store)
|
||||
- [Syncloud](https://syncloud.org/) (App Store)
|
||||
|
||||
## Acknowledgments
|
||||
## 🙇♂️ Acknowledgments
|
||||
|
||||
- Router and middleware mechanism of [Macaron](https://github.com/go-macaron/macaron).
|
||||
- System Monitor Status is inspired by [GoBlog](https://github.com/fuxiaohei/goblog).
|
||||
- Thanks [Rocker](http://weibo.com/rocker1989) for designing Logo.
|
||||
- Thanks [Crowdin](https://crowdin.com/project/gogs) for providing open source translation plan.
|
||||
- Thanks [DigitalOcean](https://www.digitalocean.com) for hosting home and demo sites.
|
||||
- Thanks [KeyCDN](https://www.keycdn.com/) and [QiNiu](http://www.qiniu.com/) for providing CDN service.
|
||||
<p>This project is proudly supported by:</p>
|
||||
<p>
|
||||
<a href="https://m.do.co/c/5aeb02268b55">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" width="201px">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Contributors
|
||||
Other acknowledgments:
|
||||
|
||||
- Ex-team members [@lunny](https://github.com/lunny), [@fuxiaohei](https://github.com/fuxiaohei) and [@slene](https://github.com/slene).
|
||||
- See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors.
|
||||
- Thanks [Egon Elbre](https://twitter.com/egonelbre) for designing the original version of the logo.
|
||||
- Thanks [Mintlify](https://mintlify.com) for sponsoring open source documentation plan.
|
||||
- Thanks [Crowdin](https://crowdin.com) for sponsoring open source translation plan.
|
||||
- Thanks [Buildkite](https://buildkite.com) for sponsoring open source CI/CD plan.
|
||||
|
||||
## 👋 Contributors
|
||||
|
||||
- See [contributors page](https://github.com/gogs/gogs/graphs/contributors) for top 100 contributors.
|
||||
- See [TRANSLATORS](conf/locale/TRANSLATORS) for public list of translators.
|
||||
|
||||
## License
|
||||
## ⚖️ License
|
||||
|
||||
This project is under the MIT License. See the [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) file for the full license text.
|
||||
This project is under the MIT License. See the [LICENSE](https://github.com/gogs/gogs/blob/main/LICENSE) file for the full license text.
|
||||
|
||||
107
README_ZH.md
107
README_ZH.md
@@ -1,107 +0,0 @@
|
||||
Gogs - Go Git Service [](https://travis-ci.org/gogits/gogs)
|
||||
=====================
|
||||
|
||||
Gogs (Go Git Service) 是一款极易搭建的自助 Git 服务。
|
||||
|
||||
## 开发目的
|
||||
|
||||
Gogs 的目标是打造一个最简单、最快速和最轻松的方式搭建自助 Git 服务。使用 Go 语言开发使得 Gogs 能够通过独立的二进制分发,并且支持 Go 语言支持的 **所有平台**,包括 Linux、Mac OS X、Windows 以及 ARM 平台。
|
||||
|
||||
## 项目概览
|
||||
|
||||
- 有关基本用法和变更日志,请通过 [使用手册](https://gogs.io/docs/intro/) 查看。
|
||||
- 您可以到 [Trello Board](https://trello.com/b/uxAoeLUl/gogs-go-git-service) 跟随开发团队的脚步。
|
||||
- 想要先睹为快?直接去 [在线体验](https://try.gogs.io/gogs/gogs) 。
|
||||
- 使用过程中遇到问题?尝试从 [故障排查](https://gogs.io/docs/intro/troubleshooting.html) 页面或 [用户论坛](https://discuss.gogs.io/) 获取帮助。
|
||||
- 希望帮助多国语言界面的翻译吗?请立即访问 [详情页面](https://gogs.io/docs/features/i18n.html)!
|
||||
|
||||
## 功能特性
|
||||
|
||||
- 支持活动时间线
|
||||
- 支持 SSH 以及 HTTP/HTTPS 协议
|
||||
- 支持 SMTP、LDAP 和反向代理的用户认证
|
||||
- 支持反向代理子路径
|
||||
- 支持用户、组织和仓库管理系统
|
||||
- 支持添加和删除仓库协作者
|
||||
- 支持仓库和组织级别 Web 钩子(包括 Slack 集成)
|
||||
- 支持仓库 Git 钩子和部署密钥
|
||||
- 支持仓库工单(Issue)、合并请求(Pull Request)以及 Wiki
|
||||
- 支持迁移和镜像仓库以及它的 Wiki
|
||||
- 支持在线编辑仓库文件和 Wiki
|
||||
- 支持自定义源的 Gravatar 和 Federated Avatar
|
||||
- 支持邮件服务
|
||||
- 支持后台管理面板
|
||||
- 支持 MySQL、PostgreSQL、SQLite3 和 [TiDB](https://github.com/pingcap/tidb)(实验性支持) 数据库
|
||||
- 支持多语言本地化([18 种语言]([more](https://crowdin.com/project/gogs)))
|
||||
|
||||
## 系统要求
|
||||
|
||||
- 最低的系统硬件要求为一个廉价的树莓派
|
||||
- 如果用于团队项目,建议使用 2 核 CPU 及 1GB 内存
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
- 请根据 [Semantic UI](https://github.com/Semantic-Org/Semantic-UI#browser-support) 查看具体支持的浏览器版本。
|
||||
- 官方支持的最小 UI 尺寸为 **1024*768**,UI 不一定会在更小尺寸的设备上被破坏,但我们无法保证且不会修复。
|
||||
|
||||
## 安装部署
|
||||
|
||||
在安装 Gogs 之前,您需要先安装 [基本环境](https://gogs.io/docs/installation)。
|
||||
|
||||
然后,您可以通过以下 5 种方式来安装 Gogs:
|
||||
|
||||
- [二进制安装](https://gogs.io/docs/installation/install_from_binary.html)
|
||||
- [源码安装](https://gogs.io/docs/installation/install_from_source.html)
|
||||
- [包管理安装](https://gogs.io/docs/installation/install_from_packages.html)
|
||||
- [采用 Docker 部署](https://github.com/gogits/gogs/tree/master/docker)
|
||||
- [通过 Vagrant 安装](https://github.com/geerlingguy/ansible-vagrant-examples/tree/master/gogs)
|
||||
|
||||
### 使用教程
|
||||
|
||||
- [使用 Gogs 搭建自己的 Git 服务器](https://mynook.info/blog/post/host-your-own-git-server-using-gogs)
|
||||
- [阿里云上 Ubuntu 14.04 64 位安装 Gogs](http://my.oschina.net/luyao/blog/375654)
|
||||
|
||||
### 云端部署
|
||||
|
||||
- [OpenShift](https://github.com/tkisme/gogs-openshift)
|
||||
- [Cloudron](https://cloudron.io/appstore.html#io.gogs.cloudronapp)
|
||||
- [Scaleway](https://www.scaleway.com/imagehub/gogs/)
|
||||
- [Portal](https://portaldemo.xyz/cloud/)
|
||||
- [Sandstorm](https://github.com/cem/gogs-sandstorm)
|
||||
- [sloppy.io](https://github.com/sloppyio/quickstarters/tree/master/gogs)
|
||||
- [YunoHost](https://github.com/mbugeia/gogs_ynh)
|
||||
- [DPlatform](https://github.com/j8r/DPlatform)
|
||||
|
||||
## 软件及服务支持
|
||||
|
||||
- [Drone](https://github.com/drone/drone)(CI)
|
||||
- [Fabric8](http://fabric8.io/)(DevOps)
|
||||
- [Taiga](https://taiga.io/)(项目管理)
|
||||
- [Puppet](https://forge.puppetlabs.com/Siteminds/gogs)(IT)
|
||||
- [Kanboard](http://kanboard.net/plugin/gogs-webhook)(项目管理)
|
||||
- [BearyChat](https://bearychat.com/)(团队交流)
|
||||
- [HiWork](http://www.hiwork.cc/)(团队交流)
|
||||
|
||||
### 产品支持
|
||||
|
||||
- [Synology](https://www.synology.com)(Docker)
|
||||
- [One Space](http://www.onespace.cc)(应用商店)
|
||||
|
||||
## 特别鸣谢
|
||||
|
||||
- 基于 [Macaron](https://github.com/go-macaron/macaron) 的路由与中间件机制。
|
||||
- 基于 [GoBlog](https://github.com/fuxiaohei/goblog) 修改的系统监视状态。
|
||||
- 感谢 [Rocker](http://weibo.com/rocker1989) 设计的 Logo。
|
||||
- 感谢 [Crowdin](https://crowdin.com/project/gogs) 提供免费的开源项目本地化支持。
|
||||
- 感谢 [DigitalOcean](https://www.digitalocean.com) 提供主站和体验站点的服务器赞助。
|
||||
- 感谢 [KeyCDN](https://www.keycdn.com/) 和 [七牛云存储](http://www.qiniu.com/) 提供 CDN 服务赞助。
|
||||
|
||||
## 贡献成员
|
||||
|
||||
- 前团队成员 [@lunny](https://github.com/lunny)、[@fuxiaohei](https://github.com/fuxiaohei) 和 [@slene](https://github.com/slene)。
|
||||
- 您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。
|
||||
- 您可以通过查看 [TRANSLATORS](conf/locale/TRANSLATORS) 文件获取公开的翻译人员列表。
|
||||
|
||||
## 授权许可
|
||||
|
||||
本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) 文件中。
|
||||
27
SECURITY.md
Normal file
27
SECURITY.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Security policy
|
||||
|
||||
## Supported versions
|
||||
|
||||
Only the latest minor version releases are supported (e.g., 0.14) for patching vulnerabilities. You can find the latest minor version in the [GitHub releases](https://github.com/gogs/gogs/releases) page.
|
||||
|
||||
Existing vulnerability reports are being tracked in [GitHub Security Advisories](https://github.com/gogs/gogs/security/advisories). Not all accepted GHSA are published.
|
||||
|
||||
## Vulnerability lifecycle
|
||||
|
||||
> [!important]
|
||||
> Starting **Nov 9, 2023 00:00 UTC**, only security vulnerabilities reported through [GitHub Security Advisories](https://github.com/gogs/gogs/security/advisories/new) are accepted.
|
||||
> Pre-existing vulnerability reported through https://huntr.dev/ or email (`security@gogs.io`) will continue to be worked through.
|
||||
|
||||
1. Report an advisory for the vulnerability.
|
||||
- Please be aware that **only advisories reported in plain English** will be reviewed.
|
||||
- We DO NOT accept vulnerabilities cannot be reproduced on the latest `main` commit.
|
||||
1. Project maintainers review the advisory:
|
||||
- Ask clarifying questions
|
||||
- Make sure there was no prior advisory exists for the same vulnerability
|
||||
- Confirm or deny the vulnerability
|
||||
1. Once the advisory is accepted, the reporter may submit a patch or wait for project maintainers to patch.
|
||||
- The latter is usually significantly slower.
|
||||
1. Patch releases will be made for the supported versions.
|
||||
1. After 14 days of the release, publish the corresponding advisory on [GitHub Security Advisories](https://github.com/gogs/gogs/security/advisories).
|
||||
|
||||
Thank you for making open source community a better place!
|
||||
99
Taskfile.yml
Normal file
99
Taskfile.yml
Normal file
@@ -0,0 +1,99 @@
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
BINARY_EXT:
|
||||
sh: echo '{{if eq OS "windows"}}.exe{{end}}'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
deps: [build]
|
||||
web:
|
||||
desc: Build the binary and start the web server
|
||||
deps: [build]
|
||||
cmds:
|
||||
- .bin/gogs web
|
||||
|
||||
build:
|
||||
desc: Build the binary
|
||||
cmds:
|
||||
- go build -v
|
||||
-ldflags '
|
||||
-X "{{.PKG_PATH}}.BuildTime={{.BUILD_TIME}}"
|
||||
-X "{{.PKG_PATH}}.BuildCommit={{.BUILD_COMMIT}}"
|
||||
'
|
||||
-tags '{{.TAGS}}'
|
||||
-trimpath -o .bin/gogs{{.BINARY_EXT}} ./cmd/gogs
|
||||
vars:
|
||||
PKG_PATH: gogs.io/gogs/internal/conf
|
||||
BUILD_TIME:
|
||||
sh: date -u '+%Y-%m-%d %I:%M:%S %Z'
|
||||
BUILD_COMMIT:
|
||||
sh: git rev-parse HEAD
|
||||
sources:
|
||||
- go.mod
|
||||
- cmd/gogs/*.go
|
||||
- internal/**/*.go
|
||||
- conf/**/*
|
||||
- public/**/*
|
||||
- templates/**/*
|
||||
- custom/**/*
|
||||
method: timestamp
|
||||
|
||||
generate-schemadoc:
|
||||
desc: Generate database schema documentation
|
||||
cmds:
|
||||
- go generate ./internal/database/schemadoc
|
||||
|
||||
generate:
|
||||
desc: Run all go:generate commands
|
||||
cmds:
|
||||
- go generate ./...
|
||||
|
||||
test:
|
||||
desc: Run all tests.
|
||||
cmds:
|
||||
- go test -cover -race ./...
|
||||
|
||||
clean:
|
||||
desc: Cleans up system meta files
|
||||
cmds:
|
||||
- find . -name "*.DS_Store" -type f -delete
|
||||
|
||||
less:
|
||||
desc: Generate CSS from LESS files
|
||||
cmds:
|
||||
- lessc --clean-css --source-map "public/less/gogs.less" public/css/gogs.min.css
|
||||
|
||||
fixme:
|
||||
desc: Show all occurrences of "FIXME"
|
||||
cmds:
|
||||
- grep -rnw "FIXME" internal
|
||||
|
||||
todo:
|
||||
desc: Show all occurrences of "TODO"
|
||||
cmds:
|
||||
- grep -rnw "TODO" internal
|
||||
|
||||
legacy:
|
||||
desc: Identify legacy and deprecated lines
|
||||
cmds:
|
||||
- grep -rnw "\(LEGACY\|Deprecated\)" internal
|
||||
|
||||
drop-test-db:
|
||||
desc: Drop the test database
|
||||
cmds:
|
||||
- |
|
||||
for dbname in $(psql -Xc "copy (select datname from pg_database where datname like 'gogs-%') to stdout"); do
|
||||
dropdb "$dbname"
|
||||
echo "dropped $dbname"
|
||||
done
|
||||
|
||||
lint:
|
||||
desc: Run all linters
|
||||
cmds:
|
||||
- golangci-lint run
|
||||
|
||||
docs:
|
||||
desc: Start docs server
|
||||
cmds:
|
||||
- cd docs && mint dev --port 3333
|
||||
70
cmd/admin.go
70
cmd/admin.go
@@ -1,70 +0,0 @@
|
||||
// Copyright 2016 The Gogs 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 (
|
||||
"fmt"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
var (
|
||||
CmdAdmin = cli.Command{
|
||||
Name: "admin",
|
||||
Usage: "Preform admin operations on command line",
|
||||
Description: `Allow using internal logic of Gogs without hacking into the source code
|
||||
to make automatic initialization process more smoothly`,
|
||||
Subcommands: []cli.Command{
|
||||
subcmdCreateUser,
|
||||
},
|
||||
}
|
||||
|
||||
subcmdCreateUser = cli.Command{
|
||||
Name: "create-user",
|
||||
Usage: "Create a new user in database",
|
||||
Action: runCreateUser,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("name", "", "Username"),
|
||||
stringFlag("password", "", "User password"),
|
||||
stringFlag("email", "", "User email address"),
|
||||
boolFlag("admin", "User is an admin"),
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func runCreateUser(c *cli.Context) error {
|
||||
if !c.IsSet("name") {
|
||||
return fmt.Errorf("Username is not specified")
|
||||
} else if !c.IsSet("password") {
|
||||
return fmt.Errorf("Password is not specified")
|
||||
} else if !c.IsSet("email") {
|
||||
return fmt.Errorf("Email is not specified")
|
||||
}
|
||||
|
||||
if c.IsSet("config") {
|
||||
setting.CustomConf = c.String("config")
|
||||
}
|
||||
|
||||
setting.NewContext()
|
||||
models.LoadConfigs()
|
||||
models.SetEngine()
|
||||
|
||||
if err := models.CreateUser(&models.User{
|
||||
Name: c.String("name"),
|
||||
Email: c.String("email"),
|
||||
Passwd: c.String("password"),
|
||||
IsActive: true,
|
||||
IsAdmin: c.Bool("admin"),
|
||||
}); err != nil {
|
||||
return fmt.Errorf("CreateUser: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("New user '%s' has been successfully created!\n", c.String("name"))
|
||||
return nil
|
||||
}
|
||||
163
cmd/cert.go
163
cmd/cert.go
@@ -1,163 +0,0 @@
|
||||
// +build cert
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2014 The Gogs 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/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"log"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var CmdCert = cli.Command{
|
||||
Name: "cert",
|
||||
Usage: "Generate self-signed certificate",
|
||||
Description: `Generate a self-signed X.509 certificate for a TLS server.
|
||||
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
|
||||
Action: runCert,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("host", "", "Comma-separated hostnames and IPs to generate a certificate for"),
|
||||
stringFlag("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521"),
|
||||
intFlag("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set"),
|
||||
stringFlag("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011"),
|
||||
durationFlag("duration", 365*24*time.Hour, "Duration that certificate is valid for"),
|
||||
boolFlag("ca", "whether this cert should be its own Certificate Authority"),
|
||||
},
|
||||
}
|
||||
|
||||
func publicKey(priv interface{}) interface{} {
|
||||
switch k := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return &k.PublicKey
|
||||
case *ecdsa.PrivateKey:
|
||||
return &k.PublicKey
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func pemBlockForKey(priv interface{}) *pem.Block {
|
||||
switch k := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
|
||||
case *ecdsa.PrivateKey:
|
||||
b, err := x509.MarshalECPrivateKey(k)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to marshal ECDSA private key: %v\n", err)
|
||||
}
|
||||
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func runCert(ctx *cli.Context) error {
|
||||
if len(ctx.String("host")) == 0 {
|
||||
log.Fatal("Missing required --host parameter")
|
||||
}
|
||||
|
||||
var priv interface{}
|
||||
var err error
|
||||
switch ctx.String("ecdsa-curve") {
|
||||
case "":
|
||||
priv, err = rsa.GenerateKey(rand.Reader, ctx.Int("rsa-bits"))
|
||||
case "P224":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
||||
case "P256":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
case "P384":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
case "P521":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
default:
|
||||
log.Fatalf("Unrecognized elliptic curve: %q", ctx.String("ecdsa-curve"))
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate private key: %s", err)
|
||||
}
|
||||
|
||||
var notBefore time.Time
|
||||
if len(ctx.String("start-date")) == 0 {
|
||||
notBefore = time.Now()
|
||||
} else {
|
||||
notBefore, err = time.Parse("Jan 2 15:04:05 2006", ctx.String("start-date"))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse creation date: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
notAfter := notBefore.Add(ctx.Duration("duration"))
|
||||
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate serial number: %s", err)
|
||||
}
|
||||
|
||||
template := x509.Certificate{
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"Acme Co"},
|
||||
CommonName: "Gogs",
|
||||
},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
hosts := strings.Split(ctx.String("host"), ",")
|
||||
for _, h := range hosts {
|
||||
if ip := net.ParseIP(h); ip != nil {
|
||||
template.IPAddresses = append(template.IPAddresses, ip)
|
||||
} else {
|
||||
template.DNSNames = append(template.DNSNames, h)
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.Bool("ca") {
|
||||
template.IsCA = true
|
||||
template.KeyUsage |= x509.KeyUsageCertSign
|
||||
}
|
||||
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create certificate: %s", err)
|
||||
}
|
||||
|
||||
certOut, err := os.Create("cert.pem")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open cert.pem for writing: %s", err)
|
||||
}
|
||||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||
certOut.Close()
|
||||
log.Println("Written cert.pem")
|
||||
|
||||
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to open key.pem for writing: %v\n", err)
|
||||
}
|
||||
pem.Encode(keyOut, pemBlockForKey(priv))
|
||||
keyOut.Close()
|
||||
log.Println("Written key.pem")
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// +build !cert
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2014 The Gogs 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 (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var CmdCert = cli.Command{
|
||||
Name: "cert",
|
||||
Usage: "Generate self-signed certificate",
|
||||
Description: `Please use build tags "cert" to rebuild Gogs in order to have this ability`,
|
||||
Action: runCert,
|
||||
}
|
||||
|
||||
func runCert(ctx *cli.Context) error {
|
||||
fmt.Println("Command cert not available, please use build tags 'cert' to rebuild.")
|
||||
os.Exit(1)
|
||||
|
||||
return nil
|
||||
}
|
||||
42
cmd/cmd.go
42
cmd/cmd.go
@@ -1,42 +0,0 @@
|
||||
// Copyright 2015 The Gogs 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 (
|
||||
"time"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func stringFlag(name, value, usage string) cli.StringFlag {
|
||||
return cli.StringFlag{
|
||||
Name: name,
|
||||
Value: value,
|
||||
Usage: usage,
|
||||
}
|
||||
}
|
||||
|
||||
func boolFlag(name, usage string) cli.BoolFlag {
|
||||
return cli.BoolFlag{
|
||||
Name: name,
|
||||
Usage: usage,
|
||||
}
|
||||
}
|
||||
|
||||
func intFlag(name string, value int, usage string) cli.IntFlag {
|
||||
return cli.IntFlag{
|
||||
Name: name,
|
||||
Value: value,
|
||||
Usage: usage,
|
||||
}
|
||||
}
|
||||
|
||||
func durationFlag(name string, value time.Duration, usage string) cli.DurationFlag {
|
||||
return cli.DurationFlag{
|
||||
Name: name,
|
||||
Value: value,
|
||||
Usage: usage,
|
||||
}
|
||||
}
|
||||
108
cmd/dump.go
108
cmd/dump.go
@@ -1,108 +0,0 @@
|
||||
// Copyright 2014 The Gogs 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 (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/Unknwon/cae/zip"
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
var CmdDump = cli.Command{
|
||||
Name: "dump",
|
||||
Usage: "Dump Gogs files and database",
|
||||
Description: `Dump compresses all related files and database into zip file.
|
||||
It can be used for backup and capture Gogs server image to send to maintainer`,
|
||||
Action: runDump,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
boolFlag("verbose, v", "Show process details"),
|
||||
stringFlag("tempdir, t", os.TempDir(), "Temporary dir path"),
|
||||
},
|
||||
}
|
||||
|
||||
func runDump(ctx *cli.Context) error {
|
||||
if ctx.IsSet("config") {
|
||||
setting.CustomConf = ctx.String("config")
|
||||
}
|
||||
setting.NewContext()
|
||||
models.LoadConfigs()
|
||||
models.SetEngine()
|
||||
|
||||
tmpDir := ctx.String("tempdir")
|
||||
if _, err := os.Stat(tmpDir); os.IsNotExist(err) {
|
||||
log.Fatalf("Path does not exist: %s", tmpDir)
|
||||
}
|
||||
TmpWorkDir, err := ioutil.TempDir(tmpDir, "gogs-dump-")
|
||||
if err != nil {
|
||||
log.Fatalf("Fail to create tmp work directory: %v", err)
|
||||
}
|
||||
log.Printf("Creating tmp work dir: %s", TmpWorkDir)
|
||||
|
||||
reposDump := path.Join(TmpWorkDir, "gogs-repo.zip")
|
||||
dbDump := path.Join(TmpWorkDir, "gogs-db.sql")
|
||||
|
||||
log.Printf("Dumping local repositories...%s", setting.RepoRootPath)
|
||||
zip.Verbose = ctx.Bool("verbose")
|
||||
if err := zip.PackTo(setting.RepoRootPath, reposDump, true); err != nil {
|
||||
log.Fatalf("Fail to dump local repositories: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("Dumping database...")
|
||||
if err := models.DumpDatabase(dbDump); err != nil {
|
||||
log.Fatalf("Fail to dump database: %v", err)
|
||||
}
|
||||
|
||||
fileName := fmt.Sprintf("gogs-dump-%d.zip", time.Now().Unix())
|
||||
log.Printf("Packing dump files...")
|
||||
z, err := zip.Create(fileName)
|
||||
if err != nil {
|
||||
os.Remove(fileName)
|
||||
log.Fatalf("Fail to create %s: %v", fileName, err)
|
||||
}
|
||||
|
||||
if err := z.AddFile("gogs-repo.zip", reposDump); err != nil {
|
||||
log.Fatalf("Fail to include gogs-repo.zip: %v", err)
|
||||
}
|
||||
if err := z.AddFile("gogs-db.sql", dbDump); err != nil {
|
||||
log.Fatalf("Fail to include gogs-db.sql: %v", err)
|
||||
}
|
||||
customDir, err := os.Stat(setting.CustomPath)
|
||||
if err == nil && customDir.IsDir() {
|
||||
if err := z.AddDir("custom", setting.CustomPath); err != nil {
|
||||
log.Fatalf("Fail to include custom: %v", err)
|
||||
}
|
||||
} else {
|
||||
log.Printf("Custom dir %s doesn't exist, skipped", setting.CustomPath)
|
||||
}
|
||||
if err := z.AddDir("log", setting.LogRootPath); err != nil {
|
||||
log.Fatalf("Fail to include log: %v", err)
|
||||
}
|
||||
// FIXME: SSH key file.
|
||||
if err = z.Close(); err != nil {
|
||||
os.Remove(fileName)
|
||||
log.Fatalf("Fail to save %s: %v", fileName, err)
|
||||
}
|
||||
|
||||
if err := os.Chmod(fileName, 0600); err != nil {
|
||||
log.Printf("Can't change file access permissions mask to 0600: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("Removing tmp work dir: %s", TmpWorkDir)
|
||||
os.RemoveAll(TmpWorkDir)
|
||||
log.Printf("Finish dumping in file %s", fileName)
|
||||
|
||||
return nil
|
||||
}
|
||||
189
cmd/gogs/admin.go
Normal file
189
cmd/gogs/admin.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/database"
|
||||
)
|
||||
|
||||
var (
|
||||
adminCommand = cli.Command{
|
||||
Name: "admin",
|
||||
Usage: "Perform admin operations on command line",
|
||||
Description: `Allow using internal logic of Gogs without hacking into the source code
|
||||
to make automatic initialization process more smoothly`,
|
||||
Commands: []*cli.Command{
|
||||
&subcmdCreateUser,
|
||||
&subcmdDeleteInactivateUsers,
|
||||
&subcmdDeleteRepositoryArchives,
|
||||
&subcmdDeleteMissingRepositories,
|
||||
&subcmdGitGcRepos,
|
||||
&subcmdRewriteAuthorizedKeys,
|
||||
&subcmdSyncRepositoryHooks,
|
||||
&subcmdReinitMissingRepositories,
|
||||
},
|
||||
}
|
||||
|
||||
subcmdCreateUser = cli.Command{
|
||||
Name: "create-user",
|
||||
Usage: "Create a new user in database",
|
||||
Action: runCreateUser,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("name", "", "Username"),
|
||||
stringFlag("password", "", "User password"),
|
||||
stringFlag("email", "", "User email address"),
|
||||
boolFlag("admin", "User is an admin"),
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
subcmdDeleteInactivateUsers = cli.Command{
|
||||
Name: "delete-inactive-users",
|
||||
Usage: "Delete all inactive accounts",
|
||||
Action: adminDashboardOperation(
|
||||
func() error { return database.Handle.Users().DeleteInactivated() },
|
||||
"All inactivated accounts have been deleted successfully",
|
||||
),
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
subcmdDeleteRepositoryArchives = cli.Command{
|
||||
Name: "delete-repository-archives",
|
||||
Usage: "Delete all repositories archives",
|
||||
Action: adminDashboardOperation(
|
||||
database.DeleteRepositoryArchives,
|
||||
"All repositories archives have been deleted successfully",
|
||||
),
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
subcmdDeleteMissingRepositories = cli.Command{
|
||||
Name: "delete-missing-repositories",
|
||||
Usage: "Delete all repository records that lost Git files",
|
||||
Action: adminDashboardOperation(
|
||||
database.DeleteMissingRepositories,
|
||||
"All repositories archives have been deleted successfully",
|
||||
),
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
subcmdGitGcRepos = cli.Command{
|
||||
Name: "collect-garbage",
|
||||
Usage: "Do garbage collection on repositories",
|
||||
Action: adminDashboardOperation(
|
||||
database.GitGcRepos,
|
||||
"All repositories have done garbage collection successfully",
|
||||
),
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
subcmdRewriteAuthorizedKeys = cli.Command{
|
||||
Name: "rewrite-authorized-keys",
|
||||
Usage: "Rewrite '.ssh/authorized_keys' file (caution: non-Gogs keys will be lost)",
|
||||
Action: adminDashboardOperation(
|
||||
database.RewriteAuthorizedKeys,
|
||||
"All public keys have been rewritten successfully",
|
||||
),
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
subcmdSyncRepositoryHooks = cli.Command{
|
||||
Name: "resync-hooks",
|
||||
Usage: "Resync pre-receive, update and post-receive hooks",
|
||||
Action: adminDashboardOperation(
|
||||
database.SyncRepositoryHooks,
|
||||
"All repositories' pre-receive, update and post-receive hooks have been resynced successfully",
|
||||
),
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
subcmdReinitMissingRepositories = cli.Command{
|
||||
Name: "reinit-missing-repositories",
|
||||
Usage: "Reinitialize all repository records that lost Git files",
|
||||
Action: adminDashboardOperation(
|
||||
database.ReinitMissingRepositories,
|
||||
"All repository records that lost Git files have been reinitialized successfully",
|
||||
),
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func runCreateUser(ctx context.Context, cmd *cli.Command) error {
|
||||
if !cmd.IsSet("name") {
|
||||
return errors.New("Username is not specified")
|
||||
} else if !cmd.IsSet("password") {
|
||||
return errors.New("Password is not specified")
|
||||
} else if !cmd.IsSet("email") {
|
||||
return errors.New("Email is not specified")
|
||||
}
|
||||
|
||||
err := conf.Init(configFromLineage(cmd))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "init configuration")
|
||||
}
|
||||
conf.InitLogging(true)
|
||||
|
||||
if _, err = database.SetEngine(); err != nil {
|
||||
return errors.Wrap(err, "set engine")
|
||||
}
|
||||
|
||||
user, err := database.Handle.Users().Create(
|
||||
ctx,
|
||||
cmd.String("name"),
|
||||
cmd.String("email"),
|
||||
database.CreateUserOptions{
|
||||
Password: cmd.String("password"),
|
||||
Activated: true,
|
||||
Admin: cmd.Bool("admin"),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "create user")
|
||||
}
|
||||
|
||||
fmt.Printf("New user %q has been successfully created!\n", user.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func adminDashboardOperation(operation func() error, successMessage string) func(context.Context, *cli.Command) error {
|
||||
return func(_ context.Context, cmd *cli.Command) error {
|
||||
err := conf.Init(configFromLineage(cmd))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "init configuration")
|
||||
}
|
||||
conf.InitLogging(true)
|
||||
|
||||
if _, err = database.SetEngine(); err != nil {
|
||||
return errors.Wrap(err, "set engine")
|
||||
}
|
||||
|
||||
if err := operation(); err != nil {
|
||||
functionName := runtime.FuncForPC(reflect.ValueOf(operation).Pointer()).Name()
|
||||
return errors.Newf("%s: %v", functionName, err)
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", successMessage)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
194
cmd/gogs/backup.go
Normal file
194
cmd/gogs/backup.go
Normal file
@@ -0,0 +1,194 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/unknwon/cae/zip"
|
||||
"github.com/urfave/cli/v3"
|
||||
"gopkg.in/ini.v1"
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/database"
|
||||
"gogs.io/gogs/internal/osx"
|
||||
)
|
||||
|
||||
var backupCommand = cli.Command{
|
||||
Name: "backup",
|
||||
Usage: "Backup files and database",
|
||||
Description: `Backup dumps and compresses all related files and database into zip file,
|
||||
which can be used for migrating Gogs to another server. The output format is meant to be
|
||||
portable among all supported database engines.`,
|
||||
Action: runBackup,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
boolFlag("verbose, v", "Show process details"),
|
||||
stringFlag("tempdir, t", os.TempDir(), "Temporary directory path"),
|
||||
stringFlag("target", "./", "Target directory path to save backup archive"),
|
||||
stringFlag("archive-name", fmt.Sprintf("gogs-backup-%s.zip", time.Now().Format("20060102150405")), "Name of backup archive"),
|
||||
boolFlag("database-only", "Only dump database"),
|
||||
boolFlag("exclude-mirror-repos", "Exclude mirror repositories"),
|
||||
boolFlag("exclude-repos", "Exclude repositories"),
|
||||
},
|
||||
}
|
||||
|
||||
const (
|
||||
currentBackupFormatVersion = 1
|
||||
archiveRootDir = "gogs-backup"
|
||||
)
|
||||
|
||||
func runBackup(ctx context.Context, cmd *cli.Command) error {
|
||||
zip.Verbose = cmd.Bool("verbose")
|
||||
|
||||
err := conf.Init(configFromLineage(cmd))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "init configuration")
|
||||
}
|
||||
conf.InitLogging(true)
|
||||
|
||||
conn, err := database.SetEngine()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "set engine")
|
||||
}
|
||||
|
||||
tmpDir := cmd.String("tempdir")
|
||||
if !osx.Exist(tmpDir) {
|
||||
log.Fatal("'--tempdir' does not exist: %s", tmpDir)
|
||||
}
|
||||
rootDir, err := os.MkdirTemp(tmpDir, "gogs-backup-")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to create backup root directory '%s': %v", rootDir, err)
|
||||
}
|
||||
log.Info("Backup root directory: %s", rootDir)
|
||||
|
||||
// Metadata
|
||||
metaFile := path.Join(rootDir, "metadata.ini")
|
||||
metadata := ini.Empty()
|
||||
metadata.Section("").Key("VERSION").SetValue(strconv.Itoa(currentBackupFormatVersion))
|
||||
metadata.Section("").Key("DATE_TIME").SetValue(time.Now().String())
|
||||
metadata.Section("").Key("GOGS_VERSION").SetValue(conf.App.Version)
|
||||
if err = metadata.SaveTo(metaFile); err != nil {
|
||||
log.Fatal("Failed to save metadata '%s': %v", metaFile, err)
|
||||
}
|
||||
|
||||
archiveName := filepath.Join(cmd.String("target"), cmd.String("archive-name"))
|
||||
log.Info("Packing backup files to: %s", archiveName)
|
||||
|
||||
z, err := zip.Create(archiveName)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to create backup archive '%s': %v", archiveName, err)
|
||||
}
|
||||
if err = z.AddFile(archiveRootDir+"/metadata.ini", metaFile); err != nil {
|
||||
log.Fatal("Failed to include 'metadata.ini': %v", err)
|
||||
}
|
||||
|
||||
// Database
|
||||
dbDir := filepath.Join(rootDir, "db")
|
||||
if err = database.DumpDatabase(ctx, conn, dbDir, cmd.Bool("verbose")); err != nil {
|
||||
log.Fatal("Failed to dump database: %v", err)
|
||||
}
|
||||
if err = z.AddDir(archiveRootDir+"/db", dbDir); err != nil {
|
||||
log.Fatal("Failed to include 'db': %v", err)
|
||||
}
|
||||
|
||||
if !cmd.Bool("database-only") {
|
||||
// Custom files
|
||||
err = addCustomDirToBackup(z)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to add custom directory to backup: %v", err)
|
||||
}
|
||||
|
||||
// Data files
|
||||
for _, dir := range []string{"ssh", "attachments", "avatars", "repo-avatars"} {
|
||||
dirPath := filepath.Join(conf.Server.AppDataPath, dir)
|
||||
if !osx.IsDir(dirPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err = z.AddDir(path.Join(archiveRootDir+"/data", dir), dirPath); err != nil {
|
||||
log.Fatal("Failed to include 'data': %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repositories
|
||||
if !cmd.Bool("exclude-repos") && !cmd.Bool("database-only") {
|
||||
reposDump := filepath.Join(rootDir, "repositories.zip")
|
||||
log.Info("Dumping repositories in %q", conf.Repository.Root)
|
||||
if cmd.Bool("exclude-mirror-repos") {
|
||||
repos, err := database.GetNonMirrorRepositories()
|
||||
if err != nil {
|
||||
log.Fatal("Failed to get non-mirror repositories: %v", err)
|
||||
}
|
||||
reposZip, err := zip.Create(reposDump)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to create %q: %v", reposDump, err)
|
||||
}
|
||||
baseDir := filepath.Base(conf.Repository.Root)
|
||||
for _, r := range repos {
|
||||
name := r.FullName() + ".git"
|
||||
if err := reposZip.AddDir(filepath.Join(baseDir, name), filepath.Join(conf.Repository.Root, name)); err != nil {
|
||||
log.Fatal("Failed to add %q: %v", name, err)
|
||||
}
|
||||
}
|
||||
if err = reposZip.Close(); err != nil {
|
||||
log.Fatal("Failed to save %q: %v", reposDump, err)
|
||||
}
|
||||
} else {
|
||||
if err = zip.PackTo(conf.Repository.Root, reposDump, true); err != nil {
|
||||
log.Fatal("Failed to dump repositories: %v", err)
|
||||
}
|
||||
}
|
||||
log.Info("Repositories dumped to: %s", reposDump)
|
||||
|
||||
if err = z.AddFile(archiveRootDir+"/repositories.zip", reposDump); err != nil {
|
||||
log.Fatal("Failed to include %q: %v", reposDump, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = z.Close(); err != nil {
|
||||
log.Fatal("Failed to save backup archive '%s': %v", archiveName, err)
|
||||
}
|
||||
|
||||
_ = os.RemoveAll(rootDir)
|
||||
log.Info("Backup succeed! Archive is located at: %s", archiveName)
|
||||
log.Stop()
|
||||
return nil
|
||||
}
|
||||
|
||||
func addCustomDirToBackup(z *zip.ZipArchive) error {
|
||||
customDir := conf.CustomDir()
|
||||
entries, err := os.ReadDir(customDir)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "list custom directory entries")
|
||||
}
|
||||
|
||||
for _, e := range entries {
|
||||
if e.Name() == "data" {
|
||||
// Skip the "data" directory because it lives under the "custom" directory in
|
||||
// the Docker setup and will be backed up separately.
|
||||
log.Trace(`Skipping "data" directory in custom directory`)
|
||||
continue
|
||||
}
|
||||
|
||||
add := z.AddFile
|
||||
if e.IsDir() {
|
||||
add = z.AddDir
|
||||
}
|
||||
err = add(
|
||||
fmt.Sprintf("%s/custom/%s", archiveRootDir, e.Name()),
|
||||
filepath.Join(customDir, e.Name()),
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "add %q", e.Name())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
43
cmd/gogs/cmd.go
Normal file
43
cmd/gogs/cmd.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
func stringFlag(name, value, usage string) *cli.StringFlag {
|
||||
parts := strings.SplitN(name, ", ", 2)
|
||||
f := &cli.StringFlag{
|
||||
Name: parts[0],
|
||||
Value: value,
|
||||
Usage: usage,
|
||||
}
|
||||
if len(parts) > 1 {
|
||||
f.Aliases = []string{parts[1]}
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// configFromLineage walks the command lineage to find the --config flag value.
|
||||
// This is needed because subcommands may not directly see flags set on parent commands.
|
||||
func configFromLineage(cmd *cli.Command) string {
|
||||
for _, c := range cmd.Lineage() {
|
||||
if c.IsSet("config") {
|
||||
return c.String("config")
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func boolFlag(name, usage string) *cli.BoolFlag {
|
||||
parts := strings.SplitN(name, ", ", 2)
|
||||
f := &cli.BoolFlag{
|
||||
Name: parts[0],
|
||||
Usage: usage,
|
||||
}
|
||||
if len(parts) > 1 {
|
||||
f.Aliases = []string{parts[1]}
|
||||
}
|
||||
return f
|
||||
}
|
||||
273
cmd/gogs/hook.go
Normal file
273
cmd/gogs/hook.go
Normal file
@@ -0,0 +1,273 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
"github.com/gogs/git-module"
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/database"
|
||||
"gogs.io/gogs/internal/email"
|
||||
"gogs.io/gogs/internal/httplib"
|
||||
"gogs.io/gogs/internal/osx"
|
||||
)
|
||||
|
||||
var (
|
||||
hookCommand = cli.Command{
|
||||
Name: "hook",
|
||||
Usage: "Delegate commands to corresponding Git hooks",
|
||||
Description: "All sub-commands should only be called by Git",
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
Commands: []*cli.Command{
|
||||
&subcmdHookPreReceive,
|
||||
&subcmdHookUpadte,
|
||||
&subcmdHookPostReceive,
|
||||
},
|
||||
}
|
||||
|
||||
subcmdHookPreReceive = cli.Command{
|
||||
Name: "pre-receive",
|
||||
Usage: "Delegate pre-receive Git hook",
|
||||
Description: "This command should only be called by Git",
|
||||
Action: runHookPreReceive,
|
||||
}
|
||||
subcmdHookUpadte = cli.Command{
|
||||
Name: "update",
|
||||
Usage: "Delegate update Git hook",
|
||||
Description: "This command should only be called by Git",
|
||||
Action: runHookUpdate,
|
||||
}
|
||||
subcmdHookPostReceive = cli.Command{
|
||||
Name: "post-receive",
|
||||
Usage: "Delegate post-receive Git hook",
|
||||
Description: "This command should only be called by Git",
|
||||
Action: runHookPostReceive,
|
||||
}
|
||||
)
|
||||
|
||||
func runHookPreReceive(_ context.Context, cmd *cli.Command) error {
|
||||
if os.Getenv("SSH_ORIGINAL_COMMAND") == "" {
|
||||
return nil
|
||||
}
|
||||
setup(cmd, "pre-receive.log", true)
|
||||
|
||||
isWiki := strings.Contains(os.Getenv(database.EnvRepoCustomHooksPath), ".wiki.git/")
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for scanner.Scan() {
|
||||
buf.Write(scanner.Bytes())
|
||||
buf.WriteByte('\n')
|
||||
|
||||
if isWiki {
|
||||
continue
|
||||
}
|
||||
|
||||
fields := bytes.Fields(scanner.Bytes())
|
||||
if len(fields) != 3 {
|
||||
continue
|
||||
}
|
||||
oldCommitID := string(fields[0])
|
||||
newCommitID := string(fields[1])
|
||||
branchName := git.RefShortName(string(fields[2]))
|
||||
|
||||
// Branch protection
|
||||
repoID, _ := strconv.ParseInt(os.Getenv(database.EnvRepoID), 10, 64)
|
||||
protectBranch, err := database.GetProtectBranchOfRepoByName(repoID, branchName)
|
||||
if err != nil {
|
||||
if database.IsErrBranchNotExist(err) {
|
||||
continue
|
||||
}
|
||||
fail("Internal error", "GetProtectBranchOfRepoByName [repo_id: %d, branch: %s]: %v", repoID, branchName, err)
|
||||
}
|
||||
if !protectBranch.Protected {
|
||||
continue
|
||||
}
|
||||
|
||||
// Whitelist users can bypass require pull request check
|
||||
bypassRequirePullRequest := false
|
||||
|
||||
// Check if user is in whitelist when enabled
|
||||
userID, _ := strconv.ParseInt(os.Getenv(database.EnvAuthUserID), 10, 64)
|
||||
if protectBranch.EnableWhitelist {
|
||||
if !database.IsUserInProtectBranchWhitelist(repoID, userID, branchName) {
|
||||
fail(fmt.Sprintf("Branch '%s' is protected and you are not in the push whitelist", branchName), "")
|
||||
}
|
||||
|
||||
bypassRequirePullRequest = true
|
||||
}
|
||||
|
||||
// Check if branch allows direct push
|
||||
if !bypassRequirePullRequest && protectBranch.RequirePullRequest {
|
||||
fail(fmt.Sprintf("Branch '%s' is protected and commits must be merged through pull request", branchName), "")
|
||||
}
|
||||
|
||||
// check and deletion
|
||||
if newCommitID == git.EmptyID {
|
||||
fail(fmt.Sprintf("Branch '%s' is protected from deletion", branchName), "")
|
||||
}
|
||||
|
||||
// Check force push
|
||||
output, err := git.NewCommand("rev-list", "--max-count=1", oldCommitID, "^"+newCommitID).
|
||||
RunInDir(database.RepoPath(os.Getenv(database.EnvRepoOwnerName), os.Getenv(database.EnvRepoName)))
|
||||
if err != nil {
|
||||
fail("Internal error", "Failed to detect force push: %v", err)
|
||||
} else if len(output) > 0 {
|
||||
fail(fmt.Sprintf("Branch '%s' is protected from force push", branchName), "")
|
||||
}
|
||||
}
|
||||
|
||||
customHooksPath := filepath.Join(os.Getenv(database.EnvRepoCustomHooksPath), "pre-receive")
|
||||
if !osx.IsFile(customHooksPath) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var hookCmd *exec.Cmd
|
||||
if conf.IsWindowsRuntime() {
|
||||
hookCmd = exec.Command("bash.exe", "custom_hooks/pre-receive")
|
||||
} else {
|
||||
hookCmd = exec.Command(customHooksPath)
|
||||
}
|
||||
hookCmd.Dir = database.RepoPath(os.Getenv(database.EnvRepoOwnerName), os.Getenv(database.EnvRepoName))
|
||||
hookCmd.Stdout = os.Stdout
|
||||
hookCmd.Stdin = buf
|
||||
hookCmd.Stderr = os.Stderr
|
||||
if err := hookCmd.Run(); err != nil {
|
||||
fail("Internal error", "Failed to execute custom pre-receive hook: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runHookUpdate(_ context.Context, cmd *cli.Command) error {
|
||||
if os.Getenv("SSH_ORIGINAL_COMMAND") == "" {
|
||||
return nil
|
||||
}
|
||||
setup(cmd, "update.log", false)
|
||||
|
||||
args := cmd.Args().Slice()
|
||||
if len(args) != 3 {
|
||||
fail("Arguments received are not equal to three", "Arguments received are not equal to three")
|
||||
} else if args[0] == "" {
|
||||
fail("First argument 'refName' is empty", "First argument 'refName' is empty")
|
||||
}
|
||||
|
||||
customHooksPath := filepath.Join(os.Getenv(database.EnvRepoCustomHooksPath), "update")
|
||||
if !osx.IsFile(customHooksPath) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var hookCmd *exec.Cmd
|
||||
if conf.IsWindowsRuntime() {
|
||||
hookCmd = exec.Command("bash.exe", append([]string{"custom_hooks/update"}, args...)...)
|
||||
} else {
|
||||
hookCmd = exec.Command(customHooksPath, args...)
|
||||
}
|
||||
hookCmd.Dir = database.RepoPath(os.Getenv(database.EnvRepoOwnerName), os.Getenv(database.EnvRepoName))
|
||||
hookCmd.Stdout = os.Stdout
|
||||
hookCmd.Stdin = os.Stdin
|
||||
hookCmd.Stderr = os.Stderr
|
||||
if err := hookCmd.Run(); err != nil {
|
||||
fail("Internal error", "Failed to execute custom pre-receive hook: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runHookPostReceive(_ context.Context, cmd *cli.Command) error {
|
||||
if os.Getenv("SSH_ORIGINAL_COMMAND") == "" {
|
||||
return nil
|
||||
}
|
||||
setup(cmd, "post-receive.log", true)
|
||||
|
||||
// Post-receive hook does more than just gather Git information,
|
||||
// so we need to setup additional services for email notifications.
|
||||
email.NewContext()
|
||||
|
||||
isWiki := strings.Contains(os.Getenv(database.EnvRepoCustomHooksPath), ".wiki.git/")
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for scanner.Scan() {
|
||||
buf.Write(scanner.Bytes())
|
||||
buf.WriteByte('\n')
|
||||
|
||||
// TODO: support news feeds for wiki
|
||||
if isWiki {
|
||||
continue
|
||||
}
|
||||
|
||||
fields := bytes.Fields(scanner.Bytes())
|
||||
if len(fields) != 3 {
|
||||
continue
|
||||
}
|
||||
|
||||
pusherID, _ := strconv.ParseInt(os.Getenv(database.EnvAuthUserID), 10, 64)
|
||||
options := database.PushUpdateOptions{
|
||||
OldCommitID: string(fields[0]),
|
||||
NewCommitID: string(fields[1]),
|
||||
FullRefspec: string(fields[2]),
|
||||
PusherID: pusherID,
|
||||
PusherName: os.Getenv(database.EnvAuthUserName),
|
||||
RepoUserName: os.Getenv(database.EnvRepoOwnerName),
|
||||
RepoName: os.Getenv(database.EnvRepoName),
|
||||
}
|
||||
if err := database.PushUpdate(options); err != nil {
|
||||
log.Error("PushUpdate: %v", err)
|
||||
}
|
||||
|
||||
// Ask for running deliver hook and test pull request tasks
|
||||
q := make(url.Values)
|
||||
q.Add("branch", git.RefShortName(options.FullRefspec))
|
||||
q.Add("secret", os.Getenv(database.EnvRepoOwnerSaltMd5))
|
||||
q.Add("pusher", os.Getenv(database.EnvAuthUserID))
|
||||
reqURL := fmt.Sprintf("%s%s/%s/tasks/trigger?%s", conf.Server.LocalRootURL, options.RepoUserName, options.RepoName, q.Encode())
|
||||
log.Trace("Trigger task: %s", reqURL)
|
||||
|
||||
resp, err := httplib.Get(reqURL).
|
||||
SetTLSClientConfig(&tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}).Response()
|
||||
if err == nil {
|
||||
_ = resp.Body.Close()
|
||||
if resp.StatusCode/100 != 2 {
|
||||
log.Error("Failed to trigger task: unsuccessful response code %d", resp.StatusCode)
|
||||
}
|
||||
} else {
|
||||
log.Error("Failed to trigger task: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
customHooksPath := filepath.Join(os.Getenv(database.EnvRepoCustomHooksPath), "post-receive")
|
||||
if !osx.IsFile(customHooksPath) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var hookCmd *exec.Cmd
|
||||
if conf.IsWindowsRuntime() {
|
||||
hookCmd = exec.Command("bash.exe", "custom_hooks/post-receive")
|
||||
} else {
|
||||
hookCmd = exec.Command(customHooksPath)
|
||||
}
|
||||
hookCmd.Dir = database.RepoPath(os.Getenv(database.EnvRepoOwnerName), os.Getenv(database.EnvRepoName))
|
||||
hookCmd.Stdout = os.Stdout
|
||||
hookCmd.Stdin = buf
|
||||
hookCmd.Stderr = os.Stderr
|
||||
if err := hookCmd.Run(); err != nil {
|
||||
fail("Internal error", "Failed to execute custom post-receive hook: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
108
cmd/gogs/import.go
Normal file
108
cmd/gogs/import.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/urfave/cli/v3"
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/osx"
|
||||
)
|
||||
|
||||
var (
|
||||
importCommand = cli.Command{
|
||||
Name: "import",
|
||||
Usage: "Import portable data as local Gogs data",
|
||||
Description: `Allow user import data from other Gogs installations to local instance
|
||||
without manually hacking the data files`,
|
||||
Commands: []*cli.Command{
|
||||
&subcmdImportLocale,
|
||||
},
|
||||
}
|
||||
|
||||
subcmdImportLocale = cli.Command{
|
||||
Name: "locale",
|
||||
Usage: "Import locale files to local repository",
|
||||
Action: runImportLocale,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("source", "", "Source directory that stores new locale files"),
|
||||
stringFlag("target", "", "Target directory that stores old locale files"),
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func runImportLocale(_ context.Context, cmd *cli.Command) error {
|
||||
if !cmd.IsSet("source") {
|
||||
return errors.New("source directory is not specified")
|
||||
} else if !cmd.IsSet("target") {
|
||||
return errors.New("target directory is not specified")
|
||||
}
|
||||
if !osx.IsDir(cmd.String("source")) {
|
||||
return errors.Newf("source directory %q does not exist or is not a directory", cmd.String("source"))
|
||||
} else if !osx.IsDir(cmd.String("target")) {
|
||||
return errors.Newf("target directory %q does not exist or is not a directory", cmd.String("target"))
|
||||
}
|
||||
|
||||
err := conf.Init(configFromLineage(cmd))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "init configuration")
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
var line []byte
|
||||
badChars := []byte(`="`)
|
||||
escapedQuotes := []byte(`\"`)
|
||||
regularQuotes := []byte(`"`)
|
||||
// Cut out en-US.
|
||||
for _, lang := range conf.I18n.Langs[1:] {
|
||||
name := fmt.Sprintf("locale_%s.ini", lang)
|
||||
source := filepath.Join(cmd.String("source"), name)
|
||||
target := filepath.Join(cmd.String("target"), name)
|
||||
if !osx.IsFile(source) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Crowdin surrounds double quotes for strings contain quotes inside,
|
||||
// this breaks INI parser, we need to fix that.
|
||||
sr, err := os.Open(source)
|
||||
if err != nil {
|
||||
return errors.Newf("open: %v", err)
|
||||
}
|
||||
|
||||
tw, err := os.Create(target)
|
||||
if err != nil {
|
||||
return errors.Newf("create: %v", err)
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(sr)
|
||||
for scanner.Scan() {
|
||||
line = scanner.Bytes()
|
||||
idx := bytes.Index(line, badChars)
|
||||
if idx > -1 && line[len(line)-1] == '"' {
|
||||
// We still want the "=" sign
|
||||
line = append(line[:idx+1], line[idx+2:len(line)-1]...)
|
||||
line = bytes.ReplaceAll(line, escapedQuotes, regularQuotes)
|
||||
}
|
||||
_, _ = tw.Write(line)
|
||||
_, _ = tw.WriteString("\n")
|
||||
}
|
||||
_ = sr.Close()
|
||||
_ = tw.Close()
|
||||
|
||||
// Modification time of files from Crowdin often ahead of current,
|
||||
// so we need to set back to current.
|
||||
_ = os.Chtimes(target, now, now)
|
||||
}
|
||||
|
||||
fmt.Println("Locale files has been successfully imported!")
|
||||
return nil
|
||||
}
|
||||
36
cmd/gogs/main.go
Normal file
36
cmd/gogs/main.go
Normal file
@@ -0,0 +1,36 @@
|
||||
// Gogs is a painless self-hosted Git Service.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
)
|
||||
|
||||
func init() {
|
||||
conf.App.Version = "0.15.0+dev"
|
||||
}
|
||||
|
||||
func main() {
|
||||
cmd := &cli.Command{
|
||||
Name: "Gogs",
|
||||
Usage: "A painless self-hosted Git service",
|
||||
Version: conf.App.Version,
|
||||
Commands: []*cli.Command{
|
||||
&webCommand,
|
||||
&servCommand,
|
||||
&hookCommand,
|
||||
&adminCommand,
|
||||
&importCommand,
|
||||
&backupCommand,
|
||||
&restoreCommand,
|
||||
},
|
||||
}
|
||||
if err := cmd.Run(context.Background(), os.Args); err != nil {
|
||||
log.Fatal("Failed to start application: %v", err)
|
||||
}
|
||||
}
|
||||
161
cmd/gogs/restore.go
Normal file
161
cmd/gogs/restore.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/unknwon/cae/zip"
|
||||
"github.com/urfave/cli/v3"
|
||||
"gopkg.in/ini.v1"
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/database"
|
||||
"gogs.io/gogs/internal/osx"
|
||||
"gogs.io/gogs/internal/semverx"
|
||||
)
|
||||
|
||||
var restoreCommand = cli.Command{
|
||||
Name: "restore",
|
||||
Usage: "Restore files and database from backup",
|
||||
Description: `Restore imports all related files and database from a backup archive.
|
||||
The backup version must lower or equal to current Gogs version. You can also import
|
||||
backup from other database engines, which is useful for database migrating.
|
||||
|
||||
If corresponding files or database tables are not presented in the archive, they will
|
||||
be skipped and remain unchanged.`,
|
||||
Action: runRestore,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
boolFlag("verbose, v", "Show process details"),
|
||||
stringFlag("tempdir, t", os.TempDir(), "Temporary directory path"),
|
||||
stringFlag("from", "", "Path to backup archive"),
|
||||
boolFlag("database-only", "Only import database"),
|
||||
boolFlag("exclude-repos", "Exclude repositories"),
|
||||
},
|
||||
}
|
||||
|
||||
// lastSupportedVersionOfFormat returns the last supported version of the backup archive
|
||||
// format that is able to import.
|
||||
var lastSupportedVersionOfFormat = map[int]string{}
|
||||
|
||||
func runRestore(ctx context.Context, cmd *cli.Command) error {
|
||||
zip.Verbose = cmd.Bool("verbose")
|
||||
|
||||
tmpDir := cmd.String("tempdir")
|
||||
if !osx.IsDir(tmpDir) {
|
||||
log.Fatal("'--tempdir' does not exist: %s", tmpDir)
|
||||
}
|
||||
archivePath := path.Join(tmpDir, archiveRootDir)
|
||||
|
||||
// Make sure there was no leftover and also clean up afterwards
|
||||
err := os.RemoveAll(archivePath)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to clean up previous leftover in %q: %v", archivePath, err)
|
||||
}
|
||||
defer func() { _ = os.RemoveAll(archivePath) }()
|
||||
|
||||
log.Info("Restoring backup from: %s", cmd.String("from"))
|
||||
err = zip.ExtractTo(cmd.String("from"), tmpDir)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to extract backup archive: %v", err)
|
||||
}
|
||||
|
||||
// Check backup version
|
||||
metaFile := filepath.Join(archivePath, "metadata.ini")
|
||||
if !osx.IsFile(metaFile) {
|
||||
log.Fatal("File 'metadata.ini' is missing")
|
||||
}
|
||||
metadata, err := ini.Load(metaFile)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to load metadata '%s': %v", metaFile, err)
|
||||
}
|
||||
backupVersion := metadata.Section("").Key("GOGS_VERSION").MustString("999.0")
|
||||
if semverx.Compare(conf.App.Version, "<", backupVersion) {
|
||||
log.Fatal("Current Gogs version is lower than backup version: %s < %s", conf.App.Version, backupVersion)
|
||||
}
|
||||
formatVersion := metadata.Section("").Key("VERSION").MustInt()
|
||||
if formatVersion == 0 {
|
||||
log.Fatal("Failed to determine the backup format version from metadata '%s': %s", metaFile, "VERSION is not presented")
|
||||
}
|
||||
if formatVersion != currentBackupFormatVersion {
|
||||
log.Fatal("Backup format version found is %d but this binary only supports %d\nThe last known version that is able to import your backup is %s",
|
||||
formatVersion, currentBackupFormatVersion, lastSupportedVersionOfFormat[formatVersion])
|
||||
}
|
||||
|
||||
// If config file is not present in backup, user must set this file via flag.
|
||||
// Otherwise, it's optional to set config file flag.
|
||||
configFile := filepath.Join(archivePath, "custom", "conf", "app.ini")
|
||||
var customConf string
|
||||
if lineageConf := configFromLineage(cmd); lineageConf != "" {
|
||||
customConf = lineageConf
|
||||
} else if !osx.IsFile(configFile) {
|
||||
log.Fatal("'--config' is not specified and custom config file is not found in backup")
|
||||
} else {
|
||||
customConf = configFile
|
||||
}
|
||||
|
||||
err = conf.Init(customConf)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "init configuration")
|
||||
}
|
||||
conf.InitLogging(true)
|
||||
|
||||
conn, err := database.SetEngine()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "set engine")
|
||||
}
|
||||
|
||||
// Database
|
||||
dbDir := path.Join(archivePath, "db")
|
||||
if err = database.ImportDatabase(ctx, conn, dbDir, cmd.Bool("verbose")); err != nil {
|
||||
log.Fatal("Failed to import database: %v", err)
|
||||
}
|
||||
|
||||
if !cmd.Bool("database-only") {
|
||||
// Custom files
|
||||
if osx.IsDir(conf.CustomDir()) {
|
||||
if err = os.Rename(conf.CustomDir(), conf.CustomDir()+".bak"); err != nil {
|
||||
log.Fatal("Failed to backup current 'custom': %v", err)
|
||||
}
|
||||
}
|
||||
if err = os.Rename(filepath.Join(archivePath, "custom"), conf.CustomDir()); err != nil {
|
||||
log.Fatal("Failed to import 'custom': %v", err)
|
||||
}
|
||||
|
||||
// Data files
|
||||
_ = os.MkdirAll(conf.Server.AppDataPath, os.ModePerm)
|
||||
for _, dir := range []string{"attachments", "avatars", "repo-avatars"} {
|
||||
// Skip if backup archive does not have corresponding data
|
||||
srcPath := filepath.Join(archivePath, "data", dir)
|
||||
if !osx.IsDir(srcPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
dirPath := filepath.Join(conf.Server.AppDataPath, dir)
|
||||
if osx.IsDir(dirPath) {
|
||||
if err = os.Rename(dirPath, dirPath+".bak"); err != nil {
|
||||
log.Fatal("Failed to backup current 'data': %v", err)
|
||||
}
|
||||
}
|
||||
if err = os.Rename(srcPath, dirPath); err != nil {
|
||||
log.Fatal("Failed to import 'data': %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Repositories
|
||||
reposPath := filepath.Join(archivePath, "repositories.zip")
|
||||
if !cmd.Bool("exclude-repos") && !cmd.Bool("database-only") && osx.IsFile(reposPath) {
|
||||
if err := zip.ExtractTo(reposPath, filepath.Dir(conf.Repository.Root)); err != nil {
|
||||
log.Fatal("Failed to extract 'repositories.zip': %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("Restore succeed!")
|
||||
log.Stop()
|
||||
return nil
|
||||
}
|
||||
274
cmd/gogs/serv.go
Normal file
274
cmd/gogs/serv.go
Normal file
@@ -0,0 +1,274 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/urfave/cli/v3"
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/database"
|
||||
)
|
||||
|
||||
const (
|
||||
accessDeniedMessage = "Repository does not exist or you do not have access"
|
||||
)
|
||||
|
||||
var servCommand = cli.Command{
|
||||
Name: "serv",
|
||||
Usage: "This command should only be called by SSH shell",
|
||||
Description: `Serv provide access auth for repositories`,
|
||||
Action: runServ,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
// fail prints user message to the Git client (i.e. os.Stderr) and
|
||||
// logs error message on the server side. When not in "prod" mode,
|
||||
// error message is also printed to the client for easier debugging.
|
||||
func fail(userMessage, errMessage string, args ...any) {
|
||||
_, _ = fmt.Fprintln(os.Stderr, "Gogs:", userMessage)
|
||||
|
||||
if len(errMessage) > 0 {
|
||||
if !conf.IsProdMode() {
|
||||
fmt.Fprintf(os.Stderr, errMessage+"\n", args...)
|
||||
}
|
||||
log.Error(errMessage, args...)
|
||||
}
|
||||
|
||||
log.Stop()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func setup(cmd *cli.Command, logFile string, connectDB bool) {
|
||||
conf.HookMode = true
|
||||
|
||||
customConf := configFromLineage(cmd)
|
||||
|
||||
err := conf.Init(customConf)
|
||||
if err != nil {
|
||||
fail("Internal error", "Failed to init configuration: %v", err)
|
||||
}
|
||||
conf.InitLogging(true)
|
||||
|
||||
level := log.LevelTrace
|
||||
if conf.IsProdMode() {
|
||||
level = log.LevelError
|
||||
}
|
||||
|
||||
err = log.NewFile(log.FileConfig{
|
||||
Level: level,
|
||||
Filename: filepath.Join(conf.Log.RootPath, "hooks", logFile),
|
||||
FileRotationConfig: log.FileRotationConfig{
|
||||
Rotate: true,
|
||||
Daily: true,
|
||||
MaxDays: 3,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
fail("Internal error", "Failed to init file logger: %v", err)
|
||||
}
|
||||
log.Remove(log.DefaultConsoleName) // Remove the primary logger
|
||||
|
||||
if !connectDB {
|
||||
return
|
||||
}
|
||||
|
||||
if conf.UseSQLite3 {
|
||||
_ = os.Chdir(conf.WorkDir())
|
||||
}
|
||||
|
||||
if _, err := database.SetEngine(); err != nil {
|
||||
fail("Internal error", "Failed to set database engine: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func parseSSHCmd(cmd string) (string, string) {
|
||||
ss := strings.SplitN(cmd, " ", 2)
|
||||
if len(ss) != 2 {
|
||||
return "", ""
|
||||
}
|
||||
return ss[0], strings.Replace(ss[1], "'/", "'", 1)
|
||||
}
|
||||
|
||||
func checkDeployKey(key *database.PublicKey, repo *database.Repository) {
|
||||
// Check if this deploy key belongs to current repository.
|
||||
if !database.HasDeployKey(key.ID, repo.ID) {
|
||||
fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
|
||||
}
|
||||
|
||||
// Update deploy key activity.
|
||||
deployKey, err := database.GetDeployKeyByRepo(key.ID, repo.ID)
|
||||
if err != nil {
|
||||
fail("Internal error", "GetDeployKey: %v", err)
|
||||
}
|
||||
|
||||
deployKey.Updated = time.Now()
|
||||
if err = database.UpdateDeployKey(deployKey); err != nil {
|
||||
fail("Internal error", "UpdateDeployKey: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
var allowedCommands = map[string]database.AccessMode{
|
||||
"git-upload-pack": database.AccessModeRead,
|
||||
"git-upload-archive": database.AccessModeRead,
|
||||
"git-receive-pack": database.AccessModeWrite,
|
||||
}
|
||||
|
||||
func runServ(ctx context.Context, cmd *cli.Command) error {
|
||||
setup(cmd, "serv.log", true)
|
||||
|
||||
if conf.SSH.Disabled {
|
||||
println("Gogs: SSH has been disabled")
|
||||
return nil
|
||||
}
|
||||
|
||||
if cmd.Args().Len() < 1 {
|
||||
fail("Not enough arguments", "Not enough arguments")
|
||||
}
|
||||
|
||||
sshCmd := os.Getenv("SSH_ORIGINAL_COMMAND")
|
||||
if sshCmd == "" {
|
||||
println("Hi there, You've successfully authenticated, but Gogs does not provide shell access.")
|
||||
println("If this is unexpected, please log in with password and setup Gogs under another user.")
|
||||
return nil
|
||||
}
|
||||
|
||||
verb, args := parseSSHCmd(sshCmd)
|
||||
repoFullName := strings.ToLower(strings.Trim(args, "'"))
|
||||
repoFields := strings.SplitN(repoFullName, "/", 2)
|
||||
if len(repoFields) != 2 {
|
||||
fail("Invalid repository path", "Invalid repository path: %v", args)
|
||||
}
|
||||
ownerName := strings.ToLower(repoFields[0])
|
||||
repoName := strings.TrimSuffix(strings.ToLower(repoFields[1]), ".git")
|
||||
repoName = strings.TrimSuffix(repoName, ".wiki")
|
||||
|
||||
owner, err := database.Handle.Users().GetByUsername(ctx, ownerName)
|
||||
if err != nil {
|
||||
if database.IsErrUserNotExist(err) {
|
||||
fail("Repository owner does not exist", "Unregistered owner: %s", ownerName)
|
||||
}
|
||||
fail("Internal error", "Failed to get repository owner '%s': %v", ownerName, err)
|
||||
}
|
||||
|
||||
repo, err := database.GetRepositoryByName(owner.ID, repoName)
|
||||
if err != nil {
|
||||
if database.IsErrRepoNotExist(err) {
|
||||
fail(accessDeniedMessage, "Repository does not exist: %s/%s", owner.Name, repoName)
|
||||
}
|
||||
fail("Internal error", "Failed to get repository: %v", err)
|
||||
}
|
||||
repo.Owner = owner
|
||||
|
||||
requestMode, ok := allowedCommands[verb]
|
||||
if !ok {
|
||||
fail("Unknown git command", "Unknown git command '%s'", verb)
|
||||
}
|
||||
|
||||
// Prohibit push to mirror repositories.
|
||||
if requestMode > database.AccessModeRead && repo.IsMirror {
|
||||
fail("Mirror repository is read-only", "")
|
||||
}
|
||||
|
||||
// Allow anonymous (user is nil) clone for public repositories.
|
||||
var user *database.User
|
||||
|
||||
keyID, _ := strconv.ParseInt(strings.TrimPrefix(cmd.Args().Get(0), "key-"), 10, 64)
|
||||
key, err := database.GetPublicKeyByID(keyID)
|
||||
if err != nil {
|
||||
fail("Invalid key ID", "Invalid key ID '%s': %v", cmd.Args().Get(0), err)
|
||||
}
|
||||
|
||||
if requestMode == database.AccessModeWrite || repo.IsPrivate {
|
||||
// Check deploy key or user key.
|
||||
if key.IsDeployKey() {
|
||||
if key.Mode < requestMode {
|
||||
fail("Key permission denied", "Cannot push with deployment key: %d", key.ID)
|
||||
}
|
||||
checkDeployKey(key, repo)
|
||||
} else {
|
||||
user, err = database.Handle.Users().GetByKeyID(ctx, key.ID)
|
||||
if err != nil {
|
||||
fail("Internal error", "Failed to get user by key ID '%d': %v", key.ID, err)
|
||||
}
|
||||
|
||||
mode := database.Handle.Permissions().AccessMode(ctx, user.ID, repo.ID,
|
||||
database.AccessModeOptions{
|
||||
OwnerID: repo.OwnerID,
|
||||
Private: repo.IsPrivate,
|
||||
},
|
||||
)
|
||||
if mode < requestMode {
|
||||
clientMessage := accessDeniedMessage
|
||||
if mode >= database.AccessModeRead {
|
||||
clientMessage = "You do not have sufficient authorization for this action"
|
||||
}
|
||||
fail(clientMessage,
|
||||
"User '%s' does not have level '%v' access to repository '%s'",
|
||||
user.Name, requestMode, repoFullName)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Check if the key can access to the repository in case of it is a deploy key (a deploy keys != user key).
|
||||
// A deploy key doesn't represent a signed in user, so in a site with Auth.RequireSignInView enabled,
|
||||
// we should give read access only in repositories where this deploy key is in use. In other cases,
|
||||
// a server or system using an active deploy key can get read access to all repositories on a Gogs instance.
|
||||
if key.IsDeployKey() && conf.Auth.RequireSigninView {
|
||||
checkDeployKey(key, repo)
|
||||
}
|
||||
}
|
||||
|
||||
// Update user key activity.
|
||||
if key.ID > 0 {
|
||||
key, err := database.GetPublicKeyByID(key.ID)
|
||||
if err != nil {
|
||||
fail("Internal error", "GetPublicKeyByID: %v", err)
|
||||
}
|
||||
|
||||
key.Updated = time.Now()
|
||||
if err = database.UpdatePublicKey(key); err != nil {
|
||||
fail("Internal error", "UpdatePublicKey: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Special handle for Windows.
|
||||
if conf.IsWindowsRuntime() {
|
||||
verb = strings.Replace(verb, "-", " ", 1)
|
||||
}
|
||||
|
||||
var gitCmd *exec.Cmd
|
||||
verbs := strings.Split(verb, " ")
|
||||
if len(verbs) == 2 {
|
||||
gitCmd = exec.Command(verbs[0], verbs[1], repoFullName)
|
||||
} else {
|
||||
gitCmd = exec.Command(verb, repoFullName)
|
||||
}
|
||||
if requestMode == database.AccessModeWrite {
|
||||
gitCmd.Env = append(os.Environ(), database.ComposeHookEnvs(database.ComposeHookEnvsOptions{
|
||||
AuthUser: user,
|
||||
OwnerName: owner.Name,
|
||||
OwnerSalt: owner.Salt,
|
||||
RepoID: repo.ID,
|
||||
RepoName: repo.Name,
|
||||
RepoPath: repo.RepoPath(),
|
||||
})...)
|
||||
}
|
||||
gitCmd.Dir = conf.Repository.Root
|
||||
gitCmd.Stdout = os.Stdout
|
||||
gitCmd.Stdin = os.Stdin
|
||||
gitCmd.Stderr = os.Stderr
|
||||
if err = gitCmd.Run(); err != nil {
|
||||
fail("Internal error", "Failed to execute git command: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
782
cmd/gogs/web.go
Normal file
782
cmd/gogs/web.go
Normal file
@@ -0,0 +1,782 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
stdctx "context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/fcgi"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/go-macaron/binding"
|
||||
"github.com/go-macaron/cache"
|
||||
"github.com/go-macaron/captcha"
|
||||
"github.com/go-macaron/csrf"
|
||||
"github.com/go-macaron/gzip"
|
||||
"github.com/go-macaron/i18n"
|
||||
"github.com/go-macaron/session"
|
||||
"github.com/go-macaron/toolbox"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/urfave/cli/v3"
|
||||
"gopkg.in/macaron.v1"
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
embedConf "gogs.io/gogs/conf"
|
||||
"gogs.io/gogs/internal/app"
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/context"
|
||||
"gogs.io/gogs/internal/database"
|
||||
"gogs.io/gogs/internal/form"
|
||||
"gogs.io/gogs/internal/osx"
|
||||
"gogs.io/gogs/internal/route"
|
||||
"gogs.io/gogs/internal/route/admin"
|
||||
apiv1 "gogs.io/gogs/internal/route/api/v1"
|
||||
"gogs.io/gogs/internal/route/dev"
|
||||
"gogs.io/gogs/internal/route/lfs"
|
||||
"gogs.io/gogs/internal/route/org"
|
||||
"gogs.io/gogs/internal/route/repo"
|
||||
"gogs.io/gogs/internal/route/user"
|
||||
"gogs.io/gogs/internal/template"
|
||||
"gogs.io/gogs/public"
|
||||
"gogs.io/gogs/templates"
|
||||
)
|
||||
|
||||
var webCommand = cli.Command{
|
||||
Name: "web",
|
||||
Usage: "Start web server",
|
||||
Description: `Gogs web server is the only thing you need to run,
|
||||
and it takes care of all the other things for you`,
|
||||
Action: runWeb,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("port, p", "3000", "Temporary port number to prevent conflict"),
|
||||
stringFlag("config, c", filepath.Join(conf.CustomDir(), "conf", "app.ini"), "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
// newMacaron initializes Macaron instance.
|
||||
func newMacaron() *macaron.Macaron {
|
||||
m := macaron.New()
|
||||
if !conf.Server.DisableRouterLog {
|
||||
m.Use(macaron.Logger())
|
||||
}
|
||||
m.Use(macaron.Recovery())
|
||||
if conf.Server.EnableGzip {
|
||||
m.Use(gzip.Gziper())
|
||||
}
|
||||
if conf.Server.Protocol == "fcgi" {
|
||||
m.SetURLPrefix(conf.Server.Subpath)
|
||||
}
|
||||
|
||||
// Register custom middleware first to make it possible to override files under "public".
|
||||
m.Use(macaron.Static(
|
||||
filepath.Join(conf.CustomDir(), "public"),
|
||||
macaron.StaticOptions{
|
||||
SkipLogging: conf.Server.DisableRouterLog,
|
||||
},
|
||||
))
|
||||
var publicFs http.FileSystem
|
||||
if !conf.Server.LoadAssetsFromDisk {
|
||||
publicFs = http.FS(public.Files)
|
||||
}
|
||||
m.Use(macaron.Static(
|
||||
filepath.Join(conf.WorkDir(), "public"),
|
||||
macaron.StaticOptions{
|
||||
ETag: true,
|
||||
SkipLogging: conf.Server.DisableRouterLog,
|
||||
FileSystem: publicFs,
|
||||
},
|
||||
))
|
||||
|
||||
m.Use(macaron.Static(
|
||||
conf.Picture.AvatarUploadPath,
|
||||
macaron.StaticOptions{
|
||||
ETag: true,
|
||||
Prefix: conf.UsersAvatarPathPrefix,
|
||||
SkipLogging: conf.Server.DisableRouterLog,
|
||||
},
|
||||
))
|
||||
m.Use(macaron.Static(
|
||||
conf.Picture.RepositoryAvatarUploadPath,
|
||||
macaron.StaticOptions{
|
||||
ETag: true,
|
||||
Prefix: database.RepoAvatarURLPrefix,
|
||||
SkipLogging: conf.Server.DisableRouterLog,
|
||||
},
|
||||
))
|
||||
|
||||
customDir := filepath.Join(conf.CustomDir(), "templates")
|
||||
renderOpt := macaron.RenderOptions{
|
||||
Directory: filepath.Join(conf.WorkDir(), "templates"),
|
||||
AppendDirectories: []string{customDir},
|
||||
Funcs: template.FuncMap(),
|
||||
IndentJSON: macaron.Env != macaron.PROD,
|
||||
}
|
||||
if !conf.Server.LoadAssetsFromDisk {
|
||||
renderOpt.TemplateFileSystem = templates.NewTemplateFileSystem("", customDir)
|
||||
}
|
||||
m.Use(macaron.Renderer(renderOpt))
|
||||
|
||||
localeNames, err := embedConf.FileNames("locale")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to list locale files: %v", err)
|
||||
}
|
||||
localeFiles := make(map[string][]byte)
|
||||
for _, name := range localeNames {
|
||||
localeFiles[name], err = embedConf.Files.ReadFile("locale/" + name)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to read locale file %q: %v", name, err)
|
||||
}
|
||||
}
|
||||
m.Use(i18n.I18n(i18n.Options{
|
||||
SubURL: conf.Server.Subpath,
|
||||
Files: localeFiles,
|
||||
CustomDirectory: filepath.Join(conf.CustomDir(), "conf", "locale"),
|
||||
Langs: conf.I18n.Langs,
|
||||
Names: conf.I18n.Names,
|
||||
DefaultLang: "en-US",
|
||||
Redirect: true,
|
||||
}))
|
||||
m.Use(cache.Cacher(cache.Options{
|
||||
Adapter: conf.Cache.Adapter,
|
||||
AdapterConfig: conf.Cache.Host,
|
||||
Interval: conf.Cache.Interval,
|
||||
}))
|
||||
m.Use(captcha.Captchaer(captcha.Options{
|
||||
SubURL: conf.Server.Subpath,
|
||||
}))
|
||||
m.Use(toolbox.Toolboxer(m, toolbox.Options{
|
||||
HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{
|
||||
{
|
||||
Desc: "Database connection",
|
||||
Func: database.Ping,
|
||||
},
|
||||
},
|
||||
}))
|
||||
return m
|
||||
}
|
||||
|
||||
func runWeb(_ stdctx.Context, cmd *cli.Command) error {
|
||||
err := route.GlobalInit(configFromLineage(cmd))
|
||||
if err != nil {
|
||||
log.Fatal("Failed to initialize application: %v", err)
|
||||
}
|
||||
|
||||
m := newMacaron()
|
||||
|
||||
reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true})
|
||||
ignSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: conf.Auth.RequireSigninView})
|
||||
reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true})
|
||||
|
||||
bindIgnErr := binding.BindIgnErr
|
||||
|
||||
m.SetAutoHead(true)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Get("/", ignSignIn, route.Home)
|
||||
m.Group("/explore", func() {
|
||||
m.Get("", func(c *context.Context) {
|
||||
c.Redirect(conf.Server.Subpath + "/explore/repos")
|
||||
})
|
||||
m.Get("/repos", route.ExploreRepos)
|
||||
m.Get("/users", route.ExploreUsers)
|
||||
m.Get("/organizations", route.ExploreOrganizations)
|
||||
}, ignSignIn)
|
||||
m.Combo("/install", route.InstallInit).Get(route.Install).
|
||||
Post(bindIgnErr(form.Install{}), route.InstallPost)
|
||||
m.Get("/^:type(issues|pulls)$", reqSignIn, user.Issues)
|
||||
|
||||
// ***** START: User *****
|
||||
m.Group("/user", func() {
|
||||
m.Group("/login", func() {
|
||||
m.Combo("").Get(user.Login).
|
||||
Post(bindIgnErr(form.SignIn{}), user.LoginPost)
|
||||
m.Combo("/two_factor").Get(user.LoginTwoFactor).Post(user.LoginTwoFactorPost)
|
||||
m.Combo("/two_factor_recovery_code").Get(user.LoginTwoFactorRecoveryCode).Post(user.LoginTwoFactorRecoveryCodePost)
|
||||
})
|
||||
|
||||
m.Get("/sign_up", user.SignUp)
|
||||
m.Post("/sign_up", bindIgnErr(form.Register{}), user.SignUpPost)
|
||||
m.Get("/reset_password", user.ResetPasswd)
|
||||
m.Post("/reset_password", user.ResetPasswdPost)
|
||||
}, reqSignOut)
|
||||
|
||||
m.Group("/user/settings", func() {
|
||||
m.Get("", user.Settings)
|
||||
m.Post("", bindIgnErr(form.UpdateProfile{}), user.SettingsPost)
|
||||
m.Combo("/avatar").Get(user.SettingsAvatar).
|
||||
Post(binding.MultipartForm(form.Avatar{}), user.SettingsAvatarPost)
|
||||
m.Post("/avatar/delete", user.SettingsDeleteAvatar)
|
||||
m.Combo("/email").Get(user.SettingsEmails).
|
||||
Post(bindIgnErr(form.AddEmail{}), user.SettingsEmailPost)
|
||||
m.Post("/email/delete", user.DeleteEmail)
|
||||
m.Get("/password", user.SettingsPassword)
|
||||
m.Post("/password", bindIgnErr(form.ChangePassword{}), user.SettingsPasswordPost)
|
||||
m.Combo("/ssh").Get(user.SettingsSSHKeys).
|
||||
Post(bindIgnErr(form.AddSSHKey{}), user.SettingsSSHKeysPost)
|
||||
m.Post("/ssh/delete", user.DeleteSSHKey)
|
||||
m.Group("/security", func() {
|
||||
m.Get("", user.SettingsSecurity)
|
||||
m.Combo("/two_factor_enable").Get(user.SettingsTwoFactorEnable).
|
||||
Post(user.SettingsTwoFactorEnablePost)
|
||||
m.Combo("/two_factor_recovery_codes").Get(user.SettingsTwoFactorRecoveryCodes).
|
||||
Post(user.SettingsTwoFactorRecoveryCodesPost)
|
||||
m.Post("/two_factor_disable", user.SettingsTwoFactorDisable)
|
||||
})
|
||||
m.Group("/repositories", func() {
|
||||
m.Get("", user.SettingsRepos)
|
||||
m.Post("/leave", user.SettingsLeaveRepo)
|
||||
})
|
||||
m.Group("/organizations", func() {
|
||||
m.Get("", user.SettingsOrganizations)
|
||||
m.Post("/leave", user.SettingsLeaveOrganization)
|
||||
})
|
||||
|
||||
settingsHandler := user.NewSettingsHandler(user.NewSettingsStore())
|
||||
m.Combo("/applications").Get(settingsHandler.Applications()).
|
||||
Post(bindIgnErr(form.NewAccessToken{}), settingsHandler.ApplicationsPost())
|
||||
m.Post("/applications/delete", settingsHandler.DeleteApplication())
|
||||
m.Route("/delete", "GET,POST", user.SettingsDelete)
|
||||
}, reqSignIn, func(c *context.Context) {
|
||||
c.Data["PageIsUserSettings"] = true
|
||||
})
|
||||
|
||||
m.Group("/user", func() {
|
||||
m.Any("/activate", user.Activate)
|
||||
m.Any("/activate_email", user.ActivateEmail)
|
||||
m.Get("/email2user", user.Email2User)
|
||||
m.Get("/forget_password", user.ForgotPasswd)
|
||||
m.Post("/forget_password", user.ForgotPasswdPost)
|
||||
m.Post("/logout", user.SignOut)
|
||||
})
|
||||
// ***** END: User *****
|
||||
|
||||
reqAdmin := context.Toggle(&context.ToggleOptions{SignInRequired: true, AdminRequired: true})
|
||||
|
||||
// ***** START: Admin *****
|
||||
m.Group("/admin", func() {
|
||||
m.Combo("").Get(admin.Dashboard).Post(admin.Operation) // "/admin"
|
||||
m.Get("/config", admin.Config)
|
||||
m.Post("/config/test_mail", admin.SendTestMail)
|
||||
m.Get("/monitor", admin.Monitor)
|
||||
|
||||
m.Group("/users", func() {
|
||||
m.Get("", admin.Users)
|
||||
m.Combo("/new").Get(admin.NewUser).Post(bindIgnErr(form.AdminCrateUser{}), admin.NewUserPost)
|
||||
m.Combo("/:userid").Get(admin.EditUser).Post(bindIgnErr(form.AdminEditUser{}), admin.EditUserPost)
|
||||
m.Post("/:userid/delete", admin.DeleteUser)
|
||||
})
|
||||
|
||||
m.Group("/orgs", func() {
|
||||
m.Get("", admin.Organizations)
|
||||
})
|
||||
|
||||
m.Group("/repos", func() {
|
||||
m.Get("", admin.Repos)
|
||||
m.Post("/delete", admin.DeleteRepo)
|
||||
})
|
||||
|
||||
m.Group("/auths", func() {
|
||||
m.Get("", admin.Authentications)
|
||||
m.Combo("/new").Get(admin.NewAuthSource).Post(bindIgnErr(form.Authentication{}), admin.NewAuthSourcePost)
|
||||
m.Combo("/:authid").Get(admin.EditAuthSource).
|
||||
Post(bindIgnErr(form.Authentication{}), admin.EditAuthSourcePost)
|
||||
m.Post("/:authid/delete", admin.DeleteAuthSource)
|
||||
})
|
||||
|
||||
m.Group("/notices", func() {
|
||||
m.Get("", admin.Notices)
|
||||
m.Post("/delete", admin.DeleteNotices)
|
||||
m.Get("/empty", admin.EmptyNotices)
|
||||
})
|
||||
}, reqAdmin)
|
||||
// ***** END: Admin *****
|
||||
|
||||
m.Group("", func() {
|
||||
m.Group("/:username", func() {
|
||||
m.Get("", user.Profile)
|
||||
m.Get("/followers", user.Followers)
|
||||
m.Get("/following", user.Following)
|
||||
m.Get("/stars", user.Stars)
|
||||
}, context.InjectParamsUser())
|
||||
|
||||
m.Get("/attachments/:uuid", func(c *context.Context) {
|
||||
attach, err := database.GetAttachmentByUUID(c.Params(":uuid"))
|
||||
if err != nil {
|
||||
c.NotFoundOrError(err, "get attachment by UUID")
|
||||
return
|
||||
} else if !osx.IsFile(attach.LocalPath()) {
|
||||
c.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
fr, err := os.Open(attach.LocalPath())
|
||||
if err != nil {
|
||||
c.Error(err, "open attachment file")
|
||||
return
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
c.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox")
|
||||
c.Header().Set("Cache-Control", "public,max-age=86400")
|
||||
c.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, attach.Name))
|
||||
|
||||
if _, err = io.Copy(c.Resp, fr); err != nil {
|
||||
c.Error(err, "copy from file to response")
|
||||
return
|
||||
}
|
||||
})
|
||||
}, ignSignIn)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Post("/issues/attachments", repo.UploadIssueAttachment)
|
||||
m.Post("/releases/attachments", repo.UploadReleaseAttachment)
|
||||
}, reqSignIn)
|
||||
|
||||
m.Group("/:username", func() {
|
||||
m.Post("/action/:action", user.Action)
|
||||
}, reqSignIn, context.InjectParamsUser())
|
||||
|
||||
if macaron.Env == macaron.DEV {
|
||||
m.Get("/template/*", dev.TemplatePreview)
|
||||
}
|
||||
|
||||
reqRepoAdmin := context.RequireRepoAdmin()
|
||||
reqRepoWriter := context.RequireRepoWriter()
|
||||
|
||||
webhookRoutes := func() {
|
||||
m.Group("", func() {
|
||||
m.Get("", repo.Webhooks)
|
||||
m.Post("/delete", repo.DeleteWebhook)
|
||||
m.Get("/:type/new", repo.WebhooksNew)
|
||||
m.Post("/gogs/new", bindIgnErr(form.NewWebhook{}), repo.WebhooksNewPost)
|
||||
m.Post("/slack/new", bindIgnErr(form.NewSlackHook{}), repo.WebhooksSlackNewPost)
|
||||
m.Post("/discord/new", bindIgnErr(form.NewDiscordHook{}), repo.WebhooksDiscordNewPost)
|
||||
m.Post("/dingtalk/new", bindIgnErr(form.NewDingtalkHook{}), repo.WebhooksDingtalkNewPost)
|
||||
m.Get("/:id", repo.WebhooksEdit)
|
||||
m.Post("/gogs/:id", bindIgnErr(form.NewWebhook{}), repo.WebhooksEditPost)
|
||||
m.Post("/slack/:id", bindIgnErr(form.NewSlackHook{}), repo.WebhooksSlackEditPost)
|
||||
m.Post("/discord/:id", bindIgnErr(form.NewDiscordHook{}), repo.WebhooksDiscordEditPost)
|
||||
m.Post("/dingtalk/:id", bindIgnErr(form.NewDingtalkHook{}), repo.WebhooksDingtalkEditPost)
|
||||
}, repo.InjectOrgRepoContext())
|
||||
}
|
||||
|
||||
// ***** START: Organization *****
|
||||
m.Group("/org", func() {
|
||||
m.Group("", func() {
|
||||
m.Get("/create", org.Create)
|
||||
m.Post("/create", bindIgnErr(form.CreateOrg{}), org.CreatePost)
|
||||
}, func(c *context.Context) {
|
||||
if !c.User.CanCreateOrganization() {
|
||||
c.NotFound()
|
||||
}
|
||||
})
|
||||
|
||||
m.Group("/:org", func() {
|
||||
m.Get("/dashboard", user.Dashboard)
|
||||
m.Get("/^:type(issues|pulls)$", user.Issues)
|
||||
m.Get("/members", org.Members)
|
||||
m.Get("/members/action/:action", org.MembersAction)
|
||||
|
||||
m.Get("/teams", org.Teams)
|
||||
}, context.OrgAssignment(true))
|
||||
|
||||
m.Group("/:org", func() {
|
||||
m.Get("/teams/:team", org.TeamMembers)
|
||||
m.Get("/teams/:team/repositories", org.TeamRepositories)
|
||||
m.Route("/teams/:team/action/:action", "GET,POST", org.TeamsAction)
|
||||
m.Route("/teams/:team/action/repo/:action", "GET,POST", org.TeamsRepoAction)
|
||||
}, context.OrgAssignment(true, false, true))
|
||||
|
||||
m.Group("/:org", func() {
|
||||
m.Get("/teams/new", org.NewTeam)
|
||||
m.Post("/teams/new", bindIgnErr(form.CreateTeam{}), org.NewTeamPost)
|
||||
m.Get("/teams/:team/edit", org.EditTeam)
|
||||
m.Post("/teams/:team/edit", bindIgnErr(form.CreateTeam{}), org.EditTeamPost)
|
||||
m.Post("/teams/:team/delete", org.DeleteTeam)
|
||||
|
||||
m.Group("/settings", func() {
|
||||
m.Combo("").Get(org.Settings).
|
||||
Post(bindIgnErr(form.UpdateOrgSetting{}), org.SettingsPost)
|
||||
m.Post("/avatar", binding.MultipartForm(form.Avatar{}), org.SettingsAvatar)
|
||||
m.Post("/avatar/delete", org.SettingsDeleteAvatar)
|
||||
m.Group("/hooks", webhookRoutes)
|
||||
m.Route("/delete", "GET,POST", org.SettingsDelete)
|
||||
})
|
||||
|
||||
m.Route("/invitations/new", "GET,POST", org.Invitation)
|
||||
}, context.OrgAssignment(true, true))
|
||||
}, reqSignIn)
|
||||
// ***** END: Organization *****
|
||||
|
||||
// ***** START: Repository *****
|
||||
m.Group("/repo", func() {
|
||||
m.Get("/create", repo.Create)
|
||||
m.Post("/create", bindIgnErr(form.CreateRepo{}), repo.CreatePost)
|
||||
m.Get("/migrate", repo.Migrate)
|
||||
m.Post("/migrate", bindIgnErr(form.MigrateRepo{}), repo.MigratePost)
|
||||
m.Combo("/fork/:repoid").Get(repo.Fork).
|
||||
Post(bindIgnErr(form.CreateRepo{}), repo.ForkPost)
|
||||
}, reqSignIn)
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Group("/settings", func() {
|
||||
m.Combo("").Get(repo.Settings).
|
||||
Post(bindIgnErr(form.RepoSetting{}), repo.SettingsPost)
|
||||
m.Combo("/avatar").Get(repo.SettingsAvatar).
|
||||
Post(binding.MultipartForm(form.Avatar{}), repo.SettingsAvatarPost)
|
||||
m.Post("/avatar/delete", repo.SettingsDeleteAvatar)
|
||||
m.Group("/collaboration", func() {
|
||||
m.Combo("").Get(repo.SettingsCollaboration).Post(repo.SettingsCollaborationPost)
|
||||
m.Post("/access_mode", repo.ChangeCollaborationAccessMode)
|
||||
m.Post("/delete", repo.DeleteCollaboration)
|
||||
})
|
||||
m.Group("/branches", func() {
|
||||
m.Get("", repo.SettingsBranches)
|
||||
m.Post("/default_branch", repo.UpdateDefaultBranch)
|
||||
m.Combo("/*").Get(repo.SettingsProtectedBranch).
|
||||
Post(bindIgnErr(form.ProtectBranch{}), repo.SettingsProtectedBranchPost)
|
||||
}, func(c *context.Context) {
|
||||
if c.Repo.Repository.IsMirror {
|
||||
c.NotFound()
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
m.Group("/hooks", func() {
|
||||
webhookRoutes()
|
||||
|
||||
m.Group("/:id", func() {
|
||||
m.Post("/test", repo.TestWebhook)
|
||||
m.Post("/redelivery", repo.RedeliveryWebhook)
|
||||
})
|
||||
|
||||
m.Group("/git", func() {
|
||||
m.Get("", repo.SettingsGitHooks)
|
||||
m.Combo("/:name").Get(repo.SettingsGitHooksEdit).
|
||||
Post(repo.SettingsGitHooksEditPost)
|
||||
}, context.GitHookService())
|
||||
})
|
||||
|
||||
m.Group("/keys", func() {
|
||||
m.Combo("").Get(repo.SettingsDeployKeys).
|
||||
Post(bindIgnErr(form.AddSSHKey{}), repo.SettingsDeployKeysPost)
|
||||
m.Post("/delete", repo.DeleteDeployKey)
|
||||
})
|
||||
}, func(c *context.Context) {
|
||||
c.Data["PageIsSettings"] = true
|
||||
})
|
||||
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef())
|
||||
|
||||
m.Post("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action)
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Get("/issues", repo.RetrieveLabels, repo.Issues)
|
||||
m.Get("/issues/:index", repo.ViewIssue)
|
||||
m.Get("/labels/", repo.RetrieveLabels, repo.Labels)
|
||||
m.Get("/milestones", repo.Milestones)
|
||||
}, ignSignIn, context.RepoAssignment(true))
|
||||
m.Group("/:username/:reponame", func() {
|
||||
// FIXME: should use different URLs but mostly same logic for comments of issue and pull request.
|
||||
// So they can apply their own enable/disable logic on routers.
|
||||
m.Group("/issues", func() {
|
||||
m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue).
|
||||
Post(bindIgnErr(form.NewIssue{}), repo.NewIssuePost)
|
||||
|
||||
m.Group("/:index", func() {
|
||||
m.Post("/title", repo.UpdateIssueTitle)
|
||||
m.Post("/content", repo.UpdateIssueContent)
|
||||
m.Combo("/comments").Post(bindIgnErr(form.CreateComment{}), repo.NewComment)
|
||||
})
|
||||
})
|
||||
m.Group("/comments/:id", func() {
|
||||
m.Post("", repo.UpdateCommentContent)
|
||||
m.Post("/delete", repo.DeleteComment)
|
||||
})
|
||||
}, reqSignIn, context.RepoAssignment(true))
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Group("/wiki", func() {
|
||||
m.Get("/?:page", repo.Wiki)
|
||||
m.Get("/_pages", repo.WikiPages)
|
||||
}, repo.MustEnableWiki, context.RepoRef())
|
||||
}, ignSignIn, context.RepoAssignment(false, true))
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
// FIXME: should use different URLs but mostly same logic for comments of issue and pull request.
|
||||
// So they can apply their own enable/disable logic on routers.
|
||||
m.Group("/issues", func() {
|
||||
m.Group("/:index", func() {
|
||||
m.Post("/label", repo.UpdateIssueLabel)
|
||||
m.Post("/milestone", repo.UpdateIssueMilestone)
|
||||
m.Post("/assignee", repo.UpdateIssueAssignee)
|
||||
}, reqRepoWriter)
|
||||
})
|
||||
m.Group("/labels", func() {
|
||||
m.Post("/new", bindIgnErr(form.CreateLabel{}), repo.NewLabel)
|
||||
m.Post("/edit", bindIgnErr(form.CreateLabel{}), repo.UpdateLabel)
|
||||
m.Post("/delete", repo.DeleteLabel)
|
||||
m.Post("/initialize", bindIgnErr(form.InitializeLabels{}), repo.InitializeLabels)
|
||||
}, reqRepoWriter, context.RepoRef())
|
||||
m.Group("/milestones", func() {
|
||||
m.Combo("/new").Get(repo.NewMilestone).
|
||||
Post(bindIgnErr(form.CreateMilestone{}), repo.NewMilestonePost)
|
||||
m.Get("/:id/edit", repo.EditMilestone)
|
||||
m.Post("/:id/edit", bindIgnErr(form.CreateMilestone{}), repo.EditMilestonePost)
|
||||
m.Get("/:id/:action", repo.ChangeMilestonStatus)
|
||||
m.Post("/delete", repo.DeleteMilestone)
|
||||
}, reqRepoWriter, context.RepoRef())
|
||||
|
||||
m.Group("/releases", func() {
|
||||
m.Get("/new", repo.NewRelease)
|
||||
m.Post("/new", bindIgnErr(form.NewRelease{}), repo.NewReleasePost)
|
||||
m.Post("/delete", repo.DeleteRelease)
|
||||
m.Get("/edit/*", repo.EditRelease)
|
||||
m.Post("/edit/*", bindIgnErr(form.EditRelease{}), repo.EditReleasePost)
|
||||
}, repo.MustBeNotBare, reqRepoWriter, func(c *context.Context) {
|
||||
c.Data["PageIsViewFiles"] = true
|
||||
})
|
||||
|
||||
// FIXME: Should use c.Repo.PullRequest to unify template, currently we have inconsistent URL
|
||||
// for PR in same repository. After select branch on the page, the URL contains redundant head user name.
|
||||
// e.g. /org1/test-repo/compare/master...org1:develop
|
||||
// which should be /org1/test-repo/compare/master...develop
|
||||
m.Combo("/compare/*", repo.MustAllowPulls).Get(repo.CompareAndPullRequest).
|
||||
Post(bindIgnErr(form.NewIssue{}), repo.CompareAndPullRequestPost)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Combo("/_edit/*").Get(repo.EditFile).
|
||||
Post(bindIgnErr(form.EditRepoFile{}), repo.EditFilePost)
|
||||
m.Combo("/_new/*").Get(repo.NewFile).
|
||||
Post(bindIgnErr(form.EditRepoFile{}), repo.NewFilePost)
|
||||
m.Post("/_preview/*", bindIgnErr(form.EditPreviewDiff{}), repo.DiffPreviewPost)
|
||||
m.Combo("/_delete/*").Get(repo.DeleteFile).
|
||||
Post(bindIgnErr(form.DeleteRepoFile{}), repo.DeleteFilePost)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Combo("/_upload/*").Get(repo.UploadFile).
|
||||
Post(bindIgnErr(form.UploadRepoFile{}), repo.UploadFilePost)
|
||||
m.Post("/upload-file", repo.UploadFileToServer)
|
||||
m.Post("/upload-remove", bindIgnErr(form.RemoveUploadFile{}), repo.RemoveUploadFileFromServer)
|
||||
}, func(c *context.Context) {
|
||||
if !conf.Repository.Upload.Enabled {
|
||||
c.NotFound()
|
||||
return
|
||||
}
|
||||
})
|
||||
}, repo.MustBeNotBare, reqRepoWriter, context.RepoRef(), func(c *context.Context) {
|
||||
if !c.Repo.CanEnableEditor() {
|
||||
c.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["PageIsViewFiles"] = true
|
||||
})
|
||||
}, reqSignIn, context.RepoAssignment())
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Group("", func() {
|
||||
m.Get("/releases", repo.MustBeNotBare, repo.Releases)
|
||||
m.Get("/pulls", repo.RetrieveLabels, repo.Pulls)
|
||||
m.Get("/pulls/:index", repo.ViewPull)
|
||||
}, context.RepoRef())
|
||||
|
||||
m.Group("/branches", func() {
|
||||
m.Get("", repo.Branches)
|
||||
m.Get("/all", repo.AllBranches)
|
||||
m.Post("/delete/*", reqSignIn, reqRepoWriter, repo.DeleteBranchPost)
|
||||
}, repo.MustBeNotBare, func(c *context.Context) {
|
||||
c.Data["PageIsViewFiles"] = true
|
||||
})
|
||||
|
||||
m.Group("/wiki", func() {
|
||||
m.Group("", func() {
|
||||
m.Combo("/_new").Get(repo.NewWiki).
|
||||
Post(bindIgnErr(form.NewWiki{}), repo.NewWikiPost)
|
||||
m.Combo("/:page/_edit").Get(repo.EditWiki).
|
||||
Post(bindIgnErr(form.NewWiki{}), repo.EditWikiPost)
|
||||
m.Post("/:page/delete", repo.DeleteWikiPagePost)
|
||||
}, reqSignIn, reqRepoWriter)
|
||||
}, repo.MustEnableWiki, context.RepoRef())
|
||||
|
||||
m.Get("/archive/*", repo.MustBeNotBare, repo.Download)
|
||||
|
||||
m.Group("/pulls/:index", func() {
|
||||
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
|
||||
m.Get("/files", context.RepoRef(), repo.ViewPullFiles)
|
||||
m.Post("/merge", reqRepoWriter, repo.MergePullRequest)
|
||||
}, repo.MustAllowPulls)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Get("/src/*", repo.Home)
|
||||
m.Get("/raw/*", repo.SingleDownload)
|
||||
m.Get("/commits/*", repo.RefCommits)
|
||||
m.Get("/commit/:sha([a-f0-9]{7,40})$", repo.Diff)
|
||||
m.Get("/forks", repo.Forks)
|
||||
}, repo.MustBeNotBare, context.RepoRef())
|
||||
m.Get("/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)", repo.MustBeNotBare, repo.RawDiff)
|
||||
|
||||
m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.MustBeNotBare, context.RepoRef(), repo.CompareDiff)
|
||||
}, ignSignIn, context.RepoAssignment())
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Get("", repo.Home)
|
||||
m.Get("/stars", repo.Stars)
|
||||
m.Get("/watchers", repo.Watchers)
|
||||
}, context.ServeGoGet(), ignSignIn, context.RepoAssignment(), context.RepoRef())
|
||||
// ***** END: Repository *****
|
||||
|
||||
// **********************
|
||||
// ----- API routes -----
|
||||
// **********************
|
||||
|
||||
// TODO: Without session and CSRF
|
||||
m.Group("/api", func() {
|
||||
apiv1.RegisterRoutes(m)
|
||||
}, ignSignIn)
|
||||
},
|
||||
session.Sessioner(session.Options{
|
||||
Provider: conf.Session.Provider,
|
||||
ProviderConfig: conf.Session.ProviderConfig,
|
||||
CookieName: conf.Session.CookieName,
|
||||
CookiePath: conf.Server.Subpath,
|
||||
Gclifetime: conf.Session.GCInterval,
|
||||
Maxlifetime: conf.Session.MaxLifeTime,
|
||||
Secure: conf.Session.CookieSecure,
|
||||
}),
|
||||
csrf.Csrfer(csrf.Options{
|
||||
Secret: conf.Security.SecretKey,
|
||||
Header: "X-CSRF-Token",
|
||||
Cookie: conf.Session.CSRFCookieName,
|
||||
CookieDomain: conf.Server.URL.Hostname(),
|
||||
CookiePath: conf.Server.Subpath,
|
||||
CookieHttpOnly: true,
|
||||
SetCookie: true,
|
||||
Secure: conf.Server.URL.Scheme == "https",
|
||||
}),
|
||||
context.Contexter(context.NewStore()),
|
||||
)
|
||||
|
||||
// ***************************
|
||||
// ----- HTTP Git routes -----
|
||||
// ***************************
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Get("/tasks/trigger", repo.TriggerTask)
|
||||
|
||||
m.Group("/info/lfs", func() {
|
||||
lfs.RegisterRoutes(m.Router)
|
||||
})
|
||||
|
||||
m.Route("/*", "GET,POST,OPTIONS", context.ServeGoGet(), repo.HTTPContexter(repo.NewStore()), repo.HTTP)
|
||||
})
|
||||
|
||||
// ***************************
|
||||
// ----- Internal routes -----
|
||||
// ***************************
|
||||
|
||||
m.Group("/-", func() {
|
||||
m.Get("/metrics", app.MetricsFilter(), promhttp.Handler()) // "/-/metrics"
|
||||
|
||||
m.Group("/api", func() {
|
||||
m.Post("/sanitize_ipynb", app.SanitizeIpynb()) // "/-/api/sanitize_ipynb"
|
||||
})
|
||||
})
|
||||
|
||||
// **********************
|
||||
// ----- robots.txt -----
|
||||
// **********************
|
||||
|
||||
m.Get("/robots.txt", func(w http.ResponseWriter, r *http.Request) {
|
||||
if conf.HasRobotsTxt {
|
||||
http.ServeFile(w, r, filepath.Join(conf.CustomDir(), "robots.txt"))
|
||||
} else {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
})
|
||||
|
||||
m.NotFound(route.NotFound)
|
||||
|
||||
// Flag for port number in case first time run conflict.
|
||||
if cmd.IsSet("port") {
|
||||
conf.Server.URL.Host = strings.Replace(conf.Server.URL.Host, ":"+conf.Server.URL.Port(), ":"+cmd.String("port"), 1)
|
||||
conf.Server.ExternalURL = conf.Server.URL.String()
|
||||
conf.Server.HTTPPort = cmd.String("port")
|
||||
}
|
||||
|
||||
var listenAddr string
|
||||
if conf.Server.Protocol == "unix" {
|
||||
listenAddr = conf.Server.HTTPAddr
|
||||
} else {
|
||||
listenAddr = fmt.Sprintf("%s:%s", conf.Server.HTTPAddr, conf.Server.HTTPPort)
|
||||
}
|
||||
log.Info("Available on %s", conf.Server.ExternalURL)
|
||||
|
||||
switch conf.Server.Protocol {
|
||||
case "http":
|
||||
err = http.ListenAndServe(listenAddr, m)
|
||||
|
||||
case "https":
|
||||
tlsMinVersion := tls.VersionTLS12
|
||||
switch conf.Server.TLSMinVersion {
|
||||
case "TLS13":
|
||||
tlsMinVersion = tls.VersionTLS13
|
||||
case "TLS12":
|
||||
tlsMinVersion = tls.VersionTLS12
|
||||
case "TLS11":
|
||||
tlsMinVersion = tls.VersionTLS11
|
||||
case "TLS10":
|
||||
tlsMinVersion = tls.VersionTLS10
|
||||
}
|
||||
server := &http.Server{
|
||||
Addr: listenAddr,
|
||||
TLSConfig: &tls.Config{
|
||||
MinVersion: uint16(tlsMinVersion),
|
||||
CurvePreferences: []tls.CurveID{tls.X25519, tls.CurveP256, tls.CurveP384, tls.CurveP521},
|
||||
PreferServerCipherSuites: true,
|
||||
CipherSuites: []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,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
},
|
||||
}, Handler: m,
|
||||
}
|
||||
err = server.ListenAndServeTLS(conf.Server.CertFile, conf.Server.KeyFile)
|
||||
|
||||
case "fcgi":
|
||||
err = fcgi.Serve(nil, m)
|
||||
|
||||
case "unix":
|
||||
if osx.Exist(listenAddr) {
|
||||
err = os.Remove(listenAddr)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to remove existing Unix domain socket: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
var listener *net.UnixListener
|
||||
listener, err = net.ListenUnix("unix", &net.UnixAddr{Name: listenAddr, Net: "unix"})
|
||||
if err != nil {
|
||||
log.Fatal("Failed to listen on Unix networks: %v", err)
|
||||
}
|
||||
|
||||
// FIXME: add proper implementation of signal capture on all protocols
|
||||
// execute this on SIGTERM or SIGINT: listener.Close()
|
||||
if err = os.Chmod(listenAddr, conf.Server.UnixSocketMode); err != nil {
|
||||
log.Fatal("Failed to change permission of Unix domain socket: %v", err)
|
||||
}
|
||||
err = http.Serve(listener, m)
|
||||
|
||||
default:
|
||||
log.Fatal("Unexpected server protocol: %s", conf.Server.Protocol)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("Failed to start server: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
296
cmd/serve.go
296
cmd/serve.go
@@ -1,296 +0,0 @@
|
||||
// Copyright 2014 The Gogs 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"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
git "github.com/gogits/git-module"
|
||||
gouuid "github.com/satori/go.uuid"
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/httplib"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
_ACCESS_DENIED_MESSAGE = "Repository does not exist or you do not have access"
|
||||
)
|
||||
|
||||
var CmdServ = cli.Command{
|
||||
Name: "serv",
|
||||
Usage: "This command should only be called by SSH shell",
|
||||
Description: `Serv provide access auth for repositories`,
|
||||
Action: runServ,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
func setup(logPath string) {
|
||||
setting.NewContext()
|
||||
log.NewGitLogger(filepath.Join(setting.LogRootPath, logPath))
|
||||
|
||||
models.LoadConfigs()
|
||||
|
||||
if setting.UseSQLite3 || setting.UseTiDB {
|
||||
workDir, _ := setting.WorkDir()
|
||||
os.Chdir(workDir)
|
||||
}
|
||||
|
||||
models.SetEngine()
|
||||
}
|
||||
|
||||
func parseCmd(cmd string) (string, string) {
|
||||
ss := strings.SplitN(cmd, " ", 2)
|
||||
if len(ss) != 2 {
|
||||
return "", ""
|
||||
}
|
||||
return ss[0], strings.Replace(ss[1], "'/", "'", 1)
|
||||
}
|
||||
|
||||
var (
|
||||
allowedCommands = map[string]models.AccessMode{
|
||||
"git-upload-pack": models.ACCESS_MODE_READ,
|
||||
"git-upload-archive": models.ACCESS_MODE_READ,
|
||||
"git-receive-pack": models.ACCESS_MODE_WRITE,
|
||||
}
|
||||
)
|
||||
|
||||
func fail(userMessage, logMessage string, args ...interface{}) {
|
||||
fmt.Fprintln(os.Stderr, "Gogs:", userMessage)
|
||||
|
||||
if len(logMessage) > 0 {
|
||||
if !setting.ProdMode {
|
||||
fmt.Fprintf(os.Stderr, logMessage+"\n", args...)
|
||||
}
|
||||
log.GitLogger.Fatal(3, logMessage, args...)
|
||||
return
|
||||
}
|
||||
|
||||
log.GitLogger.Close()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func handleUpdateTask(uuid string, user, repoUser *models.User, reponame string, isWiki bool) {
|
||||
task, err := models.GetUpdateTaskByUUID(uuid)
|
||||
if err != nil {
|
||||
if models.IsErrUpdateTaskNotExist(err) {
|
||||
log.GitLogger.Trace("No update task is presented: %s", uuid)
|
||||
return
|
||||
}
|
||||
log.GitLogger.Fatal(2, "GetUpdateTaskByUUID: %v", err)
|
||||
} else if err = models.DeleteUpdateTaskByUUID(uuid); err != nil {
|
||||
log.GitLogger.Fatal(2, "DeleteUpdateTaskByUUID: %v", err)
|
||||
}
|
||||
|
||||
if isWiki {
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.PushUpdate(models.PushUpdateOptions{
|
||||
RefFullName: task.RefName,
|
||||
OldCommitID: task.OldCommitID,
|
||||
NewCommitID: task.NewCommitID,
|
||||
PusherID: user.ID,
|
||||
PusherName: user.Name,
|
||||
RepoUserName: repoUser.Name,
|
||||
RepoName: reponame,
|
||||
}); err != nil {
|
||||
log.GitLogger.Error(2, "Update: %v", err)
|
||||
}
|
||||
|
||||
// Ask for running deliver hook and test pull request tasks.
|
||||
reqURL := setting.LocalURL + repoUser.Name + "/" + reponame + "/tasks/trigger?branch=" +
|
||||
strings.TrimPrefix(task.RefName, git.BRANCH_PREFIX) + "&secret=" + base.EncodeMD5(repoUser.Salt) + "&pusher=" + com.ToStr(user.ID)
|
||||
log.GitLogger.Trace("Trigger task: %s", reqURL)
|
||||
|
||||
resp, err := httplib.Head(reqURL).SetTLSClientConfig(&tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}).Response()
|
||||
if err == nil {
|
||||
resp.Body.Close()
|
||||
if resp.StatusCode/100 != 2 {
|
||||
log.GitLogger.Error(2, "Fail to trigger task: not 2xx response code")
|
||||
}
|
||||
} else {
|
||||
log.GitLogger.Error(2, "Fail to trigger task: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func runServ(c *cli.Context) error {
|
||||
if c.IsSet("config") {
|
||||
setting.CustomConf = c.String("config")
|
||||
}
|
||||
|
||||
setup("serv.log")
|
||||
|
||||
if setting.SSH.Disabled {
|
||||
println("Gogs: SSH has been disabled")
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(c.Args()) < 1 {
|
||||
fail("Not enough arguments", "Not enough arguments")
|
||||
}
|
||||
|
||||
cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
|
||||
if len(cmd) == 0 {
|
||||
println("Hi there, You've successfully authenticated, but Gogs does not provide shell access.")
|
||||
println("If this is unexpected, please log in with password and setup Gogs under another user.")
|
||||
return nil
|
||||
}
|
||||
|
||||
verb, args := parseCmd(cmd)
|
||||
repoPath := strings.ToLower(strings.Trim(args, "'"))
|
||||
rr := strings.SplitN(repoPath, "/", 2)
|
||||
if len(rr) != 2 {
|
||||
fail("Invalid repository path", "Invalid repository path: %v", args)
|
||||
}
|
||||
username := strings.ToLower(rr[0])
|
||||
reponame := strings.ToLower(strings.TrimSuffix(rr[1], ".git"))
|
||||
|
||||
isWiki := false
|
||||
if strings.HasSuffix(reponame, ".wiki") {
|
||||
isWiki = true
|
||||
reponame = reponame[:len(reponame)-5]
|
||||
}
|
||||
|
||||
repoUser, err := models.GetUserByName(username)
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
fail("Repository owner does not exist", "Unregistered owner: %s", username)
|
||||
}
|
||||
fail("Internal error", "Failed to get repository owner (%s): %v", username, err)
|
||||
}
|
||||
|
||||
repo, err := models.GetRepositoryByName(repoUser.ID, reponame)
|
||||
if err != nil {
|
||||
if models.IsErrRepoNotExist(err) {
|
||||
fail(_ACCESS_DENIED_MESSAGE, "Repository does not exist: %s/%s", repoUser.Name, reponame)
|
||||
}
|
||||
fail("Internal error", "Failed to get repository: %v", err)
|
||||
}
|
||||
|
||||
requestedMode, has := allowedCommands[verb]
|
||||
if !has {
|
||||
fail("Unknown git command", "Unknown git command %s", verb)
|
||||
}
|
||||
|
||||
// Prohibit push to mirror repositories.
|
||||
if requestedMode > models.ACCESS_MODE_READ && repo.IsMirror {
|
||||
fail("mirror repository is read-only", "")
|
||||
}
|
||||
|
||||
// Allow anonymous clone for public repositories.
|
||||
var (
|
||||
keyID int64
|
||||
user *models.User
|
||||
)
|
||||
if requestedMode == models.ACCESS_MODE_WRITE || repo.IsPrivate {
|
||||
keys := strings.Split(c.Args()[0], "-")
|
||||
if len(keys) != 2 {
|
||||
fail("Key ID format error", "Invalid key argument: %s", c.Args()[0])
|
||||
}
|
||||
|
||||
key, err := models.GetPublicKeyByID(com.StrTo(keys[1]).MustInt64())
|
||||
if err != nil {
|
||||
fail("Invalid key ID", "Invalid key ID[%s]: %v", c.Args()[0], err)
|
||||
}
|
||||
keyID = key.ID
|
||||
|
||||
// Check deploy key or user key.
|
||||
if key.Type == models.KEY_TYPE_DEPLOY {
|
||||
if key.Mode < requestedMode {
|
||||
fail("Key permission denied", "Cannot push with deployment key: %d", key.ID)
|
||||
}
|
||||
// Check if this deploy key belongs to current repository.
|
||||
if !models.HasDeployKey(key.ID, repo.ID) {
|
||||
fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
|
||||
}
|
||||
|
||||
// Update deploy key activity.
|
||||
deployKey, err := models.GetDeployKeyByRepo(key.ID, repo.ID)
|
||||
if err != nil {
|
||||
fail("Internal error", "GetDeployKey: %v", err)
|
||||
}
|
||||
|
||||
deployKey.Updated = time.Now()
|
||||
if err = models.UpdateDeployKey(deployKey); err != nil {
|
||||
fail("Internal error", "UpdateDeployKey: %v", err)
|
||||
}
|
||||
} else {
|
||||
user, err = models.GetUserByKeyID(key.ID)
|
||||
if err != nil {
|
||||
fail("internal error", "Failed to get user by key ID(%d): %v", keyID, err)
|
||||
}
|
||||
|
||||
mode, err := models.AccessLevel(user, repo)
|
||||
if err != nil {
|
||||
fail("Internal error", "Fail to check access: %v", err)
|
||||
} else if mode < requestedMode {
|
||||
clientMessage := _ACCESS_DENIED_MESSAGE
|
||||
if mode >= models.ACCESS_MODE_READ {
|
||||
clientMessage = "You do not have sufficient authorization for this action"
|
||||
}
|
||||
fail(clientMessage,
|
||||
"User %s does not have level %v access to repository %s",
|
||||
user.Name, requestedMode, repoPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uuid := gouuid.NewV4().String()
|
||||
os.Setenv("uuid", uuid)
|
||||
|
||||
// Special handle for Windows.
|
||||
if setting.IsWindows {
|
||||
verb = strings.Replace(verb, "-", " ", 1)
|
||||
}
|
||||
|
||||
var gitcmd *exec.Cmd
|
||||
verbs := strings.Split(verb, " ")
|
||||
if len(verbs) == 2 {
|
||||
gitcmd = exec.Command(verbs[0], verbs[1], repoPath)
|
||||
} else {
|
||||
gitcmd = exec.Command(verb, repoPath)
|
||||
}
|
||||
gitcmd.Dir = setting.RepoRootPath
|
||||
gitcmd.Stdout = os.Stdout
|
||||
gitcmd.Stdin = os.Stdin
|
||||
gitcmd.Stderr = os.Stderr
|
||||
if err = gitcmd.Run(); err != nil {
|
||||
fail("Internal error", "Failed to execute git command: %v", err)
|
||||
}
|
||||
|
||||
if requestedMode == models.ACCESS_MODE_WRITE {
|
||||
handleUpdateTask(uuid, user, repoUser, reponame, isWiki)
|
||||
}
|
||||
|
||||
// Update user key activity.
|
||||
if keyID > 0 {
|
||||
key, err := models.GetPublicKeyByID(keyID)
|
||||
if err != nil {
|
||||
fail("Internal error", "GetPublicKeyById: %v", err)
|
||||
}
|
||||
|
||||
key.Updated = time.Now()
|
||||
if err = models.UpdatePublicKey(key); err != nil {
|
||||
fail("Internal error", "UpdatePublicKey: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
// Copyright 2014 The Gogs 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 (
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
var CmdUpdate = cli.Command{
|
||||
Name: "update",
|
||||
Usage: "This command should only be called by Git hook",
|
||||
Description: `Update get pushed info and insert into database`,
|
||||
Action: runUpdate,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
func runUpdate(c *cli.Context) error {
|
||||
if c.IsSet("config") {
|
||||
setting.CustomConf = c.String("config")
|
||||
}
|
||||
|
||||
setup("update.log")
|
||||
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
log.GitLogger.Trace("SSH_ORIGINAL_COMMAND is empty")
|
||||
return nil
|
||||
}
|
||||
|
||||
args := c.Args()
|
||||
if len(args) != 3 {
|
||||
log.GitLogger.Fatal(2, "Arguments received are not equal to three")
|
||||
} else if len(args[0]) == 0 {
|
||||
log.GitLogger.Fatal(2, "First argument 'refName' is empty, shouldn't use")
|
||||
}
|
||||
|
||||
task := models.UpdateTask{
|
||||
UUID: os.Getenv("uuid"),
|
||||
RefName: args[0],
|
||||
OldCommitID: args[1],
|
||||
NewCommitID: args[2],
|
||||
}
|
||||
|
||||
if err := models.AddUpdateTask(&task); err != nil {
|
||||
log.GitLogger.Fatal(2, "AddUpdateTask: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
659
cmd/web.go
659
cmd/web.go
@@ -1,659 +0,0 @@
|
||||
// Copyright 2014 The Gogs 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"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/fcgi"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/go-macaron/binding"
|
||||
"github.com/go-macaron/cache"
|
||||
"github.com/go-macaron/captcha"
|
||||
"github.com/go-macaron/csrf"
|
||||
"github.com/go-macaron/gzip"
|
||||
"github.com/go-macaron/i18n"
|
||||
"github.com/go-macaron/session"
|
||||
"github.com/go-macaron/toolbox"
|
||||
"github.com/go-xorm/xorm"
|
||||
"github.com/mcuadros/go-version"
|
||||
"github.com/urfave/cli"
|
||||
"gopkg.in/ini.v1"
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"github.com/gogits/git-module"
|
||||
"github.com/gogits/go-gogs-client"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/bindata"
|
||||
"github.com/gogits/gogs/modules/context"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
"github.com/gogits/gogs/modules/template"
|
||||
"github.com/gogits/gogs/routers"
|
||||
"github.com/gogits/gogs/routers/admin"
|
||||
apiv1 "github.com/gogits/gogs/routers/api/v1"
|
||||
"github.com/gogits/gogs/routers/dev"
|
||||
"github.com/gogits/gogs/routers/org"
|
||||
"github.com/gogits/gogs/routers/repo"
|
||||
"github.com/gogits/gogs/routers/user"
|
||||
)
|
||||
|
||||
var CmdWeb = cli.Command{
|
||||
Name: "web",
|
||||
Usage: "Start Gogs web server",
|
||||
Description: `Gogs web server is the only thing you need to run,
|
||||
and it takes care of all the other things for you`,
|
||||
Action: runWeb,
|
||||
Flags: []cli.Flag{
|
||||
stringFlag("port, p", "3000", "Temporary port number to prevent conflict"),
|
||||
stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
|
||||
},
|
||||
}
|
||||
|
||||
type VerChecker struct {
|
||||
ImportPath string
|
||||
Version func() string
|
||||
Expected string
|
||||
}
|
||||
|
||||
// checkVersion checks if binary matches the version of templates files.
|
||||
func checkVersion() {
|
||||
// Templates.
|
||||
data, err := ioutil.ReadFile(setting.StaticRootPath + "/templates/.VERSION")
|
||||
if err != nil {
|
||||
log.Fatal(4, "Fail to read 'templates/.VERSION': %v", err)
|
||||
}
|
||||
tplVer := string(data)
|
||||
if tplVer != setting.AppVer {
|
||||
if version.Compare(tplVer, setting.AppVer, ">") {
|
||||
log.Fatal(4, "Binary version is lower than template file version, did you forget to recompile Gogs?")
|
||||
} else {
|
||||
log.Fatal(4, "Binary version is higher than template file version, did you forget to update template files?")
|
||||
}
|
||||
}
|
||||
|
||||
// Check dependency version.
|
||||
checkers := []VerChecker{
|
||||
{"github.com/go-xorm/xorm", func() string { return xorm.Version }, "0.5.5"},
|
||||
{"github.com/go-macaron/binding", binding.Version, "0.3.2"},
|
||||
{"github.com/go-macaron/cache", cache.Version, "0.1.2"},
|
||||
{"github.com/go-macaron/csrf", csrf.Version, "0.1.0"},
|
||||
{"github.com/go-macaron/i18n", i18n.Version, "0.3.0"},
|
||||
{"github.com/go-macaron/session", session.Version, "0.1.6"},
|
||||
{"github.com/go-macaron/toolbox", toolbox.Version, "0.1.0"},
|
||||
{"gopkg.in/ini.v1", ini.Version, "1.8.4"},
|
||||
{"gopkg.in/macaron.v1", macaron.Version, "1.1.7"},
|
||||
{"github.com/gogits/git-module", git.Version, "0.4.1"},
|
||||
{"github.com/gogits/go-gogs-client", gogs.Version, "0.12.1"},
|
||||
}
|
||||
for _, c := range checkers {
|
||||
if !version.Compare(c.Version(), c.Expected, ">=") {
|
||||
log.Fatal(4, `Dependency outdated!
|
||||
Package '%s' current version (%s) is below requirement (%s),
|
||||
please use following command to update this package and recompile Gogs:
|
||||
go get -u %[1]s`, c.ImportPath, c.Version(), c.Expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// newMacaron initializes Macaron instance.
|
||||
func newMacaron() *macaron.Macaron {
|
||||
m := macaron.New()
|
||||
if !setting.DisableRouterLog {
|
||||
m.Use(macaron.Logger())
|
||||
}
|
||||
m.Use(macaron.Recovery())
|
||||
if setting.EnableGzip {
|
||||
m.Use(gzip.Gziper())
|
||||
}
|
||||
if setting.Protocol == setting.FCGI {
|
||||
m.SetURLPrefix(setting.AppSubUrl)
|
||||
}
|
||||
m.Use(macaron.Static(
|
||||
path.Join(setting.StaticRootPath, "public"),
|
||||
macaron.StaticOptions{
|
||||
SkipLogging: setting.DisableRouterLog,
|
||||
},
|
||||
))
|
||||
m.Use(macaron.Static(
|
||||
setting.AvatarUploadPath,
|
||||
macaron.StaticOptions{
|
||||
Prefix: "avatars",
|
||||
SkipLogging: setting.DisableRouterLog,
|
||||
},
|
||||
))
|
||||
|
||||
funcMap := template.NewFuncMap()
|
||||
m.Use(macaron.Renderer(macaron.RenderOptions{
|
||||
Directory: path.Join(setting.StaticRootPath, "templates"),
|
||||
AppendDirectories: []string{path.Join(setting.CustomPath, "templates")},
|
||||
Funcs: funcMap,
|
||||
IndentJSON: macaron.Env != macaron.PROD,
|
||||
}))
|
||||
models.InitMailRender(path.Join(setting.StaticRootPath, "templates/mail"),
|
||||
path.Join(setting.CustomPath, "templates/mail"), funcMap)
|
||||
|
||||
localeNames, err := bindata.AssetDir("conf/locale")
|
||||
if err != nil {
|
||||
log.Fatal(4, "Fail to list locale files: %v", err)
|
||||
}
|
||||
localFiles := make(map[string][]byte)
|
||||
for _, name := range localeNames {
|
||||
localFiles[name] = bindata.MustAsset("conf/locale/" + name)
|
||||
}
|
||||
m.Use(i18n.I18n(i18n.Options{
|
||||
SubURL: setting.AppSubUrl,
|
||||
Files: localFiles,
|
||||
CustomDirectory: path.Join(setting.CustomPath, "conf/locale"),
|
||||
Langs: setting.Langs,
|
||||
Names: setting.Names,
|
||||
DefaultLang: "en-US",
|
||||
Redirect: true,
|
||||
}))
|
||||
m.Use(cache.Cacher(cache.Options{
|
||||
Adapter: setting.CacheAdapter,
|
||||
AdapterConfig: setting.CacheConn,
|
||||
Interval: setting.CacheInterval,
|
||||
}))
|
||||
m.Use(captcha.Captchaer(captcha.Options{
|
||||
SubURL: setting.AppSubUrl,
|
||||
}))
|
||||
m.Use(session.Sessioner(setting.SessionConfig))
|
||||
m.Use(csrf.Csrfer(csrf.Options{
|
||||
Secret: setting.SecretKey,
|
||||
Cookie: setting.CSRFCookieName,
|
||||
SetCookie: true,
|
||||
Header: "X-Csrf-Token",
|
||||
CookiePath: setting.AppSubUrl,
|
||||
}))
|
||||
m.Use(toolbox.Toolboxer(m, toolbox.Options{
|
||||
HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{
|
||||
&toolbox.HealthCheckFuncDesc{
|
||||
Desc: "Database connection",
|
||||
Func: models.Ping,
|
||||
},
|
||||
},
|
||||
}))
|
||||
m.Use(context.Contexter())
|
||||
return m
|
||||
}
|
||||
|
||||
func runWeb(ctx *cli.Context) error {
|
||||
if ctx.IsSet("config") {
|
||||
setting.CustomConf = ctx.String("config")
|
||||
}
|
||||
routers.GlobalInit()
|
||||
checkVersion()
|
||||
|
||||
m := newMacaron()
|
||||
|
||||
reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: true})
|
||||
ignSignIn := context.Toggle(&context.ToggleOptions{SignInRequired: setting.Service.RequireSignInView})
|
||||
ignSignInAndCsrf := context.Toggle(&context.ToggleOptions{DisableCSRF: true})
|
||||
reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequired: true})
|
||||
|
||||
bindIgnErr := binding.BindIgnErr
|
||||
|
||||
// FIXME: not all routes need go through same middlewares.
|
||||
// Especially some AJAX requests, we can reduce middleware number to improve performance.
|
||||
// Routers.
|
||||
m.Get("/", ignSignIn, routers.Home)
|
||||
m.Group("/explore", func() {
|
||||
m.Get("", func(ctx *context.Context) {
|
||||
ctx.Redirect(setting.AppSubUrl + "/explore/repos")
|
||||
})
|
||||
m.Get("/repos", routers.ExploreRepos)
|
||||
m.Get("/users", routers.ExploreUsers)
|
||||
}, ignSignIn)
|
||||
m.Combo("/install", routers.InstallInit).Get(routers.Install).
|
||||
Post(bindIgnErr(auth.InstallForm{}), routers.InstallPost)
|
||||
m.Get("/^:type(issues|pulls)$", reqSignIn, user.Issues)
|
||||
|
||||
// ***** START: User *****
|
||||
m.Group("/user", func() {
|
||||
m.Get("/login", user.SignIn)
|
||||
m.Post("/login", bindIgnErr(auth.SignInForm{}), user.SignInPost)
|
||||
m.Get("/sign_up", user.SignUp)
|
||||
m.Post("/sign_up", bindIgnErr(auth.RegisterForm{}), user.SignUpPost)
|
||||
m.Get("/reset_password", user.ResetPasswd)
|
||||
m.Post("/reset_password", user.ResetPasswdPost)
|
||||
}, reqSignOut)
|
||||
|
||||
m.Group("/user/settings", func() {
|
||||
m.Get("", user.Settings)
|
||||
m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
|
||||
m.Combo("/avatar").Get(user.SettingsAvatar).
|
||||
Post(binding.MultipartForm(auth.AvatarForm{}), user.SettingsAvatarPost)
|
||||
m.Post("/avatar/delete", user.SettingsDeleteAvatar)
|
||||
m.Combo("/email").Get(user.SettingsEmails).
|
||||
Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
|
||||
m.Post("/email/delete", user.DeleteEmail)
|
||||
m.Get("/password", user.SettingsPassword)
|
||||
m.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost)
|
||||
m.Combo("/ssh").Get(user.SettingsSSHKeys).
|
||||
Post(bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost)
|
||||
m.Post("/ssh/delete", user.DeleteSSHKey)
|
||||
m.Combo("/applications").Get(user.SettingsApplications).
|
||||
Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost)
|
||||
m.Post("/applications/delete", user.SettingsDeleteApplication)
|
||||
m.Route("/delete", "GET,POST", user.SettingsDelete)
|
||||
}, reqSignIn, func(ctx *context.Context) {
|
||||
ctx.Data["PageIsUserSettings"] = true
|
||||
})
|
||||
|
||||
m.Group("/user", func() {
|
||||
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds)
|
||||
m.Any("/activate", user.Activate)
|
||||
m.Any("/activate_email", user.ActivateEmail)
|
||||
m.Get("/email2user", user.Email2User)
|
||||
m.Get("/forget_password", user.ForgotPasswd)
|
||||
m.Post("/forget_password", user.ForgotPasswdPost)
|
||||
m.Get("/logout", user.SignOut)
|
||||
})
|
||||
// ***** END: User *****
|
||||
|
||||
adminReq := context.Toggle(&context.ToggleOptions{SignInRequired: true, AdminRequired: true})
|
||||
|
||||
// ***** START: Admin *****
|
||||
m.Group("/admin", func() {
|
||||
m.Get("", adminReq, admin.Dashboard)
|
||||
m.Get("/config", admin.Config)
|
||||
m.Post("/config/test_mail", admin.SendTestMail)
|
||||
m.Get("/monitor", admin.Monitor)
|
||||
|
||||
m.Group("/users", func() {
|
||||
m.Get("", admin.Users)
|
||||
m.Combo("/new").Get(admin.NewUser).Post(bindIgnErr(auth.AdminCrateUserForm{}), admin.NewUserPost)
|
||||
m.Combo("/:userid").Get(admin.EditUser).Post(bindIgnErr(auth.AdminEditUserForm{}), admin.EditUserPost)
|
||||
m.Post("/:userid/delete", admin.DeleteUser)
|
||||
})
|
||||
|
||||
m.Group("/orgs", func() {
|
||||
m.Get("", admin.Organizations)
|
||||
})
|
||||
|
||||
m.Group("/repos", func() {
|
||||
m.Get("", admin.Repos)
|
||||
m.Post("/delete", admin.DeleteRepo)
|
||||
})
|
||||
|
||||
m.Group("/auths", func() {
|
||||
m.Get("", admin.Authentications)
|
||||
m.Combo("/new").Get(admin.NewAuthSource).Post(bindIgnErr(auth.AuthenticationForm{}), admin.NewAuthSourcePost)
|
||||
m.Combo("/:authid").Get(admin.EditAuthSource).
|
||||
Post(bindIgnErr(auth.AuthenticationForm{}), admin.EditAuthSourcePost)
|
||||
m.Post("/:authid/delete", admin.DeleteAuthSource)
|
||||
})
|
||||
|
||||
m.Group("/notices", func() {
|
||||
m.Get("", admin.Notices)
|
||||
m.Post("/delete", admin.DeleteNotices)
|
||||
m.Get("/empty", admin.EmptyNotices)
|
||||
})
|
||||
}, adminReq)
|
||||
// ***** END: Admin *****
|
||||
|
||||
m.Group("", func() {
|
||||
m.Group("/:username", func() {
|
||||
m.Get("", user.Profile)
|
||||
m.Get("/followers", user.Followers)
|
||||
m.Get("/following", user.Following)
|
||||
m.Get("/stars", user.Stars)
|
||||
})
|
||||
|
||||
m.Get("/attachments/:uuid", func(ctx *context.Context) {
|
||||
attach, err := models.GetAttachmentByUUID(ctx.Params(":uuid"))
|
||||
if err != nil {
|
||||
if models.IsErrAttachmentNotExist(err) {
|
||||
ctx.Error(404)
|
||||
} else {
|
||||
ctx.Handle(500, "GetAttachmentByUUID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
fr, err := os.Open(attach.LocalPath())
|
||||
if err != nil {
|
||||
ctx.Handle(500, "Open", err)
|
||||
return
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
ctx.Header().Set("Cache-Control", "public,max-age=86400")
|
||||
ctx.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, attach.Name))
|
||||
// Fix #312. Attachments with , in their name are not handled correctly by Google Chrome.
|
||||
// We must put the name in " manually.
|
||||
if err = repo.ServeData(ctx, "\""+attach.Name+"\"", fr); err != nil {
|
||||
ctx.Handle(500, "ServeData", err)
|
||||
return
|
||||
}
|
||||
})
|
||||
m.Post("/issues/attachments", repo.UploadIssueAttachment)
|
||||
}, ignSignIn)
|
||||
|
||||
m.Group("/:username", func() {
|
||||
m.Get("/action/:action", user.Action)
|
||||
}, reqSignIn)
|
||||
|
||||
if macaron.Env == macaron.DEV {
|
||||
m.Get("/template/*", dev.TemplatePreview)
|
||||
}
|
||||
|
||||
reqRepoAdmin := context.RequireRepoAdmin()
|
||||
reqRepoWriter := context.RequireRepoWriter()
|
||||
|
||||
// ***** START: Organization *****
|
||||
m.Group("/org", func() {
|
||||
m.Get("/create", org.Create)
|
||||
m.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.CreatePost)
|
||||
|
||||
m.Group("/:org", func() {
|
||||
m.Get("/dashboard", user.Dashboard)
|
||||
m.Get("/^:type(issues|pulls)$", user.Issues)
|
||||
m.Get("/members", org.Members)
|
||||
m.Get("/members/action/:action", org.MembersAction)
|
||||
|
||||
m.Get("/teams", org.Teams)
|
||||
}, context.OrgAssignment(true))
|
||||
|
||||
m.Group("/:org", func() {
|
||||
m.Get("/teams/:team", org.TeamMembers)
|
||||
m.Get("/teams/:team/repositories", org.TeamRepositories)
|
||||
m.Route("/teams/:team/action/:action", "GET,POST", org.TeamsAction)
|
||||
m.Route("/teams/:team/action/repo/:action", "GET,POST", org.TeamsRepoAction)
|
||||
}, context.OrgAssignment(true, false, true))
|
||||
|
||||
m.Group("/:org", func() {
|
||||
m.Get("/teams/new", org.NewTeam)
|
||||
m.Post("/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost)
|
||||
m.Get("/teams/:team/edit", org.EditTeam)
|
||||
m.Post("/teams/:team/edit", bindIgnErr(auth.CreateTeamForm{}), org.EditTeamPost)
|
||||
m.Post("/teams/:team/delete", org.DeleteTeam)
|
||||
|
||||
m.Group("/settings", func() {
|
||||
m.Combo("").Get(org.Settings).
|
||||
Post(bindIgnErr(auth.UpdateOrgSettingForm{}), org.SettingsPost)
|
||||
m.Post("/avatar", binding.MultipartForm(auth.AvatarForm{}), org.SettingsAvatar)
|
||||
m.Post("/avatar/delete", org.SettingsDeleteAvatar)
|
||||
|
||||
m.Group("/hooks", func() {
|
||||
m.Get("", org.Webhooks)
|
||||
m.Post("/delete", org.DeleteWebhook)
|
||||
m.Get("/:type/new", repo.WebhooksNew)
|
||||
m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost)
|
||||
m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost)
|
||||
m.Get("/:id", repo.WebHooksEdit)
|
||||
m.Post("/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
|
||||
m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
|
||||
})
|
||||
|
||||
m.Route("/delete", "GET,POST", org.SettingsDelete)
|
||||
})
|
||||
|
||||
m.Route("/invitations/new", "GET,POST", org.Invitation)
|
||||
}, context.OrgAssignment(true, true))
|
||||
}, reqSignIn)
|
||||
// ***** END: Organization *****
|
||||
|
||||
// ***** START: Repository *****
|
||||
m.Group("/repo", func() {
|
||||
m.Get("/create", repo.Create)
|
||||
m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
|
||||
m.Get("/migrate", repo.Migrate)
|
||||
m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost)
|
||||
m.Combo("/fork/:repoid").Get(repo.Fork).
|
||||
Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost)
|
||||
}, reqSignIn)
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Group("/settings", func() {
|
||||
m.Combo("").Get(repo.Settings).
|
||||
Post(bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost)
|
||||
m.Group("/collaboration", func() {
|
||||
m.Combo("").Get(repo.Collaboration).Post(repo.CollaborationPost)
|
||||
m.Post("/access_mode", repo.ChangeCollaborationAccessMode)
|
||||
m.Post("/delete", repo.DeleteCollaboration)
|
||||
})
|
||||
|
||||
m.Group("/hooks", func() {
|
||||
m.Get("", repo.Webhooks)
|
||||
m.Post("/delete", repo.DeleteWebhook)
|
||||
m.Get("/:type/new", repo.WebhooksNew)
|
||||
m.Post("/gogs/new", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksNewPost)
|
||||
m.Post("/slack/new", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksNewPost)
|
||||
m.Get("/:id", repo.WebHooksEdit)
|
||||
m.Post("/:id/test", repo.TestWebhook)
|
||||
m.Post("/gogs/:id", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksEditPost)
|
||||
m.Post("/slack/:id", bindIgnErr(auth.NewSlackHookForm{}), repo.SlackHooksEditPost)
|
||||
|
||||
m.Group("/git", func() {
|
||||
m.Get("", repo.GitHooks)
|
||||
m.Combo("/:name").Get(repo.GitHooksEdit).
|
||||
Post(repo.GitHooksEditPost)
|
||||
}, context.GitHookService())
|
||||
})
|
||||
|
||||
m.Group("/keys", func() {
|
||||
m.Combo("").Get(repo.DeployKeys).
|
||||
Post(bindIgnErr(auth.AddSSHKeyForm{}), repo.DeployKeysPost)
|
||||
m.Post("/delete", repo.DeleteDeployKey)
|
||||
})
|
||||
|
||||
}, func(ctx *context.Context) {
|
||||
ctx.Data["PageIsSettings"] = true
|
||||
})
|
||||
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef())
|
||||
|
||||
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action)
|
||||
m.Group("/:username/:reponame", func() {
|
||||
// FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest.
|
||||
// So they can apply their own enable/disable logic on routers.
|
||||
m.Group("/issues", func() {
|
||||
m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue).
|
||||
Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
|
||||
|
||||
m.Group("/:index", func() {
|
||||
m.Post("/label", repo.UpdateIssueLabel)
|
||||
m.Post("/milestone", repo.UpdateIssueMilestone)
|
||||
m.Post("/assignee", repo.UpdateIssueAssignee)
|
||||
}, reqRepoWriter)
|
||||
|
||||
m.Group("/:index", func() {
|
||||
m.Post("/title", repo.UpdateIssueTitle)
|
||||
m.Post("/content", repo.UpdateIssueContent)
|
||||
m.Combo("/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
|
||||
})
|
||||
})
|
||||
m.Group("/comments/:id", func() {
|
||||
m.Post("", repo.UpdateCommentContent)
|
||||
m.Post("/delete", repo.DeleteComment)
|
||||
})
|
||||
m.Group("/labels", func() {
|
||||
m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
|
||||
m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
|
||||
m.Post("/delete", repo.DeleteLabel)
|
||||
m.Post("/initialize", bindIgnErr(auth.InitializeLabelsForm{}), repo.InitializeLabels)
|
||||
}, reqRepoWriter, context.RepoRef())
|
||||
m.Group("/milestones", func() {
|
||||
m.Combo("/new").Get(repo.NewMilestone).
|
||||
Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
|
||||
m.Get("/:id/edit", repo.EditMilestone)
|
||||
m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
|
||||
m.Get("/:id/:action", repo.ChangeMilestonStatus)
|
||||
m.Post("/delete", repo.DeleteMilestone)
|
||||
}, reqRepoWriter, context.RepoRef())
|
||||
|
||||
m.Group("/releases", func() {
|
||||
m.Get("/new", repo.NewRelease)
|
||||
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
|
||||
m.Get("/edit/*", repo.EditRelease)
|
||||
m.Post("/edit/*", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
|
||||
m.Post("/delete", repo.DeleteRelease)
|
||||
}, reqRepoWriter, context.RepoRef())
|
||||
|
||||
m.Combo("/compare/*", repo.MustAllowPulls).Get(repo.CompareAndPullRequest).
|
||||
Post(bindIgnErr(auth.CreateIssueForm{}), repo.CompareAndPullRequestPost)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Combo("/_edit/*").Get(repo.EditFile).
|
||||
Post(bindIgnErr(auth.EditRepoFileForm{}), repo.EditFilePost)
|
||||
m.Combo("/_new/*").Get(repo.NewFile).
|
||||
Post(bindIgnErr(auth.EditRepoFileForm{}), repo.NewFilePost)
|
||||
m.Post("/_preview/*", bindIgnErr(auth.EditPreviewDiffForm{}), repo.DiffPreviewPost)
|
||||
m.Combo("/_delete/*").Get(repo.DeleteFile).
|
||||
Post(bindIgnErr(auth.DeleteRepoFileForm{}), repo.DeleteFilePost)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Combo("/_upload/*").Get(repo.UploadFile).
|
||||
Post(bindIgnErr(auth.UploadRepoFileForm{}), repo.UploadFilePost)
|
||||
m.Post("/upload-file", repo.UploadFileToServer)
|
||||
m.Post("/upload-remove", bindIgnErr(auth.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer)
|
||||
}, func(ctx *context.Context) {
|
||||
if !setting.Repository.Upload.Enabled {
|
||||
ctx.Handle(404, "", nil)
|
||||
return
|
||||
}
|
||||
})
|
||||
}, reqRepoWriter, context.RepoRef(), func(ctx *context.Context) {
|
||||
if !ctx.Repo.Repository.CanEnableEditor() || ctx.Repo.IsViewCommit {
|
||||
ctx.Handle(404, "", nil)
|
||||
return
|
||||
}
|
||||
})
|
||||
}, reqSignIn, context.RepoAssignment(), repo.MustBeNotBare)
|
||||
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Group("", func() {
|
||||
m.Get("/releases", repo.Releases)
|
||||
m.Get("/^:type(issues|pulls)$", repo.RetrieveLabels, repo.Issues)
|
||||
m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue)
|
||||
m.Get("/labels/", repo.RetrieveLabels, repo.Labels)
|
||||
m.Get("/milestones", repo.Milestones)
|
||||
}, context.RepoRef())
|
||||
|
||||
// m.Get("/branches", repo.Branches)
|
||||
|
||||
m.Group("/wiki", func() {
|
||||
m.Get("/?:page", repo.Wiki)
|
||||
m.Get("/_pages", repo.WikiPages)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Combo("/_new").Get(repo.NewWiki).
|
||||
Post(bindIgnErr(auth.NewWikiForm{}), repo.NewWikiPost)
|
||||
m.Combo("/:page/_edit").Get(repo.EditWiki).
|
||||
Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
|
||||
m.Post("/:page/delete", repo.DeleteWikiPagePost)
|
||||
}, reqSignIn, reqRepoWriter)
|
||||
}, repo.MustEnableWiki, context.RepoRef())
|
||||
|
||||
m.Get("/archive/*", repo.Download)
|
||||
|
||||
m.Group("/pulls/:index", func() {
|
||||
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
|
||||
m.Get("/files", context.RepoRef(), repo.ViewPullFiles)
|
||||
m.Post("/merge", reqRepoWriter, repo.MergePullRequest)
|
||||
}, repo.MustAllowPulls)
|
||||
|
||||
m.Group("", func() {
|
||||
m.Get("/src/*", repo.Home)
|
||||
m.Get("/raw/*", repo.SingleDownload)
|
||||
m.Get("/commits/*", repo.RefCommits)
|
||||
m.Get("/commit/:sha([a-z0-9]{7,40})$", repo.Diff)
|
||||
m.Get("/forks", repo.Forks)
|
||||
}, context.RepoRef())
|
||||
m.Get("/commit/:sha([a-z0-9]{7,40})\\.:ext(patch|diff)", repo.RawDiff)
|
||||
|
||||
m.Get("/compare/:before([a-z0-9]{7,40})\\.\\.\\.:after([a-z0-9]{7,40})", repo.CompareDiff)
|
||||
}, ignSignIn, context.RepoAssignment(), repo.MustBeNotBare)
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Get("/stars", repo.Stars)
|
||||
m.Get("/watchers", repo.Watchers)
|
||||
}, ignSignIn, context.RepoAssignment(), context.RepoRef())
|
||||
|
||||
m.Group("/:username", func() {
|
||||
m.Group("/:reponame", func() {
|
||||
m.Get("", repo.Home)
|
||||
m.Get("\\.git$", repo.Home)
|
||||
}, ignSignIn, context.RepoAssignment(true), context.RepoRef())
|
||||
|
||||
m.Group("/:reponame", func() {
|
||||
m.Any("/*", ignSignInAndCsrf, repo.HTTP)
|
||||
m.Head("/tasks/trigger", repo.TriggerTask)
|
||||
})
|
||||
})
|
||||
// ***** END: Repository *****
|
||||
|
||||
m.Group("/api", func() {
|
||||
apiv1.RegisterRoutes(m)
|
||||
}, ignSignIn)
|
||||
|
||||
// robots.txt
|
||||
m.Get("/robots.txt", func(ctx *context.Context) {
|
||||
if setting.HasRobotsTxt {
|
||||
ctx.ServeFileContent(path.Join(setting.CustomPath, "robots.txt"))
|
||||
} else {
|
||||
ctx.Error(404)
|
||||
}
|
||||
})
|
||||
|
||||
// Not found handler.
|
||||
m.NotFound(routers.NotFound)
|
||||
|
||||
// Flag for port number in case first time run conflict.
|
||||
if ctx.IsSet("port") {
|
||||
setting.AppUrl = strings.Replace(setting.AppUrl, setting.HTTPPort, ctx.String("port"), 1)
|
||||
setting.HTTPPort = ctx.String("port")
|
||||
}
|
||||
|
||||
var listenAddr string
|
||||
if setting.Protocol == setting.UNIX_SOCKET {
|
||||
listenAddr = fmt.Sprintf("%s", setting.HTTPAddr)
|
||||
} else {
|
||||
listenAddr = fmt.Sprintf("%s:%s", setting.HTTPAddr, setting.HTTPPort)
|
||||
}
|
||||
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubUrl)
|
||||
|
||||
var err error
|
||||
switch setting.Protocol {
|
||||
case setting.HTTP:
|
||||
err = http.ListenAndServe(listenAddr, m)
|
||||
case setting.HTTPS:
|
||||
server := &http.Server{Addr: listenAddr, TLSConfig: &tls.Config{MinVersion: tls.VersionTLS10}, Handler: m}
|
||||
err = server.ListenAndServeTLS(setting.CertFile, setting.KeyFile)
|
||||
case setting.FCGI:
|
||||
err = fcgi.Serve(nil, m)
|
||||
case setting.UNIX_SOCKET:
|
||||
os.Remove(listenAddr)
|
||||
|
||||
var listener *net.UnixListener
|
||||
listener, err = net.ListenUnix("unix", &net.UnixAddr{listenAddr, "unix"})
|
||||
if err != nil {
|
||||
break // Handle error after switch
|
||||
}
|
||||
|
||||
// FIXME: add proper implementation of signal capture on all protocols
|
||||
// execute this on SIGTERM or SIGINT: listener.Close()
|
||||
if err = os.Chmod(listenAddr, os.FileMode(setting.UnixSocketPermission)); err != nil {
|
||||
log.Fatal(4, "Failed to set permission of unix socket: %v", err)
|
||||
}
|
||||
err = http.Serve(listener, m)
|
||||
default:
|
||||
log.Fatal(4, "Invalid protocol: %s", setting.Protocol)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(4, "Fail to start server: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
Execute following command in ROOT directory when anything is changed:
|
||||
|
||||
$ make bindata
|
||||
770
conf/app.ini
770
conf/app.ini
@@ -1,122 +1,27 @@
|
||||
# NEVER EVER MODIFY THIS FILE
|
||||
# PLEASE MAKE CHANGES ON CORRESPONDING CUSTOM CONFIG FILE
|
||||
# !!! NEVER EVER MODIFY THIS FILE !!!
|
||||
# !!! PLEASE MAKE CHANGES ON CORRESPONDING CUSTOM CONFIG FILE !!!
|
||||
# !!! IF YOU ARE PACKAGING PROVIDER, PLEASE MAKE OWN COPY OF IT !!!
|
||||
|
||||
; App name that shows on every page title
|
||||
APP_NAME = Gogs: Go Git Service
|
||||
; Change it if you run locally
|
||||
; The brand name of the application, can be your company or team name.
|
||||
BRAND_NAME = Gogs
|
||||
; The system user who should be running the applications. It has no effect on Windows,
|
||||
; otherwise, it should match the value of $USER environment variable.
|
||||
RUN_USER = git
|
||||
; Either "dev", "prod" or "test", default is "dev"
|
||||
; The running mode of the application, can be either "dev", "prod" or "test".
|
||||
RUN_MODE = dev
|
||||
|
||||
[repository]
|
||||
ROOT =
|
||||
SCRIPT_TYPE = bash
|
||||
; Default ANSI charset
|
||||
ANSI_CHARSET =
|
||||
; Force every new repository to be private
|
||||
FORCE_PRIVATE = false
|
||||
; Global maximum creation limit of repository per user, -1 means no limit
|
||||
MAX_CREATION_LIMIT = -1
|
||||
; Mirror sync queue length, increase if mirror syncing starts hanging
|
||||
MIRROR_QUEUE_LENGTH = 1000
|
||||
; Patch test queue length, increase if pull request patch testing starts hanging
|
||||
PULL_REQUEST_QUEUE_LENGTH = 1000
|
||||
; Preferred Licenses to place at the top of the List
|
||||
; Name must match file name in conf/license or custom/conf/license
|
||||
PREFERRED_LICENSES = Apache License 2.0,MIT License
|
||||
|
||||
[repository.editor]
|
||||
; List of file extensions that should have line wraps in the CodeMirror editor
|
||||
; Separate extensions with a comma. To line wrap files w/o extension, just put a comma
|
||||
LINE_WRAP_EXTENSIONS = .txt,.md,.markdown,.mdown,.mkd,
|
||||
; Valid file modes that have a preview API associated with them, such as api/v1/markdown
|
||||
; Separate values by commas. Preview tab in edit mode won't show if the file extension doesn't match
|
||||
PREVIEWABLE_FILE_MODES = markdown
|
||||
|
||||
[repository.upload]
|
||||
; Whether repository file uploads are enabled. Defaults to `true`
|
||||
ENABLED = true
|
||||
; Path for uploads. Defaults to `data/tmp/uploads` (tmp gets deleted on gogs restart)
|
||||
TEMP_PATH = data/tmp/uploads
|
||||
; One or more allowed types, e.g. image/jpeg|image/png. Nothing means any file type
|
||||
ALLOWED_TYPES =
|
||||
; Max size of each file in MB. Defaults to 3MB
|
||||
FILE_MAX_SIZE = 3
|
||||
; Max number of files per upload. Defaults to 5
|
||||
MAX_FILES = 5
|
||||
|
||||
[ui]
|
||||
; Number of repositories that are showed in one explore page
|
||||
EXPLORE_PAGING_NUM = 20
|
||||
; Number of issues that are showed in one page
|
||||
ISSUE_PAGING_NUM = 10
|
||||
; Number of maximum commits showed in one activity feed
|
||||
FEED_MAX_COMMIT_NUM = 5
|
||||
; 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
|
||||
THEME_COLOR_META_TAG = `#ff5343`
|
||||
; Max size of files to be displayed (defaults is 8MiB)
|
||||
MAX_DISPLAY_FILE_SIZE = 8388608
|
||||
|
||||
[ui.admin]
|
||||
; Number of users that are showed in one page
|
||||
USER_PAGING_NUM = 50
|
||||
; Number of repos that are showed in one page
|
||||
REPO_PAGING_NUM = 50
|
||||
; Number of notices that are showed in one page
|
||||
NOTICE_PAGING_NUM = 25
|
||||
; Number of organization that are showed in one page
|
||||
ORG_PAGING_NUM = 50
|
||||
|
||||
[ui.user]
|
||||
; Number of repos that are showed in one page
|
||||
REPO_PAGING_NUM = 15
|
||||
|
||||
[markdown]
|
||||
; Enable hard line break extension
|
||||
ENABLE_HARD_LINE_BREAK = false
|
||||
; List of custom URL-Schemes that are allowed as links when rendering Markdown
|
||||
; for example git,magnet
|
||||
CUSTOM_URL_SCHEMES =
|
||||
; List of file extensions that should be rendered/edited as Markdown
|
||||
; Separate extensions with a comma. To render files w/o extension as markdown, just put a comma
|
||||
FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd
|
||||
|
||||
[server]
|
||||
PROTOCOL = http
|
||||
; The public-facing URL for the application.
|
||||
EXTERNAL_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
|
||||
; The public-facing domain name for the application.
|
||||
DOMAIN = localhost
|
||||
ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
|
||||
; The protocol that is used to serve direct traffic to the application.
|
||||
; Currently supports "http", "https", "fcgi" and "unix".
|
||||
PROTOCOL = http
|
||||
; The address to be listened by the application.
|
||||
HTTP_ADDR = 0.0.0.0
|
||||
; The port number to be listened by the application.
|
||||
HTTP_PORT = 3000
|
||||
; Permission for unix socket
|
||||
UNIX_SOCKET_PERMISSION = 666
|
||||
; Local (DMZ) URL for Gogs 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.
|
||||
LOCAL_ROOT_URL = %(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/
|
||||
; Disable SSH feature when not available
|
||||
DISABLE_SSH = false
|
||||
; Whether use builtin SSH server or not.
|
||||
START_SSH_SERVER = false
|
||||
; Domain name to be exposed in clone URL
|
||||
SSH_DOMAIN = %(DOMAIN)s
|
||||
; Port number to be exposed in clone URL
|
||||
SSH_PORT = 22
|
||||
; Port number builtin SSH server listens on
|
||||
SSH_LISTEN_PORT = %(SSH_PORT)s
|
||||
; Root path of SSH directory, default is '~/.ssh', but you have to use '/home/git/.ssh'.
|
||||
SSH_ROOT_PATH =
|
||||
; Directory to create temporary files when test publick key using ssh-keygen,
|
||||
; default is system temporary directory.
|
||||
SSH_KEY_TEST_PATH =
|
||||
; Path to ssh-keygen, default is 'ssh-keygen' and let shell find out which one to call.
|
||||
SSH_KEYGEN_PATH = ssh-keygen
|
||||
; Indicate whether to check minimum key size with corresponding type
|
||||
MINIMUM_KEY_SIZE_CHECK = false
|
||||
; Disable CDN even in "prod" mode
|
||||
OFFLINE_MODE = false
|
||||
DISABLE_ROUTER_LOG = false
|
||||
; Generate steps:
|
||||
; $ ./gogs cert -ca=true -duration=8760h0m0s -host=myhost.example.com
|
||||
;
|
||||
@@ -126,224 +31,395 @@ DISABLE_ROUTER_LOG = false
|
||||
; $ openssl pkcs12 -in cert.pfx -out key.pem -nocerts -nodes
|
||||
CERT_FILE = custom/https/cert.pem
|
||||
KEY_FILE = custom/https/key.pem
|
||||
; Upper level of template and static file path
|
||||
; default is the path where Gogs is executed
|
||||
STATIC_ROOT_PATH =
|
||||
; Default path for App data
|
||||
APP_DATA_PATH = data
|
||||
; Application level GZIP support
|
||||
ENABLE_GZIP = false
|
||||
; Landing page for non-logged users, can be "home" or "explore"
|
||||
LANDING_PAGE = home
|
||||
; The minimum allowed TLS version, currently supports "TLS10", "TLS11", "TLS12", and "TLS13".
|
||||
TLS_MIN_VERSION = TLS12
|
||||
; File permission when serve traffic via Unix domain socket.
|
||||
UNIX_SOCKET_PERMISSION = 666
|
||||
; Local (DMZ) URL for workers (e.g. 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.
|
||||
LOCAL_ROOT_URL = %(PROTOCOL)s://%(HTTP_ADDR)s:%(HTTP_PORT)s/
|
||||
|
||||
; Define allowed algorithms and their minimum key length (use -1 to disable a type)
|
||||
; Whether to disable using CDN for static files regardless.
|
||||
OFFLINE_MODE = false
|
||||
; Whether to disable logging in router.
|
||||
DISABLE_ROUTER_LOG = true
|
||||
; Whether to enable application level GZIP compression.
|
||||
ENABLE_GZIP = false
|
||||
|
||||
; The path for storing application specific data.
|
||||
APP_DATA_PATH = data
|
||||
; Whether to enable to load assets (i.e. "conf", "templates", "public") from disk instead of embedded bindata.
|
||||
LOAD_ASSETS_FROM_DISK = false
|
||||
|
||||
; The landing page URL for anonymous users, the value should not include
|
||||
; subpath that is handled by the reverse proxy.
|
||||
LANDING_URL = /
|
||||
|
||||
; Whether to disable SSH access to the application entirely.
|
||||
DISABLE_SSH = false
|
||||
; The domain name to be exposed in SSH clone URL.
|
||||
SSH_DOMAIN = %(DOMAIN)s
|
||||
; The port number to be exposed in SSH clone URL.
|
||||
SSH_PORT = 22
|
||||
; The path of SSH root directory, default is "$HOME/.ssh".
|
||||
SSH_ROOT_PATH =
|
||||
; The path to ssh-keygen, default is "ssh-keygen" and let shell find out which one to call.
|
||||
SSH_KEYGEN_PATH = ssh-keygen
|
||||
; The directory to create temporary files when test a public key using ssh-keygen,
|
||||
; default is the system temporary directory.
|
||||
SSH_KEY_TEST_PATH =
|
||||
; Whether to check minimum public key size with corresponding type.
|
||||
MINIMUM_KEY_SIZE_CHECK = false
|
||||
; Whether to rewrite "~/.ssh/authorized_keys" file at start, ignored when use builtin SSH server.
|
||||
REWRITE_AUTHORIZED_KEYS_AT_START = false
|
||||
; Whether to start a builtin SSH server.
|
||||
START_SSH_SERVER = false
|
||||
; The network interface for builtin SSH server to listen on.
|
||||
SSH_LISTEN_HOST = 0.0.0.0
|
||||
; The port number for builtin SSH server to listen on.
|
||||
SSH_LISTEN_PORT = %(SSH_PORT)s
|
||||
; The list of accepted ciphers for connections to builtin SSH server.
|
||||
SSH_SERVER_CIPHERS = aes128-ctr, aes192-ctr, aes256-ctr, aes128-gcm@openssh.com, arcfour256, arcfour128
|
||||
; The list of accepted MACs for connections to builtin SSH server.
|
||||
SSH_SERVER_MACS = hmac-sha2-256-etm@openssh.com, hmac-sha2-256, hmac-sha1
|
||||
; The list of accepted key exchange algorithms for connections to builtin SSH server.
|
||||
SSH_SERVER_ALGORITHMS = rsa, ecdsa, ed25519
|
||||
|
||||
; Define allowed algorithms and their minimum key length (use -1 to disable a type).
|
||||
[ssh.minimum_key_sizes]
|
||||
ED25519 = 256
|
||||
ECDSA = 256
|
||||
RSA = 2048
|
||||
DSA = 1024
|
||||
|
||||
[database]
|
||||
; Either "mysql", "postgres" or "sqlite3", it's your choice
|
||||
DB_TYPE = mysql
|
||||
HOST = 127.0.0.1:3306
|
||||
NAME = gogs
|
||||
USER = root
|
||||
PASSWD =
|
||||
; For "postgres" only, either "disable", "require" or "verify-full"
|
||||
SSL_MODE = disable
|
||||
; For "sqlite3" and "tidb", use absolute path when you start as service
|
||||
PATH = data/gogs.db
|
||||
[repository]
|
||||
; The root path for storing managed repositories, default is "~/gogs-repositories"
|
||||
ROOT =
|
||||
; The script type server supports, sometimes could be "sh".
|
||||
SCRIPT_TYPE = bash
|
||||
; Default ANSI charset for an unrecognized charset.
|
||||
ANSI_CHARSET =
|
||||
; Whether to force every new repository to be private.
|
||||
FORCE_PRIVATE = false
|
||||
; The global limit of number of repositories a user can create, -1 means no limit.
|
||||
MAX_CREATION_LIMIT = -1
|
||||
; Preferred Licenses to place at the top of the list.
|
||||
; Name must match file name in "conf/license" or "custom/conf/license".
|
||||
PREFERRED_LICENSES = Apache License 2.0, MIT License
|
||||
; Whether to disable Git interaction with repositories via HTTP/HTTPS protocol.
|
||||
DISABLE_HTTP_GIT = false
|
||||
; Whether to enable ability to migrate repository by server local path.
|
||||
ENABLE_LOCAL_PATH_MIGRATION = false
|
||||
; Whether to enable render mode for raw file. There are potential security risks.
|
||||
ENABLE_RAW_FILE_RENDER_MODE = false
|
||||
; The maximum number of goroutines that can be run at the same time for a single
|
||||
; fetch request. Usually, the value depend of how many CPU (cores) you have. If
|
||||
; the value is non-positive, it matches the number of CPUs available to the application.
|
||||
COMMITS_FETCH_CONCURRENCY = 0
|
||||
; Default branch name when creating new repositories.
|
||||
DEFAULT_BRANCH = master
|
||||
|
||||
[admin]
|
||||
[repository.editor]
|
||||
; List of file extensions that should have line wraps in the CodeMirror editor.
|
||||
; Separate extensions with a comma.
|
||||
LINE_WRAP_EXTENSIONS = .txt,.md,.markdown,.mdown,.mkd
|
||||
; Valid file modes that have a preview API associated with them, such as "/api/v1/markdown".
|
||||
; Separate values by commas. Preview tab in edit mode won't show if the file extension doesn't match.
|
||||
PREVIEWABLE_FILE_MODES = markdown
|
||||
|
||||
[security]
|
||||
INSTALL_LOCK = false
|
||||
; !!CHANGE THIS TO KEEP YOUR USER DATA SAFE!!
|
||||
SECRET_KEY = !#@FDEWREWR&*(
|
||||
; Auto-login remember days
|
||||
LOGIN_REMEMBER_DAYS = 7
|
||||
COOKIE_USERNAME = gogs_awesome
|
||||
COOKIE_REMEMBER_NAME = gogs_incredible
|
||||
; Reverse proxy authentication header name of user name
|
||||
REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
|
||||
|
||||
[service]
|
||||
ACTIVE_CODE_LIVE_MINUTES = 180
|
||||
RESET_PASSWD_CODE_LIVE_MINUTES = 180
|
||||
; User need to confirm e-mail for registration
|
||||
REGISTER_EMAIL_CONFIRM = false
|
||||
; Does not allow register and admin create account only
|
||||
DISABLE_REGISTRATION = false
|
||||
; User must sign in to view anything.
|
||||
REQUIRE_SIGNIN_VIEW = false
|
||||
; Mail notification
|
||||
ENABLE_NOTIFY_MAIL = false
|
||||
; More detail: https://github.com/gogits/gogs/issues/165
|
||||
ENABLE_REVERSE_PROXY_AUTHENTICATION = false
|
||||
ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
|
||||
; Enable captcha validation for registration
|
||||
ENABLE_CAPTCHA = true
|
||||
|
||||
[webhook]
|
||||
; Hook task queue length, increase if webhook shooting starts hanging
|
||||
QUEUE_LENGTH = 1000
|
||||
; Deliver timeout in seconds
|
||||
DELIVER_TIMEOUT = 5
|
||||
; Allow insecure certification
|
||||
SKIP_TLS_VERIFY = false
|
||||
; Number of history information in each page
|
||||
PAGING_NUM = 10
|
||||
|
||||
[mailer]
|
||||
ENABLED = false
|
||||
; Buffer length of channel, keep it as it is if you don't know what it is.
|
||||
SEND_BUFFER_LEN = 100
|
||||
; Name displayed in mail title
|
||||
SUBJECT = %(APP_NAME)s
|
||||
; Mail server
|
||||
; Gmail: smtp.gmail.com:587
|
||||
; QQ: smtp.qq.com:465
|
||||
; Note, if the port ends with "465", SMTPS will be used. Using STARTTLS on port 587 is recommended per RFC 6409. If the server supports STARTTLS it will always be used.
|
||||
HOST =
|
||||
; Disable HELO operation when hostname are different.
|
||||
DISABLE_HELO =
|
||||
; Custom hostname for HELO operation, default is from system.
|
||||
HELO_HOSTNAME =
|
||||
; Do not verify the certificate of the server. Only use this for self-signed certificates
|
||||
SKIP_VERIFY =
|
||||
; Use client certificate
|
||||
USE_CERTIFICATE = false
|
||||
CERT_FILE = custom/mailer/cert.pem
|
||||
KEY_FILE = custom/mailer/key.pem
|
||||
; Mail from address, RFC 5322. This can be just an email address, or the `"Name" <email@example.com>` format
|
||||
FROM =
|
||||
; Mailer user name and password
|
||||
USER =
|
||||
PASSWD =
|
||||
; Use text/html as alternative format of content
|
||||
ENABLE_HTML_ALTERNATIVE = false
|
||||
|
||||
[cache]
|
||||
; Either "memory", "redis", or "memcache", default is "memory"
|
||||
ADAPTER = memory
|
||||
; For "memory" only, GC interval in seconds, default is 60
|
||||
INTERVAL = 60
|
||||
; For "redis" and "memcache", connection host address
|
||||
; redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180
|
||||
; memcache: `127.0.0.1:11211`
|
||||
HOST =
|
||||
|
||||
[session]
|
||||
; Either "memory", "file", or "redis", default is "memory"
|
||||
PROVIDER = memory
|
||||
; Provider config options
|
||||
; memory: not have any config yet
|
||||
; file: session file path, e.g. `data/sessions`
|
||||
; redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180
|
||||
; mysql: go-sql-driver/mysql dsn config string, e.g. `root:password@/session_table`
|
||||
PROVIDER_CONFIG = data/sessions
|
||||
; Session cookie name
|
||||
COOKIE_NAME = i_like_gogits
|
||||
; If you use session in https only, default is false
|
||||
COOKIE_SECURE = false
|
||||
; Enable set cookie, default is true
|
||||
ENABLE_SET_COOKIE = true
|
||||
; Session GC time interval, default is 86400
|
||||
GC_INTERVAL_TIME = 86400
|
||||
; Session life time, default is 86400
|
||||
SESSION_LIFE_TIME = 86400
|
||||
|
||||
[picture]
|
||||
AVATAR_UPLOAD_PATH = data/avatars
|
||||
; Chinese users can choose "duoshuo"
|
||||
; or a custom avatar source, like: http://cn.gravatar.com/avatar/
|
||||
GRAVATAR_SOURCE = gravatar
|
||||
; This value will be forced to be true in offline mode.
|
||||
DISABLE_GRAVATAR = false
|
||||
; Federated avatar lookup uses DNS to discover avatar associated
|
||||
; with emails, see https://www.libravatar.org
|
||||
; This value will be forced to be false in offline mode or Gravatar is disbaled.
|
||||
ENABLE_FEDERATED_AVATAR = false
|
||||
|
||||
[attachment]
|
||||
; Whether attachments are enabled. Defaults to `true`
|
||||
ENABLE = true
|
||||
; Path for attachments. Defaults to `data/attachments`
|
||||
PATH = data/attachments
|
||||
; One or more allowed types, e.g. image/jpeg|image/png
|
||||
ALLOWED_TYPES = image/jpeg|image/png
|
||||
; Max size of each file. Defaults to 32MB
|
||||
MAX_SIZE = 4
|
||||
; Max number of files per upload. Defaults to 10
|
||||
[repository.upload]
|
||||
; Whether to enable repository file uploads.
|
||||
ENABLED = true
|
||||
; The path to temporarily store uploads (content under this path gets wiped out on every start).
|
||||
TEMP_PATH = data/tmp/uploads
|
||||
; File types that are allowed to be uploaded, e.g. "image/jpeg|image/png". Leave empty to allow any file type.
|
||||
ALLOWED_TYPES =
|
||||
; The maximum size of each file in MB.
|
||||
FILE_MAX_SIZE = 3
|
||||
; The maximum number of files per upload.
|
||||
MAX_FILES = 5
|
||||
|
||||
[time]
|
||||
; Specifies the format for fully outputed dates. Defaults to RFC1123
|
||||
; Special supported values are ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano
|
||||
; For more information about the format see http://golang.org/pkg/time/#pkg-constants
|
||||
FORMAT =
|
||||
[database]
|
||||
; The database backend, either "postgres", "mysql" or "sqlite3".
|
||||
TYPE = postgres
|
||||
HOST = 127.0.0.1:5432
|
||||
NAME = gogs
|
||||
USER = gogs
|
||||
PASSWORD =
|
||||
; For "postgres" only
|
||||
SCHEMA = public
|
||||
; For "postgres" only, either "disable", "require" or "verify-full".
|
||||
SSL_MODE = disable
|
||||
; For "sqlite3" only, make sure to use absolute path.
|
||||
PATH = data/gogs.db
|
||||
; The maximum open connections of the pool.
|
||||
MAX_OPEN_CONNS = 30
|
||||
; The maximum idle connections of the pool.
|
||||
MAX_IDLE_CONNS = 30
|
||||
|
||||
[security]
|
||||
; Whether to show the install page, set this to "true" to bypass it.
|
||||
INSTALL_LOCK = false
|
||||
; The secret to encrypt cookie values, 2FA code, etc.
|
||||
; !!CHANGE THIS TO KEEP YOUR USER DATA SAFE!!
|
||||
SECRET_KEY = !#@FDEWREWR&*(
|
||||
; The days remembered for auto-login.
|
||||
LOGIN_REMEMBER_DAYS = 7
|
||||
; The cookie name to store auto-login information.
|
||||
COOKIE_REMEMBER_NAME = gogs_incredible
|
||||
; The cookie name to store logged in username.
|
||||
COOKIE_USERNAME = gogs_awesome
|
||||
; Whether to set secure cookie.
|
||||
COOKIE_SECURE = false
|
||||
; Whether to set cookie to indicate user login status.
|
||||
ENABLE_LOGIN_STATUS_COOKIE = false
|
||||
; The cookie name to store user login status.
|
||||
LOGIN_STATUS_COOKIE_NAME = login_status
|
||||
; A comma separated list of hostnames that are explicitly allowed to be accessed within the local network.
|
||||
; Use "*" to allow all hostnames.
|
||||
LOCAL_NETWORK_ALLOWLIST =
|
||||
|
||||
[email]
|
||||
; Whether to enable the email service.
|
||||
ENABLED = false
|
||||
; The prefix prepended to the subject line.
|
||||
SUBJECT_PREFIX = `[%(BRAND_NAME)s] `
|
||||
; The SMTP server with its port, e.g. smtp.mailgun.org:587, smtp.gmail.com:587, smtp.qq.com:465
|
||||
; If the port ends is "465", SMTPS will be used. Using STARTTLS on port 587 is recommended per RFC 6409.
|
||||
; If the server supports STARTTLS it will always be used.
|
||||
HOST = smtp.mailgun.org:587
|
||||
; The email from address (RFC 5322). This can be just an email address, or the `"Name" <email@example.com>` format.
|
||||
FROM = noreply@gogs.localhost
|
||||
; The login user.
|
||||
USER = noreply@gogs.localhost
|
||||
; The login password.
|
||||
PASSWORD =
|
||||
|
||||
; The custom hostname for HELO operation, default is from system.
|
||||
HELO_HOSTNAME =
|
||||
|
||||
; Whether to skip verifying the certificate of the server. Only use this for self-signed certificates.
|
||||
SKIP_VERIFY = false
|
||||
; Whether to use client certificates.
|
||||
USE_CERTIFICATE = false
|
||||
CERT_FILE = custom/email/cert.pem
|
||||
KEY_FILE = custom/email/key.pem
|
||||
|
||||
; Whether to use "text/plain" as content format.
|
||||
USE_PLAIN_TEXT = false
|
||||
; Whether to attach a plaintext alternative to the MIME message while sending HTML emails.
|
||||
; It is used to support older mail clients and make spam filters happier.
|
||||
ADD_PLAIN_TEXT_ALT = false
|
||||
|
||||
[auth]
|
||||
; The valid duration of activate code in minutes.
|
||||
ACTIVATE_CODE_LIVES = 180
|
||||
; The valid duration of reset password code in minutes.
|
||||
RESET_PASSWORD_CODE_LIVES = 180
|
||||
; Whether to require email confirmation for adding new email addresses.
|
||||
; Enable this option will also require user to confirm the email for registration.
|
||||
REQUIRE_EMAIL_CONFIRMATION = false
|
||||
; Whether to disallow anonymous users visiting the site.
|
||||
REQUIRE_SIGNIN_VIEW = false
|
||||
; Whether to disable self-registration. When disabled, accounts would have to be created by admins.
|
||||
DISABLE_REGISTRATION = false
|
||||
; Whether to enable captcha validation for registration
|
||||
ENABLE_REGISTRATION_CAPTCHA = true
|
||||
|
||||
; Whether to enable reverse proxy authentication via HTTP header.
|
||||
ENABLE_REVERSE_PROXY_AUTHENTICATION = false
|
||||
; Whether to automatically create new users for reverse proxy authentication.
|
||||
ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false
|
||||
; The HTTP header used as username for reverse proxy authentication.
|
||||
REVERSE_PROXY_AUTHENTICATION_HEADER = X-WEBAUTH-USER
|
||||
|
||||
[user]
|
||||
; Whether to enable email notifications for users.
|
||||
ENABLE_EMAIL_NOTIFICATION = false
|
||||
|
||||
[session]
|
||||
; The session provider, either "memory", "file", or "redis".
|
||||
PROVIDER = memory
|
||||
; The configuration for respective provider:
|
||||
; - memory: does not need any config yet
|
||||
; - file: session file path, e.g. `data/sessions`
|
||||
; - redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180,tls=true
|
||||
PROVIDER_CONFIG = data/sessions
|
||||
; The cookie name to store the session identifier.
|
||||
COOKIE_NAME = i_like_gogs
|
||||
; Whether to set cookie in HTTPS only.
|
||||
COOKIE_SECURE = false
|
||||
; The GC interval in seconds for session data.
|
||||
GC_INTERVAL = 3600
|
||||
; The maximum life time in seconds for a session.
|
||||
MAX_LIFE_TIME = 86400
|
||||
; The cookie name for CSRF token.
|
||||
CSRF_COOKIE_NAME = _csrf
|
||||
|
||||
[cache]
|
||||
; The cache adapter, either "memory", "redis", or "memcache".
|
||||
ADAPTER = memory
|
||||
; For "memory" only, GC interval in seconds.
|
||||
INTERVAL = 60
|
||||
; For "redis" and "memcache", connection host address:
|
||||
; - redis: network=tcp,addr=:6379,password=macaron,db=0,pool_size=100,idle_timeout=180
|
||||
; - memcache: `127.0.0.1:11211`
|
||||
HOST =
|
||||
|
||||
[http]
|
||||
; The value for "Access-Control-Allow-Origin" header, default is not to present.
|
||||
ACCESS_CONTROL_ALLOW_ORIGIN =
|
||||
|
||||
[lfs]
|
||||
; The storage backend for uploading new objects.
|
||||
STORAGE = local
|
||||
; The root path to store LFS objects on local file system.
|
||||
OBJECTS_PATH = data/lfs-objects
|
||||
; The path to temporarily store LFS objects during upload verification.
|
||||
OBJECTS_TEMP_PATH = data/tmp/lfs-objects
|
||||
|
||||
[attachment]
|
||||
; Whether to enabled upload attachments in general.
|
||||
ENABLED = true
|
||||
; The path to store attachments on the file system.
|
||||
PATH = data/attachments
|
||||
; File types that are allowed to be uploaded, e.g. "image/jpeg|image/png". Leave empty to allow any file type.
|
||||
ALLOWED_TYPES = image/jpeg|image/png
|
||||
; The maximum size of each file in MB.
|
||||
MAX_SIZE = 4
|
||||
; The maximum number of files per upload.
|
||||
MAX_FILES = 5
|
||||
|
||||
[release.attachment]
|
||||
; Whether to enabled upload attachments for releases.
|
||||
ENABLED = true
|
||||
; File types that are allowed to be uploaded, e.g. "image/jpeg|image/png". Leave empty to allow any file type.
|
||||
ALLOWED_TYPES = */*
|
||||
; The maximum size of each file in MB.
|
||||
MAX_SIZE = 32
|
||||
; The maximum number of files per upload.
|
||||
MAX_FILES = 10
|
||||
|
||||
[time]
|
||||
; Specifies the format for fully outputed dates.
|
||||
; Values should be one of the following:
|
||||
; ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Kitchen, Stamp, StampMilli, StampMicro and StampNano.
|
||||
; For more information about the format see http://golang.org/pkg/time/#pkg-constants.
|
||||
FORMAT = RFC1123
|
||||
|
||||
[picture]
|
||||
; The path to store user avatars on the file system.
|
||||
AVATAR_UPLOAD_PATH = data/avatars
|
||||
; The path to store repository avatars on the file system.
|
||||
REPOSITORY_AVATAR_UPLOAD_PATH = data/repo-avatars
|
||||
; Chinese users can use a custom avatar source, such as http://cn.gravatar.com/avatar/.
|
||||
GRAVATAR_SOURCE = gravatar
|
||||
; Whether to disable Gravatar, this value will be forced to be true in offline mode.
|
||||
DISABLE_GRAVATAR = false
|
||||
; Whether to enable federated avatar lookup uses DNS to discover avatar associated
|
||||
; with emails, see https://www.libravatar.org for details.
|
||||
; This value will be forced to be false in offline mode or when Gravatar is disabled.
|
||||
ENABLE_FEDERATED_AVATAR = false
|
||||
|
||||
[markdown]
|
||||
; Whether to enable hard line break extension.
|
||||
ENABLE_HARD_LINE_BREAK = false
|
||||
; The list of custom URL schemes that are allowed as links when rendering Markdown.
|
||||
; For example, "git" (for "git://") and "magnet" (for "magnet://").
|
||||
CUSTOM_URL_SCHEMES =
|
||||
; The list of file extensions that should be rendered/edited as Markdown.
|
||||
; Separate extensions with a comma. To render files with no extension as markdown, just put a comma.
|
||||
FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd
|
||||
|
||||
[smartypants]
|
||||
; Whether to enable the Smartypants extension.
|
||||
ENABLED = false
|
||||
FRACTIONS = true
|
||||
DASHES = true
|
||||
LATEX_DASHES = true
|
||||
ANGLED_QUOTES = true
|
||||
|
||||
[admin]
|
||||
; Whether to disable regular (non-admin) users to create organizations.
|
||||
DISABLE_REGULAR_ORG_CREATION = false
|
||||
|
||||
[webhook]
|
||||
; The list of enabled types for users to use, can be "gogs", "slack", "discord", "dingtalk".
|
||||
TYPES = gogs, slack, discord, dingtalk
|
||||
; Deliver timeout in seconds.
|
||||
DELIVER_TIMEOUT = 15
|
||||
; Whether to allow insecure certification.
|
||||
SKIP_TLS_VERIFY = false
|
||||
; The number of history information in each page.
|
||||
PAGING_NUM = 10
|
||||
|
||||
; General settings of loggers.
|
||||
[log]
|
||||
; The root path for all log files, default is "log/" subdirectory.
|
||||
ROOT_PATH =
|
||||
; Either "console", "file", "conn", "smtp" or "database", default is "console"
|
||||
; Can be "console", "file", "slack" and "discord".
|
||||
; Use comma to separate multiple modes, e.g. "console, file"
|
||||
MODE = console
|
||||
; Buffer length of channel, keep it as it is if you don't know what it is.
|
||||
BUFFER_LEN = 10000
|
||||
; Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "Trace"
|
||||
BUFFER_LEN = 100
|
||||
; Either "Trace", "Info", "Warn", "Error", "Fatal", default is "Trace"
|
||||
LEVEL = Trace
|
||||
|
||||
; For "console" mode only
|
||||
[log.console]
|
||||
LEVEL =
|
||||
; Comment out to inherit
|
||||
; LEVEL =
|
||||
|
||||
; For "file" mode only
|
||||
[log.file]
|
||||
LEVEL =
|
||||
; This enables automated log rotate(switch of following options), default is true
|
||||
; Comment out to inherit
|
||||
; LEVEL =
|
||||
; Whether to enable automated log rotate (switch of following options).
|
||||
LOG_ROTATE = true
|
||||
; Max line number of single file, default is 1000000
|
||||
MAX_LINES = 1000000
|
||||
; Max size shift of single file, default is 28 means 1 << 28, 256MB
|
||||
MAX_SIZE_SHIFT = 28
|
||||
; Segment log daily, default is true
|
||||
; Whether to segment log files daily.
|
||||
DAILY_ROTATE = true
|
||||
; Expired days of log file(delete after max days), default is 7
|
||||
; The maximum size shift of single file, default is 28 means 1 << 28 = 256MB.
|
||||
MAX_SIZE_SHIFT = 28
|
||||
; The maximum number of lines of single file.
|
||||
MAX_LINES = 1000000
|
||||
; The expired days of log file (delete after max days).
|
||||
MAX_DAYS = 7
|
||||
|
||||
; For "conn" mode only
|
||||
[log.conn]
|
||||
LEVEL =
|
||||
; Reconnect host for every single message, default is false
|
||||
RECONNECT_ON_MSG = false
|
||||
; Try to reconnect when connection is lost, default is false
|
||||
RECONNECT = false
|
||||
; Either "tcp", "unix" or "udp", default is "tcp"
|
||||
PROTOCOL = tcp
|
||||
; Host address
|
||||
ADDR =
|
||||
; For "slack" mode only
|
||||
[log.slack]
|
||||
; Comment out to inherit
|
||||
; LEVEL =
|
||||
; Webhook URL
|
||||
URL =
|
||||
|
||||
; For "smtp" mode only
|
||||
[log.smtp]
|
||||
LEVEL =
|
||||
; Name displayed in mail title, default is "Diagnostic message from server"
|
||||
SUBJECT = Diagnostic message from server
|
||||
; Mail server
|
||||
HOST =
|
||||
; Mailer user name and password
|
||||
USER =
|
||||
PASSWD =
|
||||
; Receivers, can be one or more, e.g. ["1@example.com","2@example.com"]
|
||||
RECEIVERS =
|
||||
[log.discord]
|
||||
; Comment out to inherit
|
||||
; LEVEL =
|
||||
; Webhook URL
|
||||
URL =
|
||||
; The username to be displayed in notification.
|
||||
USERNAME = %(BRAND_NAME)s
|
||||
|
||||
; For "database" mode only
|
||||
[log.database]
|
||||
LEVEL =
|
||||
; Either "mysql" or "postgres"
|
||||
DRIVER =
|
||||
; Based on xorm, e.g.: root:root@localhost/gogs?charset=utf8
|
||||
CONN =
|
||||
[log.xorm]
|
||||
; Enable file rotation
|
||||
ROTATE = true
|
||||
; Rotate every day
|
||||
ROTATE_DAILY = true
|
||||
; Rotate once file size excesses x MB
|
||||
MAX_SIZE = 100
|
||||
; Maximum days to keep logger files
|
||||
MAX_DAYS = 3
|
||||
|
||||
[log.gorm]
|
||||
; Whether to enable file rotation.
|
||||
ROTATE = true
|
||||
; Whether to rotate file every day.
|
||||
ROTATE_DAILY = true
|
||||
; The maximum file size in MB before next rotate.
|
||||
MAX_SIZE = 100
|
||||
; The maximum days to keep files.
|
||||
MAX_DAYS = 3
|
||||
|
||||
[cron]
|
||||
; Enable running cron tasks periodically.
|
||||
@@ -351,8 +427,8 @@ ENABLED = true
|
||||
; Run cron tasks when Gogs starts.
|
||||
RUN_AT_START = false
|
||||
|
||||
; Update mirrors
|
||||
[cron.update_mirrors]
|
||||
; Defines how often the mirror syncer checks if any mirror needs to be synchronized (based on the mirror update interval).
|
||||
SCHEDULE = @every 10m
|
||||
|
||||
; Repository health check
|
||||
@@ -368,15 +444,22 @@ ARGS =
|
||||
RUN_AT_START = true
|
||||
SCHEDULE = @every 24h
|
||||
|
||||
; Cleanup repository archives
|
||||
[cron.repo_archive_cleanup]
|
||||
RUN_AT_START = false
|
||||
SCHEDULE = @every 24h
|
||||
; Time duration to check if archive should be cleaned
|
||||
OLDER_THAN = 24h
|
||||
|
||||
[git]
|
||||
; Disables highlight of added and removed changes
|
||||
DISABLE_DIFF_HIGHLIGHT = false
|
||||
; Max number of files shown in diff view
|
||||
MAX_GIT_DIFF_FILES = 100
|
||||
; Max number of lines allowed of a single file in diff view
|
||||
MAX_GIT_DIFF_LINES = 1000
|
||||
; Max number of characters of a line allowed in diff view
|
||||
MAX_GIT_DIFF_LINE_CHARACTERS = 500
|
||||
; Max number of files shown in diff view
|
||||
MAX_GIT_DIFF_FILES = 100
|
||||
MAX_GIT_DIFF_LINE_CHARACTERS = 2000
|
||||
; Arguments for command 'git gc', e.g. "--aggressive --auto"
|
||||
; see more on http://git-scm.com/docs/git-gc/1.7.5
|
||||
GC_ARGS =
|
||||
@@ -387,21 +470,70 @@ MIGRATE = 600
|
||||
MIRROR = 300
|
||||
CLONE = 300
|
||||
PULL = 300
|
||||
DIFF = 60
|
||||
GC = 60
|
||||
|
||||
[mirror]
|
||||
; Default interval in hours between each check
|
||||
; Defines the default interval (in hours) until the next sync for a mirror (after a successful mirror sync).
|
||||
; It can be overridden individually for each mirror repository in the settings.
|
||||
DEFAULT_INTERVAL = 8
|
||||
|
||||
[api]
|
||||
; Max number of items will response in a page
|
||||
MAX_RESPONSE_ITEMS = 50
|
||||
|
||||
[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,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ
|
||||
NAMES = English,简体中文,繁體中文(香港),繁體中文(台湾),Deutsch,Français,Nederlands,Latviešu,Русский,日本語,Español,Português do Brasil,Polski,български,Italiano,Suomalainen,Türkçe,čeština
|
||||
[ui]
|
||||
; Number of repositories that are showed in one explore page
|
||||
EXPLORE_PAGING_NUM = 20
|
||||
; Number of issues that are showed in one page
|
||||
ISSUE_PAGING_NUM = 10
|
||||
; Number of maximum commits showed in one activity feed
|
||||
FEED_MAX_COMMIT_NUM = 5
|
||||
; 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
|
||||
THEME_COLOR_META_TAG = `#ff5343`
|
||||
; Max size in bytes of files to be displayed (default is 8MB)
|
||||
MAX_DISPLAY_FILE_SIZE = 8388608
|
||||
|
||||
; Used for datetimepicker
|
||||
[ui.admin]
|
||||
; Number of users that are showed in one page
|
||||
USER_PAGING_NUM = 50
|
||||
; Number of repos that are showed in one page
|
||||
REPO_PAGING_NUM = 50
|
||||
; Number of notices that are showed in one page
|
||||
NOTICE_PAGING_NUM = 25
|
||||
; Number of organization that are showed in one page
|
||||
ORG_PAGING_NUM = 50
|
||||
|
||||
[ui.user]
|
||||
; Number of repos that are showed in one page
|
||||
REPO_PAGING_NUM = 15
|
||||
; Number of news feeds that are showed in one page
|
||||
NEWS_FEED_PAGING_NUM = 20
|
||||
; Number of commits that are showed in one page
|
||||
COMMITS_PAGING_NUM = 30
|
||||
|
||||
[prometheus]
|
||||
; Whether to enable Prometheus metrics.
|
||||
ENABLED = true
|
||||
; Whether to enable HTTP Basic Authentication to protect metrics data.
|
||||
ENABLE_BASIC_AUTH = false
|
||||
; The username for HTTP Basic Authentication.
|
||||
BASIC_AUTH_USERNAME =
|
||||
; The password for HTTP Basic Authentication.
|
||||
BASIC_AUTH_PASSWORD =
|
||||
|
||||
; Extension mapping to highlight class
|
||||
; e.g. .toml=ini
|
||||
[highlight.mapping]
|
||||
|
||||
[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,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sr-SP,sv-SE,ko-KR,gl-ES,uk-UA,en-GB,hu-HU,sk-SK,id-ID,fa-IR,vi-VN,pt-PT,mn-MN,ro-RO
|
||||
NAMES = English,简体中文,繁體中文(香港),繁體中文(臺灣),Deutsch,français,Nederlands,latviešu,русский,日本語,español,português do Brasil,polski,български,italiano,suomi,Türkçe,čeština,српски,svenska,한국어,galego,українська,English (United Kingdom),Magyar,Slovenčina,Indonesian,Persian,Vietnamese,Português,Монгол,Română
|
||||
|
||||
; Used for jQuery DateTimePicker,
|
||||
; list of supported languages in https://xdsoft.net/jqplugins/datetimepicker/#lang
|
||||
[i18n.datelang]
|
||||
en-US = en
|
||||
zh-CN = zh
|
||||
@@ -421,12 +553,22 @@ it-IT = it
|
||||
fi-FI = fi
|
||||
tr-TR = tr
|
||||
cs-CZ = cs-CZ
|
||||
|
||||
; Extension mapping to highlight class
|
||||
; e.g. .toml=ini
|
||||
[highlight.mapping]
|
||||
sr-SP = sr
|
||||
sv-SE = sv
|
||||
ko-KR = ko
|
||||
gl-ES = gl
|
||||
uk-UA = uk
|
||||
en-GB = en-GB
|
||||
hu-HU = hu
|
||||
sk-SK = sk
|
||||
id-ID = id
|
||||
fa-IR = fa
|
||||
vi-VN = vi
|
||||
pt-PT = pt
|
||||
mn-MN = mn
|
||||
ro-RO = ro
|
||||
|
||||
[other]
|
||||
SHOW_FOOTER_BRANDING = false
|
||||
; Show version information about gogs and go in the footer
|
||||
SHOW_FOOTER_VERSION = true
|
||||
; Show time of template execution in the footer
|
||||
SHOW_FOOTER_TEMPLATE_LOAD_TIME = true
|
||||
|
||||
10
conf/auth.d/github.conf.example
Normal file
10
conf/auth.d/github.conf.example
Normal file
@@ -0,0 +1,10 @@
|
||||
# This is an example of GitHub authentication
|
||||
#
|
||||
id = 105
|
||||
type = github
|
||||
name = GitHub
|
||||
is_activated = true
|
||||
|
||||
[config]
|
||||
api_endpoint = https://api.github.com/
|
||||
|
||||
29
conf/auth.d/ldap_bind_dn.conf.example
Normal file
29
conf/auth.d/ldap_bind_dn.conf.example
Normal file
@@ -0,0 +1,29 @@
|
||||
# This is an example of LDAP (BindDN) authentication
|
||||
#
|
||||
id = 101
|
||||
type = ldap_bind_dn
|
||||
name = LDAP BindDN
|
||||
is_activated = true
|
||||
|
||||
[config]
|
||||
host = mydomain.com
|
||||
port = 636
|
||||
# 0 - Unencrypted, 1 - LDAPS, 2 - StartTLS
|
||||
security_protocol = 0
|
||||
skip_verify = false
|
||||
bind_dn =
|
||||
bind_password =
|
||||
user_base = ou=Users,dc=mydomain,dc=com
|
||||
attribute_username =
|
||||
attribute_name =
|
||||
attribute_surname =
|
||||
attribute_mail = mail
|
||||
attributes_in_bind = false
|
||||
filter = (&(objectClass=posixAccount)(cn=%s))
|
||||
admin_filter =
|
||||
group_enabled = false
|
||||
group_dn =
|
||||
group_filter =
|
||||
group_member_uid =
|
||||
user_uid =
|
||||
|
||||
30
conf/auth.d/ldap_simple_auth.conf.example
Normal file
30
conf/auth.d/ldap_simple_auth.conf.example
Normal file
@@ -0,0 +1,30 @@
|
||||
# This is an example of LDAP (simple auth) authentication
|
||||
#
|
||||
id = 102
|
||||
type = ldap_simple_auth
|
||||
name = LDAP Simple Auth
|
||||
is_activated = true
|
||||
|
||||
[config]
|
||||
host = mydomain.com
|
||||
port = 636
|
||||
# 0 - Unencrypted, 1 - LDAPS, 2 - StartTLS
|
||||
security_protocol = 0
|
||||
skip_verify = false
|
||||
bind_dn =
|
||||
bind_password =
|
||||
user_base =
|
||||
user_dn = cn=%s,ou=Users,dc=mydomain,dc=com
|
||||
attribute_username =
|
||||
attribute_name =
|
||||
attribute_surname =
|
||||
attribute_mail = mail
|
||||
attributes_in_bind = false
|
||||
filter = (&(objectClass=posixAccount)(cn=%s))
|
||||
admin_filter =
|
||||
group_enabled = false
|
||||
group_dn =
|
||||
group_filter =
|
||||
group_member_uid =
|
||||
user_uid =
|
||||
|
||||
10
conf/auth.d/pam.conf.example
Normal file
10
conf/auth.d/pam.conf.example
Normal file
@@ -0,0 +1,10 @@
|
||||
# This is an example of PAM authentication
|
||||
#
|
||||
id = 104
|
||||
type = pam
|
||||
name = System Auth
|
||||
is_activated = true
|
||||
|
||||
[config]
|
||||
service_name = system-auth
|
||||
|
||||
16
conf/auth.d/smtp.conf.example
Normal file
16
conf/auth.d/smtp.conf.example
Normal file
@@ -0,0 +1,16 @@
|
||||
# This is an example of SMTP authentication
|
||||
#
|
||||
id = 103
|
||||
type = smtp
|
||||
name = GMail
|
||||
is_activated = true
|
||||
|
||||
[config]
|
||||
# Either "PLAIN" or "LOGIN"
|
||||
auth = PLAIN
|
||||
host = smtp.gmail.com
|
||||
port = 587
|
||||
allowed_domains =
|
||||
tls = true
|
||||
skip_verify = false
|
||||
|
||||
23
conf/embed.go
Normal file
23
conf/embed.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"embed"
|
||||
)
|
||||
|
||||
//go:embed app.ini **/*
|
||||
var Files embed.FS
|
||||
|
||||
// FileNames returns a list of filenames exists in the given direction within
|
||||
// Files. The list includes names of subdirectories.
|
||||
func FileNames(dir string) ([]string, error) {
|
||||
entries, err := Files.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileNames := make([]string, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
fileNames = append(fileNames, entry.Name())
|
||||
}
|
||||
return fileNames, nil
|
||||
}
|
||||
16
conf/embed_test.go
Normal file
16
conf/embed_test.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFileNames(t *testing.T) {
|
||||
names, err := FileNames(".")
|
||||
require.NoError(t, err)
|
||||
|
||||
want := []string{"app.ini", "auth.d", "gitignore", "label", "license", "locale", "readme"}
|
||||
assert.Equal(t, want, names)
|
||||
}
|
||||
63
conf/gitignore/PhpStorm
vendored
Normal file
63
conf/gitignore/PhpStorm
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.xml
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# CMake
|
||||
cmake-build-debug/
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Ruby plugin and RubyMine
|
||||
/.rakeTasks
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
### PhpStorm Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
# .idea/misc.xml
|
||||
# *.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
.idea/sonarlint
|
||||
76
conf/gitignore/UnrealEngine
vendored
Normal file
76
conf/gitignore/UnrealEngine
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# Visual Studio 2015 user specific files
|
||||
.vs/
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.ipa
|
||||
|
||||
# These project files can be generated by the engine
|
||||
*.xcodeproj
|
||||
*.xcworkspace
|
||||
*.sln
|
||||
*.suo
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.VC.db
|
||||
*.VC.opendb
|
||||
|
||||
# Precompiled Assets
|
||||
SourceArt/**/*.png
|
||||
SourceArt/**/*.tga
|
||||
|
||||
# Binary Files
|
||||
Binaries/*
|
||||
Plugins/*/Binaries/*
|
||||
|
||||
# Builds
|
||||
Build/*
|
||||
|
||||
# Whitelist PakBlacklist-<BuildConfiguration>.txt files
|
||||
!Build/*/
|
||||
Build/*/**
|
||||
!Build/*/PakBlacklist*.txt
|
||||
|
||||
# Don't ignore icon files in Build
|
||||
!Build/**/*.ico
|
||||
|
||||
# Built data for maps
|
||||
*_BuiltData.uasset
|
||||
|
||||
# Configuration files generated by the Editor
|
||||
Saved/*
|
||||
|
||||
# Compiled source files for the engine to use
|
||||
Intermediate/*
|
||||
Plugins/*/Intermediate/*
|
||||
|
||||
# Cache files for the editor to use
|
||||
DerivedDataCache/*
|
||||
|
||||
|
||||
63
conf/gitignore/WebStorm
vendored
Normal file
63
conf/gitignore/WebStorm
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.xml
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# CMake
|
||||
cmake-build-debug/
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Ruby plugin and RubyMine
|
||||
/.rakeTasks
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
### WebStorm Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
# .idea/misc.xml
|
||||
# *.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
.idea/sonarlint
|
||||
49
conf/gitignore/OSX → conf/gitignore/macOS
vendored
49
conf/gitignore/OSX → conf/gitignore/macOS
vendored
@@ -1,24 +1,25 @@
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
@@ -7,22 +7,34 @@ Akihiro YAGASAKI <yaggytter AT momiage DOT com>
|
||||
Aleksejs Grocevs <aleksejs AT grocevs DOT pro>
|
||||
Aleksey Tarakin <hukendo AT yandex DOT ru>
|
||||
Alexander Steinhöfer <kontakt AT lx-s DOT de>
|
||||
Alexandre Espinosa Menor <aemenor DOT gmail DOT com>
|
||||
Alexandre Magno <alexandre DOT mbm AT gmail DOT com>
|
||||
Anders B. Hansen <anders AT birkoe DOT com>
|
||||
András Schenkerik <moviesharkteam AT gmail DOT com>
|
||||
Andrey Nering <andrey AT nering DOT com DOT br>
|
||||
Andrey Paskal <apaskal AT gmail DOT com>
|
||||
Andrey Solomatin <toadron AT yandex DOT ru>
|
||||
Antoine GIRARD <sapk AT sapk DOT fr>
|
||||
Arthur Aslanyan <arthur DOT e DOT aslanyan AT gmail DOT com>
|
||||
Aurelien Darragon <aurelien DOT darragon AT gmail DOT com>
|
||||
Barış Arda Yılmaz <ardayilmazgamer AT gmail DOT com>
|
||||
Bo-Yi Wu <appleboy DOT tw AT gmail DOT com>
|
||||
Breton Corentin <contact AT neodarz DOT net>
|
||||
Camille Baronnet <gogs AT camillebaronnet DOT fr>
|
||||
Changwoo Ryu <cwryu AT debian DOT org>
|
||||
Christoph Kisfeld <christoph DOT kisfeld AT gmail DOT com>
|
||||
Cysioland
|
||||
Damaris Padieu <damizx AT hotmail DOT fr>
|
||||
Daniel Speichert <daniel AT speichert DOT pl>
|
||||
David Yzaguirre <dvdyzag AT gmail DOT com>
|
||||
Denys Khomenko
|
||||
Dmitriy Nogay <me AT catwhocode DOT ga>
|
||||
Enrico Testori hypertesto AT gmail DOT com
|
||||
Ezequiel Gonzalez Rial <gonrial AT gmail DOT com>
|
||||
Farhan Naysee <wpmagic70 AT gmail DOT com>
|
||||
Flávio Monteiro <flaviomonteiro2013 AT gmail DOT com>
|
||||
Gabriel Dugny <gabriel DOT dugny AT gmail DOT com>
|
||||
Ganesha <reekoheek AT gmail DOT com>
|
||||
Gregor Santner <gdev AT live DOT de>
|
||||
Halil Kaya <halil AT halilkaya DOT net>
|
||||
Hamid Feizabadi <hamidfzm AT gmail DOT com>
|
||||
@@ -30,33 +42,47 @@ Huimin Wang <wanghm2009 AT hotmail DOT co DOT jp>
|
||||
ilko <kontact-mr.k AT outlook DOT com">
|
||||
Ilya Makarov
|
||||
Jamie Mansfield <dev AT jamierocks DOT uk>
|
||||
Javier Ortiz Bultron <javier DOT ortiz DOT 78 AT gmail DOT com>
|
||||
Jean THOMAS <contact AT tibounise DOT com>
|
||||
John Behm <jxsl13 AT googlemail DOT com>
|
||||
Jonas De Kegel <jonasgithub [AT] gmail [DOT] com>
|
||||
Joubert RedRat <me+github AT redrat DOT com DOT br>
|
||||
Juraj Bubniak <contact AT jbub DOT eu>
|
||||
Lafriks <lafriks AT gmail DOT com>
|
||||
Lauri Ojansivu <x AT xet7 DOT org>
|
||||
Luc Stepniewski <luc AT stepniewski DOT fr>
|
||||
Luca Bozzo <luca AT bozzo DOT it>
|
||||
Luca Kröger <l DOT kroeger01 AT gmail DOT com>
|
||||
Luc Stepniewski <luc AT stepniewski DOT fr>
|
||||
Łukasz Jan Niemier <lukasz AT niemier DOT pl>
|
||||
Marc Schiller <marc AT schiller DOT im>
|
||||
Marvin Menzerath <github AT marvin-menzerath DOT de>
|
||||
Mathias Rangel Wulff <m AT rawu DOT dk>
|
||||
Michael Härtl <haertl DOT mike AT gmail DOT com>
|
||||
Miguel de la Cruz <miguel AT mcrx DOT me>
|
||||
Mikhail Burdin <xdshot9000 AT gmail DOT com>
|
||||
Mohammad Gholami <gholami DOT mohammad DOT mgh AT gmail DOT com>
|
||||
Morten Sørensen <klim8d AT gmail DOT com>
|
||||
Muhammad Fawwaz Orabi <mfawwaz93 AT gmail DOT com>
|
||||
Nakao Takamasa <at.mattenn AT gmail DOT com>
|
||||
Natan Albuquerque <natanalbuquerque5 AT gmail DOT com>
|
||||
Odilon Junior <odilon DOT junior93 AT gmail DOT com>
|
||||
Oleksandr Yermakov <olexander DOT yermakov AT gmail DOT com>
|
||||
Óscar García Amor <ogarcia AT connectical DOT com>
|
||||
Pablo Saavedra <psaavedra AT igalia DOT com>
|
||||
Pierre Prinetti >meatqrawldotnet<
|
||||
Richard Bukovansky <richard DOT bukovansky @ gmail DOT com>
|
||||
Robert Nuske <robert DOT nuske AT web DOT de>
|
||||
Robin Hübner <profan AT prfn DOT se>
|
||||
Rste Risafov <risafov AT lazy DOT com>
|
||||
SeongJae Park <sj38 DOT park AT gmail DOT com>
|
||||
Sergey Stepanov <sergystepanov AT gmail DOT com>
|
||||
Simona Iacob <s AT zp1 DOT net>
|
||||
Thomas Fanninger <gogs DOT thomas AT fanninger DOT at>
|
||||
Tilmann Bach <tilmann AT outlook DOT com>
|
||||
Toni Villena Jiménez <tonivj5 AT gmail DOT com>
|
||||
Vincent AMSTOUTZ <vincent DOT amstoutz AT outlook DOT fr>
|
||||
Vladimir Jigulin mogaika AT yandex DOT ru
|
||||
Vladimir Vissoultchev <wqweto AT gmail DOT com>
|
||||
Vongola <me AT vongola DOT tw>
|
||||
YJSoft <yjsoft AT yjsoft DOT pe DOT kr>
|
||||
Łukasz Jan Niemier <lukasz AT niemier DOT pl>
|
||||
Pablo Saavedra <psaavedra AT igalia DOT com>
|
||||
Oscar Quisbert <quisbert_karos AT outlook DOT com>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,6 @@ sign_out=Abmelden
|
||||
sign_up=Registrieren
|
||||
register=Registrieren
|
||||
website=Webseite
|
||||
version=Version
|
||||
page=Seite
|
||||
template=Vorlage
|
||||
language=Sprache
|
||||
@@ -44,23 +43,27 @@ issues=Issues
|
||||
|
||||
cancel=Abbrechen
|
||||
|
||||
[status]
|
||||
page_not_found=Seite nicht gefunden
|
||||
internal_server_error=Interner Serverfehler
|
||||
|
||||
[install]
|
||||
install=Installation
|
||||
title=Installationsschritte für den ersten Start
|
||||
docker_helper=Wenn Gogs innerhalb von Docker läuft, lesen Sie sich bitte den <a target="_blank" href="%s">Leitfaden</a> genau durch, bevor Sie irgendwas auf dieser Seite ändern!
|
||||
requite_db_desc=Gogs benötigt MySQL, PostgreSQL, SQLite3 oder TiDB.
|
||||
docker_helper=Wenn Gogs innerhalb von Docker läuft, lesen Sie sich bitte den <a target="_blank" href="%s">Leitfaden</a> genau durch, bevor Sie etwas auf dieser Seite ändern!
|
||||
requite_db_desc=Gogs benötigt MySQL, PostgreSQL, SQLite3 oder TiDB (mit MySQL-Protokoll)
|
||||
db_title=Datenbankeinstellungen
|
||||
db_type=Datenbanktyp
|
||||
host=Host
|
||||
user=Benutzer
|
||||
password=Passwort
|
||||
db_name=Datenbankname
|
||||
db_schema=Schema
|
||||
db_helper=Bitte verwenden Sie in MySQL die InnoDB-Engine mit dem Zeichensatz utf8_general_ci.
|
||||
ssl_mode=SSL-Modus
|
||||
path=Pfad
|
||||
sqlite_helper=Der Dateipfad zur SQLite3- oder TiDB-Datenbank. <br>Bitte verwenden Sie einen absoluten Pfad, wenn Gogs als Service gestartet wird.
|
||||
err_empty_db_path=SQLite3 oder TiDB Datenbankpfad darf nicht leer sein.
|
||||
err_invalid_tidb_name=Der TiDB Datenbankname darf nicht "." und "-" enthalten.
|
||||
sqlite_helper=Der Dateipfad zur SQLite3-Datenbank. <br>Bitte verwenden Sie einen absoluten Pfad, wenn Gogs als Service gestartet wird.
|
||||
err_empty_db_path=SQLite3 Datenbankpfad darf nicht leer sein.
|
||||
no_admin_and_disable_registration=Sie können die Registrierung nicht deaktivieren, ohne ein Administratorkonto zu erstellen.
|
||||
err_empty_admin_password=Das Administrator-Passwort darf nicht leer sein.
|
||||
|
||||
@@ -75,12 +78,17 @@ domain=Domain
|
||||
domain_helper=Dies hat Auswirkung auf die SSH Klon-URLs.
|
||||
ssh_port=SSH Port
|
||||
ssh_port_helper=Der Port Ihres SSH-Servers. Leer lassen um SSH zu deaktivieren.
|
||||
use_builtin_ssh_server=Eingebauten SSH-Server verwenden
|
||||
use_builtin_ssh_server_popup=Starte eingebauten SSH-Server für git-Aufgaben, um es vom System-SSH-Dämon zu trennen.
|
||||
http_port=HTTP Port
|
||||
http_port_helper=Auf dieser Port Nummer wird Gogs erreichbar sein.
|
||||
app_url=Anwendungs-URL
|
||||
app_url_helper=Dies hat Auswirkung auf die HTTP/HTTPS Klon-URLs und den Inhalt der E-Mails.
|
||||
log_root_path=Logdateipfad
|
||||
log_root_path_helper=Verzeichnis in das Logdateien geschrieben werden.
|
||||
enable_console_mode=Konsolen-Modus einschalten
|
||||
enable_console_mode_popup=Zusätzlich zum Datei-Modus, zeige Logs auch in der Konsole.
|
||||
default_branch=Standard Branch
|
||||
|
||||
optional_title=Optionale Einstellungen
|
||||
email_title=E-Mail-Service Einstellungen
|
||||
@@ -116,7 +124,10 @@ sqlite3_not_available=Ihre Gogs-Version unterstützt SQLite3 nicht. Bitte laden
|
||||
invalid_db_setting=Datenbankeinstellungen sind nicht korrekt: %v
|
||||
invalid_repo_path=Repository Verzeichnis ist ungültig: %v
|
||||
run_user_not_match=Der ausführende Benutzer ist nicht der aktuelle Benutzer: %s -> %s
|
||||
smtp_host_missing_port=In der Adresse des SMTP Host fehlt die Portnummer.
|
||||
invalid_smtp_from=SMTP Absender Feld ist nicht gültig: %v
|
||||
save_config_failed=Fehler beim Speichern der Konfiguration: %v
|
||||
init_failed=Fehler beim Initialisieren der Anwendung: %v
|
||||
invalid_admin_setting=Admin-Konto Einstellungen sind ungültig: %v
|
||||
install_success=Herzlich Willkommen! Wir sind froh, dass Sie sich für Gogs entschieden haben. Wir wünschen viel Vergnügen damit.
|
||||
invalid_log_root_path=Pfad zum Log-Verzeichnis ist ungültig: %v
|
||||
@@ -137,6 +148,7 @@ issues.in_your_repos=In Ihren Repositories
|
||||
[explore]
|
||||
repos=Repositories
|
||||
users=Benutzer
|
||||
organizations=Organisationen
|
||||
search=Suche
|
||||
|
||||
[auth]
|
||||
@@ -145,6 +157,8 @@ register_hepler_msg=Haben Sie bereits ein Konto? Jetzt anmelden!
|
||||
social_register_hepler_msg=Haben Sie bereits ein Konto? Jetzt verknüpfen!
|
||||
disable_register_prompt=Es tut uns leid, die Registrierung wurde deaktiviert. Bitte wenden Sie sich an den Administrator.
|
||||
disable_register_mail=Es tut uns leid, die Bestätigung der Registrierungs-E-Mail wurde deaktiviert.
|
||||
auth_source=Authentifizierungsquelle
|
||||
local=Lokal
|
||||
remember_me=Angemeldet bleiben
|
||||
forgot_password=Passwort vergessen
|
||||
forget_password=Passwort vergessen?
|
||||
@@ -156,7 +170,6 @@ prohibit_login_desc=Ihrem Konto ist es nicht gestattet sich anzumelden. Bitte ko
|
||||
resent_limit_prompt=Es tut uns leid, aber Sie haben bereits eine Aktivierungs-E-Mail angefordert. Bitte warten Sie 3 Minuten und probieren Sie es dann nochmal.
|
||||
has_unconfirmed_mail=Hallo %s, Sie haben eine unbestätigte E-Mail-Adresse (<b>%s</b>). Wenn Sie keine Bestätigungs-E-Mail erhalten haben oder eine neue benötigen, klicken Sie bitte auf den folgenden Button.
|
||||
resend_mail=Hier klicken, um die Aktivierungs-E-Mail erneut zu versenden
|
||||
email_not_associate=Diese E-Mail-Adresse ist mit keinem Konto verknüpft.
|
||||
send_reset_mail=Hier klicken, um die E-Mail zum Passwort-zurücksetzen erneut zu versenden
|
||||
reset_password=Passwort zurücksetzen
|
||||
invalid_code=Es tut uns leid, der Bestätigungscode ist abgelaufen oder ungültig.
|
||||
@@ -164,6 +177,14 @@ reset_password_helper=Hier klicken, um das Passwort zurückzusetzen
|
||||
password_too_short=Das Passwort muss mindenstens 6 Zeichen lang sein.
|
||||
non_local_account=Nicht-lokale Konten können Passwörter nicht via Gogs ändern.
|
||||
|
||||
login_two_factor=Zwei-Faktor-Authentifizierung
|
||||
login_two_factor_passcode=PIN
|
||||
login_two_factor_enter_recovery_code=Geben Sie einen Wiederherstellungscode für die Zwei-Faktor-Authentifizierung ein
|
||||
login_two_factor_recovery=Zwei-Faktor-Wiederherstellung
|
||||
login_two_factor_recovery_code=Wiederherstellungscode
|
||||
login_two_factor_enter_passcode=Geben Sie die Zwei-Faktor-Authentifizierungs PIN ein
|
||||
login_two_factor_invalid_recovery_code=Der Wiederherstellungscode wurde schon benutzt oder ist nicht gültig.
|
||||
|
||||
[mail]
|
||||
activate_account=Bitte aktivieren Sie Ihr Konto
|
||||
activate_email=Bestätigen Sie Ihre E-Mail-Adresse
|
||||
@@ -199,6 +220,7 @@ Content=Inhalt
|
||||
require_error=` darf nicht leer sein.`
|
||||
alpha_dash_error=` kann ausschließlich alphanumerische Zeichen und "-_" enthalten.`
|
||||
alpha_dash_dot_error=` kann ausschließlich alphanumerische Zeichen und ".-_" enthalten.`
|
||||
alpha_dash_dot_slash_error=` kann ausschließlich alphanumerische Zeichen und ".-_/" enthalten.`
|
||||
size_error=` muss die Größe %s haben.`
|
||||
min_size_error=` muss mindestens %s Zeichen enthalten.`
|
||||
max_size_error=` darf höchstens %s Zeichen enthalten.`
|
||||
@@ -215,6 +237,7 @@ org_name_been_taken=Organisationsname ist bereits vergeben.
|
||||
team_name_been_taken=Teamname ist bereits vergeben.
|
||||
email_been_used=E-Mail-Adresse wird bereits verwendet.
|
||||
username_password_incorrect=Benutzername oder Passwort ist nicht korrekt.
|
||||
auth_source_mismatch=Die ausgewählte Authentifizierungsquelle ist dem Benutzer nicht zugeordnet.
|
||||
enterred_invalid_repo_name=Bitte achten Sie darauf, dass der von Ihnen eingegebene Repository-Name korrekt ist.
|
||||
enterred_invalid_owner_name=Bitte achten Sie darauf, dass der eingegebene Name des Besitzers korrekt ist.
|
||||
enterred_invalid_password=Bitte achten Sie darauf, dass das eingegebene Passwort richtig ist.
|
||||
@@ -242,19 +265,18 @@ following=Folge ich
|
||||
follow=Folgen
|
||||
unfollow=Nicht mehr folgen
|
||||
|
||||
form.name_reserved=Der Benutzername '%s' ist reserviert.
|
||||
form.name_pattern_not_allowed=Benutzernamen der Form '%s' sind nicht erlaubt.
|
||||
form.name_not_allowed=Benutzername oder Muster %q ist nicht erlaubt.
|
||||
|
||||
[settings]
|
||||
profile=Profil
|
||||
password=Passwort
|
||||
avatar=Profilbild
|
||||
ssh_keys=SSH-Schlüssel
|
||||
social=Soziale Konten
|
||||
applications=Anwendungen
|
||||
security=Sicherheit
|
||||
repos=Repositories
|
||||
orgs=Organisationen
|
||||
applications=Anwendungen
|
||||
delete=Konto löschen
|
||||
uid=Uid
|
||||
|
||||
public_profile=Öffentliches Profil
|
||||
profile_desc=Ihre E-Mail-Adresse ist öffentlich einsehbar und dient dazu, Ihnen Benachrichtigungen bezüglich Ihres Kontos und Aktivitäten auf der Webseite zu schicken.
|
||||
@@ -295,6 +317,7 @@ delete_email=Löschen
|
||||
email_deletion=E-Mail löschen
|
||||
email_deletion_desc=Das Löschen dieser E-Mail Adresse wird alle Informationen entfernen, die mit dieser E-Mail Adresse verknüpft sind. Wollen Sie fortfahren?
|
||||
email_deletion_success=E-Mail-Adresse wurde erfolgreich gelöscht!
|
||||
email_deletion_primary=Die primäre E-Mail-Adresse kann nicht gelöscht werden.
|
||||
add_new_email=Neue E-Mail-Adresse hinzufügen
|
||||
add_email=E-Mail-Adresse hinzufügen
|
||||
add_email_confirmation_sent=Eine neue Bestätigungsmail wurde an '%s' gesendet, bitte überprüfen Sie Ihren Posteingang innerhalb von %d Stunden um die Bestätigung abzuschließen.
|
||||
@@ -305,7 +328,7 @@ add_key=Schlüssel hinzufügen
|
||||
ssh_desc=Dies ist eine Liste aller SSH-Schlüssel, die Ihrem Konto zugeordnet sind. Bitte entfernen Sie alle Schlüssel, die Ihnen nicht bekannt sind.
|
||||
ssh_helper=<strong>Brauchen Sie Hilfe?</strong> Hier ist eine Anleitung zum <a href="%s">Erzeugen von SSH-Schlüsseln</a> oder <a href="%s">Lösen einfacher SSH-Probleme</a>.
|
||||
add_new_key=SSH-Schlüssel hinzufügen
|
||||
ssh_key_been_used=Inhalt des öffentlichen Schlüssels wurde verwendet.
|
||||
ssh_key_been_used=Inhalt des öffentlichen Schlüssels wurde bereits verwendet.
|
||||
ssh_key_name_used=Ein öffentlicher Schlüssel mit diesem Namen existiert bereits.
|
||||
key_name=Schlüsselname
|
||||
key_content=Inhalt
|
||||
@@ -320,14 +343,36 @@ no_activity=Keine neuen Aktivitäten
|
||||
key_state_desc=Dieser Schlüssel wurde in den letzten 7 Tagen verwendet
|
||||
token_state_desc=Dieses Token wurde in den letzten 7 Tagen benutzt
|
||||
|
||||
manage_social=Verknüpfte soziale Konten verwalten
|
||||
social_desc=Dies ist eine Liste verknüpfter sozialer Konten. Bitte entfernen Sie alle Verknüpfungen, die Ihnen nicht bekannt sind.
|
||||
unbind=Verknüpfung entfernen
|
||||
unbind_success=Die Verknüpfung zum sozialen Konto wurde entfernt.
|
||||
two_factor=Zwei-Faktor-Authentifizierung
|
||||
two_factor_status=Status:
|
||||
two_factor_on=Ein
|
||||
two_factor_off=Aus
|
||||
two_factor_enable=Aktivieren
|
||||
two_factor_disable=Deaktivieren
|
||||
two_factor_view_recovery_codes=Betrachten und verwahren Sie <a href="%s%s">Ihre Wiederherstellungscodes</a> an einem sicheren Ort. Sie können diese als Passwort-Code nutzen, auch wenn Sie den Zugriff zu Ihrer Authentifizierungsanwendung verloren haben.
|
||||
two_factor_http=Für HTTP/HTTPS-Operationen können Sie keine schlichten Benutzernamen und Passwörter mehr nutzen. Bitte erstellen und benutzen Sie ein <a href="%[1]s%[2]s">Persönliches Zugriffs-Token</a> als Ihre Anmeldeinformation, z.B. <code>%[3]s</code>.
|
||||
two_factor_enable_title=Zwei-Faktor-Authentifizierung aktivieren
|
||||
two_factor_scan_qr=Bitte benutzen Sie Ihre Authentifizierungsanwendung, um das Bild zu scannen:
|
||||
two_factor_or_enter_secret=Oder geben Sie Ihren Geheim-Code ein:
|
||||
two_factor_then_enter_passcode=Geben Sie die PIN ein:
|
||||
two_factor_verify=Bestätigen
|
||||
two_factor_invalid_passcode=Die eingegebene PIN ist ungültig. Bitte versuchen Sie es erneut!
|
||||
two_factor_reused_passcode=Der von dir eingegebene Passcode wurde bereits verwendet, bitte probiere einen anderen!
|
||||
two_factor_enable_error=Einschalten der Zwei-Faktor-Authentifizierung ist fehlgeschlagen: %v
|
||||
two_factor_enable_success=Die Zwei-Faktor-Authentifizierung wurde für Ihr Konto erfolgreich aktiviert!
|
||||
two_factor_recovery_codes_title=Zwei-Faktor-Authentifizierung-Wiederherstellungscodes
|
||||
two_factor_recovery_codes_desc=Wiederherstellungscodes sind dazu gedacht, verwendet zu werden, wenn Sie vorübergehend keinen Zugriff zu Ihrer Authentifizierungsanwendung haben. Jeder Wiederherstellungscode kann nur einmal verwendet werden. <b>Bitte bewahren Sie diese Codes an einem sicheren Ort auf</b>.
|
||||
two_factor_regenerate_recovery_codes=Wiederherstellungscodes neu generieren
|
||||
two_factor_regenerate_recovery_codes_error=Das erneute Generieren der Wiederherstellungscodes ist fehlgeschlagen: %v
|
||||
two_factor_regenerate_recovery_codes_success=Die neuen Wiederherstellungscodes wurden erfolgreich generiert!
|
||||
two_factor_disable_title=Zwei-Faktor-Authentifizierung deaktivieren
|
||||
two_factor_disable_desc=Das Sicherheitsniveau Ihres Kontos wird deutlich reduziert sein, nachdem die Zwei-Faktor-Authentifizierung deaktiviert wurde. Möchten Sie fortfahren?
|
||||
two_factor_disable_success=Die Zwei-Faktor-Authentifizierung wurde erfolgreich deaktiviert!
|
||||
|
||||
manage_access_token=Verwaltung persönlicher Zugangs-Token
|
||||
generate_new_token=Neuen Token erzeugen
|
||||
generate_new_token=Neues Token erzeugen
|
||||
tokens_desc=Die von Ihnen erzeugten Token können zum Zugriff auf die Gogs-API verwendet werden.
|
||||
access_token_tips=Der persönliche Zugangs-Token kann entweder als Benutzername oder als Passwort verwendet werden. Es wird empfohlen den "x-access-token" als Benutzernamen und den persönlichen Zugangs-Token als Passwort für Git-Anwendungen zu verwenden.
|
||||
new_token_desc=Jeder Token erlaubt vollen Zugriff auf ihr Konto.
|
||||
token_name=Token-Name
|
||||
generate_token=Token generieren
|
||||
@@ -336,6 +381,16 @@ delete_token=Löschen
|
||||
access_token_deletion=Persönlichen Token entfernen
|
||||
access_token_deletion_desc=Das Löschen dieses persönlichen Zugangs-Tokens wird alle zugehörigen Zugriffe der Anwendung entfernen. Möchten Sie fortfahren?
|
||||
delete_token_success=Persönlicher Zugriffs-Token wurde erfolgreich entfernt! Vergessen Sie nicht Ihre Anwendung zu aktualisieren.
|
||||
token_name_exists=Token mit dem gleichen Namen existiert bereits.
|
||||
|
||||
orgs.none=Sie sind kein Mitglied einer Organisation.
|
||||
orgs.leave_title=Organisation verlassen
|
||||
orgs.leave_desc=Sie verlieren den Zugriff auf alle Repositories und Teams nach dem Verlassen der Organisation. Möchten Sie fortfahren?
|
||||
|
||||
repos.leave=Verlassen
|
||||
repos.leave_title=Repository verlassen
|
||||
repos.leave_desc=Der Zugang zum Repository wird verloren gehen, wenn Sie es verlassen. Möchten Sie fortfahren?
|
||||
repos.leave_success=Sie haben das Repository '%s' erfolgreich verlassen!
|
||||
|
||||
delete_account=Konto löschen
|
||||
delete_prompt=Diese Aktion wird Ihr Konto dauerhaft löschen und kann <strong>NICHT</strong> rückgängig gemacht werden!
|
||||
@@ -348,10 +403,12 @@ owner=Besitzer
|
||||
repo_name=Repository-Name
|
||||
repo_name_helper=Ein guter Repository-Name besteht gewöhnlich aus kurzen, leicht zu merkenden und eindeutigen Schlüsselworten.
|
||||
visibility=Sichtbarkeit
|
||||
unlisted=Ungelistet
|
||||
visiblity_helper=Dieses Repository ist <span class="ui red text">privat</span>
|
||||
unlisted_helper=Dieses Repository ist <span class="ui red text">nicht gelistet</span>
|
||||
visiblity_helper_forced=Der Administrator hat festgelegt, dass alle neuen Repositories <span class="ui red text">privat</span> sein müssen
|
||||
visiblity_fork_helper=(Eine Änderung dieses Wertes wirkt sich auf alle Forks aus)
|
||||
clone_helper=Sie brauchen Hilfe beim Klonen? Öffnen Sie die <a target="_blank" href="%s">Hilfe</a>!
|
||||
clone_helper=Brauchen Sie Hilfe beim Klonen? Hier gibt es <a target="_blank" href="%s">Hilfe</a>!
|
||||
fork_repo=Repository forken
|
||||
fork_from=Fork von
|
||||
fork_visiblity_helper=Die Sichtbarkeit von geforkten Repositories ist nicht veränderbar.
|
||||
@@ -374,24 +431,26 @@ mirror_last_synced=Zuletzt synchronisiert
|
||||
watchers=Beobachter
|
||||
stargazers=In Favoriten von
|
||||
forks=Forks
|
||||
repo_description_helper=Beschreibung des Repository. Maximal 512 Zeichen.
|
||||
repo_description_length=Verfügbare Zeichen
|
||||
|
||||
form.reach_limit_of_creation=Der Besitzer hat die maximale Anzahl von %d erstellbaren Repositories erreicht.
|
||||
form.name_reserved=Repository-Name '%s' ist reserviert.
|
||||
form.name_pattern_not_allowed=Repository-Namen der Form '%s' sind nicht erlaubt.
|
||||
form.name_not_allowed=Repository name or pattern %q is not allowed.
|
||||
|
||||
need_auth=Authorisierung benötigt
|
||||
migrate_type=Migrationstyp
|
||||
migrate_type_helper=Dieses Repository wird ein <span class="text blue">Mirror</span> sein
|
||||
migrate_repo=Repository migrieren
|
||||
migrate.clone_address=Adresse kopieren
|
||||
migrate.clone_address_desc=Dies kann eine HTTP/HTTPS/GIT URL oder ein lokaler Serverpfad sein.
|
||||
migrate.clone_address_desc=Dies kann eine HTTP/HTTPS/GIT-URL sein.
|
||||
migrate.clone_address_desc_import_local=Sie dürfen auch ein Repository vom lokalen Serverpfad migrieren.
|
||||
migrate.permission_denied=Ihnen fehlen die Rechte zum Importieren lokaler Repositories.
|
||||
migrate.invalid_local_path=Der lokale Pfad ist ungültig, existiert nicht oder ist kein Ordner.
|
||||
migrate.clone_address_resolved_to_blocked_local_address=Klonadresse in eine lokale Netzwerkadresse aufgelöst, die implizit blockiert ist.
|
||||
migrate.failed=Fehler bei Migration: %v
|
||||
|
||||
mirror_from=Mirror von
|
||||
forked_from=geforkt von
|
||||
fork_from_self=Sie können kein Repository forken, das Ihnen gehört!
|
||||
copy_link=Kopieren
|
||||
copy_link_success=Kopiert!
|
||||
copy_link_error=Drücken Sie ⌘-C oder Strg-C zum Kopieren
|
||||
@@ -407,9 +466,9 @@ quick_guide=Kurzanleitung
|
||||
clone_this_repo=Dieses Repository klonen
|
||||
create_new_repo_command=Erstellen Sie ein neues Repository mittels der Kommandozeile
|
||||
push_exist_repo=Bestehendes Repository von der Kommandozeile pushen
|
||||
repo_is_empty=Dieses Repository ist leer. Bitte kommen Sie später wieder!
|
||||
bare_message=Dieses Repository hat noch keinen Inhalt.
|
||||
|
||||
code=Code
|
||||
files=Dateien
|
||||
branch=Branch
|
||||
tree=Struktur
|
||||
filter_branch_and_tag=Nach Branch oder Tag filtern
|
||||
@@ -420,51 +479,65 @@ pulls=Pull-Requests
|
||||
labels=Label
|
||||
milestones=Meilensteine
|
||||
commits=Commits
|
||||
git_branches=Branches
|
||||
releases=Releases
|
||||
file_raw=Originalformat
|
||||
file_history=Verlauf
|
||||
file_view_raw=Ansicht im Originalformat
|
||||
file_permalink=Permalink
|
||||
file_too_large=Diese Datei ist zu groß zum Anzeigen
|
||||
video_not_supported_in_browser=Ihr Browser unterstützt HTML5 Video-Tags nicht.
|
||||
|
||||
branches.overview=Übersicht
|
||||
branches.active_branches=Aktive Branches
|
||||
branches.stale_branches=Alte Branches
|
||||
branches.all=Alle Branches
|
||||
branches.updated_by=Aktualisiert %[1]s von %[2]s
|
||||
branches.change_default_branch=Ändere Standard-Branch
|
||||
branches.default_deletion_not_allowed=Cannot delete the default branch.
|
||||
branches.protected_deletion_not_allowed=Cannot delete a protected branch.
|
||||
|
||||
editor.new_file=Neue Datei
|
||||
editor.upload_file=Datei hochladen
|
||||
editor.edit_file=Datei bearbeiten
|
||||
editor.preview_changes=Vorschau der Änderungen
|
||||
editor.cannot_edit_non_text_files=Nicht-Text Dateien können nicht bearbeitet werden
|
||||
editor.edit_this_file=Diese Datei bearbeiten
|
||||
editor.must_be_on_a_branch=You must be on a branch to make or propose changes to this file
|
||||
editor.fork_before_edit=Um die Datei zu bearbeiten müssen Sie das Repository forken
|
||||
editor.delete_this_file=Diese Datei löschen
|
||||
editor.must_have_write_access=You must have write access to make or propose changes to this file
|
||||
editor.edit_this_file=Datei bearbeiten
|
||||
editor.must_be_on_a_branch=Sie müssen sich in einem Branch befinden, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen
|
||||
editor.fork_before_edit=Um die Datei zu bearbeiten, müssen Sie das Repository forken
|
||||
editor.delete_this_file=Datei löschen
|
||||
editor.must_have_write_access=Du musst Schreibzugriff haben, um Änderungen an dieser Datei vorzuschlagen oder vorzunehmen
|
||||
editor.file_delete_success=Die Datei '%s' wurde erfolgreich gelöscht!
|
||||
editor.name_your_file=Dateinamen eingeben...
|
||||
editor.filename_help=To add directory, just type it and press /. To remove a directory, go to the beginning of the field and press backspace.
|
||||
editor.filename_help=Um einen Ordner hinzuzufügen, gib den Namen ein und drücke /. Um einen Ordner zu entfernen, gehe zum Anfang des Feldes und drücke auf die Rücktaste.
|
||||
editor.or=oder
|
||||
editor.cancel_lower=abbrechen
|
||||
editor.commit_changes=Änderungen im Commit
|
||||
editor.commit_changes=Änderungen einchecken
|
||||
editor.add_tmpl=Hinzufügen von '%s/<filename>'
|
||||
editor.add='%s' hinzufügen
|
||||
editor.update='%s' ändern
|
||||
editor.delete='%s' löschen
|
||||
editor.commit_message_desc=Eine optionale, erweiterte Commit Beschreibung...
|
||||
editor.commit_directly_to_this_branch=Änderungen direkt dem Branch <strong class="branch-name">%s</strong> hinzufügen.
|
||||
editor.create_new_branch=Erstellen Sie einen <strong>neuen Branch</strong> für diesen Commit und starten Sie einen Pull Request.
|
||||
editor.commit_message_desc=Eine ausführlichere Beschreibung kann hinzugefügt werden...
|
||||
editor.commit_directly_to_this_branch=Direkt in den <strong class="branch-name">%s</strong> Branch einchecken.
|
||||
editor.create_new_branch=Einen <strong>neuen Branch</strong> für diesen Commit erstellen und einen Pull Request starten.
|
||||
editor.new_branch_name_desc=Neuer Branch Name...
|
||||
editor.cancel=Abbrechen
|
||||
editor.filename_cannot_be_empty=Der Dateiname darf nicht leer sein.
|
||||
editor.branch_already_exists=Branch '%s' existiert bereits in diesem Repository.
|
||||
editor.directory_is_a_file='%s' im übergeordneten Verzeichnis ist eine Datei und kein Verzeichnis.
|
||||
editor.file_is_a_symlink=Die Datei '%s' ist ein Symlink, der im Webeditor nicht bearbeitet werden kann.
|
||||
editor.filename_is_a_directory=Die Datei '%s' existiert bereits als Verzeichnis in diesem Repository.
|
||||
editor.file_editing_no_longer_exists=Die Datei '%s' welche Sie bearbeiten existiert in diesem Repository nicht mehr.
|
||||
editor.file_editing_no_longer_exists=Die Datei '%s', welche Sie bearbeiten, existiert in diesem Repository nicht mehr.
|
||||
editor.file_changed_while_editing=Seit dem Start der Bearbeitung hat sich die Datei geändert. <a target="_blank" href="%s">Hier klicken</a> um die Änderungen zu sehen, oder nochmals <strong>Commit drücken</strong> um die Änderungen zu überschreiben.
|
||||
editor.file_already_exists=Eine Datei mit dem Namen '%s' existiert bereits in diesem Repository.
|
||||
editor.no_changes_to_show=Keine Änderungen vorhanden.
|
||||
editor.fail_to_update_file=Fehler beim Ändern/Erstellen der Datei '%s'. Fehler: %v
|
||||
editor.fail_to_delete_file=Fehler beim Löschen der Datei '%s'. Fehler: %v
|
||||
editor.add_subdir=Unterverzeichnis erstellen...
|
||||
editor.unable_to_upload_files=Fehler beim Hochladen der Dateien zu '%s'. Fehler: %v
|
||||
editor.upload_files_to_dir=Dateien hochladen nach '%s'
|
||||
|
||||
commits.commit_history=Commit Verlauf
|
||||
commits.commits=Commits
|
||||
commits.search=Commits durchsuchen
|
||||
commits.find=Finden
|
||||
@@ -536,7 +609,7 @@ issues.commit_ref_at=`hat dieses Issue <a id="%[1]s" href="#%[1]s">%[2]s</a> aus
|
||||
issues.poster=Ersteller
|
||||
issues.collaborator=Mitarbeiter
|
||||
issues.owner=Besitzer
|
||||
issues.sign_in_require_desc=<a href="%s">Anmelden</a> um an der Diskussion teilzunehmen.
|
||||
issues.sign_in_require_desc=<a href="%s">Anmelden</a>, um an der Diskussion teilzunehmen.
|
||||
issues.edit=Bearbeiten
|
||||
issues.cancel=Abbrechen
|
||||
issues.save=Speichern
|
||||
@@ -562,6 +635,7 @@ pulls.compare_compare=vergleichen
|
||||
pulls.filter_branch=Branch filtern
|
||||
pulls.no_results=Keine Ergebnisse verfügbar.
|
||||
pulls.nothing_to_compare=Es gibt nichts zu vergleichen, da Base- und Head-Branch gleich sind.
|
||||
pulls.nothing_merge_base=Es gibt nichts zu vergleichen, da beide Zweige eine komplett unterschiedliche Historie haben.
|
||||
pulls.has_pull_request=`Es existiert bereits ein Pull-Request zwischen diesen beiden Zielen: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
|
||||
pulls.create=Pull-Request erstellen
|
||||
pulls.title_desc=möchte %[1]d Commits von <code>%[2]s</code> nach <code>%[3]s</code> zusammenführen
|
||||
@@ -577,16 +651,21 @@ pulls.is_checking=Die Konfliktprüfung läuft noch. Bitte aktualisieren Sie die
|
||||
pulls.can_auto_merge_desc=Dieser Pull-Request kann automatisch zusammengeführt werden.
|
||||
pulls.cannot_auto_merge_desc=Dieser Pull-Request kann nicht automatisch zusammengeführt werden, da es Konflikte gibt.
|
||||
pulls.cannot_auto_merge_helper=Bitte manuell zusammenführen, um die Konflikte zu lösen.
|
||||
pulls.create_merge_commit=Erstelle einen Merge-Commit
|
||||
pulls.rebase_before_merging=Rebase vor dem Zusammenführen
|
||||
pulls.commit_description=Commit Beschreibung
|
||||
pulls.merge_pull_request=Pull-Request zusammenführen
|
||||
pulls.open_unmerged_pull_exists=`Sie können diesen Pull-Request nicht wieder öffnen, da bereits ein offener Pull-Request (#%d) aus dem selben Repository mit den gleichen Merge-Informationen existiert und auf das Zusammenführen wartet.`
|
||||
pulls.delete_branch=Zweig löschen
|
||||
pulls.delete_branch_has_new_commits=Zweig kann nicht gelöscht werden, da er noch weitere Commits nach dem Zusammenführen enthält.
|
||||
|
||||
milestones.new=Neuer Meilenstein
|
||||
milestones.open_tab=%d offen
|
||||
milestones.close_tab=%d geschlossen
|
||||
milestones.closed=Geschlossen %s
|
||||
milestones.no_due_date=Kein Fälligkeitsdatum
|
||||
milestones.open=Offen
|
||||
milestones.close=Geschlossen
|
||||
milestones.open=Öffnen
|
||||
milestones.close=Schließen
|
||||
milestones.new_subheader=Erstellen Sie Meilensteine, um ihre Issues zu organisieren.
|
||||
milestones.create=Meilenstein erstellen
|
||||
milestones.title=Titel
|
||||
@@ -629,6 +708,29 @@ settings.collaboration.admin=Adminrechte
|
||||
settings.collaboration.write=Schreibrechte
|
||||
settings.collaboration.read=Leserechte
|
||||
settings.collaboration.undefined=Nicht definiert
|
||||
settings.branches=Branches
|
||||
settings.branches_bare=Branches leerer Repositories können nicht verwaltet werden. Bitte erst Datei(en) pushen.
|
||||
settings.default_branch=Standard-Branch
|
||||
settings.default_branch_desc=Der Standard-Branch gilt als Basis für Commits, Pull-Requests und Online-Bearbeitung.
|
||||
settings.update=Aktualisieren
|
||||
settings.update_default_branch_unsupported=Die Änderung des Standard-Branch wird von der Git-Version auf dem Server nicht unterstützt.
|
||||
settings.update_default_branch_success=Standard-Branch dieses Repositories wurde erfolgreich aktualisiert!
|
||||
settings.protected_branches=Protected Branches
|
||||
settings.protected_branches_desc=Schützt Branches vor forcierten Pushes und versehentlichem Löschen. Comitter können freigeschaltet werden.
|
||||
settings.choose_a_branch=Wählen Sie einen Branch...
|
||||
settings.branch_protection=Branch-Schutz
|
||||
settings.branch_protection_desc=Bitte wählen Sie Schutzoptionen für den Branch <b>%s</b>.
|
||||
settings.protect_this_branch=Diesen Branch schützen
|
||||
settings.protect_this_branch_desc=Verhindere forcierte Pushes sowie Löschungen.
|
||||
settings.protect_require_pull_request=Verlange Pull-Request an Stelle von direkten Pushes
|
||||
settings.protect_require_pull_request_desc=Aktivieren Sie diese Option, um direktes Pushen in diesen Branch zu verhindern. Commits müssen in einen anderen, ungeschützten Branch gepusht werden und dann per Pull-Request in diesen Branch überführt werden.
|
||||
settings.protect_whitelist_committers=Hinzufügen von Benutzern oder Teams zur Whitelist, die in diesen Branch pushen dürfen
|
||||
settings.protect_whitelist_committers_desc=Fügt Benutzer oder Teams zur Push-Whitelist dieses Branches hinzu. Auf der Whitelist geführte Benutze können können ohne Prüfung von Pull-Requests pushen.
|
||||
settings.protect_whitelist_users=Benutzer, die in diesen Branch pushen können
|
||||
settings.protect_whitelist_search_users=Benutzer suchen
|
||||
settings.protect_whitelist_teams=Teams, deren Mitglieder in diesen Branch pushen können
|
||||
settings.protect_whitelist_search_teams=Teams suchen
|
||||
settings.update_protect_branch_success=Schutzoptionen für diesen Branch wurden erfolgreich aktualisiert!
|
||||
settings.hooks=Webhooks
|
||||
settings.githooks=Git-Hooks
|
||||
settings.basic_settings=Grundeinstellungen
|
||||
@@ -641,19 +743,26 @@ settings.change_reponame_prompt=Diese Änderung wirkt sich darauf aus, wie sich
|
||||
settings.advanced_settings=Erweiterte Einstellungen
|
||||
settings.wiki_desc=Wiki einschalten
|
||||
settings.use_internal_wiki=Eingebautes Wiki verwenden
|
||||
settings.allow_public_wiki_desc=Erlaube öffentlichen Zugang zum Wiki, auch wenn das Repository privat ist
|
||||
settings.use_external_wiki=Externes Wiki verwenden
|
||||
settings.external_wiki_url=Externe Wiki URL
|
||||
settings.external_wiki_url_desc=Besucher werden auf diese URL umgeleitet, wenn sie auf den Tab klicken.
|
||||
settings.issues_desc=Issue-Tracker einschalten
|
||||
settings.use_internal_issue_tracker=Eingebauten Issue-Tracker verwenden
|
||||
settings.allow_public_issues_desc=Erlaube öffentlichen Zugriff auf Issues, auch wenn das Repository privat ist
|
||||
settings.use_external_issue_tracker=Externes Issue-System verwenden
|
||||
settings.external_tracker_url=URL eines externen Issue Trackers
|
||||
settings.external_tracker_url_desc=Besucher werden auf diese URL umgeleitet, wenn sie auf den Tab klicken.
|
||||
settings.tracker_url_format=URL-Format des externen Issue-Systems
|
||||
settings.tracker_issue_style=Namenskonvention des externen Issue-Trackers:
|
||||
settings.tracker_issue_style.numeric=Numerisch
|
||||
settings.tracker_issue_style.alphanumeric=Alphanumerisch
|
||||
settings.tracker_url_format_desc=Sie können die Platzhalter <code>{user} {repo} {index}</code> für den Benutzernamen, den Namen des Repositories und die Issue-Nummer verwenden.
|
||||
settings.pulls_desc=Pull-Requests aktivieren, um öffentliche Mitwirkung zu ermöglichen
|
||||
settings.pulls_desc=Erlaube Pull-Requests zur Zusammenarbeit von Repositories und Branches
|
||||
settings.pulls.ignore_whitespace=Ignoriere whitespace Änderungen
|
||||
settings.pulls.allow_rebase_merge=Die Verwendung von Rebase erlauben, um Commits zu mergen
|
||||
settings.danger_zone=Gefahrenzone
|
||||
settings.cannot_fork_to_same_owner=Besitzer kann das Repository nicht forken.
|
||||
settings.new_owner_has_same_repo=Der neue Eigentümer hat bereits ein Repository mit dem gleichen Namen. Bitte wählen Sie einen anderen Namen.
|
||||
settings.convert=In ein normales Repository umwandeln
|
||||
settings.convert_desc=Dieser Mirror kann in ein normales Repository umgewandelt werden. Dies kann nicht rückgängig gemacht werden.
|
||||
@@ -661,12 +770,12 @@ settings.convert_notices_1=- Dieser Vorgang wandelt das Mirror-Repository in ein
|
||||
settings.convert_confirm=Umwandlung bestätigen
|
||||
settings.convert_succeed=Das Repository wurde erfolgreich in ein normales Repository umgewandelt.
|
||||
settings.transfer=Besitz übertragen
|
||||
settings.transfer_desc=Dieses Repository auf einen anderen Benutzer bzw. eine Organisation in der Sie Admin-Rechte haben übertragen.
|
||||
settings.transfer_desc=Dieses Repository auf einen anderen Benutzer oder eine Organisation, in der Sie Admin-Rechte haben, übertragen.
|
||||
settings.transfer_notices_1=- Sie werden keinen Zugriff mehr haben, wenn der neue Besitzer ein individueller Benutzer ist.
|
||||
settings.transfer_notices_2=- Sie werden weiterhin Zugriff haben, wenn der neue Besitzer eine Organisation ist und Sie einer der Besitzer sind.
|
||||
settings.transfer_form_title=Bitte geben Sie die folgenden Informationen ein, um die Operation zu bestätigen:
|
||||
settings.wiki_delete=Wiki-Daten löschen
|
||||
settings.wiki_delete_desc=Das Löschen von Wiki Daten kann nicht rückgängig gemacht werden. Bitte seien Sie vorsichtig.
|
||||
settings.wiki_delete_desc=Das Löschen von Wiki-Daten kann nicht rückgängig gemacht werden. Bitte seien Sie vorsichtig.
|
||||
settings.wiki_delete_notices_1=- Dies löscht und deaktiviert das Wiki für %s
|
||||
settings.wiki_deletion_success=Repository Wiki Daten erfolgreich gelöscht.
|
||||
settings.delete=Dieses Repository löschen
|
||||
@@ -688,20 +797,25 @@ settings.collaborator_deletion_desc=Nach dem Löschen wird dieser Benutzer keine
|
||||
settings.remove_collaborator_success=Mitarbeiter wurde entfernt.
|
||||
settings.search_user_placeholder=Benutzer suchen...
|
||||
settings.org_not_allowed_to_be_collaborator=Eine Organisation kann nicht als Mitarbeiter hinzugefügt werden.
|
||||
settings.user_is_org_member=Benutzer ist ein Organisationsmitglied und kann nicht als Mitarbeiter hinzugefügt werden.
|
||||
settings.add_webhook=Webhook hinzufügen
|
||||
settings.hooks_desc=Webhooks erlauben es Ihnen, externe Dienste zu informieren, wenn etwas Bestimmtes in Ihrem Repository passiert. Gogs sendet dann einen POST-Request an alle angegebenen URLs. Erfahren Sie mehr in unserem <a target="_blank" href="%s">Webhooks Guide</a>.
|
||||
settings.webhooks.add_new=Einen neuen Webhook hinzufügen:
|
||||
settings.webhooks.choose_a_type=Typ auswählen...
|
||||
settings.add_webhook=Webhook hinzufügen
|
||||
settings.webhook_deletion=Webhook entfernen
|
||||
settings.webhook_deletion_desc=Das Löschen dieses Webhooks wird alle zugehörigen Informationen und den Übertragungsverlauf entfernen. Wirklich fortfahren?
|
||||
settings.webhook_deletion_success=Webhook wurde erfolgreich entfernt!
|
||||
settings.webhook.test_delivery=Senden testen
|
||||
settings.webhook.test_delivery_desc=Sendet ein simuliertes Push-Ereignis, um die Webhook-Einstellungen zu testen
|
||||
settings.webhook.test_delivery_success=Test-Webhook wurde zur Auslieferungswarteschlange hinzugefügt. Es kann einige Sekunden dauern, bevor es in der Auslieferungshistorie erscheint.
|
||||
settings.webhook.redelivery=Erneuter Versand
|
||||
settings.webhook.redelivery_success=Hook-Task '%s' wurde wieder zur Auslieferungswarteschlange hinzugefügt. Es kann einige Sekunden, bis sich der Auslieferungsstatus in der History aktualisiert hat.
|
||||
settings.webhook.request=Anfrage
|
||||
settings.webhook.response=Antwort
|
||||
settings.webhook.headers=Kopfzeilen
|
||||
settings.webhook.payload=Nutzdaten
|
||||
settings.webhook.body=Inhalt
|
||||
settings.webhook.err_cannot_parse_payload_url=Payload URL kann nicht analysiert werden: %v
|
||||
settings.webhook.url_resolved_to_blocked_local_address=Die Payload-URL wurde in eine lokale Netzwerkadresse aufgelöst, die implizit blockiert ist.
|
||||
settings.githooks_desc=Git-Hooks werden von Git selbst bereitgestellt. Sie können die Dateien der unterstützten Hooks in der Liste unten bearbeiten, um eigene Operationen einzubinden.
|
||||
settings.githook_edit_desc=Wenn ein Hook inaktiv ist, wird der Standardinhalt benutzt. Lassen Sie den Inhalt leer, um den Hook zu deaktivieren.
|
||||
settings.githook_name=Hook-Name
|
||||
@@ -711,6 +825,7 @@ settings.add_webhook_desc=Gogs sendet einen <code>POST</code>-Request an die unt
|
||||
settings.payload_url=Payload URL
|
||||
settings.content_type=Inhaltstyp
|
||||
settings.secret=Secret
|
||||
settings.secret_desc=Das Secret wird im <code>X-Gogs-Signature</code> Header als hexadezimalem SHA256 HMAC Stempel der Nutzlast.
|
||||
settings.slack_username=Benutzername
|
||||
settings.slack_icon_url=Icon URL
|
||||
settings.slack_color=Farbe
|
||||
@@ -720,10 +835,20 @@ settings.event_send_everything=Ich brauche <strong>alles</strong>.
|
||||
settings.event_choose=Lass mich auswählen, was ich brauche.
|
||||
settings.event_create=Erstellen
|
||||
settings.event_create_desc=Branch/Tag erstellt
|
||||
settings.event_pull_request=Pull Request
|
||||
settings.event_pull_request_desc=Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
|
||||
settings.event_delete=Löschen
|
||||
settings.event_delete_desc=Branch/Tag gelöscht
|
||||
settings.event_fork=Fork
|
||||
settings.event_fork_desc=Repository geforkt
|
||||
settings.event_push=Push
|
||||
settings.event_push_desc=Git push auf ein Repository
|
||||
settings.event_issues=Issues
|
||||
settings.event_issues_desc=Issue geöffnet, geschlossen, wieder geöffnet, bearbeitet, zugewiesen, nicht zugewiesen, Label aktualisiert, Label gelöscht, einem Meilenstein zugewiesen oder davon entfernt.
|
||||
settings.event_pull_request=Pull-Request
|
||||
settings.event_pull_request_desc=Pull-Request geöffnet, geschlossen, wieder geöffnet, bearbeitet, zugewiesen, nicht zugewiesen, Label aktualisiert, Label gelöscht, einem Meilenstein zugewiesen, davon entfernt oder synchronisiert.
|
||||
settings.event_issue_comment=Issue-Kommentar
|
||||
settings.event_issue_comment_desc=Issue-Kommentar angelegt, geändert oder gelöscht.
|
||||
settings.event_release=Release
|
||||
settings.event_release_desc=Release in Repository veröffentlicht.
|
||||
settings.active=Aktiv
|
||||
settings.active_helper=Details über das auslösende Ereignis des Webhooks werden ebenfalls mit gesendet
|
||||
settings.add_hook_success=Webhook hinzugefügt
|
||||
@@ -733,10 +858,13 @@ settings.delete_webhook=Webhook löschen
|
||||
settings.recent_deliveries=Letzte Zustellungen
|
||||
settings.hook_type=Hook Typ
|
||||
settings.add_slack_hook_desc=Fügen Sie <a href="%s">Slack</a>-Integration zu Ihrem Repository hinzu.
|
||||
settings.add_discord_hook_desc=Fügen Sie <a href="%s">Discord</a>-Integration zu Ihrem Repository hinzu.
|
||||
settings.add_dingtalk_hook_desc=<a href="%s">Dingtalk</a>-Integration zu deinem Repository hinzufügen.
|
||||
settings.slack_token=Token
|
||||
settings.slack_domain=Domain
|
||||
settings.slack_channel=Kanal
|
||||
settings.deploy_keys=Deploy-Schlüssel
|
||||
settings.deploy_keys_helper=<b>Häufiger Fehler!</b> Wenn Sie öffentliche Schlüssel hinzufügen wollen, gehen Sie zu Ihren <a href="%s%s"> Kontoeinstellungen</a>.
|
||||
settings.add_deploy_key=Deploy-Schlüssel hinzufügen
|
||||
settings.deploy_key_desc=Deploy-Schlüssel haben nur lesenden Zugriff. Sie sind nicht identisch mit dem SSH-Schlüssel des persönlichen Kontos.
|
||||
settings.no_deploy_keys=Sie haben noch keine Deploy-Schlüssel hinzugefügt.
|
||||
@@ -748,6 +876,8 @@ settings.add_key_success=Der Deploy-Schlüssel '%s' wurde erfolgreich hinzugefü
|
||||
settings.deploy_key_deletion=Deploy-Schlüssel löschen
|
||||
settings.deploy_key_deletion_desc=Nach dem Löschen dieses Deploy-Schlüssels werden entsprechende Zugriffe auf dieses Repository nicht mehr möglich sein. Möchten Sie wirklich fortfahren?
|
||||
settings.deploy_key_deletion_success=Deploy-Schlüssel wurde erfolgreich gelöscht!
|
||||
settings.description_desc=Beschreibung des Repository. Maximal 512 Zeichen.
|
||||
settings.description_length=Verfügbare Zeichen
|
||||
|
||||
diff.browse_source=Quellcode durchsuchen
|
||||
diff.parent=Ursprung
|
||||
@@ -766,7 +896,6 @@ release.releases=Releases
|
||||
release.new_release=Neues Release
|
||||
release.draft=Entwurf
|
||||
release.prerelease=Pre-Release
|
||||
release.stable=Stabil
|
||||
release.edit=bearbeiten
|
||||
release.ahead=<strong>%d</strong> Commits zu %s seit diesem Release
|
||||
release.source_code=Quelltext
|
||||
@@ -813,8 +942,8 @@ team_name_helper=Unter diesem Namen können Sie in Diskussionen auf das Team ver
|
||||
team_desc_helper=Worum geht es bei diesem Team?
|
||||
team_permission_desc=Welche Berechtigungsstufe soll das Team haben?
|
||||
|
||||
form.name_reserved=Organisationsname '%s' ist bereits vergeben.
|
||||
form.name_pattern_not_allowed=Organisationsnamen der Form '%s' sind nicht erlaubt.
|
||||
form.name_not_allowed=Organisationsname oder Muster %q ist nicht zulässig.
|
||||
form.team_name_not_allowed=Benutzername oder Muster %q ist nicht erlaubt.
|
||||
|
||||
settings=Einstellungen
|
||||
settings.options=Optionen
|
||||
@@ -886,12 +1015,19 @@ first_page=Erste
|
||||
last_page=Letzte
|
||||
total=Gesamt: %d
|
||||
|
||||
dashboard.build_info=Build-Informationen
|
||||
dashboard.app_ver=Anwendungsversion
|
||||
dashboard.git_version=Git-Version
|
||||
dashboard.go_version=Go-Version
|
||||
dashboard.build_time=Build-Zeit
|
||||
dashboard.build_commit=Build-Commit
|
||||
dashboard.statistic=Statistik
|
||||
dashboard.operations=Operationen
|
||||
dashboard.system_status=Systemmonitor-Status
|
||||
dashboard.statistic_info=Gogs Datenbank hat <b>%d</b> Benutzer, <b>%d</b> Organisationen, <b>%d</b> öffentliche Schlüssel, <b>%d</b> Repositories, <b>%d</b> Beobachtet, <b>%d</b> Favoriten, <b>%d</b> Aktionen, <b>%d</b> Zugriffe, <b>%d</b> Issues, <b>%d</b> Kommentare, <b>%d</b> Konten sozialer Medien, <b>%d</b> Folgende, <b>%d</b> Mirror, <b>%d</b> Releases, <b>%d</b> Login-Quellen, <b>%d</b> Webhooks, <b>%d</b> Meilensteine, <b>%d</b> Label, <b>%d</b> Hook-Tasks, <b>%d</b> Teams, <b>%d</b> Aktualisierungs-Tasks, <b>%d</b> Anhänge.
|
||||
dashboard.operation_name=Name der Operation
|
||||
dashboard.operation_switch=Wechseln
|
||||
dashboard.select_operation_to_run=Bitte wählen Sie den auszuführenden Vorgang aus
|
||||
dashboard.operation_run=Ausführen
|
||||
dashboard.clean_unbind_oauth=Nicht verbundene OAuths bereinigen
|
||||
dashboard.clean_unbind_oauth_success=Alle nicht verbundenen OAuth-Tokens wurden gelöscht.
|
||||
@@ -905,8 +1041,8 @@ dashboard.git_gc_repos=Garbage Collection auf Repositories ausführen
|
||||
dashboard.git_gc_repos_success=Garbage Collection wurde auf allen Repositories erfolgreich ausgeführt.
|
||||
dashboard.resync_all_sshkeys=Datei '.ssh/authorized_keys' neu anlegen (Achtung: Schlüssel, die nicht zu Gogs gehören gehen verloren)
|
||||
dashboard.resync_all_sshkeys_success=Alle öffentlichen Keys wurden erfolgreich neu geschrieben.
|
||||
dashboard.resync_all_update_hooks=Alle Aktualisierungs-Hooks von Repositories neu anlegen (wird benötigt, wenn der angepasste Konfigurationspfad geändert wurde)
|
||||
dashboard.resync_all_update_hooks_success=Die Hooks aller Repositories wurden erfolgreich neu angelegt.
|
||||
dashboard.resync_all_hooks=Synchronisiere pre-receive, update und post-receive Hooks für alle Repositories
|
||||
dashboard.resync_all_hooks_success=Pre-receive, update und post-receive Hooks aller Repositorien wurden erfolgreich synchronisiert.
|
||||
dashboard.reinit_missing_repos=Alle Repository-Datensätze mit verloren gegangenen Git-Dateien neu initialisieren
|
||||
dashboard.reinit_missing_repos_success=Alle Repository-Datensätze, die Git-Dateien verloren haben wurden erfolgreich neu initialisiert.
|
||||
|
||||
@@ -981,12 +1117,14 @@ repos.private=Privat
|
||||
repos.watches=Beobachtungen
|
||||
repos.stars=Favoriten
|
||||
repos.issues=Issues
|
||||
repos.size=Größe
|
||||
|
||||
auths.auth_manage_panel=Authentifizierung
|
||||
auths.auth_sources=Authentifizierungsquelle
|
||||
auths.new=Neue Quelle hinzufügen
|
||||
auths.name=Name
|
||||
auths.type=Typ
|
||||
auths.enabled=Aktiviert
|
||||
auths.default=Standard
|
||||
auths.updated=Aktualisiert
|
||||
auths.auth_type=Authentifizierungstyp
|
||||
auths.auth_name=Authentifizierungsname
|
||||
@@ -995,15 +1133,21 @@ auths.domain=Domain
|
||||
auths.host=Host
|
||||
auths.port=Port
|
||||
auths.bind_dn=DN binden
|
||||
auths.bind_dn_helper=Sie können "%s" als Platzhalter für den Benutzernamen einsetzen, z.B. DOM\%s
|
||||
auths.bind_password=Passwort binden
|
||||
auths.bind_password_helper=Achtung: Das Passwort wird im Klartext gespeichert. Benutzen Sie kein Konto mit hoher Berechtigungsstufe.
|
||||
auths.user_base=Basis für Benutzersuche
|
||||
auths.user_dn=Benutzer DN
|
||||
auths.user_dn=Benutzer-DN
|
||||
auths.attribute_username=Attribut Benutzername
|
||||
auths.attribute_username_placeholder=Leer lassen, um den Wert aus dem Anmeldeformular als Benutzernamen zu verwenden.
|
||||
auths.attribute_name=Attribut Vorname
|
||||
auths.attribute_name=Vornamenattribut
|
||||
auths.attribute_surname=Attribut Nachname
|
||||
auths.attribute_mail=Attribut E-Mail
|
||||
auths.verify_group_membership=Überprüfen der Gruppenmitgliedschaft
|
||||
auths.group_search_base_dn=Gruppensuche Basisdomainname
|
||||
auths.group_filter=Gruppenfilter
|
||||
auths.group_attribute_contain_user_list=Gruppenattribut, beinhaltet die Benutzerliste
|
||||
auths.user_attribute_listed_in_group=Benutzerattribut in der Gruppenliste
|
||||
auths.attributes_in_bind=Hole Attribute im Bind-Kontext
|
||||
auths.filter=Benutzerfilter
|
||||
auths.admin_filter=Admin Filter
|
||||
@@ -1017,9 +1161,9 @@ auths.enable_tls=TLS-Verschlüsselung aktivieren
|
||||
auths.skip_tls_verify=TLS-Prüfung überspringen
|
||||
auths.pam_service_name=PAM Dienstname
|
||||
auths.enable_auto_register=Automatische Registrierung aktivieren
|
||||
auths.tips=Tipps
|
||||
auths.edit=Authentifizierungseinstellungen bearbeiten
|
||||
auths.activated=Diese Authentifizierung ist aktiv
|
||||
auths.default_auth=Diese Authentifizierungsmethode ist die Vorgabe
|
||||
auths.new_success=Neue Authentifizierung '%s' wurde erfolgreich hinzugefügt.
|
||||
auths.update_success=Die Authentifizierungseinstellungen wurden erfolgreich aktualisiert.
|
||||
auths.update=Authentifizierungseinstellungen aktualisieren
|
||||
@@ -1028,107 +1172,189 @@ auths.delete_auth_title=Authentifizierung löschen
|
||||
auths.delete_auth_desc=Diese Authentifizierung wird gelöscht. Möchten Sie fortfahren?
|
||||
auths.still_in_used=Diese Authentifizierung wird noch von einigen Benutzern verwendet. Bitte löschen Sie diese Benutzer oder ändern Sie deren Anmeldetyp.
|
||||
auths.deletion_success=Authentifizierung wurde erfolgreich gelöscht!
|
||||
auths.login_source_exist=Login-Quelle '%s' ist bereits vorhanden.
|
||||
auths.github_api_endpoint=API Endpunkt
|
||||
|
||||
config.not_set=(nicht festgelegt)
|
||||
config.server_config=Serverkonfiguration
|
||||
config.app_name=Name der Anwendung
|
||||
config.app_ver=Anwendungsversion
|
||||
config.app_url=Anwendungs-URL
|
||||
config.domain=Domain
|
||||
config.offline_mode=Offline-Modus
|
||||
config.disable_router_log=Router-Log deaktivieren
|
||||
config.brand_name=Markenname
|
||||
config.run_user=Ausführender Benutzer
|
||||
config.run_mode=Laufzeit-Modus
|
||||
config.repo_root_path=Repository-Verzeichnis
|
||||
config.static_file_root_path=Verzeichnis für statische Dateien
|
||||
config.log_file_root_path=Log-Verzeichnis
|
||||
config.script_type=Skript-Typ
|
||||
config.reverse_auth_user=Nutzer bei Reverse-Authentifizierung
|
||||
config.server.external_url=Externe URL
|
||||
config.server.domain=Domäne
|
||||
config.server.protocol=Protokoll
|
||||
config.server.http_addr=HTTP-Adresse
|
||||
config.server.http_port=HTTP-Port
|
||||
config.server.cert_file=Zertifikatsdatei
|
||||
config.server.key_file=Schlüsseldatei
|
||||
config.server.tls_min_version=Minimale TLS-Version
|
||||
config.server.unix_socket_permission=Unix-Socket-Berechtigung
|
||||
config.server.local_root_url=Lokale Root-URL
|
||||
config.server.offline_mode=Offline-Modus
|
||||
config.server.disable_router_log=Router-Log deaktivieren
|
||||
config.server.enable_gzip=Gzip aktivieren
|
||||
config.server.app_data_path=Anwendungsdatenpfad
|
||||
config.server.load_assets_from_disk=Assets von Festplatte laden
|
||||
config.server.landing_url=Startseite
|
||||
|
||||
config.ssh_config=SSH Konfiguration
|
||||
config.ssh_enabled=Aktiviert
|
||||
config.ssh_start_builtin_server=Eingebauten Server starten
|
||||
config.ssh_domain=Domain
|
||||
config.ssh_port=Port
|
||||
config.ssh_listen_port=Listen Port
|
||||
config.ssh_root_path=Verzeichnis
|
||||
config.ssh_key_test_path=Schlüssel-Test-Pfad
|
||||
config.ssh_keygen_path=Keygen ('ssh-keygen') Pfad
|
||||
config.ssh_minimum_key_size_check=Prüfung der Mindestschlüssellänge
|
||||
config.ssh_minimum_key_sizes=Minimale Schlüssellängen
|
||||
config.ssh.enabled=Aktiviert
|
||||
config.ssh.domain=Exponierte Domain
|
||||
config.ssh.port=Exponierter Port
|
||||
config.ssh.root_path=Wurzelpfad
|
||||
config.ssh.keygen_path=Keygenpfad
|
||||
config.ssh.key_test_path=Schlüsseltestpfad
|
||||
config.ssh.minimum_key_size_check=Prüfung der Mindestschlüssellänge
|
||||
config.ssh.minimum_key_sizes=Mindestschlüssellängen
|
||||
config.ssh.rewrite_authorized_keys_at_start=Beim Start "authorized_keys" umschreiben
|
||||
config.ssh.start_builtin_server=Eingebauten Server starten
|
||||
config.ssh.listen_host=Listen-Host
|
||||
config.ssh.listen_port=Listen-Port
|
||||
config.ssh.server_ciphers=Serverchiffren
|
||||
config.ssh.server_macs=Server MACs
|
||||
config.ssh.server_algorithms=Server-Algorithmen
|
||||
|
||||
config.repo_config=Repository-Konfiguration
|
||||
config.repo.root_path=Wurzelpfad
|
||||
config.repo.script_type=Skript-Typ
|
||||
config.repo.ansi_chatset=ANSI-Zeichensatz
|
||||
config.repo.force_private=Privat erzwingen
|
||||
config.repo.max_creation_limit=Maximales Erstellungslimit
|
||||
config.repo.preferred_licenses=Bevorzugte Lizenzen
|
||||
config.repo.disable_http_git=HTTP-Git deaktivieren
|
||||
config.repo.enable_local_path_migration=Lokale Pfadmigration aktivieren
|
||||
config.repo.enable_raw_file_render_mode=Darstellen von Roh-Dateien aktivieren
|
||||
config.repo.commits_fetch_concurrency=Anzahl gleichzeitiger Commit-/Fetch-Prozesse
|
||||
config.repo.editor.line_wrap_extensions=Editor Erweiterungen für Zeilenumbrüche
|
||||
config.repo.editor.previewable_file_modes=Vorschau der Dateimodi des Editors
|
||||
config.repo.upload.enabled=Upload aktiviert
|
||||
config.repo.upload.temp_path=Temporärer Pfad für Uploads
|
||||
config.repo.upload.allowed_types=Erlaubte Upload-Typen
|
||||
config.repo.upload.file_max_size=Upload-Dateigrößenlimit
|
||||
config.repo.upload.max_files=Upload-Dateilimit
|
||||
|
||||
config.db_config=Datenbankkonfiguration
|
||||
config.db_type=Typ
|
||||
config.db_host=Host
|
||||
config.db_name=Name
|
||||
config.db_user=Benutzer
|
||||
config.db_ssl_mode=SSL-Modus
|
||||
config.db_ssl_mode_helper=(nur für "postgres")
|
||||
config.db_path=Verzeichnis
|
||||
config.db_path_helper=(für "sqlite3" und "tidb")
|
||||
config.db.type=Typ
|
||||
config.db.host=Host
|
||||
config.db.name=Name
|
||||
config.db.schema=Schema
|
||||
config.db.schema_helper=(nur für "postgres")
|
||||
config.db.user=Benutzer
|
||||
config.db.ssl_mode=SSL-Modus
|
||||
config.db.ssl_mode_helper=(nur für "postgres")
|
||||
config.db.path=Pfad
|
||||
config.db.path_helper=(nur für "sqlite3")
|
||||
config.db.max_open_conns=Maximale Anzahl offener Verbindungen
|
||||
config.db.max_idle_conns=Maximale Leerlaufverbindungen
|
||||
|
||||
config.service_config=Service-Konfiguration
|
||||
config.register_email_confirm=E-Mail-Bestätigung bei Registrierung
|
||||
config.disable_register=Registrierung deaktivieren
|
||||
config.show_registration_button=Schaltfläche Registrieren anzeigen
|
||||
config.require_sign_in_view=Ansehen erfordert Anmeldung
|
||||
config.mail_notify=E-Mail-Benachrichtigung
|
||||
config.disable_key_size_check=Prüfung der Mindestschlüssellänge deaktiveren
|
||||
config.enable_captcha=Captcha aktivieren
|
||||
config.active_code_lives=Aktivierungscode Lebensdauer
|
||||
config.reset_password_code_lives=Passwortcode Lebensdauer
|
||||
config.security_config=Sicherheitskonfiguration
|
||||
config.security.login_remember_days=Anzahl Tage zum Speichern des Logins
|
||||
config.security.cookie_remember_name=Cookie merken
|
||||
config.security.cookie_username=Benutzernamen-Cookie
|
||||
config.security.cookie_secure=Sicheres Cookie aktivieren
|
||||
config.security.reverse_proxy_auth_user=Reverse-Proxy-Authentifizierungs-Header
|
||||
config.security.enable_login_status_cookie=Login-Status-Cookie aktivieren
|
||||
config.security.login_status_cookie_name=Login-Status-Cookie
|
||||
config.security.local_network_allowlist=Zulassungsliste für lokale Netzwerke
|
||||
|
||||
config.webhook_config=Webhook-Konfiguration
|
||||
config.queue_length=Warteschlangenlänge
|
||||
config.deliver_timeout=Zeitlimit für Zustellung
|
||||
config.skip_tls_verify=TLS verifikation überspringen
|
||||
config.email_config=E-Mail-Konfiguration
|
||||
config.email.enabled=Aktiviert
|
||||
config.email.subject_prefix=Betreff-Präfix
|
||||
config.email.host=Host
|
||||
config.email.from=Von
|
||||
config.email.user=Benutzer
|
||||
config.email.disable_helo=HELO deaktivieren
|
||||
config.email.helo_hostname=HELO Hostname
|
||||
config.email.skip_verify=Zertifikatsüberprüfung überspringen
|
||||
config.email.use_certificate=Benutzerdefiniertes Zertifikat verwenden
|
||||
config.email.cert_file=Zertifikatsdatei
|
||||
config.email.key_file=Schlüsseldatei
|
||||
config.email.use_plain_text=Klartext verwenden
|
||||
config.email.add_plain_text_alt=Klartext-Alternative hinzufügen
|
||||
config.email.send_test_mail=Test-E-Mail senden
|
||||
config.email.test_mail_failed=Fehler beim Senden der Test-E-Mail an '%s': %v
|
||||
config.email.test_mail_sent=Test-E-Mail wurde an '%s ' gesendet.
|
||||
|
||||
config.mailer_config=Mailer-Konfiguration
|
||||
config.mailer_enabled=Aktiviert
|
||||
config.mailer_disable_helo=HELO Deaktivieren
|
||||
config.mailer_name=Name
|
||||
config.mailer_host=Host
|
||||
config.mailer_user=Benutzer
|
||||
config.send_test_mail=Test-E-Mail senden
|
||||
config.test_mail_failed=Das Senden der Test-E-Mail an '%s': %v ist fehlgeschlagen
|
||||
config.test_mail_sent=Test-E-Mail wurde an '%s' gesendet.
|
||||
config.auth_config=Authentifizierungskonfiguration
|
||||
config.auth_custom_logout_url=Custom logout URL
|
||||
config.auth.activate_code_lives=Aktivierungscode Lebensdauer
|
||||
config.auth.reset_password_code_lives=Gültigkeitsdauer Zurücksetzungs-Code
|
||||
config.auth.require_email_confirm=E-Mail-Bestätigung erforderlich
|
||||
config.auth.require_sign_in_view=Anmeldung erforderlich
|
||||
config.auth.disable_registration=Registrierung deaktivieren
|
||||
config.auth.enable_registration_captcha=Registrierungs-Captcha aktivieren
|
||||
config.auth.enable_reverse_proxy_authentication=Reverse-Proxy-Authentifizierung aktivieren
|
||||
config.auth.enable_reverse_proxy_auto_registration=Automatische Reverse-Proxy-Registrierung aktivieren
|
||||
config.auth.reverse_proxy_authentication_header=Reverse-Proxy-Authentifizierungs-Header
|
||||
|
||||
config.oauth_config=OAuth-Konfiguration
|
||||
config.oauth_enabled=Aktiviert
|
||||
|
||||
config.cache_config=Cache-Konfiguration
|
||||
config.cache_adapter=Cache-Adapter
|
||||
config.cache_interval=Cache-Intervall
|
||||
config.cache_conn=Cache-Anbindung
|
||||
config.user_config=Benutzerkonfiguration
|
||||
config.user.enable_email_notify=E-Mail-Benachrichtigung aktivieren
|
||||
|
||||
config.session_config=Session-Konfiguration
|
||||
config.session_provider=Session-Provider
|
||||
config.provider_config=Provider-Einstellungen
|
||||
config.cookie_name=Cookie-Name
|
||||
config.enable_set_cookie=Cookies verwenden
|
||||
config.gc_interval_time=GC-Intervall
|
||||
config.session_life_time=Session-Lebensdauer
|
||||
config.https_only=Nur HTTPS
|
||||
config.cookie_life_time=Cookie-Lebensdauer
|
||||
config.session.provider=Anbieter
|
||||
config.session.provider_config=Anbieter-Konfiguration
|
||||
config.session.cookie_name=Cookie
|
||||
config.session.https_only=Nur HTTPS
|
||||
config.session.gc_interval=GC-Intervall
|
||||
config.session.max_life_time=Maximale Lebensdauer
|
||||
config.session.csrf_cookie_name=CSRF-Cookie
|
||||
|
||||
config.cache_config=Cache-Konfiguration
|
||||
config.cache.adapter=Adapter
|
||||
config.cache.interval=GC-Intervall
|
||||
config.cache.host=Host
|
||||
|
||||
config.http_config=HTTP-Konfiguration
|
||||
config.http.access_control_allow_origin=Access-Control-Allow-Origin
|
||||
|
||||
config.attachment_config=Anhang-Konfiguration
|
||||
config.attachment.enabled=Aktiviert
|
||||
config.attachment.path=Pfad
|
||||
config.attachment.allowed_types=Erlaubte Typen
|
||||
config.attachment.max_size=Größenlimit
|
||||
config.attachment.max_files=Dateilimit
|
||||
|
||||
config.release_config=Release-Konfiguration
|
||||
config.release.attachment.enabled=Anhang aktiviert
|
||||
config.release.attachment.allowed_types=Erlaubte Anhang-Typen
|
||||
config.release.attachment.max_size=Größenlimit für Anhang
|
||||
config.release.attachment.max_files=Dateilimit für Anhang
|
||||
|
||||
config.picture_config=Konfiguration der Profilbilder
|
||||
config.picture_service=Bildservice
|
||||
config.disable_gravatar=Gravatar deaktivieren
|
||||
config.enable_federated_avatar=Föderierte Profilbilder einschalten
|
||||
config.picture.avatar_upload_path=Benutzer-Avatar Upload-Pfad
|
||||
config.picture.repo_avatar_upload_path=Repository-Avatar Upload-Pfad
|
||||
config.picture.gravatar_source=Gravatar-Quelle
|
||||
config.picture.disable_gravatar=Gravatar deaktivieren
|
||||
config.picture.enable_federated_avatar=Föderierte Avatare aktivieren
|
||||
|
||||
config.mirror_config=Mirror-Konfiguration
|
||||
config.mirror.default_interval=Standardintervall
|
||||
|
||||
config.webhook_config=Webhook-Konfiguration
|
||||
config.webhook.types=Typen
|
||||
config.webhook.deliver_timeout=Zeitlimit für Zustellung
|
||||
config.webhook.skip_tls_verify=TLS-Prüfung überspringen
|
||||
|
||||
config.git_config=Git Konfiguration
|
||||
config.git_disable_diff_highlight=Diff Syntaxhervorhebung ausschalten
|
||||
config.git_max_diff_lines=Max Diff Zeilen (in einer Datei)
|
||||
config.git_max_diff_line_characters=Max Diff Zeichen (in einer Zeile)
|
||||
config.git_max_diff_files=Max Diff Dateien (Anzeige)
|
||||
config.git_gc_args=GC-Argumente
|
||||
config.git_migrate_timeout=Zeitlimit für Migration
|
||||
config.git_mirror_timeout=Zeitlimit für Mirror-Aktualisierung
|
||||
config.git_clone_timeout=Zeitlimit für Clone
|
||||
config.git_pull_timeout=Zeitlimit für Pull
|
||||
config.git_gc_timeout=Zeitlimit für GC
|
||||
config.git.disable_diff_highlight=Diff-Syntaxhervorhebung ausschalten
|
||||
config.git.max_diff_lines=Zeilenlimit für Diff (für eine einzelne Datei)
|
||||
config.git.max_diff_line_characters=Zeichenlimit für Diff (für eine einzelne Datei)
|
||||
config.git.max_diff_files=Dateilimit für Diff (für einen einzelnen Diff)
|
||||
config.git.gc_args=GC-Argumente
|
||||
config.git.migrate_timeout=Zeitlimit für Migration
|
||||
config.git.mirror_timeout=Zeitlimit zum Spiegeln
|
||||
config.git.clone_timeout=Clone-Timeout
|
||||
config.git.pull_timeout=Pull-Timeout
|
||||
config.git.gc_timeout=GC-Timeout
|
||||
|
||||
config.lfs_config=LFS-Konfiguration
|
||||
config.lfs.storage=Speicher
|
||||
config.lfs.objects_path=Objektpfad
|
||||
|
||||
config.log_config=Konfiguration des Loggings
|
||||
config.log_mode=Log-Modus
|
||||
config.log_file_root_path=Log-Verzeichnis
|
||||
config.log_mode=Modus
|
||||
config.log_options=Optionen
|
||||
|
||||
monitor.cron=Cron-Tasks
|
||||
monitor.name=Name
|
||||
@@ -1159,17 +1385,24 @@ notices.delete_success=Systemmitteilungen wurden erfolgreich gelöscht.
|
||||
create_repo=hat das Repository <a href="%s">%s</a> erstellt
|
||||
rename_repo=hat das Repository von <code>%[1]s</code> zu <a href="%[2]s">%[3]s</a> umbenannt
|
||||
commit_repo=hat auf <a href="%[1]s/src/%[2]s">%[3]s</a> in <a href="%[1]s">%[4]s</a> gepusht
|
||||
compare_commits=Zeige Vergleich für diese %d Commits
|
||||
transfer_repo=hat Repository <code>%s</code> transferiert an <a href="%s">%s</a>
|
||||
create_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> geöffnet`
|
||||
close_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> geschlossen`
|
||||
reopen_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> wieder geöffnet`
|
||||
comment_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> kommentiert`
|
||||
create_pull_request=`hat Pull-Request <a href="%s/pulls/%s">%s#%[2]s</a> erstellt`
|
||||
close_pull_request=`hat Pull-Request <a href="%s/pulls/%s">%s#%[2]s</a> geschlossen`
|
||||
reopen_pull_request=`hat den Pull-Request <a href="%s/pulls/%s">%s#%[2]s</a> wieder geöffnet`
|
||||
comment_issue=`hat Issue <a href="%s/issues/%s">%s#%[2]s</a> kommentiert`
|
||||
merge_pull_request=`hat Pull-Request <a href="%s/pulls/%s">%s#%[2]s</a> zuammengeführt`
|
||||
transfer_repo=hat Repository <code>%s</code> transferiert an <a href="%s">%s</a>
|
||||
merge_pull_request=`hat Pull-Request <a href="%s/pulls/%s">%s#%[2]s</a> zusammengeführt`
|
||||
create_branch=hat neuen Branch <a href="%[1]s/src/%[2]s">%[3]s</a> in <a href="%[1]s">%[4]s</a> angelegt
|
||||
delete_branch=hat Branch <code>%[2]s</code> in <a href="%[1]s">%[3]s</a> gelöscht
|
||||
push_tag=hat Tag <a href="%s/src/%s">%[2]s</a> auf <a href="%[1]s">%[3]s</a> gepusht
|
||||
compare_commits=Zeige Vergleich für diese %d Commits
|
||||
delete_tag=hat Tag <code>%[2]s</code> in <a href="%[1]s">%[3]s</a> gelöscht
|
||||
fork_repo=hat das Repository nach <a href="%s">%s</a> geforkt
|
||||
mirror_sync_push=hat auf <a href="%[1]s/src/%[2]s">%[3]s</a> in <a href="%[1]s">%[4]s</a> gepusht
|
||||
mirror_sync_create=synced new reference <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a> from mirror
|
||||
mirror_sync_delete=synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror
|
||||
|
||||
[tool]
|
||||
ago=vor
|
||||
@@ -1191,6 +1424,7 @@ months=%[2]s %[1]d Monaten
|
||||
years=%[2]s %[1]d Jahren
|
||||
raw_seconds=Sekunden
|
||||
raw_minutes=Minuten
|
||||
raw_hours=Stunden
|
||||
|
||||
[dropzone]
|
||||
default_message=Zum Hochladen hier klicken oder Datei hier ablegen.
|
||||
|
||||
1511
conf/locale/locale_en-GB.ini
Normal file
1511
conf/locale/locale_en-GB.ini
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,6 @@ sign_out = Sign Out
|
||||
sign_up = Sign Up
|
||||
register = Register
|
||||
website = Website
|
||||
version = Version
|
||||
page = Page
|
||||
template = Template
|
||||
language = Language
|
||||
@@ -44,23 +43,27 @@ issues = Issues
|
||||
|
||||
cancel = Cancel
|
||||
|
||||
[status]
|
||||
page_not_found = Page Not Found
|
||||
internal_server_error = Internal Server Error
|
||||
|
||||
[install]
|
||||
install = Installation
|
||||
title = Install Steps For First-time Run
|
||||
docker_helper = If you're running Gogs inside Docker, please read <a target="_blank" href="%s">Guidelines</a> carefully before you change anything in this page!
|
||||
requite_db_desc = Gogs requires MySQL, PostgreSQL, SQLite3 or TiDB.
|
||||
requite_db_desc = Gogs requires MySQL, PostgreSQL, SQLite3 or TiDB (via MySQL protocol).
|
||||
db_title = Database Settings
|
||||
db_type = Database Type
|
||||
host = Host
|
||||
user = User
|
||||
password = Password
|
||||
db_name = Database Name
|
||||
db_schema = Schema
|
||||
db_helper = Please use INNODB engine with utf8_general_ci charset for MySQL.
|
||||
ssl_mode = SSL Mode
|
||||
path = Path
|
||||
sqlite_helper = The file path of SQLite3 or TiDB database. <br>Please use absolute path when you start as service.
|
||||
err_empty_db_path = SQLite3 or TiDB database path cannot be empty.
|
||||
err_invalid_tidb_name = TiDB database name does not allow characters "." and "-".
|
||||
sqlite_helper = The file path of SQLite3 database. <br>Please use absolute path when you start as service.
|
||||
err_empty_db_path = SQLite3 database path cannot be empty.
|
||||
no_admin_and_disable_registration = You cannot disable registration without creating an admin account.
|
||||
err_empty_admin_password = Admin password cannot be empty.
|
||||
|
||||
@@ -75,12 +78,17 @@ domain = Domain
|
||||
domain_helper = This affects SSH clone URLs.
|
||||
ssh_port = SSH Port
|
||||
ssh_port_helper = Port number which your SSH server is using, leave it empty to disable SSH feature.
|
||||
use_builtin_ssh_server = Use Builtin SSH Server
|
||||
use_builtin_ssh_server_popup = Start builtin SSH server for Git operations to distinguish from system SSH daemon.
|
||||
http_port = HTTP Port
|
||||
http_port_helper = Port number which application will listen on.
|
||||
app_url = Application URL
|
||||
app_url_helper = This affects HTTP/HTTPS clone URL and somewhere in email.
|
||||
log_root_path = Log Path
|
||||
log_root_path_helper = Directory to write log files to.
|
||||
enable_console_mode = Enable Console Mode
|
||||
enable_console_mode_popup = In addition to file mode, also print logs to console.
|
||||
default_branch = Default Branch
|
||||
|
||||
optional_title = Optional Settings
|
||||
email_title = Email Service Settings
|
||||
@@ -104,19 +112,21 @@ enable_captcha = Enable Captcha
|
||||
enable_captcha_popup = Require validate captcha for user self-registration.
|
||||
require_sign_in_view = Enable Require Sign In to View Pages
|
||||
require_sign_in_view_popup = Only signed in users can view pages, visitors will only be able to see sign in/up pages.
|
||||
admin_setting_desc = You do not have to create an admin account right now, user whoever ID=1 will gain admin access automatically.
|
||||
admin_setting_desc = You don't need to create an admin account right now. The first user in the users table will be automatically granted admin access.
|
||||
admin_title = Admin Account Settings
|
||||
admin_name = Username
|
||||
admin_password = Password
|
||||
confirm_password = Confirm Password
|
||||
admin_email = Admin Email
|
||||
install_gogs = Install Gogs
|
||||
test_git_failed = Fail to test 'git' command: %v
|
||||
sqlite3_not_available = Your release version does not support SQLite3, please download the official binary version from %s, NOT the gobuild version.
|
||||
test_git_failed = Failed to test 'git' command: %v
|
||||
invalid_db_setting = Database setting is not correct: %v
|
||||
invalid_repo_path = Repository root path is invalid: %v
|
||||
run_user_not_match = Run user isn't the current user: %s -> %s
|
||||
save_config_failed = Fail to save configuration: %v
|
||||
smtp_host_missing_port = SMTP Host port missing from address.
|
||||
invalid_smtp_from = SMTP From field is invalid: %v
|
||||
save_config_failed = Failed to save configuration: %v
|
||||
init_failed = Failed to initialize application: %v
|
||||
invalid_admin_setting = Admin account setting is invalid: %v
|
||||
install_success = Welcome! We're glad that you chose Gogs, have fun and take care.
|
||||
invalid_log_root_path = Log root path is invalid: %v
|
||||
@@ -137,6 +147,7 @@ issues.in_your_repos = In your repositories
|
||||
[explore]
|
||||
repos = Repositories
|
||||
users = Users
|
||||
organizations = Organizations
|
||||
search = Search
|
||||
|
||||
[auth]
|
||||
@@ -144,7 +155,9 @@ create_new_account = Create New Account
|
||||
register_hepler_msg = Already have an account? Sign in now!
|
||||
social_register_hepler_msg = Already have an account? Bind now!
|
||||
disable_register_prompt = Sorry, registration has been disabled. Please contact the site administrator.
|
||||
disable_register_mail = Sorry, Register Mail Confirmation has been disabled.
|
||||
disable_register_mail = Sorry, email services are disabled. Please contact the site administrator.
|
||||
auth_source = Authentication Source
|
||||
local = Local
|
||||
remember_me = Remember Me
|
||||
forgot_password= Forgot Password
|
||||
forget_password = Forgot password?
|
||||
@@ -152,18 +165,25 @@ sign_up_now = Need an account? Sign up now.
|
||||
confirmation_mail_sent_prompt = A new confirmation email has been sent to <b>%s</b>, please check your inbox within the next %d hours to complete the registration process.
|
||||
active_your_account = Activate Your Account
|
||||
prohibit_login = Login Prohibited
|
||||
prohibit_login_desc = Your account is prohibited to login, please contact site admin.
|
||||
prohibit_login_desc = Your account is prohibited from logging in. Please contact the site admin.
|
||||
resent_limit_prompt = Sorry, you already requested an activation email recently. Please wait 3 minutes then try again.
|
||||
has_unconfirmed_mail = Hi %s, you have an unconfirmed email address (<b>%s</b>). If you haven't received a confirmation email or need to resend a new one, please click on the button below.
|
||||
has_unconfirmed_mail = Hi %s, you have an unconfirmed email address (<b>%s</b>). If you haven't received a confirmation email or need to receive a new one, please click the button below.
|
||||
resend_mail = Click here to resend your activation email
|
||||
email_not_associate = This email address is not associated with any account.
|
||||
send_reset_mail = Click here to (re)send your password reset email
|
||||
reset_password = Reset Your Password
|
||||
invalid_code = Sorry, your confirmation code has expired or not valid.
|
||||
reset_password_helper = Click here to reset your password
|
||||
password_too_short = Password length cannot be less then 6.
|
||||
password_too_short = Password length must be at least 6 characters.
|
||||
non_local_account = Non-local accounts cannot change passwords through Gogs.
|
||||
|
||||
login_two_factor = Two-factor Authentication
|
||||
login_two_factor_passcode = Authentication Passcode
|
||||
login_two_factor_enter_recovery_code = Enter a two-factor recovery code
|
||||
login_two_factor_recovery = Two-factor Recovery
|
||||
login_two_factor_recovery_code = Recovery Code
|
||||
login_two_factor_enter_passcode = Enter a two-factor passcode
|
||||
login_two_factor_invalid_recovery_code = Recovery code already used or invalid.
|
||||
|
||||
[mail]
|
||||
activate_account = Please activate your account
|
||||
activate_email = Verify your email address
|
||||
@@ -197,9 +217,10 @@ TreeName = File path
|
||||
Content = Content
|
||||
|
||||
require_error = ` cannot be empty.`
|
||||
alpha_dash_error = ` must be valid alpha or numeric or dash(-_) characters.`
|
||||
alpha_dash_dot_error = ` must be valid alpha or numeric or dash(-_) or dot characters.`
|
||||
size_error = ` must be size %s.`
|
||||
alpha_dash_error = ` must be alphanumeric or dash(-_) characters.`
|
||||
alpha_dash_dot_error = ` must be alphanumeric or dash(-_) or dot characters.`
|
||||
alpha_dash_dot_slash_error = ` must be alphanumeric, dash (-_), dot or slash characters.`
|
||||
size_error = ` size must be %s.`
|
||||
min_size_error = ` must contain at least %s characters.`
|
||||
max_size_error = ` must contain at most %s characters.`
|
||||
email_error = ` is not a valid email address.`
|
||||
@@ -215,14 +236,15 @@ org_name_been_taken = Organization name has already been taken.
|
||||
team_name_been_taken = Team name has already been taken.
|
||||
email_been_used = Email address has already been used.
|
||||
username_password_incorrect = Username or password is not correct.
|
||||
auth_source_mismatch = The authentication source selected is not associated with the user.
|
||||
enterred_invalid_repo_name = Please make sure that the repository name you entered is correct.
|
||||
enterred_invalid_owner_name = Please make sure that the owner name you entered is correct.
|
||||
enterred_invalid_password = Please make sure the that password you entered is correct.
|
||||
user_not_exist = Given user does not exist.
|
||||
last_org_owner = Removing the last user from a owner team isn't allowed, as there must always be at least one owner in any given organization.
|
||||
last_org_owner = Removing the last remaining user from an owner team is not allowed, as an organization must always have at least one owner.
|
||||
|
||||
invalid_ssh_key = Sorry, we're not able to verify your SSH key: %s
|
||||
unable_verify_ssh_key = Gogs cannot verify your SSH key, but we assume that it is valid, please double-check it.
|
||||
invalid_ssh_key = Sorry, verification of your SSH key failed: %s
|
||||
unable_verify_ssh_key = Gogs cannot verify your SSH key, but it's assumed to be valid. Please double-check it.
|
||||
auth_failed = Authentication failed: %v
|
||||
|
||||
still_own_repo = Your account still has ownership over at least one repository, you have to delete or transfer them first.
|
||||
@@ -242,19 +264,18 @@ following = Following
|
||||
follow = Follow
|
||||
unfollow = Unfollow
|
||||
|
||||
form.name_reserved = Username '%s' is reserved.
|
||||
form.name_pattern_not_allowed = Username pattern '%s' is not allowed.
|
||||
form.name_not_allowed = User name or pattern %q is not allowed.
|
||||
|
||||
[settings]
|
||||
profile = Profile
|
||||
password = Password
|
||||
avatar = Avatar
|
||||
ssh_keys = SSH Keys
|
||||
social = Social Accounts
|
||||
applications = Applications
|
||||
security = Security
|
||||
repos = Repositories
|
||||
orgs = Organizations
|
||||
applications = Applications
|
||||
delete = Delete Account
|
||||
uid = Uid
|
||||
|
||||
public_profile = Public Profile
|
||||
profile_desc = Your email address is public and will be used for any account related notifications, and any web based operations made via the site.
|
||||
@@ -283,7 +304,7 @@ old_password = Current Password
|
||||
new_password = New Password
|
||||
retype_new_password = Retype New Password
|
||||
password_incorrect = Current password is not correct.
|
||||
change_password_success = Your password was successfully changed. You can now sign using this new password.
|
||||
change_password_success = Your password was successfully changed and can now be used for logging in.
|
||||
password_change_disabled = Non-local type users are not allowed to change their password.
|
||||
|
||||
emails = Email Addresses
|
||||
@@ -295,8 +316,9 @@ delete_email = Delete
|
||||
email_deletion = Email Deletion
|
||||
email_deletion_desc = Deleting this email address will remove related information from your account. Do you want to continue?
|
||||
email_deletion_success = Email has been deleted successfully!
|
||||
email_deletion_primary = Cannot delete primary email address.
|
||||
add_new_email = Add new email address
|
||||
add_email = Add email
|
||||
add_email = Add Email
|
||||
add_email_confirmation_sent = A new confirmation email has been sent to '%s', please check your inbox within the next %d hours to complete the confirmation process.
|
||||
add_email_success = Your new email address was successfully added.
|
||||
|
||||
@@ -320,14 +342,36 @@ no_activity = No recent activity
|
||||
key_state_desc = This key is used in last 7 days
|
||||
token_state_desc = This token is used in last 7 days
|
||||
|
||||
manage_social = Manage Associated Social Accounts
|
||||
social_desc = This is a list of associated social accounts. Remove any binding that you do not recognize.
|
||||
unbind = Unbind
|
||||
unbind_success = Social account has been unbound.
|
||||
two_factor = Two-factor Authentication
|
||||
two_factor_status = Status:
|
||||
two_factor_on = On
|
||||
two_factor_off = Off
|
||||
two_factor_enable = Enable
|
||||
two_factor_disable = Disable
|
||||
two_factor_view_recovery_codes = View and save <a href="%s%s">your recovery codes</a> in a safe place. You can use them as passcode if you lose access to your authentication application.
|
||||
two_factor_http = For HTTP/HTTPS operations, you are no longer able to use plain username and password. Please create and use <a href="%[1]s%[2]s">Personal Access Token</a> as your credential, e.g. <code>%[3]s</code>.
|
||||
two_factor_enable_title = Enable Two-factor Authentication
|
||||
two_factor_scan_qr = Please use your authentication application to scan the image:
|
||||
two_factor_or_enter_secret = Or enter the secret:
|
||||
two_factor_then_enter_passcode = Then enter passcode:
|
||||
two_factor_verify = Verify
|
||||
two_factor_invalid_passcode = The passcode you entered is not valid, please try again!
|
||||
two_factor_reused_passcode = The passcode you entered has already been used, please try another one!
|
||||
two_factor_enable_error = Enable Two-factor authentication failed: %v
|
||||
two_factor_enable_success = Two-factor authentication has enabled for your account successfully!
|
||||
two_factor_recovery_codes_title = Two-factor Authentication Recovery Codes
|
||||
two_factor_recovery_codes_desc = Recovery codes are used when you temporarily lose access to your authentication application. Each recovery code can only be used once, <b>please keep these codes in a safe place</b>.
|
||||
two_factor_regenerate_recovery_codes = Regenerate Recovery Codes
|
||||
two_factor_regenerate_recovery_codes_error = Regenerate recovery codes failed: %v
|
||||
two_factor_regenerate_recovery_codes_success = New recovery codes has been generated successfully!
|
||||
two_factor_disable_title = Disable Two-factor Authentication
|
||||
two_factor_disable_desc = Your account security level will decrease after disabled two-factor authentication. Do you want to continue?
|
||||
two_factor_disable_success = Two-factor authentication has disabled successfully!
|
||||
|
||||
manage_access_token = Manage Personal Access Tokens
|
||||
generate_new_token = Generate New Token
|
||||
tokens_desc = Tokens you have generated that can be used to access the Gogs APIs.
|
||||
access_token_tips=The personal access token may be used as either username or password. It is recommended to use the "x-access-token" as the username and the personal access token as the password for Git applications.
|
||||
new_token_desc = Each token will have full access to your account.
|
||||
token_name = Token Name
|
||||
generate_token = Generate Token
|
||||
@@ -336,6 +380,16 @@ delete_token = Delete
|
||||
access_token_deletion = Personal Access Token Deletion
|
||||
access_token_deletion_desc = Delete this personal access token will remove all related accesses of application. Do you want to continue?
|
||||
delete_token_success = Personal access token has been removed successfully! Don't forget to update your application as well.
|
||||
token_name_exists = Token with same name already exists.
|
||||
|
||||
orgs.none = You are not a member of any organizations.
|
||||
orgs.leave_title = Leave organization
|
||||
orgs.leave_desc = You will lose access to all repositories and teams after you left the organization. Do you want to continue?
|
||||
|
||||
repos.leave = Leave
|
||||
repos.leave_title = Leave repository
|
||||
repos.leave_desc = You will lose access to the repository after you left. Do you want to continue?
|
||||
repos.leave_success = You have left repository '%s' successfully!
|
||||
|
||||
delete_account = Delete Your Account
|
||||
delete_prompt = The operation will delete your account permanently, and <strong>CANNOT</strong> be undone!
|
||||
@@ -348,7 +402,9 @@ owner = Owner
|
||||
repo_name = Repository Name
|
||||
repo_name_helper = A good repository name is usually composed of short, memorable and unique keywords.
|
||||
visibility = Visibility
|
||||
unlisted = Unlisted
|
||||
visiblity_helper = This repository is <span class="ui red text">Private</span>
|
||||
unlisted_helper = This repository is <span class="ui red text">Unlisted</span>
|
||||
visiblity_helper_forced = Site admin has forced all new repositories to be <span class="ui red text">Private</span>
|
||||
visiblity_fork_helper = (Change of this value will affect all forks)
|
||||
clone_helper = Need help cloning? Visit <a target="_blank" href="%s">Help</a>!
|
||||
@@ -374,24 +430,26 @@ mirror_last_synced = Last Synced
|
||||
watchers = Watchers
|
||||
stargazers = Stargazers
|
||||
forks = Forks
|
||||
repo_description_helper = Description of repository. Maximum 512 characters length.
|
||||
repo_description_length = Available characters
|
||||
|
||||
form.reach_limit_of_creation = The owner has reached maximum creation limit of %d repositories.
|
||||
form.name_reserved = Repository name '%s' is reserved.
|
||||
form.name_pattern_not_allowed = Repository name pattern '%s' is not allowed.
|
||||
form.name_not_allowed = Repository name or pattern %q is not allowed.
|
||||
|
||||
need_auth = Need Authorization
|
||||
migrate_type = Migration Type
|
||||
migrate_type_helper = This repository will be a <span class="text blue">mirror</span>
|
||||
migrate_repo = Migrate Repository
|
||||
migrate.clone_address = Clone Address
|
||||
migrate.clone_address_desc = This can be a HTTP/HTTPS/GIT URL or local server path.
|
||||
migrate.clone_address_desc = This can be a HTTP/HTTPS/GIT URL.
|
||||
migrate.clone_address_desc_import_local = You're also allowed to migrate a repository by local server path.
|
||||
migrate.permission_denied = You are not allowed to import local repositories.
|
||||
migrate.invalid_local_path = Invalid local path, it does not exist or not a directory.
|
||||
migrate.clone_address_resolved_to_blocked_local_address = Clone address resolved to a local network address that is implicitly blocked.
|
||||
migrate.failed = Migration failed: %v
|
||||
|
||||
mirror_from = mirror of
|
||||
forked_from = forked from
|
||||
fork_from_self = You cannot fork a repository you already own!
|
||||
copy_link = Copy
|
||||
copy_link_success = Copied!
|
||||
copy_link_error = Press ⌘-C or Ctrl-C to copy
|
||||
@@ -407,9 +465,9 @@ quick_guide = Quick Guide
|
||||
clone_this_repo = Clone this repository
|
||||
create_new_repo_command = Create a new repository on the command line
|
||||
push_exist_repo = Push an existing repository from the command line
|
||||
repo_is_empty = This repository is empty, please come back later!
|
||||
bare_message = This repository does not have any content yet.
|
||||
|
||||
code = Code
|
||||
files = Files
|
||||
branch = Branch
|
||||
tree = Tree
|
||||
filter_branch_and_tag = Filter branch or tag
|
||||
@@ -420,12 +478,23 @@ pulls = Pull Requests
|
||||
labels = Labels
|
||||
milestones = Milestones
|
||||
commits = Commits
|
||||
git_branches = Branches
|
||||
releases = Releases
|
||||
file_raw = Raw
|
||||
file_history = History
|
||||
file_view_raw = View Raw
|
||||
file_permalink = Permalink
|
||||
file_too_large = This file is too large to be shown
|
||||
video_not_supported_in_browser = Your browser doesn't support HTML5 video tag.
|
||||
|
||||
branches.overview = Overview
|
||||
branches.active_branches = Active Branches
|
||||
branches.stale_branches = Stale Branches
|
||||
branches.all = All Branches
|
||||
branches.updated_by = Updated %[1]s by %[2]s
|
||||
branches.change_default_branch = Change Default Branch
|
||||
branches.default_deletion_not_allowed = Cannot delete the default branch.
|
||||
branches.protected_deletion_not_allowed = Cannot delete a protected branch.
|
||||
|
||||
editor.new_file = New file
|
||||
editor.upload_file = Upload file
|
||||
@@ -455,16 +524,19 @@ editor.cancel = Cancel
|
||||
editor.filename_cannot_be_empty = Filename cannot be empty.
|
||||
editor.branch_already_exists = Branch '%s' already exists in this repository.
|
||||
editor.directory_is_a_file = Entry '%s' in the parent path is a file not a directory in this repository.
|
||||
editor.file_is_a_symlink = The file '%s' is a symlink that cannot be modified from the web editor.
|
||||
editor.filename_is_a_directory = The filename '%s' is an existing directory in this repository.
|
||||
editor.file_editing_no_longer_exists = The file '%s' you are editing no longer exists in the repository.
|
||||
editor.file_changed_while_editing = File content has been changed since you started editing. <a target="_blank" href="%s">Click here</a> to see what have been changed or <strong>press commit again</strong> to overwrite those changes.
|
||||
editor.file_already_exists = A file with name '%s' already exists in this repository.
|
||||
editor.no_changes_to_show = There are no changes to show.
|
||||
editor.fail_to_update_file = Failed to update/create file '%s' with error: %v
|
||||
editor.fail_to_delete_file = Failed to delete file '%s' with error: %v
|
||||
editor.add_subdir = Add subdirectory...
|
||||
editor.unable_to_upload_files = Failed to upload files to '%s' with error: %v
|
||||
editor.upload_files_to_dir = Upload files to '%s'
|
||||
|
||||
commits.commit_history = Commit History
|
||||
commits.commits = Commits
|
||||
commits.search = Search commits
|
||||
commits.find = Find
|
||||
@@ -491,7 +563,7 @@ issues.new_label = New Label
|
||||
issues.new_label_placeholder = Label name...
|
||||
issues.create_label = Create Label
|
||||
issues.label_templates.title = Load a predefined set of labels
|
||||
issues.label_templates.info = There aren’t any labels yet. You can click on the "New Label" button above to create one or use a predefined set below.
|
||||
issues.label_templates.info = There aren't any labels yet. You can click on the "New Label" button above to create one or use a predefined set below.
|
||||
issues.label_templates.helper = Select a label set
|
||||
issues.label_templates.use = Use this label set
|
||||
issues.label_templates.fail_to_load_file = Failed to load label template file '%s': %v
|
||||
@@ -562,6 +634,7 @@ pulls.compare_compare = compare
|
||||
pulls.filter_branch = Filter branch
|
||||
pulls.no_results = No results found.
|
||||
pulls.nothing_to_compare = There is nothing to compare because base and head branches are even.
|
||||
pulls.nothing_merge_base = There is nothing to compare because two branches have completely different history.
|
||||
pulls.has_pull_request = `There is already a pull request between these two targets: <a href="%[1]s/pulls/%[3]d">%[2]s#%[3]d</a>`
|
||||
pulls.create = Create Pull Request
|
||||
pulls.title_desc = wants to merge %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code>
|
||||
@@ -577,8 +650,13 @@ pulls.is_checking = The conflict checking is still in progress, please refresh p
|
||||
pulls.can_auto_merge_desc = This pull request can be merged automatically.
|
||||
pulls.cannot_auto_merge_desc = This pull request can't be merged automatically because there are conflicts.
|
||||
pulls.cannot_auto_merge_helper = Please merge manually in order to resolve the conflicts.
|
||||
pulls.create_merge_commit = Create a merge commit
|
||||
pulls.rebase_before_merging = Rebase before merging
|
||||
pulls.commit_description = Commit Description
|
||||
pulls.merge_pull_request = Merge Pull Request
|
||||
pulls.open_unmerged_pull_exists = `You can't perform reopen operation because there is already an open pull request (#%d) from same repository with same merge information and is waiting for merging.`
|
||||
pulls.delete_branch = Delete Branch
|
||||
pulls.delete_branch_has_new_commits = Branch cannot be deleted because it has new commits after mergence.
|
||||
|
||||
milestones.new = New Milestone
|
||||
milestones.open_tab = %d Open
|
||||
@@ -629,6 +707,29 @@ settings.collaboration.admin = Admin
|
||||
settings.collaboration.write = Write
|
||||
settings.collaboration.read = Read
|
||||
settings.collaboration.undefined = Undefined
|
||||
settings.branches = Branches
|
||||
settings.branches_bare = You cannot manage branches for bare repository. Please push some content first.
|
||||
settings.default_branch = Default Branch
|
||||
settings.default_branch_desc = The default branch is considered the "base" branch for code commits, pull requests and online editing.
|
||||
settings.update = Update
|
||||
settings.update_default_branch_unsupported = Change default branch is not supported by the Git version on server.
|
||||
settings.update_default_branch_success = Default branch of this repository has been updated successfully!
|
||||
settings.protected_branches = Protected Branches
|
||||
settings.protected_branches_desc = Protect branches from force pushing, accidental deletion and whitelist code committers.
|
||||
settings.choose_a_branch = Choose a branch...
|
||||
settings.branch_protection = Branch Protection
|
||||
settings.branch_protection_desc = Please choose protect options for branch <b>%s</b>.
|
||||
settings.protect_this_branch = Protect this branch
|
||||
settings.protect_this_branch_desc = Disable force pushes and prevent from deletion.
|
||||
settings.protect_require_pull_request = Require pull request instead direct pushing
|
||||
settings.protect_require_pull_request_desc = Enable this option to disable direct pushing to this branch. Commits have to be pushed to another non-protected branch and merged to this branch through pull request.
|
||||
settings.protect_whitelist_committers = Whitelist who can push to this branch
|
||||
settings.protect_whitelist_committers_desc = Add people or teams to whitelist of direct push to this branch. Users in whitelist will bypass require pull request check.
|
||||
settings.protect_whitelist_users = Users who can push to this branch
|
||||
settings.protect_whitelist_search_users = Search users
|
||||
settings.protect_whitelist_teams = Teams for which members of them can push to this branch
|
||||
settings.protect_whitelist_search_teams = Search teams
|
||||
settings.update_protect_branch_success = Protect options for this branch has been updated successfully!
|
||||
settings.hooks = Webhooks
|
||||
settings.githooks = Git Hooks
|
||||
settings.basic_settings = Basic Settings
|
||||
@@ -641,19 +742,26 @@ settings.change_reponame_prompt = This change will affect how links relate to th
|
||||
settings.advanced_settings = Advanced Settings
|
||||
settings.wiki_desc = Enable wiki system
|
||||
settings.use_internal_wiki = Use builtin wiki
|
||||
settings.allow_public_wiki_desc = Allow public access to wiki when repository is private
|
||||
settings.use_external_wiki = Use external wiki
|
||||
settings.external_wiki_url = External Wiki URL
|
||||
settings.external_wiki_url_desc = Visitors will be redirected to URL when they click on the tab.
|
||||
settings.issues_desc = Enable issue tracker
|
||||
settings.use_internal_issue_tracker = Use builtin lightweight issue tracker
|
||||
settings.allow_public_issues_desc = Allow public access to issues when repository is private
|
||||
settings.use_external_issue_tracker = Use external issue tracker
|
||||
settings.external_tracker_url = External Issue Tracker URL
|
||||
settings.external_tracker_url_desc = Visitors will be redirected to URL when they click on the tab.
|
||||
settings.tracker_url_format = External Issue Tracker URL Format
|
||||
settings.tracker_issue_style = External Issue Tracker Naming Style:
|
||||
settings.tracker_issue_style.numeric = Numeric
|
||||
settings.tracker_issue_style.alphanumeric = Alphanumeric
|
||||
settings.tracker_url_format_desc = You can use placeholder <code>{user} {repo} {index}</code> for user name, repository name and issue index.
|
||||
settings.pulls_desc = Enable pull requests to accept public contributions
|
||||
settings.pulls_desc = Enable pull requests to accept contributions between repositories and branches
|
||||
settings.pulls.ignore_whitespace = Ignore changes in whitespace
|
||||
settings.pulls.allow_rebase_merge = Allow use rebase to merge commits
|
||||
settings.danger_zone = Danger Zone
|
||||
settings.cannot_fork_to_same_owner = You cannot fork a repository to its original owner.
|
||||
settings.new_owner_has_same_repo = The new owner already has a repository with same name. Please choose another name.
|
||||
settings.convert = Convert To Regular Repository
|
||||
settings.convert_desc = You can convert this mirror to a regular repository. This cannot be reversed.
|
||||
@@ -672,7 +780,7 @@ settings.wiki_deletion_success = Repository wiki data have been erased successfu
|
||||
settings.delete = Delete This Repository
|
||||
settings.delete_desc = Once you delete a repository, there is no going back. Please be certain.
|
||||
settings.delete_notices_1 = - This operation <strong>CANNOT</strong> be undone.
|
||||
settings.delete_notices_2 = - This operation will permanently delete the everything of this repository, including Git data, issues, comments and accesses of collaborators.
|
||||
settings.delete_notices_2 = - This operation will permanently delete everything in this repository, including Git data, issues, comments and collaborator access.
|
||||
settings.delete_notices_fork_1 = - All forks will become independent after deletion.
|
||||
settings.deletion_success = Repository has been deleted successfully!
|
||||
settings.update_settings_success = Repository options has been updated successfully.
|
||||
@@ -688,42 +796,58 @@ settings.collaborator_deletion_desc = This user will no longer have collaboratio
|
||||
settings.remove_collaborator_success = Collaborator has been removed.
|
||||
settings.search_user_placeholder = Search user...
|
||||
settings.org_not_allowed_to_be_collaborator = Organization is not allowed to be added as a collaborator.
|
||||
settings.user_is_org_member = User is organization member who cannot be added as a collaborator.
|
||||
settings.add_webhook = Add Webhook
|
||||
settings.hooks_desc = Webhooks are much like basic HTTP POST event triggers. Whenever something occurs in Gogs, we will handle the notification to the target host you specify. Learn more in this <a target="_blank" href="%s">Webhooks Guide</a>.
|
||||
settings.hooks_desc = Webhooks are much like basic HTTP POST event triggers. Whenever something occurs in Gogs, we will handle the notification to the target host you specify.
|
||||
settings.webhooks.add_new = Add a new webhook:
|
||||
settings.webhooks.choose_a_type = Choose a type...
|
||||
settings.add_webhook = Add webhook
|
||||
settings.webhook_deletion = Delete Webhook
|
||||
settings.webhook_deletion_desc = Delete this webhook will remove its information and all delivery history. Do you want to continue?
|
||||
settings.webhook_deletion_success = Webhook has been deleted successfully!
|
||||
settings.webhook.test_delivery = Test Delivery
|
||||
settings.webhook.test_delivery_desc = Send a fake push event delivery to test your webhook settings
|
||||
settings.webhook.test_delivery_success = Test webhook has been added to delivery queue. It may take few seconds before it shows up in the delivery history.
|
||||
settings.webhook.redelivery = Redelivery
|
||||
settings.webhook.redelivery_success = Hook task '%s' has been readded to delivery queue. It may take few seconds to update delivery status in history.
|
||||
settings.webhook.request = Request
|
||||
settings.webhook.response = Response
|
||||
settings.webhook.headers = Headers
|
||||
settings.webhook.payload = Payload
|
||||
settings.webhook.body = Body
|
||||
settings.webhook.err_cannot_parse_payload_url = Cannot parse payload URL: %v
|
||||
settings.webhook.url_resolved_to_blocked_local_address = Payload URL resolved to a local network address that is implicitly blocked.
|
||||
settings.githooks_desc = Git Hooks are powered by Git itself, you can edit files of supported hooks in the list below to perform custom operations.
|
||||
settings.githook_edit_desc = If the hook is inactive, sample content will be presented. Leaving content to an empty value will disable this hook.
|
||||
settings.githook_name = Hook Name
|
||||
settings.githook_content = Hook Content
|
||||
settings.update_githook = Update Hook
|
||||
settings.add_webhook_desc = Gogs will send a <code>POST</code> request to the URL you specify, along with regarding the event that occured. You can also specify what kind of data format you'd like to get upon triggering the hook (JSON, x-www-form-urlencoded, XML, etc). More information can be found in our <a target="_blank" href="%s">Webhooks Guide</a>.
|
||||
settings.add_webhook_desc = Gogs will send a <code>POST</code> request to the URL you specify, along with details regarding the event that occurred. You can also specify what kind of data format you'd like to get upon triggering the hook (JSON, x-www-form-urlencoded, XML, etc). More information can be found in our <a target="_blank" href="%s">Webhooks Guide</a>.
|
||||
settings.payload_url = Payload URL
|
||||
settings.content_type = Content Type
|
||||
settings.secret = Secret
|
||||
settings.secret_desc = Secret will be sent as SHA256 HMAC hex digest of payload via <code>X-Gogs-Signature</code> header.
|
||||
settings.slack_username = Username
|
||||
settings.slack_icon_url = Icon URL
|
||||
settings.slack_color = Color
|
||||
settings.event_desc = When should this webhook be triggered?
|
||||
settings.event_push_only = Just the <code>push</code> event.
|
||||
settings.event_send_everything = I need <strong>everything</strong>.
|
||||
settings.event_choose = Let me choose what I need.
|
||||
settings.event_push_only = Just the <code>push</code> event
|
||||
settings.event_send_everything = I need <strong>everything</strong>
|
||||
settings.event_choose = Let me choose what I need
|
||||
settings.event_create = Create
|
||||
settings.event_create_desc = Branch, or tag created
|
||||
settings.event_pull_request = Pull Request
|
||||
settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
|
||||
settings.event_create_desc = Branch or tag created
|
||||
settings.event_delete = Delete
|
||||
settings.event_delete_desc = Branch or tag deleted
|
||||
settings.event_fork = Fork
|
||||
settings.event_fork_desc = Repository forked
|
||||
settings.event_push = Push
|
||||
settings.event_push_desc = Git push to a repository
|
||||
settings.event_issues = Issues
|
||||
settings.event_issues_desc = Issue opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, or demilestoned.
|
||||
settings.event_pull_request = Pull Request
|
||||
settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, milestoned, demilestoned, or synchronized.
|
||||
settings.event_issue_comment = Issue Comment
|
||||
settings.event_issue_comment_desc = Issue comment created, edited, or deleted.
|
||||
settings.event_release = Release
|
||||
settings.event_release_desc = Release published in a repository.
|
||||
settings.active = Active
|
||||
settings.active_helper = Details regarding the event which triggered the hook will be delivered as well.
|
||||
settings.add_hook_success = New webhook has been added.
|
||||
@@ -733,10 +857,13 @@ settings.delete_webhook = Delete Webhook
|
||||
settings.recent_deliveries = Recent Deliveries
|
||||
settings.hook_type = Hook Type
|
||||
settings.add_slack_hook_desc = Add <a href="%s">Slack</a> integration to your repository.
|
||||
settings.add_discord_hook_desc = Add <a href="%s">Discord</a> integration to your repository.
|
||||
settings.add_dingtalk_hook_desc = Add <a href="%s">Dingtalk</a> integration to your repository.
|
||||
settings.slack_token = Token
|
||||
settings.slack_domain = Domain
|
||||
settings.slack_channel = Channel
|
||||
settings.deploy_keys = Deploy Keys
|
||||
settings.deploy_keys_helper = <b>Common Gotcha!</b> If you're looking for adding personal public keys, please add them in your <a href="%s%s">account settings</a>.
|
||||
settings.add_deploy_key = Add Deploy Key
|
||||
settings.deploy_key_desc = Deploy keys have read-only access. They are not the same as personal account SSH keys.
|
||||
settings.no_deploy_keys = You haven't added any deploy keys.
|
||||
@@ -748,6 +875,8 @@ settings.add_key_success = New deploy key '%s' has been added successfully!
|
||||
settings.deploy_key_deletion = Delete Deploy Key
|
||||
settings.deploy_key_deletion_desc = Deleting this deploy key will remove all related accesses for this repository. Do you want to continue?
|
||||
settings.deploy_key_deletion_success = Deploy key has been deleted successfully!
|
||||
settings.description_desc = Description of repository. Maximum 512 characters length.
|
||||
settings.description_length = Available characters
|
||||
|
||||
diff.browse_source = Browse Source
|
||||
diff.parent = parent
|
||||
@@ -766,7 +895,6 @@ release.releases = Releases
|
||||
release.new_release = New Release
|
||||
release.draft = Draft
|
||||
release.prerelease = Pre-Release
|
||||
release.stable = Stable
|
||||
release.edit = edit
|
||||
release.ahead = <strong>%d</strong> commits to %s since this release
|
||||
release.source_code = Source Code
|
||||
@@ -813,8 +941,8 @@ team_name_helper = You'll use this name to mention this team in conversations.
|
||||
team_desc_helper = What is this team all about?
|
||||
team_permission_desc = What permission level should this team have?
|
||||
|
||||
form.name_reserved = Organization name '%s' is reserved.
|
||||
form.name_pattern_not_allowed = Organization name pattern '%s' is not allowed.
|
||||
form.name_not_allowed = Organization name or pattern %q is not allowed.
|
||||
form.team_name_not_allowed = Team name or pattern %q is not allowed.
|
||||
|
||||
settings = Settings
|
||||
settings.options = Options
|
||||
@@ -864,9 +992,9 @@ teams.add_team_member = Add Team Member
|
||||
teams.delete_team_title = Team Deletion
|
||||
teams.delete_team_desc = As this team will be deleted, members of this team may lose access to some repositories. Do you want to continue?
|
||||
teams.delete_team_success = Given team has been deleted successfully.
|
||||
teams.read_permission_desc = This team grants <strong>Read</strong> access: members can view and clone the team's repositories.
|
||||
teams.write_permission_desc = This team grants <strong>Write</strong> access: members can read from and push to the team's repositories.
|
||||
teams.admin_permission_desc = This team grants <strong>Admin</strong> access: members can read from, push to, and add collaborators to the team's repositories.
|
||||
teams.read_permission_desc = Membership in this team grants <strong>Read</strong> access: members can view and clone the team's repositories.
|
||||
teams.write_permission_desc = Membership in this team grants <strong>Write</strong> access: members can read from and push to the team's repositories.
|
||||
teams.admin_permission_desc = Membership in this team grants <strong>Admin</strong> access: members can read from, push to, and add collaborators to the team's repositories.
|
||||
teams.repositories = Team Repositories
|
||||
teams.search_repo_placeholder = Search repository...
|
||||
teams.add_team_repository = Add Team Repository
|
||||
@@ -886,12 +1014,19 @@ first_page = First
|
||||
last_page = Last
|
||||
total = Total: %d
|
||||
|
||||
dashboard.statistic = Statistic
|
||||
dashboard.build_info = Build Information
|
||||
dashboard.app_ver = Application version
|
||||
dashboard.git_version = Git version
|
||||
dashboard.go_version = Go version
|
||||
dashboard.build_time = Build time
|
||||
dashboard.build_commit = Build commit
|
||||
dashboard.statistic = Statistics
|
||||
dashboard.operations = Operations
|
||||
dashboard.system_status = System Monitor Status
|
||||
dashboard.statistic_info = Gogs database has <b>%d</b> users, <b>%d</b> organizations, <b>%d</b> public keys, <b>%d</b> repositories, <b>%d</b> watches, <b>%d</b> stars, <b>%d</b> actions, <b>%d</b> accesses, <b>%d</b> issues, <b>%d</b> comments, <b>%d</b> social accounts, <b>%d</b> follows, <b>%d</b> mirrors, <b>%d</b> releases, <b>%d</b> login sources, <b>%d</b> webhooks, <b>%d</b> milestones, <b>%d</b> labels, <b>%d</b> hook tasks, <b>%d</b> teams, <b>%d</b> update tasks, <b>%d</b> attachments.
|
||||
dashboard.operation_name = Operation Name
|
||||
dashboard.operation_switch = Switch
|
||||
dashboard.select_operation_to_run = Please select operation to run
|
||||
dashboard.operation_run = Run
|
||||
dashboard.clean_unbind_oauth = Clean unbound OAuthes
|
||||
dashboard.clean_unbind_oauth_success = All unbind OAuthes have been deleted successfully.
|
||||
@@ -905,8 +1040,8 @@ dashboard.git_gc_repos = Do garbage collection on repositories
|
||||
dashboard.git_gc_repos_success = All repositories have done garbage collection successfully.
|
||||
dashboard.resync_all_sshkeys = Rewrite '.ssh/authorized_keys' file (caution: non-Gogs keys will be lost)
|
||||
dashboard.resync_all_sshkeys_success = All public keys have been rewritten successfully.
|
||||
dashboard.resync_all_update_hooks = Rewrite all update hook of repositories (needed when custom config path is changed)
|
||||
dashboard.resync_all_update_hooks_success = All repositories' update hook have been rewritten successfully.
|
||||
dashboard.resync_all_hooks = Resync pre-receive, update and post-receive hooks of all repositories
|
||||
dashboard.resync_all_hooks_success = All repositories' pre-receive, update and post-receive hooks have been resynced successfully.
|
||||
dashboard.reinit_missing_repos = Reinitialize all repository records that lost Git files
|
||||
dashboard.reinit_missing_repos_success = All repository records that lost Git files have been reinitialized successfully.
|
||||
|
||||
@@ -981,12 +1116,14 @@ repos.private = Private
|
||||
repos.watches = Watches
|
||||
repos.stars = Stars
|
||||
repos.issues = Issues
|
||||
repos.size = Size
|
||||
|
||||
auths.auth_manage_panel = Authentication Manage Panel
|
||||
auths.auth_sources = Authentication Sources
|
||||
auths.new = Add New Source
|
||||
auths.name = Name
|
||||
auths.type = Type
|
||||
auths.enabled = Enabled
|
||||
auths.default = Default
|
||||
auths.updated = Updated
|
||||
auths.auth_type = Authentication Type
|
||||
auths.auth_name = Authentication Name
|
||||
@@ -995,15 +1132,21 @@ auths.domain = Domain
|
||||
auths.host = Host
|
||||
auths.port = Port
|
||||
auths.bind_dn = Bind DN
|
||||
auths.bind_dn_helper = You can use '%s' as placeholder for username, e.g. DOM\%s
|
||||
auths.bind_password = Bind Password
|
||||
auths.bind_password_helper = Warning: This password is stored in plain text. Do not use a high privileged account.
|
||||
auths.user_base = User Search Base
|
||||
auths.user_dn = User DN
|
||||
auths.attribute_username = Username attribute
|
||||
auths.attribute_username = Username Attribute
|
||||
auths.attribute_username_placeholder = Leave empty to use sign-in form field value for user name.
|
||||
auths.attribute_name = First name attribute
|
||||
auths.attribute_surname = Surname attribute
|
||||
auths.attribute_mail = Email attribute
|
||||
auths.attribute_name = First Name Attribute
|
||||
auths.attribute_surname = Surname Attribute
|
||||
auths.attribute_mail = Email Attribute
|
||||
auths.verify_group_membership = Verify group membership
|
||||
auths.group_search_base_dn = Group Search Base DN
|
||||
auths.group_filter = Group Filter
|
||||
auths.group_attribute_contain_user_list = Group Attribute Containing List of Users
|
||||
auths.user_attribute_listed_in_group = User Attribute Listed in Group
|
||||
auths.attributes_in_bind = Fetch attributes in Bind DN context
|
||||
auths.filter = User Filter
|
||||
auths.admin_filter = Admin Filter
|
||||
@@ -1017,9 +1160,9 @@ auths.enable_tls = Enable TLS Encryption
|
||||
auths.skip_tls_verify = Skip TLS Verify
|
||||
auths.pam_service_name = PAM Service Name
|
||||
auths.enable_auto_register = Enable Auto Registration
|
||||
auths.tips = Tips
|
||||
auths.edit = Edit Authentication Setting
|
||||
auths.activated = This authentication is activated
|
||||
auths.default_auth = This authentication is default login source
|
||||
auths.new_success = New authentication '%s' has been added successfully.
|
||||
auths.update_success = Authentication setting has been updated successfully.
|
||||
auths.update = Update Authentication Setting
|
||||
@@ -1029,107 +1172,187 @@ auths.delete_auth_desc = This authentication is going to be deleted, do you want
|
||||
auths.still_in_used = This authentication is still used by some users, please delete or convert these users to another login type first.
|
||||
auths.deletion_success = Authentication has been deleted successfully!
|
||||
auths.login_source_exist = Login source '%s' already exists.
|
||||
auths.github_api_endpoint = API Endpoint
|
||||
|
||||
config.server_config = Server Configuration
|
||||
config.app_name = Application Name
|
||||
config.app_ver = Application Version
|
||||
config.app_url = Application URL
|
||||
config.domain = Domain
|
||||
config.offline_mode = Offline Mode
|
||||
config.disable_router_log = Disable Router Log
|
||||
config.run_user = Run User
|
||||
config.run_mode = Run Mode
|
||||
config.repo_root_path = Repository Root Path
|
||||
config.static_file_root_path = Static File Root Path
|
||||
config.log_file_root_path = Log File Root Path
|
||||
config.script_type = Script Type
|
||||
config.reverse_auth_user = Reverse Authentication User
|
||||
config.not_set = (not set)
|
||||
config.server_config = Server configuration
|
||||
config.brand_name = Brand name
|
||||
config.run_user = Run user
|
||||
config.run_mode = Run mode
|
||||
config.server.external_url = External URL
|
||||
config.server.domain = Domain
|
||||
config.server.protocol = Protocol
|
||||
config.server.http_addr = HTTP address
|
||||
config.server.http_port = HTTP port
|
||||
config.server.cert_file = Certificate file
|
||||
config.server.key_file = Key file
|
||||
config.server.tls_min_version = Minimum TLS version
|
||||
config.server.unix_socket_permission = Unix socket permission
|
||||
config.server.local_root_url = Local root URL
|
||||
config.server.offline_mode = Offline mode
|
||||
config.server.disable_router_log = Disable router log
|
||||
config.server.enable_gzip = Enable Gzip
|
||||
config.server.app_data_path = Application data path
|
||||
config.server.load_assets_from_disk = Load assets from disk
|
||||
config.server.landing_url = Landing URL
|
||||
|
||||
config.ssh_config = SSH Configuration
|
||||
config.ssh_enabled = Enabled
|
||||
config.ssh_start_builtin_server = Start Builtin Server
|
||||
config.ssh_domain = Domain
|
||||
config.ssh_port = Port
|
||||
config.ssh_listen_port = Listen Port
|
||||
config.ssh_root_path = Root Path
|
||||
config.ssh_key_test_path = Key Test Path
|
||||
config.ssh_keygen_path = Keygen ('ssh-keygen') Path
|
||||
config.ssh_minimum_key_size_check = Minimum Key Size Check
|
||||
config.ssh_minimum_key_sizes = Minimum Key Sizes
|
||||
config.ssh_config = SSH configuration
|
||||
config.ssh.enabled = Enabled
|
||||
config.ssh.domain = Exposed domain
|
||||
config.ssh.port = Exposed port
|
||||
config.ssh.root_path = Root path
|
||||
config.ssh.keygen_path = Keygen path
|
||||
config.ssh.key_test_path = Key test path
|
||||
config.ssh.minimum_key_size_check = Minimum key size check
|
||||
config.ssh.minimum_key_sizes = Minimum key sizes
|
||||
config.ssh.rewrite_authorized_keys_at_start = Rewrite "authorized_keys" at start
|
||||
config.ssh.start_builtin_server = Start builtin server
|
||||
config.ssh.listen_host = Listen host
|
||||
config.ssh.listen_port = Listen port
|
||||
config.ssh.server_ciphers = Server ciphers
|
||||
config.ssh.server_macs = Server MACs
|
||||
config.ssh.server_algorithms = Server algorithms
|
||||
|
||||
config.db_config = Database Configuration
|
||||
config.db_type = Type
|
||||
config.db_host = Host
|
||||
config.db_name = Name
|
||||
config.db_user = User
|
||||
config.db_ssl_mode = SSL Mode
|
||||
config.db_ssl_mode_helper = (for "postgres" only)
|
||||
config.db_path = Path
|
||||
config.db_path_helper = (for "sqlite3" and "tidb")
|
||||
config.repo_config = Repository configuration
|
||||
config.repo.root_path = Root path
|
||||
config.repo.script_type = Script type
|
||||
config.repo.ansi_chatset = ANSI charset
|
||||
config.repo.force_private = Force private
|
||||
config.repo.max_creation_limit = Max creation limit
|
||||
config.repo.preferred_licenses = Preferred licenses
|
||||
config.repo.disable_http_git = Disable HTTP Git
|
||||
config.repo.enable_local_path_migration = Enable local path migration
|
||||
config.repo.enable_raw_file_render_mode = Enable raw file render mode
|
||||
config.repo.commits_fetch_concurrency = Commits fetch concurrency
|
||||
config.repo.editor.line_wrap_extensions = Editor line wrap extensions
|
||||
config.repo.editor.previewable_file_modes = Editor previewable file modes
|
||||
config.repo.upload.enabled = Upload enabled
|
||||
config.repo.upload.temp_path = Upload temporary path
|
||||
config.repo.upload.allowed_types = Upload allowed types
|
||||
config.repo.upload.file_max_size = Upload file size limit
|
||||
config.repo.upload.max_files = Upload files limit
|
||||
|
||||
config.service_config = Service Configuration
|
||||
config.register_email_confirm = Require Email Confirmation
|
||||
config.disable_register = Disable Registration
|
||||
config.show_registration_button = Show Register Button
|
||||
config.require_sign_in_view = Require Sign In View
|
||||
config.mail_notify = Mail Notification
|
||||
config.disable_key_size_check = Disable Minimum Key Size Check
|
||||
config.enable_captcha = Enable Captcha
|
||||
config.active_code_lives = Active Code Lives
|
||||
config.reset_password_code_lives = Reset Password Code Lives
|
||||
config.db_config = Database configuration
|
||||
config.db.type = Type
|
||||
config.db.host = Host
|
||||
config.db.name = Name
|
||||
config.db.schema = Schema
|
||||
config.db.schema_helper = (for "postgres" only)
|
||||
config.db.user = User
|
||||
config.db.ssl_mode = SSL mode
|
||||
config.db.ssl_mode_helper = (for "postgres" only)
|
||||
config.db.path = Path
|
||||
config.db.path_helper = (for "sqlite3"only)
|
||||
config.db.max_open_conns = Maximum open connections
|
||||
config.db.max_idle_conns = Maximum idle connections
|
||||
|
||||
config.webhook_config = Webhook Configuration
|
||||
config.queue_length = Queue Length
|
||||
config.deliver_timeout = Deliver Timeout
|
||||
config.skip_tls_verify = Skip TLS Verify
|
||||
config.security_config = Security configuration
|
||||
config.security.login_remember_days = Login remember days
|
||||
config.security.cookie_remember_name = Remember cookie
|
||||
config.security.cookie_username = Username cookie
|
||||
config.security.cookie_secure = Enable secure cookie
|
||||
config.security.reverse_proxy_auth_user = Reverse proxy authentication header
|
||||
config.security.enable_login_status_cookie = Enable login status cookie
|
||||
config.security.login_status_cookie_name = Login status cookie
|
||||
config.security.local_network_allowlist = Local network allowlist
|
||||
|
||||
config.mailer_config = Mailer Configuration
|
||||
config.mailer_enabled = Enabled
|
||||
config.mailer_disable_helo = Disable HELO
|
||||
config.mailer_name = Name
|
||||
config.mailer_host = Host
|
||||
config.mailer_user = User
|
||||
config.send_test_mail = Send Test Email
|
||||
config.test_mail_failed = Fail to send test email to '%s': %v
|
||||
config.test_mail_sent = Test email has been sent to '%s'.
|
||||
config.email_config = Email configuration
|
||||
config.email.enabled = Enabled
|
||||
config.email.subject_prefix = Subject prefix
|
||||
config.email.host = Host
|
||||
config.email.from = From
|
||||
config.email.user = User
|
||||
config.email.helo_hostname = HELO hostname
|
||||
config.email.skip_verify = Skip certificate verify
|
||||
config.email.use_certificate = Use custom certificate
|
||||
config.email.cert_file = Certificate file
|
||||
config.email.key_file = Key file
|
||||
config.email.use_plain_text = Use plain text
|
||||
config.email.add_plain_text_alt = Add plain text alternative
|
||||
config.email.send_test_mail = Send test email
|
||||
config.email.test_mail_failed = Failed to send test email to '%s': %v
|
||||
config.email.test_mail_sent = Test email has been sent to '%s'.
|
||||
|
||||
config.oauth_config = OAuth Configuration
|
||||
config.oauth_enabled = Enabled
|
||||
config.auth_config = Authentication configuration
|
||||
config.auth_custom_logout_url = Custom logout URL
|
||||
config.auth.activate_code_lives = Activate code lives
|
||||
config.auth.reset_password_code_lives = Reset password code lives
|
||||
config.auth.require_email_confirm = Require email confirmation
|
||||
config.auth.require_sign_in_view = Require sign in view
|
||||
config.auth.disable_registration = Disable registration
|
||||
config.auth.enable_registration_captcha = Enable registration captcha
|
||||
config.auth.enable_reverse_proxy_authentication = Enable reverse proxy authentication
|
||||
config.auth.enable_reverse_proxy_auto_registration = Enable reverse proxy auto registration
|
||||
config.auth.reverse_proxy_authentication_header = Reverse proxy authentication header
|
||||
|
||||
config.cache_config = Cache Configuration
|
||||
config.cache_adapter = Cache Adapter
|
||||
config.cache_interval = Cache Interval
|
||||
config.cache_conn = Cache Connection
|
||||
config.user_config = User configuration
|
||||
config.user.enable_email_notify = Enable email notification
|
||||
|
||||
config.session_config = Session Configuration
|
||||
config.session_provider = Session Provider
|
||||
config.provider_config = Provider Config
|
||||
config.cookie_name = Cookie Name
|
||||
config.enable_set_cookie = Enable Set Cookie
|
||||
config.gc_interval_time = GC Interval Time
|
||||
config.session_life_time = Session Life Time
|
||||
config.https_only = HTTPS Only
|
||||
config.cookie_life_time = Cookie Life Time
|
||||
config.session_config = Session configuration
|
||||
config.session.provider = Provider
|
||||
config.session.provider_config = Provider config
|
||||
config.session.cookie_name = Cookie
|
||||
config.session.https_only = HTTPS only
|
||||
config.session.gc_interval = GC interval
|
||||
config.session.max_life_time = Max life time
|
||||
config.session.csrf_cookie_name = CSRF cookie
|
||||
|
||||
config.picture_config = Picture Configuration
|
||||
config.picture_service = Picture Service
|
||||
config.disable_gravatar = Disable Gravatar
|
||||
config.enable_federated_avatar = Enable Federated Avatars
|
||||
config.cache_config = Cache configuration
|
||||
config.cache.adapter = Adapter
|
||||
config.cache.interval = GC interval
|
||||
config.cache.host = Host
|
||||
|
||||
config.git_config = Git Configuration
|
||||
config.git_disable_diff_highlight = Disable Diff Syntax Highlight
|
||||
config.git_max_diff_lines = Max Diff Lines (for a single file)
|
||||
config.git_max_diff_line_characters = Max Diff Characters (for a single line)
|
||||
config.git_max_diff_files = Max Diff Files (to be shown)
|
||||
config.git_gc_args = GC Arguments
|
||||
config.git_migrate_timeout = Migration Timeout
|
||||
config.git_mirror_timeout = Mirror Update Timeout
|
||||
config.git_clone_timeout = Clone Operation Timeout
|
||||
config.git_pull_timeout = Pull Operation Timeout
|
||||
config.git_gc_timeout = GC Operation Timeout
|
||||
config.http_config = HTTP configuration
|
||||
config.http.access_control_allow_origin = Access control allow origin
|
||||
|
||||
config.log_config = Log Configuration
|
||||
config.log_mode = Log Mode
|
||||
config.attachment_config = Attachment configuration
|
||||
config.attachment.enabled = Enabled
|
||||
config.attachment.path = Path
|
||||
config.attachment.allowed_types = Allowed types
|
||||
config.attachment.max_size = Size limit
|
||||
config.attachment.max_files = Files limit
|
||||
|
||||
config.release_config = Release configuration
|
||||
config.release.attachment.enabled = Attachment enabled
|
||||
config.release.attachment.allowed_types = Attachment allowed types
|
||||
config.release.attachment.max_size = Attachment size limit
|
||||
config.release.attachment.max_files = Attachment files limit
|
||||
|
||||
config.picture_config = Picture configuration
|
||||
config.picture.avatar_upload_path = User avatar upload path
|
||||
config.picture.repo_avatar_upload_path = Repository avatar upload path
|
||||
config.picture.gravatar_source = Gravatar source
|
||||
config.picture.disable_gravatar = Disable Gravatar
|
||||
config.picture.enable_federated_avatar = Enable federated avatars
|
||||
|
||||
config.mirror_config = Mirror configuration
|
||||
config.mirror.default_interval = Default interval
|
||||
|
||||
config.webhook_config = Webhook configuration
|
||||
config.webhook.types = Types
|
||||
config.webhook.deliver_timeout = Deliver timeout
|
||||
config.webhook.skip_tls_verify = Skip TLS verify
|
||||
|
||||
config.git_config = Git configuration
|
||||
config.git.disable_diff_highlight = Disable diff syntax highlight
|
||||
config.git.max_diff_lines = Diff lines limit (for a single file)
|
||||
config.git.max_diff_line_characters = Diff characters limit (for a single line)
|
||||
config.git.max_diff_files = Diff files limit (for a single diff)
|
||||
config.git.gc_args = GC arguments
|
||||
config.git.migrate_timeout = Migration timeout
|
||||
config.git.mirror_timeout = Mirror fetch timeout
|
||||
config.git.clone_timeout = Clone timeout
|
||||
config.git.pull_timeout = Pull timeout
|
||||
config.git.gc_timeout = GC timeout
|
||||
|
||||
config.lfs_config = LFS configuration
|
||||
config.lfs.storage = Storage
|
||||
config.lfs.objects_path = Objects path
|
||||
|
||||
config.log_config = Log configuration
|
||||
config.log_file_root_path = Log file root path
|
||||
config.log_mode = Mode
|
||||
config.log_options = Options
|
||||
|
||||
monitor.cron = Cron Tasks
|
||||
monitor.name = Name
|
||||
@@ -1160,17 +1383,24 @@ notices.delete_success = System notices have been deleted successfully.
|
||||
create_repo = created repository <a href="%s">%s</a>
|
||||
rename_repo = renamed repository from <code>%[1]s</code> to <a href="%[2]s">%[3]s</a>
|
||||
commit_repo = pushed to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
compare_commits = View comparison for these %d commits
|
||||
transfer_repo = transfered repository <code>%s</code> to <a href="%s">%s</a>
|
||||
create_issue = `opened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
close_issue = `closed issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
reopen_issue = `reopened issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
comment_issue = `commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
create_pull_request = `created pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
close_pull_request = `closed pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
reopen_pull_request = `reopened pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
comment_issue = `commented on issue <a href="%s/issues/%s">%s#%[2]s</a>`
|
||||
merge_pull_request = `merged pull request <a href="%s/pulls/%s">%s#%[2]s</a>`
|
||||
transfer_repo = transfered repository <code>%s</code> to <a href="%s">%s</a>
|
||||
create_branch = created new branch <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a>
|
||||
delete_branch = deleted branch <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
push_tag = pushed tag <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a>
|
||||
compare_commits = View comparison for these %d commits
|
||||
delete_tag = deleted tag <code>%[2]s</code> at <a href="%[1]s">%[3]s</a>
|
||||
fork_repo = forked a repository to <a href="%s">%s</a>
|
||||
mirror_sync_push = synced commits to <a href="%[1]s/src/%[2]s">%[3]s</a> at <a href="%[1]s">%[4]s</a> from mirror
|
||||
mirror_sync_create = synced new reference <a href="%s/src/%s">%[2]s</a> to <a href="%[1]s">%[3]s</a> from mirror
|
||||
mirror_sync_delete = synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror
|
||||
|
||||
[tool]
|
||||
ago = ago
|
||||
@@ -1192,6 +1422,7 @@ months = %d months %s
|
||||
years = %d years %s
|
||||
raw_seconds = seconds
|
||||
raw_minutes = minutes
|
||||
raw_hours = hours
|
||||
|
||||
[dropzone]
|
||||
default_message = Drop files here or click to upload.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1436
conf/locale/locale_fa-IR.ini
Normal file
1436
conf/locale/locale_fa-IR.ini
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1435
conf/locale/locale_gl-ES.ini
Normal file
1435
conf/locale/locale_gl-ES.ini
Normal file
File diff suppressed because it is too large
Load Diff
1434
conf/locale/locale_hu-HU.ini
Normal file
1434
conf/locale/locale_hu-HU.ini
Normal file
File diff suppressed because it is too large
Load Diff
1434
conf/locale/locale_id-ID.ini
Normal file
1434
conf/locale/locale_id-ID.ini
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1436
conf/locale/locale_ko-KR.ini
Normal file
1436
conf/locale/locale_ko-KR.ini
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1434
conf/locale/locale_mn-MN.ini
Normal file
1434
conf/locale/locale_mn-MN.ini
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1434
conf/locale/locale_pt-PT.ini
Normal file
1434
conf/locale/locale_pt-PT.ini
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user