diff --git a/.github/workflows/dockerfile-hadolint.yml b/.github/workflows/dockerfile-hadolint.yml new file mode 100644 index 00000000..0783a84e --- /dev/null +++ b/.github/workflows/dockerfile-hadolint.yml @@ -0,0 +1,42 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# GitHub recommends pinning actions to a commit SHA. +# To get a newer version, you will need to update the SHA. +# You can also reference a tag or branch, but the action may change without warning. + +name: Lint Dockerfiles + +on: + push: + branches: + - '**' + +jobs: + dockerfile_linting: + name: Dockerfile linting + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Lint Alpine Dockerfile + uses: hadolint/hadolint-action@v3.1.0 + with: + dockerfile: ./docker/alpine/Dockerfile.build + config: ./docker/.config/hadolint.yml + - name: Lint Debian Bookworm Dockerfile + uses: hadolint/hadolint-action@v3.1.0 + with: + dockerfile: ./docker/debian-bookworm/Dockerfile.build + config: ./docker/.config/hadolint.yml + - name: Lint Debian Bullseye Dockerfile + uses: hadolint/hadolint-action@v3.1.0 + with: + dockerfile: ./docker/debian-bullseye/Dockerfile.build + config: ./docker/.config/hadolint.yml + - name: Lint Debian Bullseye Self-contained Dockerfile + uses: hadolint/hadolint-action@v3.1.0 + with: + dockerfile: ./docker/debian-bullseye/selfcontained/Dockerfile + config: ./docker/.config/hadolint.yml \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2e0fc4c6..d7008cf2 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,5 @@ test.* .DS_Store /coverage/ .nyc_output/ -.vscode* \ No newline at end of file +.vscode* +!test/setup-local.js # Excludes setup.js from the ignore rule \ No newline at end of file diff --git a/.mocharc.js b/.mocharc.js new file mode 100644 index 00000000..2f4f1c65 --- /dev/null +++ b/.mocharc.js @@ -0,0 +1,5 @@ +module.exports = { + timeout: 20000, // Set timeout to 20 seconds (good for slow test setups) + require: 'test/setup-local.js', + recursive: true, // Run tests in subdirectories + }; \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 184e47f1..5086bdde 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -105,3 +105,34 @@ Client side: 15. Setting `content` BehaviorSubject (rxjs) with the `ContentWrapperWithError` from the server. 16. Rendering gallery: UI is data binded to the `galleryService.content` [gallery.component.html] +## Running the tests locally +You can run tests in various ways. If you use VS Code, the built-in test explorer is a good way to visualize and run the tests. You can also run tests from the command line. + +- Run all tests: + + `npx mocha` +- Run all tests in parallel and report with very verbose output (to debug tests that don't run): + + `npx mocha --reporter spec --parallel` +- Run a specific test (here the SettingsRouter in the backend): + + `npx mocha ./test/backend/integration/routers/admin/SettingsRouter.js` + +### MySQL / MariaDB tests + The MySQL / MariaDB tests needs a separate database to be running during the test. If you have docker, you can start one with the required test-settings, using the command below: + + `docker run --name pigallery_test -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=pigallery_test -e MYSQL_USER=user -e MYSQL_PASSWORD=password -p3306:3306 -d mariadb:10.3 --log-bin --binlog-format=MIXED` + + Start this betfore running the tests in text explorer or the command line, if you want to include the MySQL tests. + + Once you're finished with the testing, you can shut down the container again: + + `docker stop pigallery_test` + + or you can shut it down AND remove it: + + `docker stop pigallery_test && docker rm pigallery_test` + + + + \ No newline at end of file diff --git a/docker/.config/hadolint.yml b/docker/.config/hadolint.yml new file mode 100644 index 00000000..c5f966d1 --- /dev/null +++ b/docker/.config/hadolint.yml @@ -0,0 +1,3 @@ +ignored: + - DL3008 + - DL3018 \ No newline at end of file diff --git a/docker/CONTRIBUTING.md b/docker/CONTRIBUTING.md new file mode 100644 index 00000000..40ffe365 --- /dev/null +++ b/docker/CONTRIBUTING.md @@ -0,0 +1,17 @@ +# PiGallery2 Docker Contribution guide (draft) + +Remember to update all the Dockerfiles. + +## Linting +To quality check your dockerfile changes you can use hadolint: + +1. Start the docker daemon if it's not already started: `sudo dockerd` +2. Change dir to the docker folder. +3. Run hadolint on the alpine dockerfile: `docker run --rm -i -v ./.config/hadolint.yml:/.config/hadolint.yaml hadolint/hadolint < ./alpine/Dockerfile.build` +4. Run hadolint on the debian-bookworm dockerfile: `docker run --rm -i -v ./.config/hadolint.yml:/.config/hadolint.yaml hadolint/hadolint < ./debian-bookworm/Dockerfile.build` +5. Run hadolint on the debian-bullseye dockerfile: `docker run --rm -i -v ./.config/hadolint.yml:/.config/hadolint.yaml hadolint/hadolint < ./debian-bullseye/Dockerfile.build` +7. Run hadolint on the debian-bullseye selfcontained dockerfile: `docker run --rm -i -v ./.config/hadolint.yml:/.config/hadolint.yaml hadolint/hadolint < ./debian-bullseye/selfcontained/Dockerfile` +8. Fix errors and warnings or add them to ignore list of the [hadolint configuration file](./.config/hadolint.yml) if there is a good reason for that. Read more [here](https://github.com/hadolint/hadolint). + +### Building the docker image locally +TBD \ No newline at end of file diff --git a/docker/alpine/Dockerfile.build b/docker/alpine/Dockerfile.build index bb8b9e47..41d00e8f 100644 --- a/docker/alpine/Dockerfile.build +++ b/docker/alpine/Dockerfile.build @@ -1,8 +1,9 @@ #-----------------BUILDER----------------- #----------------------------------------- FROM node:18-alpine3.17 AS builder -RUN apk add --update-cache --repository https://alpine.global.ssl.fastly.net/alpine/v3.17/community/ \ - python3 build-base sqlite-dev sqlite-libs imagemagick-dev libraw-dev vips-dev vips-heif vips-magick fftw-dev gcc g++ make libc6-compat && ln -snf /usr/bin/python3 /usr/bin/python +RUN apk add --no-cache --repository https://alpine.global.ssl.fastly.net/alpine/v3.17/community/ \ + python3 build-base sqlite-dev sqlite-libs imagemagick-dev libraw-dev vips-dev vips-heif vips-magick fftw-dev gcc g++ make libc6-compat && ln -snf /usr/bin/python3 /usr/bin/python && \ + rm /var/cache/apk/* COPY pigallery2-release /app WORKDIR /app RUN npm install --unsafe-perm --fetch-timeout=90000 @@ -26,10 +27,10 @@ ENV NODE_ENV=production \ PI_DOCKER=true EXPOSE 80 -RUN apk add --update-cache --repository https://alpine.global.ssl.fastly.net/alpine/v3.17/community/ \ - vips vips-cpp vips-heif vips-magick ffmpeg +RUN apk add --no-cache --repository https://alpine.global.ssl.fastly.net/alpine/v3.17/community/ \ + vips vips-cpp vips-heif vips-magick ffmpeg && \ + rm /var/cache/apk/* COPY --from=builder /app /app -VOLUME ["/app/data/config", "/app/data/db", "/app/data/images", "/app/data/tmp"] # Run build time diagnostics to make sure the app would work after build is finished RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json", "--Server-Log-level=silly"] @@ -40,4 +41,3 @@ HEALTHCHECK --interval=40s --timeout=30s --retries=3 --start-period=60s \ # after a extensive job (like video converting), pigallery calls gc, to clean up everthing as fast as possible # Exec form entrypoint is need otherwise (using shell form) ENV variables are not properly passed down to the app ENTRYPOINT ["node", "./src/backend/index", "--expose-gc", "--config-path=/app/data/config/config.json"] - diff --git a/docker/debian-bookworm/Dockerfile.build b/docker/debian-bookworm/Dockerfile.build index c82e2cab..9644ea90 100644 --- a/docker/debian-bookworm/Dockerfile.build +++ b/docker/debian-bookworm/Dockerfile.build @@ -1,7 +1,7 @@ #-----------------BUILDER----------------- #----------------------------------------- FROM node:18-bookworm AS builder -RUN apt update && apt install -y --no-install-recommends libvips-dev python3 +RUN apt-get update && apt-get install -y --no-install-recommends libvips-dev python3 COPY pigallery2-release /app WORKDIR /app RUN npm install --unsafe-perm --fetch-timeout=90000 @@ -30,7 +30,6 @@ RUN apt-get update \ && apt-get clean -q -y \ && rm -rf /var/lib/apt/lists/* COPY --from=builder /app /app -VOLUME ["/app/data/config", "/app/data/db", "/app/data/images", "/app/data/tmp"] # Run build time diagnostics to make sure the app would work after build is finished RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json", "--Server-Log-level=silly"] @@ -41,4 +40,3 @@ HEALTHCHECK --interval=40s --timeout=30s --retries=3 --start-period=60s \ # after a extensive job (like video converting), pigallery calls gc, to clean up everthing as fast as possible # Exec form entrypoint is need otherwise (using shell form) ENV variables are not properly passed down to the app ENTRYPOINT ["node", "./src/backend/index", "--expose-gc", "--config-path=/app/data/config/config.json"] - diff --git a/docker/debian-bullseye/Dockerfile.build b/docker/debian-bullseye/Dockerfile.build index 46f4005d..ac8a6276 100644 --- a/docker/debian-bullseye/Dockerfile.build +++ b/docker/debian-bullseye/Dockerfile.build @@ -1,7 +1,7 @@ #-----------------BUILDER----------------- #----------------------------------------- FROM node:18-bullseye AS builder -RUN apt update && apt install -y --no-install-recommends libvips-dev python3 +RUN apt-get update && apt-get install -y --no-install-recommends libvips-dev python3 COPY pigallery2-release /app WORKDIR /app RUN npm install --unsafe-perm --fetch-timeout=90000 @@ -30,7 +30,6 @@ RUN apt-get update \ && apt-get clean -q -y \ && rm -rf /var/lib/apt/lists/* COPY --from=builder /app /app -VOLUME ["/app/data/config", "/app/data/db", "/app/data/images", "/app/data/tmp"] # Run build time diagnostics to make sure the app would work after build is finished RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json", "--Server-Log-level=silly"] @@ -41,4 +40,3 @@ HEALTHCHECK --interval=40s --timeout=30s --retries=3 --start-period=60s \ # after a extensive job (like video converting), pigallery calls gc, to clean up everthing as fast as possible # Exec form entrypoint is need otherwise (using shell form) ENV variables are not properly passed down to the app ENTRYPOINT ["node", "./src/backend/index", "--expose-gc", "--config-path=/app/data/config/config.json"] - diff --git a/docker/debian-bullseye/selfcontained/Dockerfile b/docker/debian-bullseye/selfcontained/Dockerfile index 6badfec2..4d94887e 100644 --- a/docker/debian-bullseye/selfcontained/Dockerfile +++ b/docker/debian-bullseye/selfcontained/Dockerfile @@ -10,9 +10,9 @@ RUN npm install --unsafe-perm \ && mkdir -p /build/release/data/db \ && mkdir -p /build/release/data/images \ && mkdir -p /build/release/data/tmp \ - && npm run create-release \ - && cd /build/release \ - && npm install --unsafe-perm + && npm run create-release +WORKDIR /build/release +RUN npm install --unsafe-perm #-----------------MAIN-------------------- #----------------------------------------- @@ -33,7 +33,6 @@ RUN apt-get update \ && apt-get clean -q -y \ && rm -rf /var/lib/apt/lists/* COPY --from=builder /build/release /app -VOLUME ["/app/data/config", "/app/data/db", "/app/data/images", "/app/data/tmp"] # Run build time diagnostics to make sure the app would work after build is finished RUN ["node", "./src/backend/index", "--expose-gc", "--run-diagnostics", "--config-path=/app/diagnostics-config.json"] @@ -44,4 +43,3 @@ HEALTHCHECK --interval=40s --timeout=30s --retries=3 --start-period=60s \ # after a extensive job (like video converting), pigallery calls gc, to clean up everthing as fast as possible # Exec form entrypoint is need otherwise (using shell form) ENV variables are not properly passed down to the app ENTRYPOINT ["node", "./src/backend/index", "--expose-gc", "--config-path=/app/data/config/config.json"] - diff --git a/test/setup-local.js b/test/setup-local.js new file mode 100644 index 00000000..5eceac6f --- /dev/null +++ b/test/setup-local.js @@ -0,0 +1,6 @@ +process.env.MYSQL_HOST = 'localhost'; +process.env.MYSQL_USERNAME = 'root'; +process.env.MYSQL_PASSWORD = 'password'; +process.env.MYSQL_PORT = '3306'; +process.env.PORT = '35000'; +process.env.CI = 'true';