mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-04-06 03:19:39 +02:00
Cachefixing test (#5793)
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2
.github/workflows/PR-Auto-Deploy-V2.yml
vendored
2
.github/workflows/PR-Auto-Deploy-V2.yml
vendored
@@ -231,6 +231,8 @@ jobs:
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile
|
||||
push: true
|
||||
cache-from: type=gha,scope=stirling-pdf-latest
|
||||
cache-to: type=gha,mode=max,scope=stirling-pdf-latest
|
||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-${{ steps.commit-hash.outputs.app_short }}
|
||||
build-args: VERSION_TAG=v2-alpha
|
||||
platforms: linux/amd64
|
||||
|
||||
@@ -190,6 +190,8 @@ jobs:
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile
|
||||
push: true
|
||||
cache-from: type=gha,scope=stirling-pdf-latest
|
||||
cache-to: type=gha,mode=max,scope=stirling-pdf-latest
|
||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:pr-${{ needs.check-comment.outputs.pr_number }}
|
||||
build-args: VERSION_TAG=alpha
|
||||
platforms: linux/amd64
|
||||
|
||||
71
.github/workflows/build.yml
vendored
71
.github/workflows/build.yml
vendored
@@ -68,10 +68,20 @@ jobs:
|
||||
java-version: ${{ matrix.jdk-version }}
|
||||
distribution: "temurin"
|
||||
|
||||
- name: Cache Gradle dependency artifacts
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/wrapper
|
||||
~/.gradle/caches/modules-2/files-2.1
|
||||
~/.gradle/caches/modules-2/metadata-2.*
|
||||
key: gradle-deps-${{ runner.os }}-jdk-${{ matrix.jdk-version }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties', '**/*.gradle', '**/*.gradle.kts', 'settings.gradle', 'settings.gradle.kts', 'gradle/libs.versions.toml') }}
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1
|
||||
with:
|
||||
gradle-version: 8.14
|
||||
cache-disabled: true
|
||||
|
||||
- name: Build with Gradle and spring security ${{ matrix.spring-security }}
|
||||
run: ./gradlew build -PnoSpotless
|
||||
@@ -143,10 +153,20 @@ jobs:
|
||||
java-version: "25"
|
||||
distribution: "temurin"
|
||||
|
||||
- name: Cache Gradle dependency artifacts
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/wrapper
|
||||
~/.gradle/caches/modules-2/files-2.1
|
||||
~/.gradle/caches/modules-2/metadata-2.*
|
||||
key: gradle-deps-${{ runner.os }}-jdk-25-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties', '**/*.gradle', '**/*.gradle.kts', 'settings.gradle', 'settings.gradle.kts', 'gradle/libs.versions.toml') }}
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1
|
||||
with:
|
||||
gradle-version: 8.14
|
||||
cache-disabled: true
|
||||
|
||||
- name: Generate OpenAPI documentation
|
||||
run: ./gradlew :stirling-pdf:generateOpenApiDocs
|
||||
@@ -215,10 +235,20 @@ jobs:
|
||||
java-version: "25"
|
||||
distribution: "temurin"
|
||||
|
||||
- name: Cache Gradle dependency artifacts
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/wrapper
|
||||
~/.gradle/caches/modules-2/files-2.1
|
||||
~/.gradle/caches/modules-2/metadata-2.*
|
||||
key: gradle-deps-${{ runner.os }}-jdk-25-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties', '**/*.gradle', '**/*.gradle.kts', 'settings.gradle', 'settings.gradle.kts', 'gradle/libs.versions.toml') }}
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1
|
||||
with:
|
||||
gradle-version: 8.14
|
||||
cache-disabled: true
|
||||
|
||||
- name: check the licenses for compatibility
|
||||
# NOTE: --no-parallel is intentional here. Running the checkLicense task in parallel with other
|
||||
@@ -259,6 +289,8 @@ jobs:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
contents: read
|
||||
checks: write
|
||||
|
||||
steps:
|
||||
@@ -276,14 +308,28 @@ jobs:
|
||||
java-version: "25"
|
||||
distribution: "temurin"
|
||||
|
||||
- name: Cache Gradle dependency artifacts
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/wrapper
|
||||
~/.gradle/caches/modules-2/files-2.1
|
||||
~/.gradle/caches/modules-2/metadata-2.*
|
||||
key: gradle-deps-${{ runner.os }}-jdk-25-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties', '**/*.gradle', '**/*.gradle.kts', 'settings.gradle', 'settings.gradle.kts', 'gradle/libs.versions.toml') }}
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1
|
||||
with:
|
||||
gradle-version: 8.14
|
||||
cache-disabled: true
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
|
||||
|
||||
# Expose ACTIONS_RUNTIME_TOKEN / ACTIONS_RESULTS_URL for docker buildx type=gha cache backend.
|
||||
- name: Expose GitHub runtime for Buildx cache
|
||||
uses: crazy-max/ghaction-github-runtime@v3
|
||||
|
||||
- name: Install Docker Compose
|
||||
run: |
|
||||
sudo curl -SL "https://github.com/docker/compose/releases/download/v2.39.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
@@ -338,12 +384,15 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# - docker-rev: docker/embedded/Dockerfile
|
||||
# artifact-suffix: Dockerfile
|
||||
- docker-rev: docker/embedded/Dockerfile
|
||||
artifact-suffix: Dockerfile
|
||||
cache-scope: stirling-pdf-latest
|
||||
- docker-rev: docker/embedded/Dockerfile.ultra-lite
|
||||
artifact-suffix: Dockerfile.ultra-lite
|
||||
# - docker-rev: docker/embedded/Dockerfile.fat
|
||||
# artifact-suffix: Dockerfile.fat
|
||||
cache-scope: stirling-pdf-ultra-lite
|
||||
- docker-rev: docker/embedded/Dockerfile.fat
|
||||
artifact-suffix: Dockerfile.fat
|
||||
cache-scope: stirling-pdf-fat
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
|
||||
@@ -366,10 +415,20 @@ jobs:
|
||||
java-version: "25"
|
||||
distribution: "temurin"
|
||||
|
||||
- name: Cache Gradle dependency artifacts
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/wrapper
|
||||
~/.gradle/caches/modules-2/files-2.1
|
||||
~/.gradle/caches/modules-2/metadata-2.*
|
||||
key: gradle-deps-${{ runner.os }}-jdk-25-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties', '**/*.gradle', '**/*.gradle.kts', 'settings.gradle', 'settings.gradle.kts', 'gradle/libs.versions.toml') }}
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1
|
||||
with:
|
||||
gradle-version: 8.14
|
||||
cache-disabled: true
|
||||
|
||||
- name: Build application
|
||||
run: ./gradlew build
|
||||
@@ -394,8 +453,8 @@ jobs:
|
||||
context: .
|
||||
file: ./${{ matrix.docker-rev }}
|
||||
push: false
|
||||
cache-from: type=gha,scope=${{ matrix.artifact-suffix }}
|
||||
cache-to: type=gha,mode=max,scope=${{ matrix.artifact-suffix }}
|
||||
cache-from: type=gha,scope=${{ matrix.cache-scope }}
|
||||
cache-to: type=gha,mode=max,scope=${{ matrix.cache-scope }}
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
provenance: true
|
||||
sbom: true
|
||||
|
||||
4
.github/workflows/deploy-on-v2-commit.yml
vendored
4
.github/workflows/deploy-on-v2-commit.yml
vendored
@@ -97,6 +97,8 @@ jobs:
|
||||
context: .
|
||||
file: ./docker/frontend/Dockerfile
|
||||
push: true
|
||||
cache-from: type=gha,scope=stirling-v2-frontend
|
||||
cache-to: type=gha,mode=max,scope=stirling-v2-frontend
|
||||
tags: |
|
||||
${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }}
|
||||
${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-latest
|
||||
@@ -110,6 +112,8 @@ jobs:
|
||||
context: .
|
||||
file: ./docker/backend/Dockerfile
|
||||
push: true
|
||||
cache-from: type=gha,scope=stirling-v2-backend
|
||||
cache-to: type=gha,mode=max,scope=stirling-v2-backend
|
||||
tags: |
|
||||
${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-${{ steps.commit-hashes.outputs.backend_short }}
|
||||
${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-backend-latest
|
||||
|
||||
10
.github/workflows/multiOSReleases.yml
vendored
10
.github/workflows/multiOSReleases.yml
vendored
@@ -48,6 +48,16 @@ jobs:
|
||||
java-version: "25"
|
||||
distribution: "temurin"
|
||||
|
||||
- name: Cache Gradle dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: gradle-${{ runner.os }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
gradle-${{ runner.os }}-
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1
|
||||
with:
|
||||
|
||||
22
.github/workflows/push-docker.yml
vendored
22
.github/workflows/push-docker.yml
vendored
@@ -45,6 +45,16 @@ jobs:
|
||||
java-version: "25"
|
||||
distribution: "temurin"
|
||||
|
||||
- name: Cache Gradle dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: gradle-${{ runner.os }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
gradle-${{ runner.os }}-
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@f29f5a9d7b09a7c6b29859002d29d24e1674c884 # v5.0.1
|
||||
with:
|
||||
@@ -116,8 +126,8 @@ jobs:
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
cache-from: type=gha,scope=stirling-pdf-latest
|
||||
cache-to: type=gha,mode=max,scope=stirling-pdf-latest
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
|
||||
@@ -162,8 +172,8 @@ jobs:
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile.fat
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
cache-from: type=gha,scope=stirling-pdf-fat
|
||||
cache-to: type=gha,mode=max,scope=stirling-pdf-fat
|
||||
tags: ${{ steps.meta-fat.outputs.tags }}
|
||||
labels: ${{ steps.meta-fat.outputs.labels }}
|
||||
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
|
||||
@@ -206,8 +216,8 @@ jobs:
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile.ultra-lite
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
cache-from: type=gha,scope=stirling-pdf-ultra-lite
|
||||
cache-to: type=gha,mode=max,scope=stirling-pdf-ultra-lite
|
||||
tags: ${{ steps.meta-lite.outputs.tags }}
|
||||
labels: ${{ steps.meta-lite.outputs.labels }}
|
||||
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
|
||||
|
||||
3
.github/workflows/tauri-build.yml
vendored
3
.github/workflows/tauri-build.yml
vendored
@@ -15,6 +15,7 @@ on:
|
||||
- linux
|
||||
pull_request:
|
||||
branches: [main, V2-tauri-windows]
|
||||
types: [opened, reopened, synchronize, ready_for_review]
|
||||
paths:
|
||||
- "frontend/src-tauri/**"
|
||||
- "frontend/src/desktop/**"
|
||||
@@ -23,8 +24,6 @@ on:
|
||||
- "frontend/package-lock.json"
|
||||
- "frontend/vite.config.ts"
|
||||
- ".github/workflows/tauri-build.yml"
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
2
.github/workflows/testdriver.yml
vendored
2
.github/workflows/testdriver.yml
vendored
@@ -72,6 +72,8 @@ jobs:
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile
|
||||
push: true
|
||||
cache-from: type=gha,scope=stirling-pdf-latest
|
||||
cache-to: type=gha,mode=max,scope=stirling-pdf-latest
|
||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:test-${{ github.sha }}
|
||||
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
|
||||
platforms: linux/amd64
|
||||
|
||||
@@ -100,10 +100,12 @@ public class FileToPdf {
|
||||
while (entry != null) {
|
||||
Path filePath =
|
||||
tempUnzippedDir.getPath().resolve(sanitizeZipFilename(entry.getName()));
|
||||
Path normalizedTargetDir = tempUnzippedDir.getPath().toAbsolutePath().normalize();
|
||||
Path normalizedTargetDir =
|
||||
tempUnzippedDir.getPath().toAbsolutePath().normalize();
|
||||
Path normalizedFilePath = filePath.toAbsolutePath().normalize();
|
||||
if (!normalizedFilePath.startsWith(normalizedTargetDir)) {
|
||||
throw new IOException("Zip entry path escapes target directory: " + entry.getName());
|
||||
throw new IOException(
|
||||
"Zip entry path escapes target directory: " + entry.getName());
|
||||
}
|
||||
if (!entry.isDirectory()) {
|
||||
Files.createDirectories(filePath.getParent());
|
||||
|
||||
@@ -23,14 +23,14 @@ import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||
import org.springframework.web.multipart.support.MissingServletRequestPartException;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import stirling.software.common.util.ExceptionUtils;
|
||||
import stirling.software.common.util.ExceptionUtils.*;
|
||||
import stirling.software.common.util.RegexPatternUtils;
|
||||
@@ -874,10 +874,16 @@ public class GlobalExceptionHandler {
|
||||
errorMap.put("type", "about:blank");
|
||||
errorMap.put("title", "Not Acceptable");
|
||||
errorMap.put("status", 406);
|
||||
errorMap.put("detail", "The requested resource could not be returned in an acceptable format. Error responses are returned as JSON.");
|
||||
errorMap.put(
|
||||
"detail",
|
||||
"The requested resource could not be returned in an acceptable format. Error responses are returned as JSON.");
|
||||
errorMap.put("instance", request.getRequestURI());
|
||||
errorMap.put("timestamp", Instant.now().toString());
|
||||
errorMap.put("hints", java.util.Arrays.asList("Error responses are always returned as application/json or application/problem+json", "Set Accept header to include application/json for proper error handling"));
|
||||
errorMap.put(
|
||||
"hints",
|
||||
java.util.Arrays.asList(
|
||||
"Error responses are always returned as application/json or application/problem+json",
|
||||
"Set Accept header to include application/json for proper error handling"));
|
||||
|
||||
String errorJson = mapper.writeValueAsString(errorMap);
|
||||
response.getWriter().write(errorJson);
|
||||
|
||||
@@ -4,7 +4,8 @@ FROM ubuntu:noble AS calibre-build
|
||||
|
||||
ARG CALIBRE_VERSION=9.3.1
|
||||
|
||||
RUN set -eux; \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates curl xz-utils libnss3 libfontconfig1 \
|
||||
@@ -185,12 +186,13 @@ RUN set -eux; \
|
||||
# Build the Java application and frontend.
|
||||
FROM gradle:9.3.1-jdk25 AS app-build
|
||||
|
||||
RUN apt-get update \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
apt-get update \
|
||||
&& apt-get install -y --no-install-recommends curl ca-certificates \
|
||||
&& update-ca-certificates \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# JDK 25+: --add-exports is no longer accepted via JAVA_TOOL_OPTIONS; use JDK_JAVA_OPTIONS instead
|
||||
ENV JDK_JAVA_OPTIONS="--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
|
||||
@@ -232,11 +234,13 @@ RUN java -Djarmode=tools -jar app.jar extract --layers --destination /layers
|
||||
# Build Ghostscript 10.06.0 from source in an isolated stage (avoids library conflicts).
|
||||
FROM ubuntu:noble AS gs-build
|
||||
ARG GS_VERSION=10.06.0
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential curl ca-certificates libfontconfig1-dev && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/tmp/gs-build \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential curl ca-certificates libfontconfig1-dev && rm -rf /var/lib/apt/lists/* && \
|
||||
GS_TAG="gs$(printf '%s' "${GS_VERSION}" | tr -d '.')" && \
|
||||
curl -fsSL "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/${GS_TAG}/ghostscript-${GS_VERSION}.tar.gz" | tar xz && \
|
||||
cd /tmp/gs-build && \
|
||||
(test -d "ghostscript-${GS_VERSION}" || curl -fsSL "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/${GS_TAG}/ghostscript-${GS_VERSION}.tar.gz" | tar xz) && \
|
||||
cd "ghostscript-${GS_VERSION}" && \
|
||||
./configure \
|
||||
--prefix=/usr/local \
|
||||
@@ -252,19 +256,22 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
FROM ubuntu:noble AS pdf-tools-build
|
||||
ARG QPDF_VERSION=12.3.2
|
||||
ARG IM_VERSION=7.1.2-13
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/tmp/pdf-tools-build \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential cmake libssl-dev libjpeg-dev zlib1g-dev curl ca-certificates pkg-config \
|
||||
libpng-dev libtiff-dev libwebp-dev libxml2-dev libfreetype6-dev liblcms2-dev libzip-dev liblqr-1-0-dev \
|
||||
libltdl-dev libtool && \
|
||||
libltdl-dev libtool && rm -rf /var/lib/apt/lists/* && \
|
||||
cd /tmp/pdf-tools-build && \
|
||||
# Build QPDF
|
||||
curl -fsSL "https://github.com/qpdf/qpdf/releases/download/v${QPDF_VERSION}/qpdf-${QPDF_VERSION}.tar.gz" | tar xz && \
|
||||
(test -d "qpdf-${QPDF_VERSION}" || curl -fsSL "https://github.com/qpdf/qpdf/releases/download/v${QPDF_VERSION}/qpdf-${QPDF_VERSION}.tar.gz" | tar xz) && \
|
||||
cd "qpdf-${QPDF_VERSION}" && \
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DALLOW_CRYPTO_OPENSSL=ON -DDEFAULT_CRYPTO=openssl && \
|
||||
cmake --build build --parallel "$(nproc)" && \
|
||||
cmake --install build && \
|
||||
cd .. && \
|
||||
# Build ImageMagick 7
|
||||
curl -fsSL "https://github.com/ImageMagick/ImageMagick/archive/refs/tags/${IM_VERSION}.tar.gz" | tar xz && \
|
||||
(test -d "ImageMagick-${IM_VERSION}" || curl -fsSL "https://github.com/ImageMagick/ImageMagick/archive/refs/tags/${IM_VERSION}.tar.gz" | tar xz) && \
|
||||
cd "ImageMagick-${IM_VERSION}" && \
|
||||
./configure --prefix=/usr/local --with-modules --with-perl=no --with-magick-plus-plus=no --with-quantum-depth=16 --disable-static --enable-shared && \
|
||||
make -j"$(nproc)" && \
|
||||
@@ -289,7 +296,8 @@ ENV DEBIAN_FRONTEND=noninteractive \
|
||||
|
||||
ARG UNOSERVER_VERSION=3.6
|
||||
|
||||
RUN set -eux; \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
set -eux; \
|
||||
apt-get update; \
|
||||
# Add LibreOffice Fresh PPA for latest version (26.2.x)
|
||||
apt-get install -y --no-install-recommends software-properties-common; \
|
||||
@@ -351,8 +359,6 @@ RUN set -eux; \
|
||||
\
|
||||
# Cleanup stage.
|
||||
\
|
||||
# apt clean needed without cache mounts
|
||||
apt-get clean; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# Docs / man / info / icons / themes / GUI assets (headless server)
|
||||
|
||||
@@ -5,7 +5,8 @@ FROM ubuntu:noble AS calibre-build
|
||||
|
||||
ARG CALIBRE_VERSION=9.3.1
|
||||
|
||||
RUN set -eux; \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
set -eux; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates curl xz-utils libnss3 libfontconfig1 \
|
||||
@@ -184,12 +185,13 @@ RUN set -eux; \
|
||||
# Build the Java application and frontend.
|
||||
FROM gradle:9.3.1-jdk25 AS app-build
|
||||
|
||||
RUN apt-get update \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
apt-get update \
|
||||
&& apt-get install -y --no-install-recommends curl ca-certificates \
|
||||
&& update-ca-certificates \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# JDK 25+: --add-exports is no longer accepted via JAVA_TOOL_OPTIONS; use JDK_JAVA_OPTIONS instead
|
||||
ENV JDK_JAVA_OPTIONS="--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
|
||||
@@ -228,7 +230,8 @@ FROM ubuntu:noble AS python-build
|
||||
ARG UNOSERVER_VERSION=3.6
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
python3 python3-venv python3-dev \
|
||||
python3-packaging \
|
||||
build-essential \
|
||||
@@ -249,11 +252,13 @@ RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
# Build Ghostscript 10.06.0 from source in an isolated stage (avoids library conflicts).
|
||||
FROM ubuntu:noble AS gs-build
|
||||
ARG GS_VERSION=10.06.0
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential curl ca-certificates libfontconfig1-dev && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/tmp/gs-build \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential curl ca-certificates libfontconfig1-dev && rm -rf /var/lib/apt/lists/* && \
|
||||
GS_TAG="gs$(printf '%s' "${GS_VERSION}" | tr -d '.')" && \
|
||||
curl -fsSL "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/${GS_TAG}/ghostscript-${GS_VERSION}.tar.gz" | tar xz && \
|
||||
cd /tmp/gs-build && \
|
||||
(test -d "ghostscript-${GS_VERSION}" || curl -fsSL "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/${GS_TAG}/ghostscript-${GS_VERSION}.tar.gz" | tar xz) && \
|
||||
cd "ghostscript-${GS_VERSION}" && \
|
||||
./configure \
|
||||
--prefix=/usr/local \
|
||||
@@ -269,19 +274,22 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
FROM ubuntu:noble AS pdf-tools-build
|
||||
ARG QPDF_VERSION=12.3.2
|
||||
ARG IM_VERSION=7.1.2-13
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/tmp/pdf-tools-build \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential cmake libssl-dev libjpeg-dev zlib1g-dev curl ca-certificates pkg-config \
|
||||
libpng-dev libtiff-dev libwebp-dev libxml2-dev libfreetype6-dev liblcms2-dev libzip-dev liblqr-1-0-dev \
|
||||
libltdl-dev libtool && \
|
||||
libltdl-dev libtool && rm -rf /var/lib/apt/lists/* && \
|
||||
cd /tmp/pdf-tools-build && \
|
||||
# Build QPDF
|
||||
curl -fsSL "https://github.com/qpdf/qpdf/releases/download/v${QPDF_VERSION}/qpdf-${QPDF_VERSION}.tar.gz" | tar xz && \
|
||||
(test -d "qpdf-${QPDF_VERSION}" || curl -fsSL "https://github.com/qpdf/qpdf/releases/download/v${QPDF_VERSION}/qpdf-${QPDF_VERSION}.tar.gz" | tar xz) && \
|
||||
cd "qpdf-${QPDF_VERSION}" && \
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DALLOW_CRYPTO_OPENSSL=ON -DDEFAULT_CRYPTO=openssl && \
|
||||
cmake --build build --parallel "$(nproc)" && \
|
||||
cmake --install build && \
|
||||
cd .. && \
|
||||
# Build ImageMagick 7
|
||||
curl -fsSL "https://github.com/ImageMagick/ImageMagick/archive/refs/tags/${IM_VERSION}.tar.gz" | tar xz && \
|
||||
(test -d "ImageMagick-${IM_VERSION}" || curl -fsSL "https://github.com/ImageMagick/ImageMagick/archive/refs/tags/${IM_VERSION}.tar.gz" | tar xz) && \
|
||||
cd "ImageMagick-${IM_VERSION}" && \
|
||||
./configure --prefix=/usr/local --with-modules --with-perl=no --with-magick-plus-plus=no --with-quantum-depth=16 --disable-static --enable-shared && \
|
||||
make -j"$(nproc)" && \
|
||||
@@ -307,7 +315,6 @@ ENV DEBIAN_FRONTEND=noninteractive \
|
||||
ARG UNOSERVER_VERSION=3.6
|
||||
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
--mount=type=cache,target=/root/.cache/pip \
|
||||
set -eux; \
|
||||
apt-get update; \
|
||||
@@ -354,8 +361,6 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
\
|
||||
# Cleanup stage.
|
||||
\
|
||||
# apt clean not strictly needed with cache mounts, but good for reducing layer metadata
|
||||
apt-get clean; \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
\
|
||||
# Docs / man / info / icons / themes / GUI assets (headless server)
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
FROM gradle:9.3.1-jdk25 AS build
|
||||
|
||||
# Install Node.js and npm for frontend build
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||
&& apt-get install -y --no-install-recommends nodejs \
|
||||
&& npm --version \
|
||||
&& node --version \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
@@ -65,18 +65,6 @@ LABEL org.opencontainers.image.title="Stirling-PDF Ultra-Lite" \
|
||||
org.opencontainers.image.version="${VERSION_TAG}" \
|
||||
org.opencontainers.image.keywords="PDF, manipulation, ultra-lite, API, Spring Boot, React"
|
||||
|
||||
# Copy scripts
|
||||
COPY scripts/init-without-ocr.sh /scripts/init-without-ocr.sh
|
||||
COPY scripts/installFonts.sh /scripts/installFonts.sh
|
||||
COPY scripts/stirling-diagnostics.sh /scripts/stirling-diagnostics.sh
|
||||
|
||||
# Copy built JARs from build stage
|
||||
# Use numeric UID:GID (1000:1000) since the named user doesn't exist yet at COPY time
|
||||
COPY --from=build --chown=1000:1000 \
|
||||
/app/app/core/build/libs/*.jar /app.jar
|
||||
COPY --from=build --chown=1000:1000 \
|
||||
/app/build/libs/restart-helper.jar /restart-helper.jar
|
||||
|
||||
# Environment Variables
|
||||
# NOTE: Memory flags (InitialRAMPercentage, MaxRAMPercentage, MaxMetaspaceSize)
|
||||
# are computed dynamically by init-without-ocr.sh based on container memory limits.
|
||||
@@ -96,7 +84,6 @@ ENV VERSION_TAG=$VERSION_TAG \
|
||||
ENDPOINTS_GROUPS_TO_REMOVE=CLI
|
||||
|
||||
# Install minimal dependencies
|
||||
# --chown on COPY above removes need to chown JARs here
|
||||
RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||
echo "@community https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
||||
@@ -111,10 +98,22 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
|
||||
su-exec && \
|
||||
mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders /tmp/stirling-pdf /tmp/stirling-pdf/heap_dumps && \
|
||||
mkdir -p /usr/share/fonts/opentype/noto && \
|
||||
chmod +x /scripts/*.sh && \
|
||||
# User permissions
|
||||
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /configs /customFiles /pipeline /tmp/stirling-pdf
|
||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /configs /customFiles /pipeline /tmp/stirling-pdf
|
||||
|
||||
# Copy scripts and built artifacts after OS package layer to maximize cache reuse.
|
||||
COPY --chown=1000:1000 scripts/init-without-ocr.sh /scripts/init-without-ocr.sh
|
||||
COPY --chown=1000:1000 scripts/installFonts.sh /scripts/installFonts.sh
|
||||
COPY --chown=1000:1000 scripts/stirling-diagnostics.sh /scripts/stirling-diagnostics.sh
|
||||
|
||||
# Copy built JARs from build stage
|
||||
COPY --from=build --chown=1000:1000 \
|
||||
/app/app/core/build/libs/*.jar /app.jar
|
||||
COPY --from=build --chown=1000:1000 \
|
||||
/app/build/libs/restart-helper.jar /restart-helper.jar
|
||||
|
||||
RUN chmod +x /scripts/*.sh
|
||||
|
||||
EXPOSE 8080/tcp
|
||||
|
||||
|
||||
@@ -421,7 +421,7 @@ main() {
|
||||
should_run_test "Stirling-PDF-Ultra-Lite-Version-Check"; then
|
||||
|
||||
export DISABLE_ADDITIONAL_FEATURES=true
|
||||
if ! ./gradlew clean build; then
|
||||
if ! ./gradlew clean build -PnoSpotless; then
|
||||
echo "Gradle build failed with security disabled, exiting script."
|
||||
exit 1
|
||||
fi
|
||||
@@ -431,11 +431,18 @@ main() {
|
||||
EXPECTED_VERSION=$(get_expected_version)
|
||||
echo "Expected version: $EXPECTED_VERSION"
|
||||
|
||||
# Build Ultra-Lite image with embedded frontend (GHCR tag, matching docker-compose-latest-ultra-lite.yml)
|
||||
# Build Ultra-Lite image with embedded frontend (matching docker-compose-latest-ultra-lite.yml)
|
||||
echo "Building ultra-lite image for tests that require it..."
|
||||
docker build --build-arg VERSION_TAG=alpha \
|
||||
if [ -n "${ACTIONS_RUNTIME_TOKEN}" ] && { [ -n "${ACTIONS_RESULTS_URL}" ] || [ -n "${ACTIONS_CACHE_URL}" ]; }; then
|
||||
DOCKER_CACHE_ARGS_ULTRA_LITE="--cache-from type=gha,scope=stirling-pdf-ultra-lite --cache-to type=gha,mode=max,scope=stirling-pdf-ultra-lite"
|
||||
else
|
||||
DOCKER_CACHE_ARGS_ULTRA_LITE=""
|
||||
fi
|
||||
docker buildx build --build-arg VERSION_TAG=alpha \
|
||||
-t docker.stirlingpdf.com/stirlingtools/stirling-pdf:ultra-lite \
|
||||
-f ./docker/embedded/Dockerfile.ultra-lite .
|
||||
-f ./docker/embedded/Dockerfile.ultra-lite \
|
||||
--load \
|
||||
${DOCKER_CACHE_ARGS_ULTRA_LITE} .
|
||||
else
|
||||
echo "Skipping ultra-lite image build - no ultra-lite tests in rerun list"
|
||||
fi
|
||||
@@ -482,7 +489,7 @@ main() {
|
||||
should_run_test "Stirling-PDF-Fat-Disable-Endpoints-Version-Check"; then
|
||||
|
||||
export DISABLE_ADDITIONAL_FEATURES=false
|
||||
if ! ./gradlew clean build; then
|
||||
if ! ./gradlew clean build -PnoSpotless; then
|
||||
echo "Gradle build failed with security enabled, exiting script."
|
||||
exit 1
|
||||
fi
|
||||
@@ -491,11 +498,18 @@ main() {
|
||||
EXPECTED_VERSION=$(get_expected_version)
|
||||
echo "Expected version with security enabled: $EXPECTED_VERSION"
|
||||
|
||||
# Build Fat (Security) image with embedded frontend for GHCR tag used in all 'fat' compose files
|
||||
# Build Fat (Security) image with embedded frontend (matching all 'fat' compose files)
|
||||
echo "Building fat image for tests that require it..."
|
||||
docker build --no-cache --pull --build-arg VERSION_TAG=alpha \
|
||||
if [ -n "${ACTIONS_RUNTIME_TOKEN}" ] && { [ -n "${ACTIONS_RESULTS_URL}" ] || [ -n "${ACTIONS_CACHE_URL}" ]; }; then
|
||||
DOCKER_CACHE_ARGS_FAT="--cache-from type=gha,scope=stirling-pdf-fat --cache-to type=gha,mode=max,scope=stirling-pdf-fat"
|
||||
else
|
||||
DOCKER_CACHE_ARGS_FAT=""
|
||||
fi
|
||||
docker buildx build --build-arg VERSION_TAG=alpha \
|
||||
-t docker.stirlingpdf.com/stirlingtools/stirling-pdf:fat \
|
||||
-f ./docker/embedded/Dockerfile.fat .
|
||||
-f ./docker/embedded/Dockerfile.fat \
|
||||
--load \
|
||||
${DOCKER_CACHE_ARGS_FAT} .
|
||||
else
|
||||
echo "Skipping fat image build - no fat tests in rerun list"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user