Compare commits
105 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 338f8dc233 | |||
| f2a98ab523 | |||
| 9e689e835e | |||
| 76eb285204 | |||
| bc9bec8673 | |||
| a9508fc5c8 | |||
| 678cb8938a | |||
| 1785d0916b | |||
| fedbecc9f2 | |||
| 7fc47600f5 | |||
| 4db85a8954 | |||
| bd9374e4a9 | |||
| 0f1a551842 | |||
| 323bcde733 | |||
| 4b57fb5b37 | |||
| b959ae2570 | |||
| e3d041e3c2 | |||
| 2ba2c597e5 | |||
| 9958ac9ec9 | |||
| c57c562166 | |||
| ce2a41826e | |||
| ec0fa4d52b | |||
| f5e44f12e1 | |||
| 6e08f1f371 | |||
| 3ed5d3dbac | |||
| f9387d8478 | |||
| 4bb98471f4 | |||
| 794da29411 | |||
| dd52c2d68c | |||
| 59e4b6598e | |||
| 20ba9f97e9 | |||
| ac4ce3ea9c | |||
| 2b967ca358 | |||
| 1653cd9cd7 | |||
| 32f3707e52 | |||
| 58f1cc92d7 | |||
| d2b7e10f55 | |||
| b3ae5d34cc | |||
| 4e42fbc091 | |||
| 9926045d5e | |||
| d7381ab5c1 | |||
| 87a46dcc5e | |||
| be76857ae6 | |||
| f5de3de163 | |||
| 3634ae1f5b | |||
| 05675921be | |||
| f067212491 | |||
| bc48b67379 | |||
| 26d5fb0ac6 | |||
| f32d991131 | |||
| 9882b83cd4 | |||
| 01eb09526e | |||
| b5a4ed5160 | |||
| 0f03f77e8e | |||
| c21ce40d9c | |||
| cb01a11f19 | |||
| 5244ed6d4d | |||
| 8b80d034cb | |||
| 4b0f93cf6a | |||
| 6c4e6cb96f | |||
| b6cc2054c5 | |||
| f328104e84 | |||
| 2f7e44aa63 | |||
| ebdfe1b7b6 | |||
| daf886088a | |||
| 4c7ac1438b | |||
| 8965a9fb16 | |||
| 7ae4b7129d | |||
| 1775397a84 | |||
| 68fccad462 | |||
| bb67a9db6e | |||
| c109e28686 | |||
| e6ff21b345 | |||
| c665fd2625 | |||
| c72cf61ed0 | |||
| 19ee48f6f0 | |||
| efaf70eb9d | |||
| 665718b09e | |||
| 807111e3b5 | |||
| 815ed1ae66 | |||
| 416211916d | |||
| 23d0ea0e7b | |||
| d5e453a773 | |||
| 7f2af6f819 | |||
| f4671f4886 | |||
| 7aaf3aa57b | |||
| 506ca0d3a4 | |||
| d5ef821b24 | |||
| d10147f478 | |||
| 66004e3b83 | |||
| c20d110257 | |||
| a2722e16e7 | |||
| 4d704e9f73 | |||
| 9bc3e5b2e2 | |||
| 8608b9c6c5 | |||
| a94fad543b | |||
| 082c426e34 | |||
| da152bd284 | |||
| 257cc6c963 | |||
| 4140e93aea | |||
| b6c4b37237 | |||
| bc849e2e9f | |||
| 7fddf282cf | |||
| 6ffc227330 | |||
| 8ef3e49f74 |
@@ -1,4 +1,4 @@
|
|||||||
ARG BASEIMAGE=mcr.microsoft.com/devcontainers/typescript-node:22@sha256:b0b88ef6a5abf21194343d2c5b2829dddd9be1142f65f6a5e4390a51d5a70dd8
|
ARG BASEIMAGE=mcr.microsoft.com/devcontainers/typescript-node:22@sha256:9791f4aa527774bc370c6bd2f6705ce5a686f1e6f204badd8dfaacce28c631ae
|
||||||
FROM ${BASEIMAGE}
|
FROM ${BASEIMAGE}
|
||||||
|
|
||||||
# Flutter SDK
|
# Flutter SDK
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ mobile/openapi/**/*.dart linguist-generated=true
|
|||||||
mobile/lib/**/*.g.dart -diff -merge
|
mobile/lib/**/*.g.dart -diff -merge
|
||||||
mobile/lib/**/*.g.dart linguist-generated=true
|
mobile/lib/**/*.g.dart linguist-generated=true
|
||||||
|
|
||||||
mobile/lib/**/*.drift.dart -diff -merge
|
|
||||||
mobile/lib/**/*.drift.dart linguist-generated=true
|
|
||||||
|
|
||||||
open-api/typescript-sdk/fetch-client.ts -diff -merge
|
open-api/typescript-sdk/fetch-client.ts -diff -merge
|
||||||
open-api/typescript-sdk/fetch-client.ts linguist-generated=true
|
open-api/typescript-sdk/fetch-client.ts linguist-generated=true
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
22.14.0
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
title: '[Feature] feature-name-goes-here'
|
title: "[Feature] feature-name-goes-here"
|
||||||
labels: ['feature']
|
labels: ["feature"]
|
||||||
|
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
@@ -13,7 +13,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: I have searched the existing feature requests, both open and closed, to make sure this is not a duplicate request.
|
label: I have searched the existing feature requests, both open and closed, to make sure this is not a duplicate request.
|
||||||
options:
|
options:
|
||||||
- label: 'Yes'
|
- label: "Yes"
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: I have searched the existing issues, both open and closed, to make sure this is not a duplicate report.
|
label: I have searched the existing issues, both open and closed, to make sure this is not a duplicate report.
|
||||||
options:
|
options:
|
||||||
- label: 'Yes'
|
- label: "Yes"
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: markdown
|
- type: markdown
|
||||||
@@ -84,7 +84,7 @@ body:
|
|||||||
id: repro
|
id: repro
|
||||||
attributes:
|
attributes:
|
||||||
label: Reproduction steps
|
label: Reproduction steps
|
||||||
description: 'How do you trigger this bug? Please walk us through it step by step.'
|
description: "How do you trigger this bug? Please walk us through it step by step."
|
||||||
value: |
|
value: |
|
||||||
1.
|
1.
|
||||||
2.
|
2.
|
||||||
@@ -97,8 +97,7 @@ body:
|
|||||||
id: logs
|
id: logs
|
||||||
attributes:
|
attributes:
|
||||||
label: Relevant log output
|
label: Relevant log output
|
||||||
description:
|
description: Please copy and paste any relevant logs below. (code formatting is
|
||||||
Please copy and paste any relevant logs below. (code formatting is
|
|
||||||
enabled, no need for backticks)
|
enabled, no need for backticks)
|
||||||
render: shell
|
render: shell
|
||||||
validations:
|
validations:
|
||||||
|
|||||||
Generated
-28
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"name": ".github",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"": {
|
|
||||||
"devDependencies": {
|
|
||||||
"prettier": "^3.5.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/prettier": {
|
|
||||||
"version": "3.5.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
|
|
||||||
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"bin": {
|
|
||||||
"prettier": "bin/prettier.cjs"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"format": "prettier --check .",
|
|
||||||
"format:fix": "prettier --write ."
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"prettier": "^3.5.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,9 +22,9 @@ jobs:
|
|||||||
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
uses: dorny/paths-filter@v3
|
||||||
with:
|
with:
|
||||||
filters: |
|
filters: |
|
||||||
mobile:
|
mobile:
|
||||||
@@ -51,18 +51,18 @@ jobs:
|
|||||||
ref="${input_ref:-$github_ref}"
|
ref="${input_ref:-$github_ref}"
|
||||||
echo "ref=$ref" >> $GITHUB_OUTPUT
|
echo "ref=$ref" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: ${{ steps.get-ref.outputs.ref }}
|
ref: ${{ steps.get-ref.outputs.ref }}
|
||||||
|
|
||||||
- uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4
|
- uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
cache: 'gradle'
|
cache: 'gradle'
|
||||||
|
|
||||||
- name: Setup Flutter SDK
|
- name: Setup Flutter SDK
|
||||||
uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2
|
uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: 'stable'
|
channel: 'stable'
|
||||||
flutter-version-file: ./mobile/pubspec.yaml
|
flutter-version-file: ./mobile/pubspec.yaml
|
||||||
@@ -89,7 +89,7 @@ jobs:
|
|||||||
flutter build apk --release --split-per-abi --target-platform android-arm,android-arm64,android-x64
|
flutter build apk --release --split-per-abi --target-platform android-arm,android-arm64,android-x64
|
||||||
|
|
||||||
- name: Publish Android Artifact
|
- name: Publish Android Artifact
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
uses: actions/upload-artifact@v4
|
||||||
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
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Cleanup
|
- name: Cleanup
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ on:
|
|||||||
- 'cli/**'
|
- 'cli/**'
|
||||||
- '.github/workflows/cli.yml'
|
- '.github/workflows/cli.yml'
|
||||||
pull_request:
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
paths:
|
paths:
|
||||||
- 'cli/**'
|
- 'cli/**'
|
||||||
- '.github/workflows/cli.yml'
|
- '.github/workflows/cli.yml'
|
||||||
@@ -28,9 +29,9 @@ jobs:
|
|||||||
working-directory: ./cli
|
working-directory: ./cli
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
- uses: actions/checkout@v4
|
||||||
# Setup .npmrc file to publish to npm
|
# Setup .npmrc file to publish to npm
|
||||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './cli/.nvmrc'
|
node-version-file: './cli/.nvmrc'
|
||||||
registry-url: 'https://registry.npmjs.org'
|
registry-url: 'https://registry.npmjs.org'
|
||||||
@@ -52,16 +53,16 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
|
uses: docker/setup-qemu-action@v3.6.0
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@v3.10.0
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
uses: docker/login-action@v3
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
@@ -76,7 +77,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate docker image tags
|
- name: Generate docker image tags
|
||||||
id: metadata
|
id: metadata
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5
|
uses: docker/metadata-action@v5
|
||||||
with:
|
with:
|
||||||
flavor: |
|
flavor: |
|
||||||
latest=false
|
latest=false
|
||||||
@@ -87,7 +88,7 @@ jobs:
|
|||||||
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
||||||
|
|
||||||
- name: Build and push image
|
- name: Build and push image
|
||||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
uses: docker/build-push-action@v6.15.0
|
||||||
with:
|
with:
|
||||||
file: cli/Dockerfile
|
file: cli/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
# the `language` matrix defined below to confirm you have the correct set of
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
# supported CodeQL languages.
|
# supported CodeQL languages.
|
||||||
#
|
#
|
||||||
name: 'CodeQL'
|
name: "CodeQL"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ['main']
|
branches: [ "main" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
# The branches below must be a subset of the branches above
|
# The branches below must be a subset of the branches above
|
||||||
branches: ['main']
|
branches: [ "main" ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '20 13 * * 1'
|
- cron: '20 13 * * 1'
|
||||||
|
|
||||||
@@ -36,42 +36,43 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
language: ['javascript', 'python']
|
language: [ 'javascript', 'python' ]
|
||||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@45775bd8235c68ba998cffa5171334d58593da47 # v3
|
uses: github/codeql-action/init@v3
|
||||||
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.
|
||||||
# By default, queries listed here will override any specified in a config file.
|
# By default, queries listed here will override any specified in a config file.
|
||||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
|
||||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||||
# queries: security-extended,security-and-quality
|
# queries: security-extended,security-and-quality
|
||||||
|
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
|
||||||
- name: Autobuild
|
|
||||||
uses: github/codeql-action/autobuild@45775bd8235c68ba998cffa5171334d58593da47 # v3
|
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v3
|
||||||
|
|
||||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
|
|
||||||
# - run: |
|
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||||
# echo "Run, Build Application using script"
|
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||||
# ./location_of_script_within_repo/buildscript.sh
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
# - run: |
|
||||||
uses: github/codeql-action/analyze@45775bd8235c68ba998cffa5171334d58593da47 # v3
|
# echo "Run, Build Application using script"
|
||||||
with:
|
# ./location_of_script_within_repo/buildscript.sh
|
||||||
category: '/language:${{matrix.language}}'
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v3
|
||||||
|
with:
|
||||||
|
category: "/language:${{matrix.language}}"
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ jobs:
|
|||||||
should_run_ml: ${{ steps.found_paths.outputs.machine-learning == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run_ml: ${{ steps.found_paths.outputs.machine-learning == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
uses: dorny/paths-filter@v3
|
||||||
with:
|
with:
|
||||||
filters: |
|
filters: |
|
||||||
server:
|
server:
|
||||||
@@ -49,23 +49,23 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn']
|
suffix: ["", "-cuda", "-openvino", "-armnn","-rknn"]
|
||||||
steps:
|
steps:
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Re-tag image
|
- name: Re-tag image
|
||||||
run: |
|
run: |
|
||||||
REGISTRY_NAME="ghcr.io"
|
REGISTRY_NAME="ghcr.io"
|
||||||
REPOSITORY=${{ github.repository_owner }}/immich-machine-learning
|
REPOSITORY=${{ github.repository_owner }}/immich-machine-learning
|
||||||
TAG_OLD=main${{ matrix.suffix }}
|
TAG_OLD=main${{ matrix.suffix }}
|
||||||
TAG_PR=${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
|
TAG_PR=${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
|
||||||
TAG_COMMIT=commit-${{ github.event_name != 'pull_request' && github.sha || github.event.pull_request.head.sha }}${{ matrix.suffix }}
|
TAG_COMMIT=commit-${{ github.event_name != 'pull_request' && github.sha || github.event.pull_request.head.sha }}${{ matrix.suffix }}
|
||||||
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_PR $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_PR $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
||||||
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_COMMIT $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_COMMIT $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
||||||
|
|
||||||
retag_server:
|
retag_server:
|
||||||
name: Re-Tag Server
|
name: Re-Tag Server
|
||||||
@@ -74,10 +74,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
suffix: ['']
|
suffix: [""]
|
||||||
steps:
|
steps:
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
@@ -120,11 +120,6 @@ jobs:
|
|||||||
device: cuda
|
device: cuda
|
||||||
suffix: -cuda
|
suffix: -cuda
|
||||||
|
|
||||||
- platform: linux/amd64
|
|
||||||
runner: mich
|
|
||||||
device: rocm
|
|
||||||
suffix: -rocm
|
|
||||||
|
|
||||||
- platform: linux/amd64
|
- platform: linux/amd64
|
||||||
runner: ubuntu-latest
|
runner: ubuntu-latest
|
||||||
device: openvino
|
device: openvino
|
||||||
@@ -134,9 +129,7 @@ jobs:
|
|||||||
runner: ubuntu-24.04-arm
|
runner: ubuntu-24.04-arm
|
||||||
device: armnn
|
device: armnn
|
||||||
suffix: -armnn
|
suffix: -armnn
|
||||||
|
- platforms: linux/arm64
|
||||||
- platform: linux/arm64
|
|
||||||
runner: ubuntu-24.04-arm
|
|
||||||
device: rknn
|
device: rknn
|
||||||
suffix: -rknn
|
suffix: -rknn
|
||||||
|
|
||||||
@@ -147,13 +140,13 @@ jobs:
|
|||||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@v3.10.0
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
uses: docker/login-action@v3
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
@@ -180,7 +173,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push image
|
- name: Build and push image
|
||||||
id: build
|
id: build
|
||||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
uses: docker/build-push-action@v6.15.0
|
||||||
with:
|
with:
|
||||||
context: ${{ env.context }}
|
context: ${{ env.context }}
|
||||||
file: ${{ env.file }}
|
file: ${{ env.file }}
|
||||||
@@ -205,7 +198,7 @@ jobs:
|
|||||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||||
|
|
||||||
- name: Upload digest
|
- name: Upload digest
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ml-digests-${{ matrix.device }}-${{ env.PLATFORM_PAIR }}
|
name: ml-digests-${{ matrix.device }}-${{ env.PLATFORM_PAIR }}
|
||||||
path: ${{ runner.temp }}/digests/*
|
path: ${{ runner.temp }}/digests/*
|
||||||
@@ -225,19 +218,15 @@ jobs:
|
|||||||
- device: cpu
|
- device: cpu
|
||||||
- device: cuda
|
- device: cuda
|
||||||
suffix: -cuda
|
suffix: -cuda
|
||||||
- device: rocm
|
|
||||||
suffix: -rocm
|
|
||||||
- device: openvino
|
- device: openvino
|
||||||
suffix: -openvino
|
suffix: -openvino
|
||||||
- device: armnn
|
- device: armnn
|
||||||
suffix: -armnn
|
suffix: -armnn
|
||||||
- device: rknn
|
|
||||||
suffix: -rknn
|
|
||||||
needs:
|
needs:
|
||||||
- build_and_push_ml
|
- build_and_push_ml
|
||||||
steps:
|
steps:
|
||||||
- name: Download digests
|
- name: Download digests
|
||||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: ${{ runner.temp }}/digests
|
path: ${{ runner.temp }}/digests
|
||||||
pattern: ml-digests-${{ matrix.device }}-*
|
pattern: ml-digests-${{ matrix.device }}-*
|
||||||
@@ -245,26 +234,26 @@ jobs:
|
|||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
if: ${{ github.event_name == 'release' }}
|
if: ${{ github.event_name == 'release' }}
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Login to GHCR
|
- name: Login to GHCR
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Generate docker image tags
|
- name: Generate docker image tags
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5
|
uses: docker/metadata-action@v5
|
||||||
env:
|
env:
|
||||||
DOCKER_METADATA_PR_HEAD_SHA: 'true'
|
DOCKER_METADATA_PR_HEAD_SHA: "true"
|
||||||
with:
|
with:
|
||||||
flavor: |
|
flavor: |
|
||||||
# Disable latest tag
|
# Disable latest tag
|
||||||
@@ -315,13 +304,13 @@ jobs:
|
|||||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
uses: docker/login-action@v3
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
@@ -348,7 +337,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push image
|
- name: Build and push image
|
||||||
id: build
|
id: build
|
||||||
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
|
uses: docker/build-push-action@v6.15.0
|
||||||
with:
|
with:
|
||||||
context: ${{ env.context }}
|
context: ${{ env.context }}
|
||||||
file: ${{ env.file }}
|
file: ${{ env.file }}
|
||||||
@@ -373,7 +362,7 @@ jobs:
|
|||||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||||
|
|
||||||
- name: Upload digest
|
- name: Upload digest
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: server-digests-${{ env.PLATFORM_PAIR }}
|
name: server-digests-${{ env.PLATFORM_PAIR }}
|
||||||
path: ${{ runner.temp }}/digests/*
|
path: ${{ runner.temp }}/digests/*
|
||||||
@@ -391,7 +380,7 @@ jobs:
|
|||||||
- build_and_push_server
|
- build_and_push_server
|
||||||
steps:
|
steps:
|
||||||
- name: Download digests
|
- name: Download digests
|
||||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: ${{ runner.temp }}/digests
|
path: ${{ runner.temp }}/digests
|
||||||
pattern: server-digests-*
|
pattern: server-digests-*
|
||||||
@@ -399,26 +388,26 @@ jobs:
|
|||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
if: ${{ github.event_name == 'release' }}
|
if: ${{ github.event_name == 'release' }}
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Login to GHCR
|
- name: Login to GHCR
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Generate docker image tags
|
- name: Generate docker image tags
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5
|
uses: docker/metadata-action@v5
|
||||||
env:
|
env:
|
||||||
DOCKER_METADATA_PR_HEAD_SHA: 'true'
|
DOCKER_METADATA_PR_HEAD_SHA: "true"
|
||||||
with:
|
with:
|
||||||
flavor: |
|
flavor: |
|
||||||
# Disable latest tag
|
# Disable latest tag
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
pull_request:
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
|
|
||||||
@@ -17,9 +18,9 @@ jobs:
|
|||||||
should_run: ${{ steps.found_paths.outputs.docs == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run: ${{ steps.found_paths.outputs.docs == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
uses: dorny/paths-filter@v3
|
||||||
with:
|
with:
|
||||||
filters: |
|
filters: |
|
||||||
docs:
|
docs:
|
||||||
@@ -41,10 +42,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './docs/.nvmrc'
|
node-version-file: './docs/.nvmrc'
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ jobs:
|
|||||||
run: npm run build
|
run: npm run build
|
||||||
|
|
||||||
- name: Upload build output
|
- name: Upload build output
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: docs-build-output
|
name: docs-build-output
|
||||||
path: docs/build/
|
path: docs/build/
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: Docs deploy
|
name: Docs deploy
|
||||||
on:
|
on:
|
||||||
workflow_run:
|
workflow_run:
|
||||||
workflows: ['Docs build']
|
workflows: ["Docs build"]
|
||||||
types:
|
types:
|
||||||
- completed
|
- completed
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ jobs:
|
|||||||
run: echo 'The triggering workflow did not succeed' && exit 1
|
run: echo 'The triggering workflow did not succeed' && exit 1
|
||||||
- name: Get artifact
|
- name: Get artifact
|
||||||
id: get-artifact
|
id: get-artifact
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||||
@@ -35,7 +35,7 @@ jobs:
|
|||||||
return { found: true, id: matchArtifact.id };
|
return { found: true, id: matchArtifact.id };
|
||||||
- name: Determine deploy parameters
|
- name: Determine deploy parameters
|
||||||
id: parameters
|
id: parameters
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const eventType = context.payload.workflow_run.event;
|
const eventType = context.payload.workflow_run.event;
|
||||||
@@ -98,11 +98,11 @@ jobs:
|
|||||||
if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
|
if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Load parameters
|
- name: Load parameters
|
||||||
id: parameters
|
id: parameters
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const json = `${{ needs.checks.outputs.parameters }}`;
|
const json = `${{ needs.checks.outputs.parameters }}`;
|
||||||
@@ -115,7 +115,7 @@ jobs:
|
|||||||
echo "Starting docs deployment for ${{ steps.parameters.outputs.event }} ${{ steps.parameters.outputs.name }}"
|
echo "Starting docs deployment for ${{ steps.parameters.outputs.event }} ${{ steps.parameters.outputs.name }}"
|
||||||
|
|
||||||
- name: Download artifact
|
- name: Download artifact
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
let artifact = ${{ needs.checks.outputs.artifact }};
|
let artifact = ${{ needs.checks.outputs.artifact }};
|
||||||
@@ -138,12 +138,12 @@ jobs:
|
|||||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
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 }}
|
||||||
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2
|
uses: gruntwork-io/terragrunt-action@v2
|
||||||
with:
|
with:
|
||||||
tg_version: '0.58.12'
|
tg_version: "0.58.12"
|
||||||
tofu_version: '1.7.1'
|
tofu_version: "1.7.1"
|
||||||
tg_dir: 'deployment/modules/cloudflare/docs'
|
tg_dir: "deployment/modules/cloudflare/docs"
|
||||||
tg_command: 'apply'
|
tg_command: "apply"
|
||||||
|
|
||||||
- name: Deploy Docs Subdomain Output
|
- name: Deploy Docs Subdomain Output
|
||||||
id: docs-output
|
id: docs-output
|
||||||
@@ -153,12 +153,12 @@ jobs:
|
|||||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
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 }}
|
||||||
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2
|
uses: gruntwork-io/terragrunt-action@v2
|
||||||
with:
|
with:
|
||||||
tg_version: '0.58.12'
|
tg_version: "0.58.12"
|
||||||
tofu_version: '1.7.1'
|
tofu_version: "1.7.1"
|
||||||
tg_dir: 'deployment/modules/cloudflare/docs'
|
tg_dir: "deployment/modules/cloudflare/docs"
|
||||||
tg_command: 'output -json'
|
tg_command: "output -json"
|
||||||
|
|
||||||
- name: Output Cleaning
|
- name: Output Cleaning
|
||||||
id: clean
|
id: clean
|
||||||
@@ -167,13 +167,13 @@ jobs:
|
|||||||
echo "output=$TG_OUT" >> $GITHUB_OUTPUT
|
echo "output=$TG_OUT" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Publish to Cloudflare Pages
|
- name: Publish to Cloudflare Pages
|
||||||
uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1
|
uses: cloudflare/pages-action@v1
|
||||||
with:
|
with:
|
||||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN_PAGES_UPLOAD }}
|
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN_PAGES_UPLOAD }}
|
||||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||||
projectName: ${{ fromJson(steps.clean.outputs.output).pages_project_name.value }}
|
projectName: ${{ fromJson(steps.clean.outputs.output).pages_project_name.value }}
|
||||||
workingDirectory: 'docs'
|
workingDirectory: "docs"
|
||||||
directory: 'build'
|
directory: "build"
|
||||||
branch: ${{ steps.parameters.outputs.name }}
|
branch: ${{ steps.parameters.outputs.name }}
|
||||||
wranglerVersion: '3'
|
wranglerVersion: '3'
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ jobs:
|
|||||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
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 }}
|
||||||
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2
|
uses: gruntwork-io/terragrunt-action@v2
|
||||||
with:
|
with:
|
||||||
tg_version: '0.58.12'
|
tg_version: '0.58.12'
|
||||||
tofu_version: '1.7.1'
|
tofu_version: '1.7.1'
|
||||||
@@ -192,7 +192,7 @@ jobs:
|
|||||||
tg_command: 'apply'
|
tg_command: 'apply'
|
||||||
|
|
||||||
- name: Comment
|
- name: Comment
|
||||||
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3
|
uses: actions-cool/maintain-one-comment@v3
|
||||||
if: ${{ steps.parameters.outputs.event == 'pr' }}
|
if: ${{ steps.parameters.outputs.event == 'pr' }}
|
||||||
with:
|
with:
|
||||||
number: ${{ fromJson(needs.checks.outputs.parameters).pr_number }}
|
number: ${{ fromJson(needs.checks.outputs.parameters).pr_number }}
|
||||||
|
|||||||
@@ -9,24 +9,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Destroy Docs Subdomain
|
- name: Destroy Docs Subdomain
|
||||||
env:
|
env:
|
||||||
TF_VAR_prefix_name: 'pr-${{ github.event.number }}'
|
TF_VAR_prefix_name: "pr-${{ github.event.number }}"
|
||||||
TF_VAR_prefix_event_type: 'pr'
|
TF_VAR_prefix_event_type: "pr"
|
||||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||||
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 }}
|
||||||
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2
|
uses: gruntwork-io/terragrunt-action@v2
|
||||||
with:
|
with:
|
||||||
tg_version: '0.58.12'
|
tg_version: "0.58.12"
|
||||||
tofu_version: '1.7.1'
|
tofu_version: "1.7.1"
|
||||||
tg_dir: 'deployment/modules/cloudflare/docs'
|
tg_dir: "deployment/modules/cloudflare/docs"
|
||||||
tg_command: 'destroy -refresh=false'
|
tg_command: "destroy -refresh=false"
|
||||||
|
|
||||||
- name: Comment
|
- name: Comment
|
||||||
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3
|
uses: actions-cool/maintain-one-comment@v3
|
||||||
with:
|
with:
|
||||||
number: ${{ github.event.number }}
|
number: ${{ github.event.number }}
|
||||||
delete: true
|
delete: true
|
||||||
|
|||||||
@@ -13,19 +13,19 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
|
uses: actions/create-github-app-token@v1
|
||||||
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
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 }}
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
|
|
||||||
@@ -33,13 +33,13 @@ jobs:
|
|||||||
run: make install-all && make format-all
|
run: make install-all && make format-all
|
||||||
|
|
||||||
- name: Commit and push
|
- name: Commit and push
|
||||||
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9
|
uses: EndBug/add-and-commit@v9
|
||||||
with:
|
with:
|
||||||
default_author: github_actions
|
default_author: github_actions
|
||||||
message: 'chore: fix formatting'
|
message: 'chore: fix formatting'
|
||||||
|
|
||||||
- name: Remove label
|
- name: Remove label
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
uses: actions/github-script@v7
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
@@ -49,3 +49,4 @@ jobs:
|
|||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
name: 'fix:formatting'
|
name: 'fix:formatting'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- name: Require PR to have a changelog label
|
- name: Require PR to have a changelog label
|
||||||
uses: mheap/github-action-required-labels@388fd6af37b34cdfe5a23b37060e763217e58b03 # v5
|
uses: mheap/github-action-required-labels@v5
|
||||||
with:
|
with:
|
||||||
mode: exactly
|
mode: exactly
|
||||||
count: 1
|
count: 1
|
||||||
use_regex: true
|
use_regex: true
|
||||||
labels: 'changelog:.*'
|
labels: "changelog:.*"
|
||||||
add_comment: true
|
add_comment: true
|
||||||
message: 'Label error. Requires {{errorString}} {{count}} of: {{ provided }}. Found: {{ applied }}. A maintainer will add the required label.'
|
message: "Label error. Requires {{errorString}} {{count}} of: {{ provided }}. Found: {{ applied }}. A maintainer will add the required label."
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: 'Pull Request Labeler'
|
name: "Pull Request Labeler"
|
||||||
on:
|
on:
|
||||||
- pull_request_target
|
- pull_request_target
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
labeler:
|
labeler:
|
||||||
@@ -9,4 +9,4 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5
|
- uses: actions/labeler@v5
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: PR Conventional Commit Validation
|
- name: PR Conventional Commit Validation
|
||||||
uses: ytanikin/PRConventionalCommits@b628c5a234cc32513014b7bfdd1e47b532124d98 # 1.3.0
|
uses: ytanikin/PRConventionalCommits@1.3.0
|
||||||
with:
|
with:
|
||||||
task_types: '["feat","fix","docs","test","ci","refactor","perf","chore","revert"]'
|
task_types: '["feat","fix","docs","test","ci","refactor","perf","chore","revert"]'
|
||||||
add_label: 'false'
|
add_label: 'false'
|
||||||
|
|||||||
@@ -31,25 +31,25 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
|
uses: actions/create-github-app-token@v1
|
||||||
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.generate-token.outputs.token }}
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
|
||||||
- name: Install uv
|
- name: Install uv
|
||||||
uses: astral-sh/setup-uv@0c5e2b8115b80b4c7c5ddf6ffdd634974642d182 # v5
|
uses: astral-sh/setup-uv@v5
|
||||||
|
|
||||||
- name: Bump version
|
- name: Bump version
|
||||||
run: misc/release/pump-version.sh -s "${{ inputs.serverBump }}" -m "${{ inputs.mobileBump }}"
|
run: misc/release/pump-version.sh -s "${{ inputs.serverBump }}" -m "${{ inputs.mobileBump }}"
|
||||||
|
|
||||||
- name: Commit and tag
|
- name: Commit and tag
|
||||||
id: push-tag
|
id: push-tag
|
||||||
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9
|
uses: EndBug/add-and-commit@v9
|
||||||
with:
|
with:
|
||||||
default_author: github_actions
|
default_author: github_actions
|
||||||
message: 'chore: version ${{ env.IMMICH_VERSION }}'
|
message: 'chore: version ${{ env.IMMICH_VERSION }}'
|
||||||
@@ -70,23 +70,23 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Generate a token
|
- name: Generate a token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
|
uses: actions/create-github-app-token@v1
|
||||||
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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.generate-token.outputs.token }}
|
token: ${{ steps.generate-token.outputs.token }}
|
||||||
|
|
||||||
- name: Download APK
|
- name: Download APK
|
||||||
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: release-apk-signed
|
name: release-apk-signed
|
||||||
|
|
||||||
- name: Create draft release
|
- name: Create draft release
|
||||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
draft: true
|
draft: true
|
||||||
tag_name: ${{ env.IMMICH_VERSION }}
|
tag_name: ${{ env.IMMICH_VERSION }}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2
|
- uses: mshick/add-pr-comment@v2
|
||||||
with:
|
with:
|
||||||
message-id: 'preview-status'
|
message-id: "preview-status"
|
||||||
message: 'Deploying preview environment to https://pr-${{ github.event.pull_request.number }}.preview.internal.immich.cloud/'
|
message: "Deploying preview environment to https://pr-${{ github.event.pull_request.number }}.preview.internal.immich.cloud/"
|
||||||
|
|
||||||
remove-label:
|
remove-label:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -22,7 +22,7 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
- uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
github.rest.issues.removeLabel({
|
github.rest.issues.removeLabel({
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
working-directory: ./open-api/typescript-sdk
|
working-directory: ./open-api/typescript-sdk
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
- uses: actions/checkout@v4
|
||||||
# Setup .npmrc file to publish to npm
|
# Setup .npmrc file to publish to npm
|
||||||
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
- uses: actions/setup-node@v4
|
||||||
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'
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ jobs:
|
|||||||
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
uses: dorny/paths-filter@v3
|
||||||
with:
|
with:
|
||||||
filters: |
|
filters: |
|
||||||
mobile:
|
mobile:
|
||||||
@@ -38,10 +38,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Flutter SDK
|
- name: Setup Flutter SDK
|
||||||
uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2
|
uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: 'stable'
|
channel: 'stable'
|
||||||
flutter-version-file: ./mobile/pubspec.yaml
|
flutter-version-file: ./mobile/pubspec.yaml
|
||||||
@@ -55,7 +55,7 @@ jobs:
|
|||||||
working-directory: ./mobile
|
working-directory: ./mobile
|
||||||
|
|
||||||
- name: Find file changes
|
- name: Find file changes
|
||||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20
|
uses: tj-actions/verify-changed-files@v20
|
||||||
id: verify-changed-files
|
id: verify-changed-files
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
|
|||||||
+39
-67
@@ -21,12 +21,11 @@ jobs:
|
|||||||
should_run_ml: ${{ steps.found_paths.outputs.machine-learning == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run_ml: ${{ steps.found_paths.outputs.machine-learning == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
should_run_e2e_web: ${{ steps.found_paths.outputs.e2e == 'true' || steps.found_paths.outputs.web == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run_e2e_web: ${{ steps.found_paths.outputs.e2e == 'true' || steps.found_paths.outputs.web == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
should_run_e2e_server_cli: ${{ steps.found_paths.outputs.e2e == 'true' || steps.found_paths.outputs.server == 'true' || steps.found_paths.outputs.cli == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
should_run_e2e_server_cli: ${{ steps.found_paths.outputs.e2e == 'true' || steps.found_paths.outputs.server == 'true' || steps.found_paths.outputs.cli == 'true' || steps.should_force.outputs.should_force == 'true' }}
|
||||||
should_run_.github: ${{ steps.found_paths.outputs['.github'] == 'true' || steps.should_force.outputs.should_force == 'true' }} # redundant to have should_force but if someone changes the trigger then this won't have to be changed
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
uses: dorny/paths-filter@v3
|
||||||
with:
|
with:
|
||||||
filters: |
|
filters: |
|
||||||
web:
|
web:
|
||||||
@@ -46,8 +45,6 @@ jobs:
|
|||||||
- 'machine-learning/**'
|
- 'machine-learning/**'
|
||||||
workflow:
|
workflow:
|
||||||
- '.github/workflows/test.yml'
|
- '.github/workflows/test.yml'
|
||||||
.github:
|
|
||||||
- '.github/**'
|
|
||||||
|
|
||||||
- name: Check if we should force jobs to run
|
- name: Check if we should force jobs to run
|
||||||
id: should_force
|
id: should_force
|
||||||
@@ -64,10 +61,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
|
|
||||||
@@ -101,10 +98,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './cli/.nvmrc'
|
node-version-file: './cli/.nvmrc'
|
||||||
|
|
||||||
@@ -142,10 +139,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './cli/.nvmrc'
|
node-version-file: './cli/.nvmrc'
|
||||||
|
|
||||||
@@ -176,10 +173,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './web/.nvmrc'
|
node-version-file: './web/.nvmrc'
|
||||||
|
|
||||||
@@ -221,10 +218,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './e2e/.nvmrc'
|
node-version-file: './e2e/.nvmrc'
|
||||||
|
|
||||||
@@ -260,10 +257,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
|
|
||||||
@@ -285,12 +282,12 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './e2e/.nvmrc'
|
node-version-file: './e2e/.nvmrc'
|
||||||
|
|
||||||
@@ -327,12 +324,12 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './e2e/.nvmrc'
|
node-version-file: './e2e/.nvmrc'
|
||||||
|
|
||||||
@@ -363,9 +360,9 @@ jobs:
|
|||||||
if: ${{ needs.pre-job.outputs.should_run_mobile == 'true' }}
|
if: ${{ needs.pre-job.outputs.should_run_mobile == 'true' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
- uses: actions/checkout@v4
|
||||||
- name: Setup Flutter SDK
|
- name: Setup Flutter SDK
|
||||||
uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2
|
uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
channel: 'stable'
|
channel: 'stable'
|
||||||
flutter-version-file: ./mobile/pubspec.yaml
|
flutter-version-file: ./mobile/pubspec.yaml
|
||||||
@@ -382,10 +379,10 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
working-directory: ./machine-learning
|
working-directory: ./machine-learning
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
- uses: actions/checkout@v4
|
||||||
- name: Install uv
|
- name: Install uv
|
||||||
uses: astral-sh/setup-uv@0c5e2b8115b80b4c7c5ddf6ffdd634974642d182 # v5
|
uses: astral-sh/setup-uv@v5
|
||||||
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5
|
- uses: actions/setup-python@v5
|
||||||
# TODO: add caching when supported (https://github.com/actions/setup-python/pull/818)
|
# TODO: add caching when supported (https://github.com/actions/setup-python/pull/818)
|
||||||
# with:
|
# with:
|
||||||
# python-version: 3.11
|
# python-version: 3.11
|
||||||
@@ -395,47 +392,22 @@ jobs:
|
|||||||
uv sync --extra cpu
|
uv sync --extra cpu
|
||||||
- name: Lint with ruff
|
- name: Lint with ruff
|
||||||
run: |
|
run: |
|
||||||
uv run ruff check --output-format=github immich_ml
|
uv run ruff check --output-format=github app export
|
||||||
- name: Check black formatting
|
- name: Check black formatting
|
||||||
run: |
|
run: |
|
||||||
uv run black --check immich_ml
|
uv run black --check app export
|
||||||
- name: Run mypy type checking
|
- name: Run mypy type checking
|
||||||
run: |
|
run: |
|
||||||
uv run mypy --strict immich_ml/
|
uv run mypy --strict app/
|
||||||
- name: Run tests and coverage
|
- name: Run tests and coverage
|
||||||
run: |
|
run: |
|
||||||
uv run pytest --cov=immich_ml --cov-report term-missing
|
uv run pytest app --cov=app --cov-report term-missing
|
||||||
|
|
||||||
github-files-formatting:
|
|
||||||
name: .github Files Formatting
|
|
||||||
needs: pre-job
|
|
||||||
if: ${{ needs.pre-job.outputs['should_run_.github'] == 'true' }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: ./.github
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
|
||||||
|
|
||||||
- name: Setup Node
|
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
|
||||||
with:
|
|
||||||
node-version-file: './.github/.nvmrc'
|
|
||||||
|
|
||||||
- name: Run npm install
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Run formatter
|
|
||||||
run: npm run format
|
|
||||||
if: ${{ !cancelled() }}
|
|
||||||
|
|
||||||
shellcheck:
|
shellcheck:
|
||||||
name: ShellCheck
|
name: ShellCheck
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
- uses: actions/checkout@v4
|
||||||
- name: Run ShellCheck
|
- name: Run ShellCheck
|
||||||
uses: ludeeus/action-shellcheck@master
|
uses: ludeeus/action-shellcheck@master
|
||||||
with:
|
with:
|
||||||
@@ -449,10 +421,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
|
|
||||||
@@ -466,7 +438,7 @@ jobs:
|
|||||||
run: make open-api
|
run: make open-api
|
||||||
|
|
||||||
- name: Find file changes
|
- name: Find file changes
|
||||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20
|
uses: tj-actions/verify-changed-files@v20
|
||||||
id: verify-changed-files
|
id: verify-changed-files
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
@@ -504,10 +476,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: './server/.nvmrc'
|
node-version-file: './server/.nvmrc'
|
||||||
|
|
||||||
@@ -518,27 +490,27 @@ jobs:
|
|||||||
run: npm run build
|
run: npm run build
|
||||||
|
|
||||||
- name: Run existing migrations
|
- name: Run existing migrations
|
||||||
run: npm run migrations:run
|
run: npm run typeorm:migrations:run
|
||||||
|
|
||||||
- name: Test npm run schema:reset command works
|
- name: Test npm run schema:reset command works
|
||||||
run: npm run typeorm:schema:reset
|
run: npm run typeorm:schema:reset
|
||||||
|
|
||||||
- name: Generate new migrations
|
- name: Generate new migrations
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: npm run migrations:generate TestMigration
|
run: npm run typeorm:migrations:generate ./src/migrations/TestMigration
|
||||||
|
|
||||||
- name: Find file changes
|
- name: Find file changes
|
||||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20
|
uses: tj-actions/verify-changed-files@v20
|
||||||
id: verify-changed-files
|
id: verify-changed-files
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
server/src
|
server/src/migrations/
|
||||||
- name: Verify migration files have not changed
|
- name: Verify migration files have not changed
|
||||||
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
||||||
run: |
|
run: |
|
||||||
echo "ERROR: Generated migration files not up to date!"
|
echo "ERROR: Generated migration files not up to date!"
|
||||||
echo "Changed files: ${{ steps.verify-changed-files.outputs.changed_files }}"
|
echo "Changed files: ${{ steps.verify-changed-files.outputs.changed_files }}"
|
||||||
cat ./src/*-TestMigration.ts
|
cat ./src/migrations/*-TestMigration.ts
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
- name: Run SQL generation
|
- name: Run SQL generation
|
||||||
@@ -547,7 +519,7 @@ jobs:
|
|||||||
DB_URL: postgres://postgres:postgres@localhost:5432/immich
|
DB_URL: postgres://postgres:postgres@localhost:5432/immich
|
||||||
|
|
||||||
- name: Find file changes
|
- name: Find file changes
|
||||||
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20
|
uses: tj-actions/verify-changed-files@v20
|
||||||
id: verify-changed-sql-files
|
id: verify-changed-sql-files
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
|
|||||||
@@ -11,22 +11,22 @@ jobs:
|
|||||||
should_run: ${{ steps.found_paths.outputs.i18n == 'true' && github.head_ref != 'chore/translations'}}
|
should_run: ${{ steps.found_paths.outputs.i18n == 'true' && github.head_ref != 'chore/translations'}}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
uses: actions/checkout@v4
|
||||||
- id: found_paths
|
- id: found_paths
|
||||||
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
|
uses: dorny/paths-filter@v3
|
||||||
with:
|
with:
|
||||||
filters: |
|
filters: |
|
||||||
i18n:
|
i18n:
|
||||||
- 'i18n/!(en)**\.json'
|
- 'i18n/!(en)**\.json'
|
||||||
- name: Debug
|
- name: Debug
|
||||||
run: |
|
run: |
|
||||||
echo "Should run: ${{ steps.found_paths.outputs.i18n == 'true' && github.head_ref != 'chore/translations'}}"
|
echo "Should run: ${{ steps.found_paths.outputs.i18n == 'true' && github.head_ref != 'chore/translations'}}"
|
||||||
echo "Found i18n paths: ${{ steps.found_paths.outputs.i18n }}"
|
echo "Found i18n paths: ${{ steps.found_paths.outputs.i18n }}"
|
||||||
echo "Head ref: ${{ github.head_ref }}"
|
echo "Head ref: ${{ github.head_ref }}"
|
||||||
|
|
||||||
enforce-lock:
|
enforce-lock:
|
||||||
name: Check Weblate Lock
|
name: Check Weblate Lock
|
||||||
needs: [pre-job]
|
needs: [ pre-job ]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ needs.pre-job.outputs.should_run == 'true' }}
|
if: ${{ needs.pre-job.outputs.should_run == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
@@ -36,7 +36,7 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
- name: Find Pull Request
|
- name: Find Pull Request
|
||||||
uses: juliangruber/find-pull-request-action@48b6133aa6c826f267ebd33aa2d29470f9d9e7d0 # v1
|
uses: juliangruber/find-pull-request-action@v1
|
||||||
id: find-pr
|
id: find-pr
|
||||||
with:
|
with:
|
||||||
branch: chore/translations
|
branch: chore/translations
|
||||||
@@ -45,7 +45,7 @@ jobs:
|
|||||||
run: exit 1
|
run: exit 1
|
||||||
success-check-lock:
|
success-check-lock:
|
||||||
name: Weblate Lock Check Success
|
name: Weblate Lock Check Success
|
||||||
needs: [enforce-lock]
|
needs: [ enforce-lock ]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: always()
|
if: always()
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
Vendored
+1
-2
@@ -39,7 +39,6 @@
|
|||||||
],
|
],
|
||||||
"explorer.fileNesting.enabled": true,
|
"explorer.fileNesting.enabled": true,
|
||||||
"explorer.fileNesting.patterns": {
|
"explorer.fileNesting.patterns": {
|
||||||
"*.ts": "${capture}.spec.ts,${capture}.mock.ts",
|
"*.ts": "${capture}.spec.ts,${capture}.mock.ts"
|
||||||
"*.dart": "${capture}.g.dart,${capture}.gr.dart,${capture}.drift.dart"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ attach-server:
|
|||||||
renovate:
|
renovate:
|
||||||
LOG_LEVEL=debug npx renovate --platform=local --repository-cache=reset
|
LOG_LEVEL=debug npx renovate --platform=local --repository-cache=reset
|
||||||
|
|
||||||
MODULES = e2e server web cli sdk docs .github
|
MODULES = e2e server web cli sdk docs
|
||||||
|
|
||||||
audit-%:
|
audit-%:
|
||||||
npm --prefix $(subst sdk,open-api/typescript-sdk,$*) audit fix
|
npm --prefix $(subst sdk,open-api/typescript-sdk,$*) audit fix
|
||||||
@@ -77,14 +77,14 @@ test-medium:
|
|||||||
test-medium-dev:
|
test-medium-dev:
|
||||||
docker exec -it immich_server /bin/sh -c "npm run test:medium"
|
docker exec -it immich_server /bin/sh -c "npm run test:medium"
|
||||||
|
|
||||||
build-all: $(foreach M,$(filter-out e2e .github,$(MODULES)),build-$M) ;
|
build-all: $(foreach M,$(filter-out e2e,$(MODULES)),build-$M) ;
|
||||||
install-all: $(foreach M,$(MODULES),install-$M) ;
|
install-all: $(foreach M,$(MODULES),install-$M) ;
|
||||||
check-all: $(foreach M,$(filter-out sdk cli docs .github,$(MODULES)),check-$M) ;
|
check-all: $(foreach M,$(filter-out sdk cli docs,$(MODULES)),check-$M) ;
|
||||||
lint-all: $(foreach M,$(filter-out sdk docs .github,$(MODULES)),lint-$M) ;
|
lint-all: $(foreach M,$(filter-out sdk docs,$(MODULES)),lint-$M) ;
|
||||||
format-all: $(foreach M,$(filter-out sdk,$(MODULES)),format-$M) ;
|
format-all: $(foreach M,$(filter-out sdk,$(MODULES)),format-$M) ;
|
||||||
audit-all: $(foreach M,$(MODULES),audit-$M) ;
|
audit-all: $(foreach M,$(MODULES),audit-$M) ;
|
||||||
hygiene-all: lint-all format-all check-all sql audit-all;
|
hygiene-all: lint-all format-all check-all sql audit-all;
|
||||||
test-all: $(foreach M,$(filter-out sdk docs .github,$(MODULES)),test-$M) ;
|
test-all: $(foreach M,$(filter-out sdk docs,$(MODULES)),test-$M) ;
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
find . -name "node_modules" -type d -prune -exec rm -rf '{}' +
|
find . -name "node_modules" -type d -prune -exec rm -rf '{}' +
|
||||||
|
|||||||
@@ -61,7 +61,9 @@
|
|||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
|
||||||
Access the demo [here](https://demo.immich.app). For the mobile app, you can use `https://demo.immich.app` for the `Server Endpoint URL`.
|
Access the demo [here](https://demo.immich.app). The demo is running on a Free-tier Oracle VM in Amsterdam with a 2.4Ghz quad-core ARM64 CPU and 24GB RAM.
|
||||||
|
|
||||||
|
For the mobile app, you can use `https://demo.immich.app` for the `Server Endpoint URL`
|
||||||
|
|
||||||
### Login credentials
|
### Login credentials
|
||||||
|
|
||||||
@@ -102,7 +104,7 @@ Access the demo [here](https://demo.immich.app). For the mobile app, you can use
|
|||||||
| Read-only gallery | Yes | Yes |
|
| Read-only gallery | Yes | Yes |
|
||||||
| Stacked Photos | Yes | Yes |
|
| Stacked Photos | Yes | Yes |
|
||||||
| Tags | No | Yes |
|
| Tags | No | Yes |
|
||||||
| Folder View | Yes | Yes |
|
| Folder View | No | Yes |
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
|
|
||||||
|
|||||||
+20
-10
@@ -1,29 +1,39 @@
|
|||||||
|
import { FlatCompat } from '@eslint/eslintrc';
|
||||||
import js from '@eslint/js';
|
import js from '@eslint/js';
|
||||||
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
import typescriptEslint from '@typescript-eslint/eslint-plugin';
|
||||||
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
|
import tsParser from '@typescript-eslint/parser';
|
||||||
import globals from 'globals';
|
import globals from 'globals';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import typescriptEslint from 'typescript-eslint';
|
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
baseDirectory: __dirname,
|
||||||
|
recommendedConfig: js.configs.recommended,
|
||||||
|
allConfig: js.configs.all,
|
||||||
|
});
|
||||||
|
|
||||||
export default typescriptEslint.config([
|
export default [
|
||||||
eslintPluginUnicorn.configs.recommended,
|
|
||||||
eslintPluginPrettierRecommended,
|
|
||||||
js.configs.recommended,
|
|
||||||
typescriptEslint.configs.recommended,
|
|
||||||
{
|
{
|
||||||
ignores: ['eslint.config.mjs', 'dist'],
|
ignores: ['eslint.config.mjs', 'dist'],
|
||||||
},
|
},
|
||||||
|
...compat.extends(
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
'plugin:unicorn/recommended',
|
||||||
|
),
|
||||||
{
|
{
|
||||||
|
plugins: {
|
||||||
|
'@typescript-eslint': typescriptEslint,
|
||||||
|
},
|
||||||
|
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
globals: {
|
globals: {
|
||||||
...globals.node,
|
...globals.node,
|
||||||
},
|
},
|
||||||
|
|
||||||
parser: typescriptEslint.parser,
|
parser: tsParser,
|
||||||
ecmaVersion: 5,
|
ecmaVersion: 5,
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
|
|
||||||
@@ -48,4 +58,4 @@ export default typescriptEslint.config([
|
|||||||
'object-shorthand': ['error', 'always'],
|
'object-shorthand': ['error', 'always'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
];
|
||||||
|
|||||||
Generated
+620
-415
File diff suppressed because it is too large
Load Diff
+5
-4
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/cli",
|
"name": "@immich/cli",
|
||||||
"version": "2.2.61",
|
"version": "2.2.53",
|
||||||
"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",
|
||||||
@@ -21,7 +21,9 @@
|
|||||||
"@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.14.0",
|
"@types/node": "^22.13.9",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
||||||
|
"@typescript-eslint/parser": "^8.15.0",
|
||||||
"@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",
|
||||||
@@ -29,13 +31,12 @@
|
|||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^10.0.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^57.0.0",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
"mock-fs": "^5.2.0",
|
"mock-fs": "^5.2.0",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"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",
|
|
||||||
"vite": "^6.0.0",
|
"vite": "^6.0.0",
|
||||||
"vite-tsconfig-paths": "^5.0.0",
|
"vite-tsconfig-paths": "^5.0.0",
|
||||||
"vitest": "^3.0.0",
|
"vitest": "^3.0.0",
|
||||||
|
|||||||
@@ -95,12 +95,12 @@ services:
|
|||||||
image: immich-machine-learning-dev:latest
|
image: immich-machine-learning-dev:latest
|
||||||
# extends:
|
# extends:
|
||||||
# file: hwaccel.ml.yml
|
# file: hwaccel.ml.yml
|
||||||
# service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference
|
# service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl, rknn] for accelerated inference
|
||||||
build:
|
build:
|
||||||
context: ../machine-learning
|
context: ../machine-learning
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
- DEVICE=cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference
|
- DEVICE=cpu # set to one of [armnn, cuda, openvino, openvino-wsl, rknn] for accelerated inference
|
||||||
ports:
|
ports:
|
||||||
- 3003:3003
|
- 3003:3003
|
||||||
volumes:
|
volumes:
|
||||||
@@ -116,7 +116,7 @@ services:
|
|||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
image: docker.io/valkey/valkey:8-bookworm@sha256:42cba146593a5ea9a622002c1b7cba5da7be248650cbb64ecb9c6c33d29794b1
|
image: redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: redis-cli ping || exit 1
|
test: redis-cli ping || exit 1
|
||||||
|
|
||||||
|
|||||||
@@ -38,12 +38,12 @@ services:
|
|||||||
image: immich-machine-learning:latest
|
image: immich-machine-learning:latest
|
||||||
# extends:
|
# extends:
|
||||||
# file: hwaccel.ml.yml
|
# file: hwaccel.ml.yml
|
||||||
# service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference
|
# service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl, rknn] for accelerated inference
|
||||||
build:
|
build:
|
||||||
context: ../machine-learning
|
context: ../machine-learning
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
- DEVICE=cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference
|
- DEVICE=cpu # set to one of [armnn, cuda, openvino, openvino-wsl, rknn] for accelerated inference
|
||||||
ports:
|
ports:
|
||||||
- 3003:3003
|
- 3003:3003
|
||||||
volumes:
|
volumes:
|
||||||
@@ -56,7 +56,7 @@ services:
|
|||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
image: docker.io/valkey/valkey:8-bookworm@sha256:42cba146593a5ea9a622002c1b7cba5da7be248650cbb64ecb9c6c33d29794b1
|
image: redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: redis-cli ping || exit 1
|
test: redis-cli ping || exit 1
|
||||||
restart: always
|
restart: always
|
||||||
@@ -90,7 +90,7 @@ services:
|
|||||||
container_name: immich_prometheus
|
container_name: immich_prometheus
|
||||||
ports:
|
ports:
|
||||||
- 9090:9090
|
- 9090:9090
|
||||||
image: prom/prometheus@sha256:502ad90314c7485892ce696cb14a99fceab9fc27af29f4b427f41bd39701a199
|
image: prom/prometheus@sha256:6927e0919a144aa7616fd0137d4816816d42f6b816de3af269ab065250859a62
|
||||||
volumes:
|
volumes:
|
||||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
- ./prometheus.yml:/etc/prometheus/prometheus.yml
|
||||||
- prometheus-data:/prometheus
|
- prometheus-data:/prometheus
|
||||||
@@ -102,7 +102,7 @@ services:
|
|||||||
command: [ './run.sh', '-disable-reporting' ]
|
command: [ './run.sh', '-disable-reporting' ]
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
image: grafana/grafana:11.6.0-ubuntu@sha256:fd8fa48213c624e1a95122f1d93abbf1cf1cbe85fc73212c1e599dbd76c63ff8
|
image: grafana/grafana:11.5.2-ubuntu@sha256:8b5858c447e06fd7a89006b562ba7bba7c4d5813600c7982374c41852adefaeb
|
||||||
volumes:
|
volumes:
|
||||||
- grafana-data:/var/lib/grafana
|
- grafana-data:/var/lib/grafana
|
||||||
|
|
||||||
|
|||||||
@@ -33,12 +33,12 @@ services:
|
|||||||
|
|
||||||
immich-machine-learning:
|
immich-machine-learning:
|
||||||
container_name: immich_machine_learning
|
container_name: immich_machine_learning
|
||||||
# For hardware acceleration, add one of -[armnn, cuda, rocm, openvino, rknn] to the image tag.
|
# For hardware acceleration, add one of -[armnn, cuda, openvino, rknn] to the image tag.
|
||||||
# Example tag: ${IMMICH_VERSION:-release}-cuda
|
# Example tag: ${IMMICH_VERSION:-release}-cuda
|
||||||
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
|
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
|
||||||
# extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration
|
# extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration
|
||||||
# file: hwaccel.ml.yml
|
# file: hwaccel.ml.yml
|
||||||
# service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference - use the `-wsl` version for WSL2 where applicable
|
# service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl, rknn] for accelerated inference - use the `-wsl` version for WSL2 where applicable
|
||||||
volumes:
|
volumes:
|
||||||
- model-cache:/cache
|
- model-cache:/cache
|
||||||
env_file:
|
env_file:
|
||||||
@@ -49,7 +49,7 @@ services:
|
|||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: immich_redis
|
container_name: immich_redis
|
||||||
image: docker.io/valkey/valkey:8-bookworm@sha256:42cba146593a5ea9a622002c1b7cba5da7be248650cbb64ecb9c6c33d29794b1
|
image: docker.io/redis:6.2-alpine@sha256:148bb5411c184abd288d9aaed139c98123eeb8824c5d3fce03cf721db58066d8
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: redis-cli ping || exit 1
|
test: redis-cli ping || exit 1
|
||||||
restart: always
|
restart: always
|
||||||
|
|||||||
+1
-2
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
# The location where your uploaded files are stored
|
# The location where your uploaded files are stored
|
||||||
UPLOAD_LOCATION=./library
|
UPLOAD_LOCATION=./library
|
||||||
|
# The location where your database files are stored
|
||||||
# The location where your database files are stored. Network shares are not supported for the database
|
|
||||||
DB_DATA_LOCATION=./postgres
|
DB_DATA_LOCATION=./postgres
|
||||||
|
|
||||||
# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
|
# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
|
||||||
|
|||||||
@@ -33,13 +33,6 @@ services:
|
|||||||
capabilities:
|
capabilities:
|
||||||
- gpu
|
- gpu
|
||||||
|
|
||||||
rocm:
|
|
||||||
group_add:
|
|
||||||
- video
|
|
||||||
devices:
|
|
||||||
- /dev/dri:/dev/dri
|
|
||||||
- /dev/kfd:/dev/kfd
|
|
||||||
|
|
||||||
openvino:
|
openvino:
|
||||||
device_cgroup_rules:
|
device_cgroup_rules:
|
||||||
- 'c 189:* rmw'
|
- 'c 189:* rmw'
|
||||||
|
|||||||
+1
-1
@@ -262,7 +262,7 @@ No, this is not supported. Only models listed in the [Hugging Face][huggingface]
|
|||||||
|
|
||||||
### I want to be able to search in other languages besides English. How can I do that?
|
### I want to be able to search in other languages besides English. How can I do that?
|
||||||
|
|
||||||
You can change to a multilingual CLIP model. See [here](/docs/features/searching#clip-models) for instructions.
|
You can change to a multilingual CLIP model. See [here](/docs/features/searching#clip-model) for instructions.
|
||||||
|
|
||||||
### Does Immich support Facial Recognition for videos?
|
### Does Immich support Facial Recognition for videos?
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 12 KiB |
@@ -11,7 +11,6 @@ The `immich-server` docker image comes preinstalled with an administrative CLI (
|
|||||||
| `enable-oauth-login` | Enable OAuth login |
|
| `enable-oauth-login` | Enable OAuth login |
|
||||||
| `disable-oauth-login` | Disable OAuth login |
|
| `disable-oauth-login` | Disable OAuth login |
|
||||||
| `list-users` | List Immich users |
|
| `list-users` | List Immich users |
|
||||||
| `version` | Print Immich version |
|
|
||||||
|
|
||||||
## How to run a command
|
## How to run a command
|
||||||
|
|
||||||
@@ -81,10 +80,3 @@ immich-admin list-users
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
Print Immich Version
|
|
||||||
|
|
||||||
```
|
|
||||||
immich-admin version
|
|
||||||
v1.129.0
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -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 pencil icon and enter the storage quota in GiB. You can choose an unlimited quota using the value 0 (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.
|
||||||
|
|||||||
@@ -63,13 +63,6 @@ If you only want to do web development connected to an existing, remote backend,
|
|||||||
IMMICH_SERVER_URL=https://demo.immich.app/ npm run dev
|
IMMICH_SERVER_URL=https://demo.immich.app/ npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
If you're using PowerShell on Windows you may need to set the env var separately like so:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
$env:IMMICH_SERVER_URL = "https://demo.immich.app/"
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `@immich/ui`
|
#### `@immich/ui`
|
||||||
|
|
||||||
To see local changes to `@immich/ui` in Immich, do the following:
|
To see local changes to `@immich/ui` in Immich, do the following:
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ You begin by authenticating to your Immich server. For instance:
|
|||||||
immich login http://192.168.1.216:2283/api HFEJ38DNSDUEG
|
immich login http://192.168.1.216:2283/api HFEJ38DNSDUEG
|
||||||
```
|
```
|
||||||
|
|
||||||
This will store your credentials in a `auth.yml` file in the configuration directory which defaults to `~/.config/immich/`. The directory can be set with the `-d` option or the environment variable `IMMICH_CONFIG_DIR`. Please keep the file secure, either by performing the logout command after you are done, or deleting it manually.
|
This will store your credentials in a `auth.yml` file in the configuration directory which defaults to `~/.config/`. The directory can be set with the `-d` option or the environment variable `IMMICH_CONFIG_DIR`. Please keep the file secure, either by performing the logout command after you are done, or deleting it manually.
|
||||||
|
|
||||||
Once you are authenticated, you can upload assets to your Immich server.
|
Once you are authenticated, you can upload assets to your Immich server.
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 4.9 MiB After Width: | Height: | Size: 4.9 MiB |
@@ -95,7 +95,7 @@ The `immich-server` container will need access to the gallery. Modify your docke
|
|||||||
+ - /mnt/nas/christmas-trip:/mnt/media/christmas-trip:ro
|
+ - /mnt/nas/christmas-trip:/mnt/media/christmas-trip:ro
|
||||||
+ - /home/user/old-pics:/mnt/media/old-pics:ro
|
+ - /home/user/old-pics:/mnt/media/old-pics:ro
|
||||||
+ - /mnt/media/videos:/mnt/media/videos:ro
|
+ - /mnt/media/videos:/mnt/media/videos:ro
|
||||||
+ - /mnt/media/videos2:/mnt/media/videos2 # WARNING: Immich will be able to delete the files in this folder, as it does not end with :ro
|
+ - /mnt/media/videos2:/mnt/media/videos2 # the files in this folder can be deleted, as it does not end with :ro
|
||||||
+ - "C:/Users/user_name/Desktop/my media:/mnt/media/my-media:ro" # import path in Windows system.
|
+ - "C:/Users/user_name/Desktop/my media:/mnt/media/my-media:ro" # import path in Windows system.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ You do not need to redo any machine learning jobs after enabling hardware accele
|
|||||||
|
|
||||||
- ARM NN (Mali)
|
- ARM NN (Mali)
|
||||||
- CUDA (NVIDIA GPUs with [compute capability](https://developer.nvidia.com/cuda-gpus) 5.2 or higher)
|
- CUDA (NVIDIA GPUs with [compute capability](https://developer.nvidia.com/cuda-gpus) 5.2 or higher)
|
||||||
- ROCm (AMD GPUs)
|
|
||||||
- OpenVINO (Intel GPUs such as Iris Xe and Arc)
|
- OpenVINO (Intel GPUs such as Iris Xe and Arc)
|
||||||
- RKNN (Rockchip)
|
- RKNN (Rockchip)
|
||||||
|
|
||||||
@@ -45,12 +44,6 @@ You do not need to redo any machine learning jobs after enabling hardware accele
|
|||||||
- The installed driver must be >= 535 (it must support CUDA 12.2).
|
- The installed driver must be >= 535 (it must support CUDA 12.2).
|
||||||
- On Linux (except for WSL2), you also need to have [NVIDIA Container Toolkit][nvct] installed.
|
- On Linux (except for WSL2), you also need to have [NVIDIA Container Toolkit][nvct] installed.
|
||||||
|
|
||||||
#### ROCm
|
|
||||||
|
|
||||||
- The GPU must be supported by ROCm. If it isn't officially supported, you can attempt to use the `HSA_OVERRIDE_GFX_VERSION` environmental variable: `HSA_OVERRIDE_GFX_VERSION=<a supported version, e.g. 10.3.0>`. If this doesn't work, you might need to also set `HSA_USE_SVM=0`.
|
|
||||||
- The ROCm image is quite large and requires at least 35GiB of free disk space. However, pulling later updates to the service through Docker will generally only amount to a few hundred megabytes as the rest will be cached.
|
|
||||||
- This backend is new and may experience some issues. For example, GPU power consumption can be higher than usual after running inference, even if the machine learning service is idle. In this case, it will only go back to normal after being idle for 5 minutes (configurable with the [MACHINE_LEARNING_MODEL_TTL](/docs/install/environment-variables) setting).
|
|
||||||
|
|
||||||
#### OpenVINO
|
#### OpenVINO
|
||||||
|
|
||||||
- Integrated GPUs are more likely to experience issues than discrete GPUs, especially for older processors or servers with low RAM.
|
- Integrated GPUs are more likely to experience issues than discrete GPUs, especially for older processors or servers with low RAM.
|
||||||
@@ -71,12 +64,12 @@ You do not need to redo any machine learning jobs after enabling hardware accele
|
|||||||
|
|
||||||
1. If you do not already have it, download the latest [`hwaccel.ml.yml`][hw-file] file and ensure it's in the same folder as the `docker-compose.yml`.
|
1. If you do not already have it, download the latest [`hwaccel.ml.yml`][hw-file] file and ensure it's in the same folder as the `docker-compose.yml`.
|
||||||
2. In the `docker-compose.yml` under `immich-machine-learning`, uncomment the `extends` section and change `cpu` to the appropriate backend.
|
2. In the `docker-compose.yml` under `immich-machine-learning`, uncomment the `extends` section and change `cpu` to the appropriate backend.
|
||||||
3. Still in `immich-machine-learning`, add one of -[armnn, cuda, rocm, openvino, rknn] to the `image` section's tag at the end of the line.
|
3. Still in `immich-machine-learning`, add one of -[armnn, cuda, openvino] to the `image` section's tag at the end of the line.
|
||||||
4. Redeploy the `immich-machine-learning` container with these updated settings.
|
4. Redeploy the `immich-machine-learning` container with these updated settings.
|
||||||
|
|
||||||
### Confirming Device Usage
|
### Confirming Device Usage
|
||||||
|
|
||||||
You can confirm the device is being recognized and used by checking its utilization. There are many tools to display this, such as `nvtop` for NVIDIA or Intel, `intel_gpu_top` for Intel, and `radeontop` for AMD.
|
You can confirm the device is being recognized and used by checking its utilization. There are many tools to display this, such as `nvtop` for NVIDIA or Intel and `intel_gpu_top` for Intel.
|
||||||
|
|
||||||
You can also check the logs of the `immich-machine-learning` container. When a Smart Search or Face Detection job begins, or when you search with text in Immich, you should either see a log for `Available ORT providers` containing the relevant provider (e.g. `CUDAExecutionProvider` in the case of CUDA), or a `Loaded ANN model` log entry without errors in the case of ARM NN.
|
You can also check the logs of the `immich-machine-learning` container. When a Smart Search or Face Detection job begins, or when you search with text in Immich, you should either see a log for `Available ORT providers` containing the relevant provider (e.g. `CUDAExecutionProvider` in the case of CUDA), or a `Loaded ANN model` log entry without errors in the case of ARM NN.
|
||||||
|
|
||||||
|
|||||||
+9
-1159
File diff suppressed because it is too large
Load Diff
@@ -23,12 +23,12 @@ name: immich_remote_ml
|
|||||||
services:
|
services:
|
||||||
immich-machine-learning:
|
immich-machine-learning:
|
||||||
container_name: immich_machine_learning
|
container_name: immich_machine_learning
|
||||||
# For hardware acceleration, add one of -[armnn, cuda, rocm, openvino, rknn] to the image tag.
|
# For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.
|
||||||
# Example tag: ${IMMICH_VERSION:-release}-cuda
|
# Example tag: ${IMMICH_VERSION:-release}-cuda
|
||||||
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
|
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
|
||||||
# extends:
|
# extends:
|
||||||
# file: hwaccel.ml.yml
|
# file: hwaccel.ml.yml
|
||||||
# service: # set to one of [armnn, cuda, rocm, openvino, openvino-wsl, rknn] for accelerated inference - use the `-wsl` version for WSL2 where applicable
|
# service: # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable
|
||||||
volumes:
|
volumes:
|
||||||
- model-cache:/cache
|
- model-cache:/cache
|
||||||
restart: always
|
restart: always
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
---
|
|
||||||
sidebar_position: 100
|
|
||||||
---
|
|
||||||
|
|
||||||
# Config File
|
# Config File
|
||||||
|
|
||||||
A config file can be provided as an alternative to the UI configuration.
|
A config file can be provided as an alternative to the UI configuration.
|
||||||
|
|||||||
@@ -69,7 +69,39 @@ If you get an error `can't set healthcheck.start_interval as feature require Doc
|
|||||||
|
|
||||||
## Next Steps
|
## Next Steps
|
||||||
|
|
||||||
Read the [Post Installation](/docs/install/post-install.mdx) steps and [upgrade instructions](/docs/install/upgrading.md).
|
Read the [Post Installation](/docs/install/post-install.mdx) steps or setup optional features below.
|
||||||
|
|
||||||
|
### Setting up optional features
|
||||||
|
|
||||||
|
- [External Libraries](/docs/features/libraries.md): Adding your existing photo library to Immich
|
||||||
|
- [Hardware Transcoding](/docs/features/hardware-transcoding.md): Speeding up video transcoding
|
||||||
|
- [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md): Speeding up various machine learning tasks in Immich
|
||||||
|
|
||||||
|
### Upgrading
|
||||||
|
|
||||||
|
:::danger Read the release notes
|
||||||
|
Immich is currently under heavy development, which means you can expect [breaking changes][breaking] and bugs. Therefore, we recommend reading the release notes prior to updating and to take special care when using automated tools like [Watchtower][watchtower].
|
||||||
|
|
||||||
|
You can see versions that had breaking changes [here][breaking].
|
||||||
|
:::
|
||||||
|
|
||||||
|
If `IMMICH_VERSION` is set, it will need to be updated to the latest or desired version.
|
||||||
|
|
||||||
|
When a new version of Immich is [released][releases], the application can be upgraded and restarted with the following commands, run in the directory with the `docker-compose.yml` file:
|
||||||
|
|
||||||
|
```bash title="Upgrade and restart Immich"
|
||||||
|
docker compose pull && docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
To clean up disk space, the old version's obsolete container images can be deleted with the following command:
|
||||||
|
|
||||||
|
```bash title="Clean up unused Docker images"
|
||||||
|
docker image prune
|
||||||
|
```
|
||||||
|
|
||||||
[compose-file]: https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
|
[compose-file]: https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
|
||||||
[env-file]: https://github.com/immich-app/immich/releases/latest/download/example.env
|
[env-file]: https://github.com/immich-app/immich/releases/latest/download/example.env
|
||||||
|
[watchtower]: https://containrrr.dev/watchtower/
|
||||||
|
[breaking]: https://github.com/immich-app/immich/discussions?discussions_q=label%3Achangelog%3Abreaking-change+sort%3Adate_created
|
||||||
|
[container-auth]: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-to-the-container-registry
|
||||||
|
[releases]: https://github.com/immich-app/immich/releases
|
||||||
|
|||||||
@@ -41,9 +41,3 @@ A list of common steps to take after installing Immich include:
|
|||||||
## Step 7 - Setup Server Backups
|
## Step 7 - Setup Server Backups
|
||||||
|
|
||||||
<ServerBackup />
|
<ServerBackup />
|
||||||
|
|
||||||
## Setting up optional features
|
|
||||||
|
|
||||||
- [External Libraries](/docs/features/libraries.md): Adding your existing photo library to Immich
|
|
||||||
- [Hardware Transcoding](/docs/features/hardware-transcoding.md): Speeding up video transcoding
|
|
||||||
- [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md): Speeding up various machine learning tasks in Immich
|
|
||||||
|
|||||||
@@ -67,4 +67,10 @@ Click "**Edit Rules**" and add the following firewall rules:
|
|||||||
|
|
||||||
## Next Steps
|
## Next Steps
|
||||||
|
|
||||||
Read the [Post Installation](/docs/install/post-install.mdx) steps and [upgrade instructions](/docs/install/upgrading.md).
|
Read the [Post Installation](/docs/install/post-install.mdx) steps or setup optional features below.
|
||||||
|
|
||||||
|
### Setting up optional features
|
||||||
|
|
||||||
|
- [External Libraries](/docs/features/libraries.md): Adding your existing photo library to Immich
|
||||||
|
- [Hardware Transcoding](/docs/features/hardware-transcoding.md): Speeding up video transcoding
|
||||||
|
- [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md): Speeding up various machine learning tasks in Immich
|
||||||
|
|||||||
@@ -247,10 +247,6 @@ Some examples are: `IMMICH_VERSION`, `UPLOAD_LOCATION`, `DB_DATA_LOCATION`, `TZ`
|
|||||||
|
|
||||||
## Updating the App
|
## Updating the App
|
||||||
|
|
||||||
:::danger
|
|
||||||
Make sure to read the general [upgrade instructions](/docs/install/upgrading.md).
|
|
||||||
:::
|
|
||||||
|
|
||||||
When updates become available, SCALE alerts and provides easy updates.
|
When updates become available, SCALE alerts and provides easy updates.
|
||||||
To update the app to the latest version:
|
To update the app to the latest version:
|
||||||
|
|
||||||
|
|||||||
@@ -131,10 +131,6 @@ For more information on how to use the application once installed, please refer
|
|||||||
|
|
||||||
## Updating Steps
|
## Updating Steps
|
||||||
|
|
||||||
:::danger
|
|
||||||
Make sure to read the general [upgrade instructions](/docs/install/upgrading.md).
|
|
||||||
:::
|
|
||||||
|
|
||||||
Updating is extremely easy however it's important to be aware that containers managed via the Docker Compose Manager plugin do not integrate with Unraid's native dockerman UI, the label "_update ready_" will always be present on containers installed via the Docker Compose Manager.
|
Updating is extremely easy however it's important to be aware that containers managed via the Docker Compose Manager plugin do not integrate with Unraid's native dockerman UI, the label "_update ready_" will always be present on containers installed via the Docker Compose Manager.
|
||||||
|
|
||||||
<img
|
<img
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
---
|
|
||||||
sidebar_position: 95
|
|
||||||
---
|
|
||||||
|
|
||||||
# Upgrading
|
|
||||||
|
|
||||||
:::danger Read the release notes
|
|
||||||
Immich is currently under heavy development, which means you can expect [breaking changes][breaking] and bugs. You should read the release notes prior to updating and take special care when using automated tools like [Watchtower][watchtower].
|
|
||||||
|
|
||||||
You can see versions that had breaking changes [here][breaking].
|
|
||||||
:::
|
|
||||||
|
|
||||||
When a new version of Immich is [released][releases], you should read the release notes and account for any breaking changes noted (as mentioned above).
|
|
||||||
If you use `IMMICH_VERSION` in your `.env` file, it will need to be updated to the latest or desired version.
|
|
||||||
After that, the application can be upgraded and restarted with the following commands, run in the directory with the `docker-compose.yml` file:
|
|
||||||
|
|
||||||
```bash title="Upgrade and restart Immich"
|
|
||||||
docker compose pull && docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
To clean up disk space, the old version's obsolete container images can be deleted with the following command:
|
|
||||||
|
|
||||||
```bash title="Clean up unused Docker images"
|
|
||||||
docker image prune
|
|
||||||
```
|
|
||||||
|
|
||||||
[watchtower]: https://containrrr.dev/watchtower/
|
|
||||||
[breaking]: https://github.com/immich-app/immich/discussions?discussions_q=label%3Achangelog%3Abreaking-change+sort%3Adate_created
|
|
||||||
[releases]: https://github.com/immich-app/immich/releases
|
|
||||||
@@ -1,7 +1,2 @@
|
|||||||
Now that you have imported some pictures, you should setup server backups to preserve your memories.
|
Now that you have imported some pictures, you should setup server backups to preserve your memories.
|
||||||
You can do so by following our [backup guide](/docs/administration/backup-and-restore.md).
|
You can do so by following our [backup guide](/docs/administration/backup-and-restore.md).
|
||||||
|
|
||||||
:::danger
|
|
||||||
Immich is still under heavy development _and_ handles very important data.
|
|
||||||
It is essential that you set up good backups, and test them.
|
|
||||||
:::
|
|
||||||
|
|||||||
Generated
+12
-12
@@ -5308,9 +5308,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/autoprefixer": {
|
"node_modules/autoprefixer": {
|
||||||
"version": "10.4.21",
|
"version": "10.4.20",
|
||||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
|
||||||
"integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
|
"integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -5327,11 +5327,11 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"browserslist": "^4.24.4",
|
"browserslist": "^4.23.3",
|
||||||
"caniuse-lite": "^1.0.30001702",
|
"caniuse-lite": "^1.0.30001646",
|
||||||
"fraction.js": "^4.3.7",
|
"fraction.js": "^4.3.7",
|
||||||
"normalize-range": "^0.1.2",
|
"normalize-range": "^0.1.2",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.0.1",
|
||||||
"postcss-value-parser": "^4.2.0"
|
"postcss-value-parser": "^4.2.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -5781,9 +5781,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001706",
|
"version": "1.0.30001695",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001706.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001695.tgz",
|
||||||
"integrity": "sha512-3ZczoTApMAZwPKYWmwVbQMFpXBDds3/0VciVoUwPUbldlYyVLmRVuRs/PcUZtHpbLRpzzDvrvnFuREsGt6lUug==",
|
"integrity": "sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -15734,9 +15734,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "3.5.3",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz",
|
||||||
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
|
"integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
|
import { useColorMode } from '@docusaurus/theme-common';
|
||||||
import { discordPath, discordViewBox } from '@site/src/components/svg-paths';
|
import { discordPath, discordViewBox } from '@site/src/components/svg-paths';
|
||||||
import ThemedImage from '@theme/ThemedImage';
|
|
||||||
import Icon from '@mdi/react';
|
import Icon from '@mdi/react';
|
||||||
function HomepageHeader() {
|
function HomepageHeader() {
|
||||||
|
const { isDarkTheme } = useColorMode();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header>
|
<header>
|
||||||
<div className="top-[calc(12%)] md:top-[calc(30%)] h-screen w-full absolute -z-10">
|
<div className="top-[calc(12%)] md:top-[calc(30%)] h-screen w-full absolute -z-10">
|
||||||
@@ -12,8 +14,8 @@ function HomepageHeader() {
|
|||||||
<div className="w-full h-[120vh] absolute left-0 top-0 backdrop-blur-3xl bg-immich-bg/40 dark:bg-transparent"></div>
|
<div className="w-full h-[120vh] absolute left-0 top-0 backdrop-blur-3xl bg-immich-bg/40 dark:bg-transparent"></div>
|
||||||
</div>
|
</div>
|
||||||
<section className="text-center pt-12 sm:pt-24 bg-immich-bg/50 dark:bg-immich-dark-bg/80">
|
<section className="text-center pt-12 sm:pt-24 bg-immich-bg/50 dark:bg-immich-dark-bg/80">
|
||||||
<ThemedImage
|
<img
|
||||||
sources={{ dark: 'img/logomark-dark.svg', light: 'img/logomark-light.svg' }}
|
src={isDarkTheme ? 'img/logomark-dark.svg' : 'img/logomark-light.svg'}
|
||||||
className="h-[115px] w-[115px] mb-2 antialiased rounded-none"
|
className="h-[115px] w-[115px] mb-2 antialiased rounded-none"
|
||||||
alt="Immich logo"
|
alt="Immich logo"
|
||||||
/>
|
/>
|
||||||
@@ -33,6 +35,7 @@ function HomepageHeader() {
|
|||||||
sacrificing your privacy.
|
sacrificing your privacy.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col sm:flex-row place-items-center place-content-center mt-9 gap-4 ">
|
<div className="flex flex-col sm:flex-row place-items-center place-content-center mt-9 gap-4 ">
|
||||||
<Link
|
<Link
|
||||||
className="flex place-items-center place-content-center py-3 px-8 border bg-immich-primary dark:bg-immich-dark-primary rounded-xl no-underline hover:no-underline text-white hover:text-gray-50 dark:text-immich-dark-bg font-bold uppercase"
|
className="flex place-items-center place-content-center py-3 px-8 border bg-immich-primary dark:bg-immich-dark-primary rounded-xl no-underline hover:no-underline text-white hover:text-gray-50 dark:text-immich-dark-bg font-bold uppercase"
|
||||||
@@ -55,6 +58,7 @@ function HomepageHeader() {
|
|||||||
Buy Merch
|
Buy Merch
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="my-12 flex gap-1 font-medium place-items-center place-content-center text-immich-primary dark:text-immich-dark-primary">
|
<div className="my-12 flex gap-1 font-medium place-items-center place-content-center text-immich-primary dark:text-immich-dark-primary">
|
||||||
<Icon
|
<Icon
|
||||||
path={discordPath}
|
path={discordPath}
|
||||||
@@ -63,19 +67,22 @@ function HomepageHeader() {
|
|||||||
/>
|
/>
|
||||||
<Link to="https://discord.immich.app/">Join our Discord</Link>
|
<Link to="https://discord.immich.app/">Join our Discord</Link>
|
||||||
</div>
|
</div>
|
||||||
<ThemedImage
|
<img
|
||||||
sources={{ dark: '/img/screenshot-dark.webp', light: '/img/screenshot-light.webp' }}
|
src={isDarkTheme ? '/img/screenshot-dark.webp' : '/img/screenshot-light.webp'}
|
||||||
alt="screenshots"
|
alt="screenshots"
|
||||||
className="w-[95%] lg:w-[85%] xl:w-[70%] 2xl:w-[60%] "
|
className="w-[95%] lg:w-[85%] xl:w-[70%] 2xl:w-[60%] "
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="mx-[25%] m-auto my-14 md:my-28">
|
<div className="mx-[25%] m-auto my-14 md:my-28">
|
||||||
<hr className="border bg-gray-500 dark:bg-gray-400" />
|
<hr className="border bg-gray-500 dark:bg-gray-400" />
|
||||||
</div>
|
</div>
|
||||||
<ThemedImage
|
|
||||||
sources={{ dark: 'img/logomark-dark.svg', light: 'img/logomark-light.svg' }}
|
<img
|
||||||
|
src={isDarkTheme ? 'img/logomark-dark.svg' : 'img/logomark-light.svg'}
|
||||||
className="h-[115px] w-[115px] mb-2 antialiased rounded-none"
|
className="h-[115px] w-[115px] mb-2 antialiased rounded-none"
|
||||||
alt="Immich logo"
|
alt="Immich logo"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p className="font-bold text-2xl md:text-5xl ">Download the mobile app</p>
|
<p className="font-bold text-2xl md:text-5xl ">Download the mobile app</p>
|
||||||
<p className="text-lg">
|
<p className="text-lg">
|
||||||
@@ -94,8 +101,9 @@ function HomepageHeader() {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ThemedImage
|
|
||||||
sources={{ dark: '/img/app-qr-code-dark.svg', light: '/img/app-qr-code-light.svg' }}
|
<img
|
||||||
|
src={isDarkTheme ? '/img/app-qr-code-dark.svg' : '/img/app-qr-code-light.svg'}
|
||||||
alt="app qr code"
|
alt="app qr code"
|
||||||
width={'150px'}
|
width={'150px'}
|
||||||
className="shadow-lg p-3 my-8 dark:bg-immich-dark-bg "
|
className="shadow-lg p-3 my-8 dark:bg-immich-dark-bg "
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
|
import { useColorMode } from '@docusaurus/theme-common';
|
||||||
function HomepageHeader() {
|
function HomepageHeader() {
|
||||||
|
const { isDarkTheme } = useColorMode();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header>
|
<header>
|
||||||
<section className="max-w-[900px] m-4 p-4 md:p-6 md:m-auto md:my-12 border border-red-400 rounded-2xl bg-slate-200 dark:bg-immich-dark-gray">
|
<section className="max-w-[900px] m-4 p-4 md:p-6 md:m-auto md:my-12 border border-red-400 rounded-2xl bg-slate-200 dark:bg-immich-dark-gray">
|
||||||
|
|||||||
Vendored
-32
@@ -1,36 +1,4 @@
|
|||||||
[
|
[
|
||||||
{
|
|
||||||
"label": "v1.131.3",
|
|
||||||
"url": "https://v1.131.3.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.131.2",
|
|
||||||
"url": "https://v1.131.2.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.131.1",
|
|
||||||
"url": "https://v1.131.1.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.131.0",
|
|
||||||
"url": "https://v1.131.0.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.130.3",
|
|
||||||
"url": "https://v1.130.3.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.130.2",
|
|
||||||
"url": "https://v1.130.2.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.130.1",
|
|
||||||
"url": "https://v1.130.1.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "v1.130.0",
|
|
||||||
"url": "https://v1.130.0.archive.immich.app"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"label": "v1.129.0",
|
"label": "v1.129.0",
|
||||||
"url": "https://v1.129.0.archive.immich.app"
|
"url": "https://v1.129.0.archive.immich.app"
|
||||||
|
|||||||
+20
-10
@@ -1,29 +1,39 @@
|
|||||||
|
import { FlatCompat } from '@eslint/eslintrc';
|
||||||
import js from '@eslint/js';
|
import js from '@eslint/js';
|
||||||
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
import typescriptEslint from '@typescript-eslint/eslint-plugin';
|
||||||
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
|
import tsParser from '@typescript-eslint/parser';
|
||||||
import globals from 'globals';
|
import globals from 'globals';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import typescriptEslint from 'typescript-eslint';
|
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
baseDirectory: __dirname,
|
||||||
|
recommendedConfig: js.configs.recommended,
|
||||||
|
allConfig: js.configs.all,
|
||||||
|
});
|
||||||
|
|
||||||
export default typescriptEslint.config([
|
export default [
|
||||||
eslintPluginUnicorn.configs.recommended,
|
|
||||||
eslintPluginPrettierRecommended,
|
|
||||||
js.configs.recommended,
|
|
||||||
typescriptEslint.configs.recommended,
|
|
||||||
{
|
{
|
||||||
ignores: ['eslint.config.mjs'],
|
ignores: ['eslint.config.mjs'],
|
||||||
},
|
},
|
||||||
|
...compat.extends(
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
'plugin:unicorn/recommended',
|
||||||
|
),
|
||||||
{
|
{
|
||||||
|
plugins: {
|
||||||
|
'@typescript-eslint': typescriptEslint,
|
||||||
|
},
|
||||||
|
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
globals: {
|
globals: {
|
||||||
...globals.node,
|
...globals.node,
|
||||||
},
|
},
|
||||||
|
|
||||||
parser: typescriptEslint.parser,
|
parser: tsParser,
|
||||||
ecmaVersion: 5,
|
ecmaVersion: 5,
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
|
|
||||||
@@ -52,4 +62,4 @@ export default typescriptEslint.config([
|
|||||||
'object-shorthand': ['error', 'always'],
|
'object-shorthand': ['error', 'always'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
];
|
||||||
|
|||||||
Generated
+835
-667
File diff suppressed because it is too large
Load Diff
+5
-4
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "immich-e2e",
|
"name": "immich-e2e",
|
||||||
"version": "1.131.3",
|
"version": "1.129.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -25,16 +25,18 @@
|
|||||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||||
"@playwright/test": "^1.44.1",
|
"@playwright/test": "^1.44.1",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
"@types/node": "^22.14.0",
|
"@types/node": "^22.13.9",
|
||||||
"@types/oidc-provider": "^8.5.1",
|
"@types/oidc-provider": "^8.5.1",
|
||||||
"@types/pg": "^8.11.0",
|
"@types/pg": "^8.11.0",
|
||||||
"@types/pngjs": "^6.0.4",
|
"@types/pngjs": "^6.0.4",
|
||||||
"@types/supertest": "^6.0.2",
|
"@types/supertest": "^6.0.2",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
||||||
|
"@typescript-eslint/parser": "^8.15.0",
|
||||||
"@vitest/coverage-v8": "^3.0.0",
|
"@vitest/coverage-v8": "^3.0.0",
|
||||||
"eslint": "^9.14.0",
|
"eslint": "^9.14.0",
|
||||||
"eslint-config-prettier": "^10.0.0",
|
"eslint-config-prettier": "^10.0.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"eslint-plugin-unicorn": "^57.0.0",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
"exiftool-vendored": "^28.3.1",
|
"exiftool-vendored": "^28.3.1",
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
"jose": "^5.6.3",
|
"jose": "^5.6.3",
|
||||||
@@ -47,7 +49,6 @@
|
|||||||
"socket.io-client": "^4.7.4",
|
"socket.io-client": "^4.7.4",
|
||||||
"supertest": "^7.0.0",
|
"supertest": "^7.0.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"typescript-eslint": "^8.28.0",
|
|
||||||
"utimes": "^5.2.1",
|
"utimes": "^5.2.1",
|
||||||
"vitest": "^3.0.0"
|
"vitest": "^3.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1141,7 +1141,7 @@ describe('/asset', () => {
|
|||||||
fNumber: 8,
|
fNumber: 8,
|
||||||
focalLength: 97,
|
focalLength: 97,
|
||||||
iso: 100,
|
iso: 100,
|
||||||
lensModel: 'Sony E PZ 18-105mm F4 G OSS',
|
lensModel: 'E PZ 18-105mm F4 G OSS',
|
||||||
fileSizeInByte: 25_001_984,
|
fileSizeInByte: 25_001_984,
|
||||||
dateTimeOriginal: '2016-09-27T10:51:44+00:00',
|
dateTimeOriginal: '2016-09-27T10:51:44+00:00',
|
||||||
orientation: '1',
|
orientation: '1',
|
||||||
@@ -1163,7 +1163,7 @@ describe('/asset', () => {
|
|||||||
fNumber: 22,
|
fNumber: 22,
|
||||||
focalLength: 25,
|
focalLength: 25,
|
||||||
iso: 100,
|
iso: 100,
|
||||||
lensModel: 'Zeiss Batis 25mm F2',
|
lensModel: 'E 25mm F2',
|
||||||
fileSizeInByte: 49_512_448,
|
fileSizeInByte: 49_512_448,
|
||||||
dateTimeOriginal: '2016-01-08T14:08:01+00:00',
|
dateTimeOriginal: '2016-01-08T14:08:01+00:00',
|
||||||
orientation: '1',
|
orientation: '1',
|
||||||
@@ -1234,7 +1234,7 @@ describe('/asset', () => {
|
|||||||
focalLength: 18.3,
|
focalLength: 18.3,
|
||||||
iso: 100,
|
iso: 100,
|
||||||
latitude: 36.613_24,
|
latitude: 36.613_24,
|
||||||
lensModel: '18.3mm F2.8',
|
lensModel: 'GR LENS 18.3mm F2.8',
|
||||||
longitude: -121.897_85,
|
longitude: -121.897_85,
|
||||||
make: 'RICOH IMAGING COMPANY, LTD.',
|
make: 'RICOH IMAGING COMPANY, LTD.',
|
||||||
model: 'RICOH GR III',
|
model: 'RICOH GR III',
|
||||||
@@ -1257,7 +1257,6 @@ describe('/asset', () => {
|
|||||||
|
|
||||||
for (const { id, status } of assets) {
|
for (const { id, status } of assets) {
|
||||||
expect(status).toBe(AssetMediaStatus.Created);
|
expect(status).toBe(AssetMediaStatus.Created);
|
||||||
// longer timeout as the thumbnail generation from full-size raw files can take a while
|
|
||||||
await utils.waitForWebsocketEvent({ event: 'assetUpload', id });
|
await utils.waitForWebsocketEvent({ event: 'assetUpload', id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ describe('/libraries', () => {
|
|||||||
const library = await utils.createLibrary(admin.accessToken, {
|
const library = await utils.createLibrary(admin.accessToken, {
|
||||||
ownerId: admin.userId,
|
ownerId: admin.userId,
|
||||||
importPaths: [`${testAssetDirInternal}/temp`],
|
importPaths: [`${testAssetDirInternal}/temp`],
|
||||||
exclusionPatterns: ['**/directoryA/**'],
|
exclusionPatterns: ['**/directoryA'],
|
||||||
});
|
});
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
await utils.scan(admin.accessToken, library.id);
|
||||||
@@ -337,82 +337,7 @@ describe('/libraries', () => {
|
|||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
||||||
|
|
||||||
expect(assets.count).toBe(1);
|
expect(assets.count).toBe(1);
|
||||||
|
expect(assets.items[0].originalPath.includes('directoryB'));
|
||||||
expect(assets.items).toEqual(
|
|
||||||
expect.arrayContaining([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining('directoryB/assetB.png') }),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scan external library with multiple exclusion patterns', async () => {
|
|
||||||
const library = await utils.createLibrary(admin.accessToken, {
|
|
||||||
ownerId: admin.userId,
|
|
||||||
importPaths: [`${testAssetDirInternal}/temp`],
|
|
||||||
exclusionPatterns: ['**/directoryA/**', '**/directoryB/**'],
|
|
||||||
});
|
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.count).toBe(0);
|
|
||||||
|
|
||||||
expect(assets.items).toEqual([]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove assets covered by a new exclusion pattern', async () => {
|
|
||||||
const library = await utils.createLibrary(admin.accessToken, {
|
|
||||||
ownerId: admin.userId,
|
|
||||||
importPaths: [`${testAssetDirInternal}/temp`],
|
|
||||||
});
|
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.count).toBe(2);
|
|
||||||
|
|
||||||
expect(assets.items).toEqual(
|
|
||||||
expect.arrayContaining([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining('directoryA/assetA.png') }),
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining('directoryB/assetB.png') }),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await utils.updateLibrary(admin.accessToken, library.id, {
|
|
||||||
exclusionPatterns: ['**/directoryA/**'],
|
|
||||||
});
|
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.count).toBe(1);
|
|
||||||
|
|
||||||
expect(assets.items).toEqual(
|
|
||||||
expect.arrayContaining([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining('directoryB/assetB.png') }),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await utils.updateLibrary(admin.accessToken, library.id, {
|
|
||||||
exclusionPatterns: ['**/directoryA/**', '**/directoryB/**'],
|
|
||||||
});
|
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.count).toBe(0);
|
|
||||||
|
|
||||||
expect(assets.items).toEqual([]);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should scan multiple import paths', async () => {
|
it('should scan multiple import paths', async () => {
|
||||||
@@ -529,133 +454,6 @@ describe('/libraries', () => {
|
|||||||
utils.removeImageFile(`${testAssetDir}/temp/folder${char}2/asset2.png`);
|
utils.removeImageFile(`${testAssetDir}/temp/folder${char}2/asset2.png`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should respect exclusion patterns when using multiple import paths', async () => {
|
|
||||||
// https://github.com/immich-app/immich/issues/17121
|
|
||||||
const library = await utils.createLibrary(admin.accessToken, {
|
|
||||||
ownerId: admin.userId,
|
|
||||||
importPaths: [`${testAssetDirInternal}/temp/exclusion/`, `${testAssetDirInternal}/temp/exclusion2/`],
|
|
||||||
});
|
|
||||||
|
|
||||||
const excludedFolder = `Raw`;
|
|
||||||
|
|
||||||
utils.createImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
|
|
||||||
utils.createImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
|
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.items).toEqual(
|
|
||||||
expect.arrayContaining([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.items).toEqual(
|
|
||||||
expect.arrayContaining([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await utils.updateLibrary(admin.accessToken, library.id, { exclusionPatterns: [`**/${excludedFolder}/**`] });
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.items).toEqual([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.items).toEqual([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.removeImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
|
|
||||||
utils.removeImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
|
|
||||||
});
|
|
||||||
|
|
||||||
const annoyingExclusionPatterns = ['@', '#', '$', '%', '^', '&', '='];
|
|
||||||
|
|
||||||
it.each(annoyingExclusionPatterns)('should support exclusion patterns with %s', async (char) => {
|
|
||||||
const library = await utils.createLibrary(admin.accessToken, {
|
|
||||||
ownerId: admin.userId,
|
|
||||||
importPaths: [`${testAssetDirInternal}/temp/exclusion/`],
|
|
||||||
});
|
|
||||||
|
|
||||||
const excludedFolder = `${char}folder`;
|
|
||||||
|
|
||||||
utils.createImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
|
|
||||||
utils.createImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
|
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.items).toEqual(
|
|
||||||
expect.arrayContaining([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.items).toEqual(
|
|
||||||
expect.arrayContaining([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`${excludedFolder}/asset2.png`) }),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await utils.updateLibrary(admin.accessToken, library.id, { exclusionPatterns: [`**/${excludedFolder}/**`] });
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.items).toEqual([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
await utils.scan(admin.accessToken, library.id);
|
|
||||||
|
|
||||||
{
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, { libraryId: library.id });
|
|
||||||
|
|
||||||
expect(assets.items).toEqual([
|
|
||||||
expect.objectContaining({ originalPath: expect.stringContaining(`/asset1.png`) }),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.removeImageFile(`${testAssetDir}/temp/exclusion/asset1.png`);
|
|
||||||
utils.removeImageFile(`${testAssetDir}/temp/exclusion/${excludedFolder}/asset2.png`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should reimport a modified file', async () => {
|
it('should reimport a modified file', async () => {
|
||||||
const library = await utils.createLibrary(admin.accessToken, {
|
const library = await utils.createLibrary(admin.accessToken, {
|
||||||
ownerId: admin.userId,
|
ownerId: admin.userId,
|
||||||
|
|||||||
@@ -633,6 +633,7 @@ describe('/search', () => {
|
|||||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||||
expect(body).toEqual([
|
expect(body).toEqual([
|
||||||
'Andalusia',
|
'Andalusia',
|
||||||
|
'Berlin',
|
||||||
'Glarus',
|
'Glarus',
|
||||||
'Greater Accra',
|
'Greater Accra',
|
||||||
'Havana',
|
'Havana',
|
||||||
@@ -641,7 +642,6 @@ describe('/search', () => {
|
|||||||
'Mississippi',
|
'Mississippi',
|
||||||
'New York',
|
'New York',
|
||||||
'Shanghai',
|
'Shanghai',
|
||||||
'State of Berlin',
|
|
||||||
'St.-Petersburg',
|
'St.-Petersburg',
|
||||||
'Tbilisi',
|
'Tbilisi',
|
||||||
'Tokyo',
|
'Tokyo',
|
||||||
@@ -657,6 +657,7 @@ describe('/search', () => {
|
|||||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||||
expect(body).toEqual([
|
expect(body).toEqual([
|
||||||
'Andalusia',
|
'Andalusia',
|
||||||
|
'Berlin',
|
||||||
'Glarus',
|
'Glarus',
|
||||||
'Greater Accra',
|
'Greater Accra',
|
||||||
'Havana',
|
'Havana',
|
||||||
@@ -665,7 +666,6 @@ describe('/search', () => {
|
|||||||
'Mississippi',
|
'Mississippi',
|
||||||
'New York',
|
'New York',
|
||||||
'Shanghai',
|
'Shanghai',
|
||||||
'State of Berlin',
|
|
||||||
'St.-Petersburg',
|
'St.-Petersburg',
|
||||||
'Tbilisi',
|
'Tbilisi',
|
||||||
'Tokyo',
|
'Tokyo',
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ describe('/shared-links', () => {
|
|||||||
const resp = await request(shareUrl).get(`/${linkWithAssets.key}`);
|
const resp = await request(shareUrl).get(`/${linkWithAssets.key}`);
|
||||||
expect(resp.status).toBe(200);
|
expect(resp.status).toBe(200);
|
||||||
expect(resp.header['content-type']).toContain('text/html');
|
expect(resp.header['content-type']).toContain('text/html');
|
||||||
expect(resp.text).toContain(`<meta property="og:image" content="https://my.immich.app`);
|
expect(resp.text).toContain(`<meta property="og:image" content="http://`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -246,7 +246,15 @@ describe('/shared-links', () => {
|
|||||||
const { status, body } = await request(app).get('/shared-links/me').query({ key: linkWithMetadata.key });
|
const { status, body } = await request(app).get('/shared-links/me').query({ key: linkWithMetadata.key });
|
||||||
|
|
||||||
expect(status).toBe(200);
|
expect(status).toBe(200);
|
||||||
expect(body.assets).toHaveLength(0);
|
expect(body.assets).toHaveLength(1);
|
||||||
|
expect(body.assets[0]).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
originalFileName: 'example.png',
|
||||||
|
localDateTime: expect.any(String),
|
||||||
|
fileCreatedAt: expect.any(String),
|
||||||
|
exifInfo: expect.any(Object),
|
||||||
|
}),
|
||||||
|
);
|
||||||
expect(body.album).toBeDefined();
|
expect(body.album).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const tests: Test[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: 'should support paths with an asterisk',
|
test: 'should support paths with an asterisk',
|
||||||
paths: [`/photos*/image1.jpg`],
|
paths: [`/photos\*/image1.jpg`],
|
||||||
files: {
|
files: {
|
||||||
'/photos*/image1.jpg': true,
|
'/photos*/image1.jpg': true,
|
||||||
'/photos*/image2.jpg': false,
|
'/photos*/image2.jpg': false,
|
||||||
@@ -40,7 +40,7 @@ const tests: Test[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: 'should support paths with a single quote',
|
test: 'should support paths with a single quote',
|
||||||
paths: [`/photos'/image1.jpg`],
|
paths: [`/photos\'/image1.jpg`],
|
||||||
files: {
|
files: {
|
||||||
"/photos'/image1.jpg": true,
|
"/photos'/image1.jpg": true,
|
||||||
"/photos'/image2.jpg": false,
|
"/photos'/image2.jpg": false,
|
||||||
@@ -49,7 +49,7 @@ const tests: Test[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: 'should support paths with a double quote',
|
test: 'should support paths with a double quote',
|
||||||
paths: [`/photos"/image1.jpg`],
|
paths: [`/photos\"/image1.jpg`],
|
||||||
files: {
|
files: {
|
||||||
'/photos"/image1.jpg': true,
|
'/photos"/image1.jpg': true,
|
||||||
'/photos"/image2.jpg': false,
|
'/photos"/image2.jpg': false,
|
||||||
@@ -67,7 +67,7 @@ const tests: Test[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: 'should support paths with an opening brace',
|
test: 'should support paths with an opening brace',
|
||||||
paths: [`/photos{/image1.jpg`],
|
paths: [`/photos\{/image1.jpg`],
|
||||||
files: {
|
files: {
|
||||||
'/photos{/image1.jpg': true,
|
'/photos{/image1.jpg': true,
|
||||||
'/photos{/image2.jpg': false,
|
'/photos{/image2.jpg': false,
|
||||||
@@ -76,7 +76,7 @@ const tests: Test[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: 'should support paths with a closing brace',
|
test: 'should support paths with a closing brace',
|
||||||
paths: [`/photos}/image1.jpg`],
|
paths: [`/photos\}/image1.jpg`],
|
||||||
files: {
|
files: {
|
||||||
'/photos}/image1.jpg': true,
|
'/photos}/image1.jpg': true,
|
||||||
'/photos}/image2.jpg': false,
|
'/photos}/image2.jpg': false,
|
||||||
|
|||||||
+3
-4
@@ -493,7 +493,7 @@ export const utils = {
|
|||||||
value: accessToken,
|
value: accessToken,
|
||||||
domain,
|
domain,
|
||||||
path: '/',
|
path: '/',
|
||||||
expires: 2_058_028_213,
|
expires: 1_742_402_728,
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: false,
|
secure: false,
|
||||||
sameSite: 'Lax',
|
sameSite: 'Lax',
|
||||||
@@ -503,7 +503,7 @@ export const utils = {
|
|||||||
value: 'password',
|
value: 'password',
|
||||||
domain,
|
domain,
|
||||||
path: '/',
|
path: '/',
|
||||||
expires: 2_058_028_213,
|
expires: 1_742_402_728,
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
secure: false,
|
secure: false,
|
||||||
sameSite: 'Lax',
|
sameSite: 'Lax',
|
||||||
@@ -513,7 +513,7 @@ export const utils = {
|
|||||||
value: 'true',
|
value: 'true',
|
||||||
domain,
|
domain,
|
||||||
path: '/',
|
path: '/',
|
||||||
expires: 2_058_028_213,
|
expires: 1_742_402_728,
|
||||||
httpOnly: false,
|
httpOnly: false,
|
||||||
secure: false,
|
secure: false,
|
||||||
sameSite: 'Lax',
|
sameSite: 'Lax',
|
||||||
@@ -537,7 +537,6 @@ export const utils = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
waitForQueueFinish: (accessToken: string, queue: keyof AllJobStatusResponseDto, ms?: number) => {
|
waitForQueueFinish: (accessToken: string, queue: keyof AllJobStatusResponseDto, ms?: number) => {
|
||||||
// eslint-disable-next-line no-async-promise-executor
|
|
||||||
return new Promise<void>(async (resolve, reject) => {
|
return new Promise<void>(async (resolve, reject) => {
|
||||||
const timeout = setTimeout(() => reject(new Error('Timed out waiting for queue to empty')), ms || 10_000);
|
const timeout = setTimeout(() => reject(new Error('Timed out waiting for queue to empty')), ms || 10_000);
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,12 @@ function imageLocator(page: Page) {
|
|||||||
test.describe('Photo Viewer', () => {
|
test.describe('Photo Viewer', () => {
|
||||||
let admin: LoginResponseDto;
|
let admin: LoginResponseDto;
|
||||||
let asset: AssetMediaResponseDto;
|
let asset: AssetMediaResponseDto;
|
||||||
let rawAsset: AssetMediaResponseDto;
|
|
||||||
|
|
||||||
test.beforeAll(async () => {
|
test.beforeAll(async () => {
|
||||||
utils.initSdk();
|
utils.initSdk();
|
||||||
await utils.resetDatabase();
|
await utils.resetDatabase();
|
||||||
admin = await utils.adminSetup();
|
admin = await utils.adminSetup();
|
||||||
asset = await utils.createAsset(admin.accessToken);
|
asset = await utils.createAsset(admin.accessToken);
|
||||||
rawAsset = await utils.createAsset(admin.accessToken, { assetData: { filename: 'test.arw' } });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test.beforeEach(async ({ context, page }) => {
|
test.beforeEach(async ({ context, page }) => {
|
||||||
@@ -38,7 +36,7 @@ test.describe('Photo Viewer', () => {
|
|||||||
await expect(page.getByTestId('loading-spinner')).toBeVisible();
|
await expect(page.getByTestId('loading-spinner')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('loads original photo when zoomed', async ({ page }) => {
|
test('loads high resolution photo when zoomed', async ({ page }) => {
|
||||||
await page.goto(`/photos/${asset.id}`);
|
await page.goto(`/photos/${asset.id}`);
|
||||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('thumbnail');
|
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('thumbnail');
|
||||||
const box = await imageLocator(page).boundingBox();
|
const box = await imageLocator(page).boundingBox();
|
||||||
@@ -49,17 +47,6 @@ test.describe('Photo Viewer', () => {
|
|||||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('original');
|
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('original');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('loads fullsize image when zoomed and original is web-incompatible', async ({ page }) => {
|
|
||||||
await page.goto(`/photos/${rawAsset.id}`);
|
|
||||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('thumbnail');
|
|
||||||
const box = await imageLocator(page).boundingBox();
|
|
||||||
expect(box).toBeTruthy();
|
|
||||||
const { x, y, width, height } = box!;
|
|
||||||
await page.mouse.move(x + width / 2, y + height / 2);
|
|
||||||
await page.mouse.wheel(0, -1);
|
|
||||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('fullsize');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('reloads photo when checksum changes', async ({ page }) => {
|
test('reloads photo when checksum changes', async ({ page }) => {
|
||||||
await page.goto(`/photos/${asset.id}`);
|
await page.goto(`/photos/${asset.id}`);
|
||||||
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('thumbnail');
|
await expect.poll(async () => await imageLocator(page).getAttribute('src')).toContain('thumbnail');
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ test.describe('Shared Links', () => {
|
|||||||
await page.goto(`/share/${sharedLink.key}`);
|
await page.goto(`/share/${sharedLink.key}`);
|
||||||
await page.getByRole('heading', { name: 'Test Album' }).waitFor();
|
await page.getByRole('heading', { name: 'Test Album' }).waitFor();
|
||||||
await page.locator(`[data-asset-id="${asset.id}"]`).hover();
|
await page.locator(`[data-asset-id="${asset.id}"]`).hover();
|
||||||
await page.waitForSelector('[data-group] svg');
|
await page.waitForSelector('#asset-group-by-date svg');
|
||||||
await page.getByRole('checkbox').click();
|
await page.getByRole('checkbox').click();
|
||||||
await page.getByRole('button', { name: 'Download' }).click();
|
await page.getByRole('button', { name: 'Download' }).click();
|
||||||
await page.waitForEvent('download');
|
await page.getByText('DOWNLOADING', { exact: true }).waitFor();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('download all from shared link', async ({ page }) => {
|
test('download all from shared link', async ({ page }) => {
|
||||||
@@ -56,7 +56,6 @@ test.describe('Shared Links', () => {
|
|||||||
await page.getByRole('heading', { name: 'Test Album' }).waitFor();
|
await page.getByRole('heading', { name: 'Test Album' }).waitFor();
|
||||||
await page.getByRole('button', { name: 'Download' }).click();
|
await page.getByRole('button', { name: 'Download' }).click();
|
||||||
await page.getByText('DOWNLOADING', { exact: true }).waitFor();
|
await page.getByText('DOWNLOADING', { exact: true }).waitFor();
|
||||||
await page.waitForEvent('download');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('enter password for a shared link', async ({ page }) => {
|
test('enter password for a shared link', async ({ page }) => {
|
||||||
|
|||||||
+4
-12
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"about": "Oor",
|
"about": "Verfris",
|
||||||
"account": "Rekening",
|
"account": "Rekening",
|
||||||
"account_settings": "Rekeninginstellings",
|
"account_settings": "Rekeninginstellings",
|
||||||
"acknowledge": "Erken",
|
"acknowledge": "Erken",
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
"duplicate_detection_job_description": "Begin masjienleer op bates om soortgelyke beelde op te spoor. Maak staat op Smart Search",
|
"duplicate_detection_job_description": "Begin masjienleer op bates om soortgelyke beelde op te spoor. Maak staat op Smart Search",
|
||||||
"exclusion_pattern_description": "Met uitsluitingspatrone kan jy lêers en vouers ignoreer wanneer jy jou biblioteek skandeer. Dit is nuttig as jy vouers het wat lêers bevat wat jy nie wil invoer nie, soos RAW-lêers.",
|
"exclusion_pattern_description": "Met uitsluitingspatrone kan jy lêers en vouers ignoreer wanneer jy jou biblioteek skandeer. Dit is nuttig as jy vouers het wat lêers bevat wat jy nie wil invoer nie, soos RAW-lêers.",
|
||||||
"external_library_created_at": "Eksterne biblioteek (geskep op {date})",
|
"external_library_created_at": "Eksterne biblioteek (geskep op {date})",
|
||||||
"external_library_management": "Eksterne Biblioteekbestuur",
|
"external_library_management": "Eksterne Biblioteek-opsies",
|
||||||
"face_detection": "Gesig deteksie",
|
"face_detection": "Gesig deteksie",
|
||||||
"failed_job_command": "Opdrag {command} het misluk vir werk: {job}",
|
"failed_job_command": "Opdrag {command} het misluk vir werk: {job}",
|
||||||
"force_delete_user_warning": "WAARSKUWING: Dit sal onmiddellik die gebruiker en alle bates verwyder. Dit kan nie ontdoen word nie en die lêers kan nie herstel word nie.",
|
"force_delete_user_warning": "WAARSKUWING: Dit sal onmiddellik die gebruiker en alle bates verwyder. Dit kan nie ontdoen word nie en die lêers kan nie herstel word nie.",
|
||||||
@@ -64,8 +64,7 @@
|
|||||||
"image_format": "Formaat",
|
"image_format": "Formaat",
|
||||||
"image_format_description": "WebP produseer kleiner lêers as JPEG, maar is stadiger om te enkodeer.",
|
"image_format_description": "WebP produseer kleiner lêers as JPEG, maar is stadiger om te enkodeer.",
|
||||||
"image_prefer_embedded_preview": "Verkies ingebedde voorskou",
|
"image_prefer_embedded_preview": "Verkies ingebedde voorskou",
|
||||||
"image_prefer_wide_gamut": "Verkies wide gamut",
|
"image_prefer_wide_gamut": "Verkies wye spektrum",
|
||||||
"image_prefer_wide_gamut_setting_description": "Gebruik Display P3 vir kleinkiekies. Dit behou die lewendheid van beelde met wye kleurruimtes beter, maar beelde kan anders verskyn op ou apparate met 'n ou blaaierweergawe. sRGB-beelde gebruik steeds sRGB om kleurverskuiwings te voorkom.",
|
|
||||||
"image_preview_description": "Mediumgrootte prent met gestroopte metadata, wat gebruik word wanneer 'n enkele bate bekyk word en vir masjienleer",
|
"image_preview_description": "Mediumgrootte prent met gestroopte metadata, wat gebruik word wanneer 'n enkele bate bekyk word en vir masjienleer",
|
||||||
"image_preview_quality_description": "Voorskou kwaliteit van 1-100. Hoër is beter, maar produseer groter lêers en kan app-reaksie verminder. Die stel van 'n lae waarde kan masjienleerkwaliteit beïnvloed.",
|
"image_preview_quality_description": "Voorskou kwaliteit van 1-100. Hoër is beter, maar produseer groter lêers en kan app-reaksie verminder. Die stel van 'n lae waarde kan masjienleerkwaliteit beïnvloed.",
|
||||||
"image_preview_title": "Voorskou Instellings",
|
"image_preview_title": "Voorskou Instellings",
|
||||||
@@ -73,14 +72,7 @@
|
|||||||
"image_resolution": "Resolusie",
|
"image_resolution": "Resolusie",
|
||||||
"image_resolution_description": "Hoër resolusies kan meer detail bewaar, maar neem langer om te enkodeer, het groter lêergroottes en kan app-reaksie verminder.",
|
"image_resolution_description": "Hoër resolusies kan meer detail bewaar, maar neem langer om te enkodeer, het groter lêergroottes en kan app-reaksie verminder.",
|
||||||
"image_settings": "Prent Instellings",
|
"image_settings": "Prent Instellings",
|
||||||
"image_settings_description": "Bestuur die kwaliteit en resolusie van gegenereerde beelde",
|
"image_settings_description": "Bestuur die kwaliteit en resolusie van gegenereerde beelde"
|
||||||
"image_thumbnail_description": "Klein kleinkiekies sonder metadata, gebruik om groepe foto's soos die tydlyn te bekyk",
|
|
||||||
"image_thumbnail_quality_description": "Kleinkiekiekwaliteit van 1-100. Hoër is beter, maar produseer groter lêers en kan die toepassing vertraag.",
|
|
||||||
"image_thumbnail_title": "Kleinkiekie-instellings",
|
|
||||||
"job_concurrency": "{job} gelyktydigheid",
|
|
||||||
"job_created": "Taak gemaak",
|
|
||||||
"job_not_concurrency_safe": "Hierdie taak kan nie gelyktydig uitgevoer word nie.",
|
|
||||||
"job_settings": "Agtergrondtaakinstellings"
|
|
||||||
},
|
},
|
||||||
"search_by_description": "Soek by beskrywing",
|
"search_by_description": "Soek by beskrywing",
|
||||||
"search_by_description_example": "Stapdag in Sapa"
|
"search_by_description_example": "Stapdag in Sapa"
|
||||||
|
|||||||
-785
File diff suppressed because it is too large
Load Diff
+14
-16
@@ -1,22 +1,20 @@
|
|||||||
{
|
{
|
||||||
"about": "abaot",
|
"account": "",
|
||||||
"account": "Akaont",
|
"account_settings": "",
|
||||||
"account_settings": "Seting blo Akaont",
|
"acknowledge": "",
|
||||||
"acknowledge": "Akcept",
|
|
||||||
"action": "",
|
"action": "",
|
||||||
"actions": "",
|
"actions": "",
|
||||||
"active": "Stap Mekem",
|
"active": "",
|
||||||
"activity": "Wanem hemi Mekem",
|
"activity": "",
|
||||||
"activity_changed": "WAnem hemi Mekem hemi",
|
"add": "",
|
||||||
"add": "Ad",
|
"add_a_description": "",
|
||||||
"add_a_description": "Putem Description blo hem",
|
"add_a_location": "",
|
||||||
"add_a_location": "Putem place blo hem",
|
"add_a_name": "",
|
||||||
"add_a_name": "Putem nam blo hem",
|
"add_a_title": "",
|
||||||
"add_a_title": "Putem wan name blo hem",
|
"add_exclusion_pattern": "",
|
||||||
"add_exclusion_pattern": "Putem wan paten wae hemi karem aot",
|
"add_import_path": "",
|
||||||
"add_import_path": "Putem wan pat blo import",
|
"add_location": "",
|
||||||
"add_location": "Putem wan place blo hem",
|
"add_more_users": "",
|
||||||
"add_more_users": "Putem mor man",
|
|
||||||
"add_partner": "",
|
"add_partner": "",
|
||||||
"add_path": "",
|
"add_path": "",
|
||||||
"add_photos": "",
|
"add_photos": "",
|
||||||
|
|||||||
-782
File diff suppressed because it is too large
Load Diff
+2
-792
File diff suppressed because it is too large
Load Diff
+3
-792
File diff suppressed because it is too large
Load Diff
-790
File diff suppressed because it is too large
Load Diff
+3
-793
File diff suppressed because it is too large
Load Diff
+12
-805
File diff suppressed because it is too large
Load Diff
+5
-795
File diff suppressed because it is too large
Load Diff
@@ -66,11 +66,6 @@
|
|||||||
"forcing_refresh_library_files": "Kogu kõigi failide sundvärskendamine",
|
"forcing_refresh_library_files": "Kogu kõigi failide sundvärskendamine",
|
||||||
"image_format": "Formaat",
|
"image_format": "Formaat",
|
||||||
"image_format_description": "WebP failid on väiksemad kui JPEG, aga kodeerimine on aeglasem.",
|
"image_format_description": "WebP failid on väiksemad kui JPEG, aga kodeerimine on aeglasem.",
|
||||||
"image_fullsize_description": "Täismõõdus pilt ilma metaandmeteta, kasutatakse sisse suumimisel",
|
|
||||||
"image_fullsize_enabled": "Luba täismõõdus piltide genereerimine",
|
|
||||||
"image_fullsize_enabled_description": "Genereeri mitte-veebisõbralike formaatide jaoks täismõõdus pilt. Kui \"Eelista manustatud eelvaadet\" on lubatud, kasutatakse manustatud eelvaateid otse ilma teisendamiseta. Ei mõjuta veebisõbralikke formaate nagu JPEG.",
|
|
||||||
"image_fullsize_quality_description": "Täismõõdus pildi kvaliteet vahemikus 1-100. Kõrgem väärtus on parem, aga tulemuseks on suuremad failid.",
|
|
||||||
"image_fullsize_title": "Täismõõdus pildi seaded",
|
|
||||||
"image_prefer_embedded_preview": "Eelista manustatud eelvaadet",
|
"image_prefer_embedded_preview": "Eelista manustatud eelvaadet",
|
||||||
"image_prefer_embedded_preview_setting_description": "Kasuta pilditöötluse sisendina võimalusel RAW fotodesse manustatud eelvaateid. See võib mõnede piltide puhul anda tulemuseks täpsemad värvid, aga eelvaate kvaliteet sõltub konkreetsest kaamerast ning pildis võib olla rohkem tihendusmüra.",
|
"image_prefer_embedded_preview_setting_description": "Kasuta pilditöötluse sisendina võimalusel RAW fotodesse manustatud eelvaateid. See võib mõnede piltide puhul anda tulemuseks täpsemad värvid, aga eelvaate kvaliteet sõltub konkreetsest kaamerast ning pildis võib olla rohkem tihendusmüra.",
|
||||||
"image_prefer_wide_gamut": "Eelista laia värvigammat",
|
"image_prefer_wide_gamut": "Eelista laia värvigammat",
|
||||||
@@ -864,7 +859,6 @@
|
|||||||
"loop_videos": "Taasesita videod",
|
"loop_videos": "Taasesita videod",
|
||||||
"loop_videos_description": "Lülita sisse, et detailvaates videot automaatselt taasesitada.",
|
"loop_videos_description": "Lülita sisse, et detailvaates videot automaatselt taasesitada.",
|
||||||
"main_branch_warning": "Sa kasutad arendusversiooni; soovitame tungivalt kasutada väljalaskeversiooni!",
|
"main_branch_warning": "Sa kasutad arendusversiooni; soovitame tungivalt kasutada väljalaskeversiooni!",
|
||||||
"main_menu": "Peamenüü",
|
|
||||||
"make": "Mark",
|
"make": "Mark",
|
||||||
"manage_shared_links": "Halda jagatud linke",
|
"manage_shared_links": "Halda jagatud linke",
|
||||||
"manage_sharing_with_partners": "Halda partneritega jagamist",
|
"manage_sharing_with_partners": "Halda partneritega jagamist",
|
||||||
@@ -1085,8 +1079,6 @@
|
|||||||
"remove_from_album": "Eemalda albumist",
|
"remove_from_album": "Eemalda albumist",
|
||||||
"remove_from_favorites": "Eemalda lemmikutest",
|
"remove_from_favorites": "Eemalda lemmikutest",
|
||||||
"remove_from_shared_link": "Eemalda jagatud lingist",
|
"remove_from_shared_link": "Eemalda jagatud lingist",
|
||||||
"remove_memory": "Eemalda mälestus",
|
|
||||||
"remove_photo_from_memory": "Eemalda foto sellest mälestusest",
|
|
||||||
"remove_url": "Eemalda URL",
|
"remove_url": "Eemalda URL",
|
||||||
"remove_user": "Eemalda kasutaja",
|
"remove_user": "Eemalda kasutaja",
|
||||||
"removed_api_key": "API võti eemaldatud: {name}",
|
"removed_api_key": "API võti eemaldatud: {name}",
|
||||||
@@ -1157,7 +1149,6 @@
|
|||||||
"searching_locales": "Lokaatide otsimine...",
|
"searching_locales": "Lokaatide otsimine...",
|
||||||
"second": "Sekund",
|
"second": "Sekund",
|
||||||
"see_all_people": "Vaata kõiki isikuid",
|
"see_all_people": "Vaata kõiki isikuid",
|
||||||
"select": "Vali",
|
|
||||||
"select_album_cover": "Vali albumi kaanepilt",
|
"select_album_cover": "Vali albumi kaanepilt",
|
||||||
"select_all": "Vali kõik",
|
"select_all": "Vali kõik",
|
||||||
"select_all_duplicates": "Vali kõik duplikaadid",
|
"select_all_duplicates": "Vali kõik duplikaadid",
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
+3
-785
File diff suppressed because it is too large
Load Diff
-791
File diff suppressed because it is too large
Load Diff
-791
File diff suppressed because it is too large
Load Diff
-798
File diff suppressed because it is too large
Load Diff
+3
-794
File diff suppressed because it is too large
Load Diff
-785
File diff suppressed because it is too large
Load Diff
+3
-794
File diff suppressed because it is too large
Load Diff
+11
-917
File diff suppressed because it is too large
Load Diff
-165
@@ -1,165 +0,0 @@
|
|||||||
{
|
|
||||||
"about": "შესახებ",
|
|
||||||
"account": "ანგარიში",
|
|
||||||
"account_settings": "ანგარიშის პარამეტრები",
|
|
||||||
"acknowledge": "მიღება",
|
|
||||||
"action": "ქმედება",
|
|
||||||
"actions": "ქმედებები",
|
|
||||||
"active": "აქტიური",
|
|
||||||
"activity": "აქტივობა",
|
|
||||||
"add": "დამატება",
|
|
||||||
"add_a_description": "დაამატე აღწერა",
|
|
||||||
"add_a_location": "დაამატე ადგილი",
|
|
||||||
"add_a_name": "დაამატე სახელი",
|
|
||||||
"add_a_title": "დაასათაურე",
|
|
||||||
"add_import_path": "დაამატე საიმპორტო მისამართი",
|
|
||||||
"add_location": "დაამატე ადგილი",
|
|
||||||
"add_more_users": "დაამატე მომხმარებლები",
|
|
||||||
"add_partner": "დაამატე პარტნიორი",
|
|
||||||
"add_path": "დაამატე მისამართი",
|
|
||||||
"add_photos": "დაამატე ფოტოები",
|
|
||||||
"add_to_album": "დაამატე ალბომში",
|
|
||||||
"add_to_shared_album": "დაამატე საზიარო ალბომში",
|
|
||||||
"add_url": "დაამატე URL",
|
|
||||||
"added_to_archive": "დაარქივდა",
|
|
||||||
"added_to_favorites": "დაამატე რჩეულებში",
|
|
||||||
"added_to_favorites_count": "{count, number} დაემატა რჩეულებში",
|
|
||||||
"admin": {
|
|
||||||
"authentication_settings": "ავთენტიკაციის პარამეტრები",
|
|
||||||
"authentication_settings_description": "პაროლის, OAuth-ის და სხვა ავტენთიფიკაციის პარამეტრების მართვა",
|
|
||||||
"authentication_settings_disable_all": "ნამდვილად გინდა ავტორიზაციის ყველა მეთოდის გამორთვა? ავტორიზაციას ვეღარანაირად შეძლებ.",
|
|
||||||
"authentication_settings_reenable": "რეაქტივაციისთვის, გამოიყენე <link>სერვერის ბრძანება</link>.",
|
|
||||||
"background_task_job": "ფონური დავალებები",
|
|
||||||
"backup_database": "შექმენი სარეზერვო ასლი",
|
|
||||||
"backup_database_enable_description": "ჩართე სარეზერვო ასლების ფუნქცია",
|
|
||||||
"backup_keep_last_amount": "შესანახი სარეზერვო ასლების რაოდენობა",
|
|
||||||
"backup_settings": "სარეზერვო ასლების პარამეტრები",
|
|
||||||
"backup_settings_description": "მონაცემთა ბაზის სარეზერვო ასლების პარამეტრების მართვა",
|
|
||||||
"check_all": "შეამოწმე ყველა",
|
|
||||||
"cleanup": "გასუფთავება",
|
|
||||||
"confirm_delete_library": "ნამდვილად გინდა {library} ბიბლიოთეკის წაშლა?",
|
|
||||||
"confirm_email_below": "დასადასტურებლად, ქვემოთ აკრიფე \"{email}\"",
|
|
||||||
"confirm_user_password_reset": "ნამდვილად გინდა {user}-(ი)ს პაროლის დარესეტება?",
|
|
||||||
"disable_login": "გამორთე ავტორიზაცია",
|
|
||||||
"external_library_management": "გარე ბიბლიოთეკების მართვა",
|
|
||||||
"face_detection": "სახის ამოცნობა",
|
|
||||||
"image_format": "ფორმატი",
|
|
||||||
"image_fullsize_title": "სრული ზომის გამოსახულების პარამეტრები",
|
|
||||||
"image_quality": "ხარისხი",
|
|
||||||
"image_resolution": "გაფართოება",
|
|
||||||
"image_settings": "გამოსახულების პარამეტრები",
|
|
||||||
"image_settings_description": "გენერირებული ფოტოების ხარისხისა და რეზოლუციის მართვა",
|
|
||||||
"image_thumbnail_description": "მინიატურა მეტაინფორმაციის გარეშე, რომელიც ფოტოები ჯგუფურად თვალიერებისას გამოიყენება(მაგ. მთავარ თაიმლაინზე)",
|
|
||||||
"image_thumbnail_quality_description": "მინიატურის ხარისხი 1-დან 100-მდე. დიდი რიცხვი შეესაბამება უკეთეს ხარისხს, თუმცა, უფრო დიდ ფაილებს და აპლიკაციის შესაძლო შენელებას.",
|
|
||||||
"image_thumbnail_title": "მინიატურის პარამეტრები",
|
|
||||||
"library_created": "შეიქმნა ბიბლიოთეკა: {library}",
|
|
||||||
"library_deleted": "ბიბლიოთეკა წაიშალა",
|
|
||||||
"library_import_path_description": "აირჩიე დასაიმპორტებელი საქაღალდე. ფოტოები და ვიდეოები მოიძებნება ამ საქაღალდესა და მასში არსებულ საქაღალდეებში.",
|
|
||||||
"library_settings_description": "გარე ბიბლიოთეკების პარამეტრების მართვა",
|
|
||||||
"logging_settings": "ჟურნალი",
|
|
||||||
"map_settings": "რუკა",
|
|
||||||
"migration_job": "მიგრაცია",
|
|
||||||
"oauth_scope": "დიაპაზონი",
|
|
||||||
"oauth_settings": "OAuth",
|
|
||||||
"template_email_preview": "მინიატურა",
|
|
||||||
"transcoding_acceleration_vaapi": "VAAPI",
|
|
||||||
"transcoding_threads": "ნაკადები",
|
|
||||||
"transcoding_tone_mapping": "ტონების ასახვა"
|
|
||||||
},
|
|
||||||
"administration": "ადმინისტრაცია",
|
|
||||||
"advanced": "დამატებით",
|
|
||||||
"albums": "ალბომები",
|
|
||||||
"all": "ყველა",
|
|
||||||
"anti_clockwise": "საათის ისრის საწინააღმდეგო",
|
|
||||||
"archive": "არქივი",
|
|
||||||
"asset_hashing": "დაჰეშვა.…",
|
|
||||||
"asset_skipped": "გამოტოვებულია",
|
|
||||||
"asset_uploaded": "ატვირთულია",
|
|
||||||
"asset_uploading": "მიმდინარეობს ატვირთვა…",
|
|
||||||
"assets": "ობიექტები",
|
|
||||||
"back": "უკან",
|
|
||||||
"backward": "უკან გადასვლა",
|
|
||||||
"build": "აგება",
|
|
||||||
"camera": "კამერა",
|
|
||||||
"cancel": "გაუქმება",
|
|
||||||
"city": "ქალაქი",
|
|
||||||
"clear": "გასუფთავება",
|
|
||||||
"clockwise": "საათის ისრის მიმართულებით",
|
|
||||||
"close": "დახურვა",
|
|
||||||
"collapse": "აკეცვა",
|
|
||||||
"color": "ფერი",
|
|
||||||
"confirm": "დასტური",
|
|
||||||
"contain": "შეიცავს",
|
|
||||||
"context": "კონტექსტი",
|
|
||||||
"continue": "გაგრძელება",
|
|
||||||
"country": "ქვეყანა",
|
|
||||||
"cover": "ყდა",
|
|
||||||
"covers": "ყდები",
|
|
||||||
"create": "შექმნა",
|
|
||||||
"created": "შექმნილია",
|
|
||||||
"dark": "მუქი",
|
|
||||||
"day": "დღე",
|
|
||||||
"delete": "წაშლა",
|
|
||||||
"description": "აღწერა",
|
|
||||||
"details": "დეტალები",
|
|
||||||
"direction": "მიმართულება",
|
|
||||||
"disabled": "გათიშულია",
|
|
||||||
"discord": "Discord",
|
|
||||||
"discover": "აღმოჩენა",
|
|
||||||
"documentation": "დოკუმენტაცია",
|
|
||||||
"done": "მზადაა",
|
|
||||||
"download": "გადმოწერა",
|
|
||||||
"download_settings": "გადმოწერა",
|
|
||||||
"downloading": "მიმდინარეობს გადმოწერა",
|
|
||||||
"duplicates": "დუბლიკატები",
|
|
||||||
"duration": "ხანგრძლივობა",
|
|
||||||
"edit": "ჩასწორება",
|
|
||||||
"edited": "ჩასწორებულია",
|
|
||||||
"editor": "რედაქტორი",
|
|
||||||
"editor_crop_tool_h2_rotation": "ტრიალი",
|
|
||||||
"email": "ელფოსტა",
|
|
||||||
"enable": "ჩართვა",
|
|
||||||
"enabled": "ჩართულია",
|
|
||||||
"error": "შეცდომა",
|
|
||||||
"exif": "Exif",
|
|
||||||
"expired": "ვადაამოწურულია",
|
|
||||||
"explore": "დათვალიერება",
|
|
||||||
"explorer": "გამცილებელი",
|
|
||||||
"export": "გატანა",
|
|
||||||
"extension": "გაფართოება",
|
|
||||||
"external": "გარე",
|
|
||||||
"face_unassigned": "მიუნიჭებელი",
|
|
||||||
"favorite": "რჩეული",
|
|
||||||
"favorites": "რჩეულები",
|
|
||||||
"features": "თვისებები",
|
|
||||||
"filename": "ფაილის სახელი",
|
|
||||||
"filetype": "ფაილის ტიპი",
|
|
||||||
"folders": "საქაღალდეები",
|
|
||||||
"forward": "წინ",
|
|
||||||
"general": "ზოგადი",
|
|
||||||
"host": "ჰოსტი",
|
|
||||||
"hour": "საათი",
|
|
||||||
"image": "გამოსახულება",
|
|
||||||
"info": "ინფორმაცია",
|
|
||||||
"jobs": "დავალებები",
|
|
||||||
"keep": "შენარჩუნება",
|
|
||||||
"language": "ენა",
|
|
||||||
"latitude": "განედი",
|
|
||||||
"leave": "გასვლა",
|
|
||||||
"level": "დონე",
|
|
||||||
"library": "ბიბლიოთეკა",
|
|
||||||
"light": "ღია",
|
|
||||||
"list": "სია",
|
|
||||||
"loading": "ჩატვირთვა",
|
|
||||||
"login": "შესვლა",
|
|
||||||
"longitude": "გრძედი",
|
|
||||||
"look": "შეხედვა",
|
|
||||||
"make": "მწარმოებელი",
|
|
||||||
"map": "რუკა",
|
|
||||||
"matches": "დამთხვევები",
|
|
||||||
"memories": "მოგონებები",
|
|
||||||
"memory": "მეხსიერება",
|
|
||||||
"menu": "მენიუ",
|
|
||||||
"merge": "შერწყმა",
|
|
||||||
"minimize": "დაპატარავება"
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
+8
-844
File diff suppressed because it is too large
Load Diff
-784
File diff suppressed because it is too large
Load Diff
+29
-838
File diff suppressed because it is too large
Load Diff
-786
File diff suppressed because it is too large
Load Diff
+1
-786
File diff suppressed because it is too large
Load Diff
+3
-794
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user