name: Test on: workflow_dispatch: pull_request: push: branches: [main] concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: {} jobs: pre-job: runs-on: ubuntu-latest permissions: contents: read outputs: should_run: ${{ steps.check.outputs.should_run }} steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Check what should run id: check uses: immich-app/devtools/actions/pre-job@91f342bb4477c4bc10c576ae739da875d85aa164 # pre-job-action-v2.0.4 with: github-token: ${{ steps.token.outputs.token }} filters: | i18n: - 'i18n/**' web: - 'web/**' - 'i18n/**' - 'packages/sdk/**' - 'pnpm-lock.yaml' server: - 'server/**' - 'pnpm-lock.yaml' cli: - 'packages/cli/**' - 'packages/sdk/**' - 'pnpm-lock.yaml' e2e: - 'e2e/**' - 'pnpm-lock.yaml' mobile: - 'mobile/**' machine-learning: - 'machine-learning/**' .github: - '.github/**' force-filters: | - '.github/workflows/test.yml' force-events: 'workflow_dispatch' server-unit-tests: name: Test & Lint Server needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == true }} runs-on: ubuntu-latest permissions: contents: read steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Run ci-unit run: mise run //server:ci-unit cli-unit-tests: name: Unit Test CLI needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).cli == true }} runs-on: ubuntu-latest permissions: contents: read defaults: run: working-directory: ./packages/cli steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Run ci-unit run: mise run ci-unit cli-unit-tests-win: name: Unit Test CLI (Windows) needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).cli == true }} runs-on: windows-latest permissions: contents: read defaults: run: working-directory: ./packages/cli steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Run setup @immich/sdk run: mise run //:sdk:install && mise run //:sdk:build - name: Run pnpm install run: pnpm install --frozen-lockfile # Skip linter & formatter in Windows test. - name: Run tsc run: pnpm check if: ${{ !cancelled() }} - name: Run unit tests & coverage run: pnpm test if: ${{ !cancelled() }} web-lint: name: Lint Web needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).web == true }} runs-on: mich permissions: contents: read defaults: run: working-directory: ./web steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Run setup @immich/sdk run: mise run //:sdk:install && mise run //:sdk:build - name: Run pnpm install run: pnpm install --frozen-lockfile - name: Run linter run: pnpm lint if: ${{ !cancelled() }} web-unit-tests: name: Test Web needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).web == true }} runs-on: ubuntu-latest permissions: contents: read defaults: run: working-directory: ./web steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Run ci-unit run: mise run ci-unit i18n-tests: name: Test i18n needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).i18n == true }} runs-on: ubuntu-latest permissions: contents: read steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Install dependencies run: pnpm -w install --frozen-lockfile - name: Format run: pnpm format:fix - name: Find file changes uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4 id: verify-changed-files with: files: | i18n/** - name: Verify files have not changed if: steps.verify-changed-files.outputs.files_changed == 'true' env: CHANGED_FILES: ${{ steps.verify-changed-files.outputs.changed_files }} run: | echo "ERROR: i18n files not up to date!" echo "Changed files: ${CHANGED_FILES}" exit 1 e2e-tests-lint: name: End-to-End Lint needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).e2e == true }} runs-on: ubuntu-latest permissions: contents: read defaults: run: working-directory: ./e2e steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Run ci-unit run: mise run ci-unit if: ${{ !cancelled() }} server-medium-tests: name: Medium Tests (Server) needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).server == true }} runs-on: ubuntu-latest permissions: contents: read defaults: run: working-directory: ./server steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false submodules: 'recursive' token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Run ci-medium run: mise run ci-medium if: ${{ !cancelled() }} e2e-tests-server-cli: name: End-to-End Tests (Server & CLI) needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).e2e == true || fromJSON(needs.pre-job.outputs.should_run).server == true || fromJSON(needs.pre-job.outputs.should_run).cli == true }} runs-on: ${{ matrix.runner }} permissions: contents: read defaults: run: working-directory: ./e2e strategy: matrix: runner: [ubuntu-latest, ubuntu-24.04-arm] steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false submodules: 'recursive' token: ${{ steps.token.outputs.token }} - name: Setup pnpm uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' - name: Setup packages run: pnpm --filter @immich/sdk --filter @immich/cli install --frozen-lockfile && pnpm --filter @immich/sdk --filter @immich/cli build - name: Run setup web run: pnpm install --frozen-lockfile && pnpm exec svelte-kit sync working-directory: ./web if: ${{ !cancelled() }} - name: Install dependencies run: pnpm install --frozen-lockfile if: ${{ !cancelled() }} - name: Start Docker Compose run: docker compose up -d --build --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 if: ${{ !cancelled() }} - name: Run e2e tests (api & cli) env: VITEST_DISABLE_DOCKER_SETUP: true run: pnpm test if: ${{ !cancelled() }} - name: Run e2e tests (maintenance) env: VITEST_DISABLE_DOCKER_SETUP: true run: pnpm test:maintenance if: ${{ !cancelled() }} - name: Capture Docker logs if: always() run: docker compose logs --no-color > docker-compose-logs.txt working-directory: ./e2e - name: Archive Docker logs uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: always() with: name: e2e-server-docker-logs-${{ matrix.runner }} path: e2e/docker-compose-logs.txt e2e-tests-web: name: End-to-End Tests (Web) needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).e2e == true || fromJSON(needs.pre-job.outputs.should_run).web == true }} runs-on: ${{ matrix.runner }} permissions: contents: read defaults: run: working-directory: ./e2e strategy: matrix: runner: [ubuntu-latest, ubuntu-24.04-arm] steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false submodules: 'recursive' token: ${{ steps.token.outputs.token }} - name: Setup pnpm uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0 - name: Setup Node uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: '.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' - name: Run setup @immich/sdk run: pnpm --filter @immich/sdk install --frozen-lockfile && pnpm --filter @immich/sdk build if: ${{ !cancelled() }} - name: Install dependencies run: pnpm install --frozen-lockfile if: ${{ !cancelled() }} - name: Install Playwright Browsers run: pnpm exec playwright install chromium --only-shell if: ${{ !cancelled() }} - name: Docker build run: docker compose up -d --build --renew-anon-volumes --force-recreate --remove-orphans --wait --wait-timeout 300 if: ${{ !cancelled() }} - name: Run e2e tests (web) env: PLAYWRIGHT_DISABLE_WEBSERVER: true run: pnpm test:web if: ${{ !cancelled() }} - name: Archive e2e test (web) results uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: success() || failure() with: name: e2e-web-test-results-${{ matrix.runner }} path: e2e/playwright-report/ - name: Run ui tests (web) env: PLAYWRIGHT_DISABLE_WEBSERVER: true run: pnpm test:web:ui if: ${{ !cancelled() }} - name: Archive ui test (web) results uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: success() || failure() with: name: e2e-ui-test-results-${{ matrix.runner }} path: e2e/playwright-report/ - name: Run maintenance tests env: PLAYWRIGHT_DISABLE_WEBSERVER: true run: pnpm test:web:maintenance if: ${{ !cancelled() }} - name: Archive maintenance tests (web) results uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: success() || failure() with: name: e2e-maintenance-isolated-test-results-${{ matrix.runner }} path: e2e/playwright-report/ - name: Capture Docker logs if: always() run: docker compose logs --no-color > docker-compose-logs.txt working-directory: ./e2e - name: Archive Docker logs uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: always() with: name: e2e-web-docker-logs-${{ matrix.runner }} path: e2e/docker-compose-logs.txt success-check-e2e: name: End-to-End Tests Success needs: [e2e-tests-server-cli, e2e-tests-web] permissions: {} runs-on: ubuntu-latest if: always() steps: - uses: immich-app/devtools/actions/success-check@81113db03f6d743efee81e0058c0b43f6cd6f36d # success-check-action-v0.0.6 with: needs: ${{ toJSON(needs) }} mobile-unit-tests: name: Unit Test Mobile needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).mobile == true }} runs-on: ubuntu-latest permissions: contents: read steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Install dependencies run: flutter pub get working-directory: ./mobile - name: Generate translation files run: mise //mobile:codegen:translation - name: Run tests run: mise //mobile:test ml-unit-tests: name: Unit Test ML needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run).machine-learning == true }} runs-on: ubuntu-latest permissions: contents: read defaults: run: working-directory: ./machine-learning steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Run ci-unit run: mise run ci-unit github-files-formatting: name: .github Files Formatting needs: pre-job if: ${{ fromJSON(needs.pre-job.outputs.should_run)['.github'] == true }} runs-on: ubuntu-latest permissions: contents: read defaults: run: working-directory: ./.github steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Run pnpm install run: pnpm install --frozen-lockfile - name: Run formatter run: pnpm format if: ${{ !cancelled() }} shellcheck: name: ShellCheck runs-on: ubuntu-latest permissions: contents: read steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Run ShellCheck uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 # 2.0.0 with: ignore_paths: >- **/open-api/** **/openapi** **/node_modules/** generated-api-up-to-date: name: OpenAPI Clients runs-on: ubuntu-latest permissions: contents: read steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Install server dependencies run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm --filter immich install --frozen-lockfile - name: Run API generation run: mise //:open-api working-directory: open-api - name: Find file changes uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4 id: verify-changed-files with: files: | mobile/openapi packages/sdk open-api/immich-openapi-specs.json - name: Verify files have not changed if: steps.verify-changed-files.outputs.files_changed == 'true' env: CHANGED_FILES: ${{ steps.verify-changed-files.outputs.changed_files }} run: | echo "ERROR: Generated files not up to date!" echo "Changed files: ${CHANGED_FILES}" exit 1 sql-schema-up-to-date: name: SQL Schema Checks runs-on: ubuntu-latest permissions: contents: read services: postgres: image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3@sha256:dbf18b3ffea4a81434c65b71e20d27203baf903a0275f4341e4c16dfd901fd67 env: POSTGRES_PASSWORD: postgres POSTGRES_USER: postgres POSTGRES_DB: immich options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 steps: - id: token uses: immich-app/devtools/actions/create-workflow-token@caa599d954228439ea3e8ce1c3328f41ab120ee6 # create-workflow-token-action-v2.0.0 with: client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false token: ${{ steps.token.outputs.token }} - name: Setup Mise uses: immich-app/devtools/actions/use-mise@cf6e190bacde3d7bda59372a786b36ac7d01536a # use-mise-action-v2.0.1 with: github_token: ${{ steps.token.outputs.token }} - name: Install server dependencies run: SHARP_IGNORE_GLOBAL_LIBVIPS=true pnpm install --frozen-lockfile - name: Build plugins run: mise //:plugins - name: Build the app run: mise //server:build - name: Run existing migrations run: pnpm --filter immich migrations:run - name: Test npm run schema:reset command works run: pnpm --filter immich schema:reset - name: Generate new migrations continue-on-error: true run: pnpm --filter migrations:generate src/TestMigration - name: Find file changes uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4 id: verify-changed-files with: files: | server/src - name: Verify migration files have not changed if: steps.verify-changed-files.outputs.files_changed == 'true' env: CHANGED_FILES: ${{ steps.verify-changed-files.outputs.changed_files }} run: | echo "ERROR: Generated migration files not up to date!" echo "Changed files: ${CHANGED_FILES}" cat ./server/src/*-TestMigration.ts exit 1 - name: Run SQL generation run: mise //:sql env: DB_URL: postgres://postgres:postgres@localhost:5432/immich - name: Find file changes uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4 id: verify-changed-sql-files with: files: | server/src/queries - name: Verify SQL files have not changed if: steps.verify-changed-sql-files.outputs.files_changed == 'true' env: CHANGED_FILES: ${{ steps.verify-changed-sql-files.outputs.changed_files }} run: | echo "ERROR: Generated SQL files not up to date!" echo "Changed files: ${CHANGED_FILES}" git diff exit 1 # mobile-integration-tests: # name: Run mobile end-to-end integration tests # runs-on: macos-latest # steps: # - uses: actions/checkout@v4 # - uses: actions/setup-java@v3 # with: # distribution: 'zulu' # java-version: '12.x' # cache: 'gradle' # - name: Cache android SDK # uses: actions/cache@v3 # id: android-sdk # with: # key: android-sdk # path: | # /usr/local/lib/android/ # ~/.android # - name: Cache Gradle # uses: actions/cache@v3 # with: # path: | # ./mobile/build/ # ./mobile/android/.gradle/ # key: ${{ runner.os }}-flutter-${{ hashFiles('**/*.gradle*', 'pubspec.lock') }} # - name: Setup Android SDK # if: steps.android-sdk.outputs.cache-hit != 'true' # uses: android-actions/setup-android@v2 # - name: AVD cache # uses: actions/cache@v3 # id: avd-cache # with: # path: | # ~/.android/avd/* # ~/.android/adb* # key: avd-29 # - name: create AVD and generate snapshot for caching # if: steps.avd-cache.outputs.cache-hit != 'true' # uses: reactivecircus/android-emulator-runner@v2.27.0 # with: # working-directory: ./mobile # cores: 2 # api-level: 29 # arch: x86_64 # profile: pixel # target: default # force-avd-creation: false # emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none # disable-animations: false # script: echo "Generated AVD snapshot for caching." # - name: Setup Flutter SDK # uses: subosito/flutter-action@v2 # with: # channel: 'stable' # flutter-version: '3.7.3' # cache: true # - name: Run integration tests # uses: Wandalen/wretry.action@master # with: # action: reactivecircus/android-emulator-runner@v2.27.0 # with: | # working-directory: ./mobile # cores: 2 # api-level: 29 # arch: x86_64 # profile: pixel # target: default # force-avd-creation: false # emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none # disable-animations: true # script: | # flutter pub get # flutter test integration_test # attempt_limit: 3