Compare commits
519 Commits
feat/serve
...
release/ne
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab80cb7544 | ||
|
|
b5c3d87290 | ||
|
|
97220102e4 | ||
|
|
6430c88b84 | ||
|
|
df7efc4945 | ||
|
|
646bb372ab | ||
|
|
836d22570f | ||
|
|
3b0be896e6 | ||
|
|
be0eef405d | ||
|
|
a244d94ac8 | ||
|
|
2ee903a81c | ||
|
|
5414302350 | ||
|
|
1803692eab | ||
|
|
9219d559a0 | ||
|
|
d6c5a382f8 | ||
|
|
deb3a620e1 | ||
|
|
7e5592fec5 | ||
|
|
ccc0961ba3 | ||
|
|
497003ec57 | ||
|
|
d0d269677e | ||
|
|
c2775894e1 | ||
|
|
357ec1394a | ||
|
|
4fedae4150 | ||
|
|
b52e8cd570 | ||
|
|
984fb12ada | ||
|
|
f88f1265b6 | ||
|
|
af51a11b1b | ||
|
|
d942e7212a | ||
|
|
2792d97027 | ||
|
|
574d9c34ff | ||
|
|
3cb284c15a | ||
|
|
41c5a0ca2f | ||
|
|
6d9dc46619 | ||
|
|
20dca39143 | ||
|
|
84679fb2b2 | ||
|
|
a96a08939e | ||
|
|
9b2939d778 | ||
|
|
bccad2940e | ||
|
|
dd72c32c60 | ||
|
|
4bd01b70ff | ||
|
|
945f7fb9ea | ||
|
|
78f400305b | ||
|
|
55477a8a1a | ||
|
|
7cbfc12e0d | ||
|
|
c320146538 | ||
|
|
3304c8efd8 | ||
|
|
2dcb4efc40 | ||
|
|
2f1d1edf10 | ||
|
|
1b032339aa | ||
|
|
dc82c13ddc | ||
|
|
417af66f30 | ||
|
|
280f906e4b | ||
|
|
b669714bda | ||
|
|
0f6606848e | ||
|
|
1a8671d940 | ||
|
|
fb94ee80aa | ||
|
|
083ee0b5fe | ||
|
|
0bae88bef6 | ||
|
|
184f1a6d32 | ||
|
|
248cb86143 | ||
|
|
1649d87360 | ||
|
|
8970566865 | ||
|
|
0b4a96140e | ||
|
|
72caf8983c | ||
|
|
61a9d5cbc7 | ||
|
|
ca0d4b283a | ||
|
|
2b4e4051f0 | ||
|
|
0f3956f654 | ||
|
|
99bd7d5f27 | ||
|
|
fe1d0edf4c | ||
|
|
4ef699e9fa | ||
|
|
3e21174dd8 | ||
|
|
1b56bb84f9 | ||
|
|
b3f5b8ede8 | ||
|
|
2b77dc8e1f | ||
|
|
97a594556b | ||
|
|
4a7c4b6d15 | ||
|
|
a8198f9934 | ||
|
|
b123beae38 | ||
|
|
1ada7a8340 | ||
|
|
5d81cace23 | ||
|
|
65f9a228ba | ||
|
|
e6eca895ba | ||
|
|
8196bd9bbd | ||
|
|
07675a2de4 | ||
|
|
a2b03f7650 | ||
|
|
fdff591a11 | ||
|
|
e4443fa43e | ||
|
|
843d563178 | ||
|
|
256d62e22d | ||
|
|
91592aa48e | ||
|
|
2ac113624b | ||
|
|
0052979853 | ||
|
|
79b6c4ac70 | ||
|
|
95eb3e26c3 | ||
|
|
613dc858cb | ||
|
|
2f3fbd7dc5 | ||
|
|
80a5444bf4 | ||
|
|
d59ee7d2ae | ||
|
|
7b3a298c6a | ||
|
|
0a62ec7e29 | ||
|
|
21802ab5ba | ||
|
|
56dfdfd033 | ||
|
|
2190921c85 | ||
|
|
9fa8de7baa | ||
|
|
ed9448a6ee | ||
|
|
15224a9ac5 | ||
|
|
6e00fd92ef | ||
|
|
6fdd1ce41a | ||
|
|
91d4cd6824 | ||
|
|
c7254a0c30 | ||
|
|
38f01a6b7d | ||
|
|
f194a7ea3e | ||
|
|
05a7ba98c1 | ||
|
|
edc513a3df | ||
|
|
39212a049c | ||
|
|
9b4f370834 | ||
|
|
aba85b036c | ||
|
|
6e86697996 | ||
|
|
cc90c912f5 | ||
|
|
efd20ef0d4 | ||
|
|
0c0aa1f3c3 | ||
|
|
231a475a17 | ||
|
|
94ea83c415 | ||
|
|
4b5b9baa78 | ||
|
|
3bf0d5b99f | ||
|
|
8ed81ac3e1 | ||
|
|
7992fe85d6 | ||
|
|
afe925a55e | ||
|
|
5e3f5f2b55 | ||
|
|
d4ad523eb3 | ||
|
|
e8c80d88a5 | ||
|
|
76241a7b2b | ||
|
|
1e4af9731d | ||
|
|
88327fb872 | ||
|
|
702499b97d | ||
|
|
da248414af | ||
|
|
af2c232c87 | ||
|
|
cca037b03c | ||
|
|
1d71bb5a79 | ||
|
|
ee4f2c735d | ||
|
|
4d559a63ec | ||
|
|
573e9b0d52 | ||
|
|
a2502109ab | ||
|
|
3cdece4945 | ||
|
|
520b825511 | ||
|
|
191401f2f1 | ||
|
|
8136d7fd54 | ||
|
|
5d1e486478 | ||
|
|
85b0b97ef2 | ||
|
|
471fab0591 | ||
|
|
6997ed83c4 | ||
|
|
a2ba36c16d | ||
|
|
109c79125d | ||
|
|
fbd49e0b79 | ||
|
|
1f20b6471c | ||
|
|
1d6a9f6e80 | ||
|
|
0a9f1a3cbf | ||
|
|
4f803832ad | ||
|
|
ef4aec7398 | ||
|
|
5bb3492616 | ||
|
|
78229baeab | ||
|
|
81f269e2a9 | ||
|
|
225b0f9377 | ||
|
|
30b90f9baa | ||
|
|
1293e473ca | ||
|
|
1a24a2d35e | ||
|
|
f0f1687c79 | ||
|
|
ded980bfc3 | ||
|
|
4cb56edebf | ||
|
|
c411151560 | ||
|
|
f52bd9f38a | ||
|
|
006d02cfaf | ||
|
|
263f96da87 | ||
|
|
f22affd836 | ||
|
|
f5667cefd4 | ||
|
|
7efce389b2 | ||
|
|
f59cff4f5d | ||
|
|
984f06ac40 | ||
|
|
9d4a12dfd4 | ||
|
|
94730567ab | ||
|
|
57db5e64de | ||
|
|
4d32968f2b | ||
|
|
10989e6927 | ||
|
|
62cc12be3c | ||
|
|
1874557b95 | ||
|
|
9a78547bf0 | ||
|
|
0b1bd9deb1 | ||
|
|
7202179d63 | ||
|
|
519a7df4cd | ||
|
|
3762728c84 | ||
|
|
bc3fa2b3fb | ||
|
|
57fca378bc | ||
|
|
eb718145c0 | ||
|
|
c87c1866ae | ||
|
|
b190423d96 | ||
|
|
edd3ab7cc9 | ||
|
|
4147f1d912 | ||
|
|
e4311da1a4 | ||
|
|
b7bb118c00 | ||
|
|
21f7314907 | ||
|
|
2541011eaa | ||
|
|
18d8cc4449 | ||
|
|
8e8a2f997e | ||
|
|
86e5c611ec | ||
|
|
e700bb5467 | ||
|
|
a1aa2b807b | ||
|
|
abea5a53de | ||
|
|
bcf6685643 | ||
|
|
bd27898ea9 | ||
|
|
3321c1a9df | ||
|
|
72a898d89d | ||
|
|
a16c5955d7 | ||
|
|
e87bfa548a | ||
|
|
369a30e227 | ||
|
|
0df618feee | ||
|
|
363b9276eb | ||
|
|
36d7dd9319 | ||
|
|
a57c4d9a9e | ||
|
|
724948d36d | ||
|
|
83f8065f10 | ||
|
|
e63e8e2517 | ||
|
|
01e3b8e5df | ||
|
|
5a7c9a252c | ||
|
|
f99f5f4f91 | ||
|
|
8ad27c7cea | ||
|
|
edc21ed746 | ||
|
|
dd744f8ee3 | ||
|
|
f6f9a3abb4 | ||
|
|
1c156a179b | ||
|
|
952f189d8b | ||
|
|
40e750e8be | ||
|
|
c7510d572a | ||
|
|
165f9e15ee | ||
|
|
dfdbb773ce | ||
|
|
f053ce548d | ||
|
|
d7c28470ee | ||
|
|
28f6064240 | ||
|
|
4b3b458bb6 | ||
|
|
4736b4e3e8 | ||
|
|
a17f188e97 | ||
|
|
5b80323326 | ||
|
|
1425b3da6b | ||
|
|
3d2196b0f2 | ||
|
|
50d7956c07 | ||
|
|
22d3fd3b92 | ||
|
|
a469e86b32 | ||
|
|
138c9232df | ||
|
|
2e1f8625ec | ||
|
|
f7cbb7417c | ||
|
|
125de91c71 | ||
|
|
c9b58f5893 | ||
|
|
640fd7308b | ||
|
|
557a79f747 | ||
|
|
5ade152bc5 | ||
|
|
827bf1ef18 | ||
|
|
a02adbb828 | ||
|
|
ab7520c167 | ||
|
|
de1b448639 | ||
|
|
c15998e805 | ||
|
|
f0b069adb9 | ||
|
|
276d02e12b | ||
|
|
ded9535434 | ||
|
|
997aec2441 | ||
|
|
cb2bd47816 | ||
|
|
f1c8377ca0 | ||
|
|
8416397589 | ||
|
|
dc29635b67 | ||
|
|
00290e1e71 | ||
|
|
3ef4c4f315 | ||
|
|
b10a8baf53 | ||
|
|
77926383db | ||
|
|
35eda735c8 | ||
|
|
8f7a71d1cf | ||
|
|
33cdea88aa | ||
|
|
4b345e02ff | ||
|
|
8cf900bafa | ||
|
|
59a3f0f455 | ||
|
|
c5d99711f7 | ||
|
|
4c0a41723f | ||
|
|
f73511a754 | ||
|
|
e637387082 | ||
|
|
baad38f0e6 | ||
|
|
161147af51 | ||
|
|
cbdf5011f9 | ||
|
|
f0f1d279c4 | ||
|
|
5821f2fe61 | ||
|
|
4cbce072be | ||
|
|
5e5bb7e87d | ||
|
|
b052893a1e | ||
|
|
15e58595fd | ||
|
|
6d499c782a | ||
|
|
7af99b8606 | ||
|
|
01e39277e0 | ||
|
|
06e79703da | ||
|
|
c360781565 | ||
|
|
287f6d5c94 | ||
|
|
fe9125a3d1 | ||
|
|
8b31936bb6 | ||
|
|
19958dfd83 | ||
|
|
1e1cf0d1fe | ||
|
|
879e0ea131 | ||
|
|
42136f9091 | ||
|
|
1109c32891 | ||
|
|
3c80049192 | ||
|
|
8f1669efbe | ||
|
|
146bf65d02 | ||
|
|
75a7c9c06c | ||
|
|
ae8f5a6673 | ||
|
|
31f2c7b505 | ||
|
|
ba6687dde9 | ||
|
|
bbba1bfe8c | ||
|
|
4be9a5ebf8 | ||
|
|
d41921247b | ||
|
|
853a024f0f | ||
|
|
4fe494776e | ||
|
|
76b4adf276 | ||
|
|
75dde0d076 | ||
|
|
cffb68d1c4 | ||
|
|
45f68f73a9 | ||
|
|
4f93eda8d8 | ||
|
|
f5df5fa98d | ||
|
|
f07d1441ea | ||
|
|
1bcf28c062 | ||
|
|
62628dfcfa | ||
|
|
b11aecd184 | ||
|
|
116012f6f8 | ||
|
|
7594136050 | ||
|
|
bb341cc774 | ||
|
|
af1d4afb95 | ||
|
|
75b1ef2c57 | ||
|
|
1e37f7c8c8 | ||
|
|
a32f450059 | ||
|
|
b452ab463b | ||
|
|
79bed80226 | ||
|
|
6249996cdb | ||
|
|
a3f281caa3 | ||
|
|
7c19b0591f | ||
|
|
95c29a8aea | ||
|
|
d8ca210641 | ||
|
|
ab35afd3b1 | ||
|
|
65e4fdf98d | ||
|
|
fa43fae2a5 | ||
|
|
46afd6a101 | ||
|
|
46e1967760 | ||
|
|
922282b2b4 | ||
|
|
e3ab16a5bd | ||
|
|
08f320c801 | ||
|
|
e36261b552 | ||
|
|
c0a3b58bba | ||
|
|
f12f609038 | ||
|
|
1f6eb662e5 | ||
|
|
0c1fe35f2f | ||
|
|
e98a33cf9d | ||
|
|
d38305360c | ||
|
|
3e3ca4c104 | ||
|
|
81edf0749f | ||
|
|
01f83ae964 | ||
|
|
5eec0dc981 | ||
|
|
ca4fd07656 | ||
|
|
7ce43b3824 | ||
|
|
ce00119926 | ||
|
|
fffee80e2f | ||
|
|
64cd4e96e3 | ||
|
|
955a3bfaa6 | ||
|
|
e699d8f170 | ||
|
|
13104d49cd | ||
|
|
2d5ec528d5 | ||
|
|
5226898184 | ||
|
|
dd4169876c | ||
|
|
8321c275b8 | ||
|
|
3d6c26350a | ||
|
|
db15e5e423 | ||
|
|
35d18da14a | ||
|
|
cb56a11f0b | ||
|
|
104fa09f69 | ||
|
|
66ae07ee39 | ||
|
|
939d2c8b27 | ||
|
|
2801a6e672 | ||
|
|
4742360469 | ||
|
|
b56fa62b32 | ||
|
|
ddbe485074 | ||
|
|
01310c6d86 | ||
|
|
512327ef69 | ||
|
|
8755cd59fd | ||
|
|
7694b342ed | ||
|
|
78553a0258 | ||
|
|
c1198b99b7 | ||
|
|
8b7b9ee394 | ||
|
|
d6b39a464d | ||
|
|
75d23fe135 | ||
|
|
c860809aa1 | ||
|
|
0498f6cb9d | ||
|
|
24e5dabb51 | ||
|
|
aecf064ec9 | ||
|
|
57be3ff8c7 | ||
|
|
99505f987e | ||
|
|
1e1c4ac9d2 | ||
|
|
d952b62053 | ||
|
|
9f3eeed091 | ||
|
|
1dbc20fd77 | ||
|
|
ba8df712c4 | ||
|
|
741d838f56 | ||
|
|
ec2fa6e308 | ||
|
|
b974ed5735 | ||
|
|
78457d9b89 | ||
|
|
5d043b435e | ||
|
|
9a403d5886 | ||
|
|
1a31faf1a2 | ||
|
|
edbdc14178 | ||
|
|
e7261a04e1 | ||
|
|
acded69adf | ||
|
|
45a0315606 | ||
|
|
3856d4053c | ||
|
|
8175b3b75b | ||
|
|
56e431226f | ||
|
|
f59417cc77 | ||
|
|
11cec56e80 | ||
|
|
810f22057c | ||
|
|
2152f20b6c | ||
|
|
a6c76e78d6 | ||
|
|
644a3bf090 | ||
|
|
42dd3315f8 | ||
|
|
3a694219bf | ||
|
|
d9fd52ea18 | ||
|
|
2a281e7906 | ||
|
|
5f987a95f5 | ||
|
|
edf577d7f7 | ||
|
|
5e482dabc6 | ||
|
|
76c73549ae | ||
|
|
271a42ac7f | ||
|
|
4462952564 | ||
|
|
38d4d1a573 | ||
|
|
d310c6f3cd | ||
|
|
c086a65fa8 | ||
|
|
7134dd29ca | ||
|
|
3e08953a43 | ||
|
|
58c3c7e26b | ||
|
|
237ddcb648 | ||
|
|
fbaeffd65c | ||
|
|
d64c339b4f | ||
|
|
69880ee165 | ||
|
|
15e00f82f0 | ||
|
|
ce82e27f4b | ||
|
|
eeee5147cc | ||
|
|
af22f9b014 | ||
|
|
1086f22166 | ||
|
|
e94eb5012f | ||
|
|
4dcc049465 | ||
|
|
d784d431d0 | ||
|
|
1200bfad13 | ||
|
|
f11bfb9581 | ||
|
|
074fdb2b96 | ||
|
|
f1f203719d | ||
|
|
f73ca9d9c0 | ||
|
|
ad3f4fb434 | ||
|
|
8001dedcbf | ||
|
|
07a39226c5 | ||
|
|
88e7e21683 | ||
|
|
2cefbf8ca3 | ||
|
|
4a6c50cd81 | ||
|
|
e0535e20e6 | ||
|
|
62580455af | ||
|
|
0e7e67efe1 | ||
|
|
2c54b506b3 | ||
|
|
8969b8bdb2 | ||
|
|
5186092faa | ||
|
|
4c9142308f | ||
|
|
bea5d4fd37 | ||
|
|
74c24bfa88 | ||
|
|
95834c68d9 | ||
|
|
09024c3558 | ||
|
|
137cb043ef | ||
|
|
edf21bae41 | ||
|
|
c958f9856d | ||
|
|
70ab8bc657 | ||
|
|
edde0f93ae | ||
|
|
896665bca9 | ||
|
|
e8e9e7830e | ||
|
|
4fd9e42ce5 | ||
|
|
337e3a8dac | ||
|
|
2dc81e28fc | ||
|
|
f915d4cc90 | ||
|
|
905f4375b0 | ||
|
|
0b3633db4f | ||
|
|
2f40f5aad8 | ||
|
|
2611e2ec20 | ||
|
|
433a3cd339 | ||
|
|
0b487897a4 | ||
|
|
d5c5bdffcb | ||
|
|
dea95ac2e6 | ||
|
|
9e2208b8dd | ||
|
|
6922a92b69 | ||
|
|
7a2c8e0662 | ||
|
|
787158247f | ||
|
|
b0a0b7c2e1 | ||
|
|
cb6d81771d | ||
|
|
8de6ec1a1b | ||
|
|
d27c01ef70 | ||
|
|
d6307b262f | ||
|
|
b2cbefe41e | ||
|
|
da5a72f6de | ||
|
|
45304f1211 | ||
|
|
a4e65a7ea8 | ||
|
|
dd393c8346 | ||
|
|
493cde9d55 | ||
|
|
7705c84b04 | ||
|
|
ce0172b8c1 | ||
|
|
718b3a7b52 | ||
|
|
8a73de018c | ||
|
|
d92df63f84 | ||
|
|
6c6b00067b | ||
|
|
9cc88ed2a6 | ||
|
|
4905bba694 | ||
|
|
853d19dc2d | ||
|
|
c935ae47d0 | ||
|
|
93ab42fa24 | ||
|
|
6913697ad1 | ||
|
|
a4ae86ce29 |
@@ -29,6 +29,12 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/devcontainers/features/docker-in-docker:2": {
|
||||||
|
// https://github.com/devcontainers/features/issues/1466
|
||||||
|
"moby": false
|
||||||
|
}
|
||||||
|
},
|
||||||
"forwardPorts": [3000, 9231, 9230, 2283],
|
"forwardPorts": [3000, 9231, 9230, 2283],
|
||||||
"portsAttributes": {
|
"portsAttributes": {
|
||||||
"3000": {
|
"3000": {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ services:
|
|||||||
- app-node_modules:/usr/src/app/node_modules
|
- app-node_modules:/usr/src/app/node_modules
|
||||||
- sveltekit:/usr/src/app/web/.svelte-kit
|
- sveltekit:/usr/src/app/web/.svelte-kit
|
||||||
- coverage:/usr/src/app/web/coverage
|
- coverage:/usr/src/app/web/coverage
|
||||||
|
- ../plugins:/build/corePlugin
|
||||||
immich-web:
|
immich-web:
|
||||||
env_file: !reset []
|
env_file: !reset []
|
||||||
immich-machine-learning:
|
immich-machine-learning:
|
||||||
|
|||||||
2
.github/.nvmrc
vendored
@@ -1 +1 @@
|
|||||||
24.11.0
|
24.13.0
|
||||||
|
|||||||
10
.github/mise.toml
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[tasks.install]
|
||||||
|
run = "pnpm install --filter github --frozen-lockfile"
|
||||||
|
|
||||||
|
[tasks.format]
|
||||||
|
env._.path = "./node_modules/.bin"
|
||||||
|
run = "prettier --check ."
|
||||||
|
|
||||||
|
[tasks."format-fix"]
|
||||||
|
env._.path = "./node_modules/.bin"
|
||||||
|
run = "prettier --write ."
|
||||||
2
.github/package.json
vendored
@@ -4,6 +4,6 @@
|
|||||||
"format:fix": "prettier --write ."
|
"format:fix": "prettier --write ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^3.5.3"
|
"prettier": "^3.7.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
75
.github/workflows/build-mobile.yml
vendored
@@ -30,18 +30,6 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
IOS_CERTIFICATE_PASSWORD:
|
IOS_CERTIFICATE_PASSWORD:
|
||||||
required: true
|
required: true
|
||||||
IOS_PROVISIONING_PROFILE:
|
|
||||||
required: true
|
|
||||||
IOS_PROVISIONING_PROFILE_SHARE_EXTENSION:
|
|
||||||
required: true
|
|
||||||
IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION:
|
|
||||||
required: true
|
|
||||||
IOS_DEVELOPMENT_PROVISIONING_PROFILE:
|
|
||||||
required: true
|
|
||||||
IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION:
|
|
||||||
required: true
|
|
||||||
IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION:
|
|
||||||
required: true
|
|
||||||
FASTLANE_TEAM_ID:
|
FASTLANE_TEAM_ID:
|
||||||
required: true
|
required: true
|
||||||
pull_request:
|
pull_request:
|
||||||
@@ -96,7 +84,7 @@ jobs:
|
|||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ inputs.ref || github.sha }}
|
ref: ${{ inputs.ref || github.sha }}
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
@@ -108,14 +96,14 @@ jobs:
|
|||||||
working-directory: ./mobile
|
working-directory: ./mobile
|
||||||
run: printf "%s" $KEY_JKS | base64 -d > android/key.jks
|
run: printf "%s" $KEY_JKS | base64 -d > android/key.jks
|
||||||
|
|
||||||
- uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
|
|
||||||
- name: Restore Gradle Cache
|
- name: Restore Gradle Cache
|
||||||
id: cache-gradle-restore
|
id: cache-gradle-restore
|
||||||
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
uses: actions/cache/restore@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.gradle/caches
|
~/.gradle/caches
|
||||||
@@ -165,14 +153,14 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Publish Android Artifact
|
- name: Publish Android Artifact
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: release-apk-signed
|
name: release-apk-signed
|
||||||
path: mobile/build/app/outputs/flutter-apk/*.apk
|
path: mobile/build/app/outputs/flutter-apk/*.apk
|
||||||
|
|
||||||
- name: Save Gradle Cache
|
- name: Save Gradle Cache
|
||||||
id: cache-gradle-save
|
id: cache-gradle-save
|
||||||
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
uses: actions/cache/save@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
|
||||||
if: github.ref == 'refs/heads/main'
|
if: github.ref == 'refs/heads/main'
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
@@ -188,13 +176,13 @@ jobs:
|
|||||||
needs: pre-job
|
needs: pre-job
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
# Run on main branch or workflow_dispatch
|
# Run on main branch or workflow_dispatch, or on PRs/other branches (build only, no upload)
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork && fromJSON(needs.pre-job.outputs.should_run).mobile == true && github.ref == 'refs/heads/main' }}
|
if: ${{ !github.event.pull_request.head.repo.fork && fromJSON(needs.pre-job.outputs.should_run).mobile == true }}
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
|
||||||
with:
|
with:
|
||||||
ref: ${{ inputs.ref || github.sha }}
|
ref: ${{ inputs.ref || github.sha }}
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
@@ -222,6 +210,7 @@ jobs:
|
|||||||
uses: ruby/setup-ruby@v1
|
uses: ruby/setup-ruby@v1
|
||||||
with:
|
with:
|
||||||
ruby-version: '3.3'
|
ruby-version: '3.3'
|
||||||
|
bundler-cache: true
|
||||||
working-directory: ./mobile/ios
|
working-directory: ./mobile/ios
|
||||||
|
|
||||||
- name: Install CocoaPods dependencies
|
- name: Install CocoaPods dependencies
|
||||||
@@ -229,13 +218,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
pod install
|
pod install
|
||||||
|
|
||||||
- name: Install Fastlane
|
|
||||||
working-directory: ./mobile/ios
|
|
||||||
run: |
|
|
||||||
gem install bundler
|
|
||||||
bundle config set --local path 'vendor/bundle'
|
|
||||||
bundle install
|
|
||||||
|
|
||||||
- name: Create API Key
|
- name: Create API Key
|
||||||
env:
|
env:
|
||||||
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
||||||
@@ -246,35 +228,14 @@ jobs:
|
|||||||
mkdir -p ~/.appstoreconnect/private_keys
|
mkdir -p ~/.appstoreconnect/private_keys
|
||||||
echo "$API_KEY_CONTENT" | base64 --decode > ~/.appstoreconnect/private_keys/AuthKey_${API_KEY_ID}.p8
|
echo "$API_KEY_CONTENT" | base64 --decode > ~/.appstoreconnect/private_keys/AuthKey_${API_KEY_ID}.p8
|
||||||
|
|
||||||
- name: Import Certificate and Provisioning Profiles
|
- name: Import Certificate
|
||||||
env:
|
env:
|
||||||
IOS_CERTIFICATE_P12: ${{ secrets.IOS_CERTIFICATE_P12 }}
|
IOS_CERTIFICATE_P12: ${{ secrets.IOS_CERTIFICATE_P12 }}
|
||||||
IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
|
|
||||||
IOS_PROVISIONING_PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }}
|
|
||||||
IOS_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_SHARE_EXTENSION }}
|
|
||||||
IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION }}
|
|
||||||
IOS_DEVELOPMENT_PROVISIONING_PROFILE: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE }}
|
|
||||||
IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION }}
|
|
||||||
IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION }}
|
|
||||||
ENVIRONMENT: ${{ inputs.environment || 'development' }}
|
|
||||||
working-directory: ./mobile/ios
|
working-directory: ./mobile/ios
|
||||||
run: |
|
run: |
|
||||||
# Decode certificate
|
# Decode certificate
|
||||||
echo "$IOS_CERTIFICATE_P12" | base64 --decode > certificate.p12
|
echo "$IOS_CERTIFICATE_P12" | base64 --decode > certificate.p12
|
||||||
|
|
||||||
# Decode provisioning profiles based on environment
|
|
||||||
if [[ "$ENVIRONMENT" == "development" ]]; then
|
|
||||||
echo "$IOS_DEVELOPMENT_PROVISIONING_PROFILE" | base64 --decode > profile_dev.mobileprovision
|
|
||||||
echo "$IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION" | base64 --decode > profile_dev_share.mobileprovision
|
|
||||||
echo "$IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION" | base64 --decode > profile_dev_widget.mobileprovision
|
|
||||||
ls -lh profile_dev*.mobileprovision
|
|
||||||
else
|
|
||||||
echo "$IOS_PROVISIONING_PROFILE" | base64 --decode > profile.mobileprovision
|
|
||||||
echo "$IOS_PROVISIONING_PROFILE_SHARE_EXTENSION" | base64 --decode > profile_share.mobileprovision
|
|
||||||
echo "$IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION" | base64 --decode > profile_widget.mobileprovision
|
|
||||||
ls -lh profile*.mobileprovision
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Create keychain and import certificate
|
- name: Create keychain and import certificate
|
||||||
env:
|
env:
|
||||||
KEYCHAIN_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
|
KEYCHAIN_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
|
||||||
@@ -303,12 +264,20 @@ jobs:
|
|||||||
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
||||||
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
|
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
|
||||||
ENVIRONMENT: ${{ inputs.environment || 'development' }}
|
ENVIRONMENT: ${{ inputs.environment || 'development' }}
|
||||||
|
BUNDLE_ID_SUFFIX: ${{ inputs.environment == 'production' && '' || 'development' }}
|
||||||
|
GITHUB_REF: ${{ github.ref }}
|
||||||
working-directory: ./mobile/ios
|
working-directory: ./mobile/ios
|
||||||
run: |
|
run: |
|
||||||
if [[ "$ENVIRONMENT" == "development" ]]; then
|
# Only upload to TestFlight on main branch
|
||||||
bundle exec fastlane gha_testflight_dev
|
if [[ "$GITHUB_REF" == "refs/heads/main" ]]; then
|
||||||
|
if [[ "$ENVIRONMENT" == "development" ]]; then
|
||||||
|
bundle exec fastlane gha_testflight_dev
|
||||||
|
else
|
||||||
|
bundle exec fastlane gha_release_prod
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
bundle exec fastlane gha_release_prod
|
# Build only, no TestFlight upload for non-main branches
|
||||||
|
bundle exec fastlane gha_build_only
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Clean up keychain
|
- name: Clean up keychain
|
||||||
@@ -317,7 +286,7 @@ jobs:
|
|||||||
security delete-keychain build.keychain || true
|
security delete-keychain build.keychain || true
|
||||||
|
|
||||||
- name: Upload IPA artifact
|
- name: Upload IPA artifact
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: ios-release-ipa
|
name: ios-release-ipa
|
||||||
path: mobile/ios/Runner.ipa
|
path: mobile/ios/Runner.ipa
|
||||||
|
|||||||
2
.github/workflows/cache-cleanup.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
|
|||||||
12
.github/workflows/cli.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
|||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './cli/.nvmrc'
|
node-version-file: './cli/.nvmrc'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
@@ -78,16 +78,16 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||||
@@ -105,7 +105,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate docker image tags
|
- name: Generate docker image tags
|
||||||
id: metadata
|
id: metadata
|
||||||
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||||
with:
|
with:
|
||||||
flavor: |
|
flavor: |
|
||||||
latest=false
|
latest=false
|
||||||
|
|||||||
2
.github/workflows/close-duplicates.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
|||||||
needs: [get_body, should_run]
|
needs: [get_body, should_run]
|
||||||
if: ${{ needs.should_run.outputs.should_run == 'true' }}
|
if: ${{ needs.should_run.outputs.should_run == 'true' }}
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/immich-app/mdq:main@sha256:6b8450bfc06770af1af66bce9bf2ced7d1d9b90df1a59fc4c83a17777a9f6723
|
image: ghcr.io/immich-app/mdq:main@sha256:ab9f163cd5d5cec42704a26ca2769ecf3f10aa8e7bae847f1d527cdf075946e6
|
||||||
outputs:
|
outputs:
|
||||||
checked: ${{ steps.get_checkbox.outputs.checked }}
|
checked: ${{ steps.get_checkbox.outputs.checked }}
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
8
.github/workflows/codeql-analysis.yml
vendored
@@ -50,14 +50,14 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@16140ae1a102900babc80a33c44059580f687047 # v4.30.9
|
uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@16140ae1a102900babc80a33c44059580f687047 # v4.30.9
|
uses: github/codeql-action/autobuild@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
@@ -83,6 +83,6 @@ jobs:
|
|||||||
# ./location_of_script_within_repo/buildscript.sh
|
# ./location_of_script_within_repo/buildscript.sh
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@16140ae1a102900babc80a33c44059580f687047 # v4.30.9
|
uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
|
||||||
with:
|
with:
|
||||||
category: '/language:${{matrix.language}}'
|
category: '/language:${{matrix.language}}'
|
||||||
|
|||||||
4
.github/workflows/docker.yml
vendored
@@ -132,7 +132,7 @@ jobs:
|
|||||||
suffixes: '-rocm'
|
suffixes: '-rocm'
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64
|
||||||
runner-mapping: '{"linux/amd64": "mich"}'
|
runner-mapping: '{"linux/amd64": "mich"}'
|
||||||
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@47a2ee86898ccff51592d6572391fb1abcd7f782 # multi-runner-build-workflow-v2.0.1
|
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@0477486d82313fba68f7c82c034120a4b8981297 # multi-runner-build-workflow-v2.1.0
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
actions: read
|
actions: read
|
||||||
@@ -155,7 +155,7 @@ jobs:
|
|||||||
name: Build and Push Server
|
name: Build and Push Server
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == true }}
|
if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == true }}
|
||||||
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@47a2ee86898ccff51592d6572391fb1abcd7f782 # multi-runner-build-workflow-v2.0.1
|
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@0477486d82313fba68f7c82c034120a4b8981297 # multi-runner-build-workflow-v2.1.0
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
actions: read
|
actions: read
|
||||||
|
|||||||
7
.github/workflows/docs-build.yml
vendored
@@ -60,16 +60,17 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './docs/.nvmrc'
|
node-version-file: './docs/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -85,7 +86,7 @@ jobs:
|
|||||||
run: pnpm build
|
run: pnpm build
|
||||||
|
|
||||||
- name: Upload build output
|
- name: Upload build output
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
with:
|
with:
|
||||||
name: docs-build-output
|
name: docs-build-output
|
||||||
path: docs/build/
|
path: docs/build/
|
||||||
|
|||||||
8
.github/workflows/docs-deploy.yml
vendored
@@ -125,7 +125,7 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
@@ -174,7 +174,7 @@ jobs:
|
|||||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
||||||
working-directory: 'deployment/modules/cloudflare/docs'
|
working-directory: 'deployment/modules/cloudflare/docs'
|
||||||
run: 'mise run tf apply'
|
run: 'mise run //deployment:tf apply'
|
||||||
|
|
||||||
- name: Deploy Docs Subdomain Output
|
- name: Deploy Docs Subdomain Output
|
||||||
id: docs-output
|
id: docs-output
|
||||||
@@ -186,7 +186,7 @@ jobs:
|
|||||||
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
||||||
working-directory: 'deployment/modules/cloudflare/docs'
|
working-directory: 'deployment/modules/cloudflare/docs'
|
||||||
run: |
|
run: |
|
||||||
mise run tf output -- -json | jq -r '
|
mise run //deployment:tf output -- -json | jq -r '
|
||||||
"projectName=\(.pages_project_name.value)",
|
"projectName=\(.pages_project_name.value)",
|
||||||
"subdomain=\(.immich_app_branch_subdomain.value)"
|
"subdomain=\(.immich_app_branch_subdomain.value)"
|
||||||
' >> $GITHUB_OUTPUT
|
' >> $GITHUB_OUTPUT
|
||||||
@@ -211,7 +211,7 @@ jobs:
|
|||||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
||||||
working-directory: 'deployment/modules/cloudflare/docs-release'
|
working-directory: 'deployment/modules/cloudflare/docs-release'
|
||||||
run: 'mise run tf apply'
|
run: 'mise run //deployment:tf apply'
|
||||||
|
|
||||||
- name: Comment
|
- name: Comment
|
||||||
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3.2.0
|
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3.2.0
|
||||||
|
|||||||
4
.github/workflows/docs-destroy.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
||||||
working-directory: 'deployment/modules/cloudflare/docs'
|
working-directory: 'deployment/modules/cloudflare/docs'
|
||||||
run: 'mise run tf destroy -- -refresh=false'
|
run: 'mise run //deployment:tf destroy -- -refresh=false'
|
||||||
|
|
||||||
- name: Comment
|
- name: Comment
|
||||||
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3.2.0
|
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3.2.0
|
||||||
|
|||||||
6
.github/workflows/fix-format.yml
vendored
@@ -16,13 +16,13 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: 'Checkout'
|
- name: 'Checkout'
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.ref }}
|
ref: ${{ github.event.pull_request.head.ref }}
|
||||||
token: ${{ steps.generate-token.outputs.token }}
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
@@ -32,7 +32,7 @@ jobs:
|
|||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
|||||||
2
.github/workflows/merge-translations.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
|||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
id: generate_token
|
id: generate_token
|
||||||
if: ${{ inputs.skip != true }}
|
if: ${{ inputs.skip != true }}
|
||||||
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|||||||
28
.github/workflows/prepare-release.yml
vendored
@@ -45,30 +45,31 @@ jobs:
|
|||||||
needs: [merge_translations]
|
needs: [merge_translations]
|
||||||
outputs:
|
outputs:
|
||||||
ref: ${{ steps.push-tag.outputs.commit_long_sha }}
|
ref: ${{ steps.push-tag.outputs.commit_long_sha }}
|
||||||
|
version: ${{ steps.output.outputs.version }}
|
||||||
permissions: {} # No job-level permissions are needed because it uses the app-token
|
permissions: {} # No job-level permissions are needed because it uses the app-token
|
||||||
steps:
|
steps:
|
||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.generate-token.outputs.token }}
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
persist-credentials: true
|
persist-credentials: true
|
||||||
ref: main
|
ref: main
|
||||||
|
|
||||||
- name: Install uv
|
- name: Install uv
|
||||||
uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 # v7.1.1
|
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
|
||||||
|
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -80,13 +81,16 @@ jobs:
|
|||||||
MOBILE_BUMP: ${{ inputs.mobileBump }}
|
MOBILE_BUMP: ${{ inputs.mobileBump }}
|
||||||
run: misc/release/pump-version.sh -s "${SERVER_BUMP}" -m "${MOBILE_BUMP}"
|
run: misc/release/pump-version.sh -s "${SERVER_BUMP}" -m "${MOBILE_BUMP}"
|
||||||
|
|
||||||
|
- id: output
|
||||||
|
run: echo "version=$IMMICH_VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Commit and tag
|
- name: Commit and tag
|
||||||
id: push-tag
|
id: push-tag
|
||||||
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
|
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
|
||||||
with:
|
with:
|
||||||
default_author: github_actions
|
default_author: github_actions
|
||||||
message: 'chore: version ${{ env.IMMICH_VERSION }}'
|
message: 'chore: version ${{ steps.output.outputs.version }}'
|
||||||
tag: ${{ env.IMMICH_VERSION }}
|
tag: ${{ steps.output.outputs.version }}
|
||||||
push: true
|
push: true
|
||||||
|
|
||||||
build_mobile:
|
build_mobile:
|
||||||
@@ -119,35 +123,35 @@ jobs:
|
|||||||
|
|
||||||
prepare_release:
|
prepare_release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build_mobile
|
needs: [build_mobile, bump_version]
|
||||||
permissions:
|
permissions:
|
||||||
actions: read # To download the app artifact
|
actions: read # To download the app artifact
|
||||||
# No content permissions are needed because it uses the app-token
|
# No content permissions are needed because it uses the app-token
|
||||||
steps:
|
steps:
|
||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.generate-token.outputs.token }}
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Download APK
|
- name: Download APK
|
||||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||||
with:
|
with:
|
||||||
name: release-apk-signed
|
name: release-apk-signed
|
||||||
github-token: ${{ steps.generate-token.outputs.token }}
|
github-token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
|
||||||
- name: Create draft release
|
- name: Create draft release
|
||||||
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
tag_name: ${{ env.IMMICH_VERSION }}
|
tag_name: ${{ needs.bump_version.outputs.version }}
|
||||||
token: ${{ steps.generate-token.outputs.token }}
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
generate_release_notes: true
|
generate_release_notes: true
|
||||||
body_path: misc/release/notes.tmpl
|
body_path: misc/release/notes.tmpl
|
||||||
|
|||||||
170
.github/workflows/release-pr.yml
vendored
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
name: Manage release PR
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
bump:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Generate a token
|
||||||
|
id: generate-token
|
||||||
|
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||||
|
with:
|
||||||
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
with:
|
||||||
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
persist-credentials: true
|
||||||
|
ref: main
|
||||||
|
|
||||||
|
- name: Install uv
|
||||||
|
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
|
||||||
|
|
||||||
|
- name: Setup pnpm
|
||||||
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
|
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
|
with:
|
||||||
|
node-version-file: './server/.nvmrc'
|
||||||
|
cache: 'pnpm'
|
||||||
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
|
|
||||||
|
- name: Determine release type
|
||||||
|
id: bump-type
|
||||||
|
uses: ietf-tools/semver-action@c90370b2958652d71c06a3484129a4d423a6d8a8 # v1.11.0
|
||||||
|
with:
|
||||||
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
|
||||||
|
- name: Bump versions
|
||||||
|
env:
|
||||||
|
TYPE: ${{ steps.bump-type.outputs.bump }}
|
||||||
|
run: |
|
||||||
|
if [ "$TYPE" == "none" ]; then
|
||||||
|
exit 1 # TODO: Is there a cleaner way to abort the workflow?
|
||||||
|
fi
|
||||||
|
misc/release/pump-version.sh -s $TYPE -m true
|
||||||
|
|
||||||
|
- name: Manage Outline release document
|
||||||
|
id: outline
|
||||||
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||||
|
env:
|
||||||
|
OUTLINE_API_KEY: ${{ secrets.OUTLINE_API_KEY }}
|
||||||
|
NEXT_VERSION: ${{ steps.bump-type.outputs.next }}
|
||||||
|
with:
|
||||||
|
github-token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
script: |
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const outlineKey = process.env.OUTLINE_API_KEY;
|
||||||
|
const parentDocumentId = 'da856355-0844-43df-bd71-f8edce5382d9'
|
||||||
|
const collectionId = 'e2910656-714c-4871-8721-447d9353bd73';
|
||||||
|
const baseUrl = 'https://outline.immich.cloud';
|
||||||
|
|
||||||
|
const listResponse = await fetch(`${baseUrl}/api/documents.list`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${outlineKey}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ parentDocumentId })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!listResponse.ok) {
|
||||||
|
throw new Error(`Outline list failed: ${listResponse.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const listData = await listResponse.json();
|
||||||
|
const allDocuments = listData.data || [];
|
||||||
|
|
||||||
|
const document = allDocuments.find(doc => doc.title === 'next');
|
||||||
|
|
||||||
|
let documentId;
|
||||||
|
let documentUrl;
|
||||||
|
let documentText;
|
||||||
|
|
||||||
|
if (!document) {
|
||||||
|
// Create new document
|
||||||
|
console.log('No existing document found. Creating new one...');
|
||||||
|
const notesTmpl = fs.readFileSync('misc/release/notes.tmpl', 'utf8');
|
||||||
|
const createResponse = await fetch(`${baseUrl}/api/documents.create`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${outlineKey}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
title: 'next',
|
||||||
|
text: notesTmpl,
|
||||||
|
collectionId: collectionId,
|
||||||
|
parentDocumentId: parentDocumentId,
|
||||||
|
publish: true
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createResponse.ok) {
|
||||||
|
throw new Error(`Failed to create document: ${createResponse.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const createData = await createResponse.json();
|
||||||
|
documentId = createData.data.id;
|
||||||
|
const urlId = createData.data.urlId;
|
||||||
|
documentUrl = `${baseUrl}/doc/next-${urlId}`;
|
||||||
|
documentText = createData.data.text || '';
|
||||||
|
console.log(`Created new document: ${documentUrl}`);
|
||||||
|
} else {
|
||||||
|
documentId = document.id;
|
||||||
|
const docPath = document.url;
|
||||||
|
documentUrl = `${baseUrl}${docPath}`;
|
||||||
|
documentText = document.text || '';
|
||||||
|
console.log(`Found existing document: ${documentUrl}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate GitHub release notes
|
||||||
|
console.log('Generating GitHub release notes...');
|
||||||
|
const releaseNotesResponse = await github.rest.repos.generateReleaseNotes({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
tag_name: `${process.env.NEXT_VERSION}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Combine the content
|
||||||
|
const changelog = `
|
||||||
|
# ${process.env.NEXT_VERSION}
|
||||||
|
|
||||||
|
${documentText}
|
||||||
|
|
||||||
|
${releaseNotesResponse.data.body}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
const existingChangelog = fs.existsSync('CHANGELOG.md') ? fs.readFileSync('CHANGELOG.md', 'utf8') : '';
|
||||||
|
fs.writeFileSync('CHANGELOG.md', changelog + existingChangelog, 'utf8');
|
||||||
|
|
||||||
|
core.setOutput('document_url', documentUrl);
|
||||||
|
|
||||||
|
- name: Create PR
|
||||||
|
id: create-pr
|
||||||
|
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
|
||||||
|
with:
|
||||||
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
commit-message: 'chore: release ${{ steps.bump-type.outputs.next }}'
|
||||||
|
title: 'chore: release ${{ steps.bump-type.outputs.next }}'
|
||||||
|
body: 'Release notes: ${{ steps.outline.outputs.document_url }}'
|
||||||
|
labels: 'changelog:skip'
|
||||||
|
branch: 'release/next'
|
||||||
|
draft: true
|
||||||
148
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
name: release.yml
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [closed]
|
||||||
|
paths:
|
||||||
|
- CHANGELOG.md
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Maybe double check PR source branch?
|
||||||
|
|
||||||
|
merge_translations:
|
||||||
|
uses: ./.github/workflows/merge-translations.yml
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
secrets:
|
||||||
|
PUSH_O_MATIC_APP_ID: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
|
PUSH_O_MATIC_APP_KEY: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }}
|
||||||
|
|
||||||
|
build_mobile:
|
||||||
|
uses: ./.github/workflows/build-mobile.yml
|
||||||
|
needs: merge_translations
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
secrets:
|
||||||
|
KEY_JKS: ${{ secrets.KEY_JKS }}
|
||||||
|
ALIAS: ${{ secrets.ALIAS }}
|
||||||
|
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
||||||
|
ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
|
||||||
|
# iOS secrets
|
||||||
|
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
|
||||||
|
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
|
||||||
|
APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
|
||||||
|
IOS_CERTIFICATE_P12: ${{ secrets.IOS_CERTIFICATE_P12 }}
|
||||||
|
IOS_CERTIFICATE_PASSWORD: ${{ secrets.IOS_CERTIFICATE_PASSWORD }}
|
||||||
|
IOS_PROVISIONING_PROFILE: ${{ secrets.IOS_PROVISIONING_PROFILE }}
|
||||||
|
IOS_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_SHARE_EXTENSION }}misc/release/notes.tmpl
|
||||||
|
IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_PROVISIONING_PROFILE_WIDGET_EXTENSION }}
|
||||||
|
IOS_DEVELOPMENT_PROVISIONING_PROFILE: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE }}
|
||||||
|
IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_SHARE_EXTENSION }}
|
||||||
|
IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION: ${{ secrets.IOS_DEVELOPMENT_PROVISIONING_PROFILE_WIDGET_EXTENSION }}
|
||||||
|
FASTLANE_TEAM_ID: ${{ secrets.FASTLANE_TEAM_ID }}
|
||||||
|
with:
|
||||||
|
ref: main
|
||||||
|
environment: production
|
||||||
|
|
||||||
|
prepare_release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build_mobile
|
||||||
|
permissions:
|
||||||
|
actions: read # To download the app artifact
|
||||||
|
steps:
|
||||||
|
- name: Generate a token
|
||||||
|
id: generate-token
|
||||||
|
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||||
|
with:
|
||||||
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
with:
|
||||||
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
persist-credentials: false
|
||||||
|
ref: main
|
||||||
|
|
||||||
|
- name: Extract changelog
|
||||||
|
id: changelog
|
||||||
|
run: |
|
||||||
|
CHANGELOG_PATH=$RUNNER_TEMP/changelog.md
|
||||||
|
sed -n '1,/^---$/p' CHANGELOG.md | head -n -1 > $CHANGELOG_PATH
|
||||||
|
echo "path=$CHANGELOG_PATH" >> $GITHUB_OUTPUT
|
||||||
|
VERSION=$(sed -n 's/^# //p' $CHANGELOG_PATH)
|
||||||
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Download APK
|
||||||
|
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||||
|
with:
|
||||||
|
name: release-apk-signed
|
||||||
|
github-token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
|
||||||
|
- name: Create draft release
|
||||||
|
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
|
||||||
|
with:
|
||||||
|
tag_name: ${{ steps.version.outputs.result }}
|
||||||
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
body_path: ${{ steps.changelog.outputs.path }}
|
||||||
|
draft: true
|
||||||
|
files: |
|
||||||
|
docker/docker-compose.yml
|
||||||
|
docker/example.env
|
||||||
|
docker/hwaccel.ml.yml
|
||||||
|
docker/hwaccel.transcoding.yml
|
||||||
|
docker/prometheus.yml
|
||||||
|
*.apk
|
||||||
|
|
||||||
|
- name: Rename Outline document
|
||||||
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||||
|
continue-on-error: true
|
||||||
|
env:
|
||||||
|
OUTLINE_API_KEY: ${{ secrets.OUTLINE_API_KEY }}
|
||||||
|
VERSION: ${{ steps.changelog.outputs.version }}
|
||||||
|
with:
|
||||||
|
github-token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
script: |
|
||||||
|
const outlineKey = process.env.OUTLINE_API_KEY;
|
||||||
|
const version = process.env.VERSION;
|
||||||
|
const parentDocumentId = 'da856355-0844-43df-bd71-f8edce5382d9';
|
||||||
|
const baseUrl = 'https://outline.immich.cloud';
|
||||||
|
|
||||||
|
const listResponse = await fetch(`${baseUrl}/api/documents.list`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${outlineKey}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ parentDocumentId })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!listResponse.ok) {
|
||||||
|
throw new Error(`Outline list failed: ${listResponse.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const listData = await listResponse.json();
|
||||||
|
const allDocuments = listData.data || [];
|
||||||
|
const document = allDocuments.find(doc => doc.title === 'next');
|
||||||
|
|
||||||
|
if (document) {
|
||||||
|
console.log(`Found document 'next', renaming to '${version}'...`);
|
||||||
|
|
||||||
|
const updateResponse = await fetch(`${baseUrl}/api/documents.update`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${outlineKey}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
id: document.id,
|
||||||
|
title: version
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updateResponse.ok) {
|
||||||
|
throw new Error(`Failed to rename document: ${updateResponse.statusText}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('No document titled "next" found to rename');
|
||||||
|
}
|
||||||
4
.github/workflows/sdk.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
@@ -31,7 +31,7 @@ jobs:
|
|||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
|
|
||||||
# Setup .npmrc file to publish to npm
|
# Setup .npmrc file to publish to npm
|
||||||
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './open-api/typescript-sdk/.nvmrc'
|
node-version-file: './open-api/typescript-sdk/.nvmrc'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
|||||||
2
.github/workflows/static_analysis.yml
vendored
@@ -55,7 +55,7 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
|
|||||||
92
.github/workflows/test.yml
vendored
@@ -69,7 +69,7 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
@@ -77,7 +77,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -114,14 +114,14 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './cli/.nvmrc'
|
node-version-file: './cli/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -161,14 +161,14 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './cli/.nvmrc'
|
node-version-file: './cli/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -203,14 +203,14 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './web/.nvmrc'
|
node-version-file: './web/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -247,14 +247,14 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './web/.nvmrc'
|
node-version-file: './web/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -285,22 +285,22 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './web/.nvmrc'
|
node-version-file: './web/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
cache-dependency-path: '**/pnpm-lock.yaml'
|
cache-dependency-path: '**/pnpm-lock.yaml'
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm --filter=immich-web install --frozen-lockfile
|
run: pnpm --filter=immich-i18n install --frozen-lockfile
|
||||||
- name: Format
|
- name: Format
|
||||||
run: pnpm --filter=immich-web format:i18n
|
run: pnpm --filter=immich-i18n format:fix
|
||||||
- name: Find file changes
|
- name: Find file changes
|
||||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
|
||||||
id: verify-changed-files
|
id: verify-changed-files
|
||||||
@@ -333,14 +333,14 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './e2e/.nvmrc'
|
node-version-file: './e2e/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -379,7 +379,7 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
@@ -387,7 +387,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -418,7 +418,7 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
@@ -426,7 +426,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './e2e/.nvmrc'
|
node-version-file: './e2e/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -473,7 +473,7 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
@@ -481,7 +481,7 @@ jobs:
|
|||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './e2e/.nvmrc'
|
node-version-file: './e2e/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -500,8 +500,27 @@ jobs:
|
|||||||
run: docker compose build
|
run: docker compose build
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
- name: Run e2e tests (web)
|
- name: Run e2e tests (web)
|
||||||
run: npx playwright test
|
env:
|
||||||
|
CI: true
|
||||||
|
run: npx playwright test --project=chromium
|
||||||
if: ${{ !cancelled() }}
|
if: ${{ !cancelled() }}
|
||||||
|
- name: Archive web results
|
||||||
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
|
if: success() || failure()
|
||||||
|
with:
|
||||||
|
name: e2e-web-test-results-${{ matrix.runner }}
|
||||||
|
path: e2e/playwright-report/
|
||||||
|
- name: Run ui tests (web)
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
run: npx playwright test --project=ui
|
||||||
|
if: ${{ !cancelled() }}
|
||||||
|
- name: Archive ui results
|
||||||
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
|
if: success() || failure()
|
||||||
|
with:
|
||||||
|
name: e2e-ui-test-results-${{ matrix.runner }}
|
||||||
|
path: e2e/playwright-report/
|
||||||
success-check-e2e:
|
success-check-e2e:
|
||||||
name: End-to-End Tests Success
|
name: End-to-End Tests Success
|
||||||
needs: [e2e-tests-server-cli, e2e-tests-web]
|
needs: [e2e-tests-server-cli, e2e-tests-web]
|
||||||
@@ -526,7 +545,7 @@ jobs:
|
|||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
@@ -558,17 +577,14 @@ jobs:
|
|||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
- name: Install uv
|
- name: Install uv
|
||||||
uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 # v7.1.1
|
uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # v7.1.6
|
||||||
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
|
with:
|
||||||
# TODO: add caching when supported (https://github.com/actions/setup-python/pull/818)
|
python-version: 3.11
|
||||||
# with:
|
|
||||||
# python-version: 3.11
|
|
||||||
# cache: 'uv'
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
uv sync --extra cpu
|
uv sync --extra cpu
|
||||||
@@ -602,14 +618,14 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './.github/.nvmrc'
|
node-version-file: './.github/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -631,7 +647,7 @@ jobs:
|
|||||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
@@ -653,14 +669,14 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
@@ -715,14 +731,14 @@ jobs:
|
|||||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
token: ${{ steps.token.outputs.token }}
|
token: ${{ steps.token.outputs.token }}
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
cache: 'pnpm'
|
cache: 'pnpm'
|
||||||
|
|||||||
3
.github/workflows/weblate-lock.yml
vendored
@@ -36,8 +36,7 @@ jobs:
|
|||||||
github-token: ${{ steps.token.outputs.token }}
|
github-token: ${{ steps.token.outputs.token }}
|
||||||
filters: |
|
filters: |
|
||||||
i18n:
|
i18n:
|
||||||
- 'i18n/!(en)**\.json'
|
- modified: 'i18n/!(en)**\.json'
|
||||||
exclude-branches: 'chore/translations'
|
|
||||||
skip-force-logic: 'true'
|
skip-force-logic: 'true'
|
||||||
|
|
||||||
enforce-lock:
|
enforce-lock:
|
||||||
|
|||||||
2
.vscode/settings.json
vendored
@@ -52,7 +52,7 @@
|
|||||||
},
|
},
|
||||||
"cSpell.words": ["immich"],
|
"cSpell.words": ["immich"],
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"eslint.validate": ["javascript", "svelte"],
|
"eslint.validate": ["javascript", "typescript", "svelte"],
|
||||||
"explorer.fileNesting.enabled": true,
|
"explorer.fileNesting.enabled": true,
|
||||||
"explorer.fileNesting.patterns": {
|
"explorer.fileNesting.patterns": {
|
||||||
"*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart",
|
"*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart",
|
||||||
|
|||||||
404
CHANGELOG.md
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
|
||||||
|
# v2.5.0
|
||||||
|
|
||||||
|
# v2.5.0
|
||||||
|
|
||||||
|
## Highlights
|
||||||
|
|
||||||
|
Happy New Year! Welcome to Immich `v2.5.0`. This release is our fireworks to celebrate both the new year and reaching *90,000* stars on GitHub. It is packed with major features that have been in the works for quite some time, and the team has kicked off the year with incredible momentum that we're excited to carry forward. We couldn't wait to share this with you. Let's dive right in:
|
||||||
|
|
||||||
|
* Free Up Space
|
||||||
|
* Non-destructive editing
|
||||||
|
* Database backup and restore (web)
|
||||||
|
* Foreground upload improvements
|
||||||
|
* Visual refresh across all platforms
|
||||||
|
|
||||||
|
### Free Up Spac*e*
|
||||||
|
|
||||||
|
*This feature was requested ages ago. So long in fact, that it has a 3-digit ID (#165)! Given the rapid iteration and development pace of the pre-stable era, it was risky to include it in the app due to its bulk-delete nature. But it is now 2026* :smile:*, so here we are.*
|
||||||
|
|
||||||
|
|
||||||
|
**Free Up Space** allows you to remove local media files from your device that have already been successfully backed up to your Immich server (and are not in Immich trash). This helps reclaim storage on your mobile device without losing your memories. The feature can be accessed from the user profile panel or from the Settings page in the mobile app.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
There are configuration options and steps to make sure that everything is verified before deleting from the app.
|
||||||
|
|
||||||
|
|
||||||
|
1. **Configuration:**
|
||||||
|
* **Cutoff date:** Free Up Space will only look for photos and videos **on or before** this date.
|
||||||
|
* **Keep albums:** Hold all photos and videos in the selected albums on your device, regardless of other settings. By default, `**WhatsApp**` related albums are selected to be kept on the device. Assets that are not already on the device will not be redownloaded.
|
||||||
|
* **Keep favorites:** This works the same way `**Keep albums**` . By default, favorited assets are preserved on your device.
|
||||||
|
* **Keep on device:** You can choose to restrict removal to `**Always keep**` **All photos** or **All videos**, regardless of other settings. This setting can hamper freeing up space significantly — with 80 GB of videos and 40 GB of photos, selecting `**Always keep photos**` retains thousands of photos on your device.
|
||||||
|
2. **Scan & Review:** Before any files are removed, you are presented with a review screen to confirm which items will be deleted and how much storage will be reclaimed.
|
||||||
|
3. **Deletion:** Confirmed items are moved to your device's native Trash/Recycle Bin.
|
||||||
|
|
||||||
|
|
||||||
|
:::info
|
||||||
|
**Reclaim storage**
|
||||||
|
|
||||||
|
To use the reclaimed space right away, you must manually empty the system/gallery trash outside Immich.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
For more information about this feature, please read it [here](https://immich.app/features/mobile-app#free-up-space)
|
||||||
|
|
||||||
|
|
||||||
|
### Non-destructive editing
|
||||||
|
|
||||||
|
Immich now supports non-destructive photo editing. This means that any edits you make to an asset do not modify the original file; instead, the modifications are stored in the database, and new thumbnails are generated corresponding to the changes. This means you can always revert to the original asset if needed.
|
||||||
|
|
||||||
|
When you download an edited asset, Immich provides the edited version by default. However, you can choose to download the original version if needed. Immich always generates an edited full-size version based on your full-size quality settings. This occurs regardless if you have the "Enable full-size image generation" setting enabled or disabled.
|
||||||
|
|
||||||
|
|
||||||
|
:::info
|
||||||
|
**Limitations:**
|
||||||
|
|
||||||
|
* Mobile clients must be updated to v2.5.0 in order view the edited version of an asset. Clients will continue to see the original asset if on a mobile app version <2.5.0
|
||||||
|
* As of this version, the edited download won't include the EXIF metadata of the original asset. This feature will come in future releases.
|
||||||
|
|
||||||
|
|
||||||
|
* Mobile editing still uses the old edit system (saving a new version of the photo). The mobile editor will be upgraded to use the new non-destructive editing system in future releases.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
You can click on the following icon to enter edit mode
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Currently, Immich supports the following types of edits:
|
||||||
|
|
||||||
|
* Cropping
|
||||||
|
* Rotation
|
||||||
|
* Mirroring
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Opening the editor on an edited asset will load the existing edits back in so you can make adjustments and changes.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Backup and restore from the web UI
|
||||||
|
|
||||||
|
Backup and restore are an important part of any self-hosted application; this feature helps you maintain reliable access to your instance during unexpected events, such as database corruption caused by system failure or power loss.
|
||||||
|
|
||||||
|
Historically, restoring an Immich instance to a specific point required the user to have access to the command line, which proved challenging for many users, especially those new to self-hosting and software maintenance.
|
||||||
|
|
||||||
|
Now, we have the entire backup and restore pipeline built into Immich, which allows you to quickly restore a database backup directly from the web UI. You can perform the steps either from the `Administration > Maintenance` page, or from a brand new instance at the Onboarding step.
|
||||||
|
|
||||||
|
 
|
||||||
|
|
||||||
|
For more detailed steps, please read them in [our documentation](immich.app/administration/backup-and-restore)
|
||||||
|
|
||||||
|
### Foreground upload improvement
|
||||||
|
|
||||||
|
This release also improves foreground upload in the mobile app. The previous implementation improves background uploads but leaves foreground uploads less reliable by leveraging the queue system to offload upload handling to the OS, which can be throttled under specific criteria.
|
||||||
|
|
||||||
|
We are taking back more control over handling uploads with the *try-and-true* method used in the old timeline, but this time it is supercharged with concurrent uploads and also correctly handles assets with missing file extensions from software such as DJI or Fusion Camera.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
### Visual refresh across all platforms
|
||||||
|
|
||||||
|
This release also brings you a refreshed look and feel across the web, mobile app, and the documentation site, with a new font face ("The-name-must-not-be-named" Sans) that improves reading legibility, especially for numbers and smaller text.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The UI library (https://ui.immich.app) components have also been added to the web app in more places. You should see a more standardized, coherent, and better hierarchy for UI components across the app.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
All icon buttons now come with a tooltip, so you don't have to guess what function the button serves
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<!-- Release notes generated using configuration in .github/release.yml at main -->
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
|
||||||
|
### 🚀 Features
|
||||||
|
|
||||||
|
* feat: workflow ui by @alextran1502 in <https://github.com/immich-app/immich/pull/24190>
|
||||||
|
* feat: disable admin setup by @jrasm91 in <https://github.com/immich-app/immich/pull/24628>
|
||||||
|
* feat: free up space by @alextran1502 in <https://github.com/immich-app/immich/pull/24999>
|
||||||
|
* feat: use fastlane sigh to manage signing profiles by @alextran1502 in <https://github.com/immich-app/immich/pull/25089>
|
||||||
|
* feat: image editing by @bwees in <https://github.com/immich-app/immich/pull/24155>
|
||||||
|
* feat: add cloud id during native sync by @shenlong-tanwen in <https://github.com/immich-app/immich/pull/20418>
|
||||||
|
* feat: restore database backups by @insertish in <https://github.com/immich-app/immich/pull/23978>
|
||||||
|
* feat(mobile): star rating by @YarosMallorca in <https://github.com/immich-app/immich/pull/24457>
|
||||||
|
* feat(mobile): scrollbar for album page by @alextran1502 in <https://github.com/immich-app/immich/pull/25507>
|
||||||
|
|
||||||
|
### 🌟 Enhancements
|
||||||
|
|
||||||
|
* feat: focus jumped-to item in timeline by @bo0tzz in <https://github.com/immich-app/immich/pull/24738>
|
||||||
|
* chore: web editor improvements by @bwees in <https://github.com/immich-app/immich/pull/25169>
|
||||||
|
* feat: modal routes by @jrasm91 in <https://github.com/immich-app/immich/pull/24726>
|
||||||
|
* feat: prefer admin settings page over users page by @jrasm91 in <https://github.com/immich-app/immich/pull/24780>
|
||||||
|
* feat: shared link edit by @jrasm91 in <https://github.com/immich-app/immich/pull/24783>
|
||||||
|
* feat(mobile): use tabular figures in backup info card by @wrbl606 in <https://github.com/immich-app/immich/pull/24820>
|
||||||
|
* feat(mobile): album options to kebab menu by @idubnori in <https://github.com/immich-app/immich/pull/24204>
|
||||||
|
* feat: Hide/show controls when zoom state changes by @Lauritz-Tieste in <https://github.com/immich-app/immich/pull/24784>
|
||||||
|
* feat(server): Support camera `make`, `model`, and `lensModel` in Storage Template by @rahul-kumar-saini in <https://github.com/immich-app/immich/pull/24650>
|
||||||
|
* feat(ml): update ONNX Runtime, OpenVINO and ROCm stack by @savely-krasovsky in <https://github.com/immich-app/immich/pull/23458>
|
||||||
|
* chore(server): Vchord 1.0 support by @mmomjian in <https://github.com/immich-app/immich/pull/23845>
|
||||||
|
* feat(web): Add coordinate pair location searching. by @GustavJones in <https://github.com/immich-app/immich/pull/24799>
|
||||||
|
* feat: show asset owners for editors in shared albums by @ama156 in <https://github.com/immich-app/immich/pull/24890>
|
||||||
|
* feat(web): undo delete single asset by @YarosMallorca in <https://github.com/immich-app/immich/pull/24439>
|
||||||
|
* feat(server): implement switchable logging formats (console/json) by @DanielRamosAcosta in <https://github.com/immich-app/immich/pull/24791>
|
||||||
|
* chore(web): bump immich/ui for tooltips by @jrasm91 in <https://github.com/immich-app/immich/pull/24632>
|
||||||
|
* feat(web): star rating keyboard shortcut by @cbochs in <https://github.com/immich-app/immich/pull/24620>
|
||||||
|
* feat: bulk asset metadata endpoints by @jrasm91 in <https://github.com/immich-app/immich/pull/25133>
|
||||||
|
* feat(mobile): 2026 font by @alextran1502 in <https://github.com/immich-app/immich/pull/25213>
|
||||||
|
* feat(web): search albums by description by @YarosMallorca in <https://github.com/immich-app/immich/pull/25244>
|
||||||
|
* feat(web): 2026 font by @alextran1502 in <https://github.com/immich-app/immich/pull/25174>
|
||||||
|
* chore: dart http foreground upload by @alextran1502 in <https://github.com/immich-app/immich/pull/24883>
|
||||||
|
* feat: update intel compute driver by @savely-krasovsky in <https://github.com/immich-app/immich/pull/25259>
|
||||||
|
* feat: download original asset by @danieldietzler in <https://github.com/immich-app/immich/pull/25302>
|
||||||
|
* feat: allow /memory?id= in AndroidManifest by @arne182 in <https://github.com/immich-app/immich/pull/25373>
|
||||||
|
* fix: add scoped API permissions to map endpoints by @meesfrensel in <https://github.com/immich-app/immich/pull/25423>
|
||||||
|
* fix(server): scoped permissions for more endpoints by @meesfrensel in <https://github.com/immich-app/immich/pull/25452>
|
||||||
|
* feat: generate progressive JPEGs for thumbnails by @midzelis in <https://github.com/immich-app/immich/pull/25463>
|
||||||
|
* feat: loop slideshows by @GeneralZero in <https://github.com/immich-app/immich/pull/25462>
|
||||||
|
* feat(mobile): native clients by @mertalev in <https://github.com/immich-app/immich/pull/21459>
|
||||||
|
|
||||||
|
### 🐛 Bug fixes
|
||||||
|
|
||||||
|
* fix(maintenance): prevent enable/disable maintenance CLI hanging on occasion by @insertish in <https://github.com/immich-app/immich/pull/24713>
|
||||||
|
* fix(web): display jxl original by @mertalev in <https://github.com/immich-app/immich/pull/24766>
|
||||||
|
* fix(web): stale album info by @jrasm91 in <https://github.com/immich-app/immich/pull/24787>
|
||||||
|
* fix: album card timezone by @danieldietzler in <https://github.com/immich-app/immich/pull/24855>
|
||||||
|
* fix(web): let slideshow videos play (#19601) by @keanucz in <https://github.com/immich-app/immich/pull/24914>
|
||||||
|
* fix(server): update exiftool-vendored to v34.3 for correct colon-less timezone parsing by @dosten in <https://github.com/immich-app/immich/pull/24979>
|
||||||
|
* fix(mobile): hide delete action for remote-only assets by @skrmc in <https://github.com/immich-app/immich/pull/25010>
|
||||||
|
* fix: import config from json by @MontejoJorge in <https://github.com/immich-app/immich/pull/25030>
|
||||||
|
* fix: search input has incorrect focus state after closing the search filter modal by @alextran1502 in <https://github.com/immich-app/immich/pull/24886>
|
||||||
|
* fix(web): duplicate key error and enable expiration editing for expired shared links by @timonrieger in <https://github.com/immich-app/immich/pull/24686>
|
||||||
|
* fix: shared-link-mapper by @jrasm91 in <https://github.com/immich-app/immich/pull/24794>
|
||||||
|
* fix(server): migrate motion part of live photo by @NikhilAlapati in <https://github.com/immich-app/immich/pull/24688>
|
||||||
|
* fix(web): use asset date for change date popup when single asset selected by @majiayu000 in <https://github.com/immich-app/immich/pull/25076>
|
||||||
|
* fix(web): long text taking more width than expected in duplicate manager by @HemendraSinghShekhawat in <https://github.com/immich-app/immich/pull/24547>
|
||||||
|
* fix(web): broken asset urls if shared link has photos in name by @YarosMallorca in <https://github.com/immich-app/immich/pull/24451>
|
||||||
|
* fix(server): search statistics with personIds returns 500 by @majiayu000 in <https://github.com/immich-app/immich/pull/25074>
|
||||||
|
* fix(web): server stats layout by @meesfrensel in <https://github.com/immich-app/immich/pull/25085>
|
||||||
|
* fix: enter now submits the date modals by @fabb in <https://github.com/immich-app/immich/pull/25053>
|
||||||
|
* fix(web): improve text contrast in minimized upload panel by @majiayu000 in <https://github.com/immich-app/immich/pull/25075>
|
||||||
|
* fix: propagate iCloud Shared Album flag by @alextran1502 in <https://github.com/immich-app/immich/pull/25060>
|
||||||
|
* fix: description does not rerender when navigating between assets by @alextran1502 in <https://github.com/immich-app/immich/pull/25137>
|
||||||
|
* fix(server): avoid upserting empty metadata array by @timonrieger in <https://github.com/immich-app/immich/pull/25143>
|
||||||
|
* fix(server): Document HTTP 200 response for duplicate uploads in OpenAPI by @timonrieger in <https://github.com/immich-app/immich/pull/25148>
|
||||||
|
* fix(web): person asset count doesn't update when navigating by @YarosMallorca in <https://github.com/immich-app/immich/pull/24438>
|
||||||
|
* fix(mobile): remove weird zooming behaviour on videos and play/pause button delay by @goalie2002 in <https://github.com/immich-app/immich/pull/24006>
|
||||||
|
* fix: unlock properties after successful sidecar write by @danieldietzler in <https://github.com/immich-app/immich/pull/25168>
|
||||||
|
* fix(web): show relevant navbar options for partner assets by @YarosMallorca in <https://github.com/immich-app/immich/pull/24832>
|
||||||
|
* fix(web): added background gradient for video time visibility by @HemendraSinghShekhawat in <https://github.com/immich-app/immich/pull/25138>
|
||||||
|
* feat(mobile): do not restore locally deleted assets during trash sync (Android) by @PeterOmbodi in <https://github.com/immich-app/immich/pull/24218>
|
||||||
|
* fix: asset local type casting by @alextran1502 in <https://github.com/immich-app/immich/pull/25214>
|
||||||
|
* fix(web): ocr button not clickable for stacked assets by @YarosMallorca in <https://github.com/immich-app/immich/pull/25210>
|
||||||
|
* fix(web): Handle upload failures from public users by @juliancarrivick in <https://github.com/immich-app/immich/pull/24826>
|
||||||
|
* fix(mobile): prevent system UI from hiding on drag down gesture by @goalie2002 in <https://github.com/immich-app/immich/pull/25240>
|
||||||
|
* fix: migration order by @jrasm91 in <https://github.com/immich-app/immich/pull/25249>
|
||||||
|
* fix(web): redirect to login by @jrasm91 in <https://github.com/immich-app/immich/pull/25254>
|
||||||
|
* fix(mobile): improve asset transition back to timeline by @goalie2002 in <https://github.com/immich-app/immich/pull/24485>
|
||||||
|
* fix: dark mode appbar color by @akashKarmakar02 in <https://github.com/immich-app/immich/pull/24976>
|
||||||
|
* fix(web): add min-width to setting input field by @K0lin in <https://github.com/immich-app/immich/pull/25317>
|
||||||
|
* fix(server): api key update checks by @jrasm91 in <https://github.com/immich-app/immich/pull/25363>
|
||||||
|
* fix(mobile): album selector icon visibility by @ByteSizedMarius in <https://github.com/immich-app/immich/pull/25311>
|
||||||
|
* fix(mobile): indicators not showing on thumbnail tile after asset change in viewer by @goalie2002 in <https://github.com/immich-app/immich/pull/25297>
|
||||||
|
* fix(web): handle deletion from asset viewer on map page by @meesfrensel in <https://github.com/immich-app/immich/pull/25393>
|
||||||
|
* fix: tag update race condition by @danieldietzler in <https://github.com/immich-app/immich/pull/25371>
|
||||||
|
* fix(web): allow exiting pin setup flow by @meesfrensel in <https://github.com/immich-app/immich/pull/25413>
|
||||||
|
* fix: upload file without extension by @alextran1502 in <https://github.com/immich-app/immich/pull/25419>
|
||||||
|
* fix: incorrect asset viewer scale on image frame update by @shenlong-tanwen in <https://github.com/immich-app/immich/pull/25430>
|
||||||
|
* fix(mobile): bring back map settings by @shenlong-tanwen in <https://github.com/immich-app/immich/pull/25448>
|
||||||
|
* fix(web): fix badge value in queues page by @beinganukul in <https://github.com/immich-app/immich/pull/25445>
|
||||||
|
* fix(mobile): backfill asset dimensions to exif table by @bwees in <https://github.com/immich-app/immich/pull/25483>
|
||||||
|
* fix(mobile): do not try to load video as image by @mertalev in <https://github.com/immich-app/immich/pull/25495>
|
||||||
|
|
||||||
|
### 📚 Documentation
|
||||||
|
|
||||||
|
* fix: product keys wording in commercial guidelines faq by @bo0tzz in <https://github.com/immich-app/immich/pull/24765>
|
||||||
|
* docs: config options for hardware transcoding by @Javex in <https://github.com/immich-app/immich/pull/24853>
|
||||||
|
* fix: use my.immich.app as url placeholder in docs by @bo0tzz in <https://github.com/immich-app/immich/pull/25153>
|
||||||
|
* chore: update Thai README (remove "under active development" lines) by @ppnplus in <https://github.com/immich-app/immich/pull/25208>
|
||||||
|
* fix(docs): add missing mermaid dependency and configuration by @bdoerfchen in <https://github.com/immich-app/immich/pull/25247>
|
||||||
|
* chore(docs): update RAM req by @mmomjian in <https://github.com/immich-app/immich/pull/25344>
|
||||||
|
* feat(docs): add Free Up Space section by @aviv926 in <https://github.com/immich-app/immich/pull/25253>
|
||||||
|
* docs: update README_de_DE.md by @solluh in <https://github.com/immich-app/immich/pull/25443>
|
||||||
|
* fix(docs): document that fullsize thumbnail might redirect to original by @meesfrensel in <https://github.com/immich-app/immich/pull/25416>
|
||||||
|
* docs: update documentation by @alextran1502 in <https://github.com/immich-app/immich/pull/25440>
|
||||||
|
|
||||||
|
## New Contributors
|
||||||
|
|
||||||
|
* @wrbl606 made their first contribution in <https://github.com/immich-app/immich/pull/24820>
|
||||||
|
* @keanucz made their first contribution in <https://github.com/immich-app/immich/pull/24914>
|
||||||
|
* @rahul-kumar-saini made their first contribution in <https://github.com/immich-app/immich/pull/24650>
|
||||||
|
* @dosten made their first contribution in <https://github.com/immich-app/immich/pull/24979>
|
||||||
|
* @GustavJones made their first contribution in <https://github.com/immich-app/immich/pull/24799>
|
||||||
|
* @skrmc made their first contribution in <https://github.com/immich-app/immich/pull/25010>
|
||||||
|
* @ama156 made their first contribution in <https://github.com/immich-app/immich/pull/24890>
|
||||||
|
* @DanielRamosAcosta made their first contribution in <https://github.com/immich-app/immich/pull/24791>
|
||||||
|
* @NikhilAlapati made their first contribution in <https://github.com/immich-app/immich/pull/24688>
|
||||||
|
* @flpcury made their first contribution in <https://github.com/immich-app/immich/pull/24867>
|
||||||
|
* @Javex made their first contribution in <https://github.com/immich-app/immich/pull/24853>
|
||||||
|
* @majiayu000 made their first contribution in <https://github.com/immich-app/immich/pull/25076>
|
||||||
|
* @HemendraSinghShekhawat made their first contribution in <https://github.com/immich-app/immich/pull/24547>
|
||||||
|
* @cbochs made their first contribution in <https://github.com/immich-app/immich/pull/24620>
|
||||||
|
* @fabb made their first contribution in <https://github.com/immich-app/immich/pull/25053>
|
||||||
|
* @ppnplus made their first contribution in <https://github.com/immich-app/immich/pull/25208>
|
||||||
|
* @juliancarrivick made their first contribution in <https://github.com/immich-app/immich/pull/24826>
|
||||||
|
* @bdoerfchen made their first contribution in <https://github.com/immich-app/immich/pull/25247>
|
||||||
|
* @akashKarmakar02 made their first contribution in <https://github.com/immich-app/immich/pull/24976>
|
||||||
|
* @K0lin made their first contribution in <https://github.com/immich-app/immich/pull/25317>
|
||||||
|
* @NAM-MAN made their first contribution in <https://github.com/immich-app/immich/pull/25320>
|
||||||
|
* @ByteSizedMarius made their first contribution in <https://github.com/immich-app/immich/pull/25311>
|
||||||
|
* @arne182 made their first contribution in <https://github.com/immich-app/immich/pull/25373>
|
||||||
|
* @solluh made their first contribution in <https://github.com/immich-app/immich/pull/25443>
|
||||||
|
* @beinganukul made their first contribution in <https://github.com/immich-app/immich/pull/25445>
|
||||||
|
* @GeneralZero made their first contribution in <https://github.com/immich-app/immich/pull/25462>
|
||||||
|
|
||||||
|
**Full Changelog**: <https://github.com/immich-app/immich/compare/v2.4.1...v2.5.0>
|
||||||
|
|
||||||
|
<!-- Release notes generated using configuration in .github/release.yml at main -->
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
### 🚀 Features
|
||||||
|
* feat: workflow ui by @alextran1502 in https://github.com/immich-app/immich/pull/24190
|
||||||
|
* feat: disable admin setup by @jrasm91 in https://github.com/immich-app/immich/pull/24628
|
||||||
|
* feat: free up space by @alextran1502 in https://github.com/immich-app/immich/pull/24999
|
||||||
|
* feat: use fastlane sigh to manage signing profiles by @alextran1502 in https://github.com/immich-app/immich/pull/25089
|
||||||
|
* feat: image editing by @bwees in https://github.com/immich-app/immich/pull/24155
|
||||||
|
* feat: add cloud id during native sync by @shenlong-tanwen in https://github.com/immich-app/immich/pull/20418
|
||||||
|
* chore: web editor improvements by @bwees in https://github.com/immich-app/immich/pull/25169
|
||||||
|
* feat: restore database backups by @insertish in https://github.com/immich-app/immich/pull/23978
|
||||||
|
* feat(mobile): star rating by @YarosMallorca in https://github.com/immich-app/immich/pull/24457
|
||||||
|
* feat(mobile): scrollbar for album page by @alextran1502 in https://github.com/immich-app/immich/pull/25507
|
||||||
|
### 🌟 Enhancements
|
||||||
|
* feat: focus jumped-to item in timeline by @bo0tzz in https://github.com/immich-app/immich/pull/24738
|
||||||
|
* feat: modal routes by @jrasm91 in https://github.com/immich-app/immich/pull/24726
|
||||||
|
* feat: prefer admin settings page over users page by @jrasm91 in https://github.com/immich-app/immich/pull/24780
|
||||||
|
* feat: shared link edit by @jrasm91 in https://github.com/immich-app/immich/pull/24783
|
||||||
|
* feat(mobile): use tabular figures in backup info card by @wrbl606 in https://github.com/immich-app/immich/pull/24820
|
||||||
|
* feat(mobile): album options to kebab menu by @idubnori in https://github.com/immich-app/immich/pull/24204
|
||||||
|
* feat: Hide/show controls when zoom state changes by @Lauritz-Tieste in https://github.com/immich-app/immich/pull/24784
|
||||||
|
* feat(server): Support camera `make`, `model`, and `lensModel` in Storage Template by @rahul-kumar-saini in https://github.com/immich-app/immich/pull/24650
|
||||||
|
* feat(ml): update ONNX Runtime, OpenVINO and ROCm stack by @savely-krasovsky in https://github.com/immich-app/immich/pull/23458
|
||||||
|
* chore(server): Vchord 1.0 support by @mmomjian in https://github.com/immich-app/immich/pull/23845
|
||||||
|
* feat(web): Add coordinate pair location searching. by @GustavJones in https://github.com/immich-app/immich/pull/24799
|
||||||
|
* feat: show asset owners for editors in shared albums by @ama156 in https://github.com/immich-app/immich/pull/24890
|
||||||
|
* feat(web): undo delete single asset by @YarosMallorca in https://github.com/immich-app/immich/pull/24439
|
||||||
|
* feat(server): implement switchable logging formats (console/json) by @DanielRamosAcosta in https://github.com/immich-app/immich/pull/24791
|
||||||
|
* chore(web): bump immich/ui for tooltips by @jrasm91 in https://github.com/immich-app/immich/pull/24632
|
||||||
|
* feat(web): star rating keyboard shortcut by @cbochs in https://github.com/immich-app/immich/pull/24620
|
||||||
|
* feat: bulk asset metadata endpoints by @jrasm91 in https://github.com/immich-app/immich/pull/25133
|
||||||
|
* feat(mobile): 2026 font by @alextran1502 in https://github.com/immich-app/immich/pull/25213
|
||||||
|
* feat(web): search albums by description by @YarosMallorca in https://github.com/immich-app/immich/pull/25244
|
||||||
|
* feat(web): 2026 font by @alextran1502 in https://github.com/immich-app/immich/pull/25174
|
||||||
|
* chore: dart http foreground upload by @alextran1502 in https://github.com/immich-app/immich/pull/24883
|
||||||
|
* feat: update intel compute driver by @savely-krasovsky in https://github.com/immich-app/immich/pull/25259
|
||||||
|
* feat: download original asset by @danieldietzler in https://github.com/immich-app/immich/pull/25302
|
||||||
|
* feat: allow /memory?id= in AndroidManifest by @arne182 in https://github.com/immich-app/immich/pull/25373
|
||||||
|
* fix: add scoped API permissions to map endpoints by @meesfrensel in https://github.com/immich-app/immich/pull/25423
|
||||||
|
* fix(server): scoped permissions for more endpoints by @meesfrensel in https://github.com/immich-app/immich/pull/25452
|
||||||
|
* feat: generate progressive JPEGs for thumbnails by @midzelis in https://github.com/immich-app/immich/pull/25463
|
||||||
|
* feat: loop slideshows by @GeneralZero in https://github.com/immich-app/immich/pull/25462
|
||||||
|
* feat(mobile): native clients by @mertalev in https://github.com/immich-app/immich/pull/21459
|
||||||
|
### 🐛 Bug fixes
|
||||||
|
* fix(maintenance): prevent enable/disable maintenance CLI hanging on occasion by @insertish in https://github.com/immich-app/immich/pull/24713
|
||||||
|
* fix(web): display jxl original by @mertalev in https://github.com/immich-app/immich/pull/24766
|
||||||
|
* fix(web): stale album info by @jrasm91 in https://github.com/immich-app/immich/pull/24787
|
||||||
|
* fix: album card timezone by @danieldietzler in https://github.com/immich-app/immich/pull/24855
|
||||||
|
* fix(web): let slideshow videos play (#19601) by @keanucz in https://github.com/immich-app/immich/pull/24914
|
||||||
|
* fix(server): update exiftool-vendored to v34.3 for correct colon-less timezone parsing by @dosten in https://github.com/immich-app/immich/pull/24979
|
||||||
|
* fix(mobile): hide delete action for remote-only assets by @skrmc in https://github.com/immich-app/immich/pull/25010
|
||||||
|
* fix: import config from json by @MontejoJorge in https://github.com/immich-app/immich/pull/25030
|
||||||
|
* fix: search input has incorrect focus state after closing the search filter modal by @alextran1502 in https://github.com/immich-app/immich/pull/24886
|
||||||
|
* fix(web): duplicate key error and enable expiration editing for expired shared links by @timonrieger in https://github.com/immich-app/immich/pull/24686
|
||||||
|
* fix: shared-link-mapper by @jrasm91 in https://github.com/immich-app/immich/pull/24794
|
||||||
|
* fix(server): migrate motion part of live photo by @NikhilAlapati in https://github.com/immich-app/immich/pull/24688
|
||||||
|
* fix(web): use asset date for change date popup when single asset selected by @majiayu000 in https://github.com/immich-app/immich/pull/25076
|
||||||
|
* fix(web): long text taking more width than expected in duplicate manager by @HemendraSinghShekhawat in https://github.com/immich-app/immich/pull/24547
|
||||||
|
* fix(web): broken asset urls if shared link has photos in name by @YarosMallorca in https://github.com/immich-app/immich/pull/24451
|
||||||
|
* fix(server): search statistics with personIds returns 500 by @majiayu000 in https://github.com/immich-app/immich/pull/25074
|
||||||
|
* fix(web): server stats layout by @meesfrensel in https://github.com/immich-app/immich/pull/25085
|
||||||
|
* fix: enter now submits the date modals by @fabb in https://github.com/immich-app/immich/pull/25053
|
||||||
|
* fix(web): improve text contrast in minimized upload panel by @majiayu000 in https://github.com/immich-app/immich/pull/25075
|
||||||
|
* fix: propagate iCloud Shared Album flag by @alextran1502 in https://github.com/immich-app/immich/pull/25060
|
||||||
|
* fix: description does not rerender when navigating between assets by @alextran1502 in https://github.com/immich-app/immich/pull/25137
|
||||||
|
* fix(server): avoid upserting empty metadata array by @timonrieger in https://github.com/immich-app/immich/pull/25143
|
||||||
|
* fix(server): Document HTTP 200 response for duplicate uploads in OpenAPI by @timonrieger in https://github.com/immich-app/immich/pull/25148
|
||||||
|
* fix(web): person asset count doesn't update when navigating by @YarosMallorca in https://github.com/immich-app/immich/pull/24438
|
||||||
|
* fix(mobile): remove weird zooming behaviour on videos and play/pause button delay by @goalie2002 in https://github.com/immich-app/immich/pull/24006
|
||||||
|
* fix: unlock properties after successful sidecar write by @danieldietzler in https://github.com/immich-app/immich/pull/25168
|
||||||
|
* fix(web): show relevant navbar options for partner assets by @YarosMallorca in https://github.com/immich-app/immich/pull/24832
|
||||||
|
* fix(web): added background gradient for video time visibility by @HemendraSinghShekhawat in https://github.com/immich-app/immich/pull/25138
|
||||||
|
* feat(mobile): do not restore locally deleted assets during trash sync (Android) by @PeterOmbodi in https://github.com/immich-app/immich/pull/24218
|
||||||
|
* fix: asset local type casting by @alextran1502 in https://github.com/immich-app/immich/pull/25214
|
||||||
|
* fix(web): ocr button not clickable for stacked assets by @YarosMallorca in https://github.com/immich-app/immich/pull/25210
|
||||||
|
* fix(web): Handle upload failures from public users by @juliancarrivick in https://github.com/immich-app/immich/pull/24826
|
||||||
|
* fix(mobile): prevent system UI from hiding on drag down gesture by @goalie2002 in https://github.com/immich-app/immich/pull/25240
|
||||||
|
* fix: migration order by @jrasm91 in https://github.com/immich-app/immich/pull/25249
|
||||||
|
* fix(web): redirect to login by @jrasm91 in https://github.com/immich-app/immich/pull/25254
|
||||||
|
* fix(mobile): improve asset transition back to timeline by @goalie2002 in https://github.com/immich-app/immich/pull/24485
|
||||||
|
* fix: dark mode appbar color by @akashKarmakar02 in https://github.com/immich-app/immich/pull/24976
|
||||||
|
* fix(web): add min-width to setting input field by @K0lin in https://github.com/immich-app/immich/pull/25317
|
||||||
|
* fix(server): api key update checks by @jrasm91 in https://github.com/immich-app/immich/pull/25363
|
||||||
|
* fix(mobile): album selector icon visibility by @ByteSizedMarius in https://github.com/immich-app/immich/pull/25311
|
||||||
|
* fix(mobile): indicators not showing on thumbnail tile after asset change in viewer by @goalie2002 in https://github.com/immich-app/immich/pull/25297
|
||||||
|
* fix(web): handle deletion from asset viewer on map page by @meesfrensel in https://github.com/immich-app/immich/pull/25393
|
||||||
|
* fix: tag update race condition by @danieldietzler in https://github.com/immich-app/immich/pull/25371
|
||||||
|
* fix(web): allow exiting pin setup flow by @meesfrensel in https://github.com/immich-app/immich/pull/25413
|
||||||
|
* fix: upload file without extension by @alextran1502 in https://github.com/immich-app/immich/pull/25419
|
||||||
|
* fix: incorrect asset viewer scale on image frame update by @shenlong-tanwen in https://github.com/immich-app/immich/pull/25430
|
||||||
|
* fix(mobile): bring back map settings by @shenlong-tanwen in https://github.com/immich-app/immich/pull/25448
|
||||||
|
* fix(web): fix badge value in queues page by @beinganukul in https://github.com/immich-app/immich/pull/25445
|
||||||
|
* fix(mobile): backfill asset dimensions to exif table by @bwees in https://github.com/immich-app/immich/pull/25483
|
||||||
|
* fix(mobile): do not try to load video as image by @mertalev in https://github.com/immich-app/immich/pull/25495
|
||||||
|
* fix: deep link service when user is null by @bwees in https://github.com/immich-app/immich/pull/25530
|
||||||
|
### 📚 Documentation
|
||||||
|
* fix: product keys wording in commercial guidelines faq by @bo0tzz in https://github.com/immich-app/immich/pull/24765
|
||||||
|
* docs: config options for hardware transcoding by @Javex in https://github.com/immich-app/immich/pull/24853
|
||||||
|
* fix: use my.immich.app as url placeholder in docs by @bo0tzz in https://github.com/immich-app/immich/pull/25153
|
||||||
|
* chore: update Thai README (remove "under active development" lines) by @ppnplus in https://github.com/immich-app/immich/pull/25208
|
||||||
|
* fix(docs): add missing mermaid dependency and configuration by @bdoerfchen in https://github.com/immich-app/immich/pull/25247
|
||||||
|
* chore(docs): update RAM req by @mmomjian in https://github.com/immich-app/immich/pull/25344
|
||||||
|
* feat(docs): add Free Up Space section by @aviv926 in https://github.com/immich-app/immich/pull/25253
|
||||||
|
* docs: update README_de_DE.md by @solluh in https://github.com/immich-app/immich/pull/25443
|
||||||
|
* fix(docs): document that fullsize thumbnail might redirect to original by @meesfrensel in https://github.com/immich-app/immich/pull/25416
|
||||||
|
* docs: update documentation by @alextran1502 in https://github.com/immich-app/immich/pull/25440
|
||||||
|
|
||||||
|
## New Contributors
|
||||||
|
* @wrbl606 made their first contribution in https://github.com/immich-app/immich/pull/24820
|
||||||
|
* @keanucz made their first contribution in https://github.com/immich-app/immich/pull/24914
|
||||||
|
* @rahul-kumar-saini made their first contribution in https://github.com/immich-app/immich/pull/24650
|
||||||
|
* @dosten made their first contribution in https://github.com/immich-app/immich/pull/24979
|
||||||
|
* @GustavJones made their first contribution in https://github.com/immich-app/immich/pull/24799
|
||||||
|
* @skrmc made their first contribution in https://github.com/immich-app/immich/pull/25010
|
||||||
|
* @ama156 made their first contribution in https://github.com/immich-app/immich/pull/24890
|
||||||
|
* @DanielRamosAcosta made their first contribution in https://github.com/immich-app/immich/pull/24791
|
||||||
|
* @NikhilAlapati made their first contribution in https://github.com/immich-app/immich/pull/24688
|
||||||
|
* @flpcury made their first contribution in https://github.com/immich-app/immich/pull/24867
|
||||||
|
* @Javex made their first contribution in https://github.com/immich-app/immich/pull/24853
|
||||||
|
* @majiayu000 made their first contribution in https://github.com/immich-app/immich/pull/25076
|
||||||
|
* @HemendraSinghShekhawat made their first contribution in https://github.com/immich-app/immich/pull/24547
|
||||||
|
* @cbochs made their first contribution in https://github.com/immich-app/immich/pull/24620
|
||||||
|
* @fabb made their first contribution in https://github.com/immich-app/immich/pull/25053
|
||||||
|
* @ppnplus made their first contribution in https://github.com/immich-app/immich/pull/25208
|
||||||
|
* @juliancarrivick made their first contribution in https://github.com/immich-app/immich/pull/24826
|
||||||
|
* @bdoerfchen made their first contribution in https://github.com/immich-app/immich/pull/25247
|
||||||
|
* @akashKarmakar02 made their first contribution in https://github.com/immich-app/immich/pull/24976
|
||||||
|
* @K0lin made their first contribution in https://github.com/immich-app/immich/pull/25317
|
||||||
|
* @NAM-MAN made their first contribution in https://github.com/immich-app/immich/pull/25320
|
||||||
|
* @ByteSizedMarius made their first contribution in https://github.com/immich-app/immich/pull/25311
|
||||||
|
* @arne182 made their first contribution in https://github.com/immich-app/immich/pull/25373
|
||||||
|
* @solluh made their first contribution in https://github.com/immich-app/immich/pull/25443
|
||||||
|
* @beinganukul made their first contribution in https://github.com/immich-app/immich/pull/25445
|
||||||
|
* @GeneralZero made their first contribution in https://github.com/immich-app/immich/pull/25462
|
||||||
|
* @ianmuninio made their first contribution in https://github.com/immich-app/immich/pull/25468
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/immich-app/immich/compare/v2.4.1...v2.5.0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
31
CONTRIBUTING.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Contributing to Immich
|
||||||
|
|
||||||
|
We appreciate every contribution, and we're happy about every new contributor. So please feel invited to help make Immich a better product!
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
To get you started quickly we have detailed guides for the dev setup on our [website](https://docs.immich.app/developer/setup). If you prefer, you can also use [Devcontainers](https://docs.immich.app/developer/devcontainers).
|
||||||
|
There are also additional resources about Immich's architecture, database migrations, the use of OpenAPI, and more in our [developer documentation](https://docs.immich.app/developer/architecture).
|
||||||
|
|
||||||
|
## General
|
||||||
|
|
||||||
|
Please try to keep pull requests as focused as possible. A PR should do exactly one thing and not bleed into other, unrelated areas. The smaller a PR, the fewer changes are likely needed, and the quicker it will likely be merged. For larger/more impactful PRs, please reach out to us first to discuss your plans. The best way to do this is through our [Discord](https://discord.immich.app). We have a dedicated `#contributing` channel there. Additionally, please fill out the entire template when opening a PR.
|
||||||
|
|
||||||
|
## Finding work
|
||||||
|
|
||||||
|
If you are looking for something to work on, there are discussions and issues with a `good-first-issue` label on them. These are always a good starting point. If none of them sound interesting or fit your skill set, feel free to reach out on our Discord. We're happy to help you find something to work on!
|
||||||
|
|
||||||
|
## Use of generative AI
|
||||||
|
|
||||||
|
We generally discourage PRs entirely generated by an LLM. For any part generated by an LLM, please put extra effort into your self-review. By using generative AI without proper self-review, the time you save ends up being more work we need to put in for proper reviews and code cleanup. Please keep that in mind when submitting code by an LLM. Clearly state the use of LLMs/(generative) AI in your pull request as requested by the template.
|
||||||
|
|
||||||
|
## Feature freezes
|
||||||
|
|
||||||
|
From time to time, we put a feature freeze on parts of the codebase. For us, this means we won't accept most PRs that make changes in that area. Exempted from this are simple bug fixes that require only minor changes. We will close feature PRs that target a feature-frozen area, even if that feature is highly requested and you put a lot of work into it. Please keep that in mind, and if you're ever uncertain if a PR would be accepted, reach out to us first (e.g., in the aforementioned `#contributing` channel). We hate to throw away work. Currently, we have feature freezes on:
|
||||||
|
|
||||||
|
* Sharing/Asset ownership
|
||||||
|
* (External) libraries
|
||||||
|
|
||||||
|
## Non-code contributions
|
||||||
|
|
||||||
|
If you want to contribute to Immich but you don't feel comfortable programming in our tech stack, there are other ways you can help the team. All our translations are done through [Weblate](https://hosted.weblate.org/projects/immich). These rely entirely on the community; if you speak a language that isn't fully translated yet, submitting translations there is greatly appreciated! If you like helping others, answering Q&A discussions here on GitHub and replying to people on our Discord is also always appreciated.
|
||||||
3
Makefile
@@ -17,6 +17,9 @@ dev-docs:
|
|||||||
e2e:
|
e2e:
|
||||||
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --remove-orphans
|
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --remove-orphans
|
||||||
|
|
||||||
|
e2e-dev:
|
||||||
|
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.dev.yml up --remove-orphans
|
||||||
|
|
||||||
e2e-update:
|
e2e-update:
|
||||||
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans
|
@trap 'make e2e-down' EXIT; COMPOSE_BAKE=true docker compose -f ./e2e/docker-compose.yml up --build -V --remove-orphans
|
||||||
|
|
||||||
|
|||||||
10
README.md
@@ -118,16 +118,16 @@ Read more about translations [here](https://docs.immich.app/developer/translatio
|
|||||||
|
|
||||||
## Star history
|
## Star history
|
||||||
|
|
||||||
<a href="https://star-history.com/#immich-app/immich&Date">
|
<a href="https://star-history.com/#immich-app/immich&type=date&legend=top-left">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=immich-app/immich&type=Date&theme=dark" />
|
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=immich-app/immich&type=date&theme=dark" />
|
||||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=immich-app/immich&type=Date" />
|
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=immich-app/immich&type=date" />
|
||||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=immich-app/immich&type=Date" width="100%" />
|
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=immich-app/immich&type=date" width="100%" />
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
<a href="https://github.com/alextran1502/immich/graphs/contributors">
|
<a href="https://github.com/immich-app/immich/graphs/contributors">
|
||||||
<img src="https://contrib.rocks/image?repo=immich-app/immich" width="100%"/>
|
<img src="https://contrib.rocks/image?repo=immich-app/immich" width="100%"/>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
24.11.0
|
24.13.0
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM node:22.16.0-alpine3.20@sha256:2289fb1fba0f4633b08ec47b94a89c7e20b829fc5679f9b7b298eaa2f1ed8b7e AS core
|
FROM node:24.1.0-alpine3.20@sha256:8fe019e0d57dbdce5f5c27c0b63d2775cf34b00e3755a7dea969802d7e0c2b25 AS core
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
COPY package* pnpm* .pnpmfile.cjs ./
|
COPY package* pnpm* .pnpmfile.cjs ./
|
||||||
|
|||||||
29
cli/mise.toml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
[tasks.install]
|
||||||
|
run = "pnpm install --filter @immich/cli --frozen-lockfile"
|
||||||
|
|
||||||
|
[tasks.build]
|
||||||
|
env._.path = "./node_modules/.bin"
|
||||||
|
run = "vite build"
|
||||||
|
|
||||||
|
[tasks.test]
|
||||||
|
env._.path = "./node_modules/.bin"
|
||||||
|
run = "vite"
|
||||||
|
|
||||||
|
[tasks.lint]
|
||||||
|
env._.path = "./node_modules/.bin"
|
||||||
|
run = "eslint \"src/**/*.ts\" --max-warnings 0"
|
||||||
|
|
||||||
|
[tasks."lint-fix"]
|
||||||
|
run = { task = "lint --fix" }
|
||||||
|
|
||||||
|
[tasks.format]
|
||||||
|
env._.path = "./node_modules/.bin"
|
||||||
|
run = "prettier --check ."
|
||||||
|
|
||||||
|
[tasks."format-fix"]
|
||||||
|
env._.path = "./node_modules/.bin"
|
||||||
|
run = "prettier --write ."
|
||||||
|
|
||||||
|
[tasks.check]
|
||||||
|
env._.path = "./node_modules/.bin"
|
||||||
|
run = "tsc --noEmit"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/cli",
|
"name": "@immich/cli",
|
||||||
"version": "2.2.101",
|
"version": "2.2.106",
|
||||||
"description": "Command Line Interface (CLI) for Immich",
|
"description": "Command Line Interface (CLI) for Immich",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": "./dist/index.js",
|
"exports": "./dist/index.js",
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/micromatch": "^4.0.9",
|
"@types/micromatch": "^4.0.9",
|
||||||
"@types/mock-fs": "^4.13.1",
|
"@types/mock-fs": "^4.13.1",
|
||||||
"@types/node": "^22.18.13",
|
"@types/node": "^24.10.8",
|
||||||
"@vitest/coverage-v8": "^3.0.0",
|
"@vitest/coverage-v8": "^3.0.0",
|
||||||
"byte-size": "^9.0.0",
|
"byte-size": "^9.0.0",
|
||||||
"cli-progress": "^3.12.0",
|
"cli-progress": "^3.12.0",
|
||||||
@@ -28,15 +28,15 @@
|
|||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^60.0.0",
|
"eslint-plugin-unicorn": "^62.0.0",
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
"mock-fs": "^5.2.0",
|
"mock-fs": "^5.2.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.7.4",
|
||||||
"prettier-plugin-organize-imports": "^4.0.0",
|
"prettier-plugin-organize-imports": "^4.0.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"typescript-eslint": "^8.28.0",
|
"typescript-eslint": "^8.28.0",
|
||||||
"vite": "^7.0.0",
|
"vite": "^7.0.0",
|
||||||
"vite-tsconfig-paths": "^5.0.0",
|
"vite-tsconfig-paths": "^6.0.0",
|
||||||
"vitest": "^3.0.0",
|
"vitest": "^3.0.0",
|
||||||
"vitest-fetch-mock": "^0.4.0",
|
"vitest-fetch-mock": "^0.4.0",
|
||||||
"yaml": "^2.3.1"
|
"yaml": "^2.3.1"
|
||||||
@@ -69,6 +69,6 @@
|
|||||||
"micromatch": "^4.0.8"
|
"micromatch": "^4.0.8"
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "24.11.0"
|
"node": "24.13.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ describe('crawl', () => {
|
|||||||
.map(([file]) => file);
|
.map(([file]) => file);
|
||||||
|
|
||||||
// Compare file's content instead of path since a file can be represent in multiple ways.
|
// Compare file's content instead of path since a file can be represent in multiple ways.
|
||||||
expect(actual.map((path) => readContent(path)).sort()).toEqual(expected.sort());
|
expect(actual.map((path) => readContent(path)).toSorted()).toEqual(expected.toSorted());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ export const crawl = async (options: CrawlOptions): Promise<string[]> => {
|
|||||||
ignore: [`**/${exclusionPattern}`],
|
ignore: [`**/${exclusionPattern}`],
|
||||||
});
|
});
|
||||||
globbedFiles.push(...crawledFiles);
|
globbedFiles.push(...crawledFiles);
|
||||||
return globbedFiles.sort();
|
return globbedFiles.toSorted();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sha1 = (filepath: string) => {
|
export const sha1 = (filepath: string) => {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"target": "es2022",
|
"target": "es2023",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
|
|||||||
20
deployment/mise.toml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
[tools]
|
||||||
|
terragrunt = "0.93.10"
|
||||||
|
opentofu = "1.10.7"
|
||||||
|
|
||||||
|
[tasks."tg:fmt"]
|
||||||
|
run = "terragrunt hclfmt"
|
||||||
|
description = "Format terragrunt files"
|
||||||
|
|
||||||
|
[tasks.tf]
|
||||||
|
run = "terragrunt run --all"
|
||||||
|
description = "Wrapper for terragrunt run-all"
|
||||||
|
dir = "{{cwd}}"
|
||||||
|
|
||||||
|
[tasks."tf:fmt"]
|
||||||
|
run = "tofu fmt -recursive tf/"
|
||||||
|
description = "Format terraform files"
|
||||||
|
|
||||||
|
[tasks."tf:init"]
|
||||||
|
run = { task = "tf init -- -reconfigure" }
|
||||||
|
dir = "{{cwd}}"
|
||||||
@@ -41,6 +41,7 @@ services:
|
|||||||
- app-node_modules:/usr/src/app/node_modules
|
- app-node_modules:/usr/src/app/node_modules
|
||||||
- sveltekit:/usr/src/app/web/.svelte-kit
|
- sveltekit:/usr/src/app/web/.svelte-kit
|
||||||
- coverage:/usr/src/app/web/coverage
|
- coverage:/usr/src/app/web/coverage
|
||||||
|
- ../plugins:/build/corePlugin
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
environment:
|
environment:
|
||||||
@@ -57,10 +58,6 @@ services:
|
|||||||
IMMICH_THIRD_PARTY_BUG_FEATURE_URL: https://github.com/immich-app/immich/issues
|
IMMICH_THIRD_PARTY_BUG_FEATURE_URL: https://github.com/immich-app/immich/issues
|
||||||
IMMICH_THIRD_PARTY_DOCUMENTATION_URL: https://docs.immich.app
|
IMMICH_THIRD_PARTY_DOCUMENTATION_URL: https://docs.immich.app
|
||||||
IMMICH_THIRD_PARTY_SUPPORT_URL: https://docs.immich.app/community-guides
|
IMMICH_THIRD_PARTY_SUPPORT_URL: https://docs.immich.app/community-guides
|
||||||
ulimits:
|
|
||||||
nofile:
|
|
||||||
soft: 1048576
|
|
||||||
hard: 1048576
|
|
||||||
ports:
|
ports:
|
||||||
- 9230:9230
|
- 9230:9230
|
||||||
- 9231:9231
|
- 9231:9231
|
||||||
@@ -99,10 +96,6 @@ services:
|
|||||||
- app-node_modules:/usr/src/app/node_modules
|
- app-node_modules:/usr/src/app/node_modules
|
||||||
- sveltekit:/usr/src/app/web/.svelte-kit
|
- sveltekit:/usr/src/app/web/.svelte-kit
|
||||||
- coverage:/usr/src/app/web/coverage
|
- coverage:/usr/src/app/web/coverage
|
||||||
ulimits:
|
|
||||||
nofile:
|
|
||||||
soft: 1048576
|
|
||||||
hard: 1048576
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
immich-server:
|
immich-server:
|
||||||
@@ -134,7 +127,7 @@ services:
|
|||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
image: docker.io/valkey/valkey:8@sha256:81db6d39e1bba3b3ff32bd3a1b19a6d69690f94a3954ec131277b9a26b95b3aa
|
image: docker.io/valkey/valkey:9@sha256:546304417feac0874c3dd576e0952c6bb8f06bb4093ea0c9ca303c73cf458f63
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: redis-cli ping || exit 1
|
test: redis-cli ping || exit 1
|
||||||
|
|
||||||
@@ -153,6 +146,8 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
shm_size: 128mb
|
shm_size: 128mb
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
# set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics
|
# set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics
|
||||||
# immich-prometheus:
|
# immich-prometheus:
|
||||||
# container_name: immich_prometheus
|
# container_name: immich_prometheus
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ services:
|
|||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
image: docker.io/valkey/valkey:8@sha256:81db6d39e1bba3b3ff32bd3a1b19a6d69690f94a3954ec131277b9a26b95b3aa
|
image: docker.io/valkey/valkey:9@sha256:546304417feac0874c3dd576e0952c6bb8f06bb4093ea0c9ca303c73cf458f63
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: redis-cli ping || exit 1
|
test: redis-cli ping || exit 1
|
||||||
restart: always
|
restart: always
|
||||||
@@ -77,13 +77,15 @@ services:
|
|||||||
- 5432:5432
|
- 5432:5432
|
||||||
shm_size: 128mb
|
shm_size: 128mb
|
||||||
restart: always
|
restart: always
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
|
|
||||||
# set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics
|
# set IMMICH_TELEMETRY_INCLUDE=all in .env to enable metrics
|
||||||
immich-prometheus:
|
immich-prometheus:
|
||||||
container_name: immich_prometheus
|
container_name: immich_prometheus
|
||||||
ports:
|
ports:
|
||||||
- 9090:9090
|
- 9090:9090
|
||||||
image: prom/prometheus@sha256:49214755b6153f90a597adcbff0252cc61069f8ab69ce8411285cd4a560e8038
|
image: prom/prometheus@sha256:1f0f50f06acaceb0f5670d2c8a658a599affe7b0d8e78b898c1035653849a702
|
||||||
volumes:
|
volumes:
|
||||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||||
- prometheus-data:/prometheus
|
- prometheus-data:/prometheus
|
||||||
@@ -95,7 +97,7 @@ services:
|
|||||||
command: ['./run.sh', '-disable-reporting']
|
command: ['./run.sh', '-disable-reporting']
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
image: grafana/grafana:12.2.1-ubuntu@sha256:797530c642f7b41ba7848c44cfda5e361ef1f3391a98bed1e5d448c472b6826a
|
image: grafana/grafana:12.3.1-ubuntu@sha256:d57f1365197aec34c4d80869d8ca45bb7787c7663904950dab214dfb40c1c2fd
|
||||||
volumes:
|
volumes:
|
||||||
- grafana-data:/var/lib/grafana
|
- grafana-data:/var/lib/grafana
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ services:
|
|||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
image: docker.io/valkey/valkey:8@sha256:81db6d39e1bba3b3ff32bd3a1b19a6d69690f94a3954ec131277b9a26b95b3aa
|
image: docker.io/valkey/valkey:9@sha256:546304417feac0874c3dd576e0952c6bb8f06bb4093ea0c9ca303c73cf458f63
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: redis-cli ping || exit 1
|
test: redis-cli ping || exit 1
|
||||||
restart: always
|
restart: always
|
||||||
@@ -69,6 +69,8 @@ services:
|
|||||||
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
||||||
shm_size: 128mb
|
shm_size: 128mb
|
||||||
restart: always
|
restart: always
|
||||||
|
healthcheck:
|
||||||
|
disable: false
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
model-cache:
|
model-cache:
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
24.11.0
|
24.13.0
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ For organizations seeking to resell Immich, we have established the following gu
|
|||||||
|
|
||||||
- Do not misrepresent your reseller site or services as being officially affiliated with or endorsed by Immich or our development team.
|
- Do not misrepresent your reseller site or services as being officially affiliated with or endorsed by Immich or our development team.
|
||||||
|
|
||||||
- For small resellers who wish to contribute financially to Immich's development, we recommend directing your customers to purchase licenses directly from us rather than attempting to broker revenue-sharing arrangements. We ask that you refrain from misrepresenting reseller activities as directly supporting our development work.
|
- For small resellers who wish to contribute financially to Immich's development, we recommend directing your customers to purchase product keys directly from us rather than attempting to broker revenue-sharing arrangements. We ask that you refrain from misrepresenting reseller activities as directly supporting our development work.
|
||||||
|
|
||||||
When in doubt or if you have an edge case scenario, we encourage you to contact us directly via email to discuss the use of our trademark. We can provide clear guidance on what is acceptable and what is not. You can reach out at: questions@immich.app
|
When in doubt or if you have an edge case scenario, we encourage you to contact us directly via email to discuss the use of our trademark. We can provide clear guidance on what is acceptable and what is not. You can reach out at: questions@immich.app
|
||||||
|
|
||||||
@@ -133,9 +133,9 @@ There are a few different scenarios that can lead to this situation. The solutio
|
|||||||
The job is only automatically run once per asset after upload. If metadata extraction originally failed, the jobs were cleared/canceled, etc.,
|
The job is only automatically run once per asset after upload. If metadata extraction originally failed, the jobs were cleared/canceled, etc.,
|
||||||
the job may not have run automatically the first time.
|
the job may not have run automatically the first time.
|
||||||
|
|
||||||
### How can I hide photos from the timeline?
|
### How can I hide a photo or video from the timeline?
|
||||||
|
|
||||||
You can _archive_ them.
|
You can _archive_ them. This will hide the asset from the main timeline and folder view, but it will still show up in searches. All archived assets can be found in the _Archive_ view
|
||||||
|
|
||||||
### How can I backup data from Immich?
|
### How can I backup data from Immich?
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
import Tabs from '@theme/Tabs';
|
import Tabs from '@theme/Tabs';
|
||||||
import TabItem from '@theme/TabItem';
|
import TabItem from '@theme/TabItem';
|
||||||
|
import { mdiAlertCircle, mdiCheckCircle } from '@mdi/js';
|
||||||
|
import Icon from '@mdi/react';
|
||||||
|
|
||||||
A [3-2-1 backup strategy](https://www.backblaze.com/blog/the-3-2-1-backup-strategy/) is recommended to protect your data. You should keep copies of your uploaded photos/videos as well as the Immich database for a comprehensive backup solution. This page provides an overview on how to backup the database and the location of user-uploaded pictures and videos. A template bash script that can be run as a cron job is provided [here](/guides/template-backup-script.md)
|
A [3-2-1 backup strategy](https://www.backblaze.com/blog/the-3-2-1-backup-strategy/) is recommended to protect your data. You should keep copies of your uploaded photos/videos as well as the Immich database for a comprehensive backup solution. This page provides an overview on how to backup the database and the location of user-uploaded pictures and videos. A template bash script that can be run as a cron job is provided [here](/guides/template-backup-script.md)
|
||||||
|
|
||||||
@@ -11,47 +13,127 @@ The instructions on this page show you how to prepare your Immich instance to be
|
|||||||
|
|
||||||
## Database
|
## Database
|
||||||
|
|
||||||
|
Immich stores [file paths](https://github.com/immich-app/immich/discussions/3299) and user metadata in the database. It does not scan the library folder, so database backups are essential.
|
||||||
|
|
||||||
|
### Automatic Database Backups
|
||||||
|
|
||||||
|
Immich automatically creates database backups for disaster-recovery purposes. These backups are stored in `UPLOAD_LOCATION/backups` and can be managed through the web interface.
|
||||||
|
|
||||||
|
You can adjust the backup schedule and retention settings in **Administration > Settings > Backup** (default: keep last 14 backups, create daily at 2:00 AM).
|
||||||
|
|
||||||
:::caution
|
:::caution
|
||||||
Immich saves [file paths in the database](https://github.com/immich-app/immich/discussions/3299), it does not scan the library folder to update the database so backups are crucial.
|
Database backups do **not** contain photos or videos — only metadata. They must be used together with a copy of the files in `UPLOAD_LOCATION` as outlined below.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
#### Creating a Backup
|
||||||
|
|
||||||
|
You can trigger a database backup manually:
|
||||||
|
|
||||||
|
1. Go to **Administration > Job Queues**
|
||||||
|
2. Click **Create job** in the top right
|
||||||
|
3. Select **Create Database Backup** and click **Confirm**
|
||||||
|
|
||||||
|
The backup will appear in `UPLOAD_LOCATION/backups` and counts toward your retention limit.
|
||||||
|
|
||||||
|
### Restoring a Database Backup
|
||||||
|
|
||||||
|
Immich provides two ways to restore a database backup: through the web interface or via the command line. The web interface is the recommended method for most users.
|
||||||
|
|
||||||
|
#### Restore from Settings {#restore-from-settings}
|
||||||
|
|
||||||
|
If you have an existing Immich installation:
|
||||||
|
|
||||||
|
<img
|
||||||
|
src={require('./img/restore-from-settings.webp').default}
|
||||||
|
title="Restore from settings"
|
||||||
|
/>
|
||||||
|
|
||||||
|
1. Go to **Administration > Maintenance**
|
||||||
|
2. Expand the **Restore database backup** section
|
||||||
|
3. You'll see a list of available backups with their version and creation date
|
||||||
|
4. Click **Restore** next to the backup you want to restore
|
||||||
|
5. Confirm the restore operation
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
Refer to the official [postgres documentation](https://www.postgresql.org/docs/current/backup.html) for details about backing up and restoring a postgres database.
|
Restoring a backup will wipe the current database and replace it with the backup. A restore point is automatically created before the operation begins, allowing rollback if the restore fails.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::caution
|
#### Restore from Onboarding {#restore-from-onboarding}
|
||||||
It is not recommended to directly backup the `DB_DATA_LOCATION` folder. Doing so while the database is running can lead to a corrupted backup that cannot be restored.
|
|
||||||
|
If you're setting up Immich on a fresh installation and want to restore from an existing backup:
|
||||||
|
|
||||||
|
1. Download and populate `.env` and `docker-compose.yml` as per the [installation instructions](/install/docker-compose).
|
||||||
|
2. Move the previous's instance data directories containing `backups`, `encoded-video`, `library`, `profile`, `thumbs` and `upload` into the new `UPLOAD_LOCATION`
|
||||||
|
3. **(For external libraries)** If you used external library feature in your previous instance, make sure that the mount settings in your new `docker-compose.yml` reflect the same structure. You may need to move files accordingly.
|
||||||
|
|
||||||
|
:::info Example
|
||||||
|
|
||||||
|
Assuming your previous `UPLOAD_LOCATION` was `UPLOAD_LOCATION=/my-broken-instance/media` and your new one is `UPLOAD_LOCATION=/a-brand-new-instance/data`, you will need to perform the following file moves:
|
||||||
|
|
||||||
|
```
|
||||||
|
/my-broken-instance/media/backups -> /a-brand-new-instance/data/backups
|
||||||
|
/my-broken-instance/media/encoded-video -> /a-brand-new-instance/data/encoded-video
|
||||||
|
/my-broken-instance/media/library -> /a-brand-new-instance/data/library
|
||||||
|
/my-broken-instance/media/profile -> /a-brand-new-instance/data/profile
|
||||||
|
/my-broken-instance/media/thumbs -> /a-brand-new-instance/data/thumbs
|
||||||
|
/my-broken-instance/media/upload -> /a-brand-new-instance/data/upload
|
||||||
|
```
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Automatic Database Dumps
|
4. Start the Immich services with `docker compose up -d`
|
||||||
|
|
||||||
|
<img
|
||||||
|
src={require('./img/restore-from-onboarding.webp').default}
|
||||||
|
title="Restore from onboarding"
|
||||||
|
/>
|
||||||
|
|
||||||
|
5. On the welcome screen, click **Restore from backup**
|
||||||
|
6. Immich will enter maintenance mode and display integrity checks for your storage folders
|
||||||
|
7. Review the folder status to ensure your library files are accessible
|
||||||
|
8. Click **Next** to proceed to backup selection
|
||||||
|
9. Select a backup from the list or upload a backup file (`.sql.gz`)
|
||||||
|
10. Click **Restore** to begin the restoration process
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
Before restoring, ensure your `UPLOAD_LOCATION` folders contain the same files that existed when the backup was created. The integrity check will show you which folders are readable/writable and how many files they contain.
|
||||||
|
:::
|
||||||
|
|
||||||
|
### Uploading a Backup File {#uploading-backup}
|
||||||
|
|
||||||
|
You can upload a database backup file directly:
|
||||||
|
|
||||||
|
1. In the **Restore database backup** section, click **Select from computer**
|
||||||
|
2. Choose a `.sql.gz` file
|
||||||
|
3. The uploaded backup will appear in the list with an `uploaded-` prefix
|
||||||
|
4. Click **Restore** to restore from the uploaded file
|
||||||
|
|
||||||
|
### Backup Version Compatibility {#backup-compatibility}
|
||||||
|
|
||||||
|
When viewing backups, Immich displays compatibility indicators based on the current version and the information from the filename:
|
||||||
|
|
||||||
|
- <Icon path={mdiCheckCircle} size={1} color="green"/> Backup version matches current Immich version
|
||||||
|
- <Icon path={mdiAlertCircle} size={1} color="#feb001"/> Backup was created with a different Immich version
|
||||||
|
- <Icon path={mdiAlertCircle} size={1} color="red"/> Could not determine backup version
|
||||||
|
|
||||||
:::warning
|
:::warning
|
||||||
The automatic database dumps can be used to restore the database in the event of damage to the Postgres database files.
|
Restoring a backup from a different Immich version may require database migrations. The restore process will attempt to run migrations automatically, but you should ensure you're restoring to a compatible version when possible.
|
||||||
There is no monitoring for these dumps and you will not be notified if they are unsuccessful.
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::caution
|
### Restore Process {#restore-process}
|
||||||
The database dumps do **NOT** contain any pictures or videos, only metadata. They are only usable with a copy of the other files in `UPLOAD_LOCATION` as outlined below.
|
|
||||||
:::
|
|
||||||
|
|
||||||
For disaster-recovery purposes, Immich will automatically create database dumps. The dumps are stored in `UPLOAD_LOCATION/backups`.
|
During restoration, Immich will:
|
||||||
Please be sure to make your own, independent backup of the database together with the asset folders as noted below.
|
|
||||||
You can adjust the schedule and amount of kept database dumps in the [admin settings](http://my.immich.app/admin/system-settings?isOpen=backup).
|
|
||||||
By default, Immich will keep the last 14 database dumps and create a new dump every day at 2:00 AM.
|
|
||||||
|
|
||||||
#### Trigger Dump
|
1. Create a backup of the current database (restore point)
|
||||||
|
2. Restore the selected backup
|
||||||
|
3. Run database migrations if needed
|
||||||
|
4. Perform a health check to verify the restore succeeded
|
||||||
|
|
||||||
You are able to trigger a database dump in the [admin job status page](http://my.immich.app/admin/jobs-status).
|
If the restore fails (e.g., corrupted backup or missing admin user), Immich will automatically roll back to the restore point.
|
||||||
Visit the page, open the "Create job" modal from the top right, select "Create Database Dump" and click "Confirm".
|
|
||||||
A job will run and trigger a dump, you can verify this worked correctly by checking the logs or the `backups/` folder.
|
|
||||||
This dumps will count towards the last `X` dumps that will be kept based on your settings.
|
|
||||||
|
|
||||||
#### Restoring
|
### Restore via Command Line {#restore-cli}
|
||||||
|
|
||||||
We hope to make restoring simpler in future versions, for now you can find the database dumps in the `UPLOAD_LOCATION/backups` folder on your host.
|
For advanced users or automated recovery scenarios, you can restore a database backup using the command line.
|
||||||
Then please follow the steps in the following section for restoring the database.
|
|
||||||
|
|
||||||
### Manual Backup and Restore
|
|
||||||
|
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<TabItem value="Linux system" label="Linux system" default>
|
<TabItem value="Linux system" label="Linux system" default>
|
||||||
@@ -106,10 +188,12 @@ docker compose up -d # Start remainder of Immich ap
|
|||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
Note that for the database restore to proceed properly, it requires a completely fresh install (i.e. the Immich server has never run since creating the Docker containers). If the Immich app has run, Postgres conflicts may be encountered upon database restoration (relation already exists, violated foreign key constraints, multiple primary keys, etc.), in which case you need to delete the `DB_DATA_LOCATION` folder to reset the database.
|
:::note
|
||||||
|
For the database restore to proceed properly, it requires a completely fresh install (i.e., the Immich server has never run since creating the Docker containers). If the Immich app has run, you may encounter Postgres conflicts (relation already exists, violated foreign key constraints, etc.). In this case, delete the `DB_DATA_LOCATION` folder to reset the database.
|
||||||
|
:::
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
Some deployment methods make it difficult to start the database without also starting the server. In these cases, you may set the environment variable `DB_SKIP_MIGRATIONS=true` before starting the services. This will prevent the server from running migrations that interfere with the restore process. Be sure to remove this variable and restart the services after the database is restored.
|
Some deployment methods make it difficult to start the database without also starting the server. In these cases, set the environment variable `DB_SKIP_MIGRATIONS=true` before starting the services. This prevents the server from running migrations that interfere with the restore process. Remove this variable and restart services after the database is restored.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Filesystem
|
## Filesystem
|
||||||
@@ -157,17 +241,14 @@ for more info read the [release notes](https://github.com/immich-app/immich/rele
|
|||||||
- **Encoded Assets:**
|
- **Encoded Assets:**
|
||||||
- Videos that have been re-encoded from the original for wider compatibility. The original is not removed.
|
- Videos that have been re-encoded from the original for wider compatibility. The original is not removed.
|
||||||
- Stored in `UPLOAD_LOCATION/encoded-video/<userID>`.
|
- Stored in `UPLOAD_LOCATION/encoded-video/<userID>`.
|
||||||
|
- **Database Dump Backups:**
|
||||||
|
- Automatic database backups created by Immich for disaster recovery.
|
||||||
|
- Stored in `UPLOAD_LOCATION/backups/`.
|
||||||
- **Postgres**
|
- **Postgres**
|
||||||
- The Immich database containing all the information to allow the system to function properly.
|
- The Immich database containing all the information to allow the system to function properly.
|
||||||
**Note:** This folder will only appear to users who have made the changes mentioned in [v1.102.0](https://github.com/immich-app/immich/discussions/8930) (an optional, non-mandatory change) or who started with this version.
|
**Note:** This folder will only appear to users who have made the changes mentioned in [v1.102.0](https://github.com/immich-app/immich/discussions/8930) (an optional, non-mandatory change) or who started with this version.
|
||||||
- Stored in `DB_DATA_LOCATION`.
|
- Stored in `DB_DATA_LOCATION`.
|
||||||
|
|
||||||
:::danger
|
|
||||||
A backup of this folder does not constitute a backup of your database!
|
|
||||||
Follow the instructions listed [here](/administration/backup-and-restore#database) to learn how to perform a proper backup.
|
|
||||||
:::
|
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem value="Storage Template On" label="Storage Template On">
|
<TabItem value="Storage Template On" label="Storage Template On">
|
||||||
|
|
||||||
@@ -203,16 +284,14 @@ When you turn off the storage template engine, it will leave the assets in `UPLO
|
|||||||
- Files uploaded through mobile apps.
|
- Files uploaded through mobile apps.
|
||||||
- Temporarily located in `UPLOAD_LOCATION/upload/<userID>`.
|
- Temporarily located in `UPLOAD_LOCATION/upload/<userID>`.
|
||||||
- Transferred to `UPLOAD_LOCATION/library/<userID>` upon successful upload.
|
- Transferred to `UPLOAD_LOCATION/library/<userID>` upon successful upload.
|
||||||
|
- **Database Dump Backups:**
|
||||||
|
- Automatic database backups created by Immich for disaster recovery.
|
||||||
|
- Stored in `UPLOAD_LOCATION/backups/`.
|
||||||
- **Postgres**
|
- **Postgres**
|
||||||
- The Immich database containing all the information to allow the system to function properly.
|
- The Immich database containing all the information to allow the system to function properly.
|
||||||
**Note:** This folder will only appear to users who have made the changes mentioned in [v1.102.0](https://github.com/immich-app/immich/discussions/8930) (an optional, non-mandatory change) or who started with this version.
|
**Note:** This folder will only appear to users who have made the changes mentioned in [v1.102.0](https://github.com/immich-app/immich/discussions/8930) (an optional, non-mandatory change) or who started with this version.
|
||||||
- Stored in `DB_DATA_LOCATION`.
|
- Stored in `DB_DATA_LOCATION`.
|
||||||
|
|
||||||
:::danger
|
|
||||||
A backup of this folder does not constitute a backup of your database!
|
|
||||||
Follow the instructions listed [here](/administration/backup-and-restore#database) to learn how to perform a proper backup.
|
|
||||||
:::
|
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 323 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 55 KiB |
BIN
docs/docs/administration/img/restore-from-onboarding.webp
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
docs/docs/administration/img/restore-from-settings.webp
Normal file
|
After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 103 KiB |
BIN
docs/docs/administration/img/user-edit-menu.webp
Normal file
|
After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 35 KiB |
@@ -50,7 +50,7 @@ When a new asset is uploaded it kicks off a series of jobs, which include metada
|
|||||||
|
|
||||||
Additionally, some jobs (such as memories generation) run on a schedule, which is every night at midnight by default. To change when they run or enable/disable a job navigate to System Settings -> [Nightly Tasks Settings](https://my.immich.app/admin/system-settings?isOpen=nightly-tasks).
|
Additionally, some jobs (such as memories generation) run on a schedule, which is every night at midnight by default. To change when they run or enable/disable a job navigate to System Settings -> [Nightly Tasks Settings](https://my.immich.app/admin/system-settings?isOpen=nightly-tasks).
|
||||||
|
|
||||||
<img src={require('./img/admin-nightly-tasks.webp').default} width="60%" title="Admin nightly tasks" />
|
<img src={require('./img/admin-nightly-tasks.webp').default} width="80%" title="Admin nightly tasks" />
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
Some jobs ([External Libraries](/features/libraries) scanning, Database Dump) are configured in their own sections in System Settings.
|
Some jobs ([External Libraries](/features/libraries) scanning, Database Dump) are configured in their own sections in System Settings.
|
||||||
|
|||||||
18
docs/docs/administration/maintenance-mode.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Maintenance Mode
|
||||||
|
|
||||||
|
Maintenance mode is used to perform administrative tasks such as restoring backups to Immich.
|
||||||
|
|
||||||
|
You can enter maintenance mode by either:
|
||||||
|
|
||||||
|
- Selecting "Switch to maintenance mode" in `Maintenance` tab in administration.
|
||||||
|
- Running the enable maintenance mode [administration command](./server-commands.md).
|
||||||
|
|
||||||
|
## Logging in during maintenance
|
||||||
|
|
||||||
|
Maintenance mode uses a separate login system which is handled automatically behind the scenes in most cases. Enabling maintenance mode in settings will automatically log you into maintenance mode when the server comes back up.
|
||||||
|
|
||||||
|
If you find that you've been logged out, you can:
|
||||||
|
|
||||||
|
- Open the logs for the Immich server and look for _"🚧 Immich is in maintenance mode, you can log in using the following URL:"_
|
||||||
|
- Run the enable maintenance mode [administration command](./server-commands.md) again, this will give you a new URL to login with.
|
||||||
|
- Run the disable maintenance mode [administration command](./server-commands.md) then re-enter through system settings.
|
||||||
@@ -10,16 +10,19 @@ Running with a pre-existing Postgres server can unlock powerful administrative f
|
|||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
You must install `pgvector` (`>= 0.7.0, < 1.0.0`), as it is a prerequisite for `vchord`.
|
You must install pgvector as it is a prerequisite for VectorChord.
|
||||||
The easiest way to do this on Debian/Ubuntu is by adding the [PostgreSQL Apt repository][pg-apt] and then
|
The easiest way to do this on Debian/Ubuntu is by adding the [PostgreSQL Apt repository][pg-apt] and then
|
||||||
running `apt install postgresql-NN-pgvector`, where `NN` is your Postgres version (e.g., `16`).
|
running `apt install postgresql-NN-pgvector`, where `NN` is your Postgres version (e.g., `16`).
|
||||||
|
|
||||||
You must install VectorChord into your instance of Postgres using their [instructions][vchord-install]. After installation, add `shared_preload_libraries = 'vchord.so'` to your `postgresql.conf`. If you already have some `shared_preload_libraries` set, you can separate each extension with a comma. For example, `shared_preload_libraries = 'pg_stat_statements, vchord.so'`.
|
You must install VectorChord into your instance of Postgres using their [instructions][vchord-install]. After installation, add `shared_preload_libraries = 'vchord.so'` to your `postgresql.conf`. If you already have some `shared_preload_libraries` set, you can separate each extension with a comma. For example, `shared_preload_libraries = 'pg_stat_statements, vchord.so'`.
|
||||||
|
|
||||||
:::note
|
:::note Supported versions
|
||||||
Immich is known to work with Postgres versions `>= 14, < 18`.
|
Immich is known to work with Postgres versions `>= 14, < 19`.
|
||||||
|
|
||||||
Make sure the installed version of VectorChord is compatible with your version of Immich. The current accepted range for VectorChord is `>= 0.3.0, < 0.5.0`.
|
VectorChord is known to work with pgvector versions `>= 0.7, < 0.9`.
|
||||||
|
|
||||||
|
The Immich server will check the VectorChord version on startup to ensure compatibility, and refuse to start if a compatible version is not found.
|
||||||
|
The current accepted range for VectorChord is `>= 0.3, < 2.0`.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Specifying the connection URL
|
## Specifying the connection URL
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ server {
|
|||||||
# allow large file uploads
|
# allow large file uploads
|
||||||
client_max_body_size 50000M;
|
client_max_body_size 50000M;
|
||||||
|
|
||||||
|
# disable buffering uploads to prevent OOM on reverse proxy server and make uploads twice as fast (no pause)
|
||||||
|
proxy_request_buffering off;
|
||||||
|
|
||||||
|
# increase body buffer to avoid limiting upload speed
|
||||||
|
client_body_buffer_size 1024k;
|
||||||
|
|
||||||
# Set headers
|
# Set headers
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
@@ -29,8 +35,6 @@ server {
|
|||||||
|
|
||||||
# enable websockets: http://nginx.org/en/docs/http/websocket.html
|
# enable websockets: http://nginx.org/en/docs/http/websocket.html
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
|
|
||||||
# set timeout
|
# set timeout
|
||||||
@@ -40,6 +44,8 @@ server {
|
|||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://<backend_url>:2283;
|
proxy_pass http://<backend_url>:2283;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
}
|
}
|
||||||
|
|
||||||
# useful when using Let's Encrypt http-01 challenge
|
# useful when using Let's Encrypt http-01 challenge
|
||||||
|
|||||||
@@ -2,17 +2,19 @@
|
|||||||
|
|
||||||
The `immich-server` docker image comes preinstalled with an administrative CLI (`immich-admin`) that supports the following commands:
|
The `immich-server` docker image comes preinstalled with an administrative CLI (`immich-admin`) that supports the following commands:
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
| ------------------------ | ------------------------------------------------------------- |
|
| -------------------------- | ------------------------------------------------------------- |
|
||||||
| `help` | Display help |
|
| `help` | Display help |
|
||||||
| `reset-admin-password` | Reset the password for the admin user |
|
| `reset-admin-password` | Reset the password for the admin user |
|
||||||
| `disable-password-login` | Disable password login |
|
| `disable-password-login` | Disable password login |
|
||||||
| `enable-password-login` | Enable password login |
|
| `enable-password-login` | Enable password login |
|
||||||
| `enable-oauth-login` | Enable OAuth login |
|
| `disable-maintenance-mode` | Disable maintenance mode |
|
||||||
| `disable-oauth-login` | Disable OAuth login |
|
| `enable-maintenance-mode` | Enable maintenance mode |
|
||||||
| `list-users` | List Immich users |
|
| `enable-oauth-login` | Enable OAuth login |
|
||||||
| `version` | Print Immich version |
|
| `disable-oauth-login` | Disable OAuth login |
|
||||||
| `change-media-location` | Change database file paths to align with a new media location |
|
| `list-users` | List Immich users |
|
||||||
|
| `version` | Print Immich version |
|
||||||
|
| `change-media-location` | Change database file paths to align with a new media location |
|
||||||
|
|
||||||
## How to run a command
|
## How to run a command
|
||||||
|
|
||||||
@@ -47,6 +49,23 @@ immich-admin enable-password-login
|
|||||||
Password login has been enabled.
|
Password login has been enabled.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Disable Maintenance Mode
|
||||||
|
|
||||||
|
```
|
||||||
|
immich-admin disable-maintenance-mode
|
||||||
|
Maintenance mode has been disabled.
|
||||||
|
```
|
||||||
|
|
||||||
|
Enable Maintenance Mode
|
||||||
|
|
||||||
|
```
|
||||||
|
immich-admin enable-maintenance-mode
|
||||||
|
Maintenance mode has been enabled.
|
||||||
|
|
||||||
|
Log in using the following URL:
|
||||||
|
https://my.immich.app/maintenance?token=<token>
|
||||||
|
```
|
||||||
|
|
||||||
Enable OAuth login
|
Enable OAuth login
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Admin can send a welcome email if the Email option is set, you can learn here ho
|
|||||||
|
|
||||||
Admin can specify the storage quota for the user as the instance's admin; once the limit is reached, the user won't be able to upload to the instance anymore.
|
Admin can specify the storage quota for the user as the instance's admin; once the limit is reached, the user won't be able to upload to the instance anymore.
|
||||||
|
|
||||||
In order to select a storage quota, click on the pencil icon and enter the storage quota in GiB. You can choose an unlimited quota by leaving it empty (default).
|
In order to select a storage quota, click on the edit user icon and enter the storage quota in GiB. You can choose an unlimited quota by leaving it empty (default).
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
The system administrator can see the usage quota percentage of all users in Server Stats page.
|
The system administrator can see the usage quota percentage of all users in Server Stats page.
|
||||||
@@ -41,12 +41,12 @@ The system administrator can see the usage quota percentage of all users in Serv
|
|||||||
External libraries don't take up space from the storage quota.
|
External libraries don't take up space from the storage quota.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
<img src={require('./img/user-quota-size.webp').default} width="40%" title="Set Quota Size" />
|
<img src={require('./img/user-quota-size.webp').default} width="80%" title="Set Quota Size" />
|
||||||
|
|
||||||
## Set Storage Label For User
|
## Set Storage Label For User
|
||||||
|
|
||||||
The admin can add a custom label for each user, so instead of `upload/{userId}/your-template` it will be `upload/{custom_user_label}/your-template`.
|
The admin can add a custom label for each user, so instead of `upload/{userId}/your-template` it will be `upload/{custom_user_label}/your-template`.
|
||||||
To apply a storage template, go to the Administration page -> click on the pencil button next to the user.
|
To apply a storage template, go to the `Administration > Users`, then click on the context menu button next to the user.
|
||||||
:::note
|
:::note
|
||||||
To apply the Storage Label to previously uploaded assets, run the Storage Migration Job.
|
To apply the Storage Label to previously uploaded assets, run the Storage Migration Job.
|
||||||
:::
|
:::
|
||||||
@@ -55,25 +55,21 @@ To apply the Storage Label to previously uploaded assets, run the Storage Migrat
|
|||||||
|
|
||||||
## Password Reset
|
## Password Reset
|
||||||
|
|
||||||
To reset a user's password, click the pencil icon to edit a user, then click "Reset Password". The user's password will be reset to random password and they have to change it next time the sign in.
|
<img src={require('./img/user-edit-menu.webp').default} width="80%" title="Customize Delete User" />
|
||||||
|
|
||||||
<img src={require('./img/user-management-update.webp').default} width="40%" title="Reset Password" />
|
To reset a user's password, go to `Administration > Users`, then click on the context menu button next to the user, then click "Reset Password". The user's password will be reset to a random password and they have to change it next time they sign in.
|
||||||
|
|
||||||
## Delete a User
|
## Delete a User
|
||||||
|
|
||||||
If you need to remove a user from Immich, head to "Administration", where users can be scheduled for deletion. The user account will immediately become disabled and their library and all associated data will be removed after 7 days by default.
|
If you need to remove a user from Immich, go to `Administration > Users`, then click on the context menu button next to the user. The user account will immediately become disabled and their library and all associated data will be removed after 7 days by default.
|
||||||
|
|
||||||
<img src={require('./img/delete-user.webp').default} width="40%" title="Delete User" />
|
|
||||||
|
|
||||||
### Delete Delay
|
### Delete Delay
|
||||||
|
|
||||||
You can customize the time of the deletion of the users from the Administration -> Settings -> User Settings.
|
You can customize the time of the deletion of the users from `Administration -> Settings -> User Settings`.
|
||||||
:::info user deletion job
|
:::info user deletion job
|
||||||
The user deletion job runs at midnight to check for users that are ready for deletion. Changes to this setting will be evaluated at the next execution.
|
The user deletion job runs at midnight to check for users that are ready for deletion. Changes to this setting will be evaluated at the next execution.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
<img src={require('./img/customize-delete-user.webp').default} width="80%" title="Customize Delete User" />
|
|
||||||
|
|
||||||
### Immediately Remove User
|
### Immediately Remove User
|
||||||
|
|
||||||
You can choose to delete a user immediately by checking the box
|
You can choose to delete a user immediately by checking the box
|
||||||
|
|||||||
@@ -12,3 +12,13 @@ pnpm run migrations:generate <migration-name>
|
|||||||
3. Move the migration file to folder `./server/src/schema/migrations` in your code editor.
|
3. Move the migration file to folder `./server/src/schema/migrations` in your code editor.
|
||||||
|
|
||||||
The server will automatically detect `*.ts` file changes and restart. Part of the server start-up process includes running any new migrations, so it will be applied immediately.
|
The server will automatically detect `*.ts` file changes and restart. Part of the server start-up process includes running any new migrations, so it will be applied immediately.
|
||||||
|
|
||||||
|
## Reverting a Migration
|
||||||
|
|
||||||
|
If you need to undo the most recently applied migration—for example, when developing or testing on schema changes—run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm run migrations:revert
|
||||||
|
```
|
||||||
|
|
||||||
|
This command rolls back the latest migration and brings the database schema back to its previous state.
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ The Dev Container supports multiple ways to run tests:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run tests for specific components
|
# Run tests for specific components
|
||||||
make test-server # Server unit tests
|
make test-server # Server unit tests
|
||||||
make test-web # Web unit tests
|
make test-web # Web unit tests
|
||||||
make test-e2e # End-to-end tests
|
make test-e2e # End-to-end tests
|
||||||
make test-cli # CLI tests
|
make test-cli # CLI tests
|
||||||
@@ -268,12 +268,13 @@ make test-all # Runs tests for all components
|
|||||||
make test-medium-dev # End-to-end tests
|
make test-medium-dev # End-to-end tests
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Using NPM Directly
|
#### Using PNPM Directly
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Server tests
|
# Server tests
|
||||||
cd /workspaces/immich/server
|
cd /workspaces/immich/server
|
||||||
pnpm test # Run all tests
|
pnpm test # Run all tests
|
||||||
|
pnpm run test:medium # Medium tests (integration tests)
|
||||||
pnpm run test:watch # Watch mode
|
pnpm run test:watch # Watch mode
|
||||||
pnpm run test:cov # Coverage report
|
pnpm run test:cov # Coverage report
|
||||||
|
|
||||||
@@ -293,21 +294,21 @@ pnpm run test:web # Run web UI tests
|
|||||||
```bash
|
```bash
|
||||||
# Linting
|
# Linting
|
||||||
make lint-server # Lint server code
|
make lint-server # Lint server code
|
||||||
make lint-web # Lint web code
|
make lint-web # Lint web code
|
||||||
make lint-all # Lint all components
|
make lint-all # Lint all components
|
||||||
|
|
||||||
# Formatting
|
# Formatting
|
||||||
make format-server # Format server code
|
make format-server # Format server code
|
||||||
make format-web # Format web code
|
make format-web # Format web code
|
||||||
make format-all # Format all code
|
make format-all # Format all code
|
||||||
|
|
||||||
# Type checking
|
# Type checking
|
||||||
make check-server # Type check server
|
make check-server # Type check server
|
||||||
make check-web # Type check web
|
make check-web # Type check web
|
||||||
make check-all # Check all components
|
make check-all # Check all components
|
||||||
|
|
||||||
# Complete hygiene check
|
# Complete hygiene check
|
||||||
make hygiene-all # Runs lint, format, check, SQL sync, and audit
|
make hygiene-all # Run lint, format, check, SQL sync, and audit
|
||||||
```
|
```
|
||||||
|
|
||||||
### Additional Make Commands
|
### Additional Make Commands
|
||||||
@@ -315,21 +316,21 @@ make hygiene-all # Runs lint, format, check, SQL sync, and audit
|
|||||||
```bash
|
```bash
|
||||||
# Build commands
|
# Build commands
|
||||||
make build-server # Build server
|
make build-server # Build server
|
||||||
make build-web # Build web app
|
make build-web # Build web app
|
||||||
make build-all # Build everything
|
make build-all # Build everything
|
||||||
|
|
||||||
# API generation
|
# API generation
|
||||||
make open-api # Generate OpenAPI specs
|
make open-api # Generate OpenAPI specs
|
||||||
make open-api-typescript # Generate TypeScript SDK
|
make open-api-typescript # Generate TypeScript SDK
|
||||||
make open-api-dart # Generate Dart SDK
|
make open-api-dart # Generate Dart SDK
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
make sql # Sync database schema
|
make sql # Sync database schema
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
make install-server # Install server dependencies
|
make install-server # Install server dependencies
|
||||||
make install-web # Install web dependencies
|
make install-web # Install web dependencies
|
||||||
make install-all # Install all dependencies
|
make install-all # Install all dependencies
|
||||||
```
|
```
|
||||||
|
|
||||||
### Debugging
|
### Debugging
|
||||||
|
|||||||
@@ -14,15 +14,15 @@ When contributing code through a pull request, please check the following:
|
|||||||
- [ ] `pnpm run check:typescript` (check typescript)
|
- [ ] `pnpm run check:typescript` (check typescript)
|
||||||
- [ ] `pnpm test` (unit tests)
|
- [ ] `pnpm test` (unit tests)
|
||||||
|
|
||||||
|
:::tip AIO
|
||||||
|
Run all web checks with `pnpm run check:all`
|
||||||
|
:::
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
- [ ] `pnpm run format` (formatting via Prettier)
|
- [ ] `pnpm run format` (formatting via Prettier)
|
||||||
- [ ] Update the `_redirects` file if you have renamed a page or removed it from the documentation.
|
- [ ] Update the `_redirects` file if you have renamed a page or removed it from the documentation.
|
||||||
|
|
||||||
:::tip AIO
|
|
||||||
Run all web checks with `pnpm run check:all`
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Server Checks
|
## Server Checks
|
||||||
|
|
||||||
- [ ] `pnpm run lint` (linting via ESLint)
|
- [ ] `pnpm run lint` (linting via ESLint)
|
||||||
|
|||||||
@@ -4,8 +4,12 @@ sidebar_position: 2
|
|||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
Make sure to read the [`CONTRIBUTING.md`](https://github.com/immich-app/immich/blob/main/CONTRIBUTING.md) before you dive into the code.
|
||||||
|
:::
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
If there's a feature you're planning to work on, just give us a heads up in [Discord](https://discord.com/channels/979116623879368755/1071165397228855327) so we can:
|
If there's a feature you're planning to work on, just give us a heads up in [#contributing](https://discord.com/channels/979116623879368755/1071165397228855327) on [our Discord](https://discord.immich.app) so we can:
|
||||||
|
|
||||||
1. Let you know if it's something we would accept into Immich
|
1. Let you know if it's something we would accept into Immich
|
||||||
2. Provide any guidance on how something like that would ideally be implemented
|
2. Provide any guidance on how something like that would ideally be implemented
|
||||||
@@ -33,7 +37,8 @@ All the services are packaged to run as with single Docker Compose command.
|
|||||||
1. Clone the project repo.
|
1. Clone the project repo.
|
||||||
2. Run `cp docker/example.env docker/.env`.
|
2. Run `cp docker/example.env docker/.env`.
|
||||||
3. Edit `docker/.env` to provide values for the required variable `UPLOAD_LOCATION`.
|
3. Edit `docker/.env` to provide values for the required variable `UPLOAD_LOCATION`.
|
||||||
4. From the root directory, run:
|
4. Install dependencies - `pnpm i`
|
||||||
|
5. From the root directory, run:
|
||||||
|
|
||||||
```bash title="Start development server"
|
```bash title="Start development server"
|
||||||
make dev # required Makefile installed on the system.
|
make dev # required Makefile installed on the system.
|
||||||
@@ -48,7 +53,6 @@ You can access the web from `http://your-machine-ip:3000` or `http://localhost:3
|
|||||||
**Notes:**
|
**Notes:**
|
||||||
|
|
||||||
- The "web" development container runs with uid 1000. If that uid does not have read/write permissions on the mounted volumes, you may encounter errors
|
- The "web" development container runs with uid 1000. If that uid does not have read/write permissions on the mounted volumes, you may encounter errors
|
||||||
- In case of rootless docker setup, you need to use root within the container, otherwise you will encounter read/write permission related errors, see comments in `docker/docker-compose.dev.yml`.
|
|
||||||
|
|
||||||
#### Connect web to a remote backend
|
#### Connect web to a remote backend
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ make e2e
|
|||||||
Before you can run the tests, you need to run the following commands _once_:
|
Before you can run the tests, you need to run the following commands _once_:
|
||||||
|
|
||||||
- `pnpm install` (in `e2e/`)
|
- `pnpm install` (in `e2e/`)
|
||||||
|
- `pnpm run build` (in `cli/`)
|
||||||
- `make open-api` (in the project root `/`)
|
- `make open-api` (in the project root `/`)
|
||||||
|
|
||||||
Once the test environment is running, the e2e tests can be run via:
|
Once the test environment is running, the e2e tests can be run via:
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
# Automatic Backup
|
|
||||||
|
|
||||||
Immich supports uploading photos and videos from your mobile device to the server automatically.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
You can enable the settings by accessing the upload options from the upload page
|
|
||||||
|
|
||||||
<img src={require('./img/backup-settings-access.webp').default} width="50%" title="Backup option selection" />
|
|
||||||
|
|
||||||
<img src={require('./img/background-foreground-backup.webp').default} width="50%" title="Foreground&Background Backup" />
|
|
||||||
|
|
||||||
## Foreground backup
|
|
||||||
|
|
||||||
If foreground backup is enabled: whenever the app is opened or resumed, it will check if any photos or videos in the selected album(s) have yet to be uploaded to the cloud (the remainder count). If there are any, they will be uploaded.
|
|
||||||
|
|
||||||
## Background backup
|
|
||||||
|
|
||||||
This feature is intended for everyday use. For initial bulk uploading, please use the foreground upload feature. For more information on why background upload is not working as expected, please refer to the [FAQ](/FAQ#why-does-foreground-backup-stop-when-i-navigate-away-from-the-app-shouldnt-it-transfer-the-job-to-background-backup).
|
|
||||||
|
|
||||||
If background backup is enabled. The app will periodically check if there are any new photos or videos in the selected album(s) to be uploaded to the server. If there are, it will upload them to the cloud in the background.
|
|
||||||
|
|
||||||
:::info Note
|
|
||||||
|
|
||||||
#### General
|
|
||||||
|
|
||||||
- The app must be in the background for the backup worker to start running.
|
|
||||||
- If you reopen the app and the first page you see is the backup page, the counts will not reflect the background uploaded result. You have to navigate out of the page and come back to see the updated counts.
|
|
||||||
|
|
||||||
#### Android
|
|
||||||
|
|
||||||
- It is a well-known problem that some Android models are very strict with battery optimization settings, which can cause a problem with the background worker. Please visit [Don't kill my app](https://dontkillmyapp.com/) for a guide on disabling this setting on your phone.
|
|
||||||
|
|
||||||
#### iOS
|
|
||||||
|
|
||||||
- You must enable **Background App Refresh** for the app to work in the background. You can enable it in the Settings app under General > Background App Refresh.
|
|
||||||
|
|
||||||
<div style={{textAlign: 'center'}}>
|
|
||||||
<img src={require('./img/background-app-refresh.webp').default} width="30%" title="background-app-refresh" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
:::
|
|
||||||
@@ -188,6 +188,8 @@ immich upload --dry-run . | tail -n +6 | jq .newFiles[]
|
|||||||
|
|
||||||
### Obtain the API Key
|
### Obtain the API Key
|
||||||
|
|
||||||
The API key can be obtained in the user setting panel on the web interface.
|
The API key can be obtained in the user setting panel on the web interface. You can also specify permissions for the key to limit its access.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
|
|||||||
19
docs/docs/features/editing.mdx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Editing
|
||||||
|
|
||||||
|
Immich supports non-destructive editing of photos. This means that any edits you make to an asset do not modify the original file, but instead create a new version of the asset with the edits applied. You can always revert back to the original asset if needed.
|
||||||
|
|
||||||
|
## Supported Edits
|
||||||
|
|
||||||
|
Currently, Immich supports the following types of edits:
|
||||||
|
|
||||||
|
- Cropping
|
||||||
|
- Rotation
|
||||||
|
- Mirroring
|
||||||
|
|
||||||
|
<img src={require('./img/web-edit-interface.webp').default} title="Web edit interface" />
|
||||||
|
|
||||||
|
## Download
|
||||||
|
|
||||||
|
When you download an edited asset, Immich provides the edited version of the asset by default. However, you can choose to download the original version if needed.
|
||||||
|
|
||||||
|
<img src={require('./img/web-edit-download.webp').default} title="Web edit download" />
|
||||||
@@ -21,14 +21,14 @@ The asset detail view will also show the faces that are recognized in the asset.
|
|||||||
Additional actions you can do include:
|
Additional actions you can do include:
|
||||||
|
|
||||||
- Changing the feature photo of the person
|
- Changing the feature photo of the person
|
||||||
- Setting a person's date of birth
|
|
||||||
- Merging two or more detected faces into one person
|
|
||||||
- Hiding the faces of a person from the Explore page and detail view
|
- Hiding the faces of a person from the Explore page and detail view
|
||||||
- Assigning an unrecognized face to a person
|
- Setting a person's date of birth, so that the age of the person can be shown at the time the photo was taken
|
||||||
|
- Merging two or more detected people into one person
|
||||||
|
- Favoriting a person to pin them to the top of the list
|
||||||
|
|
||||||
It can be found from the app bar when you access the detail view of a person.
|
It can be found from the app bar when you access the detail view of a person.
|
||||||
|
|
||||||
<img src={require('./img/facial-recognition-4.webp').default} title='Facial Recognition 4' width="70%"/>
|
<img src={require('./img/facial-recognition-4.webp').default} title='Facial Recognition 4' />
|
||||||
|
|
||||||
## How Face Detection Works
|
## How Face Detection Works
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,22 @@ For RKMPP to work:
|
|||||||
|
|
||||||
5. (Optional) Enable hardware decoding for optimal performance.
|
5. (Optional) Enable hardware decoding for optimal performance.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>immich.json</summary>
|
||||||
|
|
||||||
|
If you use a [configuration file](/install/config-file.md), use the `accel` option to select the hardware (e.g. `qsv` for Intel or `nvenc` for Nvidia). Set `accelDecode` to `true` if you want hardware decoding.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ffmpeg": {
|
||||||
|
"accel": "qsv",
|
||||||
|
"accelDecode": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
#### Single Compose File
|
#### Single Compose File
|
||||||
|
|
||||||
Some platforms, including Unraid and Portainer, do not support multiple Compose files as of writing. As an alternative, you can "inline" the relevant contents of the [`hwaccel.transcoding.yml`][hw-file] file into the `immich-server` service directly.
|
Some platforms, including Unraid and Portainer, do not support multiple Compose files as of writing. As an alternative, you can "inline" the relevant contents of the [`hwaccel.transcoding.yml`][hw-file] file into the `immich-server` service directly.
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 68 KiB |
BIN
docs/docs/features/img/android-backup-options.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 43 KiB |
BIN
docs/docs/features/img/backup-album-selection.webp
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
docs/docs/features/img/backup-album-sync.webp
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
docs/docs/features/img/backup-options.webp
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
docs/docs/features/img/enable-backup-button.webp
Normal file
|
After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 286 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
BIN
docs/docs/features/img/free-up-space.webp
Normal file
|
After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 4.9 MiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 16 KiB |
BIN
docs/docs/features/img/obtain-api-key-2.webp
Normal file
|
After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 319 KiB |
BIN
docs/docs/features/img/read-only-mode.webp
Normal file
|
After Width: | Height: | Size: 170 KiB |