refactor: move cli to package folder (#28356)

pull/28358/head
Jason Rasmussen 2026-05-11 14:49:45 -04:00 committed by GitHub
parent fb0a54d548
commit db589455f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 133 additions and 139 deletions

View File

@ -75,7 +75,7 @@
{ {
"label": "Build Immich CLI", "label": "Build Immich CLI",
"type": "shell", "type": "shell",
"command": "pnpm --filter cli build:dev" "command": "pnpm --filter @immich/cli build:dev"
} }
] ]
} }

2
.github/labeler.yml vendored
View File

@ -1,7 +1,7 @@
cli: cli:
- changed-files: - changed-files:
- any-glob-to-any-file: - any-glob-to-any-file:
- cli/src/** - packages/cli/src/**
documentation: documentation:
- changed-files: - changed-files:

View File

@ -3,11 +3,11 @@ on:
push: push:
branches: [main] branches: [main]
paths: paths:
- 'cli/**' - 'packages/cli/**'
- '.github/workflows/cli.yml' - '.github/workflows/cli.yml'
pull_request: pull_request:
paths: paths:
- 'cli/**' - 'packages/cli/**'
- '.github/workflows/cli.yml' - '.github/workflows/cli.yml'
release: release:
types: [published] types: [published]
@ -28,7 +28,7 @@ jobs:
packages: write packages: write
defaults: defaults:
run: run:
working-directory: ./cli working-directory: ./packages/cli
steps: steps:
- id: token - id: token
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
@ -89,7 +89,7 @@ jobs:
- name: Get package version - name: Get package version
id: package-version id: package-version
run: | run: |
version=$(jq -r '.version' cli/package.json) version=$(jq -r '.version' packages/cli/package.json)
echo "version=$version" >> "$GITHUB_OUTPUT" echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Generate docker image tags - name: Generate docker image tags
@ -107,7 +107,7 @@ jobs:
- name: Build and push image - name: Build and push image
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with: with:
file: cli/Dockerfile file: packages/cli/Dockerfile
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
push: ${{ github.event_name == 'release' }} push: ${{ github.event_name == 'release' }}
cache-from: type=gha cache-from: type=gha

View File

@ -39,7 +39,7 @@ jobs:
- 'server/**' - 'server/**'
- 'pnpm-lock.yaml' - 'pnpm-lock.yaml'
cli: cli:
- 'cli/**' - 'packages/cli/**'
- 'packages/sdk/**' - 'packages/sdk/**'
- 'pnpm-lock.yaml' - 'pnpm-lock.yaml'
e2e: e2e:
@ -95,7 +95,7 @@ jobs:
contents: read contents: read
defaults: defaults:
run: run:
working-directory: ./cli working-directory: ./packages/cli
steps: steps:
- id: token - id: token
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
@ -126,7 +126,7 @@ jobs:
contents: read contents: read
defaults: defaults:
run: run:
working-directory: ./cli working-directory: ./packages/cli
steps: steps:
- id: token - id: token
uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0
@ -379,19 +379,14 @@ jobs:
cache: 'pnpm' cache: 'pnpm'
cache-dependency-path: '**/pnpm-lock.yaml' cache-dependency-path: '**/pnpm-lock.yaml'
- name: Setup @immich/sdk - name: Setup packages
run: pnpm --filter @immich/sdk install --frozen-lockfile && pnpm --filter @immich/sdk build run: pnpm --filter "@immich/*" install --frozen-lockfile && pnpm --filter "@immich/*" build
- name: Run setup web - name: Run setup web
run: pnpm install --frozen-lockfile && pnpm exec svelte-kit sync run: pnpm install --frozen-lockfile && pnpm exec svelte-kit sync
working-directory: ./web working-directory: ./web
if: ${{ !cancelled() }} if: ${{ !cancelled() }}
- name: Run setup cli
run: pnpm install --frozen-lockfile && pnpm build
working-directory: ./cli
if: ${{ !cancelled() }}
- name: Install dependencies - name: Install dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
if: ${{ !cancelled() }} if: ${{ !cancelled() }}

10
.vscode/launch.json vendored
View File

@ -23,15 +23,17 @@
"type": "node", "type": "node",
"request": "launch", "request": "launch",
"name": "Immich CLI", "name": "Immich CLI",
"program": "${workspaceFolder}/cli/dist/index.js", "program": "${workspaceFolder}/packages/cli/dist/index.js",
"args": ["upload", "--help"], "args": ["upload", "--help"],
"runtimeArgs": ["--enable-source-maps"], "runtimeArgs": ["--enable-source-maps"],
"console": "integratedTerminal", "console": "integratedTerminal",
"resolveSourceMapLocations": ["${workspaceFolder}/cli/dist/**/*.js.map"], "resolveSourceMapLocations": [
"${workspaceFolder}/packages/cli/dist/**/*.js.map"
],
"sourceMaps": true, "sourceMaps": true,
"outFiles": ["${workspaceFolder}/cli/dist/**/*.js"], "outFiles": ["${workspaceFolder}/packages/cli/dist/**/*.js"],
"skipFiles": ["<node_internals>/**"], "skipFiles": ["<node_internals>/**"],
"preLaunchTask": "Build Immich CLI" "preLaunchTask": "Build @immich/cli"
} }
] ]
} }

View File

@ -66,7 +66,7 @@ VOLUME_DIRS = \
./packages/sdk/node_modules \ ./packages/sdk/node_modules \
./.github/node_modules \ ./.github/node_modules \
./node_modules \ ./node_modules \
./cli/node_modules ./packages/cli/node_modules
# Include .env file if it exists # Include .env file if it exists
-include docker/.env -include docker/.env

View File

@ -25,7 +25,7 @@ services:
- server_node_modules:/usr/src/app/server/node_modules - server_node_modules:/usr/src/app/server/node_modules
- web_node_modules:/usr/src/app/web/node_modules - web_node_modules:/usr/src/app/web/node_modules
- github_node_modules:/usr/src/app/.github/node_modules - github_node_modules:/usr/src/app/.github/node_modules
- cli_node_modules:/usr/src/app/cli/node_modules - cli_node_modules:/usr/src/app/packages/cli/node_modules
- docs_node_modules:/usr/src/app/docs/node_modules - docs_node_modules:/usr/src/app/docs/node_modules
- e2e_node_modules:/usr/src/app/e2e/node_modules - e2e_node_modules:/usr/src/app/e2e/node_modules
- sdk_node_modules:/usr/src/app/packages/sdk/node_modules - sdk_node_modules:/usr/src/app/packages/sdk/node_modules

View File

@ -10,7 +10,8 @@ Our [GitHub Repository](https://github.com/immich-app/immich) is a [monorepo](ht
| :------------------ | :------------------------------------------------------------------- | | :------------------ | :------------------------------------------------------------------- |
| `.github/` | Github templates and action workflows | | `.github/` | Github templates and action workflows |
| `.vscode/` | VSCode debug launch profiles | | `.vscode/` | VSCode debug launch profiles |
| `cli/` | Source code for the work-in-progress CLI rewrite | | `packages/cli` | Source code for the CLI |
| `packages/sdk` | Source code for the generated OpenAPI SDK |
| `docker/` | Docker compose resources for dev, test, production | | `docker/` | Docker compose resources for dev, test, production |
| `design/` | Screenshots and logos for the README | | `design/` | Screenshots and logos for the README |
| `docs/` | Source code for the [https://immich.app](https://immich.app) website | | `docs/` | Source code for the [https://immich.app](https://immich.app) website |

View File

@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs';
import { immichCli } from 'src/utils'; import { immichCli } from 'src/utils';
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
const pkg = JSON.parse(readFileSync('../cli/package.json', 'utf8')); const pkg = JSON.parse(readFileSync('../packages/cli/package.json', 'utf8'));
describe(`immich --version`, () => { describe(`immich --version`, () => {
describe('immich --version', () => { describe('immich --version', () => {

View File

@ -90,7 +90,7 @@ export const tempDir = tmpdir();
export const asBearerAuth = (accessToken: string) => ({ Authorization: `Bearer ${accessToken}` }); export const asBearerAuth = (accessToken: string) => ({ Authorization: `Bearer ${accessToken}` });
export const asKeyAuth = (key: string) => ({ 'x-api-key': key }); export const asKeyAuth = (key: string) => ({ 'x-api-key': key });
export const immichCli = (args: string[]) => export const immichCli = (args: string[]) =>
executeCommand('pnpm', ['exec', 'immich', '-d', `/${tempDir}/immich/`, ...args], { cwd: '../cli' }).promise; executeCommand('pnpm', ['exec', 'immich', '-d', `/${tempDir}/immich/`, ...args], { cwd: '../packages/cli' }).promise;
export const dockerExec = (args: string[]) => export const dockerExec = (args: string[]) =>
executeCommand('docker', ['exec', '-i', 'immich-e2e-server', '/bin/bash', '-c', args.join(' ')]); executeCommand('docker', ['exec', '-i', 'immich-e2e-server', '/bin/bash', '-c', args.join(' ')]);
export const immichAdmin = (args: string[]) => dockerExec([`immich-admin ${args.join(' ')}`]); export const immichAdmin = (args: string[]) => dockerExec([`immich-admin ${args.join(' ')}`]);

View File

@ -65,7 +65,7 @@ if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then
pnpm version "$NEXT_SERVER" --no-git-tag-version pnpm version "$NEXT_SERVER" --no-git-tag-version
pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix server pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix server
pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix i18n pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix i18n
pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix cli pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix packages/cli
pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix web pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix web
pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix e2e pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix e2e
pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix packages/sdk pnpm version "$NEXT_SERVER" --no-git-tag-version --prefix packages/sdk

View File

@ -4,7 +4,7 @@ experimental_monorepo_root = true
config_roots = [ config_roots = [
"plugins", "plugins",
"server", "server",
"cli", "packages/cli",
"deployment", "deployment",
"mobile", "mobile",
"e2e", "e2e",

View File

@ -2,13 +2,11 @@ FROM node:24.1.0-alpine3.20@sha256:8fe019e0d57dbdce5f5c27c0b63d2775cf34b00e3755a
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY package* pnpm* .pnpmfile.cjs ./ COPY package* pnpm* .pnpmfile.cjs ./
COPY ./cli ./cli/
COPY ./packages ./packages/ COPY ./packages ./packages/
RUN corepack enable pnpm && \ RUN corepack enable pnpm && \
pnpm install --filter @immich/sdk --filter @immich/cli --frozen-lockfile && \ pnpm --filter @immich/sdk --filter @immich/cli install --frozen-lockfile && \
pnpm --filter @immich/sdk build && \ pnpm --filter @immich/sdk --filter @immich/cli build
pnpm --filter @immich/cli build
WORKDIR /import WORKDIR /import
ENTRYPOINT ["node", "/usr/src/app/cli/dist"] ENTRYPOINT ["node", "/usr/src/app/packages/cli/dist"]

View File

@ -2,6 +2,11 @@
"name": "@immich/cli", "name": "@immich/cli",
"version": "2.7.5", "version": "2.7.5",
"description": "Command Line Interface (CLI) for Immich", "description": "Command Line Interface (CLI) for Immich",
"repository": {
"type": "git",
"url": "git+https://github.com/immich-app/immich.git",
"directory": "packages/cli"
},
"type": "module", "type": "module",
"exports": "./dist/index.js", "exports": "./dist/index.js",
"bin": { "bin": {
@ -52,11 +57,6 @@
"format:fix": "prettier --cache --write --list-different .", "format:fix": "prettier --cache --write --list-different .",
"check": "tsc --noEmit" "check": "tsc --noEmit"
}, },
"repository": {
"type": "git",
"url": "git+https://github.com/immich-app/immich.git",
"directory": "cli"
},
"engines": { "engines": {
"node": ">=20.0.0" "node": ">=20.0.0"
}, },

View File

@ -24,103 +24,6 @@ importers:
specifier: ^3.7.4 specifier: ^3.7.4
version: 3.8.3 version: 3.8.3
cli:
dependencies:
chokidar:
specifier: ^4.0.3
version: 4.0.3
fast-glob:
specifier: ^3.3.2
version: 3.3.3
fastq:
specifier: ^1.17.1
version: 1.20.1
lodash-es:
specifier: ^4.17.21
version: 4.18.1
micromatch:
specifier: ^4.0.8
version: 4.0.8
devDependencies:
'@eslint/js':
specifier: ^10.0.0
version: 10.0.1(eslint@10.2.1(jiti@2.6.1))
'@immich/sdk':
specifier: workspace:*
version: link:../packages/sdk
'@types/byte-size':
specifier: ^8.1.0
version: 8.1.2
'@types/cli-progress':
specifier: ^3.11.0
version: 3.11.6
'@types/lodash-es':
specifier: ^4.17.12
version: 4.17.12
'@types/micromatch':
specifier: ^4.0.9
version: 4.0.10
'@types/mock-fs':
specifier: ^4.13.1
version: 4.13.4
'@types/node':
specifier: ^24.12.2
version: 24.12.2
'@vitest/coverage-v8':
specifier: ^4.0.0
version: 4.1.5(vitest@4.1.5)
byte-size:
specifier: ^9.0.0
version: 9.0.1
cli-progress:
specifier: ^3.12.0
version: 3.12.0
commander:
specifier: ^12.0.0
version: 12.1.0
eslint:
specifier: ^10.0.0
version: 10.2.1(jiti@2.6.1)
eslint-config-prettier:
specifier: ^10.1.8
version: 10.1.8(eslint@10.2.1(jiti@2.6.1))
eslint-plugin-prettier:
specifier: ^5.1.3
version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(prettier@3.8.3)
eslint-plugin-unicorn:
specifier: ^64.0.0
version: 64.0.0(eslint@10.2.1(jiti@2.6.1))
globals:
specifier: ^17.0.0
version: 17.5.0
mock-fs:
specifier: ^5.2.0
version: 5.5.0
prettier:
specifier: ^3.7.4
version: 3.8.3
prettier-plugin-organize-imports:
specifier: ^4.0.0
version: 4.3.0(prettier@3.8.3)(typescript@6.0.3)
typescript:
specifier: ^6.0.0
version: 6.0.3
typescript-eslint:
specifier: ^8.58.0
version: 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)
vite:
specifier: ^8.0.0
version: 8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
vitest:
specifier: ^4.0.0
version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
vitest-fetch-mock:
specifier: ^0.4.0
version: 0.4.5(vitest@4.1.5)
yaml:
specifier: ^2.3.1
version: 2.8.3
docs: docs:
dependencies: dependencies:
'@docusaurus/core': '@docusaurus/core':
@ -201,7 +104,7 @@ importers:
version: 10.4.0 version: 10.4.0
'@immich/cli': '@immich/cli':
specifier: workspace:* specifier: workspace:*
version: link:../cli version: link:../packages/cli
'@immich/e2e-auth-server': '@immich/e2e-auth-server':
specifier: workspace:* specifier: workspace:*
version: link:../e2e-auth-server version: link:../e2e-auth-server
@ -314,6 +217,103 @@ importers:
specifier: ^4.1.1 specifier: ^4.1.1
version: 4.2.0(prettier@3.8.3) version: 4.2.0(prettier@3.8.3)
packages/cli:
dependencies:
chokidar:
specifier: ^4.0.3
version: 4.0.3
fast-glob:
specifier: ^3.3.2
version: 3.3.3
fastq:
specifier: ^1.17.1
version: 1.20.1
lodash-es:
specifier: ^4.17.21
version: 4.18.1
micromatch:
specifier: ^4.0.8
version: 4.0.8
devDependencies:
'@eslint/js':
specifier: ^10.0.0
version: 10.0.1(eslint@10.2.1(jiti@2.6.1))
'@immich/sdk':
specifier: workspace:*
version: link:../sdk
'@types/byte-size':
specifier: ^8.1.0
version: 8.1.2
'@types/cli-progress':
specifier: ^3.11.0
version: 3.11.6
'@types/lodash-es':
specifier: ^4.17.12
version: 4.17.12
'@types/micromatch':
specifier: ^4.0.9
version: 4.0.10
'@types/mock-fs':
specifier: ^4.13.1
version: 4.13.4
'@types/node':
specifier: ^24.12.2
version: 24.12.2
'@vitest/coverage-v8':
specifier: ^4.0.0
version: 4.1.5(vitest@4.1.5)
byte-size:
specifier: ^9.0.0
version: 9.0.1
cli-progress:
specifier: ^3.12.0
version: 3.12.0
commander:
specifier: ^12.0.0
version: 12.1.0
eslint:
specifier: ^10.0.0
version: 10.2.1(jiti@2.6.1)
eslint-config-prettier:
specifier: ^10.1.8
version: 10.1.8(eslint@10.2.1(jiti@2.6.1))
eslint-plugin-prettier:
specifier: ^5.1.3
version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(prettier@3.8.3)
eslint-plugin-unicorn:
specifier: ^64.0.0
version: 64.0.0(eslint@10.2.1(jiti@2.6.1))
globals:
specifier: ^17.0.0
version: 17.5.0
mock-fs:
specifier: ^5.2.0
version: 5.5.0
prettier:
specifier: ^3.7.4
version: 3.8.3
prettier-plugin-organize-imports:
specifier: ^4.0.0
version: 4.3.0(prettier@3.8.3)(typescript@6.0.3)
typescript:
specifier: ^6.0.0
version: 6.0.3
typescript-eslint:
specifier: ^8.58.0
version: 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)
vite:
specifier: ^8.0.0
version: 8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)
vitest:
specifier: ^4.0.0
version: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
vitest-fetch-mock:
specifier: ^0.4.0
version: 0.4.5(vitest@4.1.5)
yaml:
specifier: ^2.3.1
version: 2.8.3
packages/sdk: packages/sdk:
dependencies: dependencies:
'@oazapfts/runtime': '@oazapfts/runtime':
@ -18018,7 +18018,7 @@ snapshots:
obug: 2.1.1 obug: 2.1.1
std-env: 4.1.0 std-env: 4.1.0
tinyrainbow: 3.1.0 tinyrainbow: 3.1.0
vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@2.11.2))(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) vitest: 4.1.5(@opentelemetry/api@1.9.1)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.6.1)(sass@1.99.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3))
'@vitest/expect@3.2.4': '@vitest/expect@3.2.4':
dependencies: dependencies:

View File

@ -1,6 +1,5 @@
packages: packages:
- packages/** - packages/**
- cli
- docs - docs
- e2e - e2e
- e2e-auth-server - e2e-auth-server

View File

@ -40,7 +40,6 @@ RUN --mount=type=cache,id=pnpm-web,target=/buildcache/pnpm-store \
FROM builder AS cli FROM builder AS cli
COPY ./cli ./cli/
COPY ./packages ./packages/ COPY ./packages ./packages/
RUN --mount=type=cache,id=pnpm-cli,target=/buildcache/pnpm-store \ RUN --mount=type=cache,id=pnpm-cli,target=/buildcache/pnpm-store \
--mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=package.json,target=package.json \