Compare commits

...
Author SHA1 Message Date
Anthony Stirling 00af9fd828 Delete .github/workflows directory 2025-09-22 13:59:42 +01:00
GitHub Actions eee10478c8 Update template reference hashes [skip ci] 2025-04-16 14:25:50 +00:00
Anthony Stirling 072de14f38 test 2025-04-16 15:25:34 +01:00
GitHub Actions ae8221d134 Update template reference hashes [skip ci] 2025-04-16 13:37:59 +00:00
Anthony Stirling 90382f5467 test 2025-04-16 14:37:42 +01:00
GitHub Actions 83f35bf40e Update template reference hashes [skip ci] 2025-04-16 12:52:18 +00:00
Anthony Stirling bb7fb664fa extra 2025-04-16 13:52:04 +01:00
Anthony Stirling 364b8c7c26 test 2025-04-16 12:26:38 +01:00
GitHub Actions 1f37c4b742 Update template reference hashes [skip ci] 2025-04-16 11:08:07 +00:00
Anthony Stirling e9b42e4025 update 2025-04-16 12:07:52 +01:00
Anthony Stirling 13c7a1fb16 hashs 2025-04-16 12:05:47 +01:00
26 changed files with 934 additions and 2373 deletions
@@ -1,320 +0,0 @@
name: PR Deployment via Comment
on:
issue_comment:
types: [created]
permissions:
contents: read
issues: write # Required for adding reactions to comments
pull-requests: read # Required for reading PR information
jobs:
check-comment:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: read
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' ||
github.event.comment.user.login == 'DarioGii' ||
github.event.comment.user.login == 'ConnorYoh'
)
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 }}
comment_id: ${{ github.event.comment.id }}
enable_security: ${{ steps.check-security-flag.outputs.enable_security }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
# Generate GitHub App token
- name: Generate GitHub App Token
id: generate-token
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Get PR data
id: get-pr
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
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@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
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);
- name: Check for security/login flag
id: check-security-flag
env:
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
if [[ "$COMMENT_BODY" == *"security"* ]] || [[ "$COMMENT_BODY" == *"login"* ]]; then
echo "Security flags detected in comment"
echo "enable_security=true" >> $GITHUB_OUTPUT
else
echo "No security flags detected in comment"
echo "enable_security=false" >> $GITHUB_OUTPUT
fi
- name: Add 'in_progress' reaction to comment
id: add-eyes-reaction
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
console.log(`Adding eyes reaction to comment ID: ${context.payload.comment.id}`);
try {
const { data: reaction } = await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: 'eyes'
});
console.log(`Added reaction with ID: ${reaction.id}`);
return { success: true, id: reaction.id };
} catch (error) {
console.error(`Failed to add reaction: ${error.message}`);
console.error(error);
return { success: false, error: error.message };
}
deploy-pr:
needs: check-comment
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Generate GitHub App Token
id: generate-token
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Checkout PR
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "17"
distribution: "temurin"
- name: Run Gradle Command
run: |
if [ "${{ needs.check-comment.outputs.enable_security }}" == "true" ]; then
export DOCKER_ENABLE_SECURITY=true
else
export DOCKER_ENABLE_SECURITY=false
fi
./gradlew clean build
env:
STIRLING_PDF_DESKTOP_UI: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Get version number
id: versionNumber
run: |
VERSION=$(grep "^version =" build.gradle | awk -F'"' '{print $2}')
echo "versionNumber=$VERSION" >> $GITHUB_OUTPUT
- name: Login to Docker Hub
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_API }}
- name: Build and push PR-specific image
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
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
id: deploy
run: |
# Set security settings based on flags
if [ "${{ needs.check-comment.outputs.enable_security }}" == "true" ]; then
DOCKER_SECURITY="true"
LOGIN_SECURITY="true"
SECURITY_STATUS="🔒 Security Enabled"
else
DOCKER_SECURITY="false"
LOGIN_SECURITY="false"
SECURITY_STATUS="Security Disabled"
fi
# 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: "${DOCKER_SECURITY}"
SECURITY_ENABLELOGIN: "${LOGIN_SECURITY}"
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
# Set output for use in PR comment
echo "security_status=${SECURITY_STATUS}" >> $GITHUB_ENV
- name: Add success reaction to comment
if: success()
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
console.log(`Adding rocket reaction to comment ID: ${{ needs.check-comment.outputs.comment_id }}`);
try {
const { data: reaction } = await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: ${{ needs.check-comment.outputs.comment_id }},
content: 'rocket'
});
console.log(`Added rocket reaction with ID: ${reaction.id}`);
} catch (error) {
console.error(`Failed to add reaction: ${error.message}`);
console.error(error);
}
- name: Add failure reaction to comment
if: failure()
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
console.log(`Adding -1 reaction to comment ID: ${{ needs.check-comment.outputs.comment_id }}`);
try {
const { data: reaction } = await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: ${{ needs.check-comment.outputs.comment_id }},
content: '-1'
});
console.log(`Added -1 reaction with ID: ${reaction.id}`);
} catch (error) {
console.error(`Failed to add reaction: ${error.message}`);
console.error(error);
}
- name: Post deployment URL to PR
if: success()
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.generate-token.outputs.token }}
script: |
const { GITHUB_REPOSITORY } = process.env;
const [repoOwner, repoName] = GITHUB_REPOSITORY.split('/');
const prNumber = ${{ needs.check-comment.outputs.pr_number }};
const securityStatus = process.env.security_status || "Security Disabled";
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` +
`${securityStatus}\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
});
-59
View File
@@ -1,59 +0,0 @@
name: PR Deployment cleanup
on:
pull_request:
types: [opened, synchronize, reopened, closed]
permissions:
contents: read
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
permissions:
contents: write
pull-requests: write
if: github.event.action == 'closed'
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- 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: |
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
-27
View File
@@ -1,27 +0,0 @@
name: "Pull Request Labeler"
on:
pull_request_target:
types: [opened, synchronize]
permissions:
contents: read
jobs:
labeler:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Apply Labels
uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
configuration-path: .github/labeler-config.yml
sync-labels: true
-145
View File
@@ -1,145 +0,0 @@
name: Build repo
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
permissions:
actions: read
security-events: write
strategy:
fail-fast: false
matrix:
jdk-version: [17, 21]
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up JDK ${{ matrix.jdk-version }}
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: ${{ matrix.jdk-version }}
distribution: "temurin"
- name: Build with Gradle and no spring security
run: ./gradlew clean build
env:
DOCKER_ENABLE_SECURITY: false
- name: Build with Gradle and with spring security
run: ./gradlew clean build
env:
DOCKER_ENABLE_SECURITY: true
- name: Upload Test Reports
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: test-reports-jdk-${{ matrix.jdk-version }}
path: |
build/reports/tests/
build/test-results/
build/reports/problems/
retention-days: 3
check-licence:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "17"
distribution: "adopt"
- name: check the licenses for compatibility
run: ./gradlew clean checkLicense
- name: FAILED - check the licenses for compatibility
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dependencies-without-allowed-license.json
path: |
build/reports/dependency-license/dependencies-without-allowed-license.json
retention-days: 3
docker-compose-tests:
# 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@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Checkout Repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Java 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "17"
distribution: "adopt"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Install Docker Compose
run: |
sudo curl -SL "https://github.com/docker/compose/releases/download/v2.32.4/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@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
with:
python-version: "3.12"
cache: 'pip' # caching pip dependencies
- 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
-250
View File
@@ -1,250 +0,0 @@
name: Check Properties Files on PR
on:
pull_request_target:
types: [opened, synchronize, reopened]
paths:
- "src/main/resources/messages_*.properties"
permissions:
contents: read # Allow read access to repository content
jobs:
check-files:
if: github.event_name == 'pull_request_target'
runs-on: ubuntu-latest
permissions:
issues: write # Allow posting comments on issues/PRs
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Checkout main branch first
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Python
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
with:
python-version: "3.12"
- name: Get PR data
id: get-pr-data
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const prNumber = context.payload.pull_request.number;
const repoOwner = context.payload.repository.owner.login;
const repoName = context.payload.repository.name;
const branch = context.payload.pull_request.head.ref;
console.log(`PR Number: ${prNumber}`);
console.log(`Repo Owner: ${repoOwner}`);
console.log(`Repo Name: ${repoName}`);
console.log(`Branch: ${branch}`);
core.setOutput("pr_number", prNumber);
core.setOutput("repo_owner", repoOwner);
core.setOutput("repo_name", repoName);
core.setOutput("branch", branch);
continue-on-error: true
- name: Fetch PR changed files
id: fetch-pr-changes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "Fetching PR changed files..."
echo "Getting list of changed files from PR..."
gh pr view ${{ steps.get-pr-data.outputs.pr_number }} --json files -q ".files[].path" | grep -E '^src/main/resources/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}\.properties$' > changed_files.txt # Filter only matching property files
- name: Determine reference file test
id: determine-file
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const fs = require("fs");
const path = require("path");
const prNumber = ${{ steps.get-pr-data.outputs.pr_number }};
const repoOwner = "${{ steps.get-pr-data.outputs.repo_owner }}";
const repoName = "${{ steps.get-pr-data.outputs.repo_name }}";
const prRepoOwner = "${{ github.event.pull_request.head.repo.owner.login }}";
const prRepoName = "${{ github.event.pull_request.head.repo.name }}";
const branch = "${{ steps.get-pr-data.outputs.branch }}";
console.log(`Determining reference file for PR #${prNumber}`);
// Validate inputs
const validateInput = (input, regex, name) => {
if (!regex.test(input)) {
throw new Error(`Invalid ${name}: ${input}`);
}
};
validateInput(repoOwner, /^[a-zA-Z0-9_-]+$/, "repository owner");
validateInput(repoName, /^[a-zA-Z0-9._-]+$/, "repository name");
validateInput(branch, /^[a-zA-Z0-9._/-]+$/, "branch name");
// Get the list of changed files in the PR
const { data: files } = await github.rest.pulls.listFiles({
owner: repoOwner,
repo: repoName,
pull_number: prNumber,
});
// Filter for relevant files based on the PR changes
const changedFiles = files
.map(file => file.filename)
.filter(file => /^src\/main\/resources\/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}\.properties$/.test(file));
console.log("Changed files:", changedFiles);
// Create a temporary directory for PR files
const tempDir = "pr-branch";
if (!fs.existsSync(tempDir)) {
fs.mkdirSync(tempDir, { recursive: true });
}
// Download and save each changed file
for (const file of changedFiles) {
const { data: fileContent } = await github.rest.repos.getContent({
owner: prRepoOwner,
repo: prRepoName,
path: file,
ref: branch,
});
const content = Buffer.from(fileContent.content, "base64").toString("utf-8");
const filePath = path.join(tempDir, file);
const dirPath = path.dirname(filePath);
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
}
fs.writeFileSync(filePath, content);
console.log(`Saved file: ${filePath}`);
}
// Output the list of changed files for further processing
const fileList = changedFiles.join(" ");
core.exportVariable("FILES_LIST", fileList);
console.log("Files saved and listed in FILES_LIST.");
// Determine reference file
let referenceFilePath;
if (changedFiles.includes("src/main/resources/messages_en_GB.properties")) {
console.log("Using PR branch reference file.");
const { data: fileContent } = await github.rest.repos.getContent({
owner: prRepoOwner,
repo: prRepoName,
path: "src/main/resources/messages_en_GB.properties",
ref: branch,
});
referenceFilePath = "pr-branch-messages_en_GB.properties";
const content = Buffer.from(fileContent.content, "base64").toString("utf-8");
fs.writeFileSync(referenceFilePath, content);
} else {
console.log("Using main branch reference file.");
const { data: fileContent } = await github.rest.repos.getContent({
owner: repoOwner,
repo: repoName,
path: "src/main/resources/messages_en_GB.properties",
ref: "main",
});
referenceFilePath = "main-branch-messages_en_GB.properties";
const content = Buffer.from(fileContent.content, "base64").toString("utf-8");
fs.writeFileSync(referenceFilePath, content);
}
console.log(`Reference file path: ${referenceFilePath}`);
core.exportVariable("REFERENCE_FILE", referenceFilePath);
- name: Run Python script to check files
id: run-check
run: |
echo "Running Python script to check files..."
python .github/scripts/check_language_properties.py \
--actor ${{ github.event.pull_request.user.login }} \
--reference-file "${REFERENCE_FILE}" \
--branch "pr-branch" \
--files "${FILES_LIST[@]}" > result.txt
continue-on-error: true # Continue the job even if this step fails
- name: Capture output
id: capture-output
run: |
if [ -f result.txt ] && [ -s result.txt ]; then
echo "Test, capturing output..."
SCRIPT_OUTPUT=$(cat result.txt)
echo "SCRIPT_OUTPUT<<EOF" >> $GITHUB_ENV
echo "$SCRIPT_OUTPUT" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
echo "${SCRIPT_OUTPUT}"
# Determine job failure based on script output
if [[ "$SCRIPT_OUTPUT" == *"❌"* ]]; then
echo "FAIL_JOB=true" >> $GITHUB_ENV
else
echo "FAIL_JOB=false" >> $GITHUB_ENV
fi
else
echo "No update found."
echo "SCRIPT_OUTPUT=" >> $GITHUB_ENV
echo "FAIL_JOB=false" >> $GITHUB_ENV
fi
- name: Post comment on PR
if: env.SCRIPT_OUTPUT != ''
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const { GITHUB_REPOSITORY, SCRIPT_OUTPUT } = process.env;
const [repoOwner, repoName] = GITHUB_REPOSITORY.split('/');
const issueNumber = context.issue.number;
// Find existing comment
const comments = await github.rest.issues.listComments({
owner: repoOwner,
repo: repoName,
issue_number: issueNumber
});
const comment = comments.data.find(c => c.body.includes("## 🚀 Translation Verification Summary"));
// Only update or create comments by the action user
const expectedActor = "github-actions[bot]";
if (comment && comment.user.login === expectedActor) {
// Update existing comment
await github.rest.issues.updateComment({
owner: repoOwner,
repo: repoName,
comment_id: comment.id,
body: `## 🚀 Translation Verification Summary\n\n\n${SCRIPT_OUTPUT}\n`
});
console.log("Updated existing comment.");
} else if (!comment) {
// Create new comment if no existing comment is found
await github.rest.issues.createComment({
owner: repoOwner,
repo: repoName,
issue_number: issueNumber,
body: `## 🚀 Translation Verification Summary\n\n\n${SCRIPT_OUTPUT}\n`
});
console.log("Created new comment.");
} else {
console.log("Comment update attempt denied. Actor does not match.");
}
- name: Fail job if errors found
if: env.FAIL_JOB == 'true'
run: |
echo "Failing the job because errors were detected."
exit 1
-79
View File
@@ -1,79 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
#disable for now
#on:
# push:
# branches: ["main"]
# pull_request:
# The branches below must be a subset of the branches above
# branches: ["main"]
# schedule:
# - cron: "0 0 * * 1"
permissions:
contents: read
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: ["java"]
# CodeQL supports [ $supported-codeql-languages ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Harden Runner
uses: step-security/harden-runner@c95a14d0e5bab51a9f56296a4eb0e416910cd350 # v2.10.3
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
with:
category: "/language:${{matrix.language}}"
-27
View File
@@ -1,27 +0,0 @@
# Dependency Review Action
#
# This Action will scan dependency manifest files that change as part of a Pull Request,
# surfacing known-vulnerable versions of the packages declared or updated in the PR.
# Once installed, if the workflow run is marked as required,
# PRs introducing known-vulnerable packages will be blocked from merging.
#
# Source repository: https://github.com/actions/dependency-review-action
name: "Dependency Review"
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: "Checkout Repository"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: "Dependency Review"
uses: actions/dependency-review-action@ce3cf9537a52e8119d91fd484ab5b8a807627bf8 # v4.6.0
-92
View File
@@ -1,92 +0,0 @@
name: License Report Workflow
on:
push:
branches:
- main
paths:
- "build.gradle"
permissions:
contents: read
jobs:
generate-license-report:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Generate GitHub App Token
id: generate-token
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Check out code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "17"
distribution: "adopt"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- name: check the licenses for compatibility
run: ./gradlew clean checkLicense
- name: FAILED - check the licenses for compatibility
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dependencies-without-allowed-license.json
path: |
build/reports/dependency-license/dependencies-without-allowed-license.json
retention-days: 3
- name: Move and Rename License File
run: |
mv build/reports/dependency-license/index.json src/main/resources/static/3rdPartyLicenses.json
- name: Set up git config
run: |
git config --global user.name "stirlingbot[bot]"
git config --global user.email "1113334+stirlingbot[bot]@users.noreply.github.com"
- name: Run git add
run: |
git add src/main/resources/static/3rdPartyLicenses.json
git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
- name: Create Pull Request
id: cpr
if: env.CHANGES_DETECTED == 'true'
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
token: ${{ steps.generate-token.outputs.token }}
commit-message: "Update 3rd Party Licenses"
committer: "stirlingbot[bot] <1113334+stirlingbot[bot]@users.noreply.github.com>"
author: "stirlingbot[bot] <1113334+stirlingbot[bot]@users.noreply.github.com>"
signoff: true
branch: update-3rd-party-licenses
title: "Update 3rd Party Licenses"
body: |
Auto-generated by StirlingBot
labels: licenses,github-actions
draft: false
delete-branch: true
sign-commits: true
- name: Enable Pull Request Automerge
if: steps.cpr.outputs.pull-request-operation == 'created'
run: gh pr merge --squash --auto "${{ steps.cpr.outputs.pull-request-number }}"
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
-30
View File
@@ -1,30 +0,0 @@
name: Manage labels
on:
schedule:
- cron: "30 20 * * *"
permissions:
contents: read
jobs:
labeler:
name: Labeler
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Check out the repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run Labeler
uses: crazy-max/ghaction-github-labeler@24d110aa46a59976b8a7f35518cb7f14f434c916 # v5.3.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
yaml-file: .github/labels.yml
skip-delete: true
-314
View File
@@ -1,314 +0,0 @@
name: Test Installers Build
on:
workflow_dispatch:
release:
types: [created]
inputs:
test_mode:
description: "Run in test mode (skips release step)"
required: false
default: "false"
permissions:
contents: read
jobs:
read_versions:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.versionNumber.outputs.versionNumber }}
versionMac: ${{ steps.versionNumberMac.outputs.versionNumberMac }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Get version number
- name: Get version number
id: versionNumber
run: |
VERSION=$(grep "^version =" build.gradle | awk -F'"' '{print $2}')
echo "versionNumber=$VERSION" >> $GITHUB_OUTPUT
- name: Get version number mac
id: versionNumberMac
run: |
VERSION=$(grep "^version =" build.gradle | awk -F'"' '{print $2}')
CURRENT_YEAR=$(date +'%Y')
IFS='.' read -r -a VERSION_PARTS <<< "$VERSION"
MAC_VERSION="$CURRENT_YEAR.${VERSION_PARTS[1]:-0}.${VERSION_PARTS[2]:-0}"
echo "versionNumberMac=$MAC_VERSION" >> $GITHUB_OUTPUT
build-portable:
needs: read_versions
runs-on: ubuntu-latest
strategy:
matrix:
enable_security: [true, false]
include:
- enable_security: true
file_suffix: "-with-login"
- enable_security: false
file_suffix: ""
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up JDK 21
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "21"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
with:
gradle-version: 8.12
- name: Generate jar (With Security=${{ matrix.enable_security }})
run: ./gradlew clean createExe
env:
DOCKER_ENABLE_SECURITY: ${{ matrix.enable_security }}
STIRLING_PDF_DESKTOP_UI: false
- name: Rename binaries
run: |
mkdir ./binaries
mv ./build/launch4j/Stirling-PDF.exe ./binaries/win-Stirling-PDF-portable-Server${{ matrix.file_suffix }}.exe
mv ./build/libs/Stirling-PDF-${{ needs.read_versions.outputs.version }}.jar ./binaries/Stirling-PDF${{ matrix.file_suffix }}.jar
- name: Upload build artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
retention-days: 1
if-no-files-found: error
name: stirling${{ matrix.file_suffix }}-binaries
path: |
./binaries/*
sign_verify-portable:
needs: [build-portable, read_versions]
runs-on: ubuntu-latest
strategy:
matrix:
enable_security: [true, false]
include:
- enable_security: true
file_suffix: "with-login-"
- enable_security: false
file_suffix: ""
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Download build artifacts
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with:
name: stirling-${{ matrix.file_suffix }}binaries
- name: Display structure of downloaded files
run: ls -R
- name: Upload signed artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
retention-days: 1
if-no-files-found: error
name: stirling-${{ matrix.file_suffix }}signed
path: |
./*
!cosign.*
build-installers:
needs: read_versions
strategy:
matrix:
include:
- os: windows-latest
platform: win-
- os: macos-latest
platform: mac-
# - os: ubuntu-latest
# platform: linux-
runs-on: ${{ matrix.os }}
permissions:
contents: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up JDK 21
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "21"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
with:
gradle-version: 8.12
# Install Windows dependencies
- name: Install WiX Toolset
if: matrix.os == 'windows-latest'
run: |
curl -L -o wix.exe https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314.exe
.\wix.exe /install /quiet
# Build installer
- name: Build Installer
run: ./gradlew build jpackage -x test --info
env:
DOCKER_ENABLE_SECURITY: false
STIRLING_PDF_DESKTOP_UI: true
BROWSER_OPEN: true
- name: ☕ Set up JDK (x86_64)
if: matrix.os == 'macos-latest'
run: |
curl -L -o jdk.tar.gz https://cdn.azul.com/zulu/bin/zulu17.56.15-ca-jdk17.0.14-macosx_x64.tar.gz
mkdir -p zulu17
tar -xzf jdk.tar.gz -C zulu17 --strip-components=1
echo "JAVA_HOME=$PWD/zulu17" >> $GITHUB_ENV
echo "$PWD/zulu17/bin" >> $GITHUB_PATH
- name: Verify JDK architecture
if: matrix.os == 'macos-latest'
run: file $JAVA_HOME/bin/java
- name: Build project and run jpackage (x86_64)
if: matrix.os == 'macos-latest'
run: arch -x86_64 ./gradlew jpackageMacX64
# Rename and collect artifacts based on OS
- name: Prepare artifacts
id: prepare
shell: bash
run: |
ls -lah ./build/jpackage/
mkdir ./binaries
if [ "${{ matrix.os }}" = "windows-latest" ]; then
mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.version }}.exe" "./binaries/Stirling-PDF-win-installer.exe"
elif [ "${{ matrix.os }}" = "macos-latest" ]; then
mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-installer.dmg"
mv "./build/jpackage/x86_64/Stirling-PDF (x86_64)-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-x86_64-installer.dmg"
else
mv "./build/jpackage/stirling-pdf_${{ needs.read_versions.outputs.version }}-1_amd64.deb" "./binaries/Stirling-PDF-linux-installer.deb"
fi
- name: Display structure of downloaded files
run: ls -R ./binaries
- name: Upload build artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
retention-days: 1
if-no-files-found: error
name: ${{ matrix.platform }}binaries
path: |
./binaries/*
sign_verify:
needs: [read_versions, build-installers]
strategy:
matrix:
include:
- os: windows-latest
platform: win-
- os: macos-latest
platform: mac-
# - os: ubuntu-latest
# platform: linux-
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Download build artifacts
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with:
name: ${{ matrix.platform }}binaries
- name: Display structure of downloaded files
run: ls -R
- name: Install Cosign
if: matrix.os == 'windows-latest'
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
- name: Generate key pair
if: matrix.os == 'windows-latest'
run: cosign generate-key-pair
- name: Sign and generate attestations
if: matrix.os == 'windows-latest'
run: |
cosign sign-blob \
--key ./cosign.key \
--yes \
--output-signature ./Stirling-PDF-win-installer.exe.sig \
./Stirling-PDF-win-installer.exe
cosign attest-blob \
--predicate - \
--key ./cosign.key \
--yes \
--output-attestation ./Stirling-PDF-win-installer.exe.intoto.jsonl \
./Stirling-PDF-win-installer.exe
cosign verify-blob \
--key ./cosign.pub \
--signature ./Stirling-PDF-win-installer.exe.sig \
./Stirling-PDF-win-installer.exe
- name: Display structure of downloaded files
run: ls -R
- name: Upload signed artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
retention-days: 1
if-no-files-found: error
name: ${{ matrix.platform }}signed
path: |
./Stirling-PDF-${{ matrix.platform }}installer.*
./Stirling-PDF-${{ matrix.platform }}x86_64-installer.*
!cosign.*
create-release:
if: github.event_name != 'workflow_dispatch' || github.event.inputs.test_mode != 'true'
needs: [read_versions, sign_verify, sign_verify-portable]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Download signed artifacts
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
- name: Display structure of downloaded files
run: ls -R
- name: Upload binaries, attestations and signatures to Release and create GitHub Release
uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # v2.1.0
with:
tag_name: v${{ needs.read_versions.outputs.version }}
generate_release_notes: true
files: |
./*signed/*
-80
View File
@@ -1,80 +0,0 @@
name: Pre-commit
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * 1"
permissions:
contents: read
jobs:
pre-commit:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Generate GitHub App Token
id: generate-token
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Get GitHub App User ID
id: get-user-id
run: echo "user-id=$(gh api "/users/${{ steps.generate-token.outputs.app-slug }}[bot]" --jq .id)" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
- id: committer
run: |
echo "string=${{ steps.generate-token.outputs.app-slug }}[bot] <${{ steps.get-user-id.outputs.user-id }}+${{ steps.generate-token.outputs.app-slug }}[bot]@users.noreply.github.com>" >> "$GITHUB_OUTPUT"
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
with:
python-version: 3.12
cache: 'pip' # caching pip dependencies
- name: Run Pre-Commit Hooks
run: |
pip install --require-hashes -r ./.github/scripts/requirements_pre_commit.txt
- run: pre-commit run --all-files -c .pre-commit-config.yaml
continue-on-error: true
- name: Set up git config
run: |
git config --global user.name ${{ steps.generate-token.outputs.app-slug }}[bot]
git config --global user.email "${{ steps.get-user-id.outputs.user-id }}+${{ steps.generate-token.outputs.app-slug }}[bot]@users.noreply.github.com"
- name: git add
run: |
git add .
git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
- name: Create Pull Request
if: env.CHANGES_DETECTED == 'true'
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
token: ${{ steps.generate-token.outputs.token }}
commit-message: ":file_folder: pre-commit"
committer: ${{ steps.committer.outputs.string }}
author: ${{ steps.committer.outputs.string }}
signoff: true
branch: pre-commit
title: "🤖 format everything with pre-commit by <${{ steps.generate-token.outputs.app-slug }}>"
body: |
Auto-generated by [create-pull-request][1] with **${{ steps.generate-token.outputs.app-slug }}**
[1]: https://github.com/peter-evans/create-pull-request
draft: false
delete-branch: true
labels: github-actions
sign-commits: true
-195
View File
@@ -1,195 +0,0 @@
name: Push Docker Image with VersionNumber
on:
workflow_dispatch:
push:
branches:
- master
- main
permissions:
contents: read
jobs:
push:
runs-on: ubuntu-latest
permissions:
packages: write
id-token: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "17"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
with:
gradle-version: 8.12
- name: Run Gradle Command
run: ./gradlew clean build
env:
DOCKER_ENABLE_SECURITY: false
STIRLING_PDF_DESKTOP_UI: false
- name: Install cosign
if: github.ref == 'refs/heads/master'
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
with:
cosign-release: "v2.4.1"
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- 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@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_API }}
- name: Login to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Convert repository owner to lowercase
id: repoowner
run: echo "lowercase=$(echo ${{ github.repository_owner }} | awk '{print tolower($0)}')" >> $GITHUB_OUTPUT
- name: Generate tags
id: meta
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with:
images: |
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/stirling-pdf
${{ secrets.DOCKER_HUB_ORG_USERNAME }}/stirling-pdf
tags: |
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }},enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=alpha,enable=${{ github.ref == 'refs/heads/main' }}
- name: Build and push main Dockerfile
id: build-push-regular
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
platforms: linux/amd64,linux/arm64/v8
provenance: true
sbom: true
- name: Sign regular images
if: github.ref == 'refs/heads/master'
env:
DIGEST: ${{ steps.build-push-regular.outputs.digest }}
TAGS: ${{ steps.meta.outputs.tags }}
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
run: |
echo "$TAGS" | tr ',' '\n' | while read -r tag; do
cosign sign --yes \
--key env://COSIGN_PRIVATE_KEY \
"${tag}@${DIGEST}"
done
- name: Generate tags ultra-lite
id: meta2
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
if: github.ref != 'refs/heads/main'
with:
images: |
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/stirling-pdf
${{ secrets.DOCKER_HUB_ORG_USERNAME }}/stirling-pdf
tags: |
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }}
- name: Build and push Dockerfile-ultra-lite
id: build-push-lite
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
if: github.ref != 'refs/heads/main'
with:
context: .
file: ./Dockerfile.ultra-lite
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: ${{ steps.meta2.outputs.tags }}
labels: ${{ steps.meta2.outputs.labels }}
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
platforms: linux/amd64,linux/arm64/v8
provenance: true
sbom: true
- name: Generate tags fat
id: meta3
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
if: github.ref != 'refs/heads/main'
with:
images: |
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/stirling-pdf
${{ secrets.DOCKER_HUB_ORG_USERNAME }}/stirling-pdf
tags: |
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-fat,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest-fat,enable=${{ github.ref == 'refs/heads/master' }}
- name: Build and push main Dockerfile fat
id: build-push-fat
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
if: github.ref != 'refs/heads/main'
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile.fat
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: ${{ steps.meta3.outputs.tags }}
labels: ${{ steps.meta3.outputs.labels }}
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
platforms: linux/amd64,linux/arm64/v8
provenance: true
sbom: true
- name: Sign fat images
if: github.ref == 'refs/heads/master'
env:
DIGEST: ${{ steps.build-push-fat.outputs.digest }}
TAGS: ${{ steps.meta3.outputs.tags }}
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
run: |
echo "$TAGS" | tr ',' '\n' | while read -r tag; do
cosign sign --key env://COSIGN_PRIVATE_KEY --yes "${tag}@${DIGEST}"
done
-180
View File
@@ -1,180 +0,0 @@
name: Release Artifacts
on:
workflow_dispatch:
release:
types: [created]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
enable_security: [true, false]
include:
- enable_security: true
file_suffix: "-with-login"
- enable_security: false
file_suffix: ""
outputs:
version: ${{ steps.versionNumber.outputs.versionNumber }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "17"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
with:
gradle-version: 8.12
- name: Generate jar (With Security=${{ matrix.enable_security }})
run: ./gradlew clean createExe
env:
DOCKER_ENABLE_SECURITY: ${{ matrix.enable_security }}
STIRLING_PDF_DESKTOP_UI: false
- name: Get version number
id: versionNumber
run: |
VERSION=$(grep "^version =" build.gradle | awk -F'"' '{print $2}')
echo "versionNumber=$VERSION" >> $GITHUB_OUTPUT
- name: Rename binaries
run: |
mv ./build/launch4j/Stirling-PDF.exe ./build/launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe
mv ./build/libs/Stirling-PDF-${{ steps.versionNumber.outputs.versionNumber }}.jar ./build/libs/Stirling-PDF${{ matrix.file_suffix }}.jar
- name: Debug build artifacts
run: |
echo "Current Directory: $(pwd)"
ls -R ./build/libs
ls -R ./build/launch4j
- name: Upload build artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: binaries${{ matrix.file_suffix }}
path: |
./build/launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.*
./build/libs/Stirling-PDF${{ matrix.file_suffix }}.*
sign_verify:
needs: build
runs-on: ubuntu-latest
strategy:
matrix:
enable_security: [true, false]
include:
- enable_security: true
file_suffix: "-with-login"
- enable_security: false
file_suffix: ""
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Download build artifacts
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with:
name: binaries${{ matrix.file_suffix }}
- name: Display structure of downloaded files
run: ls -R
- name: Install Cosign
uses: sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
- name: Generate key pair
run: cosign generate-key-pair
- name: Sign and generate attestations
run: |
cosign sign-blob \
--key ./cosign.key \
--yes \
--output-signature ./libs/Stirling-PDF${{ matrix.file_suffix }}.jar.sig \
./libs/Stirling-PDF${{ matrix.file_suffix }}.jar
cosign attest-blob \
--predicate - \
--key ./cosign.key \
--yes \
--output-attestation ./libs/Stirling-PDF${{ matrix.file_suffix }}.jar.intoto.jsonl \
./libs/Stirling-PDF${{ matrix.file_suffix }}.jar
cosign verify-blob \
--key ./cosign.pub \
--signature ./libs/Stirling-PDF${{ matrix.file_suffix }}.jar.sig \
./libs/Stirling-PDF${{ matrix.file_suffix }}.jar
cosign sign-blob \
--key ./cosign.key \
--yes \
--output-signature ./launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe.sig \
./launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe
cosign attest-blob \
--predicate - \
--key ./cosign.key \
--yes \
--output-attestation ./launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe.intoto.jsonl \
./launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe
cosign verify-blob \
--key ./cosign.pub \
--signature ./launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe.sig \
./launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe
- name: Upload signed artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: signed${{ matrix.file_suffix }}
path: |
./libs/Stirling-PDF${{ matrix.file_suffix }}.*
./launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.*
release:
needs: [build, sign_verify]
runs-on: ubuntu-latest
permissions:
contents: write
strategy:
matrix:
enable_security: [true, false]
include:
- enable_security: true
file_suffix: "-with-login"
- enable_security: false
file_suffix: ""
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Download signed artifacts
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with:
name: signed${{ matrix.file_suffix }}
- name: Upload binaries, attestations and signatures to Release and create GitHub Release
uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # v2.1.0
with:
tag_name: v${{ needs.build.outputs.version }}
generate_release_notes: true
files: |
./libs/Stirling-PDF*
./launch4j/Stirling-PDF-Server*
-79
View File
@@ -1,79 +0,0 @@
# 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.
name: Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: "20 7 * * 2"
push:
branches: ["main"]
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
contents: read
actions: read
# To allow GraphQL ListCommits to work
issues: read
pull-requests: read
# To detect SAST tools
checks: read
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: "Checkout code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with:
results_file: results.sarif
results_format: sarif
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecards on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
# Public repositories:
# - Publish results to OpenSSF REST API for easy access by consumers
# - Allows the repository to include the Scorecard badge.
# - See https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories:
# - `publish_results` will always be set to `false`, regardless
# of the value entered here.
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15
with:
sarif_file: results.sarif
-63
View File
@@ -1,63 +0,0 @@
name: Run Sonarqube
on:
push:
branches:
- master
pull_request_target:
branches:
- main
workflow_dispatch:
permissions:
pull-requests: read
actions: read
jobs:
sonarqube:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Setup Gradle
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- name: Build and analyze with Gradle
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
DOCKER_ENABLE_SECURITY: true
STIRLING_PDF_DESKTOP_UI: true
run: |
./gradlew clean build sonar \
-Dsonar.projectKey=Stirling-Tools_Stirling-PDF \
-Dsonar.organization=stirling-tools \
-Dsonar.host.url=https://sonarcloud.io \
-Dsonar.login=${SONAR_TOKEN} \
-Dsonar.log.level=DEBUG \
--info
- name: Upload Problems Report on Failure
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: gradle-problems-report
path: build/reports/problems/problems-report.html
retention-days: 7
- name: Upload Sonar Logs on Failure
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: sonar-logs
path: |
.scannerwork/report-task.txt
build/sonar/
retention-days: 7
-40
View File
@@ -1,40 +0,0 @@
name: Close stale issues
on:
schedule:
- cron: "30 0 * * *"
workflow_dispatch:
permissions:
contents: read
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: 30 days stale issues
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30
days-before-close: 7
stale-issue-message: >
This issue has been automatically marked as stale because it has had no recent activity.
It will be closed if no further activity occurs. Thank you for your contributions.
close-issue-message: >
This issue has been automatically closed because it has had no recent activity after being marked as stale.
Please reopen if you need further assistance.
stale-issue-label: "Stale"
remove-stale-when-updated: true
only-issue-labels: "more-info-needed"
days-before-pr-stale: -1 # Prevents PRs from being marked as stale
days-before-pr-close: -1 # Prevents PRs from being closed
start-date: "2024-07-06T00:00:00Z" # ISO 8601 Format
-49
View File
@@ -1,49 +0,0 @@
name: Update Swagger
on:
workflow_dispatch:
push:
branches:
- master
permissions:
contents: read
jobs:
push:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: "17"
distribution: "temurin"
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1
- name: Generate Swagger documentation
run: ./gradlew generateOpenApiDocs
- name: Upload Swagger Documentation to SwaggerHub
run: ./gradlew swaggerhubUpload
env:
SWAGGERHUB_API_KEY: ${{ secrets.SWAGGERHUB_API_KEY }}
SWAGGERHUB_USER: "Frooodle"
- name: Get version number
id: versionNumber
run: echo "versionNumber=$(./gradlew printVersion --quiet | tail -1)" >> $GITHUB_OUTPUT
- name: Set API version as published and default on SwaggerHub
run: |
curl -X PUT -H "Authorization: ${SWAGGERHUB_API_KEY}" "https://api.swaggerhub.com/apis/${SWAGGERHUB_USER}/Stirling-PDF/${{ steps.versionNumber.outputs.versionNumber }}/settings/lifecycle" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"published\":true,\"default\":true}"
env:
SWAGGERHUB_API_KEY: ${{ secrets.SWAGGERHUB_API_KEY }}
SWAGGERHUB_USER: "Frooodle"
-145
View File
@@ -1,145 +0,0 @@
name: Sync Files
on:
workflow_dispatch:
push:
branches:
- main
paths:
- "build.gradle"
- "README.md"
- "src/main/resources/messages_*.properties"
- "src/main/resources/static/3rdPartyLicenses.json"
- "scripts/ignore_translation.toml"
permissions:
contents: read
jobs:
read_bot_entries:
runs-on: ubuntu-latest
outputs:
userName: ${{ steps.get-user-id.outputs.user_name }}
userEmail: ${{ steps.get-user-id.outputs.user_email }}
committer: ${{ steps.committer.outputs.committer }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Generate GitHub App Token
id: generate-token
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Get GitHub App User ID
id: get-user-id
run: |
USER_NAME="${{ steps.generate-token.outputs.app-slug }}[bot]"
USER_ID=$(gh api "/users/$USER_NAME" --jq .id)
USER_EMAIL="$USER_ID+$USER_NAME@users.noreply.github.com"
echo "user_name=$USER_NAME" >> "$GITHUB_OUTPUT"
echo "user_email=$USER_EMAIL" >> "$GITHUB_OUTPUT"
echo "user-id=$USER_ID" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
- id: committer
run: |
COMMITTER="${{ steps.get-user-id.outputs.user_name }} <${{ steps.get-user-id.outputs.user_email }}>"
echo "committer=$COMMITTER" >> "$GITHUB_OUTPUT"
sync-files:
needs: ["read_bot_entries"]
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Generate GitHub App Token
id: generate-token
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
with:
app-id: ${{ vars.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Python
uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
with:
python-version: "3.12"
cache: 'pip' # caching pip dependencies
- name: Sync translation property files
run: |
python .github/scripts/check_language_properties.py --reference-file "src/main/resources/messages_en_GB.properties" --branch main
- name: Set up git config
run: |
git config --global user.name ${{ needs.read_bot_entries.outputs.userName }}
git config --global user.email ${{ needs.read_bot_entries.outputs.userEmail }}
- name: Run git add
run: |
git add src/main/resources/messages_*.properties
git diff --staged --quiet || git commit -m ":memo: Sync translation files" || echo "no changes"
- name: Install dependencies
run: pip install --require-hashes -r ./.github/scripts/requirements_sync_readme.txt
- name: Sync README.md
run: |
python scripts/counter_translation.py
- name: Run git add
run: |
git add README.md
git diff --staged --quiet || git commit -m ":memo: Sync README.md" || echo "no changes"
- name: Create Pull Request
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
with:
token: ${{ steps.generate-token.outputs.token }}
commit-message: Update files
committer: ${{ needs.read_bot_entries.outputs.committer }}
author: ${{ needs.read_bot_entries.outputs.committer }}
signoff: true
branch: sync_readme
title: ":globe_with_meridians: Sync Translations + Update README Progress Table"
body: |
### Description of Changes
This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made:
#### **1. Synchronization of Translation Files**
- Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`.
- Ensured consistency and synchronization across all supported language files.
- Highlighted any missing or incomplete translations.
#### **2. Update README.md**
- Generated the translation progress table in `README.md`.
- Added a summary of the current translation status for all supported languages.
- Included up-to-date statistics on translation coverage.
#### **Why these changes are necessary**
- Keeps translation files aligned with the latest reference updates.
- Ensures the documentation reflects the current translation progress.
---
Auto-generated by [create-pull-request][1].
[1]: https://github.com/peter-evans/create-pull-request
draft: false
delete-branch: true
labels: github-actions
sign-commits: true
add-paths: |
README.md
src/main/resources/messages_*.properties
-154
View File
@@ -1,154 +0,0 @@
name: UI test with TestDriverAI
on:
push:
branches: ["master", "UITest", "testdriver"]
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up JDK
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
run: ./gradlew clean build
env:
DOCKER_ENABLE_SECURITY: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Get version number
id: versionNumber
run: |
VERSION=$(grep "^version =" build.gradle | awk -F'"' '{print $2}')
echo "versionNumber=$VERSION" >> $GITHUB_OUTPUT
- name: Login to Docker Hub
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_API }}
- name: Build and push test image
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:test-${{ github.sha }}
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: |
cat > docker-compose.yml << EOF
version: '3.3'
services:
stirling-pdf:
container_name: stirling-pdf-test-${{ github.sha }}
image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:test-${{ github.sha }}
ports:
- "1337:8080"
volumes:
- /stirling/test-${{ github.sha }}/data:/usr/share/tessdata:rw
- /stirling/test-${{ github.sha }}/config:/configs:rw
- /stirling/test-${{ github.sha }}/logs:/logs:rw
environment:
DOCKER_ENABLE_SECURITY: "false"
SECURITY_ENABLELOGIN: "false"
SYSTEM_DEFAULTLOCALE: en-GB
UI_APPNAME: "Stirling-PDF Test"
UI_HOMEDESCRIPTION: "Test Deployment"
UI_APPNAMENAVBAR: "Test"
SYSTEM_MAXFILESIZE: "100"
METRICS_ENABLED: "true"
SYSTEM_GOOGLEVISIBILITY: "false"
SYSTEM_ENABLEANALYTICS: "false"
restart: on-failure:5
EOF
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 ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << EOF
mkdir -p /stirling/test-${{ github.sha }}/{data,config,logs}
mv /tmp/docker-compose.yml /stirling/test-${{ github.sha }}/docker-compose.yml
cd /stirling/test-${{ github.sha }}
docker-compose pull
docker-compose up -d
EOF
test:
needs: deploy
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run TestDriver.ai
uses: testdriverai/action@f0d0f45fdd684db628baa843fe9313f3ca3a8aa8 #1.1.3
with:
key: ${{secrets.TESTDRIVER_API_KEY}}
prerun: |
npm install
npm run build
npm install dashcam-chrome --save
Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--load-extension=$(pwd)/node_modules/dashcam-chrome/build", "http://${{ secrets.VPS_HOST }}:1337"
Start-Sleep -Seconds 20
prompt: |
1. /run testing/testdriver/test.yml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
FORCE_COLOR: "3"
cleanup:
needs: [deploy, test]
runs-on: ubuntu-latest
if: always()
steps:
- name: Harden Runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:
egress-policy: audit
- name: Set up SSH
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
sudo chmod 600 ../private.key
- name: Cleanup deployment
run: |
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << EOF
cd /stirling/test-${{ github.sha }}
docker-compose down
cd /stirling
rm -rf test-${{ github.sha }}
EOF
@@ -0,0 +1,272 @@
package stirling.software.SPDF.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.zip.CRC32;
@Configuration
public class TemplateIntegrityConfig {
private static final Logger logger = LoggerFactory.getLogger(TemplateIntegrityConfig.class);
// Buffer size for reading files (8KB is a good balance)
private static final int BUFFER_SIZE = 8192;
private final ResourceLoader resourceLoader;
@Value("${template.hash.reference:classpath:reference-hash.json}")
private String referenceHashPath;
@Value("${template.directories:classpath:templates/,classpath:static/}")
private String[] templateDirectories;
@Value("${template.normalize.line.endings:true}")
private boolean normalizeLineEndings;
@Value("${template.integrity.enabled:true}")
private boolean integrityCheckEnabled;
public TemplateIntegrityConfig(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Bean
public boolean templatesModified() {
if (!integrityCheckEnabled) {
logger.info("Template integrity checking is disabled");
return false;
}
try {
// Log configuration information
logConfiguration();
Map<String, String> referenceHashes = loadReferenceHashes();
// Check for modifications with early termination
if (checkForModifications(referenceHashes)) {
logger.warn("SECURITY WARNING: Templates appear to have been modified from the release version!");
return true;
}
logger.info("Template integrity verified successfully");
return false;
} catch (Exception e) {
logger.error("Error verifying template integrity", e);
// In case of error, assume modified for security
return true;
}
}
private void logConfiguration() {
logger.info("Template integrity check starting with configuration:");
logger.info(" - Reference hash path: {}", referenceHashPath);
logger.info(" - Template directories: {}", String.join(", ", templateDirectories));
logger.info(" - Line ending normalization: {}", normalizeLineEndings ? "enabled" : "disabled");
}
private Map<String, String> loadReferenceHashes() throws IOException {
Resource resource = resourceLoader.getResource(referenceHashPath);
try (InputStream is = resource.getInputStream()) {
String content = new String(is.readAllBytes());
Map<String, String> hashes = parseHashJson(content);
logReferenceHashes(hashes);
return hashes;
}
}
private void logReferenceHashes(Map<String, String> hashes) {
logger.info("Loaded {} reference hashes", hashes.size());
// Log a few example files for debugging
logger.info("Sample of reference hashes:");
hashes.entrySet().stream()
.limit(5)
.forEach(e -> logger.info(" - {}: {}", e.getKey(), e.getValue()));
// Also log sample PDF files if any
hashes.entrySet().stream()
.filter(e -> e.getKey().endsWith(".pdf"))
.limit(3)
.forEach(e -> logger.info(" - PDF file: {}: {}", e.getKey(), e.getValue()));
}
private Map<String, String> parseHashJson(String json) {
Map<String, String> result = new HashMap<>();
// Simple JSON parsing to avoid additional dependencies
// Remove all whitespace first to make parsing more robust
json = json.replaceAll("\\s+", "");
String[] entries = json.replaceAll("[{}\"]", "").split(",");
for (String entry : entries) {
if (entry.isEmpty()) continue;
String[] parts = entry.split(":");
if (parts.length == 2) {
result.put(parts[0], parts[1]);
}
}
logger.debug("Loaded {} reference hashes", result.size());
return result;
}
private boolean checkForModifications(Map<String, String> referenceHashes) throws IOException {
// Track files we've found to check for missing files later
Map<String, Boolean> foundFiles = new HashMap<>();
for (String key : referenceHashes.keySet()) {
foundFiles.put(key, false);
}
AtomicBoolean modified = new AtomicBoolean(false);
// Check each directory
for (String dir : templateDirectories) {
if (modified.get()) {
break; // Early termination
}
// Remove classpath: prefix if present
String dirPath = dir.replace("classpath:", "");
// Get the resource as a file
Resource resource = resourceLoader.getResource("classpath:" + dirPath);
try {
Path directory = Paths.get(resource.getURI());
if (Files.exists(directory) && Files.isDirectory(directory)) {
// Walk the directory tree - process ALL files, not just text files
Files.walk(directory)
.filter(Files::isRegularFile)
.forEach(path -> {
if (modified.get()) return; // Skip if already found modification
try {
String basePath = dirPath.replace("/", "");
String relativePath = basePath + "/" + directory.relativize(path).toString().replace("\\", "/");
// Debug log the path normalization
logger.debug("Processing file: {} -> {}", path, relativePath);
// Check if this file is in our reference
String referenceHash = referenceHashes.get(relativePath);
if (referenceHash == null) {
// Try with different path format
relativePath = directory.relativize(path).toString().replace("\\", "/");
referenceHash = referenceHashes.get(relativePath);
if (referenceHash == null) {
// New file found
String currentHash = computeFileHash(path);
logger.warn("New file detected: {} (calculated hash: {})",
relativePath, currentHash);
modified.set(true);
return;
}
}
// Track that we found this file
foundFiles.put(relativePath, true);
// Check if the hash matches
String currentHash = computeFileHash(path);
// Log hash comparison for debugging
logger.info("Hash comparison for {}: reference={}, current={}",
relativePath, referenceHash, currentHash);
if (!currentHash.equals(referenceHash)) {
logger.warn("Modified file detected: {} (expected hash: {}, actual hash: {})",
relativePath, referenceHash, currentHash);
modified.set(true);
}
} catch (IOException e) {
logger.warn("Failed to hash file: {}", path, e);
modified.set(true); // Fail safe
}
});
}
} catch (Exception e) {
logger.error("Error accessing directory: {}", dirPath, e);
return true; // Assume modified on error
}
}
// If we haven't found a modification yet, check for missing files
if (!modified.get()) {
for (Map.Entry<String, Boolean> entry : foundFiles.entrySet()) {
if (!entry.getValue()) {
// File was in reference but not found - report ALL missing files
logger.warn("Missing file detected: {} (expected hash: {})",
entry.getKey(), referenceHashes.get(entry.getKey()));
return true;
}
}
}
return modified.get();
}
private String computeFileHash(Path filePath) throws IOException {
// For text files like HTML, normalize content before hashing
String extension = getFileExtension(filePath.toString()).toLowerCase();
if (normalizeLineEndings && isTextFile(extension)) {
return computeNormalizedTextFileHash(filePath);
} else {
// Binary files use direct CRC32
return computeBinaryFileHash(filePath);
}
}
private String computeNormalizedTextFileHash(Path filePath) throws IOException {
byte[] content = Files.readAllBytes(filePath);
String text = new String(content, StandardCharsets.UTF_8);
// Remove ALL carriage returns to match GitHub workflow's tr -d '\r'
text = text.replace("\r", "");
byte[] normalizedBytes = text.getBytes(StandardCharsets.UTF_8);
CRC32 checksum = new CRC32();
checksum.update(normalizedBytes, 0, normalizedBytes.length);
return String.valueOf(checksum.getValue());
}
private String computeBinaryFileHash(Path filePath) throws IOException {
byte[] content = Files.readAllBytes(filePath);
CRC32 checksum = new CRC32();
checksum.update(content, 0, content.length);
return String.valueOf(checksum.getValue());
}
private String getFileExtension(String filename) {
int lastDot = filename.lastIndexOf('.');
if (lastDot == -1 || lastDot == filename.length() - 1) {
return "";
}
return filename.substring(lastDot + 1);
}
private boolean isTextFile(String extension) {
// List of common text file extensions
return extension.equals("html") || extension.equals("htm") ||
extension.equals("css") || extension.equals("js") ||
extension.equals("txt") || extension.equals("md") ||
extension.equals("xml") || extension.equals("json") ||
extension.equals("csv") || extension.equals("properties");
}
}
+637
View File
@@ -0,0 +1,637 @@
{
"static/3rdPartyLicenses.json": "1229806676",
"static/android-chrome-192x192.png": "81292174",
"static/android-chrome-512x512.png": "2225043850",
"static/apple-touch-icon.png": "4086094808",
"static/browserconfig.xml": "1544478906",
"static/css/account.css": "2759066875",
"static/css/add-image.css": "2865506209",
"static/css/bootstrap-icons.css": "3243076773",
"static/css/bootstrap-icons.min.css": "4153732813",
"static/css/bootstrap.min.css": "1689706049",
"static/css/bootstrap.min.css.map": "3390460638",
"static/css/cookieconsent.css": "3523622749",
"static/css/cookieconsentCustomisation.css": "3688151178",
"static/css/dragdrop.css": "3608137622",
"static/css/error.css": "2492494937",
"static/css/errorBanner.css": "776950833",
"static/css/fileSelect.css": "3856036123",
"static/css/fonts/bootstrap-icons.woff": "2550557042",
"static/css/fonts/bootstrap-icons.woff2": "2506739912",
"static/css/footer.css": "2484212037",
"static/css/game.css": "781267531",
"static/css/general.css": "510444270",
"static/css/home-legacy.css": "4203130249",
"static/css/home.css": "3138729040",
"static/css/imageHighlighter.css": "3363891740",
"static/css/licenses.css": "1935689034",
"static/css/login.css": "463867561",
"static/css/merge.css": "83033112",
"static/css/multi-tool.css": "2076422567",
"static/css/navbar.css": "1561300963",
"static/css/pdfActions.css": "262525104",
"static/css/pipeline.css": "1641938110",
"static/css/prism.css": "2441988556",
"static/css/rainbow-mode.css": "3749668904",
"static/css/redact.css": "2372516835",
"static/css/removeImage.css": "3707867653",
"static/css/rotate-pdf.css": "796830012",
"static/css/sign.css": "702477677",
"static/css/split-pdf-by-sections.css": "2274811011",
"static/css/stamp.css": "683032492",
"static/css/tab-container.css": "886515714",
"static/css/theme/componentes.css": "3193844532",
"static/css/theme/font.css": "391249967",
"static/css/theme/theme.css": "1270042309",
"static/css/theme/theme.dark.css": "3242422795",
"static/css/theme/theme.light.css": "1949462314",
"static/css/usage.css": "3285305074",
"static/favicon-16x16.png": "478663016",
"static/favicon-32x32.png": "1738736947",
"static/favicon.icns": "2939245569",
"static/favicon.ico": "2372923367",
"static/favicon.png": "151349943",
"static/favicon.svg": "4253447741",
"static/files/Auto Splitter Divider (with instructions).pdf": "1660944084",
"static/files/popularity.txt": "1111109125",
"static/fonts/Arimo-Regular.woff2": "3579229415",
"static/fonts/DancingScript-Regular.woff2": "1149517625",
"static/fonts/Estonia.woff2": "1047176002",
"static/fonts/IndieFlower-Regular.woff2": "389792484",
"static/fonts/Meiryo.ttf": "939652936",
"static/fonts/NotoSans-Regular.ttf": "728005021",
"static/fonts/NotoSansArabic-Regular.ttf": "2456313448",
"static/fonts/NotoSansJP-Regular.ttf": "2909684520",
"static/fonts/NotoSansSC-Regular.ttf": "3013430169",
"static/fonts/SimSun.ttf": "4052153469",
"static/fonts/Tangerine.woff2": "3783755990",
"static/fonts/Tinos-Regular.woff2": "4065964104",
"static/fonts/google-symbol.woff2": "1829782430",
"static/fonts/malgun.ttf": "1057764895",
"static/fonts/static/NotoSansArabic-Regular.ttf": "2456313448",
"static/fonts/static/NotoSansJP-Regular.ttf": "2909684520",
"static/images/Files.svg": "2824014709",
"static/images/arrow-right-short.svg": "2689017919",
"static/images/book.svg": "266640917",
"static/images/clipboard.svg": "4156082331",
"static/images/discord.svg": "1854800855",
"static/images/docker.svg": "3226709572",
"static/images/file-earmark-pdf.svg": "542109425",
"static/images/github.svg": "17348698",
"static/images/google-drive.svg": "2046910859",
"static/images/redact-auto.svg": "2360528643",
"static/images/redact-manual.svg": "4124720765",
"static/images/rename.svg": "2588201487",
"static/images/signature.png": "1399452799",
"static/images/split-auto.svg": "279810086",
"static/images/split-chapters.svg": "2694426399",
"static/images/split-size.svg": "404618030",
"static/images/update.svg": "751260275",
"static/js/DecryptFiles.js": "101637227",
"static/js/cacheFormInputs.js": "4132750297",
"static/js/compare/diff.js": "1886629456",
"static/js/compare/pdfWorker.js": "1942960477",
"static/js/csrf.js": "2627654323",
"static/js/darkmode.js": "1387683192",
"static/js/download.js": "3184469014",
"static/js/downloader.js": "4018120238",
"static/js/draggable-utils.js": "2852095189",
"static/js/errorBanner.js": "1034517098",
"static/js/favourites.js": "420226678",
"static/js/fetch-utils.js": "1969008888",
"static/js/file-icon-factory.js": "3044878297",
"static/js/file-utils.js": "731247806",
"static/js/fileInput.js": "1810771594",
"static/js/game.js": "4183827120",
"static/js/githubVersion.js": "4108695586",
"static/js/googleFilePicker.js": "1170695682",
"static/js/homecard-legacy.js": "2206659887",
"static/js/homecard.js": "3864275751",
"static/js/languageSelection.js": "1685294785",
"static/js/local-pdf-input-download.js": "740207637",
"static/js/merge.js": "545373593",
"static/js/multitool/DragDropManager.js": "4266549244",
"static/js/multitool/ImageHighlighter.js": "882692397",
"static/js/multitool/PdfActionsManager.js": "1347379144",
"static/js/multitool/PdfContainer.js": "1408228191",
"static/js/multitool/UndoManager.js": "2350100876",
"static/js/multitool/commands/add-page.js": "1013750615",
"static/js/multitool/commands/command.js": "139745180",
"static/js/multitool/commands/commands-sequence.js": "2773105924",
"static/js/multitool/commands/delete-page.js": "4067560822",
"static/js/multitool/commands/move-page.js": "178890182",
"static/js/multitool/commands/page-break.js": "459543243",
"static/js/multitool/commands/remove.js": "227657941",
"static/js/multitool/commands/rotate.js": "4081745289",
"static/js/multitool/commands/select.js": "4156938430",
"static/js/multitool/commands/split.js": "2410232821",
"static/js/navbar.js": "1605830618",
"static/js/pages/add-image.js": "2341994819",
"static/js/pages/adjust-contrast.js": "2377072209",
"static/js/pages/change-metadata.js": "1801562158",
"static/js/pages/crop.js": "2466662217",
"static/js/pages/home.js": "2461515247",
"static/js/pages/pdf-to-csv.js": "3295302382",
"static/js/pages/sign.js": "2111582536",
"static/js/pipeline.js": "2423477306",
"static/js/redact.js": "892372093",
"static/js/search.js": "1706030584",
"static/js/settings.js": "937519315",
"static/js/sign/signature-canvas.js": "4251442164",
"static/js/tab-container.js": "2704937913",
"static/js/thirdParty/bootstrap.min.js": "1370242179",
"static/js/thirdParty/bootstrap.min.js.map": "3983913575",
"static/js/thirdParty/chart.umd.min.js": "3973720551",
"static/js/thirdParty/cookieconsent-config.js": "156419308",
"static/js/thirdParty/cookieconsent.umd.js": "3824668452",
"static/js/thirdParty/fontfaceobserver.standalone.js": "1570234949",
"static/js/thirdParty/interact.min.js": "3744632834",
"static/js/thirdParty/interact.min.js.map": "1057690385",
"static/js/thirdParty/jquery.min.js": "2331563552",
"static/js/thirdParty/jquery.validate.min.js": "2184571784",
"static/js/thirdParty/jszip.min.js": "3577268273",
"static/js/thirdParty/pdf-lib.min.js": "761931226",
"static/js/thirdParty/pdf-lib.min.js.map": "632347702",
"static/js/thirdParty/popper.min.js": "2188869012",
"static/js/thirdParty/popper.min.js.map": "3980223165",
"static/js/thirdParty/prism.js": "2520358674",
"static/js/thirdParty/signature_pad.umd.min.js": "1850470598",
"static/js/thirdParty/signature_pad.umd.min.js.map": "4114448793",
"static/js/usage.js": "3788668416",
"static/js/uuid.js": "90340888",
"static/manifest.json": "1605505975",
"static/moon.svg": "2869020792",
"static/mstile-144x144.png": "300463106",
"static/mstile-150x150.png": "3098693039",
"static/mstile-310x150.png": "2898707172",
"static/mstile-310x310.png": "1509160851",
"static/mstile-70x70.png": "3686632632",
"static/pdfjs-legacy/cmaps/78-EUC-H.bcmap": "2935523365",
"static/pdfjs-legacy/cmaps/78-EUC-V.bcmap": "1215664696",
"static/pdfjs-legacy/cmaps/78-H.bcmap": "727054873",
"static/pdfjs-legacy/cmaps/78-RKSJ-H.bcmap": "2313580186",
"static/pdfjs-legacy/cmaps/78-RKSJ-V.bcmap": "1765807051",
"static/pdfjs-legacy/cmaps/78-V.bcmap": "3630341985",
"static/pdfjs-legacy/cmaps/78ms-RKSJ-H.bcmap": "3538898282",
"static/pdfjs-legacy/cmaps/78ms-RKSJ-V.bcmap": "954831649",
"static/pdfjs-legacy/cmaps/83pv-RKSJ-H.bcmap": "1816984529",
"static/pdfjs-legacy/cmaps/90ms-RKSJ-H.bcmap": "2640388869",
"static/pdfjs-legacy/cmaps/90ms-RKSJ-V.bcmap": "2689717230",
"static/pdfjs-legacy/cmaps/90msp-RKSJ-H.bcmap": "442781296",
"static/pdfjs-legacy/cmaps/90msp-RKSJ-V.bcmap": "3813105348",
"static/pdfjs-legacy/cmaps/90pv-RKSJ-H.bcmap": "1449629516",
"static/pdfjs-legacy/cmaps/90pv-RKSJ-V.bcmap": "2150096073",
"static/pdfjs-legacy/cmaps/Add-H.bcmap": "991617969",
"static/pdfjs-legacy/cmaps/Add-RKSJ-H.bcmap": "1358556981",
"static/pdfjs-legacy/cmaps/Add-RKSJ-V.bcmap": "687911045",
"static/pdfjs-legacy/cmaps/Add-V.bcmap": "1992675008",
"static/pdfjs-legacy/cmaps/Adobe-CNS1-0.bcmap": "318654637",
"static/pdfjs-legacy/cmaps/Adobe-CNS1-1.bcmap": "3876085864",
"static/pdfjs-legacy/cmaps/Adobe-CNS1-2.bcmap": "1497712689",
"static/pdfjs-legacy/cmaps/Adobe-CNS1-3.bcmap": "3952802782",
"static/pdfjs-legacy/cmaps/Adobe-CNS1-4.bcmap": "2170674459",
"static/pdfjs-legacy/cmaps/Adobe-CNS1-5.bcmap": "1128661073",
"static/pdfjs-legacy/cmaps/Adobe-CNS1-6.bcmap": "3265114187",
"static/pdfjs-legacy/cmaps/Adobe-CNS1-UCS2.bcmap": "3815001805",
"static/pdfjs-legacy/cmaps/Adobe-GB1-0.bcmap": "321104391",
"static/pdfjs-legacy/cmaps/Adobe-GB1-1.bcmap": "3078356106",
"static/pdfjs-legacy/cmaps/Adobe-GB1-2.bcmap": "12271552",
"static/pdfjs-legacy/cmaps/Adobe-GB1-3.bcmap": "1565649755",
"static/pdfjs-legacy/cmaps/Adobe-GB1-4.bcmap": "891137737",
"static/pdfjs-legacy/cmaps/Adobe-GB1-5.bcmap": "1333741453",
"static/pdfjs-legacy/cmaps/Adobe-GB1-UCS2.bcmap": "4258237810",
"static/pdfjs-legacy/cmaps/Adobe-Japan1-0.bcmap": "638423810",
"static/pdfjs-legacy/cmaps/Adobe-Japan1-1.bcmap": "324444563",
"static/pdfjs-legacy/cmaps/Adobe-Japan1-2.bcmap": "2106653903",
"static/pdfjs-legacy/cmaps/Adobe-Japan1-3.bcmap": "2110071234",
"static/pdfjs-legacy/cmaps/Adobe-Japan1-4.bcmap": "3190778019",
"static/pdfjs-legacy/cmaps/Adobe-Japan1-5.bcmap": "114514500",
"static/pdfjs-legacy/cmaps/Adobe-Japan1-6.bcmap": "3331639032",
"static/pdfjs-legacy/cmaps/Adobe-Japan1-UCS2.bcmap": "2220323089",
"static/pdfjs-legacy/cmaps/Adobe-Korea1-0.bcmap": "964959775",
"static/pdfjs-legacy/cmaps/Adobe-Korea1-1.bcmap": "1035658642",
"static/pdfjs-legacy/cmaps/Adobe-Korea1-2.bcmap": "3429891476",
"static/pdfjs-legacy/cmaps/Adobe-Korea1-UCS2.bcmap": "3576578106",
"static/pdfjs-legacy/cmaps/B5-H.bcmap": "1305638476",
"static/pdfjs-legacy/cmaps/B5-V.bcmap": "3312329546",
"static/pdfjs-legacy/cmaps/B5pc-H.bcmap": "384598821",
"static/pdfjs-legacy/cmaps/B5pc-V.bcmap": "2922146617",
"static/pdfjs-legacy/cmaps/CNS-EUC-H.bcmap": "374138555",
"static/pdfjs-legacy/cmaps/CNS-EUC-V.bcmap": "2347910364",
"static/pdfjs-legacy/cmaps/CNS1-H.bcmap": "481999617",
"static/pdfjs-legacy/cmaps/CNS1-V.bcmap": "1344232354",
"static/pdfjs-legacy/cmaps/CNS2-H.bcmap": "2505659432",
"static/pdfjs-legacy/cmaps/CNS2-V.bcmap": "3249310900",
"static/pdfjs-legacy/cmaps/ETHK-B5-H.bcmap": "1793349426",
"static/pdfjs-legacy/cmaps/ETHK-B5-V.bcmap": "757603944",
"static/pdfjs-legacy/cmaps/ETen-B5-H.bcmap": "3979387347",
"static/pdfjs-legacy/cmaps/ETen-B5-V.bcmap": "1160598327",
"static/pdfjs-legacy/cmaps/ETenms-B5-H.bcmap": "3094635261",
"static/pdfjs-legacy/cmaps/ETenms-B5-V.bcmap": "3718993024",
"static/pdfjs-legacy/cmaps/EUC-H.bcmap": "2004937234",
"static/pdfjs-legacy/cmaps/EUC-V.bcmap": "3456045255",
"static/pdfjs-legacy/cmaps/Ext-H.bcmap": "4060307298",
"static/pdfjs-legacy/cmaps/Ext-RKSJ-H.bcmap": "3104367268",
"static/pdfjs-legacy/cmaps/Ext-RKSJ-V.bcmap": "2394309666",
"static/pdfjs-legacy/cmaps/Ext-V.bcmap": "2846830421",
"static/pdfjs-legacy/cmaps/GB-EUC-H.bcmap": "954377692",
"static/pdfjs-legacy/cmaps/GB-EUC-V.bcmap": "456223590",
"static/pdfjs-legacy/cmaps/GB-H.bcmap": "2578647423",
"static/pdfjs-legacy/cmaps/GB-V.bcmap": "3060676607",
"static/pdfjs-legacy/cmaps/GBK-EUC-H.bcmap": "4142842701",
"static/pdfjs-legacy/cmaps/GBK-EUC-V.bcmap": "3737065709",
"static/pdfjs-legacy/cmaps/GBK2K-H.bcmap": "465400037",
"static/pdfjs-legacy/cmaps/GBK2K-V.bcmap": "4179958592",
"static/pdfjs-legacy/cmaps/GBKp-EUC-H.bcmap": "2372866802",
"static/pdfjs-legacy/cmaps/GBKp-EUC-V.bcmap": "1250940062",
"static/pdfjs-legacy/cmaps/GBT-EUC-H.bcmap": "2979783535",
"static/pdfjs-legacy/cmaps/GBT-EUC-V.bcmap": "4115776022",
"static/pdfjs-legacy/cmaps/GBT-H.bcmap": "3429110978",
"static/pdfjs-legacy/cmaps/GBT-V.bcmap": "2740189073",
"static/pdfjs-legacy/cmaps/GBTpc-EUC-H.bcmap": "2953195113",
"static/pdfjs-legacy/cmaps/GBTpc-EUC-V.bcmap": "1341020212",
"static/pdfjs-legacy/cmaps/GBpc-EUC-H.bcmap": "4023150530",
"static/pdfjs-legacy/cmaps/GBpc-EUC-V.bcmap": "1717815923",
"static/pdfjs-legacy/cmaps/H.bcmap": "436786100",
"static/pdfjs-legacy/cmaps/HKdla-B5-H.bcmap": "3200750930",
"static/pdfjs-legacy/cmaps/HKdla-B5-V.bcmap": "2384100636",
"static/pdfjs-legacy/cmaps/HKdlb-B5-H.bcmap": "1276598372",
"static/pdfjs-legacy/cmaps/HKdlb-B5-V.bcmap": "2816805808",
"static/pdfjs-legacy/cmaps/HKgccs-B5-H.bcmap": "4168780367",
"static/pdfjs-legacy/cmaps/HKgccs-B5-V.bcmap": "3477028701",
"static/pdfjs-legacy/cmaps/HKm314-B5-H.bcmap": "2032399570",
"static/pdfjs-legacy/cmaps/HKm314-B5-V.bcmap": "4190629966",
"static/pdfjs-legacy/cmaps/HKm471-B5-H.bcmap": "1982538898",
"static/pdfjs-legacy/cmaps/HKm471-B5-V.bcmap": "598758151",
"static/pdfjs-legacy/cmaps/HKscs-B5-H.bcmap": "1835313510",
"static/pdfjs-legacy/cmaps/HKscs-B5-V.bcmap": "3858177964",
"static/pdfjs-legacy/cmaps/Hankaku.bcmap": "3480962665",
"static/pdfjs-legacy/cmaps/Hiragana.bcmap": "424061514",
"static/pdfjs-legacy/cmaps/KSC-EUC-H.bcmap": "3541080431",
"static/pdfjs-legacy/cmaps/KSC-EUC-V.bcmap": "360170940",
"static/pdfjs-legacy/cmaps/KSC-H.bcmap": "3828116236",
"static/pdfjs-legacy/cmaps/KSC-Johab-H.bcmap": "4048702457",
"static/pdfjs-legacy/cmaps/KSC-Johab-V.bcmap": "3351989078",
"static/pdfjs-legacy/cmaps/KSC-V.bcmap": "1132751989",
"static/pdfjs-legacy/cmaps/KSCms-UHC-H.bcmap": "1369510166",
"static/pdfjs-legacy/cmaps/KSCms-UHC-HW-H.bcmap": "191114971",
"static/pdfjs-legacy/cmaps/KSCms-UHC-HW-V.bcmap": "2524719784",
"static/pdfjs-legacy/cmaps/KSCms-UHC-V.bcmap": "3681493563",
"static/pdfjs-legacy/cmaps/KSCpc-EUC-H.bcmap": "3174537837",
"static/pdfjs-legacy/cmaps/KSCpc-EUC-V.bcmap": "1931198587",
"static/pdfjs-legacy/cmaps/Katakana.bcmap": "4057367482",
"static/pdfjs-legacy/cmaps/LICENSE": "3373243097",
"static/pdfjs-legacy/cmaps/NWP-H.bcmap": "3764264138",
"static/pdfjs-legacy/cmaps/NWP-V.bcmap": "2185402986",
"static/pdfjs-legacy/cmaps/RKSJ-H.bcmap": "1094971537",
"static/pdfjs-legacy/cmaps/RKSJ-V.bcmap": "2939374609",
"static/pdfjs-legacy/cmaps/Roman.bcmap": "3459026600",
"static/pdfjs-legacy/cmaps/UniCNS-UCS2-H.bcmap": "3919386729",
"static/pdfjs-legacy/cmaps/UniCNS-UCS2-V.bcmap": "4163319147",
"static/pdfjs-legacy/cmaps/UniCNS-UTF16-H.bcmap": "457950540",
"static/pdfjs-legacy/cmaps/UniCNS-UTF16-V.bcmap": "3955847799",
"static/pdfjs-legacy/cmaps/UniCNS-UTF32-H.bcmap": "3664760320",
"static/pdfjs-legacy/cmaps/UniCNS-UTF32-V.bcmap": "3136766662",
"static/pdfjs-legacy/cmaps/UniCNS-UTF8-H.bcmap": "2421485088",
"static/pdfjs-legacy/cmaps/UniCNS-UTF8-V.bcmap": "3694982117",
"static/pdfjs-legacy/cmaps/UniGB-UCS2-H.bcmap": "1494243687",
"static/pdfjs-legacy/cmaps/UniGB-UCS2-V.bcmap": "1518297593",
"static/pdfjs-legacy/cmaps/UniGB-UTF16-H.bcmap": "2858681174",
"static/pdfjs-legacy/cmaps/UniGB-UTF16-V.bcmap": "1485054769",
"static/pdfjs-legacy/cmaps/UniGB-UTF32-H.bcmap": "3102168113",
"static/pdfjs-legacy/cmaps/UniGB-UTF32-V.bcmap": "1287338444",
"static/pdfjs-legacy/cmaps/UniGB-UTF8-H.bcmap": "1330667590",
"static/pdfjs-legacy/cmaps/UniGB-UTF8-V.bcmap": "1105219764",
"static/pdfjs-legacy/cmaps/UniJIS-UCS2-H.bcmap": "4145130767",
"static/pdfjs-legacy/cmaps/UniJIS-UCS2-HW-H.bcmap": "1603386144",
"static/pdfjs-legacy/cmaps/UniJIS-UCS2-HW-V.bcmap": "629109090",
"static/pdfjs-legacy/cmaps/UniJIS-UCS2-V.bcmap": "3444593289",
"static/pdfjs-legacy/cmaps/UniJIS-UTF16-H.bcmap": "3064424947",
"static/pdfjs-legacy/cmaps/UniJIS-UTF16-V.bcmap": "3625850940",
"static/pdfjs-legacy/cmaps/UniJIS-UTF32-H.bcmap": "1624227467",
"static/pdfjs-legacy/cmaps/UniJIS-UTF32-V.bcmap": "3812610791",
"static/pdfjs-legacy/cmaps/UniJIS-UTF8-H.bcmap": "3166338980",
"static/pdfjs-legacy/cmaps/UniJIS-UTF8-V.bcmap": "2110165130",
"static/pdfjs-legacy/cmaps/UniJIS2004-UTF16-H.bcmap": "1649651136",
"static/pdfjs-legacy/cmaps/UniJIS2004-UTF16-V.bcmap": "1917186042",
"static/pdfjs-legacy/cmaps/UniJIS2004-UTF32-H.bcmap": "3843155258",
"static/pdfjs-legacy/cmaps/UniJIS2004-UTF32-V.bcmap": "4051860030",
"static/pdfjs-legacy/cmaps/UniJIS2004-UTF8-H.bcmap": "2598682363",
"static/pdfjs-legacy/cmaps/UniJIS2004-UTF8-V.bcmap": "3200763449",
"static/pdfjs-legacy/cmaps/UniJISPro-UCS2-HW-V.bcmap": "2520410150",
"static/pdfjs-legacy/cmaps/UniJISPro-UCS2-V.bcmap": "1336410077",
"static/pdfjs-legacy/cmaps/UniJISPro-UTF8-V.bcmap": "142888237",
"static/pdfjs-legacy/cmaps/UniJISX0213-UTF32-H.bcmap": "844139573",
"static/pdfjs-legacy/cmaps/UniJISX0213-UTF32-V.bcmap": "1264744789",
"static/pdfjs-legacy/cmaps/UniJISX02132004-UTF32-H.bcmap": "2355793543",
"static/pdfjs-legacy/cmaps/UniJISX02132004-UTF32-V.bcmap": "1871184730",
"static/pdfjs-legacy/cmaps/UniKS-UCS2-H.bcmap": "2453854452",
"static/pdfjs-legacy/cmaps/UniKS-UCS2-V.bcmap": "3333973478",
"static/pdfjs-legacy/cmaps/UniKS-UTF16-H.bcmap": "4088092562",
"static/pdfjs-legacy/cmaps/UniKS-UTF16-V.bcmap": "1023049006",
"static/pdfjs-legacy/cmaps/UniKS-UTF32-H.bcmap": "2197348013",
"static/pdfjs-legacy/cmaps/UniKS-UTF32-V.bcmap": "3510175806",
"static/pdfjs-legacy/cmaps/UniKS-UTF8-H.bcmap": "1626947074",
"static/pdfjs-legacy/cmaps/UniKS-UTF8-V.bcmap": "1120721597",
"static/pdfjs-legacy/cmaps/V.bcmap": "1698015673",
"static/pdfjs-legacy/cmaps/WP-Symbol.bcmap": "3318423969",
"static/pdfjs-legacy/css/debugger.css": "752924108",
"static/pdfjs-legacy/css/viewer-redact.css": "1979433975",
"static/pdfjs-legacy/css/viewer.css": "1972608301",
"static/pdfjs-legacy/example/Welcome.pdf": "2318235964",
"static/pdfjs-legacy/example/Welcome_old.pdf": "3548702533",
"static/pdfjs-legacy/images/altText_add.svg": "4090768085",
"static/pdfjs-legacy/images/altText_done.svg": "1235065751",
"static/pdfjs-legacy/images/annotation-check.svg": "2561831381",
"static/pdfjs-legacy/images/annotation-comment.svg": "3324793215",
"static/pdfjs-legacy/images/annotation-help.svg": "3356171899",
"static/pdfjs-legacy/images/annotation-insert.svg": "2097228350",
"static/pdfjs-legacy/images/annotation-key.svg": "566996641",
"static/pdfjs-legacy/images/annotation-newparagraph.svg": "2490327670",
"static/pdfjs-legacy/images/annotation-noicon.svg": "421416337",
"static/pdfjs-legacy/images/annotation-note.svg": "3067462965",
"static/pdfjs-legacy/images/annotation-paperclip.svg": "305707414",
"static/pdfjs-legacy/images/annotation-paragraph.svg": "2828828407",
"static/pdfjs-legacy/images/annotation-pushpin.svg": "2415319833",
"static/pdfjs-legacy/images/cursor-editorFreeHighlight.svg": "705554546",
"static/pdfjs-legacy/images/cursor-editorFreeText.svg": "3497424456",
"static/pdfjs-legacy/images/cursor-editorInk.svg": "2628061285",
"static/pdfjs-legacy/images/cursor-editorTextHighlight.svg": "2003609743",
"static/pdfjs-legacy/images/editor-toolbar-delete.svg": "1611790845",
"static/pdfjs-legacy/images/findbarButton-next.svg": "1870266707",
"static/pdfjs-legacy/images/findbarButton-previous.svg": "883193681",
"static/pdfjs-legacy/images/gv-toolbarButton-download.svg": "2424302361",
"static/pdfjs-legacy/images/loading-icon.gif": "1000971472",
"static/pdfjs-legacy/images/loading.svg": "2326450055",
"static/pdfjs-legacy/images/secondaryToolbarButton-documentProperties.svg": "3287468884",
"static/pdfjs-legacy/images/secondaryToolbarButton-firstPage.svg": "2706581541",
"static/pdfjs-legacy/images/secondaryToolbarButton-handTool.svg": "2174815805",
"static/pdfjs-legacy/images/secondaryToolbarButton-lastPage.svg": "3857947100",
"static/pdfjs-legacy/images/secondaryToolbarButton-rotateCcw.svg": "1309912847",
"static/pdfjs-legacy/images/secondaryToolbarButton-rotateCw.svg": "1407930709",
"static/pdfjs-legacy/images/secondaryToolbarButton-scrollHorizontal.svg": "2492411596",
"static/pdfjs-legacy/images/secondaryToolbarButton-scrollPage.svg": "759071723",
"static/pdfjs-legacy/images/secondaryToolbarButton-scrollVertical.svg": "3891705721",
"static/pdfjs-legacy/images/secondaryToolbarButton-scrollWrapped.svg": "1018662479",
"static/pdfjs-legacy/images/secondaryToolbarButton-selectTool.svg": "902953521",
"static/pdfjs-legacy/images/secondaryToolbarButton-spreadEven.svg": "1051626498",
"static/pdfjs-legacy/images/secondaryToolbarButton-spreadNone.svg": "982411527",
"static/pdfjs-legacy/images/secondaryToolbarButton-spreadOdd.svg": "222673772",
"static/pdfjs-legacy/images/toolbarButton-bookmark.svg": "3980524312",
"static/pdfjs-legacy/images/toolbarButton-currentOutlineItem.svg": "3935300727",
"static/pdfjs-legacy/images/toolbarButton-download.svg": "2492023525",
"static/pdfjs-legacy/images/toolbarButton-editorFreeText.svg": "3807710736",
"static/pdfjs-legacy/images/toolbarButton-editorHighlight.svg": "1500761392",
"static/pdfjs-legacy/images/toolbarButton-editorInk.svg": "2128566939",
"static/pdfjs-legacy/images/toolbarButton-editorStamp.svg": "2729275912",
"static/pdfjs-legacy/images/toolbarButton-home.svg": "3284387620",
"static/pdfjs-legacy/images/toolbarButton-menuArrow.svg": "103183755",
"static/pdfjs-legacy/images/toolbarButton-openFile.svg": "755195018",
"static/pdfjs-legacy/images/toolbarButton-pageDown.svg": "3798815865",
"static/pdfjs-legacy/images/toolbarButton-pageUp.svg": "1634062528",
"static/pdfjs-legacy/images/toolbarButton-presentationMode.svg": "880098234",
"static/pdfjs-legacy/images/toolbarButton-print.svg": "2989631602",
"static/pdfjs-legacy/images/toolbarButton-search.svg": "1699484533",
"static/pdfjs-legacy/images/toolbarButton-secondaryToolbarToggle.svg": "2129797277",
"static/pdfjs-legacy/images/toolbarButton-sidebarToggle.svg": "957795621",
"static/pdfjs-legacy/images/toolbarButton-viewAttachments.svg": "2187697129",
"static/pdfjs-legacy/images/toolbarButton-viewLayers.svg": "1590526272",
"static/pdfjs-legacy/images/toolbarButton-viewOutline.svg": "3731686923",
"static/pdfjs-legacy/images/toolbarButton-viewThumbnail.svg": "2382514839",
"static/pdfjs-legacy/images/toolbarButton-zoomIn.svg": "2469054350",
"static/pdfjs-legacy/images/toolbarButton-zoomOut.svg": "1174739568",
"static/pdfjs-legacy/images/treeitem-collapsed.svg": "2485814586",
"static/pdfjs-legacy/images/treeitem-expanded.svg": "3049880413",
"static/pdfjs-legacy/js/viewer.mjs": "603466221",
"static/pdfjs-legacy/js/viewer.mjs.map": "2086745145",
"static/pdfjs-legacy/locale/ach/viewer.ftl": "1980908712",
"static/pdfjs-legacy/locale/af/viewer.ftl": "224272564",
"static/pdfjs-legacy/locale/an/viewer.ftl": "1238479368",
"static/pdfjs-legacy/locale/ar/viewer.ftl": "1379793476",
"static/pdfjs-legacy/locale/ast/viewer.ftl": "1330248763",
"static/pdfjs-legacy/locale/az/viewer.ftl": "3592696552",
"static/pdfjs-legacy/locale/be/viewer.ftl": "2035404997",
"static/pdfjs-legacy/locale/bg/viewer.ftl": "2053195741",
"static/pdfjs-legacy/locale/bn/viewer.ftl": "3460960323",
"static/pdfjs-legacy/locale/bo/viewer.ftl": "1138897229",
"static/pdfjs-legacy/locale/br/viewer.ftl": "142293956",
"static/pdfjs-legacy/locale/brx/viewer.ftl": "3933240419",
"static/pdfjs-legacy/locale/bs/viewer.ftl": "257125530",
"static/pdfjs-legacy/locale/ca/viewer.ftl": "1069759629",
"static/pdfjs-legacy/locale/cak/viewer.ftl": "345005238",
"static/pdfjs-legacy/locale/ckb/viewer.ftl": "669722694",
"static/pdfjs-legacy/locale/cs/viewer.ftl": "3983468472",
"static/pdfjs-legacy/locale/cy/viewer.ftl": "1000740246",
"static/pdfjs-legacy/locale/da/viewer.ftl": "1596550577",
"static/pdfjs-legacy/locale/de/viewer.ftl": "2538100689",
"static/pdfjs-legacy/locale/dsb/viewer.ftl": "1017194879",
"static/pdfjs-legacy/locale/el/viewer.ftl": "738875555",
"static/pdfjs-legacy/locale/en-CA/viewer.ftl": "1486957518",
"static/pdfjs-legacy/locale/en-GB/viewer.ftl": "2305506570",
"static/pdfjs-legacy/locale/en-US/viewer.ftl": "115050625",
"static/pdfjs-legacy/locale/eo/viewer.ftl": "494491650",
"static/pdfjs-legacy/locale/es-AR/viewer.ftl": "3830588040",
"static/pdfjs-legacy/locale/es-CL/viewer.ftl": "1684829806",
"static/pdfjs-legacy/locale/es-ES/viewer.ftl": "3872677738",
"static/pdfjs-legacy/locale/es-MX/viewer.ftl": "872182372",
"static/pdfjs-legacy/locale/et/viewer.ftl": "3646382249",
"static/pdfjs-legacy/locale/eu/viewer.ftl": "2819828461",
"static/pdfjs-legacy/locale/fa/viewer.ftl": "1927477186",
"static/pdfjs-legacy/locale/ff/viewer.ftl": "1446757509",
"static/pdfjs-legacy/locale/fi/viewer.ftl": "3594326705",
"static/pdfjs-legacy/locale/fr/viewer.ftl": "4117988381",
"static/pdfjs-legacy/locale/fur/viewer.ftl": "2560761832",
"static/pdfjs-legacy/locale/fy-NL/viewer.ftl": "232149105",
"static/pdfjs-legacy/locale/ga-IE/viewer.ftl": "3995499916",
"static/pdfjs-legacy/locale/gd/viewer.ftl": "3200290539",
"static/pdfjs-legacy/locale/gl/viewer.ftl": "252739953",
"static/pdfjs-legacy/locale/gn/viewer.ftl": "806947646",
"static/pdfjs-legacy/locale/gu-IN/viewer.ftl": "809941552",
"static/pdfjs-legacy/locale/he/viewer.ftl": "1491036152",
"static/pdfjs-legacy/locale/hi-IN/viewer.ftl": "2655282221",
"static/pdfjs-legacy/locale/hr/viewer.ftl": "2727165442",
"static/pdfjs-legacy/locale/hsb/viewer.ftl": "1498421291",
"static/pdfjs-legacy/locale/hu/viewer.ftl": "2196255296",
"static/pdfjs-legacy/locale/hy-AM/viewer.ftl": "3294889129",
"static/pdfjs-legacy/locale/hye/viewer.ftl": "3094737368",
"static/pdfjs-legacy/locale/ia/viewer.ftl": "481452996",
"static/pdfjs-legacy/locale/id/viewer.ftl": "2067658098",
"static/pdfjs-legacy/locale/is/viewer.ftl": "847509193",
"static/pdfjs-legacy/locale/it/viewer.ftl": "2842620006",
"static/pdfjs-legacy/locale/ja/viewer.ftl": "417613875",
"static/pdfjs-legacy/locale/ka/viewer.ftl": "1238276525",
"static/pdfjs-legacy/locale/kab/viewer.ftl": "1778067144",
"static/pdfjs-legacy/locale/kk/viewer.ftl": "2928003337",
"static/pdfjs-legacy/locale/km/viewer.ftl": "32743210",
"static/pdfjs-legacy/locale/kn/viewer.ftl": "2170413691",
"static/pdfjs-legacy/locale/ko/viewer.ftl": "16750009",
"static/pdfjs-legacy/locale/lij/viewer.ftl": "478888829",
"static/pdfjs-legacy/locale/lo/viewer.ftl": "337442244",
"static/pdfjs-legacy/locale/locale.json": "3100509089",
"static/pdfjs-legacy/locale/lt/viewer.ftl": "909047758",
"static/pdfjs-legacy/locale/ltg/viewer.ftl": "1027634928",
"static/pdfjs-legacy/locale/lv/viewer.ftl": "1455591509",
"static/pdfjs-legacy/locale/meh/viewer.ftl": "2945173537",
"static/pdfjs-legacy/locale/mk/viewer.ftl": "961140182",
"static/pdfjs-legacy/locale/mr/viewer.ftl": "1223743170",
"static/pdfjs-legacy/locale/ms/viewer.ftl": "211776931",
"static/pdfjs-legacy/locale/my/viewer.ftl": "3044479448",
"static/pdfjs-legacy/locale/nb-NO/viewer.ftl": "727660473",
"static/pdfjs-legacy/locale/ne-NP/viewer.ftl": "2159310918",
"static/pdfjs-legacy/locale/nl/viewer.ftl": "2127489456",
"static/pdfjs-legacy/locale/nn-NO/viewer.ftl": "3642573142",
"static/pdfjs-legacy/locale/oc/viewer.ftl": "2186123157",
"static/pdfjs-legacy/locale/pa-IN/viewer.ftl": "414616297",
"static/pdfjs-legacy/locale/pl/viewer.ftl": "1442861848",
"static/pdfjs-legacy/locale/pt-BR/viewer.ftl": "436219389",
"static/pdfjs-legacy/locale/pt-PT/viewer.ftl": "2300390749",
"static/pdfjs-legacy/locale/rm/viewer.ftl": "3417357752",
"static/pdfjs-legacy/locale/ro/viewer.ftl": "1951961738",
"static/pdfjs-legacy/locale/ru/viewer.ftl": "1830204964",
"static/pdfjs-legacy/locale/sat/viewer.ftl": "3899012888",
"static/pdfjs-legacy/locale/sc/viewer.ftl": "2158618915",
"static/pdfjs-legacy/locale/scn/viewer.ftl": "3467702403",
"static/pdfjs-legacy/locale/sco/viewer.ftl": "3513139447",
"static/pdfjs-legacy/locale/si/viewer.ftl": "1663749559",
"static/pdfjs-legacy/locale/sk/viewer.ftl": "3352097995",
"static/pdfjs-legacy/locale/skr/viewer.ftl": "2401135746",
"static/pdfjs-legacy/locale/sl/viewer.ftl": "3188432653",
"static/pdfjs-legacy/locale/son/viewer.ftl": "3792123385",
"static/pdfjs-legacy/locale/sq/viewer.ftl": "438991571",
"static/pdfjs-legacy/locale/sr/viewer.ftl": "3412560345",
"static/pdfjs-legacy/locale/sv-SE/viewer.ftl": "2656080831",
"static/pdfjs-legacy/locale/szl/viewer.ftl": "168181399",
"static/pdfjs-legacy/locale/ta/viewer.ftl": "3344521948",
"static/pdfjs-legacy/locale/te/viewer.ftl": "1665716366",
"static/pdfjs-legacy/locale/tg/viewer.ftl": "1103007121",
"static/pdfjs-legacy/locale/th/viewer.ftl": "2493816278",
"static/pdfjs-legacy/locale/tl/viewer.ftl": "584957769",
"static/pdfjs-legacy/locale/tr/viewer.ftl": "924544936",
"static/pdfjs-legacy/locale/trs/viewer.ftl": "1378118586",
"static/pdfjs-legacy/locale/uk/viewer.ftl": "4097097469",
"static/pdfjs-legacy/locale/ur/viewer.ftl": "769608800",
"static/pdfjs-legacy/locale/uz/viewer.ftl": "4171128427",
"static/pdfjs-legacy/locale/vi/viewer.ftl": "2946740131",
"static/pdfjs-legacy/locale/wo/viewer.ftl": "3876100634",
"static/pdfjs-legacy/locale/xh/viewer.ftl": "932342001",
"static/pdfjs-legacy/locale/zh-CN/viewer.ftl": "2154527140",
"static/pdfjs-legacy/locale/zh-TW/viewer.ftl": "103465971",
"static/pdfjs-legacy/pdf.mjs": "3043219252",
"static/pdfjs-legacy/pdf.mjs.map": "3472639744",
"static/pdfjs-legacy/pdf.sandbox.mjs": "4175817824",
"static/pdfjs-legacy/pdf.sandbox.mjs.map": "2142610412",
"static/pdfjs-legacy/pdf.worker.entry.js": "1110314212",
"static/pdfjs-legacy/pdf.worker.mjs": "1102065083",
"static/pdfjs-legacy/pdf.worker.mjs.map": "1775521231",
"static/pdfjs-legacy/standard_fonts/FoxitDingbats.pfb": "3096052441",
"static/pdfjs-legacy/standard_fonts/FoxitFixed.pfb": "3344911508",
"static/pdfjs-legacy/standard_fonts/FoxitFixedBold.pfb": "668995403",
"static/pdfjs-legacy/standard_fonts/FoxitFixedBoldItalic.pfb": "2793650527",
"static/pdfjs-legacy/standard_fonts/FoxitFixedItalic.pfb": "2555951209",
"static/pdfjs-legacy/standard_fonts/FoxitSerif.pfb": "4134707818",
"static/pdfjs-legacy/standard_fonts/FoxitSerifBold.pfb": "2308674889",
"static/pdfjs-legacy/standard_fonts/FoxitSerifBoldItalic.pfb": "3879789538",
"static/pdfjs-legacy/standard_fonts/FoxitSerifItalic.pfb": "4139115954",
"static/pdfjs-legacy/standard_fonts/FoxitSymbol.pfb": "1735985075",
"static/pdfjs-legacy/standard_fonts/LICENSE_FOXIT": "3796230208",
"static/pdfjs-legacy/standard_fonts/LICENSE_LIBERATION": "1495711592",
"static/pdfjs-legacy/standard_fonts/LiberationSans-Bold.ttf": "2322388090",
"static/pdfjs-legacy/standard_fonts/LiberationSans-BoldItalic.ttf": "3556386482",
"static/pdfjs-legacy/standard_fonts/LiberationSans-Italic.ttf": "2294934833",
"static/pdfjs-legacy/standard_fonts/LiberationSans-Regular.ttf": "606071962",
"static/rainbow.svg": "572998223",
"static/safari-pinned-tab.svg": "1486555599",
"static/site.webmanifest": "318876612",
"static/sun.svg": "2148897294",
"templates/account.html": "4003025365",
"templates/adminSettings.html": "4111706491",
"templates/auto-split-pdf.html": "3079958784",
"templates/change-creds.html": "2526450486",
"templates/convert/file-to-pdf.html": "2380970147",
"templates/convert/html-to-pdf.html": "2763046575",
"templates/convert/img-to-pdf.html": "1084147181",
"templates/convert/markdown-to-pdf.html": "3819494041",
"templates/convert/pdf-to-csv.html": "604801628",
"templates/convert/pdf-to-html.html": "641461184",
"templates/convert/pdf-to-img.html": "2912971423",
"templates/convert/pdf-to-markdown.html": "644840741",
"templates/convert/pdf-to-pdfa.html": "1606644037",
"templates/convert/pdf-to-presentation.html": "1579697320",
"templates/convert/pdf-to-text.html": "1043880059",
"templates/convert/pdf-to-word.html": "4214831863",
"templates/convert/pdf-to-xml.html": "1427461833",
"templates/convert/url-to-pdf.html": "1833689377",
"templates/crop.html": "2905959970",
"templates/database.html": "3855518198",
"templates/error.html": "4206899739",
"templates/extract-page.html": "4089958808",
"templates/fragments/card.html": "16440436",
"templates/fragments/common.html": "4100425091",
"templates/fragments/errorBanner.html": "783151307",
"templates/fragments/errorBannerPerPage.html": "2124374267",
"templates/fragments/featureGroupHeader.html": "1905082759",
"templates/fragments/featureGroupHeaderLegacy.html": "1350466212",
"templates/fragments/footer.html": "2635595918",
"templates/fragments/languageEntry.html": "2731331770",
"templates/fragments/languages.html": "1555261172",
"templates/fragments/multi-toolAdvert.html": "2570656025",
"templates/fragments/navElements.html": "214632829",
"templates/fragments/navbar.html": "2333326363",
"templates/fragments/navbarEntry.html": "1872372661",
"templates/fragments/navbarEntryCustom.html": "1997337405",
"templates/home-legacy.html": "927084907",
"templates/home.html": "1007490496",
"templates/licenses.html": "1886130118",
"templates/login.html": "3682550013",
"templates/merge-pdfs.html": "3358182876",
"templates/misc/add-image.html": "660370195",
"templates/misc/add-page-numbers.html": "290821602",
"templates/misc/adjust-contrast.html": "997484277",
"templates/misc/auto-crop.html": "651944045",
"templates/misc/auto-rename.html": "1542317390",
"templates/misc/change-metadata.html": "2636623501",
"templates/misc/compare.html": "3383752072",
"templates/misc/compress-pdf.html": "3872589071",
"templates/misc/extract-image-scans.html": "2342613358",
"templates/misc/extract-images.html": "3622269126",
"templates/misc/fake-scan.html": "3918475570",
"templates/misc/flatten.html": "4094903108",
"templates/misc/ocr-pdf.html": "655752125",
"templates/misc/print-file.html": "548381403",
"templates/misc/remove-annotations.html": "2717474853",
"templates/misc/remove-blanks.html": "2984174606",
"templates/misc/repair.html": "3971203939",
"templates/misc/replace-color.html": "2888488818",
"templates/misc/show-javascript.html": "3378887859",
"templates/misc/stamp.html": "2008662282",
"templates/multi-page-layout.html": "3667835344",
"templates/multi-tool.html": "925307352",
"templates/overlay-pdf.html": "2702819078",
"templates/pdf-organizer.html": "4139798132",
"templates/pdf-to-single-page.html": "935831522",
"templates/pipeline.html": "3151033492",
"templates/releases.html": "2785982435",
"templates/remove-image-pdf.html": "3581478289",
"templates/remove-pages.html": "3566590993",
"templates/rotate-pdf.html": "2045148221",
"templates/scale-pages.html": "3102920063",
"templates/security/add-password.html": "806079580",
"templates/security/add-watermark.html": "733202811",
"templates/security/auto-redact.html": "3317004060",
"templates/security/cert-sign.html": "495997371",
"templates/security/change-permissions.html": "3482497147",
"templates/security/get-info-on-pdf.html": "2632596742",
"templates/security/redact.html": "2984187434",
"templates/security/remove-cert-sign.html": "3478214344",
"templates/security/remove-password.html": "387074786",
"templates/security/remove-watermark.html": "1082337683",
"templates/security/sanitize-pdf.html": "1534479025",
"templates/security/validate-signature.html": "3223667314",
"templates/sign.html": "3461243374",
"templates/split-by-size-or-count.html": "3940269005",
"templates/split-pdf-by-chapters.html": "75724057",
"templates/split-pdf-by-sections.html": "3958812972",
"templates/split-pdfs.html": "3812681720",
"templates/usage.html": "3093550255",
"templates/view-pdf.html": "4035238680"
}
-21
View File
@@ -1,21 +0,0 @@
<!DOCTYPE html>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title='<3')}"></th:block>
</head>
<body>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card"></div>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>
-5
View File
@@ -1,7 +1,6 @@
<!DOCTYPE html>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}"
xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title='')}"></th:block>
</head>
@@ -10,9 +9,6 @@
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br class="d-md-none">
<!-- Features -->
<script th:src="@{'/js/homecard.js'}"></script>
@@ -20,7 +16,6 @@
width: 100%;
display: flex;
flex-direction: column;">
<div>
<br>
<div style="justify-content: center; display: flex;">
+22 -18
View File
@@ -6,12 +6,10 @@
# ___) || | | || _ <| |___ | || |\ | |_| |_____| __/| |_| | _| #
# |____/ |_| |___|_| \_\_____|___|_| \_|\____| |_| |____/|_| #
# #
# Custom setting.yml file with all endpoints disabled to only be used for testing purposes #
# Do not comment out any entry, it will be removed on next startup #
# If you want to override with environment parameter follow parameter naming SECURITY_INITIALLOGIN_USERNAME #
#############################################################################################################
security:
enableLogin: false # set to 'true' to enable login
csrfDisabled: false # set to 'true' to disable CSRF protection (not recommended for production)
@@ -62,15 +60,21 @@ security:
privateKey: classpath:saml-private-key.key # Your private key. Generated from your keypair
spCert: classpath:saml-public-cert.crt # Your signing certificate. Generated from your keypair
enterpriseEdition:
enabled: false # set to 'true' to enable enterprise edition
premium:
key: 00000000-0000-0000-0000-000000000000
SSOAutoLogin: false # Enable to auto login to first provided SSO
CustomMetadata:
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
author: username # supports text such as 'John Doe' or types such as username to autopopulate with user's username
creator: Stirling-PDF # supports text such as 'Company-PDF'
producer: Stirling-PDF # supports text such as 'Company-PDF'
enabled: false # Enable license key checks for pro/enterprise features
proFeatures:
SSOAutoLogin: false
CustomMetadata:
autoUpdateMetadata: false
author: username
creator: Stirling-PDF
producer: Stirling-PDF
googleDrive:
enabled: false
clientId: ''
apiKey: ''
appId: ''
legal:
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
@@ -88,6 +92,7 @@ system:
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template HTML files
tessdataDir: /usr/share/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored.
enableAnalytics: true # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
enableUrlToPDF: false # Set to 'true' to enable URL to PDF, INTERNAL ONLY, known security issues, should not be used externally
disableSanitize: false # set to true to disable Sanitize HTML; (can lead to injections in HTML)
datasource:
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
@@ -100,13 +105,12 @@ system:
name: postgres # set the name of your database. Should match the name of the database you create
customPaths:
pipeline:
watchedFoldersDir: "" #Defaults to /pipeline/watchedFolders
finishedFoldersDir: "" #Defaults to /pipeline/finishedFolders
watchedFoldersDir: '' #Defaults to /pipeline/watchedFolders
finishedFoldersDir: '' #Defaults to /pipeline/finishedFolders
operations:
weasyprint: "" #Defaults to /opt/venv/bin/weasyprint
unoconvert: "" #Defaults to /opt/venv/bin/unoconvert
weasyprint: '' #Defaults to /opt/venv/bin/weasyprint
unoconvert: '' #Defaults to /opt/venv/bin/unoconvert
fileUploadLimit: '' # Defaults to "". No limit when string is empty. Set a number, between 0 and 999, followed by one of the following strings to set a limit. "KB", "MB", "GB".
ui:
appName: '' # application's visible name
@@ -114,7 +118,7 @@ ui:
appNameNavbar: '' # name displayed on the navigation bar
languages: [] # If empty, all languages are enabled. To display only German and Polish ["de_DE", "pl_PL"]. British English is always enabled.
endpoints: # All the possible endpoints are disabled
endpoints:
toRemove: [crop, merge-pdfs, multi-page-layout, overlay-pdfs, pdf-to-single-page, rearrange-pages, remove-image-pdf, remove-pages, rotate-pdf, scale-pages, split-by-size-or-count, split-pages, split-pdf-by-chapters, split-pdf-by-sections, add-password, add-watermark, auto-redact, cert-sign, get-info-on-pdf, redact, remove-cert-sign, remove-password, sanitize-pdf, validate-signature, file-to-pdf, html-to-pdf, img-to-pdf, markdown-to-pdf, pdf-to-csv, pdf-to-html, pdf-to-img, pdf-to-markdown, pdf-to-pdfa, pdf-to-presentation, pdf-to-text, pdf-to-word, pdf-to-xml, url-to-pdf, add-image, add-page-numbers, add-stamp, auto-rename, auto-split-pdf, compress-pdf, decompress-pdf, extract-image-scans, extract-images, flatten, ocr-pdf, remove-blanks, repair, replace-invert-pdf, show-javascript, update-metadata, filter-contains-image, filter-contains-text, filter-file-size, filter-page-count, filter-page-rotation, filter-page-size] # list endpoints to disable (e.g. ['img-to-pdf', 'remove-pages'])
groupsToRemove: [] # list groups to disable (e.g. ['LibreOffice'])
@@ -125,7 +129,7 @@ metrics:
AutomaticallyGenerated:
key: cbb81c0f-50b1-450c-a2b5-89ae527776eb
UUID: 10dd4fba-01fa-4717-9b78-3dc4f54e398a
appVersion: 0.44.3
appVersion: 0.45.6
processExecutor:
sessionLimit: # Process executor instances limits
+1
View File
@@ -51,3 +51,4 @@
/swagger-ui/index.html
/licenses
/releases
/v1/api-docs
+2 -1
View File
@@ -62,4 +62,5 @@
/stamp
/validate-signature
/view-pdf
/swagger-ui/index.html
/swagger-ui/index.html
/v1/api-docs