mirror of
https://github.com/immich-app/immich.git
synced 2026-03-26 03:54:23 -07:00
Compare commits
17 Commits
chore/remo
...
fix/librar
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa9baad116 | ||
|
|
3e43da5d8d | ||
|
|
b9b5dba037 | ||
|
|
8bfa75087c | ||
|
|
95280edd6c | ||
|
|
a9666d2cef | ||
|
|
292fbef180 | ||
|
|
4af9edc20b | ||
|
|
c975fe5bc7 | ||
|
|
05b07ca233 | ||
|
|
12a4d8e2ee | ||
|
|
ce9b32a61a | ||
|
|
4ddc288cd1 | ||
|
|
94b15b8678 | ||
|
|
ff9ae24219 | ||
|
|
b456f78771 | ||
|
|
1506776891 |
22
.github/workflows/build-mobile.yml
vendored
22
.github/workflows/build-mobile.yml
vendored
@@ -51,14 +51,14 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Check what should run
|
||||
id: check
|
||||
uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2
|
||||
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
filters: |
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -103,7 +103,7 @@ jobs:
|
||||
|
||||
- name: Restore Gradle Cache
|
||||
id: cache-gradle-restore
|
||||
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
@@ -114,7 +114,7 @@ jobs:
|
||||
key: build-mobile-gradle-${{ runner.os }}-main
|
||||
|
||||
- name: Setup Flutter SDK
|
||||
uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0
|
||||
uses: subosito/flutter-action@0ca7a949e71ae44c8e688a51c5e7e93b2c87e295 # v2.22.0
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version-file: ./mobile/pubspec.yaml
|
||||
@@ -153,14 +153,14 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Publish Android Artifact
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: release-apk-signed
|
||||
path: mobile/build/app/outputs/flutter-apk/*.apk
|
||||
|
||||
- name: Save Gradle Cache
|
||||
id: cache-gradle-save
|
||||
uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
|
||||
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
if: github.ref == 'refs/heads/main'
|
||||
with:
|
||||
path: |
|
||||
@@ -185,13 +185,13 @@ jobs:
|
||||
run: sudo xcode-select -s /Applications/Xcode_26.2.app/Contents/Developer
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
ref: ${{ inputs.ref || github.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup Flutter SDK
|
||||
uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2
|
||||
uses: subosito/flutter-action@0ca7a949e71ae44c8e688a51c5e7e93b2c87e295 # v2.22.0
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version-file: ./mobile/pubspec.yaml
|
||||
@@ -210,7 +210,7 @@ jobs:
|
||||
working-directory: ./mobile
|
||||
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
uses: ruby/setup-ruby@319994f95fa847cf3fb3cd3dbe89f6dcde9f178f # v1.295.0
|
||||
with:
|
||||
ruby-version: '3.3'
|
||||
bundler-cache: true
|
||||
@@ -291,7 +291,7 @@ jobs:
|
||||
security delete-keychain build.keychain || true
|
||||
|
||||
- name: Upload IPA artifact
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: ios-release-ipa
|
||||
path: mobile/ios/Runner.ipa
|
||||
|
||||
2
.github/workflows/cache-cleanup.yml
vendored
2
.github/workflows/cache-cleanup.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
actions: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
2
.github/workflows/check-openapi.yml
vendored
2
.github/workflows/check-openapi.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check for breaking API changes
|
||||
uses: oasdiff/oasdiff-action/breaking@748daafaf3aac877a36307f842a48d55db938ac8 # v0.0.31
|
||||
uses: oasdiff/oasdiff-action/breaking@2a37bc82462349c03a533b8b608bebbaf57b3e60 # v0.0.33
|
||||
with:
|
||||
base: https://raw.githubusercontent.com/${{ github.repository }}/main/open-api/immich-openapi-specs.json
|
||||
revision: open-api/immich-openapi-specs.json
|
||||
|
||||
16
.github/workflows/cli.yml
vendored
16
.github/workflows/cli.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
working-directory: ./cli
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
@@ -71,7 +71,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -83,13 +83,13 @@ jobs:
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
||||
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
|
||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||
with:
|
||||
registry: ghcr.io
|
||||
@@ -104,7 +104,7 @@ jobs:
|
||||
|
||||
- name: Generate docker image tags
|
||||
id: metadata
|
||||
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0
|
||||
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
|
||||
with:
|
||||
flavor: |
|
||||
latest=false
|
||||
@@ -115,7 +115,7 @@ jobs:
|
||||
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
||||
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2
|
||||
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
|
||||
with:
|
||||
file: cli/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
2
.github/workflows/close-duplicates.yml
vendored
2
.github/workflows/close-duplicates.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
needs: [get_body, should_run]
|
||||
if: ${{ needs.should_run.outputs.should_run == 'true' }}
|
||||
container:
|
||||
image: ghcr.io/immich-app/mdq:main@sha256:4f9860d04c88f7f87861f8ee84bfeedaec15ed7ca5ca87bc7db44b036f81645f
|
||||
image: ghcr.io/immich-app/mdq:main@sha256:df7188ba88abb0800d73cc97d3633280f0c0c3d4c441d678225067bf154150fb
|
||||
outputs:
|
||||
checked: ${{ steps.get_checkbox.outputs.checked }}
|
||||
steps:
|
||||
|
||||
8
.github/workflows/codeql-analysis.yml
vendored
8
.github/workflows/codeql-analysis.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
uses: github/codeql-action/init@b1bff81932f5cdfc8695c7752dcee935dcd061c8 # v4.33.0
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
uses: github/codeql-action/autobuild@b1bff81932f5cdfc8695c7752dcee935dcd061c8 # v4.33.0
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
@@ -83,6 +83,6 @@ jobs:
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
|
||||
uses: github/codeql-action/analyze@b1bff81932f5cdfc8695c7752dcee935dcd061c8 # v4.33.0
|
||||
with:
|
||||
category: '/language:${{matrix.language}}'
|
||||
|
||||
12
.github/workflows/docker.yml
vendored
12
.github/workflows/docker.yml
vendored
@@ -23,14 +23,14 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Check what should run
|
||||
id: check
|
||||
uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2
|
||||
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
filters: |
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn']
|
||||
steps:
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
@@ -90,7 +90,7 @@ jobs:
|
||||
suffix: ['']
|
||||
steps:
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
@@ -132,7 +132,7 @@ jobs:
|
||||
suffixes: '-rocm'
|
||||
platforms: linux/amd64
|
||||
runner-mapping: '{"linux/amd64": "pokedex-large"}'
|
||||
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@bd49ed7a5a6022149f79b6564df48177476a822b # multi-runner-build-workflow-v2.2.1
|
||||
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@61a0fc2b41524edcc7c9fffb8bb178e6b0ccf21d # multi-runner-build-workflow-v2.3.0
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
@@ -155,7 +155,7 @@ jobs:
|
||||
name: Build and Push Server
|
||||
needs: pre-job
|
||||
if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == true }}
|
||||
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@bd49ed7a5a6022149f79b6564df48177476a822b # multi-runner-build-workflow-v2.2.1
|
||||
uses: immich-app/devtools/.github/workflows/multi-runner-build.yml@61a0fc2b41524edcc7c9fffb8bb178e6b0ccf21d # multi-runner-build-workflow-v2.3.0
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
|
||||
10
.github/workflows/docs-build.yml
vendored
10
.github/workflows/docs-build.yml
vendored
@@ -21,14 +21,14 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Check what should run
|
||||
id: check
|
||||
uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2
|
||||
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
filters: |
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
run: pnpm build
|
||||
|
||||
- name: Upload build output
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: docs-build-output
|
||||
path: docs/build/
|
||||
|
||||
6
.github/workflows/docs-deploy.yml
vendored
6
.github/workflows/docs-deploy.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
artifact: ${{ steps.get-artifact.outputs.result }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -119,7 +119,7 @@ jobs:
|
||||
if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -131,7 +131,7 @@ jobs:
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@dab18118da6476e8237ac94080fd937983fecd42 # use-mise-action-v1.1.2
|
||||
uses: immich-app/devtools/actions/use-mise@035e80a7d4355d5f087ffb95db9e4a0944c04e56 # use-mise-action-v1.1.3
|
||||
|
||||
- name: Load parameters
|
||||
id: parameters
|
||||
|
||||
4
.github/workflows/docs-destroy.yml
vendored
4
.github/workflows/docs-destroy.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Mise
|
||||
uses: immich-app/devtools/actions/use-mise@dab18118da6476e8237ac94080fd937983fecd42 # use-mise-action-v1.1.2
|
||||
uses: immich-app/devtools/actions/use-mise@035e80a7d4355d5f087ffb95db9e4a0944c04e56 # use-mise-action-v1.1.3
|
||||
|
||||
- name: Destroy Docs Subdomain
|
||||
env:
|
||||
|
||||
4
.github/workflows/fix-format.yml
vendored
4
.github/workflows/fix-format.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
steps:
|
||||
- name: Generate a token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
persist-credentials: true
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
|
||||
2
.github/workflows/merge-translations.yml
vendored
2
.github/workflows/merge-translations.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
- name: Generate a token
|
||||
id: generate_token
|
||||
if: ${{ inputs.skip != true }}
|
||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
4
.github/workflows/pr-label-validation.yml
vendored
4
.github/workflows/pr-label-validation.yml
vendored
@@ -14,13 +14,13 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Require PR to have a changelog label
|
||||
uses: mheap/github-action-required-labels@8afbe8ae6ab7647d0c9f0cfa7c2f939650d22509 # v5.5.1
|
||||
uses: mheap/github-action-required-labels@0ac283b4e65c1fb28ce6079dea5546ceca98ccbe # v5.5.2
|
||||
with:
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
mode: exactly
|
||||
|
||||
2
.github/workflows/pr-labeler.yml
vendored
2
.github/workflows/pr-labeler.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
12
.github/workflows/prepare-release.yml
vendored
12
.github/workflows/prepare-release.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
steps:
|
||||
- name: Generate a token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -63,10 +63,10 @@ jobs:
|
||||
ref: main
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@6ee6290f1cbc4156c0bdd66691b2c144ef8df19a # v7.4.0
|
||||
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
@@ -124,7 +124,7 @@ jobs:
|
||||
steps:
|
||||
- name: Generate a token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -136,13 +136,13 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download APK
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
name: release-apk-signed
|
||||
github-token: ${{ steps.generate-token.outputs.token }}
|
||||
|
||||
- name: Create draft release
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
|
||||
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1
|
||||
with:
|
||||
draft: true
|
||||
tag_name: ${{ needs.bump_version.outputs.version }}
|
||||
|
||||
10
.github/workflows/preview-label.yaml
vendored
10
.github/workflows/preview-label.yaml
vendored
@@ -14,12 +14,12 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2
|
||||
- uses: mshick/add-pr-comment@ffd016c7e151d97d69d21a843022fd4cd5b96fe5 # v3.9.0
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
message-id: 'preview-status'
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -48,14 +48,14 @@ jobs:
|
||||
name: 'preview'
|
||||
})
|
||||
|
||||
- uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2
|
||||
- uses: mshick/add-pr-comment@ffd016c7e151d97d69d21a843022fd4cd5b96fe5 # v3.9.0
|
||||
if: ${{ github.event.pull_request.head.repo.fork }}
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
message-id: 'preview-status'
|
||||
message: 'PRs from forks cannot have preview environments.'
|
||||
|
||||
- uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2
|
||||
- uses: mshick/add-pr-comment@ffd016c7e151d97d69d21a843022fd4cd5b96fe5 # v3.9.0
|
||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
|
||||
4
.github/workflows/sdk.yml
vendored
4
.github/workflows/sdk.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
working-directory: ./open-api/typescript-sdk
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
|
||||
# Setup .npmrc file to publish to npm
|
||||
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
|
||||
8
.github/workflows/static_analysis.yml
vendored
8
.github/workflows/static_analysis.yml
vendored
@@ -20,14 +20,14 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Check what should run
|
||||
id: check
|
||||
uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2
|
||||
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
filters: |
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
working-directory: ./mobile
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup Flutter SDK
|
||||
uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0
|
||||
uses: subosito/flutter-action@0ca7a949e71ae44c8e688a51c5e7e93b2c87e295 # v2.22.0
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version-file: ./mobile/pubspec.yaml
|
||||
|
||||
76
.github/workflows/test.yml
vendored
76
.github/workflows/test.yml
vendored
@@ -17,14 +17,14 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Check what should run
|
||||
id: check
|
||||
uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2
|
||||
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
filters: |
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
working-directory: ./server
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
working-directory: ./cli
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -119,7 +119,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -155,7 +155,7 @@ jobs:
|
||||
working-directory: ./cli
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -166,7 +166,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -197,7 +197,7 @@ jobs:
|
||||
working-directory: ./web
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -208,7 +208,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -241,7 +241,7 @@ jobs:
|
||||
working-directory: ./web
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -252,7 +252,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -279,7 +279,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -290,7 +290,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -327,7 +327,7 @@ jobs:
|
||||
working-directory: ./e2e
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -338,7 +338,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -373,7 +373,7 @@ jobs:
|
||||
working-directory: ./server
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -385,7 +385,7 @@ jobs:
|
||||
submodules: 'recursive'
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -412,7 +412,7 @@ jobs:
|
||||
runner: [ubuntu-latest, ubuntu-24.04-arm]
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -424,7 +424,7 @@ jobs:
|
||||
submodules: 'recursive'
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -464,7 +464,7 @@ jobs:
|
||||
run: docker compose logs --no-color > docker-compose-logs.txt
|
||||
working-directory: ./e2e
|
||||
- name: Archive Docker logs
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
if: always()
|
||||
with:
|
||||
name: e2e-server-docker-logs-${{ matrix.runner }}
|
||||
@@ -484,7 +484,7 @@ jobs:
|
||||
runner: [ubuntu-latest, ubuntu-24.04-arm]
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -496,7 +496,7 @@ jobs:
|
||||
submodules: 'recursive'
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -522,7 +522,7 @@ jobs:
|
||||
run: pnpm test:web
|
||||
if: ${{ !cancelled() }}
|
||||
- name: Archive e2e test (web) results
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
if: success() || failure()
|
||||
with:
|
||||
name: e2e-web-test-results-${{ matrix.runner }}
|
||||
@@ -533,7 +533,7 @@ jobs:
|
||||
run: pnpm test:web:ui
|
||||
if: ${{ !cancelled() }}
|
||||
- name: Archive ui test (web) results
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
if: success() || failure()
|
||||
with:
|
||||
name: e2e-ui-test-results-${{ matrix.runner }}
|
||||
@@ -544,7 +544,7 @@ jobs:
|
||||
run: pnpm test:web:maintenance
|
||||
if: ${{ !cancelled() }}
|
||||
- name: Archive maintenance tests (web) results
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
if: success() || failure()
|
||||
with:
|
||||
name: e2e-maintenance-isolated-test-results-${{ matrix.runner }}
|
||||
@@ -554,7 +554,7 @@ jobs:
|
||||
run: docker compose logs --no-color > docker-compose-logs.txt
|
||||
working-directory: ./e2e
|
||||
- name: Archive Docker logs
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
if: always()
|
||||
with:
|
||||
name: e2e-web-docker-logs-${{ matrix.runner }}
|
||||
@@ -578,7 +578,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -588,7 +588,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup Flutter SDK
|
||||
uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0
|
||||
uses: subosito/flutter-action@0ca7a949e71ae44c8e688a51c5e7e93b2c87e295 # v2.22.0
|
||||
with:
|
||||
channel: 'stable'
|
||||
flutter-version-file: ./mobile/pubspec.yaml
|
||||
@@ -610,7 +610,7 @@ jobs:
|
||||
working-directory: ./machine-learning
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -620,7 +620,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@6ee6290f1cbc4156c0bdd66691b2c144ef8df19a # v7.4.0
|
||||
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
|
||||
with:
|
||||
python-version: 3.11
|
||||
- name: Install dependencies
|
||||
@@ -650,7 +650,7 @@ jobs:
|
||||
working-directory: ./.github
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -661,7 +661,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -680,7 +680,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -701,7 +701,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -712,7 +712,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
@@ -763,7 +763,7 @@ jobs:
|
||||
working-directory: ./server
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
@@ -774,7 +774,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
token: ${{ steps.token.outputs.token }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
|
||||
6
.github/workflows/weblate-lock.yml
vendored
6
.github/workflows/weblate-lock.yml
vendored
@@ -24,14 +24,14 @@ jobs:
|
||||
should_run: ${{ steps.check.outputs.should_run }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
- name: Check what should run
|
||||
id: check
|
||||
uses: immich-app/devtools/actions/pre-job@eed0f8b8165ffcb951f2ba854b2dd031935e1d73 # pre-job-action-v2.0.2
|
||||
uses: immich-app/devtools/actions/pre-job@f50e3b600b6ac1763ddb8f3dfc69093512b967a1 # pre-job-action-v2.0.3
|
||||
with:
|
||||
github-token: ${{ steps.token.outputs.token }}
|
||||
filters: |
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
if: ${{ fromJSON(needs.pre-job.outputs.should_run).i18n == true }}
|
||||
steps:
|
||||
- id: token
|
||||
uses: immich-app/devtools/actions/create-workflow-token@05e16407c0a5492138bb38139c9d9bf067b40886 # create-workflow-token-action-v1.0.1
|
||||
uses: immich-app/devtools/actions/create-workflow-token@57ff6ebfd507b045514442683ff06ff1b2f6efbd # create-workflow-token-action-v1.0.2
|
||||
with:
|
||||
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
|
||||
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@immich/cli",
|
||||
"version": "2.6.1",
|
||||
"version": "2.6.2",
|
||||
"description": "Command Line Interface (CLI) for Immich",
|
||||
"type": "module",
|
||||
"exports": "./dist/index.js",
|
||||
|
||||
@@ -8,7 +8,7 @@ Hardware and software requirements for Immich:
|
||||
|
||||
## Hardware
|
||||
|
||||
- **OS**: Recommended Linux or \*nix operating system (Ubuntu, Debian, etc).
|
||||
- **OS**: Recommended Linux or \*nix 64-bit operating system (Ubuntu, Debian, etc).
|
||||
- Non-Linux OSes tend to provide a poor Docker experience and are strongly discouraged.
|
||||
Our ability to assist with setup or troubleshooting on non-Linux OSes will be severely reduced.
|
||||
If you still want to try to use a non-Linux OS, you can set it up as follows:
|
||||
@@ -19,6 +19,10 @@ Hardware and software requirements for Immich:
|
||||
If you have issues, we recommend that you switch to a supported VM deployment.
|
||||
- **RAM**: Minimum 6GB, recommended 8GB.
|
||||
- **CPU**: Minimum 2 cores, recommended 4 cores.
|
||||
- Immich runs on the `amd64` and `arm64` platforms.
|
||||
Since `v2.6`, the machine learning container on `amd64` requires the `>= x86-64-v2` [microarchitecture level](https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels).
|
||||
Most CPUs released since ~2012 support this microarchitecture.
|
||||
If you are using a virtual machine, ensure you have selected a [supported microarchitecture](https://pve.proxmox.com/pve-docs/chapter-qm.html#_qemu_cpu_types).
|
||||
- **Storage**: Recommended Unix-compatible filesystem (EXT4, ZFS, APFS, etc.) with support for user/group ownership and permissions.
|
||||
- The generation of thumbnails and transcoded video can increase the size of the photo library by 10-20% on average.
|
||||
|
||||
|
||||
4
docs/static/archived-versions.json
vendored
4
docs/static/archived-versions.json
vendored
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"label": "v2.6.1",
|
||||
"url": "https://docs.v2.6.1.archive.immich.app"
|
||||
"label": "v2.6.2",
|
||||
"url": "https://docs.v2.6.2.archive.immich.app"
|
||||
},
|
||||
{
|
||||
"label": "v2.5.6",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-e2e",
|
||||
"version": "2.6.1",
|
||||
"version": "2.6.2",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
|
||||
@@ -524,14 +524,19 @@ describe('/albums', () => {
|
||||
expect(body).toEqual(errorDto.badRequest('Not found or no album.update access'));
|
||||
});
|
||||
|
||||
it('should not be able to update as an editor', async () => {
|
||||
it('should be able to update as an editor', async () => {
|
||||
const { status, body } = await request(app)
|
||||
.patch(`/albums/${user1Albums[0].id}`)
|
||||
.set('Authorization', `Bearer ${user2.accessToken}`)
|
||||
.send({ albumName: 'New album name' });
|
||||
|
||||
expect(status).toBe(400);
|
||||
expect(body).toEqual(errorDto.badRequest('Not found or no album.update access'));
|
||||
expect(status).toBe(200);
|
||||
expect(body).toEqual(
|
||||
expect.objectContaining({
|
||||
id: user1Albums[0].id,
|
||||
albumName: 'New album name',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -866,6 +866,7 @@
|
||||
"crop_aspect_ratio_fixed": "Fixed",
|
||||
"crop_aspect_ratio_free": "Free",
|
||||
"crop_aspect_ratio_original": "Original",
|
||||
"crop_aspect_ratio_square": "Square",
|
||||
"curated_object_page_title": "Things",
|
||||
"current_device": "Current device",
|
||||
"current_pin_code": "Current PIN code",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-i18n",
|
||||
"version": "2.6.1",
|
||||
"version": "2.6.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"format": "prettier --cache --check .",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "immich-ml"
|
||||
version = "2.6.1"
|
||||
version = "2.6.2"
|
||||
description = ""
|
||||
authors = [{ name = "Hau Tran", email = "alex.tran1502@gmail.com" }]
|
||||
requires-python = ">=3.11,<4.0"
|
||||
|
||||
2
machine-learning/uv.lock
generated
2
machine-learning/uv.lock
generated
@@ -898,7 +898,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "immich-ml"
|
||||
version = "2.6.1"
|
||||
version = "2.6.2"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "aiocache" },
|
||||
|
||||
@@ -35,8 +35,8 @@ platform :android do
|
||||
task: 'bundle',
|
||||
build_type: 'Release',
|
||||
properties: {
|
||||
"android.injected.version.code" => 3039,
|
||||
"android.injected.version.name" => "2.6.1",
|
||||
"android.injected.version.code" => 3040,
|
||||
"android.injected.version.name" => "2.6.2",
|
||||
}
|
||||
)
|
||||
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
|
||||
|
||||
@@ -150,7 +150,6 @@ class URLSessionManager: NSObject {
|
||||
config.httpCookieStorage = cookieStorage
|
||||
config.httpMaximumConnectionsPerHost = 64
|
||||
config.timeoutIntervalForRequest = 60
|
||||
config.timeoutIntervalForResource = 300
|
||||
|
||||
var headers = UserDefaults.group.dictionary(forKey: HEADERS_KEY) as? [String: String] ?? [:]
|
||||
headers["User-Agent"] = headers["User-Agent"] ?? userAgent
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.6.1</string>
|
||||
<string>2.6.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
||||
@@ -67,6 +67,9 @@ class AuthService {
|
||||
bool isValid = false;
|
||||
|
||||
try {
|
||||
final urls = ApiService.getServerUrls();
|
||||
urls.add(url);
|
||||
await NetworkRepository.setHeaders(ApiService.getRequestHeaders(), urls);
|
||||
final uri = Uri.parse('$url/users/me');
|
||||
final response = await NetworkRepository.client.get(uri);
|
||||
if (response.statusCode == 200) {
|
||||
|
||||
@@ -143,8 +143,7 @@ enum ActionButtonType {
|
||||
!context.isInLockedView && //
|
||||
context.currentAlbum != null,
|
||||
ActionButtonType.setAlbumCover =>
|
||||
context.isOwner && //
|
||||
!context.isInLockedView && //
|
||||
!context.isInLockedView && //
|
||||
context.currentAlbum != null && //
|
||||
context.selectedCount == 1,
|
||||
ActionButtonType.unstack =>
|
||||
|
||||
2
mobile/openapi/README.md
generated
2
mobile/openapi/README.md
generated
@@ -3,7 +3,7 @@ Immich API
|
||||
|
||||
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
||||
|
||||
- API version: 2.6.1
|
||||
- API version: 2.6.2
|
||||
- Generator version: 7.8.0
|
||||
- Build package: org.openapitools.codegen.languages.DartClientCodegen
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ name: immich_mobile
|
||||
description: Immich - selfhosted backup media file on mobile phone
|
||||
|
||||
publish_to: 'none'
|
||||
version: 2.6.1+3039
|
||||
version: 2.6.2+3040
|
||||
|
||||
environment:
|
||||
sdk: '>=3.8.0 <4.0.0'
|
||||
|
||||
@@ -727,7 +727,7 @@ void main() {
|
||||
expect(ActionButtonType.setAlbumCover.shouldShow(context), isTrue);
|
||||
});
|
||||
|
||||
test('should not show when not owner', () {
|
||||
test('should show when not owner', () {
|
||||
final album = createRemoteAlbum();
|
||||
final context = ActionButtonContext(
|
||||
asset: mergedAsset,
|
||||
@@ -742,7 +742,7 @@ void main() {
|
||||
selectedCount: 1,
|
||||
);
|
||||
|
||||
expect(ActionButtonType.setAlbumCover.shouldShow(context), isFalse);
|
||||
expect(ActionButtonType.setAlbumCover.shouldShow(context), isTrue);
|
||||
});
|
||||
|
||||
test('should not show when in locked view', () {
|
||||
|
||||
@@ -15166,7 +15166,7 @@
|
||||
"info": {
|
||||
"title": "Immich",
|
||||
"description": "Immich API",
|
||||
"version": "2.6.1",
|
||||
"version": "2.6.2",
|
||||
"contact": {}
|
||||
},
|
||||
"tags": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@immich/sdk",
|
||||
"version": "2.6.1",
|
||||
"version": "2.6.2",
|
||||
"description": "Auto-generated TypeScript SDK for the Immich API",
|
||||
"type": "module",
|
||||
"main": "./build/index.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Immich
|
||||
* 2.6.1
|
||||
* 2.6.2
|
||||
* DO NOT MODIFY - This file has been generated using oazapfts.
|
||||
* See https://www.npmjs.com/package/oazapfts
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-monorepo",
|
||||
"version": "2.6.1",
|
||||
"version": "2.6.2",
|
||||
"description": "Monorepo for Immich",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@10.30.3+sha512.c961d1e0a2d8e354ecaa5166b822516668b7f44cb5bd95122d590dd81922f606f5473b6d23ec4a5be05e7fcd18e8488d47d978bbe981872f1145d06e9a740017",
|
||||
|
||||
52
pnpm-lock.yaml
generated
52
pnpm-lock.yaml
generated
@@ -431,8 +431,8 @@ importers:
|
||||
specifier: ^5.51.0
|
||||
version: 5.70.4
|
||||
chokidar:
|
||||
specifier: ^4.0.3
|
||||
version: 4.0.3
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0
|
||||
class-transformer:
|
||||
specifier: ^0.5.1
|
||||
version: 0.5.1
|
||||
@@ -592,7 +592,7 @@ importers:
|
||||
version: 11.0.16(@swc/core@1.15.18(@swc/helpers@0.5.17))(@types/node@24.12.0)(esbuild@0.27.3)
|
||||
'@nestjs/schematics':
|
||||
specifier: ^11.0.0
|
||||
version: 11.0.9(chokidar@4.0.3)(typescript@5.9.3)
|
||||
version: 11.0.9(chokidar@5.0.0)(typescript@5.9.3)
|
||||
'@nestjs/testing':
|
||||
specifier: ^11.0.4
|
||||
version: 11.1.16(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(@nestjs/platform-express@11.1.16)
|
||||
@@ -6050,6 +6050,10 @@ packages:
|
||||
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
|
||||
engines: {node: '>= 14.16.0'}
|
||||
|
||||
chokidar@5.0.0:
|
||||
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
chownr@1.1.4:
|
||||
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
||||
|
||||
@@ -10540,6 +10544,10 @@ packages:
|
||||
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
|
||||
engines: {node: '>= 14.18.0'}
|
||||
|
||||
readdirp@5.0.0:
|
||||
resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
recma-build-jsx@1.0.0:
|
||||
resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==}
|
||||
|
||||
@@ -12602,6 +12610,17 @@ snapshots:
|
||||
optionalDependencies:
|
||||
chokidar: 4.0.3
|
||||
|
||||
'@angular-devkit/core@19.2.17(chokidar@5.0.0)':
|
||||
dependencies:
|
||||
ajv: 8.17.1
|
||||
ajv-formats: 3.0.1(ajv@8.17.1)
|
||||
jsonc-parser: 3.3.1
|
||||
picomatch: 4.0.2
|
||||
rxjs: 7.8.1
|
||||
source-map: 0.7.4
|
||||
optionalDependencies:
|
||||
chokidar: 5.0.0
|
||||
|
||||
'@angular-devkit/core@19.2.19(chokidar@4.0.3)':
|
||||
dependencies:
|
||||
ajv: 8.17.1
|
||||
@@ -12635,6 +12654,16 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- chokidar
|
||||
|
||||
'@angular-devkit/schematics@19.2.17(chokidar@5.0.0)':
|
||||
dependencies:
|
||||
'@angular-devkit/core': 19.2.17(chokidar@5.0.0)
|
||||
jsonc-parser: 3.3.1
|
||||
magic-string: 0.30.17
|
||||
ora: 5.4.1
|
||||
rxjs: 7.8.1
|
||||
transitivePeerDependencies:
|
||||
- chokidar
|
||||
|
||||
'@angular-devkit/schematics@19.2.19(chokidar@4.0.3)':
|
||||
dependencies:
|
||||
'@angular-devkit/core': 19.2.19(chokidar@4.0.3)
|
||||
@@ -15720,6 +15749,17 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- chokidar
|
||||
|
||||
'@nestjs/schematics@11.0.9(chokidar@5.0.0)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@angular-devkit/core': 19.2.17(chokidar@5.0.0)
|
||||
'@angular-devkit/schematics': 19.2.17(chokidar@5.0.0)
|
||||
comment-json: 4.4.1
|
||||
jsonc-parser: 3.3.1
|
||||
pluralize: 8.0.0
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- chokidar
|
||||
|
||||
'@nestjs/swagger@11.2.6(@nestjs/common@11.1.16(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.16)(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)':
|
||||
dependencies:
|
||||
'@microsoft/tsdoc': 0.16.0
|
||||
@@ -18441,6 +18481,10 @@ snapshots:
|
||||
dependencies:
|
||||
readdirp: 4.1.2
|
||||
|
||||
chokidar@5.0.0:
|
||||
dependencies:
|
||||
readdirp: 5.0.0
|
||||
|
||||
chownr@1.1.4: {}
|
||||
|
||||
chownr@2.0.0: {}
|
||||
@@ -23672,6 +23716,8 @@ snapshots:
|
||||
|
||||
readdirp@4.1.2: {}
|
||||
|
||||
readdirp@5.0.0: {}
|
||||
|
||||
recma-build-jsx@1.0.0:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
"matchUpdateTypes": ["major"],
|
||||
"enabled": false
|
||||
},
|
||||
{
|
||||
"matchPackageNames": ["ghcr.io/immich-app/base-server-*"],
|
||||
"maxMajorIncrement": 0
|
||||
},
|
||||
{
|
||||
"matchPackageNames": ["ruby"],
|
||||
"groupName": "ruby",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ghcr.io/immich-app/base-server-dev:202603031112@sha256:837536db5fd9e432f0f474ef9b61712fe3b3815821c3e4edf5e5b0b1f1ed30ad AS builder
|
||||
FROM ghcr.io/immich-app/base-server-dev:202603251709@sha256:2bf3053c732fcb87ec90c3c614632ac44847423468ccc57fd935bff771828d9d AS builder
|
||||
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
|
||||
CI=1 \
|
||||
COREPACK_HOME=/tmp \
|
||||
@@ -52,7 +52,7 @@ FROM builder AS plugins
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
COPY --from=ghcr.io/jdx/mise:2026.1.1@sha256:a55c391f7582f34c58bce1a85090cd526596402ba77fc32b06c49b8404ef9c14 /usr/local/bin/mise /usr/local/bin/mise
|
||||
COPY --from=ghcr.io/jdx/mise:2026.3.12@sha256:0210678cbf58413806531a27adb2c7daf1c37238e56e8f7ea381d73521571775 /usr/local/bin/mise /usr/local/bin/mise
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
COPY ./plugins/mise.toml ./plugins/
|
||||
@@ -71,7 +71,7 @@ RUN --mount=type=cache,id=pnpm-plugins,target=/buildcache/pnpm-store \
|
||||
--mount=type=cache,id=mise-tools-${TARGETPLATFORM},target=/buildcache/mise \
|
||||
cd plugins && mise run build
|
||||
|
||||
FROM ghcr.io/immich-app/base-server-prod:202603031112@sha256:bb8c8645ee61977140121e56ba09db7ae656a7506f9a6af1be8461b4d81fdf03
|
||||
FROM ghcr.io/immich-app/base-server-prod:202603251709@sha256:17de30977ff87aa06758a56ad7f10d6b5c97bf9dab76e4ec4177a2a8d1b2b5f3
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
ENV NODE_ENV=production \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# dev build
|
||||
FROM ghcr.io/immich-app/base-server-dev:202603031112@sha256:837536db5fd9e432f0f474ef9b61712fe3b3815821c3e4edf5e5b0b1f1ed30ad AS dev
|
||||
FROM ghcr.io/immich-app/base-server-dev:202603251709@sha256:2bf3053c732fcb87ec90c3c614632ac44847423468ccc57fd935bff771828d9d AS dev
|
||||
|
||||
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
|
||||
CI=1 \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich",
|
||||
"version": "2.6.1",
|
||||
"version": "2.6.2",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
@@ -64,7 +64,7 @@
|
||||
"bcrypt": "^6.0.0",
|
||||
"body-parser": "^2.2.0",
|
||||
"bullmq": "^5.51.0",
|
||||
"chokidar": "^4.0.3",
|
||||
"chokidar": "^5.0.0",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.15.0",
|
||||
"compression": "^1.8.0",
|
||||
|
||||
@@ -26,6 +26,21 @@ import { JobOf } from 'src/types';
|
||||
import { mimeTypes } from 'src/utils/mime-types';
|
||||
import { handlePromiseError } from 'src/utils/misc';
|
||||
|
||||
const createMatchers = (exclusionPatterns: string[]) => {
|
||||
const supportedExtensions = mimeTypes.getSupportedFileExtensions().map((extension) => extension.toLowerCase());
|
||||
const expandedPatterns = exclusionPatterns.flatMap((pattern) =>
|
||||
pattern.endsWith('/**') ? [pattern, pattern.slice(0, -3)] : [pattern],
|
||||
);
|
||||
const excludeMatcher = picomatch(expandedPatterns, { nocase: true });
|
||||
return {
|
||||
isExcluded: (path: string) => excludeMatcher(path.replaceAll('\\', '/')),
|
||||
isSupported: (path: string) => {
|
||||
const normalizedPath = path.toLowerCase();
|
||||
return supportedExtensions.some((extension) => normalizedPath.endsWith(extension));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class LibraryService extends BaseService {
|
||||
private watchLibraries = false;
|
||||
@@ -90,24 +105,24 @@ export class LibraryService extends BaseService {
|
||||
|
||||
this.logger.log(`Starting to watch library ${library.id} with import path(s) ${library.importPaths}`);
|
||||
|
||||
const matcher = picomatch(`**/*{${mimeTypes.getSupportedFileExtensions().join(',')}}`, {
|
||||
nocase: true,
|
||||
ignore: library.exclusionPatterns,
|
||||
});
|
||||
const { isExcluded, isSupported } = createMatchers(library.exclusionPatterns);
|
||||
|
||||
let _resolve: () => void;
|
||||
const ready$ = new Promise<void>((resolve) => (_resolve = resolve));
|
||||
|
||||
const handler = async (event: string, path: string) => {
|
||||
if (matcher(path)) {
|
||||
this.logger.debug(`File ${event} event received for ${path} in library ${library.id}}`);
|
||||
await this.jobRepository.queue({
|
||||
name: JobName.LibrarySyncFiles,
|
||||
data: { libraryId: library.id, paths: [path] },
|
||||
});
|
||||
} else {
|
||||
const ignored = !isSupported(path);
|
||||
|
||||
if (ignored) {
|
||||
this.logger.verbose(`Ignoring file ${event} event for ${path} in library ${library.id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.logger.debug(`File ${event} event received for ${path} in library ${library.id}}`);
|
||||
await this.jobRepository.queue({
|
||||
name: JobName.LibrarySyncFiles,
|
||||
data: { libraryId: library.id, paths: [path] },
|
||||
});
|
||||
};
|
||||
|
||||
const deletionHandler = async (path: string) => {
|
||||
@@ -123,6 +138,7 @@ export class LibraryService extends BaseService {
|
||||
{
|
||||
usePolling: false,
|
||||
ignoreInitial: true,
|
||||
ignored: isExcluded,
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 5000,
|
||||
pollInterval: 1000,
|
||||
|
||||
@@ -190,7 +190,13 @@ const checkOtherAccess = async (access: AccessRepository, request: OtherAccessRe
|
||||
}
|
||||
|
||||
case Permission.AlbumUpdate: {
|
||||
return await access.album.checkOwnerAccess(auth.user.id, ids);
|
||||
const isOwner = await access.album.checkOwnerAccess(auth.user.id, ids);
|
||||
const isShared = await access.album.checkSharedAlbumAccess(
|
||||
auth.user.id,
|
||||
setDifference(ids, isOwner),
|
||||
AlbumUserRole.Editor,
|
||||
);
|
||||
return setUnion(isOwner, isShared);
|
||||
}
|
||||
|
||||
case Permission.AlbumDelete: {
|
||||
@@ -198,7 +204,13 @@ const checkOtherAccess = async (access: AccessRepository, request: OtherAccessRe
|
||||
}
|
||||
|
||||
case Permission.AlbumShare: {
|
||||
return await access.album.checkOwnerAccess(auth.user.id, ids);
|
||||
const isOwner = await access.album.checkOwnerAccess(auth.user.id, ids);
|
||||
const isShared = await access.album.checkSharedAlbumAccess(
|
||||
auth.user.id,
|
||||
setDifference(ids, isOwner),
|
||||
AlbumUserRole.Editor,
|
||||
);
|
||||
return setUnion(isOwner, isShared);
|
||||
}
|
||||
|
||||
case Permission.AlbumDownload: {
|
||||
|
||||
@@ -30,6 +30,7 @@ import { DatabaseRepository } from 'src/repositories/database.repository';
|
||||
import { EmailRepository } from 'src/repositories/email.repository';
|
||||
import { EventRepository } from 'src/repositories/event.repository';
|
||||
import { JobRepository } from 'src/repositories/job.repository';
|
||||
import { LibraryRepository } from 'src/repositories/library.repository';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { MachineLearningRepository } from 'src/repositories/machine-learning.repository';
|
||||
import { MapRepository } from 'src/repositories/map.repository';
|
||||
@@ -405,6 +406,7 @@ const newRealRepository = <T>(key: ClassConstructor<T>, db: Kysely<DB>): T => {
|
||||
case AssetRepository:
|
||||
case AssetEditRepository:
|
||||
case AssetJobRepository:
|
||||
case LibraryRepository:
|
||||
case MemoryRepository:
|
||||
case NotificationRepository:
|
||||
case OcrRepository:
|
||||
@@ -466,6 +468,7 @@ const newMockRepository = <T>(key: ClassConstructor<T>) => {
|
||||
case AlbumRepository:
|
||||
case AssetRepository:
|
||||
case AssetJobRepository:
|
||||
case LibraryRepository:
|
||||
case ConfigRepository:
|
||||
case CryptoRepository:
|
||||
case MemoryRepository:
|
||||
|
||||
135
server/test/medium/specs/repositories/storage.repository.spec.ts
Normal file
135
server/test/medium/specs/repositories/storage.repository.spec.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
import { Kysely } from 'kysely';
|
||||
import { mkdtemp, rm, unlink, writeFile } from 'node:fs/promises';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { StorageRepository } from 'src/repositories/storage.repository';
|
||||
import { DB } from 'src/schema';
|
||||
import { BaseService } from 'src/services/base.service';
|
||||
import { newMediumService } from 'test/medium.factory';
|
||||
import { getKyselyDB } from 'test/utils';
|
||||
|
||||
let defaultDatabase: Kysely<DB>;
|
||||
|
||||
const setup = (db?: Kysely<DB>) => {
|
||||
const { ctx } = newMediumService(BaseService, {
|
||||
database: db || defaultDatabase,
|
||||
real: [],
|
||||
mock: [LoggingRepository],
|
||||
});
|
||||
|
||||
return { ctx, sut: ctx.get(StorageRepository) };
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
defaultDatabase = await getKyselyDB();
|
||||
});
|
||||
|
||||
const watchForEvent = (
|
||||
sut: StorageRepository,
|
||||
folder: string,
|
||||
event: 'add' | 'change' | 'unlink',
|
||||
action: () => Promise<void>,
|
||||
): Promise<string> => {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
void close().finally(() => reject(new Error(`Timed out waiting for ${event} event`)));
|
||||
}, 10_000);
|
||||
|
||||
const onResolve = (path: string) => {
|
||||
clearTimeout(timeout);
|
||||
void close().finally(() => resolve(path));
|
||||
};
|
||||
|
||||
const onReject = (error: Error) => {
|
||||
clearTimeout(timeout);
|
||||
void close().finally(() => reject(error));
|
||||
};
|
||||
|
||||
const close = sut.watch(
|
||||
[folder],
|
||||
{
|
||||
ignoreInitial: true,
|
||||
usePolling: true,
|
||||
interval: 50,
|
||||
},
|
||||
{
|
||||
onReady: () => {
|
||||
void action().catch((error) => onReject(error as Error));
|
||||
},
|
||||
onAdd: (path) => {
|
||||
if (event === 'add') {
|
||||
onResolve(path);
|
||||
}
|
||||
},
|
||||
onChange: (path) => {
|
||||
if (event === 'change') {
|
||||
onResolve(path);
|
||||
}
|
||||
},
|
||||
onUnlink: (path) => {
|
||||
if (event === 'unlink') {
|
||||
onResolve(path);
|
||||
}
|
||||
},
|
||||
onError: (error) => onReject(error),
|
||||
},
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
describe(StorageRepository.name, () => {
|
||||
describe('watch', () => {
|
||||
it('should fire create (add) events', async () => {
|
||||
const { sut } = setup();
|
||||
const folder = await mkdtemp(join(tmpdir(), 'immich-storage-watch-add-'));
|
||||
const file = join(folder, 'created.jpg');
|
||||
|
||||
try {
|
||||
const changedPath = await watchForEvent(sut, folder, 'add', async () => {
|
||||
await writeFile(file, 'created');
|
||||
});
|
||||
|
||||
expect(changedPath).toBe(file);
|
||||
} finally {
|
||||
await rm(folder, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it('should fire change events', async () => {
|
||||
const { sut } = setup();
|
||||
const folder = await mkdtemp(join(tmpdir(), 'immich-storage-watch-change-'));
|
||||
const file = join(folder, 'changed.jpg');
|
||||
|
||||
await writeFile(file, 'before');
|
||||
|
||||
try {
|
||||
const changedPath = await watchForEvent(sut, folder, 'change', async () => {
|
||||
await writeFile(file, 'after');
|
||||
});
|
||||
|
||||
expect(changedPath).toBe(file);
|
||||
} finally {
|
||||
await rm(folder, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it('should fire unlink events', async () => {
|
||||
const { sut } = setup();
|
||||
const folder = await mkdtemp(join(tmpdir(), 'immich-storage-watch-unlink-'));
|
||||
const file = join(folder, 'deleted.jpg');
|
||||
|
||||
await writeFile(file, 'content');
|
||||
|
||||
try {
|
||||
const changedPath = await watchForEvent(sut, folder, 'unlink', async () => {
|
||||
await unlink(file);
|
||||
});
|
||||
|
||||
expect(changedPath).toBe(file);
|
||||
} finally {
|
||||
await rm(folder, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
169
server/test/medium/specs/services/library.service.spec.ts
Normal file
169
server/test/medium/specs/services/library.service.spec.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
import { ChokidarOptions } from 'chokidar';
|
||||
import { Kysely } from 'kysely';
|
||||
import { JobName } from 'src/enum';
|
||||
import { EventRepository } from 'src/repositories/event.repository';
|
||||
import { JobRepository } from 'src/repositories/job.repository';
|
||||
import { LibraryRepository } from 'src/repositories/library.repository';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { StorageRepository, WatchEvents } from 'src/repositories/storage.repository';
|
||||
import { DB } from 'src/schema';
|
||||
import { LibraryService } from 'src/services/library.service';
|
||||
import { newMediumService } from 'test/medium.factory';
|
||||
import { getKyselyDB } from 'test/utils';
|
||||
|
||||
let defaultDatabase: Kysely<DB>;
|
||||
|
||||
const setup = (db?: Kysely<DB>) => {
|
||||
return newMediumService(LibraryService, {
|
||||
database: db || defaultDatabase,
|
||||
real: [LibraryRepository],
|
||||
mock: [EventRepository, JobRepository, LoggingRepository, StorageRepository],
|
||||
});
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
defaultDatabase = await getKyselyDB();
|
||||
});
|
||||
|
||||
const closeWatcher = () => Promise.resolve();
|
||||
|
||||
const setWatchMode = (sut: LibraryService) => {
|
||||
const service = sut as unknown as { lock: boolean; watchLibraries: boolean };
|
||||
service.lock = true;
|
||||
service.watchLibraries = true;
|
||||
};
|
||||
|
||||
const makeMockWatcher =
|
||||
(paths: { add?: string[]; change?: string[]; unlink?: string[] }) =>
|
||||
(_paths: string[], options: ChokidarOptions, events: Partial<WatchEvents>): (() => Promise<void>) => {
|
||||
const ignored = options.ignored as ((path: string) => boolean) | undefined;
|
||||
events.onReady?.();
|
||||
for (const path of paths.add ?? []) {
|
||||
if (!ignored?.(path)) {
|
||||
events.onAdd?.(path);
|
||||
}
|
||||
}
|
||||
|
||||
for (const path of paths.change ?? []) {
|
||||
if (!ignored?.(path)) {
|
||||
events.onChange?.(path);
|
||||
}
|
||||
}
|
||||
|
||||
for (const path of paths.unlink ?? []) {
|
||||
if (!ignored?.(path)) {
|
||||
events.onUnlink?.(path);
|
||||
}
|
||||
}
|
||||
|
||||
return closeWatcher;
|
||||
};
|
||||
|
||||
describe(`${LibraryService.name} (watch, medium)`, () => {
|
||||
it('should queue add and change events for supported files', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const storageRepo = ctx.getMock(StorageRepository);
|
||||
const jobRepo = ctx.getMock(JobRepository);
|
||||
|
||||
jobRepo.queue.mockResolvedValue();
|
||||
setWatchMode(sut);
|
||||
|
||||
const { user } = await ctx.newUser();
|
||||
const library = await sut.create({
|
||||
ownerId: user.id,
|
||||
importPaths: ['/test-assets/temp/watcher-behavior'],
|
||||
exclusionPatterns: ['**/@eaDir/**'],
|
||||
});
|
||||
|
||||
storageRepo.watch.mockImplementation(
|
||||
makeMockWatcher({
|
||||
add: ['/test-assets/temp/watcher-behavior/add.png'],
|
||||
change: ['/test-assets/temp/watcher-behavior/change.jpg'],
|
||||
}),
|
||||
);
|
||||
|
||||
await sut.watchAll();
|
||||
|
||||
expect(jobRepo.queue).toHaveBeenCalledWith({
|
||||
name: JobName.LibrarySyncFiles,
|
||||
data: { libraryId: library.id, paths: ['/test-assets/temp/watcher-behavior/add.png'] },
|
||||
});
|
||||
expect(jobRepo.queue).toHaveBeenCalledWith({
|
||||
name: JobName.LibrarySyncFiles,
|
||||
data: { libraryId: library.id, paths: ['/test-assets/temp/watcher-behavior/change.jpg'] },
|
||||
});
|
||||
|
||||
await sut.onShutdown();
|
||||
});
|
||||
|
||||
it('should queue unlink events for tracked files', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const storageRepo = ctx.getMock(StorageRepository);
|
||||
const jobRepo = ctx.getMock(JobRepository);
|
||||
|
||||
jobRepo.queue.mockResolvedValue();
|
||||
setWatchMode(sut);
|
||||
|
||||
const { user } = await ctx.newUser();
|
||||
const library = await sut.create({
|
||||
ownerId: user.id,
|
||||
importPaths: ['/test-assets/temp/watcher-behavior'],
|
||||
exclusionPatterns: ['**/@eaDir/**'],
|
||||
});
|
||||
|
||||
storageRepo.watch.mockImplementation(
|
||||
makeMockWatcher({
|
||||
unlink: ['/test-assets/temp/watcher-behavior/delete.png'],
|
||||
}),
|
||||
);
|
||||
|
||||
await sut.watchAll();
|
||||
|
||||
expect(jobRepo.queue).toHaveBeenCalledWith({
|
||||
name: JobName.LibraryRemoveAsset,
|
||||
data: { libraryId: library.id, paths: ['/test-assets/temp/watcher-behavior/delete.png'] },
|
||||
});
|
||||
|
||||
await sut.onShutdown();
|
||||
});
|
||||
|
||||
it('should ignore add, change, and unlink events in excluded directories', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
const storageRepo = ctx.getMock(StorageRepository);
|
||||
const jobRepo = ctx.getMock(JobRepository);
|
||||
|
||||
jobRepo.queue.mockResolvedValue();
|
||||
setWatchMode(sut);
|
||||
|
||||
await ctx.newUser().then(({ user }) =>
|
||||
sut.create({
|
||||
ownerId: user.id,
|
||||
importPaths: ['/test-assets/temp/watcher-behavior'],
|
||||
exclusionPatterns: ['**/@eaDir/**'],
|
||||
}),
|
||||
);
|
||||
|
||||
storageRepo.watch.mockImplementation(
|
||||
makeMockWatcher({
|
||||
add: ['/test-assets/temp/watcher-behavior/@eaDir/add.png'],
|
||||
change: ['/test-assets/temp/watcher-behavior/@eaDir/change.png'],
|
||||
unlink: ['/test-assets/temp/watcher-behavior/@eaDir/unlink.png'],
|
||||
}),
|
||||
);
|
||||
|
||||
await sut.watchAll();
|
||||
|
||||
expect(jobRepo.queue).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
name: JobName.LibrarySyncFiles,
|
||||
}),
|
||||
);
|
||||
expect(jobRepo.queue).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
name: JobName.LibraryRemoveAsset,
|
||||
}),
|
||||
);
|
||||
|
||||
await sut.onShutdown();
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "immich-web",
|
||||
"version": "2.6.1",
|
||||
"version": "2.6.2",
|
||||
"license": "GNU Affero General Public License version 3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
{ label: '2:3', value: '2:3', width: 16, height: 24 },
|
||||
{ label: '16:9', value: '16:9', width: 24, height: 14 },
|
||||
{ label: '9:16', value: '9:16', width: 14, height: 24 },
|
||||
{ label: 'Square', value: '1:1', width: 20, height: 20 },
|
||||
{ label: $t('crop_aspect_ratio_square'), value: '1:1', width: 20, height: 20 },
|
||||
];
|
||||
|
||||
let isRotated = $derived(transformManager.normalizedRotation % 180 !== 0);
|
||||
|
||||
@@ -28,7 +28,10 @@
|
||||
let { onClose }: Props = $props();
|
||||
|
||||
onMount(async () => {
|
||||
albums = await getAllAlbums({});
|
||||
// TODO the server should *really* just return all albums (paginated ideally)
|
||||
const ownedAlbums = await getAllAlbums({ shared: false });
|
||||
ownedAlbums.push.apply(ownedAlbums, await getAllAlbums({ shared: true }));
|
||||
albums = ownedAlbums;
|
||||
recentAlbums = albums.sort((a, b) => (new Date(a.updatedAt) > new Date(b.updatedAt) ? -1 : 1)).slice(0, 3);
|
||||
loading = false;
|
||||
});
|
||||
|
||||
@@ -476,13 +476,6 @@
|
||||
<ChangeDate menuItem />
|
||||
<ChangeDescription menuItem />
|
||||
<ChangeLocation menuItem />
|
||||
{#if assetInteraction.selectedAssets.length === 1}
|
||||
<MenuOption
|
||||
text={$t('set_as_album_cover')}
|
||||
icon={mdiImageOutline}
|
||||
onClick={() => updateThumbnailUsingCurrentSelection()}
|
||||
/>
|
||||
{/if}
|
||||
<ArchiveAction
|
||||
menuItem
|
||||
unarchive={assetInteraction.isAllArchived}
|
||||
@@ -490,6 +483,13 @@
|
||||
/>
|
||||
<SetVisibilityAction menuItem onVisibilitySet={handleSetVisibility} />
|
||||
{/if}
|
||||
{#if assetInteraction.selectedAssets.length === 1}
|
||||
<MenuOption
|
||||
text={$t('set_as_album_cover')}
|
||||
icon={mdiImageOutline}
|
||||
onClick={() => updateThumbnailUsingCurrentSelection()}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if $preferences.tags.enabled && assetInteraction.isAllUserOwned}
|
||||
<TagAction menuItem />
|
||||
|
||||
Reference in New Issue
Block a user