diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..b3201c7 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +/app/node_modules/ diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..1ad3d10 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,58 @@ +name: Publish docker image + +on: + workflow_dispatch: + push: + tags: + - 'v*' + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Get version from package.json + run: echo "PACKAGE_VERSION=$(jq -r '.version' app/package.json)" >> $GITHUB_ENV + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3.2.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile + push: true + platforms: linux/amd64,linux/arm64,linux/arm/v7 + build-args: | + PACKAGE_VERSION=${{ env.PACKAGE_VERSION }} + tags: | + ${{ github.repository }}:${{ env.PACKAGE_VERSION }} + ${{ github.repository }}:latest + ghcr.io/${{ github.repository }}:${{ env.PACKAGE_VERSION }} + ghcr.io/${{ github.repository }}:latest diff --git a/.gitignore b/.gitignore index e5fb8dd..c987d53 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .idea/ .env node_modules/ -/data/ config.json +store.json diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8b266bb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM node:lts-alpine AS builder + +USER node +WORKDIR /app +COPY --chown=node:node app/ ./ + +RUN npm ci \ + && npx tsc + +FROM node:lts-alpine AS runner + +USER node +WORKDIR /app +COPY --from=builder --chown=node:node app/ ./ + +RUN npm ci --omit=dev + +ARG PACKAGE_VERSION +ENV APP_VERSION=${PACKAGE_VERSION} +ENV NODE_ENV=production + +CMD ["node", "dist/index.js" ] diff --git a/package-lock.json b/app/package-lock.json similarity index 99% rename from package-lock.json rename to app/package-lock.json index 7992241..315e84e 100644 --- a/package-lock.json +++ b/app/package-lock.json @@ -10,7 +10,7 @@ "license": "AGPL-3.0", "dependencies": { "@immich/sdk": "^1.137.3", - "dotenv": "^16.4.5", + "node-cron": "^4.2.1", "tslib": "^2.8.1" }, "bin": { @@ -1078,18 +1078,6 @@ "node": ">=6.0.0" } }, - "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2929,6 +2917,15 @@ "dev": true, "license": "MIT" }, + "node_modules/node-cron": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-4.2.1.tgz", + "integrity": "sha512-lgimEHPE/QDgFlywTd8yTR61ptugX3Qer29efeyWw2rv259HtGBNn1vZVmp8lB9uo9wC0t/AT4iGqXxia+CJFg==", + "license": "ISC", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", diff --git a/package.json b/app/package.json similarity index 74% rename from package.json rename to app/package.json index d575586..a98cbc9 100644 --- a/package.json +++ b/app/package.json @@ -4,6 +4,7 @@ "scripts": { "dev": "ts-node src/index.ts", "build": "npx tsc", + "test": "podman build --build-arg PACKAGE_VERSION=$(npm pkg get version | xargs) --format docker -t immich-person-test .. && podman run --init -it -p=3000:3000 -v ../data:/data:Z --restart=always immich-person-test", "start": "node dist/index.js" }, "author": "Alan Grainger", @@ -17,8 +18,8 @@ "bin": "dist/index.js", "dependencies": { "tslib": "^2.8.1", - "dotenv": "^16.4.5", - "@immich/sdk": "^1.137.3" + "@immich/sdk": "^1.137.3", + "node-cron": "^4.2.1" }, "devDependencies": { "@types/node": "^16.18.111", diff --git a/src/function.ts b/app/src/function.ts similarity index 96% rename from src/function.ts rename to app/src/function.ts index 1d2ccb7..ef6fe18 100644 --- a/src/function.ts +++ b/app/src/function.ts @@ -1,8 +1,7 @@ import { Link, Config } from './types' import { addAssetsToAlbum, searchAssets } from '@immich/sdk' import store from './store' - -// require('dotenv').config() +import path from 'path' export class PersonToAlbum { config: Config @@ -20,7 +19,7 @@ export class PersonToAlbum { // Attempt to parse docker-compose config string into JSON (if specified) this.config = JSON.parse(process.env.CONFIG) } else { - const configJson = require('../config.json') + const configJson = require(path.resolve('../data/config.json')) if (typeof configJson === 'object') this.config = configJson } } catch (e) { diff --git a/src/index.ts b/app/src/index.ts similarity index 100% rename from src/index.ts rename to app/src/index.ts diff --git a/src/store.ts b/app/src/store.ts similarity index 94% rename from src/store.ts rename to app/src/store.ts index c90baac..88a32f4 100644 --- a/src/store.ts +++ b/app/src/store.ts @@ -7,7 +7,7 @@ export class JSONKeyValueStore { cache: Map constructor () { - this.filePath = path.resolve('./data/store.json') + this.filePath = path.resolve('../data/store.json') this.cache = new Map() try { const data = fs.readFileSync(this.filePath, 'utf8') diff --git a/src/types.ts b/app/src/types.ts similarity index 100% rename from src/types.ts rename to app/src/types.ts diff --git a/tsconfig.json b/app/tsconfig.json similarity index 100% rename from tsconfig.json rename to app/tsconfig.json diff --git a/config.json.example b/data/config.json.example similarity index 100% rename from config.json.example rename to data/config.json.example diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9f59bdd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +services: + immich-person-to-album: + image: alangrainger/immich-person-to-album:latest + container_name: immich-person-to-album + restart: always + ports: + - "3000:3000" + volumes: + - ./data:/data