Compare commits
24 Commits
v0.33.1
...
Frooodle-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d19d87b8f0 | ||
|
|
a22ce69bc3 | ||
|
|
59b60ebfb8 | ||
|
|
a6ae3734ca | ||
|
|
b9a014b5c7 | ||
|
|
9e30918aae | ||
|
|
c239d95131 | ||
|
|
d591874da6 | ||
|
|
6c623d8d84 | ||
|
|
e059caa14e | ||
|
|
8eab35761d | ||
|
|
c43af24ffe | ||
|
|
e1b3cc736c | ||
|
|
0fb9e18636 | ||
|
|
5e1aac0b84 | ||
|
|
60bf649260 | ||
|
|
a58696a38e | ||
|
|
44abc67678 | ||
|
|
d1e690ff8d | ||
|
|
5dc8fa08ee | ||
|
|
db028dfe27 | ||
|
|
c24c504350 | ||
|
|
5dcfe64d1c | ||
|
|
d843696703 |
179
.github/workflows/PR-Demo-Comment.yml
vendored
Normal file
179
.github/workflows/PR-Demo-Comment.yml
vendored
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
name: PR Deployment via Comment
|
||||||
|
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-comment:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: |
|
||||||
|
github.event.issue.pull_request &&
|
||||||
|
(
|
||||||
|
contains(github.event.comment.body, 'prdeploy') ||
|
||||||
|
contains(github.event.comment.body, 'deploypr')
|
||||||
|
)
|
||||||
|
&&
|
||||||
|
(
|
||||||
|
github.event.comment.user.login == 'frooodle' ||
|
||||||
|
github.event.comment.user.login == 'sf298' ||
|
||||||
|
github.event.comment.user.login == 'Ludy87' ||
|
||||||
|
github.event.comment.user.login == 'LaserKaspar' ||
|
||||||
|
github.event.comment.user.login == 'sbplat' ||
|
||||||
|
github.event.comment.user.login == 'reecebrowne'
|
||||||
|
)
|
||||||
|
outputs:
|
||||||
|
pr_number: ${{ steps.get-pr.outputs.pr_number }}
|
||||||
|
pr_repository: ${{ steps.get-pr-info.outputs.repository }}
|
||||||
|
pr_ref: ${{ steps.get-pr-info.outputs.ref }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Get PR data
|
||||||
|
id: get-pr
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const prNumber = context.payload.issue.number;
|
||||||
|
console.log(`PR Number: ${prNumber}`);
|
||||||
|
core.setOutput('pr_number', prNumber);
|
||||||
|
|
||||||
|
- name: Get PR repository and ref
|
||||||
|
id: get-pr-info
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { owner, repo } = context.repo;
|
||||||
|
const prNumber = context.payload.issue.number;
|
||||||
|
|
||||||
|
const { data: pr } = await github.rest.pulls.get({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
pull_number: prNumber,
|
||||||
|
});
|
||||||
|
|
||||||
|
// For forks, use the full repository name, for internal PRs use the current repo
|
||||||
|
const repository = pr.head.repo.fork ? pr.head.repo.full_name : `${owner}/${repo}`;
|
||||||
|
|
||||||
|
console.log(`PR Repository: ${repository}`);
|
||||||
|
console.log(`PR Branch: ${pr.head.ref}`);
|
||||||
|
|
||||||
|
core.setOutput('repository', repository);
|
||||||
|
core.setOutput('ref', pr.head.ref);
|
||||||
|
|
||||||
|
deploy-pr:
|
||||||
|
needs: check-comment
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout PR
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: ${{ needs.check-comment.outputs.pr_repository }}
|
||||||
|
ref: ${{ needs.check-comment.outputs.pr_ref }}
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set up JDK
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
java-version: '17'
|
||||||
|
distribution: 'temurin'
|
||||||
|
|
||||||
|
- name: Run Gradle Command
|
||||||
|
run: ./gradlew clean build
|
||||||
|
env:
|
||||||
|
DOCKER_ENABLE_SECURITY: false
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Get version number
|
||||||
|
id: versionNumber
|
||||||
|
run: echo "versionNumber=$(./gradlew printVersion --quiet | tail -1)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_HUB_API }}
|
||||||
|
|
||||||
|
- name: Build and push PR-specific image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:pr-${{ needs.check-comment.outputs.pr_number }}
|
||||||
|
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
|
||||||
|
platforms: linux/amd64
|
||||||
|
|
||||||
|
- name: Set up SSH
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh/
|
||||||
|
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
|
||||||
|
sudo chmod 600 ../private.key
|
||||||
|
|
||||||
|
- name: Deploy to VPS
|
||||||
|
run: |
|
||||||
|
# First create the docker-compose content locally
|
||||||
|
cat > docker-compose.yml << 'EOF'
|
||||||
|
version: '3.3'
|
||||||
|
services:
|
||||||
|
stirling-pdf:
|
||||||
|
container_name: stirling-pdf-pr-${{ needs.check-comment.outputs.pr_number }}
|
||||||
|
image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:pr-${{ needs.check-comment.outputs.pr_number }}
|
||||||
|
ports:
|
||||||
|
- "${{ needs.check-comment.outputs.pr_number }}:8080"
|
||||||
|
volumes:
|
||||||
|
- /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/data:/usr/share/tessdata:rw
|
||||||
|
- /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/config:/configs:rw
|
||||||
|
- /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/logs:/logs:rw
|
||||||
|
environment:
|
||||||
|
DOCKER_ENABLE_SECURITY: "false"
|
||||||
|
SECURITY_ENABLELOGIN: "false"
|
||||||
|
SYSTEM_DEFAULTLOCALE: en-GB
|
||||||
|
UI_APPNAME: "Stirling-PDF PR#${{ needs.check-comment.outputs.pr_number }}"
|
||||||
|
UI_HOMEDESCRIPTION: "PR#${{ needs.check-comment.outputs.pr_number }} for Stirling-PDF Latest"
|
||||||
|
UI_APPNAMENAVBAR: "PR#${{ needs.check-comment.outputs.pr_number }}"
|
||||||
|
SYSTEM_MAXFILESIZE: "100"
|
||||||
|
METRICS_ENABLED: "true"
|
||||||
|
SYSTEM_GOOGLEVISIBILITY: "false"
|
||||||
|
restart: on-failure:5
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Then copy the file and execute commands
|
||||||
|
scp -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null docker-compose.yml ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }}:/tmp/docker-compose.yml
|
||||||
|
|
||||||
|
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << 'ENDSSH'
|
||||||
|
# Create PR-specific directories
|
||||||
|
mkdir -p /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/{data,config,logs}
|
||||||
|
|
||||||
|
# Move docker-compose file to correct location
|
||||||
|
mv /tmp/docker-compose.yml /stirling/PR-${{ needs.check-comment.outputs.pr_number }}/docker-compose.yml
|
||||||
|
|
||||||
|
# Start or restart the container
|
||||||
|
cd /stirling/PR-${{ needs.check-comment.outputs.pr_number }}
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose up -d
|
||||||
|
ENDSSH
|
||||||
|
|
||||||
|
- name: Post deployment URL to PR
|
||||||
|
if: success()
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { GITHUB_REPOSITORY } = process.env;
|
||||||
|
const [repoOwner, repoName] = GITHUB_REPOSITORY.split('/');
|
||||||
|
const prNumber = ${{ needs.check-comment.outputs.pr_number }};
|
||||||
|
|
||||||
|
const deploymentUrl = `http://${{ secrets.VPS_HOST }}:${prNumber}`;
|
||||||
|
const commentBody = `## 🚀 PR Test Deployment\n\n` +
|
||||||
|
`Your PR has been deployed for testing!\n\n` +
|
||||||
|
`🔗 **Test URL:** [${deploymentUrl}](${deploymentUrl})\n\n` +
|
||||||
|
`This deployment will be automatically cleaned up when the PR is closed.\n\n`;
|
||||||
|
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner: repoOwner,
|
||||||
|
repo: repoName,
|
||||||
|
issue_number: prNumber,
|
||||||
|
body: commentBody
|
||||||
|
});
|
||||||
78
.github/workflows/PR-Demo-cleanup.yml
vendored
Normal file
78
.github/workflows/PR-Demo-cleanup.yml
vendored
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
name: PR Deployment cleanup
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened, closed]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
SERVER_IP: ${{ secrets.VPS_IP }} # Add this to your GitHub secrets
|
||||||
|
CLEANUP_PERFORMED: 'false' # Add flag to track if cleanup occurred
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cleanup:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event.action == 'closed'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up SSH
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh/
|
||||||
|
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
|
||||||
|
sudo chmod 600 ../private.key
|
||||||
|
|
||||||
|
- name: Cleanup PR deployment
|
||||||
|
id: cleanup
|
||||||
|
run: |
|
||||||
|
CLEANUP_STATUS=$(ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << 'ENDSSH'
|
||||||
|
if [ -d "/stirling/PR-${{ github.event.pull_request.number }}" ]; then
|
||||||
|
echo "Found PR directory, proceeding with cleanup..."
|
||||||
|
|
||||||
|
# Stop and remove containers
|
||||||
|
cd /stirling/PR-${{ github.event.pull_request.number }}
|
||||||
|
docker-compose down || true
|
||||||
|
|
||||||
|
# Go back to root before removal
|
||||||
|
cd /
|
||||||
|
|
||||||
|
# Remove PR-specific directories
|
||||||
|
rm -rf /stirling/PR-${{ github.event.pull_request.number }}
|
||||||
|
|
||||||
|
# Remove the Docker image
|
||||||
|
docker rmi --no-prune ${{ secrets.DOCKER_HUB_USERNAME }}/test:pr-${{ github.event.pull_request.number }} || true
|
||||||
|
|
||||||
|
echo "PERFORMED_CLEANUP"
|
||||||
|
else
|
||||||
|
echo "PR directory not found, nothing to clean up"
|
||||||
|
echo "NO_CLEANUP_NEEDED"
|
||||||
|
fi
|
||||||
|
ENDSSH
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ $CLEANUP_STATUS == *"PERFORMED_CLEANUP"* ]]; then
|
||||||
|
echo "cleanup_performed=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "cleanup_performed=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Post cleanup notice to PR
|
||||||
|
if: steps.cleanup.outputs.cleanup_performed == 'true'
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { GITHUB_REPOSITORY } = process.env;
|
||||||
|
const [repoOwner, repoName] = GITHUB_REPOSITORY.split('/');
|
||||||
|
const prNumber = context.issue.number;
|
||||||
|
|
||||||
|
const commentBody = `## 🧹 Deployment Cleanup\n\n` +
|
||||||
|
`The test deployment for this PR has been cleaned up.`;
|
||||||
|
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner: repoOwner,
|
||||||
|
repo: repoName,
|
||||||
|
issue_number: prNumber,
|
||||||
|
body: commentBody
|
||||||
|
});
|
||||||
54
.github/workflows/check_properties.yml
vendored
54
.github/workflows/check_properties.yml
vendored
@@ -9,6 +9,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- "src/main/resources/messages_en_GB.properties"
|
- "src/main/resources/messages_en_GB.properties"
|
||||||
|
|
||||||
|
# Permissions required for the workflow
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
@@ -18,6 +19,13 @@ jobs:
|
|||||||
if: github.event_name == 'pull_request_target'
|
if: github.event_name == 'pull_request_target'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- name: Checkout main branch first
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: main
|
||||||
|
path: main-branch
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Checkout PR branch
|
- name: Checkout PR branch
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@@ -26,13 +34,6 @@ jobs:
|
|||||||
path: pr-branch
|
path: pr-branch
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Checkout main branch
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: main
|
|
||||||
path: main-branch
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
@@ -49,34 +50,46 @@ jobs:
|
|||||||
echo "Fetching PR changed files..."
|
echo "Fetching PR changed files..."
|
||||||
cd pr-branch
|
cd pr-branch
|
||||||
gh repo set-default ${{ github.repository }}
|
gh repo set-default ${{ github.repository }}
|
||||||
gh pr view ${{ github.event.pull_request.number }} --json files -q ".files[].path" > ../changed_files.txt
|
# Store files in a safe way, only allowing valid properties files
|
||||||
|
echo "Getting list of changed files from PR..."
|
||||||
|
gh pr view ${{ github.event.pull_request.number }} --json files -q ".files[].path" | grep -E '^src/main/resources/messages_[a-zA-Z_]+\.properties$' > ../changed_files.txt
|
||||||
cd ..
|
cd ..
|
||||||
echo $(cat changed_files.txt)
|
echo "Setting branch path..."
|
||||||
BRANCH_PATH="pr-branch"
|
BRANCH_PATH="pr-branch"
|
||||||
|
|
||||||
echo "BRANCH_PATH=${BRANCH_PATH}" >> $GITHUB_ENV
|
echo "BRANCH_PATH=${BRANCH_PATH}" >> $GITHUB_ENV
|
||||||
CHANGED_FILES=$(cat changed_files.txt | tr '\n' ' ')
|
echo "Processing changed files..."
|
||||||
echo "CHANGED_FILES=${CHANGED_FILES}" >> $GITHUB_ENV
|
mapfile -t CHANGED_FILES < changed_files.txt
|
||||||
echo "Changed files: ${CHANGED_FILES}"
|
|
||||||
|
CHANGED_FILES_STR="${CHANGED_FILES[*]}"
|
||||||
|
echo "CHANGED_FILES=${CHANGED_FILES_STR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "Changed files: ${CHANGED_FILES_STR}"
|
||||||
echo "Branch: ${BRANCH_PATH}"
|
echo "Branch: ${BRANCH_PATH}"
|
||||||
|
|
||||||
- name: Determine reference file
|
- name: Determine reference file
|
||||||
id: determine-file
|
id: determine-file
|
||||||
run: |
|
run: |
|
||||||
echo "Determining reference file..."
|
echo "Determining reference file..."
|
||||||
if echo "${{ env.CHANGED_FILES }}" | grep -q 'src/main/resources/messages_en_GB.properties'; then
|
if grep -Fxq "src/main/resources/messages_en_GB.properties" changed_files.txt; then
|
||||||
|
echo "Using PR branch reference file"
|
||||||
echo "REFERENCE_FILE=pr-branch/src/main/resources/messages_en_GB.properties" >> $GITHUB_ENV
|
echo "REFERENCE_FILE=pr-branch/src/main/resources/messages_en_GB.properties" >> $GITHUB_ENV
|
||||||
else
|
else
|
||||||
|
echo "Using main branch reference file"
|
||||||
echo "REFERENCE_FILE=main-branch/src/main/resources/messages_en_GB.properties" >> $GITHUB_ENV
|
echo "REFERENCE_FILE=main-branch/src/main/resources/messages_en_GB.properties" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
echo "REFERENCE_FILE=${{ env.REFERENCE_FILE }}"
|
|
||||||
|
|
||||||
- name: Show REFERENCE_FILE
|
- name: Show REFERENCE_FILE
|
||||||
run: echo "Reference file is set to ${{ env.REFERENCE_FILE }}"
|
run: echo "Reference file is set to ${REFERENCE_FILE}"
|
||||||
|
|
||||||
- name: Run Python script to check files
|
- name: Run Python script to check files
|
||||||
id: run-check
|
id: run-check
|
||||||
run: |
|
run: |
|
||||||
python main-branch/.github/scripts/check_language_properties.py --reference-file ${{ env.REFERENCE_FILE }} --branch ${{ env.BRANCH_PATH }} --files ${{ env.CHANGED_FILES }} > failure.txt || true
|
echo "Running Python script to check files..."
|
||||||
|
python main-branch/.github/scripts/check_language_properties.py \
|
||||||
|
--reference-file "${REFERENCE_FILE}" \
|
||||||
|
--branch "${BRANCH_PATH}" \
|
||||||
|
--files ${CHANGED_FILES} > failure.txt || true
|
||||||
|
|
||||||
- name: Capture output
|
- name: Capture output
|
||||||
id: capture-output
|
id: capture-output
|
||||||
@@ -87,7 +100,7 @@ jobs:
|
|||||||
echo "ERROR_OUTPUT<<EOF" >> $GITHUB_ENV
|
echo "ERROR_OUTPUT<<EOF" >> $GITHUB_ENV
|
||||||
echo "$ERROR_OUTPUT" >> $GITHUB_ENV
|
echo "$ERROR_OUTPUT" >> $GITHUB_ENV
|
||||||
echo "EOF" >> $GITHUB_ENV
|
echo "EOF" >> $GITHUB_ENV
|
||||||
echo $ERROR_OUTPUT
|
echo "${ERROR_OUTPUT}"
|
||||||
else
|
else
|
||||||
echo "No errors found."
|
echo "No errors found."
|
||||||
echo "ERROR_OUTPUT=" >> $GITHUB_ENV
|
echo "ERROR_OUTPUT=" >> $GITHUB_ENV
|
||||||
@@ -110,7 +123,7 @@ jobs:
|
|||||||
});
|
});
|
||||||
|
|
||||||
const comment = comments.data.find(c => c.body.includes("## 🚀 Translation Verification Summary"));
|
const comment = comments.data.find(c => c.body.includes("## 🚀 Translation Verification Summary"));
|
||||||
|
|
||||||
// Only allow the action user to update comments
|
// Only allow the action user to update comments
|
||||||
const expectedActor = "github-actions[bot]";
|
const expectedActor = "github-actions[bot]";
|
||||||
|
|
||||||
@@ -169,7 +182,10 @@ jobs:
|
|||||||
- name: Run Python script to check files
|
- name: Run Python script to check files
|
||||||
id: run-check
|
id: run-check
|
||||||
run: |
|
run: |
|
||||||
python .github/scripts/check_language_properties.py --reference-file src/main/resources/messages_en_GB.properties --branch main
|
echo "Running Python script to check files..."
|
||||||
|
python .github/scripts/check_language_properties.py \
|
||||||
|
--reference-file src/main/resources/messages_en_GB.properties \
|
||||||
|
--branch main
|
||||||
|
|
||||||
- name: Set up git config
|
- name: Set up git config
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ These files provide pre-configured setups for different scenarios. For example,
|
|||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Security
|
container_name: Stirling-PDF-Security
|
||||||
image: frooodle/s-pdf:latest
|
image: stirlingtools/stirling-pdf:latest
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
@@ -173,20 +173,20 @@ Stirling-PDF uses different Docker images for various configurations. The build
|
|||||||
For the latest version:
|
For the latest version:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile .
|
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest -f ./Dockerfile .
|
||||||
```
|
```
|
||||||
|
|
||||||
For the ultra-lite version:
|
For the ultra-lite version:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
|
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
|
||||||
```
|
```
|
||||||
|
|
||||||
For the fat version (with security enabled):
|
For the fat version (with security enabled):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export DOCKER_ENABLE_SECURITY=true
|
export DOCKER_ENABLE_SECURITY=true
|
||||||
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-fat -f ./Dockerfile-fat .
|
docker build --no-cache --pull --build-arg VERSION_TAG=alpha -t stirlingtools/stirling-pdf:latest-fat -f ./Dockerfile-fat .
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: The `--no-cache` and `--pull` flags ensure that the build process uses the latest base images and doesn't use cached layers, which is useful for testing and ensuring reproducible builds. however to improve build times these can often be removed depending on your usecase
|
Note: The `--no-cache` and `--pull` flags ensure that the build process uses the latest base images and doesn't use cached layers, which is useful for testing and ensuring reproducible builds. however to improve build times these can often be removed depending on your usecase
|
||||||
|
|||||||
45
Jenkinsfile
vendored
45
Jenkinsfile
vendored
@@ -1,45 +0,0 @@
|
|||||||
pipeline {
|
|
||||||
agent any
|
|
||||||
stages {
|
|
||||||
stage('Build') {
|
|
||||||
steps {
|
|
||||||
sh 'chmod 755 gradlew'
|
|
||||||
sh './gradlew build'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Docker Build') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
|
|
||||||
def image = "frooodle/s-pdf:$appVersion"
|
|
||||||
sh "docker build -t $image ."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Docker Push') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
|
|
||||||
def image = "frooodle/s-pdf:$appVersion"
|
|
||||||
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
|
|
||||||
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
|
|
||||||
sh "docker push $image"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('Helm Push') {
|
|
||||||
steps {
|
|
||||||
script {
|
|
||||||
//TODO: Read chartVersion from Chart.yaml
|
|
||||||
def chartVersion = '1.0.0'
|
|
||||||
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
|
|
||||||
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
|
|
||||||
sh "helm package chart/stirling-pdf"
|
|
||||||
sh "helm push stirling-pdf-chart-1.0.0.tgz oci://registry-1.docker.io/frooodle"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
12
README.md
12
README.md
@@ -120,13 +120,13 @@ Please view the [LocalRunGuide](https://github.com/Stirling-Tools/Stirling-PDF/b
|
|||||||
### Docker / Podman
|
### Docker / Podman
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> <https://hub.docker.com/r/frooodle/s-pdf>
|
> <https://hub.docker.com/r/stirlingtools/stirling-pdf>
|
||||||
|
|
||||||
Stirling-PDF has three different versions: a full version, an ultra-lite version, and a 'fat' version. Depending on the types of features you use, you may want a smaller image to save on space. To see what the different versions offer, please look at our [version mapping](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Version-groups.md). For people that don't mind space optimization, just use the latest tag.
|
Stirling-PDF has three different versions: a full version, an ultra-lite version, and a 'fat' version. Depending on the types of features you use, you may want a smaller image to save on space. To see what the different versions offer, please look at our [version mapping](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/Version-groups.md). For people that don't mind space optimization, just use the latest tag.
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
Please note in the examples below, you may need to change the volume paths as needed, e.g., `./extraConfigs:/configs` to `/opt/stirlingpdf/extraConfigs:/configs`.
|
Please note in the examples below, you may need to change the volume paths as needed, e.g., `./extraConfigs:/configs` to `/opt/stirlingpdf/extraConfigs:/configs`.
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ docker run -d \
|
|||||||
-e INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \
|
-e INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \
|
||||||
-e LANGS=en_GB \
|
-e LANGS=en_GB \
|
||||||
--name stirling-pdf \
|
--name stirling-pdf \
|
||||||
frooodle/s-pdf:latest
|
stirlingtools/stirling-pdf:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### Docker Compose
|
### Docker Compose
|
||||||
@@ -153,7 +153,7 @@ docker run -d \
|
|||||||
version: '3.3'
|
version: '3.3'
|
||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
image: frooodle/s-pdf:latest
|
image: stirlingtools/stirling-pdf:latest
|
||||||
ports:
|
ports:
|
||||||
- '8080:8080'
|
- '8080:8080'
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ plugins {
|
|||||||
//id "nebula.lint" version "19.0.3"
|
//id "nebula.lint" version "19.0.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import com.github.jk1.license.render.*
|
import com.github.jk1.license.render.*
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
@@ -17,7 +19,7 @@ ext {
|
|||||||
pdfboxVersion = "3.0.3"
|
pdfboxVersion = "3.0.3"
|
||||||
logbackVersion = "1.5.7"
|
logbackVersion = "1.5.7"
|
||||||
imageioVersion = "3.12.0"
|
imageioVersion = "3.12.0"
|
||||||
lombokVersion = "1.18.34"
|
lombokVersion = "1.18.36"
|
||||||
bouncycastleVersion = "1.78.1"
|
bouncycastleVersion = "1.78.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Security-Fat
|
container_name: Stirling-PDF-Security-Fat
|
||||||
image: frooodle/s-pdf:latest-fat
|
image: stirlingtools/stirling-pdf:latest-fat
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Security
|
container_name: Stirling-PDF-Security
|
||||||
image: frooodle/s-pdf:latest
|
image: stirlingtools/stirling-pdf:latest
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Security
|
container_name: Stirling-PDF-Security
|
||||||
image: frooodle/s-pdf:latest
|
image: stirlingtools/stirling-pdf:latest
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Ultra-Lite-Security
|
container_name: Stirling-PDF-Ultra-Lite-Security
|
||||||
image: frooodle/s-pdf:latest-ultra-lite
|
image: stirlingtools/stirling-pdf:latest-ultra-lite
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF-Ultra-Lite
|
container_name: Stirling-PDF-Ultra-Lite
|
||||||
image: frooodle/s-pdf:latest-ultra-lite
|
image: stirlingtools/stirling-pdf:latest-ultra-lite
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
stirling-pdf:
|
stirling-pdf:
|
||||||
container_name: Stirling-PDF
|
container_name: Stirling-PDF
|
||||||
image: frooodle/s-pdf:latest
|
image: stirlingtools/stirling-pdf:latest
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ public class DatabaseBackupHelper implements DatabaseBackupInterface {
|
|||||||
@Value("${spring.datasource.url}")
|
@Value("${spring.datasource.url}")
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.username}")
|
||||||
|
private String databaseUsername;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.password}")
|
||||||
|
private String databasePassword;
|
||||||
|
|
||||||
private Path backupPath = Paths.get("configs/db/backup/");
|
private Path backupPath = Paths.get("configs/db/backup/");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -134,7 +140,8 @@ public class DatabaseBackupHelper implements DatabaseBackupInterface {
|
|||||||
this.getBackupFilePath("backup_" + dateNow.format(myFormatObj) + ".sql");
|
this.getBackupFilePath("backup_" + dateNow.format(myFormatObj) + ".sql");
|
||||||
String query = "SCRIPT SIMPLE COLUMNS DROP to ?;";
|
String query = "SCRIPT SIMPLE COLUMNS DROP to ?;";
|
||||||
|
|
||||||
try (Connection conn = DriverManager.getConnection(url, "sa", "");
|
try (Connection conn =
|
||||||
|
DriverManager.getConnection(url, databaseUsername, databasePassword);
|
||||||
PreparedStatement stmt = conn.prepareStatement(query)) {
|
PreparedStatement stmt = conn.prepareStatement(query)) {
|
||||||
stmt.setString(1, insertOutputFilePath.toString());
|
stmt.setString(1, insertOutputFilePath.toString());
|
||||||
stmt.execute();
|
stmt.execute();
|
||||||
@@ -147,7 +154,8 @@ public class DatabaseBackupHelper implements DatabaseBackupInterface {
|
|||||||
// Retrieves the H2 database version.
|
// Retrieves the H2 database version.
|
||||||
public String getH2Version() {
|
public String getH2Version() {
|
||||||
String version = "Unknown";
|
String version = "Unknown";
|
||||||
try (Connection conn = DriverManager.getConnection(url, "sa", "")) {
|
try (Connection conn =
|
||||||
|
DriverManager.getConnection(url, databaseUsername, databasePassword)) {
|
||||||
try (Statement stmt = conn.createStatement();
|
try (Statement stmt = conn.createStatement();
|
||||||
ResultSet rs = stmt.executeQuery("SELECT H2VERSION() AS version")) {
|
ResultSet rs = stmt.executeQuery("SELECT H2VERSION() AS version")) {
|
||||||
if (rs.next()) {
|
if (rs.next()) {
|
||||||
@@ -189,7 +197,8 @@ public class DatabaseBackupHelper implements DatabaseBackupInterface {
|
|||||||
private boolean executeDatabaseScript(Path scriptPath) {
|
private boolean executeDatabaseScript(Path scriptPath) {
|
||||||
String query = "RUNSCRIPT from ?;";
|
String query = "RUNSCRIPT from ?;";
|
||||||
|
|
||||||
try (Connection conn = DriverManager.getConnection(url, "sa", "");
|
try (Connection conn =
|
||||||
|
DriverManager.getConnection(url, databaseUsername, databasePassword);
|
||||||
PreparedStatement stmt = conn.prepareStatement(query)) {
|
PreparedStatement stmt = conn.prepareStatement(query)) {
|
||||||
stmt.setString(1, scriptPath.toString());
|
stmt.setString(1, scriptPath.toString());
|
||||||
stmt.execute();
|
stmt.execute();
|
||||||
|
|||||||
@@ -32,11 +32,19 @@ public class MetricsAggregatorService {
|
|||||||
.counters()
|
.counters()
|
||||||
.forEach(
|
.forEach(
|
||||||
counter -> {
|
counter -> {
|
||||||
String key =
|
String method = counter.getId().getTag("method");
|
||||||
String.format(
|
String uri = counter.getId().getTag("uri");
|
||||||
"http_requests_%s_%s",
|
|
||||||
counter.getId().getTag("method"),
|
// Skip if either method or uri is null
|
||||||
counter.getId().getTag("uri").replace("/", "_"));
|
if (method == null || uri == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = String.format(
|
||||||
|
"http_requests_%s_%s",
|
||||||
|
method,
|
||||||
|
uri.replace("/", "_")
|
||||||
|
);
|
||||||
|
|
||||||
double currentCount = counter.count();
|
double currentCount = counter.count();
|
||||||
double lastCount = lastSentMetrics.getOrDefault(key, 0.0);
|
double lastCount = lastSentMetrics.getOrDefault(key, 0.0);
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ span.icon-text::after {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-text {
|
/* .tooltip-text {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
background-color: rgb(71 67 67 / 80%);
|
background-color: rgb(71 67 67 / 80%);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@@ -162,7 +162,7 @@ span.icon-text::after {
|
|||||||
.nav-item:hover .tooltip-text {
|
.nav-item:hover .tooltip-text {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
} */
|
||||||
|
|
||||||
.dropdown-menu.scrollable-y {
|
.dropdown-menu.scrollable-y {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
@@ -324,6 +324,18 @@ span.icon-text::after {
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* .icon-hide {
|
||||||
|
display: none;
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width:1199px) {
|
||||||
|
.icon-hide {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width:1200px) {
|
||||||
.icon-hide {
|
.icon-hide {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,14 +96,31 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function getPDFPageCount(file) {
|
||||||
|
try {
|
||||||
|
const arrayBuffer = await file.arrayBuffer();
|
||||||
|
pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdfjs-legacy/pdf.worker.mjs'
|
||||||
|
const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
|
||||||
|
return pdf.numPages;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error getting PDF page count:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleSingleDownload(url, formData, isMulti = false, isZip = false) {
|
async function handleSingleDownload(url, formData, isMulti = false, isZip = false) {
|
||||||
|
const startTime = performance.now();
|
||||||
|
const file = formData.get('fileInput');
|
||||||
|
let success = false;
|
||||||
|
let errorMessage = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url, { method: "POST", body: formData });
|
const response = await fetch(url, { method: "POST", body: formData });
|
||||||
const contentType = response.headers.get("content-type");
|
const contentType = response.headers.get("content-type");
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
errorMessage = response.status;
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
// Handle 401 Unauthorized error
|
|
||||||
showSessionExpiredPrompt();
|
showSessionExpiredPrompt();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -118,6 +135,8 @@
|
|||||||
let filename = getFilenameFromContentDisposition(contentDisposition);
|
let filename = getFilenameFromContentDisposition(contentDisposition);
|
||||||
|
|
||||||
const blob = await response.blob();
|
const blob = await response.blob();
|
||||||
|
success = true;
|
||||||
|
|
||||||
if (contentType.includes("application/pdf") || contentType.includes("image/")) {
|
if (contentType.includes("application/pdf") || contentType.includes("image/")) {
|
||||||
clearFileInput();
|
clearFileInput();
|
||||||
return handleResponse(blob, filename, !isMulti, isZip);
|
return handleResponse(blob, filename, !isMulti, isZip);
|
||||||
@@ -127,13 +146,29 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
success = false;
|
||||||
|
errorMessage = error.message;
|
||||||
clearFileInput();
|
clearFileInput();
|
||||||
console.error("Error in handleSingleDownload:", error);
|
console.error("Error in handleSingleDownload:", error);
|
||||||
throw error;
|
throw error;
|
||||||
|
} finally {
|
||||||
|
const processingTime = performance.now() - startTime;
|
||||||
|
|
||||||
|
// Capture analytics
|
||||||
|
const pageCount = file && file.type === 'application/pdf' ? await getPDFPageCount(file) : null;
|
||||||
|
|
||||||
|
posthog.capture('file_processing', {
|
||||||
|
success: success,
|
||||||
|
file_type: file ? file.type || 'unknown' : 'unknown',
|
||||||
|
file_size: file ? file.size : 0,
|
||||||
|
processing_time: processingTime,
|
||||||
|
error_message: errorMessage,
|
||||||
|
pdf_pages: pageCount
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilenameFromContentDisposition(contentDisposition) {
|
function getFilenameFromContentDisposition(contentDisposition) {
|
||||||
let filename;
|
let filename;
|
||||||
|
|
||||||
if (contentDisposition && contentDisposition.indexOf("attachment") !== -1) {
|
if (contentDisposition && contentDisposition.indexOf("attachment") !== -1) {
|
||||||
@@ -145,7 +180,7 @@
|
|||||||
|
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleJsonResponse(response) {
|
async function handleJsonResponse(response) {
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
const errorMessage = JSON.stringify(json, null, 2);
|
const errorMessage = JSON.stringify(json, null, 2);
|
||||||
@@ -308,14 +343,14 @@
|
|||||||
if(editSectionElement){
|
if(editSectionElement){
|
||||||
editSectionElement.style.display = "none";
|
editSectionElement.style.display = "none";
|
||||||
}
|
}
|
||||||
let cropPdfCanvas = document.querySelector("#crop-pdf-canvas");
|
let cropPdfCanvas = document.querySelector("#cropPdfCanvas");
|
||||||
let overlayCanvas = document.querySelector("#overlayCanvas");
|
let overlayCanvas = document.querySelector("#overlayCanvas");
|
||||||
if(cropPdfCanvas && overlayCanvas){
|
if(cropPdfCanvas && overlayCanvas){
|
||||||
cropPdfCanvas.width = 0;
|
cropPdfCanvas.width = 0;
|
||||||
cropPdfCanvas.heigth = 0;
|
cropPdfCanvas.height = 0;
|
||||||
|
|
||||||
overlayCanvas.width = 0;
|
overlayCanvas.width = 0;
|
||||||
overlayCanvas.heigth = 0;
|
overlayCanvas.height = 0;
|
||||||
}
|
}
|
||||||
} else{
|
} else{
|
||||||
console.log("Disabled for 'Merge'");
|
console.log("Disabled for 'Merge'");
|
||||||
|
|||||||
@@ -201,6 +201,7 @@
|
|||||||
window.stirlingPDF.error = /*[[#{error}]]*/ "Error";
|
window.stirlingPDF.error = /*[[#{error}]]*/ "Error";
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
|
||||||
<script th:src="@{'/js/downloader.js'}"></script>
|
<script th:src="@{'/js/downloader.js'}"></script>
|
||||||
|
|
||||||
<div class="custom-file-chooser" th:attr="data-bs-unique-id=${name}, data-bs-element-id=${name+'-input'}, data-bs-files-selected=#{filesSelected}, data-bs-pdf-prompt=#{pdfPrompt}">
|
<div class="custom-file-chooser" th:attr="data-bs-unique-id=${name}, data-bs-element-id=${name+'-input'}, data-bs-files-selected=#{filesSelected}, data-bs-pdf-prompt=#{pdfPrompt}">
|
||||||
@@ -218,4 +219,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script th:src="@{'/js/fileInput.js'}"></script>
|
<script th:src="@{'/js/fileInput.js'}"></script>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|||||||
@@ -330,7 +330,7 @@
|
|||||||
<span class="material-symbols-rounded" id="dark-mode-icon">
|
<span class="material-symbols-rounded" id="dark-mode-icon">
|
||||||
dark_mode
|
dark_mode
|
||||||
</span>
|
</span>
|
||||||
<span class="icon-text icon-hide tooltip-text" id="dark-mode-text" th:data-text="#{navbar.darkmode}" th:text="#{navbar.darkmode}"></span>
|
<span class="icon-text icon-hide" id="dark-mode-text" th:data-text="#{navbar.darkmode}" th:text="#{navbar.darkmode}"></span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
@@ -380,7 +380,7 @@
|
|||||||
<span class="material-symbols-rounded">
|
<span class="material-symbols-rounded">
|
||||||
settings
|
settings
|
||||||
</span>
|
</span>
|
||||||
<span class="icon-text icon-hide tooltip-text" th:data-text="#{navbar.settings}" th:text="#{navbar.settings}"></span>
|
<span class="icon-text icon-hide" th:data-text="#{navbar.settings}" th:text="#{navbar.settings}"></span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -411,7 +411,7 @@
|
|||||||
th:title="#{visitGithub}">
|
th:title="#{visitGithub}">
|
||||||
<img th:src="@{'/images/github.svg'}" alt="github">
|
<img th:src="@{'/images/github.svg'}" alt="github">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://hub.docker.com/r/frooodle/s-pdf" class="mx-1" role="button" target="_blank"th:title="#{seeDockerHub}">
|
<a href="https://hub.docker.com/r/stirlingtools/stirling-pdf" class="mx-1" role="button" target="_blank"th:title="#{seeDockerHub}">
|
||||||
<img th:src="@{'/images/docker.svg'}" alt="docker">
|
<img th:src="@{'/images/docker.svg'}" alt="docker">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://discord.gg/Cn8pWhQRxZ" class="mx-1" role="button" target="_blank" th:title="#{joinDiscord}">
|
<a href="https://discord.gg/Cn8pWhQRxZ" class="mx-1" role="button" target="_blank" th:title="#{joinDiscord}">
|
||||||
|
|||||||
2
test2.sh
2
test2.sh
@@ -49,7 +49,7 @@ check_health() {
|
|||||||
build_and_test() {
|
build_and_test() {
|
||||||
local version_tag="alpha"
|
local version_tag="alpha"
|
||||||
local dockerfile_name="./Dockerfile"
|
local dockerfile_name="./Dockerfile"
|
||||||
local image_base="frooodle/s-pdf"
|
local image_base="stirlingtools/stirling-pdf"
|
||||||
local security_suffix=""
|
local security_suffix=""
|
||||||
local docker_compose_base="./exampleYmlFiles/docker-compose-latest"
|
local docker_compose_base="./exampleYmlFiles/docker-compose-latest"
|
||||||
local compose_suffix=".yml"
|
local compose_suffix=".yml"
|
||||||
|
|||||||
Reference in New Issue
Block a user