forked from vikunja/vikunja
Compare commits
562 Commits
release/0.
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
279bbcd70c | ||
a6556f3505 | |||
92a87cfe4f | |||
163a4624ee | |||
37a07aa677 | |||
e52c45d5aa | |||
|
acaa85083f | ||
f5ebada913 | |||
7b10176a10 | |||
3ab0ac9f27 | |||
dc5faaf2cf | |||
85be5a7bcd | |||
9ab00fd2e6 | |||
9845fcc170 | |||
b4f57dc3e1 | |||
|
4960a498ff | ||
|
96e519ea96 | ||
81a18661ad | |||
fabd3471a8 | |||
8cdbc78b1c | |||
91c89931f8 | |||
e4b50e84a4 | |||
726a517bec | |||
de97fcbd12 | |||
d3bdafb717 | |||
e19ad11846 | |||
6b51fae093 | |||
ba2bdff391 | |||
7fa0865188 | |||
6df865876d | |||
2ec7d7a8a8 | |||
f83b09af59 | |||
362706b38d | |||
1fa1cd365e | |||
0a1d8c9404 | |||
d08dcc4e44 | |||
ac6818a476 | |||
5cf263a86f | |||
09c0d14444 | |||
da0bcc6322 | |||
f5b0c603a3 | |||
aa30baf1bc | |||
581dcd41f1 | |||
d013020268 | |||
bc8a02d794 | |||
b60c69c5a8 | |||
9d816205da | |||
8aa646e4d9 | |||
b167aac624 | |||
75f74b429e | |||
21541bc118 | |||
72ee84d43d | |||
f2f6cc68d9 | |||
c870627644 | |||
edc5084278 | |||
82158d7718 | |||
16a98a5c70 | |||
f77f2387b6 | |||
a423e111e9 | |||
f96c2fe23f | |||
81ab23385f | |||
325ba622e0 | |||
cda78ea702 | |||
8bf2254f4b | |||
22e3f242a3 | |||
8cb92b3924 | |||
44aaf0a4ec | |||
2bc82bc1a0 | |||
43f1daf40c | |||
545999cf5e | |||
c8aab8a8ad | |||
7978c91d09 | |||
519675ab23 | |||
4e257b82a3 | |||
386412caca | |||
8f10a852c2 | |||
d056d2df51 | |||
4432ebf4a5 | |||
c5611f79ea | |||
d2adf00790 | |||
1322cb16d7 | |||
2598550e49 | |||
9196826390 | |||
6cbad9546a | |||
df35531e70 | |||
daa7d26b3d | |||
272fd6dabf | |||
1d8d0f140e | |||
7af4761cc3 | |||
7a27e1317f | |||
59a1e8d0a9 | |||
4e7ceb22dd | |||
b615f06da3 | |||
7c6fc41543 | |||
230c784f55 | |||
049ae39c62 | |||
f7a06e4644 | |||
da318e3db1 | |||
bb88beb417 | |||
61d49c3a56 | |||
e116fbad79 | |||
f255fb2d5c | |||
4aa045d710 | |||
b316a412ed | |||
a9296d807f | |||
614dcaeb9d | |||
832b7184f3 | |||
8fb597cae2 | |||
64cc299fb1 | |||
fbf271978d | |||
514c11d342 | |||
7b2fe5db50 | |||
|
a4c85fed55 | ||
9d8f9d9de9 | |||
c2e8a8ad98 | |||
5e4d632e79 | |||
402c34fb12 | |||
94fff0ac88 | |||
62c3dec6e3 | |||
c5d831ec7c | |||
351d72f02d | |||
4752888c06 | |||
d31c0dfeac | |||
a31086a7a9 | |||
a98119f2d6 | |||
8bb3f8d37c | |||
190a9f2a4c | |||
5c88dfe88e | |||
70e005e7ce | |||
f581885e65 | |||
72d3c54efd | |||
2f0a36eb47 | |||
22e1a4f151 | |||
a9ff6b7561 | |||
24e1460e04 | |||
73ee696fc3 | |||
13561f2114 | |||
f9724181b1 | |||
87515d133d | |||
acc4a8a294 | |||
9194ac6776 | |||
6ece909286 | |||
445cc4f79d | |||
d75a13891a | |||
922eac6029 | |||
fd0d462bf4 | |||
86480ad969 | |||
f8a0a7e953 | |||
b0622732a1 | |||
072b82412b | |||
ea539cc284 | |||
|
36bf3d216a | ||
efd0970971 | |||
677ca03489 | |||
1fa74cba64 | |||
0b7762590f | |||
c3e0e6405a | |||
57e5d10eee | |||
88a2cede19 | |||
093d0c65ca | |||
da2d5e41c7 | |||
9bf32aae99 | |||
2aea1691cf | |||
4829c89940 | |||
cf05de19b3 | |||
2ae1da473e | |||
62361d8ad9 | |||
98316a04b2 | |||
ae192c1291 | |||
e3210a11df | |||
5763aca428 | |||
609497d08c | |||
b92c370d6d | |||
0b707369d0 | |||
e64f06fabc | |||
bcfaa78c1a | |||
29eb0765f3 | |||
473692cf7a | |||
b9819de157 | |||
b3e520427b | |||
cb74337738 | |||
a03d119a06 | |||
2683ef23d5 | |||
516c812043 | |||
9eca971c93 | |||
cc612d505f | |||
53703dd0c4 | |||
068ad56d2b | |||
a20cbc99fd | |||
eb47161c64 | |||
b194715690 | |||
8f55af07c9 | |||
9869fd694a | |||
ff7270838e | |||
4bdf147c89 | |||
1443f8aa2d | |||
af306e5ad3 | |||
9fbda1d503 | |||
445703e155 | |||
4c05912633 | |||
8dfbb2c344 | |||
84fe135f69 | |||
0a6e6dcac1 | |||
|
dcb52c00f1 | ||
50b65a517d | |||
d7e47a28d4 | |||
c2b6119434 | |||
f46c1c5d13 | |||
66589ca37d | |||
45a8c63015 | |||
fce8b89b45 | |||
82a3330412 | |||
fb9fa27488 | |||
cd6cd840a2 | |||
c2f33868c8 | |||
73a99ebd92 | |||
68998e90a4 | |||
c67456d420 | |||
2ab27c72f2 | |||
df5c5e3be2 | |||
1f067930a2 | |||
0ca1560bf1 | |||
4de8ec56a6 | |||
ae8db176db | |||
56efbdc297 | |||
4764a8e4f0 | |||
dbd6f36da6 | |||
4255bc3a94 | |||
bb086eb9f8 | |||
c4da0b424b | |||
037457e865 | |||
e51f125931 | |||
57d447b165 | |||
4136255c67 | |||
0f2013f915 | |||
0ca31aed28 | |||
351fe1f624 | |||
abfdae0012 | |||
5f5936c972 | |||
111ac92619 | |||
bf00ea4939 | |||
465f6d90ab | |||
07bda3eae3 | |||
03d818fd9f | |||
f019ae42bb | |||
9000f2c3cd | |||
cc1bb3083f | |||
be47459c14 | |||
086f005e3d | |||
24bb7e98fa | |||
496c38de8e | |||
90146aea5b | |||
fc51a3e76f | |||
4154247d95 | |||
e3956527d4 | |||
15e5a9069b | |||
c9d0f519ee | |||
72f7c3333a | |||
d7b74500c3 | |||
bd24743640 | |||
e2dd9d85b5 | |||
f8833ae8a2 | |||
ade085ddeb | |||
e00bcf4802 | |||
aee4b14ed0 | |||
f98c7877fc | |||
52eb923327 | |||
f04c8048df | |||
8382d06ea9 | |||
67681f9e2b | |||
fef3d8199c | |||
32ba088497 | |||
b451399a1d | |||
98f367eb97 | |||
dcddaab7b5 | |||
b3bb7395cd | |||
483496cc26 | |||
7ffa08ee1a | |||
ed65a7cd34 | |||
83809d1bd6 | |||
2007f63502 | |||
b92da0a5f1 | |||
6b7aa380ec | |||
27119ad6d4 | |||
cd21c5fc6e | |||
77c2b77079 | |||
1fbd9b67e0 | |||
fb69260b64 | |||
aeba72a7ea | |||
cd5b46363d | |||
c3da454854 | |||
e38be9bd18 | |||
dc2915875b | |||
be4d53d805 | |||
d34c85d544 | |||
647f3cb9f1 | |||
f237afd2ac | |||
4c5f457313 | |||
9c2a59582a | |||
d746c1bede | |||
220f43331f | |||
24f7d9b4f7 | |||
5cfc9bf2f9 | |||
3572ac4b82 | |||
1571dfa825 | |||
e600f61e06 | |||
ea921f5350 | |||
6ccb85a0dc | |||
dac315db59 | |||
eae3cbc7bb | |||
d9b38b85f6 | |||
c7f337f303 | |||
733f26f017 | |||
e4a0066e20 | |||
d28390d792 | |||
0b90d826be | |||
850c3a3dd4 | |||
4cf7c459da | |||
2a80e552cc | |||
7e229a1b83 | |||
7ee535de47 | |||
4216ed7277 | |||
d5d4d8b6ed | |||
9559cbf1ec | |||
265e778867 | |||
53f37e12ec | |||
302199089d | |||
7adbd21698 | |||
d26f81162f | |||
e21a3904ff | |||
562ef9af36 | |||
294fc16593 | |||
d0c77ad1c1 | |||
373e3f3d60 | |||
358661e060 | |||
32a07c4c61 | |||
5b825f1cc8 | |||
50b49ffab6 | |||
8b6aeb8571 | |||
0c5dfe5c48 | |||
d7932d2648 | |||
f1df45b632 | |||
ff2dac1a10 | |||
e857d73c22 | |||
b3f7827e39 | |||
bba6d8feb1 | |||
2cc365ff0c | |||
5593d7bace | |||
e6d4620f92 | |||
f70d357a93 | |||
37718c3282 | |||
7408380560 | |||
4ed4a96059 | |||
9b03c28e0d | |||
f17e2f9e7c | |||
441e38086d | |||
bf68ccbb25 | |||
1386ed4023 | |||
d2a3db5dce | |||
63340b32f8 | |||
52f6b10a65 | |||
81d469f687 | |||
769b5d1c6c | |||
1c77e40e6e | |||
6f54d4d8be | |||
6018573d81 | |||
b4f08e88ae | |||
88c3bd43a4 | |||
61dd159131 | |||
5c79add056 | |||
6b70069eba | |||
9147e6739f | |||
570d146b21 | |||
cc2c158b9d | |||
78a206c818 | |||
fc5703ac8c | |||
3277f6acf7 | |||
8a1e98a7f2 | |||
9a2655dbf1 | |||
d48aa101cf | |||
df45675df3 | |||
afd6bde74d | |||
e23014dbe4 | |||
8e65ffb99b | |||
3f6d85497f | |||
88b9ea6a96 | |||
67f863120e | |||
ffede02ddc | |||
3973ce985d | |||
2351194547 | |||
b7ec24ff52 | |||
aaac4c6dfc | |||
2e52cc1802 | |||
20ede346b4 | |||
b76ad8efe2 | |||
d695681a0e | |||
52c3075c3d | |||
e837c2a003 | |||
f670d394fa | |||
71cc7334cc | |||
fc1867ec70 | |||
d69482cda9 | |||
71d60e908a | |||
86b7d224ab | |||
9dc72c5c98 | |||
f052fc19fc | |||
06cc0a06e4 | |||
02dd7ee571 | |||
abc1fa2fed | |||
b5da7fc546 | |||
d715b02421 | |||
b7b69afa0c | |||
ce15ade6b8 | |||
0986ec6bdd | |||
8b56308a59 | |||
0f5f85e687 | |||
4ceeb877b1 | |||
4393320691 | |||
e4db9dfe6c | |||
4504499f60 | |||
43cb7f1fc2 | |||
30919fd4da | |||
5089049b17 | |||
6fc4e35ac4 | |||
6e263b6a91 | |||
7ff7b0d743 | |||
410a7426cf | |||
8d1cee4500 | |||
f429efc220 | |||
6e5a9868f5 | |||
2547de59ae | |||
b4d726f5a8 | |||
ad9749e37d | |||
967270b2c1 | |||
d07b284ee3 | |||
b3c604fd2f | |||
6a927c0703 | |||
126f3acdc8 | |||
8ddc00bd29 | |||
cb0df3ebbc | |||
325dcc5795 | |||
84291679cc | |||
b7d832891a | |||
b2bbb03e48 | |||
0b8173c1c3 | |||
9b7eef985e | |||
8a7baaed19 | |||
73f2d4532d | |||
bc782e68ff | |||
6c3488b8aa | |||
d7f3c653f9 | |||
e2aa916bdd | |||
398f05e9a0 | |||
be3184d49f | |||
81d021e872 | |||
d1b87d2705 | |||
7b29ac7128 | |||
7b7ccddf51 | |||
532855d850 | |||
ee436efba3 | |||
9d0dcb8d7d | |||
6fa95e6492 | |||
fc4eb8ceb9 | |||
87f7cbfa73 | |||
f8683796e8 | |||
5e048feedf | |||
67167d4abb | |||
156e50f371 | |||
cf2cfde4fc | |||
f78bb613e4 | |||
3a7678bfb9 | |||
466b2b676c | |||
89d0fbcc7c | |||
77e9a58a52 | |||
81665168bc | |||
6de3d8b3a1 | |||
3999580fe6 | |||
c71a1fea82 | |||
729cb3de38 | |||
4880a0265b | |||
2178166ece | |||
509f23c550 | |||
a22dd094c2 | |||
b6accd7c67 | |||
393a3bc37a | |||
b98ac9f551 | |||
8ab5289c3d | |||
32cf66e9d5 | |||
eb3a945678 | |||
3afedc25f0 | |||
4fc7d1f64f | |||
0c5c54a267 | |||
86a9d2e9f3 | |||
8b2b996e7a | |||
d8623fe185 | |||
c873c1ec32 | |||
0bd27ddeb7 | |||
aaeb89db4f | |||
2f1a3fea88 | |||
d9a57e7ef4 | |||
ddcf7624bd | |||
911e5b22ee | |||
bef22f5756 | |||
d8e10e1a58 | |||
83f003355d | |||
58492fffce | |||
268e344128 | |||
9cff4e33ca | |||
e7875ecb3b | |||
618b464ca3 | |||
448ac314b6 | |||
d6c6fcadc5 | |||
65f42b8bda | |||
ec7becd426 | |||
59092afbc0 | |||
480db6aa9b | |||
bb77df68f5 | |||
9ef17a6dbc | |||
37a4e1e658 | |||
02b6dbd07d | |||
61d76e6875 | |||
7debeaa9ff | |||
5d698f2ff8 | |||
7bb3f4c847 | |||
269e7dd5df | |||
8cfa2aa480 | |||
015ca310e9 | |||
9fe46f9a61 | |||
18b35e1119 | |||
b8ccfbd190 | |||
490ba2ea50 | |||
fb53322d40 | |||
55f9106c9e | |||
d600d8b5a6 | |||
0ab9ce9ec4 | |||
a71aa0c898 | |||
c4a71016b8 | |||
34ef1438d8 | |||
657dcc5313 | |||
2d283b78c2 | |||
6bdc1fdb0d | |||
d69c799197 | |||
2e88600c93 | |||
fe72f30b24 | |||
6945d8ba69 | |||
ef0035d4bd | |||
db77de3ae6 | |||
1c98fecbd9 | |||
343fa6ca0d | |||
aadfb8d8f2 | |||
2447f84e2b | |||
c1ad9d58f5 | |||
e16c5f72ca | |||
20af034d78 | |||
32c021e2b3 | |||
e9263f92d5 | |||
044a1a9161 | |||
10ba7b5b65 | |||
e9a340026d | |||
64441701fd | |||
df79173b22 | |||
4e137ed72d |
@ -1,3 +1,4 @@
|
||||
---
|
||||
kind: pipeline
|
||||
name: testing
|
||||
|
||||
@ -5,42 +6,96 @@ workspace:
|
||||
base: /go
|
||||
path: src/code.vikunja.io/api
|
||||
|
||||
volumes:
|
||||
- name: tmp-sqlite-unit
|
||||
temp:
|
||||
medium: memory
|
||||
- name: tmp-sqlite-integration
|
||||
temp:
|
||||
medium: memory
|
||||
- name: tmp-sqlite-migration
|
||||
temp:
|
||||
medium: memory
|
||||
- name: tmp-mysql-unit
|
||||
temp:
|
||||
medium: memory
|
||||
- name: tmp-mysql-integration
|
||||
temp:
|
||||
medium: memory
|
||||
- name: tmp-mysql-migration
|
||||
temp:
|
||||
medium: memory
|
||||
- name: tmp-postgres-unit
|
||||
temp:
|
||||
medium: memory
|
||||
- name: tmp-postgres-integration
|
||||
temp:
|
||||
medium: memory
|
||||
- name: tmp-postgres-migration
|
||||
temp:
|
||||
medium: memory
|
||||
|
||||
|
||||
services:
|
||||
- name: test-mysql-unit
|
||||
image: mariadb:10
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: vikunjatest
|
||||
MYSQL_DATABASE: vikunjatest
|
||||
volumes:
|
||||
- name: tmp-mysql-unit
|
||||
path: /var/lib/mysql
|
||||
- name: test-mysql-integration
|
||||
image: mariadb:10
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: vikunjatest
|
||||
MYSQL_DATABASE: vikunjatest
|
||||
volumes:
|
||||
- name: tmp-mysql-integration
|
||||
path: /var/lib/mysql
|
||||
- name: test-mysql-migration
|
||||
image: mariadb:10
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: vikunjatest
|
||||
MYSQL_DATABASE: vikunjatest
|
||||
volumes:
|
||||
- name: tmp-mysql-migration
|
||||
path: /var/lib/mysql
|
||||
- name: test-postgres-unit
|
||||
image: postgres:12
|
||||
image: postgres:14
|
||||
environment:
|
||||
POSTGRES_PASSWORD: vikunjatest
|
||||
POSTGRES_DB: vikunjatest
|
||||
volumes:
|
||||
- name: tmp-postgres-unit
|
||||
path: /var/lib/postgresql/data
|
||||
commands:
|
||||
- docker-entrypoint.sh -c fsync=off -c full_page_writes=off # turns of wal
|
||||
- name: test-postgres-integration
|
||||
image: postgres:12
|
||||
image: postgres:14
|
||||
environment:
|
||||
POSTGRES_PASSWORD: vikunjatest
|
||||
POSTGRES_DB: vikunjatest
|
||||
volumes:
|
||||
- name: tmp-postgres-integration
|
||||
path: /var/lib/postgresql/data
|
||||
commands:
|
||||
- docker-entrypoint.sh -c fsync=off -c full_page_writes=off # turns of wal
|
||||
- name: test-postgres-migration
|
||||
image: postgres:12
|
||||
image: postgres:14
|
||||
environment:
|
||||
POSTGRES_PASSWORD: vikunjatest
|
||||
POSTGRES_DB: vikunjatest
|
||||
volumes:
|
||||
- name: tmp-postgres-migration
|
||||
path: /var/lib/postgresql/data
|
||||
commands:
|
||||
- docker-entrypoint.sh -c fsync=off -c full_page_writes=off # turns of wal
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
include:
|
||||
- master
|
||||
- main
|
||||
event:
|
||||
include:
|
||||
- push
|
||||
@ -61,6 +116,7 @@ steps:
|
||||
GOPROXY: 'https://goproxy.kolaente.de'
|
||||
commands:
|
||||
- mage -compile ./mage-static
|
||||
- env
|
||||
when:
|
||||
event: [ push, tag, pull_request ]
|
||||
|
||||
@ -82,10 +138,8 @@ steps:
|
||||
GOPROXY: 'https://goproxy.kolaente.de'
|
||||
depends_on: [ build ]
|
||||
commands:
|
||||
- ./mage-static build:generate
|
||||
- ./mage-static check:got-swag
|
||||
- wget -O - -q https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.31.0
|
||||
- ./mage-static check:golangci
|
||||
- wget -O - -q https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.45.2
|
||||
- ./mage-static check:all
|
||||
when:
|
||||
event: [ push, tag, pull_request ]
|
||||
|
||||
@ -94,8 +148,8 @@ steps:
|
||||
pull: true
|
||||
commands:
|
||||
# Get the latest version
|
||||
- wget https://dl.vikunja.io/api/master/vikunja-master-linux-amd64-full.zip -q -O vikunja-latest.zip
|
||||
- unzip vikunja-latest.zip vikunja-master-linux-amd64
|
||||
- wget https://dl.vikunja.io/api/unstable/vikunja-unstable-linux-amd64-full.zip -q -O vikunja-latest.zip
|
||||
- unzip vikunja-latest.zip vikunja-unstable-linux-amd64
|
||||
|
||||
- name: test-migration-sqlite
|
||||
image: kolaente/toolbox:latest
|
||||
@ -103,11 +157,14 @@ steps:
|
||||
depends_on: [ test-migration-prepare, build ]
|
||||
environment:
|
||||
VIKUNJA_DATABASE_TYPE: sqlite
|
||||
VIKUNJA_DATABASE_PATH: ./vikunja-migration-test.db
|
||||
VIKUNJA_DATABASE_PATH: /db/vikunja-migration-test.db
|
||||
VIKUNJA_LOG_DATABASE: stdout
|
||||
VIKUNJA_LOG_DATABASELEVEL: debug
|
||||
volumes:
|
||||
- name: tmp-sqlite-migration
|
||||
path: /db
|
||||
commands:
|
||||
- ./vikunja-master-linux-amd64 migrate
|
||||
- ./vikunja-unstable-linux-amd64 migrate
|
||||
# Run the migrations from the binary build in the step before
|
||||
- ./vikunja migrate
|
||||
when:
|
||||
@ -126,7 +183,7 @@ steps:
|
||||
VIKUNJA_LOG_DATABASE: stdout
|
||||
VIKUNJA_LOG_DATABASELEVEL: debug
|
||||
commands:
|
||||
- ./vikunja-master-linux-amd64 migrate
|
||||
- ./vikunja-unstable-linux-amd64 migrate
|
||||
# Run the migrations from the binary build in the step before
|
||||
- ./vikunja migrate
|
||||
when:
|
||||
@ -146,7 +203,7 @@ steps:
|
||||
VIKUNJA_LOG_DATABASE: stdout
|
||||
VIKUNJA_LOG_DATABASELEVEL: debug
|
||||
commands:
|
||||
- ./vikunja-master-linux-amd64 migrate
|
||||
- ./vikunja-unstable-linux-amd64 migrate
|
||||
# Run the migrations from the binary build in the step before
|
||||
- ./vikunja migrate
|
||||
when:
|
||||
@ -158,7 +215,6 @@ steps:
|
||||
environment:
|
||||
GOPROXY: 'https://goproxy.kolaente.de'
|
||||
commands:
|
||||
- ./mage-static build:generate
|
||||
- ./mage-static test:unit
|
||||
depends_on: [ fetch-tags, mage ]
|
||||
when:
|
||||
@ -171,8 +227,11 @@ steps:
|
||||
GOPROXY: 'https://goproxy.kolaente.de'
|
||||
VIKUNJA_TESTS_USE_CONFIG: 1
|
||||
VIKUNJA_DATABASE_TYPE: sqlite
|
||||
VIKUNJA_DATABASE_PATH: /db/vikunja-test.db
|
||||
volumes:
|
||||
- name: tmp-sqlite-unit
|
||||
path: /db
|
||||
commands:
|
||||
- ./mage-static build:generate
|
||||
- ./mage-static test:unit
|
||||
depends_on: [ fetch-tags, mage ]
|
||||
when:
|
||||
@ -190,7 +249,6 @@ steps:
|
||||
VIKUNJA_DATABASE_PASSWORD: vikunjatest
|
||||
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
||||
commands:
|
||||
- ./mage-static build:generate
|
||||
- ./mage-static test:unit
|
||||
depends_on: [ fetch-tags, mage ]
|
||||
when:
|
||||
@ -209,7 +267,6 @@ steps:
|
||||
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
||||
VIKUNJA_DATABASE_SSLMODE: disable
|
||||
commands:
|
||||
- ./mage-static build:generate
|
||||
- ./mage-static test:unit
|
||||
depends_on: [ fetch-tags, mage ]
|
||||
when:
|
||||
@ -221,7 +278,6 @@ steps:
|
||||
environment:
|
||||
GOPROXY: 'https://goproxy.kolaente.de'
|
||||
commands:
|
||||
- ./mage-static build:generate
|
||||
- ./mage-static test:integration
|
||||
depends_on: [ fetch-tags, mage ]
|
||||
when:
|
||||
@ -234,8 +290,11 @@ steps:
|
||||
GOPROXY: 'https://goproxy.kolaente.de'
|
||||
VIKUNJA_TESTS_USE_CONFIG: 1
|
||||
VIKUNJA_DATABASE_TYPE: sqlite
|
||||
VIKUNJA_DATABASE_PATH: /db/vikunja-test.db
|
||||
volumes:
|
||||
- name: tmp-sqlite-integration
|
||||
path: /db
|
||||
commands:
|
||||
- ./mage-static build:generate
|
||||
- ./mage-static test:integration
|
||||
depends_on: [ fetch-tags, mage ]
|
||||
when:
|
||||
@ -253,7 +312,6 @@ steps:
|
||||
VIKUNJA_DATABASE_PASSWORD: vikunjatest
|
||||
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
||||
commands:
|
||||
- ./mage-static build:generate
|
||||
- ./mage-static test:integration
|
||||
depends_on: [ fetch-tags, mage ]
|
||||
when:
|
||||
@ -272,7 +330,6 @@ steps:
|
||||
VIKUNJA_DATABASE_DATABASE: vikunjatest
|
||||
VIKUNJA_DATABASE_SSLMODE: disable
|
||||
commands:
|
||||
- ./mage-static build:generate
|
||||
- ./mage-static test:integration
|
||||
depends_on: [ fetch-tags, mage ]
|
||||
when:
|
||||
@ -295,7 +352,7 @@ workspace:
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/master
|
||||
- refs/heads/main
|
||||
- "refs/tags/**"
|
||||
|
||||
steps:
|
||||
@ -323,7 +380,6 @@ steps:
|
||||
commands:
|
||||
- export PATH=$PATH:$GOPATH/bin
|
||||
- go install github.com/magefile/mage
|
||||
- ./mage-static build:generate
|
||||
- ./mage-static release:dirs
|
||||
depends_on: [ fetch-tags, mage ]
|
||||
|
||||
@ -403,7 +459,7 @@ steps:
|
||||
|
||||
# Push the releases to our pseudo-s3-bucket
|
||||
- name: release-latest
|
||||
image: plugins/s3:1
|
||||
image: plugins/s3
|
||||
pull: true
|
||||
settings:
|
||||
bucket: vikunja-releases
|
||||
@ -416,16 +472,16 @@ steps:
|
||||
path_style: true
|
||||
strip_prefix: dist/zip/
|
||||
source: dist/zip/*
|
||||
target: /api/master/
|
||||
target: /api/unstable/
|
||||
when:
|
||||
branch:
|
||||
- master
|
||||
- main
|
||||
event:
|
||||
- push
|
||||
depends_on: [ sign-release ]
|
||||
|
||||
- name: release-version
|
||||
image: plugins/s3:1
|
||||
image: plugins/s3
|
||||
pull: true
|
||||
settings:
|
||||
bucket: vikunja-releases
|
||||
@ -451,11 +507,14 @@ steps:
|
||||
commands:
|
||||
- apk add git go
|
||||
- ./mage-static release:packages
|
||||
- mv dist/os-packages/vikunja*.x86_64.rpm dist/os-packages/vikunja-unstable-x86_64.rpm
|
||||
- mv dist/os-packages/vikunja*_amd64.deb dist/os-packages/vikunja-unstable-amd64.deb
|
||||
- mv dist/os-packages/vikunja*_x86_64.apk dist/os-packages/vikunja-unstable-x86_64.apk
|
||||
depends_on: [ static-build-linux ]
|
||||
|
||||
# Push the os releases to our pseudo-s3-bucket
|
||||
- name: release-os-latest
|
||||
image: plugins/s3:1
|
||||
image: plugins/s3
|
||||
pull: true
|
||||
settings:
|
||||
bucket: vikunja-releases
|
||||
@ -468,16 +527,16 @@ steps:
|
||||
path_style: true
|
||||
strip_prefix: dist/os-packages/
|
||||
source: dist/os-packages/*
|
||||
target: /api/master/
|
||||
target: /api/unstable/
|
||||
when:
|
||||
branch:
|
||||
- master
|
||||
- main
|
||||
event:
|
||||
- push
|
||||
depends_on: [ build-os-packages ]
|
||||
|
||||
- name: release-os-version
|
||||
image: plugins/s3:1
|
||||
image: plugins/s3
|
||||
pull: true
|
||||
settings:
|
||||
bucket: vikunja-releases
|
||||
@ -496,27 +555,28 @@ steps:
|
||||
- tag
|
||||
depends_on: [ build-os-packages ]
|
||||
|
||||
- name: deb-structure
|
||||
image: kolaente/reprepro
|
||||
pull: true
|
||||
environment:
|
||||
GPG_PRIVATE_KEY:
|
||||
from_secret: gpg_privatekey
|
||||
commands:
|
||||
- export GPG_TTY=$(tty)
|
||||
- gpg -qk
|
||||
- echo "use-agent" >> ~/.gnupg/gpg.conf
|
||||
- gpgconf --kill gpg-agent
|
||||
- echo $GPG_PRIVATE_KEY > ~/frederik.gpg
|
||||
- gpg --import ~/frederik.gpg
|
||||
- mkdir debian/conf -p
|
||||
- cp build/reprepro-dist-conf debian/conf/distributions
|
||||
- ./mage-static release:reprepro
|
||||
depends_on: [ build-os-packages ]
|
||||
### Broken, disabled until we figure out how to fix it
|
||||
# - name: deb-structure
|
||||
# image: kolaente/reprepro
|
||||
# pull: true
|
||||
# environment:
|
||||
# GPG_PRIVATE_KEY:
|
||||
# from_secret: gpg_privatekey
|
||||
# commands:
|
||||
# - export GPG_TTY=$(tty)
|
||||
# - gpg -qk
|
||||
# - echo "use-agent" >> ~/.gnupg/gpg.conf
|
||||
# - gpgconf --kill gpg-agent
|
||||
# - echo $GPG_PRIVATE_KEY > ~/frederik.gpg
|
||||
# - gpg --import ~/frederik.gpg
|
||||
# - mkdir debian/conf -p
|
||||
# - cp build/reprepro-dist-conf debian/conf/distributions
|
||||
# - ./mage-static release:reprepro
|
||||
# depends_on: [ build-os-packages ]
|
||||
|
||||
# Push the releases to our pseudo-s3-bucket
|
||||
- name: release-deb
|
||||
image: plugins/s3:1
|
||||
image: plugins/s3
|
||||
pull: true
|
||||
settings:
|
||||
bucket: vikunja-releases
|
||||
@ -530,7 +590,7 @@ steps:
|
||||
strip_prefix: debian
|
||||
source: debian/*/*/*/*/*
|
||||
target: /deb/
|
||||
depends_on: [ deb-structure ]
|
||||
# depends_on: [ deb-structure ]
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
@ -547,26 +607,21 @@ trigger:
|
||||
event:
|
||||
- push
|
||||
branch:
|
||||
- master
|
||||
- main
|
||||
|
||||
steps:
|
||||
- name: submodules
|
||||
image: docker:git
|
||||
commands:
|
||||
- git submodule update --init
|
||||
- git submodule update --recursive --remote
|
||||
|
||||
- name: theme
|
||||
image: kolaente/yarn
|
||||
image: kolaente/toolbox
|
||||
pull: true
|
||||
group: build-static
|
||||
commands:
|
||||
- mkdir docs/themes/vikunja -p
|
||||
- cd docs/themes/vikunja
|
||||
- yarn --production=false
|
||||
- ./node_modules/.bin/gulp prod
|
||||
- wget https://dl.vikunja.io/theme/vikunja-theme.tar.gz
|
||||
- tar -xzf vikunja-theme.tar.gz
|
||||
|
||||
- name: build
|
||||
image: monachus/hugo:v0.54.0
|
||||
image: klakegg/hugo:0.93.3
|
||||
pull: true
|
||||
commands:
|
||||
- cd docs
|
||||
@ -595,11 +650,11 @@ depends_on:
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: arm
|
||||
arch: arm64
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/master
|
||||
- refs/heads/main
|
||||
- "refs/tags/**"
|
||||
|
||||
steps:
|
||||
@ -607,7 +662,22 @@ steps:
|
||||
image: docker:git
|
||||
commands:
|
||||
- git fetch --tags
|
||||
- name: docker
|
||||
- name: docker-arm-unstable
|
||||
image: plugins/docker:linux-arm
|
||||
pull: true
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
repo: vikunja/api
|
||||
tags: unstable-linux-arm
|
||||
depends_on: [ fetch-tags ]
|
||||
when:
|
||||
ref:
|
||||
- refs/heads/main
|
||||
|
||||
- name: docker-arm
|
||||
image: plugins/docker:linux-arm
|
||||
pull: true
|
||||
settings:
|
||||
@ -619,6 +689,40 @@ steps:
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-arm
|
||||
depends_on: [ fetch-tags ]
|
||||
when:
|
||||
ref:
|
||||
- "refs/tags/**"
|
||||
|
||||
- name: docker-arm64-unstable
|
||||
image: plugins/docker:linux-arm64
|
||||
pull: true
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
repo: vikunja/api
|
||||
tags: unstable-linux-arm64
|
||||
depends_on: [ fetch-tags ]
|
||||
when:
|
||||
ref:
|
||||
- refs/heads/main
|
||||
|
||||
- name: docker-arm64
|
||||
image: plugins/docker:linux-arm64
|
||||
pull: true
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
repo: vikunja/api
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-arm64
|
||||
depends_on: [ fetch-tags ]
|
||||
when:
|
||||
ref:
|
||||
- "refs/tags/**"
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
@ -634,7 +738,7 @@ platform:
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/master
|
||||
- refs/heads/main
|
||||
- "refs/tags/**"
|
||||
|
||||
steps:
|
||||
@ -642,6 +746,22 @@ steps:
|
||||
image: docker:git
|
||||
commands:
|
||||
- git fetch --tags
|
||||
|
||||
- name: docker-unstable
|
||||
image: plugins/docker:linux-amd64
|
||||
pull: true
|
||||
settings:
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
repo: vikunja/api
|
||||
tags: unstable-linux-amd64
|
||||
depends_on: [ fetch-tags ]
|
||||
when:
|
||||
ref:
|
||||
- refs/heads/main
|
||||
|
||||
- name: docker
|
||||
image: plugins/docker:linux-amd64
|
||||
pull: true
|
||||
@ -654,6 +774,9 @@ steps:
|
||||
auto_tag: true
|
||||
auto_tag_suffix: linux-amd64
|
||||
depends_on: [ fetch-tags ]
|
||||
when:
|
||||
ref:
|
||||
- "refs/tags/**"
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
@ -662,7 +785,7 @@ name: docker-manifest
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/master
|
||||
- refs/heads/main
|
||||
- "refs/tags/**"
|
||||
|
||||
depends_on:
|
||||
@ -670,7 +793,22 @@ depends_on:
|
||||
- docker-arm-release
|
||||
|
||||
steps:
|
||||
- name: manifest
|
||||
- name: manifest-unstable
|
||||
pull: always
|
||||
image: plugins/manifest
|
||||
settings:
|
||||
tags: unstable
|
||||
ignore_missing: true
|
||||
spec: docker-manifest-unstable.tmpl
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
when:
|
||||
ref:
|
||||
- refs/heads/main
|
||||
|
||||
- name: manifest-release
|
||||
pull: always
|
||||
image: plugins/manifest
|
||||
settings:
|
||||
@ -681,6 +819,26 @@ steps:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
when:
|
||||
ref:
|
||||
- "refs/tags/**"
|
||||
|
||||
- name: manifest-release-latest
|
||||
pull: always
|
||||
image: plugins/manifest
|
||||
depends_on:
|
||||
- clone
|
||||
settings:
|
||||
tags: latest
|
||||
ignore_missing: true
|
||||
spec: docker-manifest.tmpl
|
||||
password:
|
||||
from_secret: docker_password
|
||||
username:
|
||||
from_secret: docker_username
|
||||
when:
|
||||
ref:
|
||||
- "refs/tags/**"
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
@ -689,26 +847,33 @@ name: notify
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/heads/master
|
||||
- refs/heads/main
|
||||
- "refs/tags/**"
|
||||
|
||||
depends_on:
|
||||
- testing
|
||||
- release
|
||||
- deploy-docs
|
||||
- docker-arm-release
|
||||
- docker-amd64-release
|
||||
- docker-manifest
|
||||
|
||||
steps:
|
||||
- name: telegram
|
||||
image: appleboy/drone-telegram:1-linux-amd64
|
||||
- name: notify
|
||||
image: plugins/matrix
|
||||
settings:
|
||||
token:
|
||||
from_secret: TELEGRAM_TOKEN
|
||||
to:
|
||||
from_secret: TELEGRAM_TO
|
||||
message: >
|
||||
{{repo.owner}}/{{repo.name}}: \[{{build.status}}] Build {{build.number}}
|
||||
{{commit.author}} pushed to {{commit.branch}} {{commit.sha}}: `{{commit.message}}`
|
||||
Build started at {{datetime build.started "2006-Jan-02T15:04:05Z" "GMT+2"}} finished at {{datetime build.finished "2006-Jan-02T15:04:05Z" "GMT+2"}}.
|
||||
homeserver: https://matrix.org
|
||||
roomid: WqBDCxzghKcNflkErL:matrix.org
|
||||
username:
|
||||
from_secret: matrix_username
|
||||
password:
|
||||
from_secret: matrix_password
|
||||
when:
|
||||
status:
|
||||
- success
|
||||
- failure
|
||||
---
|
||||
kind: signature
|
||||
hmac: 1c4c211e66e4b6eddd2a1c1bad31e5c960d4f67d6033f4d5c4de7896dfae6c30
|
||||
|
||||
...
|
22
.editorconfig
Normal file
22
.editorconfig
Normal file
@ -0,0 +1,22 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = false
|
||||
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
|
||||
[*.{yaml,yml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 4
|
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@ -1 +1,2 @@
|
||||
github: kolaente
|
||||
custom: https://www.buymeacoffee.com/kolaente
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,6 +4,7 @@
|
||||
config.yml
|
||||
config.yaml
|
||||
!docs/config.yml
|
||||
docs/themes/
|
||||
*.db
|
||||
Run
|
||||
dist/
|
||||
@ -23,3 +24,4 @@ files/
|
||||
vikunja-dump*
|
||||
vendor/
|
||||
os-packages/
|
||||
mage_output_file.go
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
||||
[submodule "docs/themes/vikunja"]
|
||||
path = docs/themes/vikunja
|
||||
url = ../theme.git
|
@ -1,5 +1,5 @@
|
||||
run:
|
||||
timeout: 5m
|
||||
timeout: 15m
|
||||
tests: true
|
||||
|
||||
linters:
|
||||
@ -13,10 +13,11 @@ linters:
|
||||
- goheader
|
||||
- gofmt
|
||||
- goimports
|
||||
- golint
|
||||
- revive
|
||||
- misspell
|
||||
disable:
|
||||
- scopelint # Obsolete, using exportloopref instead
|
||||
- durationcheck
|
||||
presets:
|
||||
- bugs
|
||||
- unused
|
||||
@ -35,6 +36,7 @@ issues:
|
||||
linters:
|
||||
- gocyclo
|
||||
- deadcode
|
||||
- errorlint
|
||||
- path: pkg/integrations/*
|
||||
linters:
|
||||
- gocyclo
|
||||
@ -80,3 +82,9 @@ issues:
|
||||
- text: "Missed string"
|
||||
linters:
|
||||
- goheader
|
||||
- path: pkg/.*/error.go
|
||||
linters:
|
||||
- errorlint
|
||||
- path: pkg/models/favorites\.go
|
||||
linters:
|
||||
- nilerr
|
||||
|
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"go.testEnvVars": {
|
||||
"VIKUNJA_SERVICE_ROOTPATH": "${workspaceRoot}"
|
||||
}
|
||||
}
|
376
CHANGELOG.md
376
CHANGELOG.md
@ -2,11 +2,365 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
|
||||
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
All releases can be found on https://code.vikunja.io/api/releases.
|
||||
|
||||
## [0.18.1] - 2021-09-08
|
||||
|
||||
### Fixed
|
||||
|
||||
* Docs: Add another third-party tutorial link
|
||||
* Don't try to export items which do not have a parent
|
||||
* fix(deps): update golang.org/x/sys commit hash to 6f6e228 (#970)
|
||||
* fix(deps): update golang.org/x/sys commit hash to c212e73 (#971)
|
||||
* Fix exporting tasks from archived lists
|
||||
* Fix lint
|
||||
* Fix tasks not exported
|
||||
* Fix tmp export file created in the wrong path
|
||||
|
||||
## [0.18.0] - 2021-09-05
|
||||
|
||||
### Added
|
||||
|
||||
* Add default list setting (#875)
|
||||
* Add menu link to Vikunja Cloud in docs
|
||||
* Add more logging and better error messages for openid authentication + clarify docs
|
||||
* Add more logging for test data api endpoint
|
||||
* Add searching for tasks by index
|
||||
* Add setting for first day of the week
|
||||
* Add support of Unix socket (#912)
|
||||
* Add truncate parameter to test fixtures setup
|
||||
* Notify the user after three failed login attempts
|
||||
* Reorder tasks, lists and kanban buckets (#923)
|
||||
* Send a notification on failed TOTP
|
||||
* Task mentions (#926)
|
||||
* Try to get more information about the user when authenticating with openid
|
||||
* User account deletion (#937)
|
||||
* User Data Export and import (#967)
|
||||
|
||||
### Changed
|
||||
|
||||
* Allow running migration 20210711173657 multiple times to fix issues when it didn't completely run through previously
|
||||
* Better logging for errors while importing a bunch of tasks
|
||||
* Change task title to TEXT instead of varchar(250) to allow for longer task titles
|
||||
* Disable the user account after 10 failed password attempts
|
||||
* Docs: Add a note about default password
|
||||
* Docs: Add another youtube tutorial
|
||||
* Docs: Add ios to the list of not working caldav clients
|
||||
* Docs: Add k8s-at-home Helm Chart for Vikunja
|
||||
* Docs: Add other installation resources
|
||||
* Docs: Add translation docs
|
||||
* Docs: Fix rewrite rules in apache example configs
|
||||
* Docs: Translation now happening at crowdin
|
||||
* Docs: Update translation guidelines
|
||||
* Don't fail when removing the last bucket in migration from other services
|
||||
* Don't notify the user who created the team
|
||||
* Don't use the mariadb root user in docker-compose examples
|
||||
* Ensure case insensitive search on postgres (#927)
|
||||
* Increase test timeout
|
||||
* Only filter out failing openid providers if multiple are configured and one of them failed
|
||||
* Only send an email about failed totp after three failed attempts
|
||||
* Rearrange setting frontend url in config
|
||||
* Refactor user email confirmation + password reset handling (#919)
|
||||
* Rename and sign drone config
|
||||
* Replace jwt-go with github.com/golang-jwt/jwt
|
||||
* Reset failed totp attempts when logging in successfully
|
||||
* Save user tokens as text and not varchar
|
||||
* Save user tokens as varchar(450) and not text to fix mysql indexing issues
|
||||
* Set todoist migration redirect url to the frontend url by default
|
||||
* Show config full paths and env variables with config options
|
||||
* Switch the :latest docker image tag to contain the latest release instead of the latest unstable
|
||||
* Tune test db server settings to speed up tests (#939)
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix authentication callback
|
||||
* Fix duplicating empty lists
|
||||
* Fix error handling when deleting an attachment file
|
||||
* Fix error when searching for a namespace returned no results
|
||||
* Fix error when searching for a namespace with subscribers
|
||||
* Fix goimports
|
||||
* Fix importing archived projects and done items from todoist
|
||||
* Fix jwt middleware
|
||||
* Fix lint
|
||||
* Fix mapping task priorities from Vikunja to calDAV
|
||||
* Fix moving the done bucket around
|
||||
* Fix old references to master in docs
|
||||
* Fix panic on invalid smtp config
|
||||
* Fix parsing openid config when using a json config file
|
||||
* Fix saving pointer values to memory keyvalue
|
||||
* Fix saving reminders of repeating tasks
|
||||
* Fix setting a saved filter as favorite
|
||||
* Fix setting task favorite status of related tasks
|
||||
* Fix setting up keyvalue storage in tests
|
||||
* Fix swagger docs for create requests
|
||||
* Fix task relations not getting properly cleaned up when deleting them
|
||||
* Fix tests & lint
|
||||
* Make sure a bucket exists or use the default bucket when importing tasks
|
||||
* Make sure all associated entities of a task are deleted when the task is deleted
|
||||
* Make sure list / task favorites are set per user, not per entity (#915)
|
||||
* Make sure the configured frontend url always has a / at the end
|
||||
* Refactor & fix storing struct-values in redis keyvalue
|
||||
* Todoist migration: don't panic if no reminder was found for task
|
||||
|
||||
### Dependency updates
|
||||
|
||||
* fix(deps): update golang.org/x/sys commit hash to 63515b4 (#959)
|
||||
* fix(deps): update golang.org/x/sys commit hash to 97244b9 (#965)
|
||||
* fix(deps): update golang.org/x/sys commit hash to f475640 (#962)
|
||||
* fix(deps): update golang.org/x/sys commit hash to f4d4317 (#961)
|
||||
* fix(deps): update module github.com/lib/pq to v1.10.3 (#963)
|
||||
* Update alpine Docker tag to v3.13 (#884)
|
||||
* Update alpine Docker tag to v3.14 (#889)
|
||||
* Update golang.org/x/crypto commit hash to 0a44fdf (#944)
|
||||
* Update golang.org/x/crypto commit hash to 0ba0e8f (#943)
|
||||
* Update golang.org/x/crypto commit hash to 32db794 (#949)
|
||||
* Update golang.org/x/crypto commit hash to 5ff15b2 (#891)
|
||||
* Update golang.org/x/crypto commit hash to a769d52 (#916)
|
||||
* Update golang.org/x/image commit hash to 775e3b0 (#880)
|
||||
* Update golang.org/x/image commit hash to a66eb64 (#900)
|
||||
* Update golang.org/x/image commit hash to e6eecd4 (#893)
|
||||
* Update golang.org/x/net commit hash to 37e1c6af
|
||||
* Update golang.org/x/oauth2 commit hash to 14747e6 (#894)
|
||||
* Update golang.org/x/oauth2 commit hash to 2bc19b1 (#955)
|
||||
* Update golang.org/x/oauth2 commit hash to 6f1e639 (#931)
|
||||
* Update golang.org/x/oauth2 commit hash to 7df4dd6 (#952)
|
||||
* Update golang.org/x/oauth2 commit hash to a41e5a7 (#902)
|
||||
* Update golang.org/x/oauth2 commit hash to a8dc77f (#896)
|
||||
* Update golang.org/x/oauth2 commit hash to bce0382 (#895)
|
||||
* Update golang.org/x/oauth2 commit hash to d040287 (#888)
|
||||
* Update golang.org/x/oauth2 commit hash to f6687ab (#862)
|
||||
* Update golang.org/x/oauth2 commit hash to faf39c7 (#935)
|
||||
* Update golang.org/x/sys commit hash to 00dd8d7 (#953)
|
||||
* Update golang.org/x/sys commit hash to 15123e1 (#946)
|
||||
* Update golang.org/x/sys commit hash to 1e6c022 (#947)
|
||||
* Update golang.org/x/sys commit hash to 30e4713 (#945)
|
||||
* Update golang.org/x/sys commit hash to 41cdb87 (#956)
|
||||
* Update golang.org/x/sys commit hash to 7d9622a (#948)
|
||||
* Update golang.org/x/sys commit hash to bfb29a6 (#951)
|
||||
* Update golang.org/x/sys commit hash to d867a43 (#934)
|
||||
* Update golang.org/x/sys commit hash to e5e7981 (#933)
|
||||
* Update golang.org/x/sys commit hash to f52c844 (#954)
|
||||
* Update golang.org/x/term commit hash to 6886f2d (#887)
|
||||
* Update module getsentry/sentry-go to v0.11.0 (#869)
|
||||
* Update module github.com/coreos/go-oidc to v3 (#885)
|
||||
* Update module github.com/gabriel-vasile/mimetype to v1.3.1 (#904)
|
||||
* Update module github.com/golang-jwt/jwt to v3.2.2 (#928)
|
||||
* Update module github.com/golang-jwt/jwt to v4 (#930)
|
||||
* Update module github.com/go-redis/redis/v8 to v8.11.0 (#903)
|
||||
* Update module github.com/go-redis/redis/v8 to v8.11.1 (#925)
|
||||
* Update module github.com/go-redis/redis/v8 to v8.11.2 (#932)
|
||||
* Update module github.com/go-redis/redis/v8 to v8.11.3 (#942)
|
||||
* Update module github.com/iancoleman/strcase to v0.2.0 (#918)
|
||||
* Update module github.com/labstack/echo/v4 to v4.4.0 (#917)
|
||||
* Update module github.com/labstack/echo/v4 to v4.5.0 (#929)
|
||||
* Update module github.com/mattn/go-sqlite3 to v1.14.8 (#921)
|
||||
* Update module github.com/spf13/cobra to v1.2.0 (#905)
|
||||
* Update module github.com/spf13/cobra to v1.2.1 (#906)
|
||||
* Update module github.com/spf13/viper to v1.8.0 (#890)
|
||||
* Update module github.com/spf13/viper to v1.8.1 (#899)
|
||||
* Update module github.com/swaggo/swag to v1.7.1 (#936)
|
||||
* Update module github.com/yuin/goldmark to v1.3.8 (#892)
|
||||
* Update module github.com/yuin/goldmark to v1.3.9 (#901)
|
||||
* Update module github.com/yuin/goldmark to v1.4.0 (#908)
|
||||
* Update module go-redis/redis/v8 to v8.10.0 (#882)
|
||||
* Update module go-redis/redis/v8 to v8.7.1 (#807)
|
||||
* Update module go-testfixtures/testfixtures/v3 to v3.6.1 (#868)
|
||||
* Update module lib/pq to v1.10.2 (#865)
|
||||
* Update module prometheus/client_golang to v1.11.0 (#879)
|
||||
* Update module yuin/goldmark to v1.3.6 (#863)
|
||||
* Update module yuin/goldmark to v1.3.7 (#867)
|
||||
* Update monachus/hugo Docker tag to v0.75.1 (#940)
|
||||
|
||||
## [0.17.1] - 2021-06-09
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix parsing openid config when using a json config file
|
||||
|
||||
## [0.17.0] - 2021-05-14
|
||||
|
||||
### Added
|
||||
|
||||
* Add a "done" option to kanban buckets (#821)
|
||||
* Add arm64 builds
|
||||
* Add basic auth for metrics endpoint
|
||||
* Add bucket limit validation
|
||||
* Add crud endpoints for notifications (#801)
|
||||
* Add endpoint to remove a list background
|
||||
* Add events (#777)
|
||||
* Add github funding link
|
||||
* Add link share password authentication (#831)
|
||||
* Add names for link shares (#829)
|
||||
* Add notifications package for easy sending of notifications (#779)
|
||||
* Add reminders for overdue tasks (#832)
|
||||
* Add repeat monthly setting for tasks (#834)
|
||||
* Add security information to readme
|
||||
* Add separate docker manifest file for latest docker images
|
||||
* Add systemd service file to linux packages
|
||||
* Add test for moving a task to another list
|
||||
* Enable searching users by full email or name
|
||||
* Expose tls parameter of Go MySQL driver to config file (#855)
|
||||
* Pagingation for tasks in kanban buckets (#805)
|
||||
|
||||
### Changed
|
||||
|
||||
* Change keyvalue.Get to return if a value exists or not instead of an error
|
||||
* Change main branch to main
|
||||
* Change test file names to unstable
|
||||
* Change the name of the newly created bucket from "New Bucket" to "Backlog"
|
||||
* Change unstable versions in migration tests
|
||||
* Check if we're on main and change the version name accordingly if that's the case
|
||||
* Cleanup listener names
|
||||
* Cleanup old docs themes submodule
|
||||
* Disable deb repo in drone
|
||||
* Don't keep old releases from os packages when releasing for master
|
||||
* Don't try to get users for tasks if no tasks were found when looking for reminders
|
||||
* Explicitly add docker build step for latest
|
||||
* Explicitly check if there are Ids before trying to get items by a list of Ids
|
||||
* Improve duration format of overdue tasks in reminders
|
||||
* Improve loading labels performance (#824)
|
||||
* Improve sending overdue task reminders by only sending one for all overdue tasks
|
||||
* Make sure all tables are properly pluralized
|
||||
* Only send reminders for undone tasks
|
||||
* Re-Enable migration test steps in pipeline
|
||||
* Refactor getting all namespaces
|
||||
* Remove unused tools from tools.go
|
||||
* Run all lint checks at once
|
||||
* Send a notification to the user when they are added to the list
|
||||
* Show empty avatar when the user was not found
|
||||
* Subscribe a user to a task when they are assigned to it
|
||||
* Subscriptions and notifications for namespaces, tasks and lists (#786)
|
||||
* Switch building the docs to download the theme instead of building
|
||||
* Switch telegram notifications to matrix notifications
|
||||
* Temporarily disable migration step
|
||||
* Temporary build fix
|
||||
* Update changelog
|
||||
* Update copyright year
|
||||
* Update README (#858)
|
||||
* Use golang's tzdata package to handle time zones
|
||||
|
||||
### Fixed
|
||||
|
||||
* Explicitly set darwin-10.15 when building binaries
|
||||
* Fix build
|
||||
* Fix checking list rights when accessing a bucket
|
||||
* Fix /dav/principals/*/ throwing a server error when accessed with GET instead of PROPFIND (#769)
|
||||
* Fix deleting task relations
|
||||
* Fix docs
|
||||
* Fix drone file
|
||||
* Fix due dates with times when migrating from todoist
|
||||
* Fix event error handler retrying infinitely
|
||||
* Fix filter for task index
|
||||
* Fix getting lists for shared, favorite and saved lists namespace
|
||||
* Fix getting user info from /user endpoint for link shares
|
||||
* Fix IncrBy and DecrBy in memory keyvalue implementation if there was no value set previously
|
||||
* Fix lint
|
||||
* Fix matrix notify room id
|
||||
* Fix moving repeating tasks to the done bucket
|
||||
* Fix multiarch docker image building
|
||||
* Fix not able to make saved filters favorite
|
||||
* Fix notifications table not being created on initial setup
|
||||
* Fix resetting the bucket limit
|
||||
* Fix retrieving over openid providers if there are none
|
||||
* Fix sending notifications to users if the user object didn't have an email
|
||||
* Fix setting the user in created_by when uploading an attachment
|
||||
* Fix shared lists showing up twice
|
||||
* Fix tests
|
||||
* Fix the shared lists pseudo namespace containing owned lists
|
||||
* Fix unstable version build file names
|
||||
* Fix user uploaded avatars
|
||||
* Pin golang alpine builder image to 3.12 to fix builds on arm
|
||||
* Revert "Update alpine Docker tag to v3.13 (#768)"
|
||||
|
||||
### Dependency Updates
|
||||
|
||||
* Update alpine Docker tag to v3.13 (#768)
|
||||
* Update github.com/gordonklaus/ineffassign commit hash to 2e10b26 (#803)
|
||||
* Update github.com/gordonklaus/ineffassign commit hash to d0e41b2 (#780)
|
||||
* Update golang.org/x/crypto commit hash to 0c34fe9 (#822)
|
||||
* Update golang.org/x/crypto commit hash to 3497b51 (#853)
|
||||
* Update golang.org/x/crypto commit hash to 38f3c27 (#854)
|
||||
* Update golang.org/x/crypto commit hash to 4f45737 (#836)
|
||||
* Update golang.org/x/crypto commit hash to 513c2a4 (#817)
|
||||
* Update golang.org/x/crypto commit hash to 5bf0f12 (#839)
|
||||
* Update golang.org/x/crypto commit hash to 5ea612d (#797)
|
||||
* Update golang.org/x/crypto commit hash to 83a5a9b (#840)
|
||||
* Update golang.org/x/crypto commit hash to b8e89b7 (#793)
|
||||
* Update golang.org/x/crypto commit hash to c07d793 (#861)
|
||||
* Update golang.org/x/crypto commit hash to cd7d49e (#860)
|
||||
* Update golang.org/x/crypto commit hash to e6e6c4f (#816)
|
||||
* Update golang.org/x/crypto commit hash to e9a3299 (#851)
|
||||
* Update golang.org/x/image commit hash to 4410531 (#788)
|
||||
* Update golang.org/x/image commit hash to 55ae14f (#787)
|
||||
* Update golang.org/x/image commit hash to 7319ad4 (#852)
|
||||
* Update golang.org/x/image commit hash to ac19c3e (#798)
|
||||
* Update golang.org/x/oauth2 commit hash to 0101308 (#776)
|
||||
* Update golang.org/x/oauth2 commit hash to 01de73c (#762)
|
||||
* Update golang.org/x/oauth2 commit hash to 16ff188 (#789)
|
||||
* Update golang.org/x/oauth2 commit hash to 22b0ada (#823)
|
||||
* Update golang.org/x/oauth2 commit hash to 2e8d934 (#827)
|
||||
* Update golang.org/x/oauth2 commit hash to 5366d9d (#813)
|
||||
* Update golang.org/x/oauth2 commit hash to 5e61552 (#833)
|
||||
* Update golang.org/x/oauth2 commit hash to 6667018 (#783)
|
||||
* Update golang.org/x/oauth2 commit hash to 81ed05c (#848)
|
||||
* Update golang.org/x/oauth2 commit hash to 8b1d76f (#764)
|
||||
* Update golang.org/x/oauth2 commit hash to 9bb9049 (#796)
|
||||
* Update golang.org/x/oauth2 commit hash to af13f52 (#773)
|
||||
* Update golang.org/x/oauth2 commit hash to ba52d33 (#794)
|
||||
* Update golang.org/x/oauth2 commit hash to cd4f82c (#815)
|
||||
* Update golang.org/x/oauth2 commit hash to d3ed898 (#765)
|
||||
* Update golang.org/x/oauth2 commit hash to f9ce19e (#775)
|
||||
* Update golang.org/x/sync commit hash to 036812b (#799)
|
||||
* Update golang.org/x/term commit hash to 6a3ed07 (#800)
|
||||
* Update golang.org/x/term commit hash to 72f3dc4 (#828)
|
||||
* Update golang.org/x/term commit hash to a79de54 (#850)
|
||||
* Update golang.org/x/term commit hash to b80969c (#843)
|
||||
* Update golang.org/x/term commit hash to c04ba85 (#849)
|
||||
* Update golang.org/x/term commit hash to de623e6 (#818)
|
||||
* Update golang.org/x/term commit hash to f5beecf (#845)
|
||||
* Update module adlio/trello to v1.9.0 (#825)
|
||||
* Update module coreos/go-oidc to v3 (#760)
|
||||
* Update module gabriel-vasile/mimetype to v1.2.0 (#812)
|
||||
* Update module gabriel-vasile/mimetype to v1.3.0 (#857)
|
||||
* Update module getsentry/sentry-go to v0.10.0 (#792)
|
||||
* Update module go-redis/redis/v8 to v8.4.10 (#771)
|
||||
* Update module go-redis/redis/v8 to v8.4.11 (#774)
|
||||
* Update module go-redis/redis/v8 to v8.4.9 (#770)
|
||||
* Update module go-redis/redis/v8 to v8.5.0 (#778)
|
||||
* Update module go-redis/redis/v8 to v8.6.0 (#795)
|
||||
* Update module go-sql-driver/mysql to v1.6.0 (#826)
|
||||
* Update module go-testfixtures/testfixtures/v3 to v3.5.0 (#761)
|
||||
* Update module go-testfixtures/testfixtures/v3 to v3.6.0 (#838)
|
||||
* Update module iancoleman/strcase to v0.1.3 (#766)
|
||||
* Update module imdario/mergo to v0.3.12 (#811)
|
||||
* Update module jgautheron/goconst to v1 (#804)
|
||||
* Update module labstack/echo/v4 to v4.2.0 (#785)
|
||||
* Update module labstack/echo/v4 to v4.2.1 (#810)
|
||||
* Update module labstack/echo/v4 to v4.2.2 (#830)
|
||||
* Update module labstack/echo/v4 to v4.3.0 (#856)
|
||||
* Update module lib/pq to v1.10.0 (#809)
|
||||
* Update module lib/pq to v1.10.1 (#841)
|
||||
* Update module mattn/go-sqlite3 to v1.14.7 (#835)
|
||||
* Update module olekukonko/tablewriter to v0.0.5 (#782)
|
||||
* Update module prometheus/client_golang to v1.10.0 (#819)
|
||||
* Update module spf13/afero to v1.6.0 (#820)
|
||||
* Update module spf13/cobra to v1.1.2 (#781)
|
||||
* Update module spf13/cobra to v1.1.3 (#784)
|
||||
* Update module src.techknowlogick.com/xgo to v1.3.0+1.16.0 (#791)
|
||||
* Update module src.techknowlogick.com/xgo to v1.4.0+1.16.2 (#814)
|
||||
* Update module stretchr/testify to v1.7.0 (#763)
|
||||
|
||||
## [0.16.1] - 2021-04-22
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix checking list rights when accessing a bucket
|
||||
* Remove old deb-structure ci step
|
||||
* Fix docker from
|
||||
|
||||
## [0.16.0] - 2021-01-10
|
||||
|
||||
### Added
|
||||
@ -265,7 +619,7 @@ All releases can be found on https://code.vikunja.io/api/releases.
|
||||
|
||||
## [0.14.0] - 2020-07-01
|
||||
|
||||
### Added
|
||||
### Added
|
||||
|
||||
* Add ability to run the docker container with configurable user and group ids
|
||||
* Add better errors if the sqlite db file is not writable
|
||||
@ -479,7 +833,7 @@ All releases can be found on https://code.vikunja.io/api/releases.
|
||||
|
||||
## [0.12] - 2020-04-04
|
||||
|
||||
#### Added
|
||||
#### Added
|
||||
|
||||
* Add support for archiving lists and namespaces (#152)
|
||||
* Colors for lists and namespaces (#155)
|
||||
@ -503,7 +857,7 @@ All releases can be found on https://code.vikunja.io/api/releases.
|
||||
|
||||
## [0.11] - 2020-03-01
|
||||
|
||||
### Added
|
||||
### Added
|
||||
|
||||
* Add config options for cors handling (#124)
|
||||
* Add config options for task attachments (#125)
|
||||
@ -571,7 +925,7 @@ All releases can be found on https://code.vikunja.io/api/releases.
|
||||
|
||||
## [0.9] - 2019-11-24
|
||||
|
||||
### Added
|
||||
### Added
|
||||
|
||||
* Task Attachments (#104)
|
||||
* Task Relations (#103)
|
||||
@ -584,7 +938,8 @@ All releases can be found on https://code.vikunja.io/api/releases.
|
||||
### Fixed
|
||||
|
||||
* Fix default logging settings (#107)
|
||||
* Fixed a bug where adding assignees or reminders via an update would re-create them and not respect already inserted ones, leaving a lot of garbage
|
||||
* Fixed a bug where adding assignees or reminders via an update would re-create them and not respect already inserted
|
||||
ones, leaving a lot of garbage
|
||||
* Fixed a bug where deleting an attachment would cause a nil panic
|
||||
* Fixed building docs theme
|
||||
* Fixed error when setting max file size on 32-Bit systems
|
||||
@ -597,7 +952,7 @@ All releases can be found on https://code.vikunja.io/api/releases.
|
||||
* Fixed removing reminders
|
||||
* Small link share fixes (#96)
|
||||
|
||||
### Changed
|
||||
### Changed
|
||||
|
||||
* Improve pagination (#105)
|
||||
* Moved `teams_{namespace|list}_*` to `{namespace|list}_teams_*` for better consistency (#101)
|
||||
@ -718,7 +1073,8 @@ All releases can be found on https://code.vikunja.io/api/releases.
|
||||
|
||||
* Updated libraries
|
||||
* Updated drone to version 1
|
||||
* Releases are now signed with our pgp key (more info about this on [the download page](https://vikunja.io/en/download/)).
|
||||
* Releases are now signed with our pgp key (more info about this
|
||||
on [the download page](https://vikunja.io/en/download/)).
|
||||
|
||||
## [0.5] - 2018-12-02
|
||||
|
||||
@ -748,7 +1104,7 @@ All releases can be found on https://code.vikunja.io/api/releases.
|
||||
|
||||
## [0.3] - 2018-11-02
|
||||
|
||||
### Added
|
||||
### Added
|
||||
|
||||
* Password reset
|
||||
* Email verification when registering
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
##############
|
||||
# Build stage
|
||||
FROM golang:1-alpine AS build-env
|
||||
FROM golang:1-alpine3.12 AS build-env
|
||||
|
||||
ARG VIKUNJA_VERSION
|
||||
ENV TAGS "sqlite"
|
||||
@ -17,7 +17,7 @@ WORKDIR ${GOPATH}/src/code.vikunja.io/api
|
||||
# Checkout version if set
|
||||
RUN if [ -n "${VIKUNJA_VERSION}" ]; then git checkout "${VIKUNJA_VERSION}"; fi \
|
||||
&& go install github.com/magefile/mage \
|
||||
&& mage build:clean build:build
|
||||
&& mage build:clean build
|
||||
|
||||
###################
|
||||
# The actual image
|
||||
|
22
README.md
22
README.md
@ -2,10 +2,10 @@
|
||||
|
||||
[](https://drone.kolaente.de/vikunja/api)
|
||||
[](LICENSE)
|
||||
[](https://dl.vikunja.io)
|
||||
[](https://dl.vikunja.io)
|
||||
[](https://hub.docker.com/r/vikunja/api/)
|
||||
[](https://try.vikunja.io/api/v1/docs)
|
||||
[](https://goreportcard.com/report/git.kolaente.de/vikunja/api)
|
||||
[](https://goreportcard.com/report/kolaente.dev/vikunja/api)
|
||||
|
||||
# Vikunja API
|
||||
|
||||
@ -13,17 +13,22 @@
|
||||
|
||||
# Table of contents
|
||||
|
||||
* [Security Reports](#security-reports)
|
||||
* [Features](#features)
|
||||
* [Docs](#docs)
|
||||
* [Roadmap](#roadmap)
|
||||
* [Contributing](#contributing)
|
||||
* [License](#license)
|
||||
|
||||
## Security Reports
|
||||
|
||||
If you find any security-related issues you don't want to disclose publicly, please use [the contact information on our website](https://vikunja.io/contact/#security).
|
||||
|
||||
## Features
|
||||
|
||||
* Create TODO lists with tasks
|
||||
* Reminder for tasks
|
||||
* Namespaces: A "group" which bundels multiple lists
|
||||
* Namespaces: A "group" which bundles multiple lists
|
||||
* Share lists and namespaces with teams and users with granular permissions
|
||||
* Plenty of details for tasks
|
||||
|
||||
@ -35,23 +40,22 @@ try it on [try.vikunja.io](https://try.vikunja.io)!
|
||||
* [Installing](https://vikunja.io/docs/installing/)
|
||||
* [Build from source](https://vikunja.io/docs/build-from-sources/)
|
||||
* [Development setup](https://vikunja.io/docs/development/)
|
||||
* [Magefile](https://vikunja.io/docs/mage/)
|
||||
* [Magefile](https://vikunja.io/docs/magefile/)
|
||||
* [Testing](https://vikunja.io/docs/testing/)
|
||||
|
||||
All docs can be found on [the vikunja home page](https://vikunja.io/docs/).
|
||||
All docs can be found on [the Vikunja home page](https://vikunja.io/docs/).
|
||||
|
||||
### Roadmap
|
||||
|
||||
See [the roadmap](https://my.vikunja.cloud/share/QFyzYEmEYfSyQfTOmIRSwLUpkFjboaBqQCnaPmWd/auth) (hosted on Vikunja!) for more!
|
||||
|
||||
* [ ] [Mobile apps](https://code.vikunja.io/app) (seperate repo) *In Progress*
|
||||
* [ ] [Webapp](https://code.vikunja.io/frontend) (seperate repo) *In Progress*
|
||||
* [ ] [Mobile apps](https://code.vikunja.io/app) (separate repo) *In Progress*
|
||||
* [ ] [Webapp](https://code.vikunja.io/frontend) (separate repo) *In Progress*
|
||||
|
||||
## Contributing
|
||||
|
||||
Fork -> Push -> Pull-Request. Also see the [dev docs](https://vikunja.io/docs/development/) for more infos.
|
||||
Fork -> Push -> Pull-Request. Also see the [dev docs](https://vikunja.io/docs/development/) for more info.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the AGPLv3 License. See the [LICENSE](LICENSE) file for the full license text.
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
systemctl enable vikunja.service
|
||||
|
||||
# Fix the config to contain proper values
|
||||
NEW_SECRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
|
||||
sed -i "s/<jwt-secret>/$NEW_SECRET/g" /etc/vikunja/config.yml
|
||||
|
@ -1,5 +1,5 @@
|
||||
Vikunja is a to-do list application to facilitate your life.
|
||||
Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public Licensee as published by
|
||||
|
@ -3,19 +3,29 @@ service:
|
||||
# Default is a random token which will be generated at each startup of vikunja.
|
||||
# (This means all already issued tokens will be invalid once you restart vikunja)
|
||||
JWTSecret: "<jwt-secret>"
|
||||
# The duration of the issed JWT tokens in seconds.
|
||||
# The default is 259200 seconds (3 Days).
|
||||
jwtttl: 259200
|
||||
# The duration of the "remember me" time in seconds. When the login request is made with
|
||||
# the long param set, the token returned will be valid for this period.
|
||||
# The default is 2592000 seconds (30 Days).
|
||||
jwtttllong: 2592000
|
||||
# The interface on which to run the webserver
|
||||
interface: ":3456"
|
||||
# Path to Unix socket. If set, it will be created and used instead of tcp
|
||||
unixsocket:
|
||||
# Permission bits for the Unix socket. Note that octal values must be prefixed by "0o", e.g. 0o660
|
||||
unixsocketmode:
|
||||
# The URL of the frontend, used to send password reset emails.
|
||||
frontendurl: ""
|
||||
# The base path on the file system where the binary and assets are.
|
||||
# Vikunja will also look in this path for a config file, so you could provide only this variable to point to a folder
|
||||
# with a config file which will then be used.
|
||||
rootpath: <rootpath>
|
||||
# Path on the file system to serve static files from. Set to the path of the frontend files to host frontend alongside the api.
|
||||
staticpath: ""
|
||||
# The max number of items which can be returned per page
|
||||
maxitemsperpage: 50
|
||||
# If set to true, enables a /metrics endpoint for prometheus to collect metrics about the system
|
||||
# You'll need to use redis for this in order to enable common metrics over multiple nodes
|
||||
enablemetrics: false
|
||||
# Enable the caldav endpoint, see the docs for more details
|
||||
enablecaldav: true
|
||||
# Set the motd message, available from the /info endpoint
|
||||
@ -26,7 +36,7 @@ service:
|
||||
enableregistration: true
|
||||
# Whether to enable task attachments or not
|
||||
enabletaskattachments: true
|
||||
# The time zone all timestamps are in
|
||||
# The time zone all timestamps are in. Please note that time zones have to use [the official tz database names](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). UTC or GMT offsets won't work.
|
||||
timezone: GMT
|
||||
# Whether task comments should be enabled or not
|
||||
enabletaskcomments: true
|
||||
@ -42,17 +52,21 @@ service:
|
||||
# If enabled, vikunja will send an email to everyone who is either assigned to a task or created it when a task reminder
|
||||
# is due.
|
||||
enableemailreminders: true
|
||||
# If true, will allow users to request the complete deletion of their account. When using external authentication methods
|
||||
# it may be required to coordinate with them in order to delete the account. This setting will not affect the cli commands
|
||||
# for user deletion.
|
||||
enableuserdeletion: true
|
||||
|
||||
database:
|
||||
# Database type to use. Supported types are mysql, postgres and sqlite.
|
||||
type: "sqlite"
|
||||
# Database user which is used to connect to the database.
|
||||
user: "vikunja"
|
||||
# Databse password
|
||||
# Database password
|
||||
password: ""
|
||||
# Databse host
|
||||
# Database host
|
||||
host: "localhost"
|
||||
# Databse to use
|
||||
# Database to use
|
||||
database: "vikunja"
|
||||
# When using sqlite, this is the path where to store the data
|
||||
path: "./vikunja.db"
|
||||
@ -65,6 +79,14 @@ database:
|
||||
# Secure connection mode. Only used with postgres.
|
||||
# (see https://pkg.go.dev/github.com/lib/pq?tab=doc#hdr-Connection_String_Parameters)
|
||||
sslmode: disable
|
||||
# The path to the client cert. Only used with postgres.
|
||||
sslcert: ""
|
||||
# The path to the client key. Only used with postgres.
|
||||
sslkey: ""
|
||||
# The path to the ca cert. Only used with postgres.
|
||||
sslrootcert: ""
|
||||
# Enable SSL/TLS for mysql connections. Options: false, true, skip-verify, preferred
|
||||
tls: false
|
||||
|
||||
cache:
|
||||
# If cache is enabled or not
|
||||
@ -136,6 +158,10 @@ log:
|
||||
http: "stdout"
|
||||
# Echo has its own logging which usually is unnessecary, which is why it is disabled by default. Possible values are stdout, stderr, file or off to disable standard logging.
|
||||
echo: "off"
|
||||
# Whether or not to log events. Useful for debugging. Possible values are stdout, stderr, file or off to disable events logging.
|
||||
events: "stdout"
|
||||
# The log level for event log messages. Possible values (case-insensitive) are ERROR, INFO, DEBUG.
|
||||
eventslevel: "info"
|
||||
|
||||
ratelimit:
|
||||
# whether or not to enable the rate limit
|
||||
@ -187,7 +213,7 @@ migration:
|
||||
# This is usually the frontend url where the frontend then makes a request to /migration/todoist/migrate
|
||||
# with the code obtained from the todoist api.
|
||||
# Note that the vikunja frontend expects this to be /migrate/todoist
|
||||
redirecturl:
|
||||
redirecturl: <frontend url>/migrate/todoist
|
||||
trello:
|
||||
# Wheter to enable the trello migrator or not
|
||||
enable: false
|
||||
@ -259,10 +285,12 @@ auth:
|
||||
enabled: true
|
||||
# OpenID configuration will allow users to authenticate through a third-party OpenID Connect compatible provider.<br/>
|
||||
# The provider needs to support the `openid`, `profile` and `email` scopes.<br/>
|
||||
# **Note:** The frontend expects to be redirected after authentication by the third party
|
||||
# **Note:** Some openid providers (like gitlab) only make the email of the user available through openid claims if they have set it to be publicly visible.
|
||||
# If the email is not public in those cases, authenticating will fail.
|
||||
# **Note 2:** The frontend expects to be redirected after authentication by the third party
|
||||
# to <frontend-url>/auth/openid/<auth key>. Please make sure to configure the redirect url with your third party
|
||||
# auth service accordingy if you're using the default vikunja frontend.
|
||||
# Take a look at the [default config file](https://kolaente.dev/vikunja/api/src/branch/master/config.yml.sample) for more information about how to configure openid authentication.
|
||||
# Take a look at the [default config file](https://kolaente.dev/vikunja/api/src/branch/main/config.yml.sample) for more information about how to configure openid authentication.
|
||||
openid:
|
||||
# Enable or disable OpenID Connect authentication
|
||||
enabled: false
|
||||
@ -279,3 +307,12 @@ auth:
|
||||
clientid:
|
||||
# The client secret used to authenticate Vikunja at the OpenID Connect provider.
|
||||
clientsecret:
|
||||
|
||||
# Prometheus metrics endpoint
|
||||
metrics:
|
||||
# If set to true, enables a /metrics endpoint for prometheus to collect metrics about Vikunja.
|
||||
enabled: false
|
||||
# If set to a non-empty value the /metrics endpoint will require this as a username via basic auth in combination with the password below.
|
||||
username:
|
||||
# If set to a non-empty value the /metrics endpoint will require this as a password via basic auth in combination with the username below.
|
||||
password:
|
||||
|
17
docker-manifest-unstable.tmpl
Normal file
17
docker-manifest-unstable.tmpl
Normal file
@ -0,0 +1,17 @@
|
||||
image: vikunja/api:unstable
|
||||
manifests:
|
||||
-
|
||||
image: vikunja/api:unstable-linux-amd64
|
||||
platform:
|
||||
architecture: amd64
|
||||
os: linux
|
||||
-
|
||||
image: vikunja/api:unstable-linux-arm64
|
||||
platform:
|
||||
architecture: arm64
|
||||
os: linux
|
||||
-
|
||||
image: vikunja/api:unstable-linux-arm
|
||||
platform:
|
||||
architecture: arm
|
||||
os: linux
|
@ -11,6 +11,11 @@ manifests:
|
||||
platform:
|
||||
architecture: amd64
|
||||
os: linux
|
||||
-
|
||||
image: vikunja/api:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm64
|
||||
platform:
|
||||
architecture: arm64
|
||||
os: linux
|
||||
-
|
||||
image: vikunja/api:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}linux-arm
|
||||
platform:
|
||||
|
@ -2,7 +2,7 @@ baseurl: https://vikunja.io/docs/
|
||||
title: Vikunja
|
||||
theme: vikunja
|
||||
enableRobotsTXT: true
|
||||
canonifyURLs: true
|
||||
canonifyURLs: false
|
||||
|
||||
pygmentsUseClasses: true
|
||||
|
||||
@ -31,10 +31,10 @@ menu:
|
||||
url: https://vikunja.io/en/
|
||||
weight: 10
|
||||
- name: Features
|
||||
url: https://vikunja.io/en/features
|
||||
url: https://vikunja.io/features
|
||||
weight: 20
|
||||
- name: Download
|
||||
url: https://vikunja.io/en/download
|
||||
url: https://vikunja.io/download
|
||||
weight: 30
|
||||
- name: Docs
|
||||
url: https://vikunja.io/docs
|
||||
@ -45,3 +45,6 @@ menu:
|
||||
- name: Community
|
||||
url: https://community.vikunja.io/
|
||||
weight: 60
|
||||
- name: Get it Hosted
|
||||
url: https://vikunja.cloud/?utm_source=io&utm_medium=io&utm_campaign=menu
|
||||
weight: 70
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
date: "2019-03-31:00:00+01:00"
|
||||
title: "Adding new cli commands"
|
||||
title: "Cli Commands"
|
||||
draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
|
41
docs/content/doc/development/config.md
Normal file
41
docs/content/doc/development/config.md
Normal file
@ -0,0 +1,41 @@
|
||||
---
|
||||
date: "2019-02-12:00:00+02:00"
|
||||
title: "Configuration Options"
|
||||
draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "development"
|
||||
---
|
||||
|
||||
# Configuration options
|
||||
|
||||
All configuration variables are declared in the `config` package.
|
||||
It uses [viper](https://github.com/spf13/viper) under the hood to handle setting defaults and parsing config files.
|
||||
Viper handles parsing all different configuration sources.
|
||||
|
||||
## Adding new config options
|
||||
|
||||
To make handling configuration parameters a bit easier, we introduced a `Key` string type in the `config` package which
|
||||
you can call directly to get a config value.
|
||||
|
||||
To add a new config option, you should add a new key const to `pkg/config/config.go` and possibly a default value.
|
||||
Default values should always enable the feature to work or turn it off completely if it always needs
|
||||
additional configuration.
|
||||
|
||||
Make sure to also add the new config option to the default config file (`config.yml.sample` at the root of the repository)
|
||||
with an explanatory comment to make sure it is well documented.
|
||||
Then run `mage generate-docs` to generate the configuration docs from the sample file.
|
||||
|
||||
## Getting Configuration Values
|
||||
|
||||
To retreive a configured value call the key with a getter for the type you need.
|
||||
For example:
|
||||
|
||||
{{< highlight golang >}}
|
||||
if config.CacheEnabled.GetBool() {
|
||||
// Do something with enabled caches
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
Take a look at the methods declared on the type to see what's available.
|
35
docs/content/doc/development/cron.md
Normal file
35
docs/content/doc/development/cron.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
title: "Cron Tasks"
|
||||
date: 2021-07-13T23:21:52+02:00
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "development"
|
||||
---
|
||||
|
||||
# How to add a cron job task
|
||||
|
||||
Cron jobs are tasks which run on a predefined schedule.
|
||||
Vikunja uses these through a light wrapper package around the excellent [github.com/robfig/cron](https://github.com/robfig/cron) package.
|
||||
|
||||
The package exposes a `cron.Schedule` method with two arguments: The first one to define the schedule when the cron task
|
||||
should run, and the second one with the actual function to run at the schedule.
|
||||
You would then create a new function to register your the actual cron task in your package.
|
||||
|
||||
A basic function to register a cron task looks like this:
|
||||
|
||||
{{< highlight golang >}}
|
||||
func RegisterSomeCronTask() {
|
||||
err := cron.Schedule("0 * * * *", func() {
|
||||
// Do something every hour
|
||||
}
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
Call the register method in the `FullInit()` method of the `init` package to actually register it.
|
||||
|
||||
## Schedule Syntax
|
||||
|
||||
The cron syntax uses the same on you may know from unix systems.
|
||||
|
||||
It is described in detail [here](https://pkg.go.dev/github.com/robfig/cron#hdr-CRON_Expression_Format).
|
40
docs/content/doc/development/database.md
Normal file
40
docs/content/doc/development/database.md
Normal file
@ -0,0 +1,40 @@
|
||||
---
|
||||
date: "2019-02-12:00:00+02:00"
|
||||
title: "Database"
|
||||
draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "development"
|
||||
---
|
||||
|
||||
# Database
|
||||
|
||||
Vikunja uses [xorm](https://xorm.io/) as an abstraction layer to handle the database connection.
|
||||
Please refer to [their](https://xorm.io/docs/) documentation on how to exactly use it.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## Using the database
|
||||
|
||||
When using the common web handlers, you get an `xorm.Session` to do database manipulations.
|
||||
In other packages, use the `db.NewSession()` method to get a new database session.
|
||||
|
||||
## Adding new database tables
|
||||
|
||||
To add a new table to the database, create the struct and [add a migration for it]({{< ref "db-migrations.md" >}}).
|
||||
|
||||
To learn more about how to configure your struct to create "good" tables, refer to [the xorm documentaion](https://xorm.io/docs/).
|
||||
|
||||
In most cases you will also need to implement the `TableName() string` method on the new struct to make sure the table
|
||||
name matches the rest of the tables - plural.
|
||||
|
||||
## Adding data to test fixtures
|
||||
|
||||
Adding data for test fixtures can be done via `yaml` files in `pkg/models/fixtures`.
|
||||
|
||||
The name of the yaml file should match the table name in the database.
|
||||
Adding values to it is done via array definition inside it.
|
||||
|
||||
**Note**: Table and column names need to be in snake_case as that's what is used internally in the database
|
||||
and for mapping values from the database to xorm so your structs can use it.
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
date: "2019-03-29:00:00+02:00"
|
||||
title: "Database migrations"
|
||||
title: "Database Migrations"
|
||||
draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
@ -37,6 +37,11 @@ All migrations are sorted before being executed, since `init()` does not guarant
|
||||
When you're adding a new struct, you also need to add it to the `models.GetTables()` function
|
||||
to ensure it will be created on new installations.
|
||||
|
||||
### Generating a new migration stub
|
||||
|
||||
You can easily generate a pre-filled migration stub by running `mage dev:make-migration`.
|
||||
It will ask you for a table name and generate an empty migration similar to the example shown below.
|
||||
|
||||
### Example
|
||||
|
||||
{{< highlight golang >}}
|
||||
|
@ -12,56 +12,45 @@ menu:
|
||||
|
||||
# Development
|
||||
|
||||
We use go modules to vendor libraries for Vikunja, so you'll need at least go `1.11` to use these.
|
||||
If you don't intend to add new dependencies, go `1.9` and above should be fine.
|
||||
{{< table_of_contents >}}
|
||||
|
||||
To contribute to Vikunja, fork the project and work on the master branch.
|
||||
## General
|
||||
|
||||
To contribute to Vikunja, fork the project and work on the main branch.
|
||||
Once you feel like your changes are ready, open a PR in the respective repo.
|
||||
A maintainer will take a look and give you feedback. Once everyone is happy, the PR gets merged and released.
|
||||
|
||||
If you plan to do a bigger change, it is better to open an issue for discussion first.
|
||||
|
||||
## API
|
||||
|
||||
The code for the api is located at [code.vikunja.io/api](https://code.vikunja.io/api).
|
||||
|
||||
We use go modules to manage third-party libraries for Vikunja, so you'll need at least go `1.17` to use these.
|
||||
|
||||
A lot of developing tasks are automated using a Magefile, so make sure to [take a look at it]({{< ref "mage.md">}}).
|
||||
|
||||
{{< table_of_contents >}}
|
||||
Make sure to check the other doc articles for specific development tasks like [testing]({{< ref "test.md">}}),
|
||||
[database migrations]({{< ref "db-migrations.md" >}}) and the [project structure]({{< ref "structure.md" >}}).
|
||||
|
||||
## Libraries
|
||||
## Frontend requirements
|
||||
|
||||
We keep all libraries used for Vikunja around in the `vendor/` folder to still be able to build the project even if
|
||||
some maintainers take their libraries down like [it happened in the past](https://github.com/jteeuwen/go-bindata/issues/5).
|
||||
The code for the frontend is located at [code.vikunja.io/frontend](https://code.vikunja.io/frontend).
|
||||
|
||||
## Tests
|
||||
You need to have yarn v1 and nodejs in version 16 installed.
|
||||
|
||||
See [testing]({{< ref "test.md">}}).
|
||||
## Git flow
|
||||
|
||||
#### Development using go modules
|
||||
The `main` branch is the latest and bleeding edge branch with all changes. Unstable releases are automatically
|
||||
created from this branch.
|
||||
|
||||
If you're able to use go modules, you can clone the project wherever you want to and work from there.
|
||||
A release gets tagged from the main branch with the version name as tag name.
|
||||
|
||||
#### Development-setup without go modules
|
||||
Backports and point-releases should go to a `release/version` branch, based on the tag they are building on top of.
|
||||
|
||||
Some internal packages are referenced using their respective package URL. This can become problematic.
|
||||
To “trick” the Go tool into thinking this is a clone from the official repository, download the source code
|
||||
into `$GOPATH/code.vikunja.io/api`. Fork the Vikunja repository, it should then be possible to switch the source directory on the command line.
|
||||
## Conventional commits
|
||||
|
||||
{{< highlight bash >}}
|
||||
cd $GOPATH/src/code.vikunja.io/api
|
||||
{{< /highlight >}}
|
||||
We're using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) because they greatly simplify
|
||||
generating release notes.
|
||||
|
||||
To be able to create pull requests, the forked repository should be added as a remote to the Vikunja sources, otherwise changes can’t be pushed.
|
||||
|
||||
{{< highlight bash >}}
|
||||
git remote rename origin upstream
|
||||
git remote add origin git@git.kolaente.de:<USERNAME>/api.git
|
||||
git fetch --all --prune
|
||||
{{< /highlight >}}
|
||||
|
||||
This should provide a working development environment for Vikunja. Take a look at the Magefile to get an overview about
|
||||
the available tasks. The most common tasks should be `mage test:unit` which will start our test environment and `mage build:build`
|
||||
which will build a vikunja binary into the working directory. Writing test cases is not mandatory to contribute, but it
|
||||
is highly encouraged and helps developers sleep at night.
|
||||
|
||||
That’s it! You are ready to hack on Vikunja. Test changes, push them to the repository, and open a pull request.
|
||||
|
||||
## Static assets
|
||||
|
||||
Each Vikunja release contains all static assets directly compiled into the binary.
|
||||
To prevent this during development, use the `dev` tag when developing.
|
||||
|
||||
See the [mage docs](mage.md#statically-compile-all-templates-into-the-binary) about how to compile with static assets for a release.
|
||||
It is not required to use them when creating a PR, but appreciated.
|
||||
|
@ -5,7 +5,7 @@ draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "practical instructions"
|
||||
parent: "development"
|
||||
---
|
||||
|
||||
# Custom Errors
|
211
docs/content/doc/development/events-and-listeners.md
Normal file
211
docs/content/doc/development/events-and-listeners.md
Normal file
@ -0,0 +1,211 @@
|
||||
---
|
||||
date: 2018-10-13T19:26:34+02:00
|
||||
title: "Events and Listeners"
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "development"
|
||||
---
|
||||
|
||||
# Events and Listeners
|
||||
|
||||
Vikunja provides a simple observer pattern mechanism through events and listeners.
|
||||
The basic principle of events is always the same: Something happens (=An event is fired) and something reacts to it (=A listener is called).
|
||||
|
||||
Vikunja supports this principle through the `events` package.
|
||||
It is built upon the excellent [watermill](https://watermill.io) library.
|
||||
|
||||
Currently, it only supports dispatching events through Go Channels which makes it configuration-less.
|
||||
More methods of dispatching events (like kafka or rabbitmq) are available in watermill and could be enabled with a PR.
|
||||
|
||||
This document explains how events and listeners work in Vikunja, how to use them and how to create new ones.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## Events
|
||||
|
||||
### Definition
|
||||
|
||||
Each event has to implement this interface:
|
||||
|
||||
{{< highlight golang >}}
|
||||
type Event interface {
|
||||
Name() string
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
An event can contain whatever data you need.
|
||||
|
||||
When an event is dispatched, all of the data it contains will be marshaled into json for dispatching.
|
||||
You then get the event with all its data back in the listener, see below.
|
||||
|
||||
#### Naming Convention
|
||||
|
||||
Event names should roughly have the entity they're dealing with on the left and the action on the right of the name, separated by `.`.
|
||||
There's no limit to how "deep" or specifig an event name can be.
|
||||
|
||||
The name should have the most general concept it's describing at the left, getting more specific on the right of it.
|
||||
|
||||
#### Location
|
||||
|
||||
All events for a package should be declared in the `events.go` file of that package.
|
||||
|
||||
### Creating a New Event
|
||||
|
||||
The easiest way to create a new event is to generate it with mage:
|
||||
|
||||
```
|
||||
mage dev:make-event <event-name> <package>
|
||||
```
|
||||
|
||||
The function takes the name of the event as the first argument and the package where the event should be created as the second argument.
|
||||
Events will be appended to the `pkg/<module>/events.go` file.
|
||||
Both parameters are mandatory.
|
||||
|
||||
The event type name is automatically camel-cased and gets the `Event` suffix if the provided name does not already have one.
|
||||
The event name is derived from the type name and stripped of the `.event` suffix.
|
||||
|
||||
The generated event will look something like the example below.
|
||||
|
||||
### Dispatching events
|
||||
|
||||
To dispatch an event, simply call the `events.Dispatch` method and pass in the event as parameter.
|
||||
|
||||
### Example
|
||||
|
||||
The `TaskCreatedEvent` is declared in the `pkg/models/events.go` file as follows:
|
||||
|
||||
{{< highlight golang >}}
|
||||
// TaskCreatedEvent represents an event where a task has been created
|
||||
type TaskCreatedEvent struct {
|
||||
Task *Task
|
||||
Doer web.Auth
|
||||
}
|
||||
|
||||
// Name defines the name for TaskCreatedEvent
|
||||
func (t *TaskCreatedEvent) Name() string {
|
||||
return "task.created"
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
It is dispatched in the `createTask` function of the `models` package:
|
||||
|
||||
{{< highlight golang >}}
|
||||
func createTask(s *xorm.Session, t *Task, a web.Auth, updateAssignees bool) (err error) {
|
||||
|
||||
// ...
|
||||
|
||||
err = events.Dispatch(&TaskCreatedEvent{
|
||||
Task: t,
|
||||
Doer: a,
|
||||
})
|
||||
|
||||
// ...
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
As you can see, the curent task and doer are injected into it.
|
||||
|
||||
### Special Events
|
||||
|
||||
#### `BootedEvent`
|
||||
|
||||
Once Vikunja is fully initialized, right before the api web server is started, this event is fired.
|
||||
|
||||
## Listeners
|
||||
|
||||
A listener is a piece of code that gets executed asynchronously when an event is dispatched.
|
||||
|
||||
A single event can have multiple listeners who are independent of each other.
|
||||
|
||||
### Definition
|
||||
|
||||
All listeners must implement this interface:
|
||||
|
||||
{{< highlight golang >}}
|
||||
// Listener represents something that listens to events
|
||||
type Listener interface {
|
||||
Handle(msg *message.Message) error
|
||||
Name() string
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
The `Handle` method is executed when the event this listener listens on is dispatched.
|
||||
* As the single parameter, it gets the payload of the event, which is the event struct when it was dispatched decoded as json object and passed as a slice of bytes.
|
||||
To use it you'll need to unmarshal it. Unfortunately there's no way to pass an already populated event object to the function because we would not know what type it has when parsing it.
|
||||
* If the handler returns an error, the listener is retried 5 times, with an exponentional back-off period in between retries.
|
||||
If it still fails after the fifth retry, the event is nack'd and it's up to the event dispatcher to resend it.
|
||||
You can learn more about this mechanism in the [watermill documentation](https://watermill.io/docs/middlewares/#retry).
|
||||
|
||||
The `Name` method needs to return a unique listener name for this listener.
|
||||
It should follow the same convention as event names, see above.
|
||||
|
||||
### Creating a New Listener
|
||||
|
||||
The easiest way to create a new listener for an event is with mage:
|
||||
|
||||
```
|
||||
mage dev:make-listener <listener-name> <event-name> <package>
|
||||
```
|
||||
|
||||
This will create a new listener type in the `pkg/<package>/listners.go` file and implement the `Handle` and `Name` methods.
|
||||
It will also pre-generate some boilerplate code to unmarshal the event from the payload.
|
||||
|
||||
Furthermore, it will register the listener for its event in the `RegisterListeners()` method of the same file.
|
||||
This function is called at startup and has to contain all events you want to listen for.
|
||||
|
||||
### Listening for Events
|
||||
|
||||
To listen for an event, you need to register the listener for the event it should be called for.
|
||||
This usually happens in the `RegisterListeners()` method in `pkg/<package>/listners.go` which is called at start up.
|
||||
|
||||
The listener will never be executed if it hasn't been registered.
|
||||
|
||||
See the example below.
|
||||
|
||||
### Example
|
||||
|
||||
{{< highlight golang >}}
|
||||
// RegisterListeners registers all event listeners
|
||||
func RegisterListeners() {
|
||||
events.RegisterListener((&ListCreatedEvent{}).Name(), &IncreaseListCounter{})
|
||||
}
|
||||
|
||||
// IncreaseTaskCounter represents a listener
|
||||
type IncreaseTaskCounter struct {}
|
||||
|
||||
// Name defines the name for the IncreaseTaskCounter listener
|
||||
func (s *IncreaseTaskCounter) Name() string {
|
||||
return "task.counter.increase"
|
||||
}
|
||||
|
||||
// Hanlde is executed when the event IncreaseTaskCounter listens on is fired
|
||||
func (s *IncreaseTaskCounter) Handle(payload message.Payload) (err error) {
|
||||
return keyvalue.IncrBy(metrics.TaskCountKey, 1)
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
## Testing
|
||||
|
||||
When testing, you should call the `events.Fake()` method in the `TestMain` function of the package you want to test.
|
||||
This prevents any events from being fired and lets you assert an event has been dispatched like so:
|
||||
|
||||
{{< highlight golang >}}
|
||||
events.AssertDispatched(t, &TaskCreatedEvent{})
|
||||
{{< /highlight >}}
|
||||
|
||||
### Testing a listener
|
||||
|
||||
You can call an event listener manually with the `events.TestListener` method like so:
|
||||
|
||||
{{< highlight golang >}}
|
||||
ev := &TaskCommentCreatedEvent{
|
||||
Task: &task,
|
||||
Doer: u,
|
||||
Comment: tc,
|
||||
}
|
||||
|
||||
events.TestListener(t, ev, &SendTaskCommentNotification{})
|
||||
{{< /highlight >}}
|
||||
|
||||
This will call the listener's `Handle` method and assert it did not return an error when calling.
|
@ -1,11 +1,11 @@
|
||||
---
|
||||
date: "2019-02-12:00:00+02:00"
|
||||
title: "Add a new api endpoint"
|
||||
title: "New API Endpoints"
|
||||
draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "practical instructions"
|
||||
parent: "development"
|
||||
---
|
||||
|
||||
# Add a new api endpoint/feature
|
@ -11,9 +11,9 @@ menu:
|
||||
# Mage
|
||||
|
||||
Vikunja uses [Mage](https://magefile.org/) to script common development tasks and even releasing.
|
||||
Mage is a pure go solution which allows for greater flexibility and things like better paralelization.
|
||||
Mage is a pure go solution which allows for greater flexibility and things like better parallelization.
|
||||
|
||||
This document explains what taks are available and what they do.
|
||||
This document explains what tasks are available and what they do.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
@ -39,7 +39,7 @@ There are multiple categories of subcommands in the magefile:
|
||||
|
||||
## CI
|
||||
|
||||
These tasks are automatically run in our CI every time someone pushes to master or you update a pull request:
|
||||
These tasks are automatically run in our CI every time someone pushes to main or you update a pull request:
|
||||
|
||||
* `mage check:lint`
|
||||
* `mage check:fmt`
|
||||
@ -57,15 +57,13 @@ These tasks are automatically run in our CI every time someone pushes to master
|
||||
mage build:build
|
||||
{{< /highlight >}}
|
||||
|
||||
Builds a `vikunja`-binary in the root directory of the repo for the platform it is run on.
|
||||
|
||||
### Statically compile all templates into the binary
|
||||
or
|
||||
|
||||
{{< highlight bash >}}
|
||||
mage build:generate
|
||||
mage build
|
||||
{{< /highlight >}}
|
||||
|
||||
This generates static code with all templates, meaning no template need to be referenced at runtime.
|
||||
Builds a `vikunja`-binary in the root directory of the repo for the platform it is run on.
|
||||
|
||||
### clean
|
||||
|
||||
@ -73,7 +71,7 @@ This generates static code with all templates, meaning no template need to be re
|
||||
mage build:clean
|
||||
{{< /highlight >}}
|
||||
|
||||
Cleans all build, executable and bindata files
|
||||
Cleans all build and executable files
|
||||
|
||||
## Check
|
||||
|
||||
@ -173,6 +171,8 @@ mage dev:create-migration
|
||||
Creates a new migration with the current date.
|
||||
Will ask for the name of the struct you want to create a migration for.
|
||||
|
||||
See also [migration docs]({{< ref "mage.md" >}}).
|
||||
|
||||
## Misc
|
||||
|
||||
### Format the code
|
||||
|
@ -5,7 +5,7 @@ draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "practical instructions"
|
||||
parent: "development"
|
||||
---
|
||||
|
||||
# Metrics
|
||||
@ -17,7 +17,7 @@ The `metrics` package provides several functions to create and update metrics.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## New metrics
|
||||
## Exposing New Metrics
|
||||
|
||||
First, define a `const` with the metric key in redis. This is done in `pkg/metrics/metrics.go`.
|
||||
|
@ -14,7 +14,17 @@ It is possible to migrate data from other to-do services to Vikunja.
|
||||
To make this easier, we have put together a few helpers which are documented on this page.
|
||||
|
||||
In general, each migrator implements a migrator interface which is then called from a client.
|
||||
The interface makes it possible to use helper methods which handle http an focus only on the implementation of the migrator itself.
|
||||
The interface makes it possible to use helper methods which handle http and focus only on the implementation of the migrator itself.
|
||||
|
||||
There are two ways of migrating data from another service:
|
||||
1. Through the auth-based flow where the user gives you access to their data at the third-party service through an
|
||||
oauth flow. You can then call the service's api on behalf of your user to get all the data.
|
||||
The Todoist, Trello and Microsoft To-Do Migrators use this pattern.
|
||||
2. A file migration where the user uploads a file obtained from some third-party service. In your migrator, you need
|
||||
to parse the file and create the lists, tasks etc.
|
||||
The Vikunja File Import uses this pattern.
|
||||
|
||||
To differentiate the two, there are two different interfaces you must implement.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
@ -23,13 +33,16 @@ The interface makes it possible to use helper methods which handle http an focus
|
||||
All migrator implementations live in their own package in `pkg/modules/migration/<name-of-the-service>`.
|
||||
When creating a new migrator, you should place all related code inside that module.
|
||||
|
||||
## Migrator interface
|
||||
## Migrator Interface
|
||||
|
||||
The migrator interface is defined as follows:
|
||||
|
||||
```go
|
||||
// Migrator is the basic migrator interface which is shared among all migrators
|
||||
type Migrator interface {
|
||||
// Name holds the name of the migration.
|
||||
// This is used to show the name to users and to keep track of users who already migrated.
|
||||
Name() string
|
||||
// Migrate is the interface used to migrate a user's tasks from another platform to vikunja.
|
||||
// The user object is the user who's tasks will be migrated.
|
||||
Migrate(user *models.User) error
|
||||
@ -37,9 +50,20 @@ type Migrator interface {
|
||||
// The use case for this are Oauth flows, where the server token should remain hidden and not
|
||||
// known to the frontend.
|
||||
AuthURL() string
|
||||
}
|
||||
```
|
||||
|
||||
## File Migrator Interface
|
||||
|
||||
```go
|
||||
// FileMigrator handles importing Vikunja data from a file. The implementation of it determines the format.
|
||||
type FileMigrator interface {
|
||||
// Name holds the name of the migration.
|
||||
// This is used to show the name to users and to keep track of users who already migrated.
|
||||
Name() string
|
||||
// Migrate is the interface used to migrate a user's tasks, list and other things from a file to vikunja.
|
||||
// The user object is the user who's tasks will be migrated.
|
||||
Migrate(user *user.User, file io.ReaderAt, size int64) error
|
||||
}
|
||||
```
|
||||
|
||||
@ -54,23 +78,35 @@ authUrl, Status and Migrate methods.
|
||||
```go
|
||||
// This is an example for the Wunderlist migrator
|
||||
if config.MigrationWunderlistEnable.GetBool() {
|
||||
wunderlistMigrationHandler := &migrationHandler.MigrationWeb{
|
||||
wunderlistMigrationHandler := &migrationHandler.MigrationWeb{
|
||||
MigrationStruct: func() migration.Migrator {
|
||||
return &wunderlist.Migration{}
|
||||
},
|
||||
}
|
||||
wunderlistMigrationHandler.RegisterRoutes(m)
|
||||
wunderlistMigrationHandler.RegisterRoutes(m)
|
||||
}
|
||||
```
|
||||
|
||||
You should also document the routes with [swagger annotations]({{< ref "../practical-instructions/swagger-docs.md" >}}).
|
||||
And for the file migrator:
|
||||
|
||||
```go
|
||||
vikunjaFileMigrationHandler := &migrationHandler.FileMigratorWeb{
|
||||
MigrationStruct: func() migration.FileMigrator {
|
||||
return &vikunja_file.FileMigrator{}
|
||||
},
|
||||
}
|
||||
vikunjaFileMigrationHandler.RegisterRoutes(m)
|
||||
```
|
||||
|
||||
You should also document the routes with [swagger annotations]({{< ref "swagger-docs.md" >}}).
|
||||
|
||||
## Insertion helper method
|
||||
|
||||
There is a method available in the `migration` package which takes a fully nested Vikunja structure and creates it with all relations.
|
||||
This means you start by adding a namespace, then add lists inside of that namespace, then tasks in the lists and so on.
|
||||
|
||||
The root structure must be present as `[]*models.NamespaceWithLists`.
|
||||
The root structure must be present as `[]*models.NamespaceWithListsAndTasks`. It allows to represent all of Vikunja's
|
||||
hierachie as a single data structure.
|
||||
|
||||
Then call the method like so:
|
||||
|
||||
@ -85,14 +121,16 @@ err = migration.InsertFromStructure(fullVikunjaHierachie, user)
|
||||
|
||||
## Configuration
|
||||
|
||||
You should add at least an option to enable or disable the migration.
|
||||
If your migrator is an oauth-based one, you should add at least an option to enable or disable it.
|
||||
Chances are, you'll need some more options for things like client ID and secret
|
||||
(if the other service uses oAuth as an authentication flow).
|
||||
|
||||
The easiest way to implement an on/off switch is to check whether your migration service is enabled or not when
|
||||
registering the routes, and then simply don't registering the routes in the case it is disabled.
|
||||
registering the routes, and then simply don't registering the routes in case it is disabled.
|
||||
|
||||
File based migrators can always be enabled.
|
||||
|
||||
### Making the migrator public in `/info`
|
||||
|
||||
You should make your migrator available in the `/info` endpoint so that frontends can display options to enable them or not.
|
||||
To do this, add an entry to `pkg/routes/api/v1/info.go`.
|
||||
To do this, add an entry to the `AvailableMigrators` field in `pkg/routes/api/v1/info.go`.
|
||||
|
120
docs/content/doc/development/notifications.md
Normal file
120
docs/content/doc/development/notifications.md
Normal file
@ -0,0 +1,120 @@
|
||||
---
|
||||
date: 2021-02-07T19:26:34+02:00
|
||||
title: "Notifications"
|
||||
toc: true
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "development"
|
||||
---
|
||||
|
||||
# Notifications
|
||||
|
||||
Vikunjs provides a simple abstraction to send notifications per mail and in the database.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## Definition
|
||||
|
||||
Each notification has to implement this interface:
|
||||
|
||||
{{< highlight golang >}}
|
||||
type Notification interface {
|
||||
ToMail() *Mail
|
||||
ToDB() interface{}
|
||||
Name() string
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
Both functions return the formatted messages for mail and database.
|
||||
|
||||
A notification will only be sent or recorded for those of the two methods which don't return `nil`.
|
||||
For example, if your notification should not be recorded in the database but only sent out per mail, it is enough to let the `ToDB` function return `nil`.
|
||||
|
||||
### Mail notifications
|
||||
|
||||
A list of chainable functions is available to compose a mail:
|
||||
|
||||
{{< highlight golang >}}
|
||||
mail := NewMail().
|
||||
// The optional sender of the mail message.
|
||||
From("test@example.com").
|
||||
// The optional receipient of the mail message. Uses the mail address of the notifiable if omitted.
|
||||
To("test@otherdomain.com").
|
||||
// The subject of the mail to send.
|
||||
Subject("Testmail").
|
||||
// The greeting, or "intro" line of the mail.
|
||||
Greeting("Hi there,").
|
||||
// A line of text
|
||||
Line("This is a line of text").
|
||||
// An action can contain a title and a url. It gets rendered as a big button in the mail.
|
||||
// Note that you can have only one action per mail.
|
||||
// All lines added before an action will appearr in the mail before the button, all lines
|
||||
// added afterwards will appear after it.
|
||||
Action("The Action", "https://example.com").
|
||||
// Another line of text.
|
||||
Line("This should be an outro line").
|
||||
{{< /highlight >}}
|
||||
|
||||
If not provided, the `from` field of the mail contains the value configured in [`mailer.fromemail`](https://vikunja.io/docs/config-options/#fromemail).
|
||||
|
||||
### Database notifications
|
||||
|
||||
All data returned from the `ToDB()` method is serialized to json and saved into the database, along with the id of the
|
||||
notifiable, the name of the notification and a time stamp.
|
||||
If you don't use the database notification, the `Name()` function can return an empty string.
|
||||
|
||||
## Creating a new notification
|
||||
|
||||
The easiest way to generate a mail is by using the `mage dev:make-notification` command.
|
||||
|
||||
It takes the name of the notification and the package where the notification will be created.
|
||||
|
||||
## Notifiables
|
||||
|
||||
Notifiables can receive a notification.
|
||||
A notifiable is defined with this interface:
|
||||
|
||||
{{< highlight golang >}}
|
||||
type Notifiable interface {
|
||||
// Should return the email address this notifiable has.
|
||||
RouteForMail() string
|
||||
// Should return the id of the notifiable entity
|
||||
RouteForDB() int64
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
The `User` type from the `user` package implements this interface.
|
||||
|
||||
## Sending a notification
|
||||
|
||||
Sending a notification is done with the `Notify` method from the `notifications` package.
|
||||
It takes a notifiable and a notification as input.
|
||||
|
||||
For example, the email confirm notification when a new user registers is sent like this:
|
||||
|
||||
{{< highlight golang >}}
|
||||
n := &EmailConfirmNotification{
|
||||
User: update.User,
|
||||
IsNew: false,
|
||||
}
|
||||
|
||||
err = notifications.Notify(update.User, n)
|
||||
return
|
||||
{{< /highlight >}}
|
||||
|
||||
## Testing
|
||||
|
||||
The `mail` package provides a `Fake()` method which you should call in the `MainTest` functions of your package.
|
||||
If it was called, no mails are being sent and you can instead assert they have been sent with the `AssertSent` method.
|
||||
|
||||
When testing, you should call the `notifications.Fake()` method in the `TestMain` function of the package you want to test.
|
||||
This prevents any notifications from being sent and lets you assert a notifications has been sent like this:
|
||||
|
||||
{{< highlight golang >}}
|
||||
notifications.AssertSent(t, &ReminderDueNotification{})
|
||||
{{< /highlight >}}
|
||||
|
||||
## Example
|
||||
|
||||
Take a look at the [pkg/user/notifications.go](https://code.vikunja.io/api/src/branch/main/pkg/user/notifications.go) file for a good example.
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
date: "2019-02-12:00:00+02:00"
|
||||
title: "Project structure"
|
||||
title: "Project Structure"
|
||||
draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
@ -10,40 +10,7 @@ menu:
|
||||
|
||||
# Project structure
|
||||
|
||||
In general, this api repo has the following structure:
|
||||
|
||||
* `docker`
|
||||
* `docs`
|
||||
* `pkg`
|
||||
* `caldav`
|
||||
* `cmd`
|
||||
* `config`
|
||||
* `db`
|
||||
* `fixtures`
|
||||
* `files`
|
||||
* `integration`
|
||||
* `log`
|
||||
* `mail`
|
||||
* `metrics`
|
||||
* `migration`
|
||||
* `models`
|
||||
* `modules`
|
||||
* `migration`
|
||||
* `handler`
|
||||
* `wunderlist`
|
||||
* `red`
|
||||
* `routes`
|
||||
* `api/v1`
|
||||
* `static`
|
||||
* `swagger`
|
||||
* `user`
|
||||
* `utils`
|
||||
* `version`
|
||||
* `REST-Tests`
|
||||
* `templates`
|
||||
* `vendor`
|
||||
|
||||
This document will explain what these mean and what you can find where.
|
||||
This document explains what each package does.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
@ -52,18 +19,13 @@ This document will explain what these mean and what you can find where.
|
||||
The root directory is where [the config file]({{< ref "../setup/config.md">}}), [Magefile]({{< ref "mage.md">}}), license, drone config,
|
||||
application entry point (`main.go`) and so on are located.
|
||||
|
||||
## docker
|
||||
|
||||
This directory holds additonal files needed to build and run the docker container, mainly service configuration to properly run Vikunja inside a docker
|
||||
container.
|
||||
|
||||
## pkg
|
||||
|
||||
This is where most of the magic happens. Most packages with actual code are located in this folder.
|
||||
|
||||
### caldav
|
||||
|
||||
This folder holds a simple caldav implementation which is responsible for returning the caldav feature.
|
||||
This folder holds a simple caldav implementation which is responsible for the caldav feature.
|
||||
|
||||
### cmd
|
||||
|
||||
@ -75,10 +37,15 @@ To learn more about how to use this cli, see [the cli usage docs]({{< ref "../us
|
||||
|
||||
### config
|
||||
|
||||
This package configures the config. It sets default values and sets up viper and tells it where to look for config files,
|
||||
how to interpret which env variables for config etc.
|
||||
This package configures handling of Vikunja's runtime configuration.
|
||||
It sets default values and sets up viper and tells it where to look for config files, how to interpret which env variables
|
||||
for config etc.
|
||||
|
||||
If you want to add a new config parameter, you should add default value in this package.
|
||||
See also the [docs about adding a new configuration parameter]({{< ref "config.md" >}}).
|
||||
|
||||
### cron
|
||||
|
||||
See [how to add a cron task]({{< ref "cron.md" >}}).
|
||||
|
||||
### db
|
||||
|
||||
@ -102,17 +69,17 @@ This init is called in `main.go` after the config init is done.
|
||||
|
||||
### mail
|
||||
|
||||
This package handles all mail sending. To learn how to send a mail, see [sending emails]({{< ref "../practical-instructions/mail.md">}}).
|
||||
This package handles all mail sending. To learn how to send a mail, see [notifications]({{< ref "notifications.md" >}}).
|
||||
|
||||
### metrics
|
||||
|
||||
This package handles all metrics which are exposed to the prometheus endpoint.
|
||||
To learn how it works and how to add new metrics, take a look at [how metrics work]({{< ref "../practical-instructions/metrics.md">}}).
|
||||
To learn how it works and how to add new metrics, take a look at [how metrics work]({{< ref "metrics.md">}}).
|
||||
|
||||
### migration
|
||||
|
||||
This package handles all migrations.
|
||||
All migrations are stored and executed here.
|
||||
All migrations are stored and executed in this package.
|
||||
|
||||
To learn more, take a look at the [migrations docs]({{< ref "../development/db-migrations.md">}}).
|
||||
|
||||
@ -123,11 +90,35 @@ When adding new features or upgrading existing ones, that most likely happens he
|
||||
|
||||
Because this package is pretty huge, there are several documents and how-to's about it:
|
||||
|
||||
* [Adding a feature]({{< ref "../practical-instructions/feature.md">}})
|
||||
* [Making calls to the database]({{< ref "../practical-instructions/database.md">}})
|
||||
* [Adding a feature]({{< ref "feature.md">}})
|
||||
* [Making calls to the database]({{< ref "database.md">}})
|
||||
|
||||
### modules
|
||||
|
||||
Everything that can have multiple implementations (like a task migrator from a third-party task provider) lives in a
|
||||
respective sub package in this package.
|
||||
|
||||
#### auth
|
||||
|
||||
Contains openid related authentication.
|
||||
|
||||
#### avatar
|
||||
|
||||
Contains all possible avatar providers a user can choose to set their avatar.
|
||||
|
||||
#### background
|
||||
|
||||
All list background providers are in sub-packages of this package.
|
||||
|
||||
#### dump
|
||||
|
||||
Handles everything related to the `dump` and `restore` commands of Vikunja.
|
||||
|
||||
#### keyvalue
|
||||
|
||||
A simple key-value store with an implementation for memory and redis.
|
||||
Can be used to cache values.
|
||||
|
||||
#### migration
|
||||
|
||||
See [writing a migrator]({{< ref "migration.md" >}}).
|
||||
@ -142,20 +133,19 @@ to talk to redis.
|
||||
|
||||
It uses the [go-redis](https://github.com/go-redis/redis) library, please see their configuration on how to use it.
|
||||
|
||||
**Note**: Only use this package directly if you have to use a direct redis connection.
|
||||
In most cases, using the `keyvalue` package is a better fit.
|
||||
|
||||
### routes
|
||||
|
||||
This package defines all routes which are available for vikunja clients to use.
|
||||
To add a new route, see [adding a new route]({{< ref "../practical-instructions/feature.md">}}).
|
||||
To add a new route, see [adding a new route]({{< ref "feature.md">}}).
|
||||
|
||||
#### api/v1
|
||||
|
||||
This is where all http-handler functions for the api are stored.
|
||||
Every handler function which does not use the standard web handler should live here.
|
||||
|
||||
### static
|
||||
|
||||
All static files generated by `mage generate` live here.
|
||||
|
||||
### swagger
|
||||
|
||||
This is where the [generated]({{< ref "mage.md#generate-swagger-definitions-from-code-comments">}} [api docs]({{< ref "../usage/api.md">}}) live.
|
||||
@ -179,23 +169,3 @@ See their function definitions for instructions on how to use them.
|
||||
The single purpouse of this package is to hold the current vikunja version which gets overridden through build flags
|
||||
each time `mage release` or `mage build` is run.
|
||||
It is a seperate package to avoid import cycles with other packages.
|
||||
|
||||
## REST-Tests
|
||||
|
||||
Holds all kinds of test files to directly test the api from inside of [jetbrains ide's](https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html).
|
||||
|
||||
These files are currently more an experiment, maybe we will drop them in the future to use something we could integrate in the testing process with drone.
|
||||
Therefore, this has no claim to be complete yet even working, you're free to change whatever is needed to get it working for you.
|
||||
|
||||
## templates
|
||||
|
||||
Holds the email templates used to send plain text and html emails for new user registration and password changes.
|
||||
|
||||
## vendor
|
||||
|
||||
All libraries needed to build Vikunja.
|
||||
|
||||
We keep all libraries used for Vikunja around in the `vendor/` folder to still be able to build the project even if
|
||||
some maintainers take their libraries down like [it happened in the past](https://github.com/jteeuwen/go-bindata/issues/5).
|
||||
|
||||
When adding a new dependency, make sure to run `go mod vendor` to put it inside this directory.
|
||||
|
@ -1,17 +1,19 @@
|
||||
---
|
||||
date: "2019-02-12:00:00+02:00"
|
||||
title: "Modifying swagger api docs"
|
||||
title: "Modifying Swagger API Docs"
|
||||
draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "practical instructions"
|
||||
parent: "development"
|
||||
---
|
||||
|
||||
# Adding/editing swagger api docs
|
||||
# Modifying swagger api docs
|
||||
|
||||
The api documentation is generated using [swaggo](https://github.com/swaggo/swag) from comments.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## Documenting structs
|
||||
|
||||
You should always comment every field which will be exposed as a json in the api.
|
||||
@ -45,3 +47,27 @@ type List struct {
|
||||
web.Rights `xorm:"-" json:"-"`
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
## Documenting api Endpoints
|
||||
|
||||
All api routes should be documented with a comment above the handler function.
|
||||
When generating the api docs with mage, the swagger cli will pick these up and put them in a neat document.
|
||||
|
||||
A comment looks like this:
|
||||
|
||||
{{< highlight golang >}}
|
||||
// @Summary Login
|
||||
// @Description Logs a user in. Returns a JWT-Token to authenticate further requests.
|
||||
// @tags user
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param credentials body user.Login true "The login credentials"
|
||||
// @Success 200 {object} auth.Token
|
||||
// @Failure 400 {object} models.Message "Invalid user password model."
|
||||
// @Failure 412 {object} models.Message "Invalid totp passcode."
|
||||
// @Failure 403 {object} models.Message "Invalid username or password."
|
||||
// @Router /login [post]
|
||||
func Login(c echo.Context) error {
|
||||
// Handler logic
|
||||
}
|
||||
{{< /highlight >}}
|
@ -10,32 +10,31 @@ menu:
|
||||
|
||||
# Testing
|
||||
|
||||
You can run unit tests with [our `Magefile`]({{< ref "mage.md">}}) with
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## API Tests
|
||||
|
||||
The following parts are about the kinds of tests in the API package and how to run them.
|
||||
|
||||
### Prerequesites
|
||||
|
||||
To run any kind of test, you need to specify Vikunja's [root path](https://vikunja.io/docs/config-options/#rootpath).
|
||||
This is required to make sure all test fixtures are correctly loaded.
|
||||
|
||||
The easies way to do that is to set the environment variable `VIKUNJA_SERVICE_ROOTPATH` to the path where you cloned the working directory.
|
||||
|
||||
### Unit tests
|
||||
|
||||
To run unit tests with [mage]({{< ref "mage.md">}}), execute
|
||||
|
||||
{{< highlight bash >}}
|
||||
mage test:unit
|
||||
{{< /highlight >}}
|
||||
|
||||
{{< table_of_contents >}}
|
||||
In Vikunja, everything that is not an integration test counts as unit test - even if it accesses the db.
|
||||
This definition is a bit blurry, but we haven't found a better one yet.
|
||||
|
||||
## Running tests with config
|
||||
|
||||
You can run tests with all available config variables if you want, enabeling you to run tests for a lot of scenarios.
|
||||
|
||||
To use the normal config set the enviroment variable `VIKUNJA_TESTS_USE_CONFIG=1`.
|
||||
|
||||
## Show sql queries
|
||||
|
||||
When `UNIT_TESTS_VERBOSE=1` is set, all sql queries will be shown when tests are run.
|
||||
|
||||
## Fixtures
|
||||
|
||||
All tests are run against a set of db fixtures.
|
||||
These fixtures are defined in `pkg/models/fixtures` in YAML-Files which represent the database structure.
|
||||
|
||||
When you add a new test case which requires new database entries to test against, update these files.
|
||||
|
||||
## Integration tests
|
||||
### Integration tests
|
||||
|
||||
All integration tests live in `pkg/integrations`.
|
||||
You can run them by executing `mage test:integration`.
|
||||
@ -45,7 +44,25 @@ see at the beginning of this document.
|
||||
|
||||
To run integration tests, use `mage test:integration`.
|
||||
|
||||
## Initializing db fixtures when writing tests
|
||||
### Running tests with config
|
||||
|
||||
You can run tests with all available config variables if you want, enabeling you to run tests for a lot of scenarios.
|
||||
We use this in CI to run all tests with different databases.
|
||||
|
||||
To use the normal config set the enviroment variable `VIKUNJA_TESTS_USE_CONFIG=1`.
|
||||
|
||||
### Showing sql queries
|
||||
|
||||
When the environment variable `UNIT_TESTS_VERBOSE=1` is set, all sql queries will be shown during the test run.
|
||||
|
||||
### Fixtures
|
||||
|
||||
All tests are run against a set of db fixtures.
|
||||
These fixtures are defined in `pkg/models/fixtures` in YAML-Files which represent the database structure.
|
||||
|
||||
When you add a new test case which requires new database entries to test against, update these files.
|
||||
|
||||
#### Initializing db fixtures when writing tests
|
||||
|
||||
All db fixtures for all tests live in the `pkg/db/fixtures/` folder as yaml files.
|
||||
Each file has the same name as the table the fixtures are for.
|
||||
@ -54,19 +71,39 @@ You should put new fixtures in this folder.
|
||||
When initializing db fixtures, you are responsible for defining which tables your package needs in your test init function.
|
||||
Usually, this is done as follows (this code snippet is taken from the `user` package):
|
||||
|
||||
```go
|
||||
{{< highlight go >}}
|
||||
err = db.InitTestFixtures("users")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
```
|
||||
{{< /highlight >}}
|
||||
|
||||
In your actual tests, you then load the fixtures into the in-memory db like so:
|
||||
|
||||
```go
|
||||
{{< highlight go >}}
|
||||
db.LoadAndAssertFixtures(t)
|
||||
```
|
||||
{{< /highlight >}}
|
||||
|
||||
This will load all fixtures you defined in your test init method.
|
||||
You should always use this method to load fixtures, the only exception is when your package tests require extra test
|
||||
fixtures other than db fixtures (like files).
|
||||
|
||||
## Frontend tests
|
||||
|
||||
The frontend has end to end tests with Cypress that use a Vikunja instance and drive a browser against it.
|
||||
Check out the docs [in the frontend repo](https://kolaente.dev/vikunja/frontend/src/branch/main/cypress/README.md) about how they work and how to get them running.
|
||||
|
||||
### Unit Tests
|
||||
|
||||
To run the frontend unit tests, run
|
||||
|
||||
{{< highlight bash >}}
|
||||
yarn test:unit
|
||||
{{< /highlight >}}
|
||||
|
||||
The frontend also has a watcher available that re-runs all unit tests every time you change something.
|
||||
To use it, simply run
|
||||
|
||||
{{< highlight bash >}}
|
||||
yarn test:unit-watch
|
||||
{{< /highlight >}}
|
||||
|
@ -0,0 +1,76 @@
|
||||
---
|
||||
title: "German Translation Instructions"
|
||||
date: 2021-06-23T23:47:34+02:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
# German Translation Instructions
|
||||
|
||||
<div class="notification is-warning">
|
||||
<b>NOTE:</b> This document contains translation instructions specific to the german translation of Vikunja.
|
||||
For instructions applicable to all languages, check out the <a href="{{< ref "./translations.md">}}">general translation instructions</a>.
|
||||
</div>
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## Allgemein
|
||||
|
||||
Anrede: Wenig förmlich:
|
||||
|
||||
* “Du”-Form
|
||||
* Keine “Amtsdeusch“-Umschreibungen, einfach so als ob man den Nutzer direkt persönlich ansprechen würde
|
||||
|
||||
Genauer definiert:
|
||||
|
||||
* “falsch” anstatt “nicht korrekt/inkorrekt”
|
||||
* “Wende dich an …” anstatt “kontaktiere …”
|
||||
* In derselben Zeit übersetzen (sonst wird aus dem englischen “is“ das deutsche “war”)
|
||||
* Richtige Anführungszeichen verwenden. Also `„“` statt `''` oder `'` oder ` oder ´
|
||||
* `„` für beginnende Anführungszeichen, `“` für schließende Anführungszeichen
|
||||
|
||||
Es gelten Artikel und Worttrennungen aus dem [Duden](https://duden.de).
|
||||
|
||||
## Formulierungen
|
||||
|
||||
* `Account` statt `Konto`.
|
||||
* `TOTP` immer als ein Wort und Groß.
|
||||
* `CalDAV` immer so.
|
||||
* `löschen` oder `entfernen` je nach Kontext. Wenn etwas *gelöscht* wird, existiert das gelöschte Objekt und danach
|
||||
nicht mehr und hat evtl. andere Objekte mitgelöscht (z.B. eine Aufgabe). Wird etwas *entfernt*, bezieht sich das
|
||||
meistens auf die Beziehung zu einem anderen Objekt. Das entfernte Objekt existiert danach immernoch, z.B. beim
|
||||
Entfernen eine:r Nutzer:in aus einem Team.
|
||||
* Analog zu `löschen` oder `entfernen` gilt ähnliches für `hinzufügen` oder `erstellen`. Eine Aufgabe wird *erstellt*,
|
||||
aber ein:e Nutzer:in nur zu einem Team *hinzugefügt*.
|
||||
* `Anmeldename` anstatt `Benutzer:innenname`
|
||||
|
||||
## Formulierungen in Modals und Buttons
|
||||
|
||||
Es sollten die gleichen Formulierungen auf Buttons und Modals verwendet werden.
|
||||
|
||||
Beispiel: Wenn der Button mit `löschen` beschriftet ist, sollte im Modal die Frage
|
||||
lauten `Willst du das wirklich löschen?` und nicht `Willst du das wirklich entfernen?`. Gleiches gilt für
|
||||
Erfolgs/Fehlermeldungen nach der Aktion.
|
||||
|
||||
## Gendern
|
||||
|
||||
Wo möglich, sollte eine geschlechtsneutrale Anrede verwendet werden. Falls diese sehr umständlich würden (siehe oben
|
||||
„Amtsdeutsch-Umschreibungen“), soll mit *Doppelpunkt* gegendert werden.
|
||||
|
||||
Beispiel: „Benutzer:in“
|
||||
|
||||
## Trennungen
|
||||
|
||||
* E-Mail-Adresse (siehe Duden)
|
||||
|
||||
## Wörter und Ausdrücke
|
||||
|
||||
| Englisches Original | Verwendung in deutscher Übersetzung |
|
||||
| ------------------- | -------------------- |
|
||||
| Bucket | Spalte |
|
||||
| Namespace | Namespace |
|
||||
| Link Share | Linkfreigabe |
|
||||
| Username | Anmeldename |
|
||||
|
||||
## Weiterführende Links
|
||||
|
||||
* https://docs.translatehouse.org/projects/localization-guide/en/latest/guide/translation_guidelines_german.html
|
54
docs/content/doc/development/translations.md
Normal file
54
docs/content/doc/development/translations.md
Normal file
@ -0,0 +1,54 @@
|
||||
---
|
||||
title: "Translations"
|
||||
date: 2021-06-23T22:52:06+02:00
|
||||
draft: false
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "development"
|
||||
---
|
||||
|
||||
# Translations
|
||||
|
||||
This document provides documentation about how to translate Vikunja.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## Where to translate
|
||||
|
||||
Translation happens at [crowdin](https://crowdin.com/project/vikunja).
|
||||
|
||||
Currently, only the frontend (and by extension, the desktop app) is translatable.
|
||||
|
||||
## Translation Instructions
|
||||
|
||||
> These are the instructions for translating Vikunja in another language.
|
||||
> For information about how to add new translation strings, see below.
|
||||
|
||||
For all languages these translation guidelines should be applied when translating:
|
||||
|
||||
* Use a less-formal style, as if you were talking to a friend.
|
||||
* If the source string contains characters like `&` or `…`, the translated string should contain them as well.
|
||||
|
||||
More specific instructions for some languages can be found below.
|
||||
|
||||
### Wrong translation strings
|
||||
|
||||
If you encounter a wrong original translation string while translating, please don't correct it in the translation.
|
||||
Instead, translate it to reflect the original meaning in the translated string but add a comment under the source string to discuss potential changes.
|
||||
|
||||
### Language-specific instructions
|
||||
|
||||
* [German]({{< ref "./translation-instructions-german.md">}})
|
||||
|
||||
## How to add new translation strings
|
||||
|
||||
All translation strings are stored in `src/i18n/lang/`.
|
||||
New strings should be added only in the `en.json` file.
|
||||
Strings in other languages will be synced through weblate and should not be added directly as a PR/commit in the frontend repo.
|
||||
|
||||
## Requesting a new language
|
||||
|
||||
If you want to start translating Vikunja in a language not yet available in Vikunja, please request the language through the crowdin interface.
|
||||
If you have issues with this or need a discussion before doing so, please [contact us](https://vikunja.io/contact/) or [start a discussion in the forum](https://community.vikunja.io).
|
||||
|
||||
Once at least 50% of all translation strings are translated and approved, they will be added and distributed with the Vikunja frontend for users to select and use Vikunja with them.
|
@ -1,40 +0,0 @@
|
||||
---
|
||||
date: "2019-02-12:00:00+02:00"
|
||||
title: "Database"
|
||||
draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "practical instructions"
|
||||
---
|
||||
|
||||
# Database
|
||||
|
||||
Vikunja uses [xorm](http://xorm.io/) as an abstraction layer to handle the database connection.
|
||||
Please refer to [their](http://xorm.io/docs/) documentation on how to exactly use it.
|
||||
|
||||
Inside the `models` package, a variable `x` is available which contains a pointer to an instance of `xorm.Engine`.
|
||||
This is used whenever you make a call to the database to get or update data.
|
||||
|
||||
This xorm instance is set up and initialized every time vikunja is started.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## Adding new database tables
|
||||
|
||||
To add a new table to the database, add a an instance of your struct to the `tables` variable in the
|
||||
init function in `pkg/models/models.go`. Xorm will sync them automatically.
|
||||
|
||||
You also need to add a pointer to the `tablesWithPointer` slice to enable caching for all instances of this struct.
|
||||
|
||||
To learn more about how to configure your struct to create "good" tables, refer to [the xorm documentaion](http://xorm.io/docs/).
|
||||
|
||||
## Adding data to test fixtures
|
||||
|
||||
Adding data for test fixtures is done in via `yaml` files insinde of `pkg/models/fixtures`.
|
||||
|
||||
The name of the yaml file should equal the table name in the database.
|
||||
Adding values to it is done via array definition inside of the yaml file.
|
||||
|
||||
**Note**: Table and column names need to be in snake_case as that's what is used internally in the database
|
||||
and for mapping values from the database to xorm so your structs can use it.
|
@ -1,86 +0,0 @@
|
||||
---
|
||||
date: "2019-02-12:00:00+02:00"
|
||||
title: "Mailer"
|
||||
draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "practical instructions"
|
||||
---
|
||||
|
||||
# Mailer
|
||||
|
||||
This document explains how to use the mailer to send emails and what to do to create a new kind of email to be sent.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## Sending emails
|
||||
|
||||
**Note:** You should use mail templates whenever possible (see below).
|
||||
|
||||
To send an email, use the function `mail.SendMail(options)`. The options are defined as follows:
|
||||
|
||||
{{< highlight golang >}}
|
||||
type Opts struct {
|
||||
To string // The email address of the recipent
|
||||
Subject string // The subject of the mail
|
||||
Message string // The plaintext message in the mail
|
||||
HTMLMessage string // The html message
|
||||
ContentType ContentType // The content type of the mail. Can be either mail.ContentTypePlain, mail.ContentTypeHTML, mail.ContentTypeMultipart. You should set this according to the kind of mail you want to send.
|
||||
Boundary string
|
||||
Headers []*header // Other headers to set in the mail.
|
||||
}
|
||||
{{< /highlight >}}
|
||||
|
||||
### Sending emails based on a template
|
||||
|
||||
For each mail with a template, there are two email templates: One for plaintext emails, one for html emails.
|
||||
|
||||
These are located in the `templates/mail` folder and follow the conventions of `template-name.{plain|hmtl}.tmpl`,
|
||||
both the plaintext and html templates are in the same folder.
|
||||
|
||||
To send a mail based on a template, use the function `mail.SendMailWithTemplate(to, subject, tpl string, data map[string]interface{})`.
|
||||
`to` and `subject` are pretty much self-explanatory, `tpl` is the name of the template, without `.html.tmpl` or `.plain.tmpl`.
|
||||
`data` is a map you can pass additional data to your template.
|
||||
|
||||
### Sending a mail with a template
|
||||
|
||||
A basic html email template would look like this:
|
||||
|
||||
{{< highlight go-html-template >}}
|
||||
{{template "mail-header.tmpl" .}}
|
||||
<p>
|
||||
Hey there!<br/>
|
||||
This is a minimal html email example.<br/>
|
||||
{{.Something}}
|
||||
</p>
|
||||
{{template "mail-footer.tmpl"}}
|
||||
{{< /highlight >}}
|
||||
|
||||
And the corresponding plaintext template:
|
||||
|
||||
{{< highlight go-text-template >}}
|
||||
Hey there!
|
||||
|
||||
This is a minimal html email example.
|
||||
|
||||
{{.Something}}
|
||||
{{< /highlight >}}
|
||||
You would then call this like so:
|
||||
|
||||
{{< highlight golang >}}
|
||||
data := make(map[string]interface{})
|
||||
data["Something"] = "I am some computed value"
|
||||
to := "test@example.com"
|
||||
subject := "A simple test mail"
|
||||
tpl := "demo" // Assuming you saved the templates as demo.plain.tmpl and demo.html.tmpl
|
||||
mail.SendMailWithTemplate(to, subject, tpl, data)
|
||||
{{< /highlight >}}
|
||||
|
||||
The function does not return an error. If an error occures when sending a mail, it is logged but not returned because sending the mail happens asinchrounly.
|
||||
|
||||
Notice the `mail-header.tmpl` and `mail-footer.tmpl` in the template. These populate some basic css, a box for your content and the vikunja logo.
|
||||
All that's left for you is to put the content in, which then will appear in a beautifully-styled box.
|
||||
|
||||
Remeber, these are email templates. This is different from normal html/css, you cannot use whatever you want (because most of the clients are wayyy to outdated).
|
||||
|
@ -1,31 +0,0 @@
|
||||
---
|
||||
date: "2019-02-12:00:00+02:00"
|
||||
title: "Adding new config options"
|
||||
draft: false
|
||||
type: "doc"
|
||||
menu:
|
||||
sidebar:
|
||||
parent: "practical instructions"
|
||||
---
|
||||
|
||||
# Adding new config options
|
||||
|
||||
Vikunja uses [viper](https://github.com/spf13/viper) to handle configuration options.
|
||||
It handles parsing all different configuration sources.
|
||||
|
||||
The configuration is done in sections. These are represented with a `.` in viper.
|
||||
Take a look at `pkg/config/config.go` to understand how these are set.
|
||||
|
||||
To add a new config option, you should add a default value to `pkg/config/config.go`.
|
||||
Default values should always enable the feature to work somehow, or turn it off completely if it always needs
|
||||
additional configuration.
|
||||
|
||||
Make sure to add the new config option to [the config document]({{< ref "../setup/config.md">}}) and the default config file
|
||||
(`config.yml.sample` at the root of the repository) to make sure it is well documented.
|
||||
|
||||
If you're using a computed value as a default, make sure to update the sample config file and debian
|
||||
post-install scripts to reflect that.
|
||||
|
||||
To get a configured option, use `viper.Get("config.option")`.
|
||||
Take a look at [viper's documentation](https://github.com/spf13/viper#getting-values-from-viper) to learn of the
|
||||
different ways available to get config options.
|
@ -10,12 +10,17 @@ menu:
|
||||
|
||||
# What to backup
|
||||
|
||||
Vikunja does not store any data outside of the database.
|
||||
So, all you need to backup are the contents of that database and maybe the config file.
|
||||
There are two parts you need to back up: The database and attachment files.
|
||||
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## MySQL
|
||||
## Files
|
||||
|
||||
To back up attachments and other files, it is enough to copy them [from the attachments folder]({{< ref "config.md" >}}#basepath) to some other place.
|
||||
|
||||
## Database
|
||||
|
||||
### MySQL
|
||||
|
||||
To create a backup from mysql use the `mysqldump` command:
|
||||
|
||||
@ -31,7 +36,7 @@ To restore it, simply pipe it back into the `mysql` command:
|
||||
mysql -u <user> -p -h <db-host> <database> < vkunja-backup.sql
|
||||
{{< /highlight >}}
|
||||
|
||||
## PostgreSQL
|
||||
### PostgreSQL
|
||||
|
||||
To create a backup from PostgreSQL use the `pg_dump` command:
|
||||
|
||||
@ -49,6 +54,6 @@ psql -U <user> -h <db-host> <database> < vikunja-backup.sql
|
||||
|
||||
For more information, please visit the [relevant PostgreSQL documentation](https://www.postgresql.org/docs/12/backup-dump.html).
|
||||
|
||||
## SQLite
|
||||
### SQLite
|
||||
|
||||
To backup sqllite databases, it is enough to copy the database elsewhere.
|
||||
To back up sqllite databases, it is enough to copy the [database file]({{< ref "config.md" >}}#path) to somwhere else.
|
||||
|
@ -10,20 +10,37 @@ menu:
|
||||
|
||||
# Build Vikunja from source
|
||||
|
||||
Vikunja being a go application, has no other dependencies than go itself.
|
||||
All libraries are bundeled inside the repo in the `vendor/` folder, so all it boils down to are these steps:
|
||||
To completely build Vikunja from source, you need to build the api and frontend.
|
||||
|
||||
1. Make sure [Go](https://golang.org/doc/install) is properly installed on your system. You'll need at least Go `1.9`.
|
||||
2. Make sure [Mage](https://magefile) is properly installed on your system.
|
||||
3. Clone the repo with `git clone https://code.vikunja.io/api`
|
||||
{{< table_of_contents >}}
|
||||
|
||||
## API
|
||||
|
||||
The Vikunja API has no other dependencies than go itself.
|
||||
That means compiling it boils down to these steps:
|
||||
|
||||
1. Make sure [Go](https://golang.org/doc/install) is properly installed on your system. You'll need at least Go `1.17`.
|
||||
2. Make sure [Mage](https://magefile.org) is properly installed on your system.
|
||||
3. Clone the repo with `git clone https://code.vikunja.io/api` and switch into the directory.
|
||||
3. Run `mage build:build` in the source of this repo. This will build a binary in the root of the repo which will be able to run on your system.
|
||||
|
||||
*Note:* Static ressources such as email templates are built into the binary.
|
||||
For these to work, you may need to run `mage build:generate` before building the vikunja binary.
|
||||
When builing entirely with `mage`, you dont need to do this, `mage build:generate` will be run automatically when running `mage build:build`.
|
||||
|
||||
# Build for different architectures
|
||||
### Build for different architectures
|
||||
|
||||
To build for other platforms and architectures than the one you're currently on, simply run `mage release:release` or `mage release:{linux|windows|darwin}`.
|
||||
|
||||
More options are available, please refer to the [magefile docs]({{< ref "../development/mage.md">}}) for more details.
|
||||
More options are available, please refer to the [magefile docs]({{< ref "../development/mage.md">}}) for more details.
|
||||
|
||||
## Frontend
|
||||
|
||||
The code for the frontend is located at [code.vikunja.io/frontend](https://code.vikunja.io/frontend).
|
||||
|
||||
You need to have yarn v1 and nodejs in version 16 installed.
|
||||
|
||||
1. Make sure [yarn v1](https://yarnpkg.com/getting-started/install) is properly installed on your system.
|
||||
3. Clone the repo with `git clone https://code.vikunja.io/frontend` and switch into the directory.
|
||||
3. Install all dependencies with `yarn install`
|
||||
4. Build the frontend with `yarn build`. This will result in a js bundle in the `dist/` folder which you can deploy.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,6 +36,8 @@ services:
|
||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: supersecret
|
||||
MYSQL_USER: vikunja
|
||||
MYSQL_PASSWORD: secret
|
||||
MYSQL_DATABASE: vikunja
|
||||
volumes:
|
||||
- ./db:/var/lib/mysql
|
||||
@ -44,9 +46,9 @@ services:
|
||||
image: vikunja/api
|
||||
environment:
|
||||
VIKUNJA_DATABASE_HOST: db
|
||||
VIKUNJA_DATABASE_PASSWORD: supersecret
|
||||
VIKUNJA_DATABASE_PASSWORD: secret
|
||||
VIKUNJA_DATABASE_TYPE: mysql
|
||||
VIKUNJA_DATABASE_USER: root
|
||||
VIKUNJA_DATABASE_USER: vikunja
|
||||
VIKUNJA_DATABASE_DATABASE: vikunja
|
||||
volumes:
|
||||
- ./files:/app/vikunja/files
|
||||
|
@ -25,6 +25,9 @@ All examples on this page already reflect this and do not require additional wor
|
||||
|
||||
## Redis
|
||||
|
||||
While Vikunja has support to use redis as a caching backend, you'll probably not need it unless you're using Vikunja
|
||||
with more than a handful of users.
|
||||
|
||||
To use redis, you'll need to add this to the config examples below:
|
||||
|
||||
{{< highlight yaml >}}
|
||||
@ -44,6 +47,78 @@ services:
|
||||
image: redis
|
||||
{{< /highlight >}}
|
||||
|
||||
## PostgreSQL
|
||||
|
||||
Vikunja supports postgres, mysql and sqlite as a database backend. The examples on this page use mysql with a mariadb container.
|
||||
To use postgres as a database backend, change the `db` section of the examples to this:
|
||||
|
||||
{{< highlight yaml >}}
|
||||
db:
|
||||
image: postgres:13
|
||||
environment:
|
||||
POSTGRES_PASSWORD: secret
|
||||
POSTGRES_USER: vikunja
|
||||
volumes:
|
||||
- ./db:/var/lib/postgresql/data
|
||||
restart: unless-stopped
|
||||
{{< /highlight >}}
|
||||
|
||||
You'll also need to change the `VIKUNJA_DATABASE_TYPE` to `postgres` on the api container declaration.
|
||||
|
||||
<div class="notification is-warning">
|
||||
<b>NOTE:</b> The mariadb container can sometimes take a while to initialize, especially on the first run.
|
||||
During this time, the api container will fail to start at all. It will automatically restart every few seconds.
|
||||
</div>
|
||||
|
||||
## Example without any proxy
|
||||
|
||||
This example lets you host Vikunja without any reverse proxy in front of it. This is the absolute minimum configuration
|
||||
you need to get something up and running. If you want to host Vikunja on one single port instead of two different ones
|
||||
or need tls termination, check out one of the other examples.
|
||||
|
||||
Not that you need to change the `VIKUNJA_API_URL` environment variable to the ip (the docker host you're running this on)
|
||||
is reachable at. Because the browser you'll use to access the Vikunja frontend uses that url to make the requests, it
|
||||
has to be able to reach that ip + port from the outside. Putting everything in a private network won't work.
|
||||
|
||||
{{< highlight yaml >}}
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
db:
|
||||
image: mariadb:10
|
||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: supersecret
|
||||
MYSQL_USER: vikunja
|
||||
MYSQL_PASSWORD: secret
|
||||
MYSQL_DATABASE: vikunja
|
||||
volumes:
|
||||
- ./db:/var/lib/mysql
|
||||
restart: unless-stopped
|
||||
api:
|
||||
image: vikunja/api
|
||||
environment:
|
||||
VIKUNJA_DATABASE_HOST: db
|
||||
VIKUNJA_DATABASE_PASSWORD: secret
|
||||
VIKUNJA_DATABASE_TYPE: mysql
|
||||
VIKUNJA_DATABASE_USER: vikunja
|
||||
VIKUNJA_DATABASE_DATABASE: vikunja
|
||||
ports:
|
||||
- 3456:3456
|
||||
volumes:
|
||||
- ./files:/app/vikunja/files
|
||||
depends_on:
|
||||
- db
|
||||
restart: unless-stopped
|
||||
frontend:
|
||||
image: vikunja/frontend
|
||||
ports:
|
||||
- 80:80
|
||||
environment:
|
||||
VIKUNJA_API_URL: http://<your-ip-here>:3456/api/v1
|
||||
restart: unless-stopped
|
||||
{{< /highlight >}}
|
||||
|
||||
## Example with traefik 2
|
||||
|
||||
This example assumes [traefik](https://traefik.io) version 2 installed and configured to [use docker as a configuration provider](https://docs.traefik.io/providers/docker/).
|
||||
@ -203,6 +278,8 @@ services:
|
||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: supersecret
|
||||
MYSQL_USER: vikunja
|
||||
MYSQL_PASSWORD: secret
|
||||
MYSQL_DATABASE: vikunja
|
||||
volumes:
|
||||
- ./db:/var/lib/mysql
|
||||
@ -211,9 +288,9 @@ services:
|
||||
image: vikunja/api
|
||||
environment:
|
||||
VIKUNJA_DATABASE_HOST: db
|
||||
VIKUNJA_DATABASE_PASSWORD: supersecret
|
||||
VIKUNJA_DATABASE_PASSWORD: secret
|
||||
VIKUNJA_DATABASE_TYPE: mysql
|
||||
VIKUNJA_DATABASE_USER: root
|
||||
VIKUNJA_DATABASE_USER: vikunja
|
||||
VIKUNJA_DATABASE_DATABASE: vikunja
|
||||
volumes:
|
||||
- ./files:/app/vikunja/files
|
||||
@ -258,7 +335,9 @@ services:
|
||||
image: mariadb:10
|
||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: supersecret
|
||||
MYSQL_ROOT_PASSWORD: supersecret
|
||||
MYSQL_USER: vikunja
|
||||
MYSQL_PASSWORD: secret
|
||||
MYSQL_DATABASE: vikunja
|
||||
volumes:
|
||||
- ./db:/var/lib/mysql
|
||||
@ -267,9 +346,9 @@ services:
|
||||
image: vikunja/api
|
||||
environment:
|
||||
VIKUNJA_DATABASE_HOST: db
|
||||
VIKUNJA_DATABASE_PASSWORD: supersecret
|
||||
VIKUNJA_DATABASE_PASSWORD: secret
|
||||
VIKUNJA_DATABASE_TYPE: mysql
|
||||
VIKUNJA_DATABASE_USER: root
|
||||
VIKUNJA_DATABASE_USER: vikunja
|
||||
VIKUNJA_DATABASE_DATABASE: vikunja
|
||||
volumes:
|
||||
- ./files:/app/vikunja/files
|
||||
@ -291,3 +370,81 @@ services:
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
{{< /highlight >}}
|
||||
|
||||
## Setup on a Synology NAS
|
||||
|
||||
There is a proxy preinstalled in DSM, so if you want to access vikunja from outside,
|
||||
you can prepare 2 proxy rules:
|
||||
|
||||
* a redirection rule for vikunja's api (see example screenshot using port 3456)
|
||||
* a similar redirection rule for vikunja's frontend (using port 4321)
|
||||
|
||||

|
||||
|
||||
You should also add 2 empty folders for mariadb and vikunja inside Synology's
|
||||
docker main folders:
|
||||
|
||||
* Docker
|
||||
* vikunja
|
||||
* mariadb
|
||||
|
||||
Synology has it's own GUI for managing Docker containers... But it's easier via docker compose.
|
||||
|
||||
To do that, you can
|
||||
|
||||
* either activate SSH and paste the adapted compose file in a terminal (using Putty or similar)
|
||||
* without activating SSH as a "custom script" (go to Control Panel / Task Scheduler / Create / Scheduled Task / User-defined script)
|
||||
* without activating SSH, by using Portainer (you have to install first, check out [this tutorial](https://www.portainer.io/blog/how-to-install-portainer-on-a-synology-nas) for exmple):
|
||||
1. Go to **Dashboard / Stacks** click the button **"Add Stack"**
|
||||
2. Give it the name Vikunja and paste the adapted docker compose file
|
||||
3. Deploy the Stack with the "Delpoy Stack" button:
|
||||
|
||||

|
||||
|
||||
The docker-compose file we're going to use is very similar to the [example without any proxy](#example-without-any-proxy) above:
|
||||
|
||||
{{< highlight yaml >}}
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
db:
|
||||
image: mariadb:10
|
||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: supersecret
|
||||
MYSQL_USER: vikunja
|
||||
MYSQL_PASSWORD: secret
|
||||
MYSQL_DATABASE: vikunja
|
||||
volumes:
|
||||
- ./db:/var/lib/mysql
|
||||
restart: unless-stopped
|
||||
api:
|
||||
image: vikunja/api
|
||||
environment:
|
||||
VIKUNJA_DATABASE_HOST: db
|
||||
VIKUNJA_DATABASE_PASSWORD: secret
|
||||
VIKUNJA_DATABASE_TYPE: mysql
|
||||
VIKUNJA_DATABASE_USER: vikunja
|
||||
VIKUNJA_DATABASE_DATABASE: vikunja
|
||||
ports:
|
||||
- 3456:3456
|
||||
volumes:
|
||||
- ./files:/app/vikunja/files
|
||||
depends_on:
|
||||
- db
|
||||
restart: unless-stopped
|
||||
frontend:
|
||||
image: vikunja/frontend
|
||||
ports:
|
||||
- 4321:80
|
||||
environment:
|
||||
VIKUNJA_API_URL: http://vikunja-api-domain.tld/api/v1
|
||||
restart: unless-stopped
|
||||
{{< /highlight >}}
|
||||
|
||||
You may want to change the volumes to match the rest of your setup.
|
||||
|
||||
Once deployed, you might want to change the [`PUID` and `GUID` settings]({{< ref "install-backend.md">}}#setting-user-and-group-id-of-the-user-running-vikunja) or [set the time zone]({{< ref "config.md">}}#timezone).
|
||||
|
||||
After registering all your users, you might also want to [disable the user registration]({{<ref "config.md">}}#enableregistration).
|
||||
|
||||
|
@ -28,7 +28,7 @@ wget <download-url>
|
||||
### Verify the GPG signature
|
||||
|
||||
Starting with version `0.7`, all releases are signed using pgp.
|
||||
Releases from `master` will always be signed.
|
||||
Releases from `main` will always be signed.
|
||||
|
||||
To validate the downloaded zip file use the signiture file `.asc` and the key `FF054DACD908493A`:
|
||||
|
||||
@ -52,7 +52,7 @@ ln -s /opt/vikunja/vikunja /usr/bin/vikunja
|
||||
|
||||
### Systemd service
|
||||
|
||||
Take the following `service` file and adapt it to your needs:
|
||||
Save the following service file to `/etc/systemd/system/vikunja.service` and adapt it to your needs:
|
||||
|
||||
{{< highlight service >}}
|
||||
[Unit]
|
||||
@ -83,8 +83,6 @@ WantedBy=multi-user.target
|
||||
|
||||
If you've installed Vikunja to a directory other than `/opt/vikunja`, you need to adapt `WorkingDirectory` accordingly.
|
||||
|
||||
Save the file to `/etc/systemd/system/vikunja.service`
|
||||
|
||||
After you made all nessecary modifications, it's time to start the service:
|
||||
|
||||
{{< highlight bash >}}
|
||||
@ -147,9 +145,9 @@ services:
|
||||
image: vikunja/api:latest
|
||||
environment:
|
||||
VIKUNJA_DATABASE_HOST: db
|
||||
VIKUNJA_DATABASE_PASSWORD: supersecret
|
||||
VIKUNJA_DATABASE_PASSWORD: secret
|
||||
VIKUNJA_DATABASE_TYPE: mysql
|
||||
VIKUNJA_DATABASE_USER: root
|
||||
VIKUNJA_DATABASE_USER: vikunja
|
||||
VIKUNJA_SERVICE_JWTSECRET: <generated secret>
|
||||
volumes:
|
||||
- ./files:/app/vikunja/files
|
||||
@ -158,6 +156,8 @@ services:
|
||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: supersecret
|
||||
MYSQL_USER: vikunja
|
||||
MYSQL_PASSWORD: secret
|
||||
MYSQL_DATABASE: vikunja
|
||||
volumes:
|
||||
- ./db:/var/lib/mysql
|
||||
@ -275,3 +275,8 @@ The API is now available through IP:
|
||||
## Configuration
|
||||
|
||||
See [available configuration options]({{< ref "config.md">}}).
|
||||
|
||||
## Default Password
|
||||
|
||||
After successfully installing Vikunja, there is no default user or password.
|
||||
You only need to register a new account and set all the details when creating it.
|
||||
|
@ -122,7 +122,7 @@ Put the following config in `cat /etc/apache2/sites-available/vikunja.conf`:
|
||||
ServerName localhost
|
||||
DocumentRoot /path/to/vikunja/static/frontend/files
|
||||
RewriteEngine On
|
||||
RewriteRule ^\/?(config\.json|favicon\.ico|css|fonts|images|img|js) - [L]
|
||||
RewriteRule ^\/?(favicon\.ico|assets|audio|fonts|images|manifest\.webmanifest|robots\.txt|sw\.js|workbox-.*|api|dav|\.well-known) - [L]
|
||||
RewriteRule ^(.*)$ /index.html [QSA,L]
|
||||
</VirtualHost>
|
||||
{{< /highlight >}}
|
||||
|
@ -39,3 +39,16 @@ This document provides an overview and instructions for the different methods.
|
||||
* [Reverse proxies]({{< ref "reverse-proxies.md">}})
|
||||
* [Full docker example]({{< ref "full-docker-example.md">}})
|
||||
* [Backups]({{< ref "backups.md">}})
|
||||
|
||||
## Installation on kubernetes
|
||||
|
||||
A third-party Helm Chart is available from the k8s-at-home project [here](https://github.com/k8s-at-home/charts/tree/master/charts/stable/vikunja).
|
||||
|
||||
## Other installation resources
|
||||
|
||||
* [Docker Compose is MUCH Easier Than you Think - Let's Install Vikunja](https://www.youtube.com/watch?v=fGlz2PkXjuo) (Youtube)
|
||||
* [Setup Vikunja using Docker Compose - Homelab Wiki](https://thehomelab.wiki/books/docker/page/setup-vikunja-using-docker-compose)
|
||||
* [A Closer look at Vikunja - Email Notifications - Enable or Disable Registrations - Allow Attachments](https://www.youtube.com/watch?v=47wj9pRT6Gw) (Youtube)
|
||||
* [Install Vikunja in Docker for self-hosted Task Tracking](https://smarthomepursuits.com/install-vikunja-in-docker-for-self-hosted-task-tracking/)
|
||||
* [Self-Hosted To-Do List with Vikunja in Docker](https://www.youtube.com/watch?v=DqyqDWpEvKI) (Youtube)
|
||||
* [Vikunja self-hosted (step by step)](https://nguyenminhhung.com/vikunja-self-hosted-step-by-step/)
|
||||
|
@ -80,6 +80,22 @@ server {
|
||||
<b>NOTE:</b> If you change the max upload size in Vikunja's settings, you'll need to also change the <code>client_max_body_size</code> in the nginx proxy config.
|
||||
</div>
|
||||
|
||||
## NGINX Proxy Manager (NPM)
|
||||
|
||||
1. Create a standard Proxy Host for the Vikunja Frontend within NPM and point it to the URL you plan to use. The next several steps will enable the Proxy Host to successfully navigate to the API (on port 3456).
|
||||
2. Verify that the page will pull up in your browser. (Do not bother trying to log in. It won't work. Trust me.)
|
||||
3. Now, we'll work with the NPM container, so you need to identify the container name for your NPM installation. e.g. NGINX-PM
|
||||
4. From the command line, enter `sudo docker exec -it [NGINX-PM container name] /bin/bash` and navigate to the proxy hosts folder where the `.conf` files are stashed. Probably `/data/nginx/proxy_host`. (This folder is a persistent folder created in the NPM container and mounted by NPM.)
|
||||
5. Locate the `.conf` file where the server_name inside the file matches your Vikunja Proxy Host. Once found, add the following code, unchanged, just above the existing location block in that file. (They are listed by number, not name.)
|
||||
```
|
||||
location ~* ^/(api|dav|\.well-known)/ {
|
||||
proxy_pass http://api:3456;
|
||||
client_max_body_size 20M;
|
||||
}
|
||||
```
|
||||
6. After saving the edited file, return to NPM's UI browser window and refresh the page to verify your Proxy Host for Vikunja is still online.
|
||||
7. Now, switch over to your Vikunja browswer window and hit refresh. If you configured your URL correctly in original Vikunja container, you should be all set and the browser will correctly show Vikunja. If not, you'll need to adjust the address in the top of the login subscreen to match your proxy address.
|
||||
|
||||
## Apache
|
||||
|
||||
Put the following config in `cat /etc/apache2/sites-available/vikunja.conf`:
|
||||
@ -101,11 +117,11 @@ Put the following config in `cat /etc/apache2/sites-available/vikunja.conf`:
|
||||
|
||||
DocumentRoot /var/www/html
|
||||
RewriteEngine On
|
||||
RewriteRule ^\/?(config\.json|favicon\.ico|css|fonts|images|img|js|api|dav|\.well-known) - [L]
|
||||
RewriteRule ^\/?(favicon\.ico|assets|audio|fonts|images|manifest\.webmanifest|robots\.txt|sw\.js|workbox-.*|api|dav|\.well-known) - [L]
|
||||
RewriteRule ^(.*)$ /index.html [QSA,L]
|
||||
</VirtualHost>
|
||||
{{< /highlight >}}
|
||||
|
||||
**Note:** The apache modules `proxy`, `proxy_http` and `rewrite` must be enabled for this.
|
||||
|
||||
For more details see the [frontend apache configuration]({{< ref "install-frontend.md#apache">}}).
|
||||
For more details see the [frontend apache configuration]({{< ref "install-frontend.md#apache">}}).
|
||||
|
@ -11,7 +11,7 @@ menu:
|
||||
# API Documentation
|
||||
|
||||
You can find the api docs under `http://vikunja.tld/api/v1/docs` of your instance.
|
||||
A public instance is available on [try.vikunja.io](http://try.vikunja.io/api/v1/docs).
|
||||
A public instance is available on [try.vikunja.io](https://try.vikunja.io/api/v1/docs).
|
||||
|
||||
These docs are autgenerated from annotations in the code with swagger.
|
||||
|
||||
|
@ -75,6 +75,7 @@ Vikunja **currently does not** support these properties:
|
||||
### Not working
|
||||
|
||||
* [Thunderbird (68)](https://www.thunderbird.net/)
|
||||
* iOS calDAV Sync (See [#753](https://kolaente.dev/vikunja/api/issues/753))
|
||||
|
||||
## Dev logs
|
||||
|
||||
|
@ -40,6 +40,8 @@ This document describes the different errors Vikunja can return.
|
||||
| 1016 | 412 | Totp is not enabled for this user. |
|
||||
| 1017 | 412 | The provided Totp passcode is invalid. |
|
||||
| 1018 | 412 | The provided user avatar provider type setting is invalid. |
|
||||
| 1019 | 412 | No openid email address was provided. |
|
||||
| 1020 | 412 | This user account is disabled. |
|
||||
|
||||
## Validation
|
||||
|
||||
@ -131,10 +133,11 @@ This document describes the different errors Vikunja can return.
|
||||
|
||||
| ErrorCode | HTTP Status Code | Description |
|
||||
|-----------|------------------|-------------|
|
||||
| 10001 | 404 | The bucket does not exist. |
|
||||
| 10002 | 400 | The bucket does not belong to that list. |
|
||||
| 10003 | 412 | You cannot remove the last bucket on a list. |
|
||||
| 10004 | 412 | You cannot add the task to this bucket as it already exceeded the limit of tasks it can hold. |
|
||||
| 10001 | 404 | The bucket does not exist. |
|
||||
| 10002 | 400 | The bucket does not belong to that list. |
|
||||
| 10003 | 412 | You cannot remove the last bucket on a list. |
|
||||
| 10004 | 412 | You cannot add the task to this bucket as it already exceeded the limit of tasks it can hold. |
|
||||
| 10005 | 412 | There can be only one done bucket per list. |
|
||||
|
||||
## Saved Filters
|
||||
|
||||
@ -142,3 +145,17 @@ This document describes the different errors Vikunja can return.
|
||||
|-----------|------------------|-------------|
|
||||
| 11001 | 404 | The saved filter does not exist. |
|
||||
| 11002 | 412 | Saved filters are not available for link shares. |
|
||||
|
||||
## Subscriptions
|
||||
|
||||
| ErrorCode | HTTP Status Code | Description |
|
||||
|-----------|------------------|-------------|
|
||||
| 12001 | 412 | The subscription entity type is invalid. |
|
||||
| 12002 | 412 | The user is already subscribed to the entity itself or a parent entity. |
|
||||
|
||||
## Link Shares
|
||||
|
||||
| ErrorCode | HTTP Status Code | Description |
|
||||
|-----------|------------------|-------------|
|
||||
| 13001 | 412 | This link share requires a password for authentication, but none was provided. |
|
||||
| 13002 | 403 | The provided link share password was invalid. |
|
||||
|
@ -18,4 +18,8 @@ server {
|
||||
location /docs/contact {
|
||||
return 301 $scheme://vikunja.io/en/contact;
|
||||
}
|
||||
|
||||
location /docs/docs {
|
||||
return 301 $scheme://vikunja.io/docs;
|
||||
}
|
||||
}
|
||||
|
BIN
docs/static/synology-proxy-1.png
vendored
Normal file
BIN
docs/static/synology-proxy-1.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 121 KiB |
BIN
docs/static/synology-proxy-2.png
vendored
Normal file
BIN
docs/static/synology-proxy-2.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 502 KiB |
1
docs/themes/vikunja
vendored
1
docs/themes/vikunja
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 958219fc84db455ed58d7a4380bbffc8d04fd5cf
|
103
go.mod
103
go.mod
@ -17,85 +17,66 @@
|
||||
module code.vikunja.io/api
|
||||
|
||||
require (
|
||||
4d63.com/tz v1.2.0
|
||||
code.vikunja.io/web v0.0.0-20201223143420-588abb73703a
|
||||
dmitri.shuralyov.com/go/generated v0.0.0-20170818220700-b1254a446363 // indirect
|
||||
code.vikunja.io/web v0.0.0-20210706160506-d85def955bd3
|
||||
gitea.com/xorm/xorm-redis-cache v0.2.0
|
||||
github.com/adlio/trello v1.8.0
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||
github.com/ThreeDotsLabs/watermill v1.1.1
|
||||
github.com/adlio/trello v1.9.0
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef
|
||||
github.com/bbrks/go-blurhash v1.1.1
|
||||
github.com/beevik/etree v1.1.0 // indirect
|
||||
github.com/c2h5oh/datasize v0.0.0-20200825124411-48ed595a09d2
|
||||
github.com/client9/misspell v0.3.4
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
github.com/coreos/go-oidc/v3 v3.2.0
|
||||
github.com/cweill/gotests v1.6.0
|
||||
github.com/d4l3k/messagediff v1.2.1
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/dustinkirkland/golang-petname v0.0.0-20191129215211-8e5a1ed0cff0
|
||||
github.com/fzipp/gocyclo v0.3.1
|
||||
github.com/gabriel-vasile/mimetype v1.1.2
|
||||
github.com/getsentry/sentry-go v0.9.0
|
||||
github.com/go-errors/errors v1.1.1
|
||||
github.com/go-redis/redis/v8 v8.4.8
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.4.1
|
||||
github.com/gabriel-vasile/mimetype v1.4.0
|
||||
github.com/getsentry/sentry-go v0.13.0
|
||||
github.com/go-errors/errors v1.1.1 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/go-testfixtures/testfixtures/v3 v3.6.1
|
||||
github.com/golang-jwt/jwt/v4 v4.4.1
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
||||
github.com/golang/snappy v0.0.2 // indirect
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20210104184537-8eed68eb605f
|
||||
github.com/iancoleman/strcase v0.1.2
|
||||
github.com/imdario/mergo v0.3.11
|
||||
github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/labstack/echo/v4 v4.1.17
|
||||
github.com/labstack/gommon v0.3.0
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/iancoleman/strcase v0.2.0
|
||||
github.com/imdario/mergo v0.3.13
|
||||
github.com/labstack/echo/v4 v4.7.2
|
||||
github.com/labstack/gommon v0.3.1
|
||||
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef
|
||||
github.com/lib/pq v1.9.0
|
||||
github.com/magefile/mage v1.11.0
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.6
|
||||
github.com/mitchellh/mapstructure v1.3.2 // indirect
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.4
|
||||
github.com/lib/pq v1.10.6
|
||||
github.com/magefile/mage v1.13.0
|
||||
github.com/mattn/go-sqlite3 v1.14.13
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||
github.com/pelletier/go-toml v1.8.0 // indirect
|
||||
github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e // indirect
|
||||
github.com/pquerna/otp v1.3.0
|
||||
github.com/prometheus/client_golang v1.9.0
|
||||
github.com/prometheus/client_golang v1.12.2
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/samedi/caldav-go v3.0.0+incompatible
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
|
||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
|
||||
github.com/spf13/afero v1.5.1
|
||||
github.com/spf13/cast v1.3.1 // indirect
|
||||
github.com/spf13/cobra v1.1.1
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/viper v1.7.1
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/swaggo/swag v1.7.0
|
||||
github.com/ulule/limiter/v3 v3.8.0
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5
|
||||
golang.org/x/net v0.0.0-20201216054612-986b41b23924 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||
golang.org/x/sys v0.0.0-20201223074533-0d417f636930 // indirect
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf
|
||||
github.com/spf13/afero v1.8.2
|
||||
github.com/spf13/cobra v1.4.0
|
||||
github.com/spf13/viper v1.11.0
|
||||
github.com/stretchr/testify v1.7.2
|
||||
github.com/swaggo/swag v1.8.2
|
||||
github.com/tkuchiki/go-timezone v0.2.2
|
||||
github.com/ulule/limiter/v3 v3.10.0
|
||||
github.com/vectordotdev/go-datemath v0.1.1-0.20211214182920-0a4ac8742b93
|
||||
github.com/yuin/goldmark v1.4.12
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/d4l3k/messagediff.v1 v1.2.1
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/ini.v1 v1.57.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c
|
||||
honnef.co/go/tools v0.0.1-2020.1.5
|
||||
src.techknowlogick.com/xgo v1.2.1-0.20201205054505-b97762e7a76b
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
src.techknowlogick.com/xgo v1.4.1-0.20210311222705-d25c33fcd864
|
||||
src.techknowlogick.com/xormigrate v1.4.0
|
||||
xorm.io/builder v0.3.7
|
||||
xorm.io/builder v0.3.9
|
||||
xorm.io/core v0.7.3
|
||||
xorm.io/xorm v1.0.5
|
||||
xorm.io/xorm v1.1.2
|
||||
)
|
||||
|
||||
replace (
|
||||
@ -107,4 +88,4 @@ replace (
|
||||
gopkg.in/fsnotify.v1 => github.com/kolaente/fsnotify v1.4.10-0.20200411160148-1bc3c8ff4048 // See https://github.com/fsnotify/fsnotify/issues/328 and https://github.com/golang/go/issues/26904
|
||||
)
|
||||
|
||||
go 1.13
|
||||
go 1.15
|
||||
|
283
magefile.go
283
magefile.go
@ -1,5 +1,5 @@
|
||||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||
@ -14,6 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public Licensee
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//go:build mage
|
||||
// +build mage
|
||||
|
||||
package main
|
||||
@ -24,6 +25,7 @@ import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"github.com/iancoleman/strcase"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -51,28 +53,41 @@ var (
|
||||
Ldflags = ""
|
||||
Tags = ""
|
||||
VersionNumber = "dev"
|
||||
Version = "master" // This holds the built version, master by default, when building from a tag or release branch, their name
|
||||
Version = "unstable" // This holds the built version, unstable by default, when building from a tag or release branch, their name
|
||||
BinLocation = ""
|
||||
PkgVersion = "master"
|
||||
PkgVersion = "unstable"
|
||||
ApiPackages = []string{}
|
||||
RootPath = ""
|
||||
GoFiles = []string{}
|
||||
|
||||
// Aliases are mage aliases of targets
|
||||
Aliases = map[string]interface{}{
|
||||
"build": Build.Build,
|
||||
"do-the-swag": DoTheSwag,
|
||||
"check:got-swag": Check.GotSwag,
|
||||
"release:os-package": Release.OsPackage,
|
||||
"dev:create-migration": Dev.CreateMigration,
|
||||
"generate-docs": GenerateDocs,
|
||||
"check:golangci-fix": Check.GolangciFix,
|
||||
"build": Build.Build,
|
||||
"do-the-swag": DoTheSwag,
|
||||
"check:got-swag": Check.GotSwag,
|
||||
"release:os-package": Release.OsPackage,
|
||||
"dev:make-migration": Dev.MakeMigration,
|
||||
"dev:make-event": Dev.MakeEvent,
|
||||
"dev:make-listener": Dev.MakeListener,
|
||||
"dev:make-notification": Dev.MakeNotification,
|
||||
"generate-docs": GenerateDocs,
|
||||
"check:golangci-fix": Check.GolangciFix,
|
||||
}
|
||||
)
|
||||
|
||||
func runCmdWithOutput(name string, arg ...string) (output []byte, err error) {
|
||||
cmd := exec.Command(name, arg...)
|
||||
output, err = cmd.Output()
|
||||
if err != nil {
|
||||
ee := err.(*exec.ExitError)
|
||||
return nil, fmt.Errorf("error running command: %s, %s", string(ee.Stderr), err)
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func setVersion() {
|
||||
versionCmd := exec.Command("git", "describe", "--tags", "--always", "--abbrev=10")
|
||||
version, err := versionCmd.Output()
|
||||
version, err := runCmdWithOutput("git", "describe", "--tags", "--always", "--abbrev=10")
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting version: %s\n", err)
|
||||
os.Exit(1)
|
||||
@ -86,6 +101,10 @@ func setVersion() {
|
||||
} else if os.Getenv("DRONE_BRANCH") != "" {
|
||||
Version = strings.Replace(os.Getenv("DRONE_BRANCH"), "release/v", "", 1)
|
||||
}
|
||||
|
||||
if Version == "main" {
|
||||
Version = "unstable"
|
||||
}
|
||||
}
|
||||
|
||||
func setBinLocation() {
|
||||
@ -97,7 +116,7 @@ func setBinLocation() {
|
||||
}
|
||||
|
||||
func setPkgVersion() {
|
||||
if Version == "master" {
|
||||
if Version == "unstable" {
|
||||
PkgVersion = VersionNumber
|
||||
}
|
||||
}
|
||||
@ -109,8 +128,7 @@ func setExecutable() {
|
||||
}
|
||||
|
||||
func setApiPackages() {
|
||||
cmd := exec.Command("go", "list", "all")
|
||||
pkgs, err := cmd.Output()
|
||||
pkgs, err := runCmdWithOutput("go", "list", "all")
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting packages: %s\n", err)
|
||||
os.Exit(1)
|
||||
@ -137,8 +155,7 @@ func setRootPath() {
|
||||
|
||||
func setGoFiles() {
|
||||
// GOFILES := $(shell find . -name "*.go" -type f ! -path "*/bindata.go")
|
||||
cmd := exec.Command("find", ".", "-name", "*.go", "-type", "f", "!", "-path", "*/bindata.go")
|
||||
files, err := cmd.Output()
|
||||
files, err := runCmdWithOutput("find", ".", "-name", "*.go", "-type", "f", "!", "-path", "*/bindata.go")
|
||||
if err != nil {
|
||||
fmt.Printf("Error getting go files: %s\n", err)
|
||||
os.Exit(1)
|
||||
@ -162,7 +179,6 @@ func initVars() {
|
||||
setVersion()
|
||||
setBinLocation()
|
||||
setPkgVersion()
|
||||
setApiPackages()
|
||||
setGoFiles()
|
||||
Ldflags = `-X "` + PACKAGE + `/pkg/version.Version=` + VersionNumber + `" -X "main.Tags=` + Tags + `"`
|
||||
}
|
||||
@ -294,6 +310,25 @@ func moveFile(src, dst string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func appendToFile(filename, content string) error {
|
||||
f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.WriteString(content)
|
||||
return err
|
||||
}
|
||||
|
||||
const InfoColor = "\033[1;32m%s\033[0m"
|
||||
|
||||
func printSuccess(text string, args ...interface{}) {
|
||||
text = fmt.Sprintf(text, args...)
|
||||
fmt.Printf(InfoColor+"\n", text)
|
||||
}
|
||||
|
||||
// Formats the code using go fmt
|
||||
func Fmt() {
|
||||
mg.Deps(initVars)
|
||||
@ -313,8 +348,9 @@ type Test mg.Namespace
|
||||
// Runs all tests except integration tests
|
||||
func (Test) Unit() {
|
||||
mg.Deps(initVars)
|
||||
setApiPackages()
|
||||
// We run everything sequentially and not in parallel to prevent issues with real test databases
|
||||
args := append([]string{"test", Goflags[0], "-p", "1"}, ApiPackages...)
|
||||
args := append([]string{"test", Goflags[0], "-p", "1", "-coverprofile", "cover.out", "-timeout", "20m"}, ApiPackages...)
|
||||
runAndStreamOutput("go", args...)
|
||||
}
|
||||
|
||||
@ -329,7 +365,7 @@ func (Test) Coverage() {
|
||||
func (Test) Integration() {
|
||||
mg.Deps(initVars)
|
||||
// We run everything sequentially and not in parallel to prevent issues with real test databases
|
||||
runAndStreamOutput("go", "test", Goflags[0], "-p", "1", PACKAGE+"/pkg/integrations")
|
||||
runAndStreamOutput("go", "test", Goflags[0], "-p", "1", "-timeout", "20m", PACKAGE+"/pkg/integrations")
|
||||
}
|
||||
|
||||
type Check mg.Namespace
|
||||
@ -383,7 +419,7 @@ func (Check) GolangciFix() {
|
||||
runAndStreamOutput("golangci-lint", "run", "--fix")
|
||||
}
|
||||
|
||||
// Runs fmt-check, lint, got-swag, misspell-check, ineffasign-check, gocyclo-check, static-check, gosec-check, goconst-check all in parallel
|
||||
// Runs golangci and the swagger test in parralel
|
||||
func (Check) All() {
|
||||
mg.Deps(initVars)
|
||||
mg.Deps(
|
||||
@ -412,16 +448,9 @@ func (Build) Clean() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generates static content into the final binary
|
||||
func (Build) Generate() {
|
||||
mg.Deps(initVars)
|
||||
runAndStreamOutput("go", "generate", PACKAGE+"/pkg/static")
|
||||
}
|
||||
|
||||
// Builds a vikunja binary, ready to run
|
||||
func (Build) Build() {
|
||||
mg.Deps(initVars)
|
||||
mg.Deps(Build.Generate)
|
||||
runAndStreamOutput("go", "build", Goflags[0], "-tags", Tags, "-ldflags", "-s -w "+Ldflags, "-o", Executable)
|
||||
}
|
||||
|
||||
@ -430,8 +459,7 @@ type Release mg.Namespace
|
||||
// Runs all steps in the right order to create release packages for various platforms
|
||||
func (Release) Release(ctx context.Context) error {
|
||||
mg.Deps(initVars)
|
||||
mg.Deps(Build.Generate, Release.Dirs)
|
||||
mg.Deps(Release.Windows, Release.Linux, Release.Darwin)
|
||||
mg.Deps(Release.Dirs)
|
||||
|
||||
// Run compiling in parallel to speed it up
|
||||
errs, _ := errgroup.WithContext(ctx)
|
||||
@ -514,7 +542,7 @@ func (Release) Linux() error {
|
||||
|
||||
// Builds binaries for darwin
|
||||
func (Release) Darwin() error {
|
||||
return runXgo("darwin/*")
|
||||
return runXgo("darwin-10.15/*")
|
||||
}
|
||||
|
||||
// Compresses the built binaries in dist/binaries/ to reduce their filesize
|
||||
@ -695,7 +723,7 @@ func (Release) Packages() error {
|
||||
type Dev mg.Namespace
|
||||
|
||||
// Creates a new bare db migration skeleton in pkg/migration with the current date
|
||||
func (Dev) CreateMigration() error {
|
||||
func (Dev) MakeMigration() error {
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
fmt.Print("Enter the name of the struct: ")
|
||||
@ -705,7 +733,7 @@ func (Dev) CreateMigration() error {
|
||||
date := time.Now().Format("20060102150405")
|
||||
|
||||
migration := `// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||
@ -747,14 +775,175 @@ func init() {
|
||||
})
|
||||
}
|
||||
`
|
||||
f, err := os.Create(RootPath + "/pkg/migration/" + date + ".go")
|
||||
filename := "/pkg/migration/" + date + ".go"
|
||||
f, err := os.Create(RootPath + filename)
|
||||
defer f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = f.WriteString(migration)
|
||||
return err
|
||||
if _, err := f.WriteString(migration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printSuccess("Migration has been created at %s!", filename)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create a new event. Takes the name of the event as the first argument and the module where the event should be created as the second argument. Events will be appended to the pkg/<module>/events.go file.
|
||||
func (Dev) MakeEvent(name, module string) error {
|
||||
|
||||
name = strcase.ToCamel(name)
|
||||
|
||||
if !strings.HasSuffix(name, "Event") {
|
||||
name += "Event"
|
||||
}
|
||||
|
||||
eventName := strings.ReplaceAll(strcase.ToDelimited(name, '.'), ".event", "")
|
||||
|
||||
newEventCode := `
|
||||
// ` + name + ` represents a ` + name + ` event
|
||||
type ` + name + ` struct {
|
||||
}
|
||||
|
||||
// Name defines the name for ` + name + `
|
||||
func (t *` + name + `) Name() string {
|
||||
return "` + eventName + `"
|
||||
}
|
||||
`
|
||||
filename := "./pkg/" + module + "/events.go"
|
||||
if err := appendToFile(filename, newEventCode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printSuccess("The new event has been created successfully! Head over to %s and adjust its content.", filename)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create a new listener for an event. Takes the name of the listener, the name of the event to listen to and the module where everything should be placed as parameters.
|
||||
func (Dev) MakeListener(name, event, module string) error {
|
||||
name = strcase.ToCamel(name)
|
||||
listenerName := strcase.ToDelimited(name, '.')
|
||||
listenerCode := `
|
||||
// ` + name + ` represents a listener
|
||||
type ` + name + ` struct {
|
||||
}
|
||||
|
||||
// Name defines the name for the ` + name + ` listener
|
||||
func (s *` + name + `) Name() string {
|
||||
return "` + listenerName + `"
|
||||
}
|
||||
|
||||
// Handle is executed when the event ` + name + ` listens on is fired
|
||||
func (s *` + name + `) Handle(msg *message.Message) (err error) {
|
||||
event := &` + event + `{}
|
||||
err = json.Unmarshal(msg.Payload, event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
`
|
||||
filename := "./pkg/" + module + "/listeners.go"
|
||||
|
||||
//////
|
||||
// Register the listener
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
var idx int64 = 0
|
||||
for scanner.Scan() {
|
||||
if scanner.Text() == "}" {
|
||||
//idx -= int64(len(scanner.Text()))
|
||||
break
|
||||
}
|
||||
idx += int64(len(scanner.Bytes()) + 1)
|
||||
}
|
||||
file.Close()
|
||||
|
||||
registerListenerCode := ` events.RegisterListener((&` + event + `{}).Name(), &` + name + `{})
|
||||
`
|
||||
|
||||
f, err := os.OpenFile(filename, os.O_RDWR, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
if _, err := f.Seek(idx, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
remainder, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Seek(idx, 0)
|
||||
f.Write([]byte(registerListenerCode))
|
||||
f.Write(remainder)
|
||||
|
||||
///////
|
||||
// Append the listener code
|
||||
if err := appendToFile(filename, listenerCode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printSuccess("The new listener has been created successfully! Head over to %s and adjust its content.", filename)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create a new notification. Takes the name of the notification as the first argument and the module where the notification should be created as the second argument. Notifications will be appended to the pkg/<module>/notifications.go file.
|
||||
func (Dev) MakeNotification(name, module string) error {
|
||||
|
||||
name = strcase.ToCamel(name)
|
||||
|
||||
if !strings.HasSuffix(name, "Notification") {
|
||||
name += "Notification"
|
||||
}
|
||||
|
||||
notficationName := strings.ReplaceAll(strcase.ToDelimited(name, '.'), ".notification", "")
|
||||
|
||||
newNotificationCode := `
|
||||
// ` + name + ` represents a ` + name + ` notification
|
||||
type ` + name + ` struct {
|
||||
}
|
||||
|
||||
// ToMail returns the mail notification for ` + name + `
|
||||
func (n *` + name + `) ToMail() *notifications.Mail {
|
||||
return notifications.NewMail().
|
||||
Subject("").
|
||||
Greeting("Hi ").
|
||||
Line("").
|
||||
Action("", "")
|
||||
}
|
||||
|
||||
// ToDB returns the ` + name + ` notification in a format which can be saved in the db
|
||||
func (n *` + name + `) ToDB() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Name returns the name of the notification
|
||||
func (n *` + name + `) Name() string {
|
||||
return "` + notficationName + `"
|
||||
}
|
||||
|
||||
`
|
||||
filename := "./pkg/" + module + "/notifications.go"
|
||||
if err := appendToFile(filename, newNotificationCode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printSuccess("The new notification has been created successfully! Head over to %s and adjust its content.", filename)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type configOption struct {
|
||||
@ -815,13 +1004,20 @@ func parseYamlConfigNode(node *yaml.Node) (config *configOption) {
|
||||
return config
|
||||
}
|
||||
|
||||
func printConfig(config []*configOption, level int) (rendered string) {
|
||||
func printConfig(config []*configOption, level int, parent string) (rendered string) {
|
||||
|
||||
// Keep track of what we already printed to prevent printing things twice
|
||||
printed := make(map[string]bool)
|
||||
|
||||
for _, option := range config {
|
||||
|
||||
// FIXME: Not a good solution. Ideally this would work without the level check, but since generating config
|
||||
// for more than two levels is currently broken anyway, I'll fix this after moving the config generation
|
||||
// to a better format than yaml.
|
||||
if level == 0 && option.key != "" {
|
||||
parent = option.key
|
||||
}
|
||||
|
||||
if option.key != "" {
|
||||
|
||||
// Filter out all config objects where the default value == key
|
||||
@ -850,12 +1046,17 @@ func printConfig(config []*configOption, level int) (rendered string) {
|
||||
if option.defaultValue == "" {
|
||||
rendered += "<empty>"
|
||||
}
|
||||
rendered += "`\n"
|
||||
rendered += "`\n\n"
|
||||
|
||||
fullPath := parent + "." + option.key
|
||||
|
||||
rendered += "Full path: `" + fullPath + "`\n\n"
|
||||
rendered += "Environment path: `VIKUNJA_" + strcase.ToScreamingSnake(fullPath) + "`\n\n"
|
||||
}
|
||||
}
|
||||
|
||||
printed[option.key] = true
|
||||
rendered += "\n" + printConfig(option.children, level+1)
|
||||
rendered += "\n" + printConfig(option.children, level+1, parent)
|
||||
}
|
||||
|
||||
return
|
||||
@ -866,7 +1067,7 @@ const (
|
||||
configInjectComment = `<!-- Generated config will be injected here -->`
|
||||
)
|
||||
|
||||
// Generates the error docs from a commented config.yml.sample file in the repo root.
|
||||
// Generates the config docs from a commented config.yml.sample file in the repo root.
|
||||
func GenerateDocs() error {
|
||||
|
||||
config, err := ioutil.ReadFile("config.yml.sample")
|
||||
@ -889,7 +1090,7 @@ func GenerateDocs() error {
|
||||
}
|
||||
}
|
||||
|
||||
renderedConfig := printConfig(conf, 0)
|
||||
renderedConfig := printConfig(conf, 0, "")
|
||||
|
||||
// Rebuild the config
|
||||
file, err := os.OpenFile(configDocPath, os.O_RDWR, 0)
|
||||
|
2
main.go
2
main.go
@ -1,5 +1,5 @@
|
||||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||
|
@ -8,6 +8,8 @@ homepage: "https://vikunja.io"
|
||||
section: "default"
|
||||
priority: "extra"
|
||||
license: "AGPLv3"
|
||||
depends:
|
||||
- systemd
|
||||
contents:
|
||||
- src: <binlocation>
|
||||
dst: /opt/vikunja/vikunja
|
||||
@ -17,5 +19,7 @@ contents:
|
||||
- src: /opt/vikunja/vikunja
|
||||
dst: /usr/local/bin/vikunja
|
||||
type: "symlink"
|
||||
- src: vikunja.service
|
||||
dst: /usr/lib/systemd/system/vikunja.service
|
||||
scripts:
|
||||
postinstall: ./build/after-install.sh
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||
@ -216,7 +216,7 @@ DURATION:PT` + fmt.Sprintf("%.6f", t.Duration.Hours()) + `H` + fmt.Sprintf("%.6f
|
||||
|
||||
if t.Priority != 0 {
|
||||
caldavtodos += `
|
||||
PRIORITY:` + strconv.Itoa(int(t.Priority))
|
||||
PRIORITY:` + strconv.Itoa(mapPriorityToCaldav(t.Priority))
|
||||
}
|
||||
|
||||
caldavtodos += `
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||
@ -375,6 +375,39 @@ COMPLETED:20181201T013024
|
||||
STATUS:COMPLETED
|
||||
LAST-MODIFIED:00010101T000000
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
{
|
||||
name: "with priority",
|
||||
args: args{
|
||||
config: &Config{
|
||||
Name: "test",
|
||||
ProdID: "RandomProdID which is not random",
|
||||
},
|
||||
todos: []*Todo{
|
||||
{
|
||||
Summary: "Todo #1",
|
||||
Description: "Lorem Ipsum",
|
||||
UID: "randommduid",
|
||||
Priority: 1,
|
||||
Timestamp: time.Unix(1543626724, 0).In(config.GetTimeZone()),
|
||||
},
|
||||
},
|
||||
},
|
||||
wantCaldavtasks: `BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
METHOD:PUBLISH
|
||||
X-PUBLISHED-TTL:PT4H
|
||||
X-WR-CALNAME:test
|
||||
PRODID:-//RandomProdID which is not random//EN
|
||||
BEGIN:VTODO
|
||||
UID:randommduid
|
||||
DTSTAMP:20181201T011204
|
||||
SUMMARY:Todo #1
|
||||
DESCRIPTION:Lorem Ipsum
|
||||
PRIORITY:9
|
||||
LAST-MODIFIED:00010101T000000
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
|
||||
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||
@ -21,21 +21,20 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.vikunja.io/api/pkg/caldav"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"github.com/laurent22/ical-go"
|
||||
)
|
||||
|
||||
func getCaldavTodosForTasks(list *models.List, listTasks []*models.Task) string {
|
||||
func GetCaldavTodosForTasks(list *models.ListWithTasksAndBuckets, listTasks []*models.TaskWithComments) string {
|
||||
|
||||
// Make caldav todos from Vikunja todos
|
||||
var caldavtodos []*caldav.Todo
|
||||
var caldavtodos []*Todo
|
||||
for _, t := range listTasks {
|
||||
|
||||
duration := t.EndDate.Sub(t.StartDate)
|
||||
|
||||
caldavtodos = append(caldavtodos, &caldav.Todo{
|
||||
caldavtodos = append(caldavtodos, &Todo{
|
||||
Timestamp: t.Updated,
|
||||
UID: t.UID,
|
||||
Summary: t.Title,
|
||||
@ -52,15 +51,15 @@ func getCaldavTodosForTasks(list *models.List, listTasks []*models.Task) string
|
||||
})
|
||||
}
|
||||
|
||||
caldavConfig := &caldav.Config{
|
||||
caldavConfig := &Config{
|
||||
Name: list.Title,
|
||||
ProdID: "Vikunja Todo App",
|
||||
}
|
||||
|
||||
return caldav.ParseTodos(caldavConfig, caldavtodos)
|
||||
return ParseTodos(caldavConfig, caldavtodos)
|
||||
}
|
||||
|
||||
func parseTaskFromVTODO(content string) (vTask *models.Task, err error) {
|
||||
func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
|
||||
parsed, err := ical.ParseCalendar(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -78,13 +77,15 @@ func parseTaskFromVTODO(content string) (vTask *models.Task, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the UID
|
||||
// Parse the priority
|
||||
var priority int64
|
||||
if _, ok := task["PRIORITY"]; ok {
|
||||
priority, err = strconv.ParseInt(task["PRIORITY"], 10, 64)
|
||||
priorityParsed, err := strconv.ParseInt(task["PRIORITY"], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
priority = parseVTODOPriority(priorityParsed)
|
||||
}
|
||||
|
||||
// Parse the enddate
|
||||
@ -118,7 +119,7 @@ func caldavTimeToTimestamp(tstring string) time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
format := caldav.DateFormat
|
||||
format := DateFormat
|
||||
|
||||
if strings.HasSuffix(tstring, "Z") {
|
||||
format = `20060102T150405Z`
|
101
pkg/caldav/parsing_test.go
Normal file
101
pkg/caldav/parsing_test.go
Normal file
@ -0,0 +1,101 @@
|
||||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public Licensee for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public Licensee
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package caldav
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.vikunja.io/api/pkg/config"
|
||||
"code.vikunja.io/api/pkg/models"
|
||||
"gopkg.in/d4l3k/messagediff.v1"
|
||||
)
|
||||
|
||||
func TestParseTaskFromVTODO(t *testing.T) {
|
||||
type args struct {
|
||||
content string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantVTask *models.Task
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "normal",
|
||||
args: args{content: `BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
METHOD:PUBLISH
|
||||
X-PUBLISHED-TTL:PT4H
|
||||
X-WR-CALNAME:test
|
||||
PRODID:-//RandomProdID which is not random//EN
|
||||
BEGIN:VTODO
|
||||
UID:randomuid
|
||||
DTSTAMP:20181201T011204
|
||||
SUMMARY:Todo #1
|
||||
DESCRIPTION:Lorem Ipsum
|
||||
LAST-MODIFIED:00010101T000000
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
wantVTask: &models.Task{
|
||||
Title: "Todo #1",
|
||||
UID: "randomuid",
|
||||
Description: "Lorem Ipsum",
|
||||
Updated: time.Unix(1543626724, 0).In(config.GetTimeZone()),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "With priority",
|
||||
args: args{content: `BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
METHOD:PUBLISH
|
||||
X-PUBLISHED-TTL:PT4H
|
||||
X-WR-CALNAME:test
|
||||
PRODID:-//RandomProdID which is not random//EN
|
||||
BEGIN:VTODO
|
||||
UID:randomuid
|
||||
DTSTAMP:20181201T011204
|
||||
SUMMARY:Todo #1
|
||||
DESCRIPTION:Lorem Ipsum
|
||||
PRIORITY:9
|
||||
LAST-MODIFIED:00010101T000000
|
||||
END:VTODO
|
||||
END:VCALENDAR`,
|
||||
},
|
||||
wantVTask: &models.Task{
|
||||
Title: "Todo #1",
|
||||
UID: "randomuid",
|
||||
Description: "Lorem Ipsum",
|
||||
Priority: 1,
|
||||
Updated: time.Unix(1543626724, 0).In(config.GetTimeZone()),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := ParseTaskFromVTODO(tt.args.content)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ParseTaskFromVTODO() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if diff, equal := messagediff.PrettyDiff(got, tt.wantVTask); !equal {
|
||||
t.Errorf("ParseTaskFromVTODO() gotVTask = %v, want %v, diff = %s", got, tt.wantVTask, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
66
pkg/caldav/priority.go
Normal file
66
pkg/caldav/priority.go
Normal file
@ -0,0 +1,66 @@
|
||||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public Licensee for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public Licensee
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package caldav
|
||||
|
||||
// In caldav, priority values are an int from 0 to 9 where 1 is the highest priority and 9 the lowest. 0 is "unset".
|
||||
// Vikunja only has priorites from 0 to 5 where 0 is unset and 5 is the highest
|
||||
// See https://icalendar.org/iCalendar-RFC-5545/3-8-1-9-priority.html
|
||||
func mapPriorityToCaldav(priority int64) (caldavPriority int) {
|
||||
switch priority {
|
||||
case 0:
|
||||
return 0
|
||||
case 1: // Low
|
||||
return 9
|
||||
case 2: // Medium
|
||||
return 5
|
||||
case 3: // High
|
||||
return 3
|
||||
case 4: // Urgent
|
||||
return 2
|
||||
case 5: // DO NOW
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// See mapPriorityToCaldav
|
||||
func parseVTODOPriority(priority int64) (vikunjaPriority int64) {
|
||||
switch priority {
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return 5
|
||||
case 2:
|
||||
return 4
|
||||
case 3:
|
||||
return 3
|
||||
case 4:
|
||||
return 3
|
||||
case 5:
|
||||
return 2
|
||||
case 6:
|
||||
return 1
|
||||
case 7:
|
||||
return 1
|
||||
case 8:
|
||||
return 1
|
||||
case 9:
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
131
pkg/caldav/priority_test.go
Normal file
131
pkg/caldav/priority_test.go
Normal file
@ -0,0 +1,131 @@
|
||||
// Vikunja is a to-do list application to facilitate your life.
|
||||
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public Licensee as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public Licensee for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public Licensee
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package caldav
|
||||
|
||||
import "testing"
|
||||
|
||||
func Test_parseVTODOPriority(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
priority int64
|
||||
want int64
|
||||
}{
|
||||
{
|
||||
name: "unset",
|
||||
priority: 0,
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "DO NOW",
|
||||
priority: 1,
|
||||
want: 5,
|
||||
},
|
||||
{
|
||||
name: "urgent",
|
||||
priority: 2,
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
name: "high 1",
|
||||
priority: 3,
|
||||
want: 3,
|
||||
},
|
||||
{
|
||||
name: "high 2",
|
||||
priority: 4,
|
||||
want: 3,
|
||||
},
|
||||
{
|
||||
name: "medium",
|
||||
priority: 5,
|
||||
want: 2,
|
||||
},
|
||||
{
|
||||
name: "low 1",
|
||||
priority: 6,
|
||||
want: 1,
|
||||
},
|
||||
{
|
||||
name: "low 2",
|
||||
priority: 7,
|
||||
want: 1,
|
||||
},
|
||||
{
|
||||
name: "low 3",
|
||||
priority: 8,
|
||||
want: 1,
|
||||
},
|
||||
{
|
||||
name: "low 4",
|
||||
priority: 9,
|
||||
want: 1,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if gotVikunjaPriority := parseVTODOPriority(tt.priority); gotVikunjaPriority != tt.want {
|
||||
t.Errorf("parseVTODOPriority() = %v, want %v", gotVikunjaPriority, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_mapPriorityToCaldav(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
priority int64
|
||||
wantCaldavPriority int
|
||||
}{
|
||||
{
|
||||
name: "unset",
|
||||
priority: 0,
|
||||
wantCaldavPriority: 0,
|
||||
},
|
||||
{
|
||||
name: "low",
|
||||
priority: 1,
|
||||
wantCaldavPriority: 9,
|
||||