mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-12-18 20:04:17 +01:00
Bump base image and community repository to Alpine 3.22. Add Calibre and related package fixes to the installed packages. Improve comments and update package installation commands for clarity.
427 lines
16 KiB
YAML
427 lines
16 KiB
YAML
name: Build and Test Workflow
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
# push:
|
|
# branches: ["main"]
|
|
pull_request:
|
|
branches: ["main"]
|
|
|
|
# cancel in-progress jobs if a new job is triggered
|
|
# This is useful to avoid running multiple builds for the same branch if a new commit is pushed
|
|
# or a pull request is updated.
|
|
# It helps to save resources and time by ensuring that only the latest commit is built and tested
|
|
# This is particularly useful for long-running jobs that may take a while to complete.
|
|
# The `group` is set to a combination of the workflow name, event name, and branch name.
|
|
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
|
|
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref_name || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
files-changed:
|
|
name: detect what files changed
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 3
|
|
# Map a step output to a job output
|
|
outputs:
|
|
build: ${{ steps.changes.outputs.build }}
|
|
app: ${{ steps.changes.outputs.app }}
|
|
project: ${{ steps.changes.outputs.project }}
|
|
openapi: ${{ steps.changes.outputs.openapi }}
|
|
docker: ${{ steps.changes.outputs.docker }}
|
|
steps:
|
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
|
|
- name: Check for file changes
|
|
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
|
id: changes
|
|
with:
|
|
filters: ".github/config/.files.yaml"
|
|
build:
|
|
runs-on: ubuntu-latest
|
|
|
|
permissions:
|
|
actions: read
|
|
security-events: write
|
|
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
jdk-version: [17, 21]
|
|
spring-security: [true, false]
|
|
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
|
|
- name: Set up JDK ${{ matrix.jdk-version }}
|
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
|
with:
|
|
java-version: ${{ matrix.jdk-version }}
|
|
distribution: "temurin"
|
|
|
|
- name: Setup Gradle
|
|
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0
|
|
with:
|
|
gradle-version: 8.14
|
|
|
|
- name: Build with Gradle and spring security ${{ matrix.spring-security }}
|
|
run: gradle clean build -x spotlessApply -x spotlessCheck
|
|
env:
|
|
DISABLE_ADDITIONAL_FEATURES: ${{ matrix.spring-security }}
|
|
|
|
- name: Check Test Reports Exist
|
|
id: check-reports
|
|
if: always()
|
|
run: |
|
|
declare -a dirs=(
|
|
"app/core/build/reports/tests/"
|
|
"app/core/build/test-results/"
|
|
"app/common/build/reports/tests/"
|
|
"app/common/build/test-results/"
|
|
"app/proprietary/build/reports/tests/"
|
|
"app/proprietary/build/test-results/"
|
|
)
|
|
missing_reports=()
|
|
for dir in "${dirs[@]}"; do
|
|
if [ ! -d "$dir" ]; then
|
|
missing_reports+=("$dir")
|
|
fi
|
|
done
|
|
if [ ${#missing_reports[@]} -gt 0 ]; then
|
|
echo "ERROR: The following required test report directories are missing:"
|
|
printf '%s\n' "${missing_reports[@]}"
|
|
exit 1
|
|
fi
|
|
echo "All required test report directories are present"
|
|
|
|
- name: Upload Test Reports
|
|
if: always()
|
|
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
|
with:
|
|
name: test-reports-jdk-${{ matrix.jdk-version }}-spring-security-${{ matrix.spring-security }}
|
|
path: |
|
|
app/core/build/reports/jacoco/test
|
|
app/core/build/reports/tests/
|
|
app/core/build/test-results/
|
|
app/core/build/reports/problems/
|
|
app/common/build/reports/tests/
|
|
app/common/build/test-results/
|
|
app/common/build/reports/jacoco/test
|
|
app/common/build/reports/problems/
|
|
app/proprietary/build/reports/tests/
|
|
app/proprietary/build/test-results/
|
|
app/proprietary/build/reports/jacoco/test
|
|
app/proprietary/build/reports/problems/
|
|
build/reports/problems/
|
|
retention-days: 3
|
|
if-no-files-found: warn
|
|
|
|
- name: Add coverage to PR with spring security ${{ matrix.spring-security }} and JDK ${{ matrix.jdk-version }}
|
|
id: jacoco
|
|
uses: madrapps/jacoco-report@50d3aff4548aa991e6753342d9ba291084e63848 # v1.7.2
|
|
with:
|
|
paths: |
|
|
${{ github.workspace }}/**/build/reports/jacoco/test/jacocoTestReport.xml
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
min-coverage-overall: 10
|
|
min-coverage-changed-files: 0
|
|
comment-type: summary
|
|
|
|
check-generateOpenApiDocs:
|
|
if: needs.files-changed.outputs.openapi == 'true'
|
|
needs: [files-changed, build]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
|
|
- name: Set up JDK 17
|
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
|
with:
|
|
java-version: "17"
|
|
distribution: "temurin"
|
|
|
|
- name: Setup Gradle
|
|
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0
|
|
|
|
- name: Generate OpenAPI documentation
|
|
run: gradle :stirling-pdf:generateOpenApiDocs
|
|
env:
|
|
DISABLE_ADDITIONAL_FEATURES: true
|
|
|
|
- name: Upload OpenAPI Documentation
|
|
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
|
with:
|
|
name: openapi-docs
|
|
path: ./SwaggerDoc.json
|
|
|
|
check-licence:
|
|
if: needs.files-changed.outputs.build == 'true'
|
|
needs: [files-changed, build]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
|
|
- name: Set up JDK 17
|
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
|
with:
|
|
java-version: "17"
|
|
distribution: "temurin"
|
|
|
|
- name: Check licenses for compatibility
|
|
run: gradle clean checkLicense
|
|
env:
|
|
DISABLE_ADDITIONAL_FEATURES: false
|
|
STIRLING_PDF_DESKTOP_UI: true
|
|
|
|
- name: FAILED - Check licenses for compatibility
|
|
if: failure()
|
|
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
|
with:
|
|
name: dependencies-without-allowed-license.json
|
|
path: |
|
|
build/reports/dependency-license/dependencies-without-allowed-license.json
|
|
retention-days: 3
|
|
|
|
docker-compose-tests:
|
|
if: needs.files-changed.outputs.project != 'true'
|
|
needs: files-changed
|
|
# if: github.event_name == 'push' && github.ref == 'refs/heads/main' ||
|
|
# (github.event_name == 'pull_request' &&
|
|
# contains(github.event.pull_request.labels.*.name, 'licenses') == false &&
|
|
# (
|
|
# contains(github.event.pull_request.labels.*.name, 'Front End') ||
|
|
# contains(github.event.pull_request.labels.*.name, 'Java') ||
|
|
# contains(github.event.pull_request.labels.*.name, 'Back End') ||
|
|
# contains(github.event.pull_request.labels.*.name, 'Security') ||
|
|
# contains(github.event.pull_request.labels.*.name, 'API') ||
|
|
# contains(github.event.pull_request.labels.*.name, 'Docker') ||
|
|
# contains(github.event.pull_request.labels.*.name, 'Test')
|
|
# )
|
|
# )
|
|
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
|
|
- name: Set up Java 17
|
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
|
with:
|
|
java-version: "17"
|
|
distribution: "temurin"
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
|
|
|
- name: Install Docker Compose
|
|
run: |
|
|
sudo curl -SL "https://github.com/docker/compose/releases/download/v2.40.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
|
sudo chmod +x /usr/local/bin/docker-compose
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
|
|
with:
|
|
python-version: "3.12"
|
|
cache: "pip" # caching pip dependencies
|
|
cache-dependency-path: ./testing/cucumber/requirements.txt
|
|
|
|
- name: Pip requirements
|
|
run: |
|
|
pip install --require-hashes -r ./testing/cucumber/requirements.txt
|
|
|
|
- name: Run Docker Compose Tests
|
|
run: |
|
|
chmod +x ./testing/test_webpages.sh
|
|
chmod +x ./testing/test.sh
|
|
chmod +x ./testing/test_disabledEndpoints.sh
|
|
./testing/test.sh
|
|
|
|
test-build-docker-images:
|
|
if: (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') && needs.files-changed.outputs.docker == 'true'
|
|
needs: [files-changed, build, docker-compose-tests] # tmp disable
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# docker-rev: ["Dockerfile", "Dockerfile.ultra-lite", "Dockerfile.fat"] # temp disable
|
|
docker-rev: ["Dockerfile.fat"]
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
|
|
- name: Set up JDK 17
|
|
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0
|
|
with:
|
|
java-version: "17"
|
|
distribution: "temurin"
|
|
|
|
- name: Set up Gradle
|
|
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0
|
|
with:
|
|
gradle-version: 8.14
|
|
|
|
- name: Build application
|
|
run: gradle clean build -x spotlessApply -x spotlessCheck
|
|
env:
|
|
DISABLE_ADDITIONAL_FEATURES: true
|
|
STIRLING_PDF_DESKTOP_UI: false
|
|
|
|
- name: Set up QEMU
|
|
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
|
|
with:
|
|
platforms: linux/amd64,linux/arm64/v8
|
|
|
|
- name: Set up Docker Buildx
|
|
id: buildx
|
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
|
with:
|
|
platforms: linux/amd64,linux/arm64/v8
|
|
|
|
- name: Convert repository owner to lowercase
|
|
id: repoowner
|
|
run: echo "lowercase=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
|
|
|
|
- name: Generate safe test tag
|
|
id: meta
|
|
run: |
|
|
SAFE_NAME=$(echo "${{ matrix.docker-rev }}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9.-]/-/g')
|
|
TAG="ghcr.io/${{ steps.repoowner.outputs.lowercase }}/stirling-pdf-test:${SAFE_NAME}-${{ github.sha }}"
|
|
echo "tags=$TAG" >> $GITHUB_OUTPUT
|
|
echo "Building and testing: $TAG"
|
|
|
|
- name: Build and load amd64 image
|
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
|
with:
|
|
builder: ${{ steps.buildx.outputs.name }}
|
|
context: .
|
|
file: ./${{ matrix.docker-rev }}
|
|
push: false
|
|
load: true
|
|
cache-from: type=gha
|
|
cache-to: type=gha,mode=max
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
platforms: linux/amd64
|
|
provenance: false
|
|
sbom: false
|
|
|
|
- name: Test Java works (amd64)
|
|
run: docker run --rm ${{ steps.meta.outputs.tags }} java -version
|
|
|
|
- name: Prune amd64 image and cache
|
|
if: always()
|
|
run: |
|
|
docker image rm -f ${{ steps.meta.outputs.tags }} || true
|
|
docker builder prune --force || true
|
|
|
|
- name: Build and load arm64 image
|
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
|
with:
|
|
builder: ${{ steps.buildx.outputs.name }}
|
|
context: .
|
|
file: ./${{ matrix.docker-rev }}
|
|
push: false
|
|
load: true
|
|
cache-from: type=gha
|
|
cache-to: type=gha,mode=max
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
platforms: linux/arm64/v8
|
|
provenance: false
|
|
sbom: false
|
|
|
|
- name: Test Java works (arm64)
|
|
run: docker run --rm --platform linux/arm64 ${{ steps.meta.outputs.tags }} java -version
|
|
|
|
- name: Test app.jar exists (arm64)
|
|
run: |
|
|
docker run --rm --platform linux/arm64 ${{ steps.meta.outputs.tags }} \
|
|
sh -c "test -f /app.jar && echo 'app.jar OK' || (echo 'ERROR: app.jar missing!' && exit 1)"
|
|
|
|
- name: Deep arm64 tests (fat image only)
|
|
if: matrix.docker-rev == 'Dockerfile.fat'
|
|
run: |
|
|
TAG="${{ steps.meta.outputs.tags }}"
|
|
echo "Running deep tests on arm64 for fat image..."
|
|
|
|
# LibreOffice binary linkage
|
|
docker run --rm --platform linux/arm64 $TAG \
|
|
sh -c "ldd /usr/lib/libreoffice/program/soffice.bin > /dev/null && echo 'LibreOffice binary linked OK'" || \
|
|
(echo "LibreOffice binary broken on arm64!" && exit 1)
|
|
|
|
# Python uno import
|
|
docker run --rm --platform linux/arm64 $TAG \
|
|
sh -c "python3 -c 'import uno; print(\"uno import OK\")'" || \
|
|
(echo "Python uno import failed on arm64!" && exit 1)
|
|
|
|
# Full startup
|
|
TAG="${{ steps.meta.outputs.tags }}"
|
|
echo "Running quick startup check on arm64..."
|
|
|
|
docker run --rm --platform linux/arm64 \
|
|
$TAG \
|
|
sh -c "java -jar /app.jar --version || java -jar /app.jar --help || java -jar /app.jar" > startup.log 2>&1 &
|
|
|
|
# Warte max. 90 Sekunden und prüfe, ob die Startzeile mit Version erscheint
|
|
timeout 90 bash -c "
|
|
until grep -q 'Starting SPDFApplication v' startup.log; do
|
|
sleep 2
|
|
if ! kill -0 \$! 2>/dev/null; then
|
|
echo 'Java process died!'
|
|
cat startup.log
|
|
exit 1
|
|
fi
|
|
done
|
|
echo 'Stirling-PDF fat started successfully on arm64!'
|
|
" || (echo "Startup failed:"; cat startup.log; exit 1)
|
|
|
|
- name: Cleanup arm64 image and cache
|
|
if: always()
|
|
run: |
|
|
docker image rm -f ${{ steps.meta.outputs.tags }} || true
|
|
docker builder prune --force || true
|
|
|
|
- name: Upload Docker build reports
|
|
if: always()
|
|
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
|
with:
|
|
name: reports-docker-${{ matrix.docker-rev }}
|
|
path: |
|
|
build/reports/
|
|
build/test-results/
|
|
build/reports/problems/
|
|
retention-days: 3
|
|
if-no-files-found: warn
|