From 3fd039864831397aac214c9036267c60218b2a45 Mon Sep 17 00:00:00 2001 From: Ludy Date: Tue, 30 Dec 2025 19:56:09 +0100 Subject: [PATCH] chore(ci): streamline GitHub workflows, labels, and license automation for main (#5356) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description of Changes This pull request makes several updates to the repository’s CI/CD configuration, focusing on improving workflow automation, updating Java versions, enhancing labeling and file ownership, and cleaning up unused files. The most significant changes involve migrating workflows and labels to support a new `V3` branch, updating build environments to use JDK 21, and expanding automated dependency update coverage. **Key changes include:** ### CI/CD Workflow Updates * Updated all GitHub Actions workflows (`build.yml`, `PR-Demo-Comment-with-react.yml`, etc.) to use JDK 21 instead of JDK 17 for Java builds, ensuring compatibility with newer Java features and dependencies. [[1]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L120-R125) [[2]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721R180-R187) [[3]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L226-R232) [[4]](diffhunk://#diff-8d23782ae5caff72d55828bb25814854f5f2523f299d7dbcda4a3537dd84c5c3L154-R154) [[5]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L288-L298) * Removed the now-unused `codeql.yml-disabled` file, cleaning up deprecated static analysis configuration. * Added a dedicated `frontend-validation` job in `build.yml` that only runs when frontend files change, improving CI efficiency. * Minor workflow improvements: consistent quoting in config paths, improved cache settings, and small cleanups in deploy scripts. [[1]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L150-R152) [[2]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L244-R247) [[3]](diffhunk://#diff-7cdd3ccec44c8ba176bdc3b9ef54c3f56aa210a1a4e2bb5f79d87b1e50314a18L29-R29) [[4]](diffhunk://#diff-f8b6ec3c0af9cd2d8dffef6f3def2be6357fe596a606850ca7f5d799e1349069L87) [[5]](diffhunk://#diff-f8b6ec3c0af9cd2d8dffef6f3def2be6357fe596a606850ca7f5d799e1349069L120-L127) [[6]](diffhunk://#diff-f8b6ec3c0af9cd2d8dffef6f3def2be6357fe596a606850ca7f5d799e1349069L189) [[7]](diffhunk://#diff-26fc40a450703e6602af586a24594196fb10e132de14a9a488ae64ee8cc51166L99) [[8]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L30-R39) [[9]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721L69-R75) [[10]](diffhunk://#diff-5c3fa597431eda03ac3339ae6bf7f05e1a50d6fc7333679ec38e21b337cb6721R93) ### Branch and Label Management * Migrated auto-labeler and build workflows to track the `V3` branch instead of `V2`, and updated labels and labeler config to use `v3` instead of `v2`. [[1]](diffhunk://#diff-cfe84f4bb9657c721ff741644ee0bce45aa81aaef9dea1ea8741c946984e9722L7-R7) [[2]](diffhunk://#diff-d3d79c492fbafebc87fbb739c553afea093a79344ff78b88fe785ac3ca7e7b3dL49-R75) [[3]](diffhunk://#diff-080b7ef0dc11b28f262ea02985043c6229e353ecfdd5920b4d3b19f369f85dc6R87-R89) * Added new labels for `v3`, `Rust`, `Tauri`, and `license-review-required` to improve PR categorization and review processes. ### Dependency Automation * Expanded `dependabot.yml` to update Gradle dependencies in all relevant subdirectories (`/`, `/app/common`, `/app/core`, `/app/proprietary`) and ensured all ecosystems use the `rebase-strategy: auto` setting for more reliable PR updates. ### File Ownership and Labeling * Enhanced `.github/config/.files.yaml` to include new scripts and frontend-related files under the correct project and frontend categories, and introduced license file groups for both frontend and backend. [[1]](diffhunk://#diff-16e8af5ab290e6fdcf843429e4970b7dee6721897ad02c5291f259f47e0978deL5-R7) [[2]](diffhunk://#diff-16e8af5ab290e6fdcf843429e4970b7dee6721897ad02c5291f259f47e0978deR34-R60) * Improved labeler configuration to better match new frontend and translation file patterns, and introduced a new label group for Tauri-related files. --- These changes collectively modernize the repository’s automation, streamline maintenance, and prepare the project for ongoing work on the `V3` branch. --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### Translations (if applicable) - [ ] I ran [`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --- .github/config/.files.yaml | 26 +- .github/dependabot.yml | 16 +- .github/labeler-config-srvaroa.yml | 20 +- .github/labels.yml | 14 + .github/workflows/PR-Auto-Deploy-V2.yml | 26 +- .../workflows/PR-Demo-Comment-with-react.yml | 2 +- .github/workflows/PR-Demo-cleanup.yml | 1 - .github/workflows/ai_pr_title_review.yml | 2 +- .github/workflows/auto-labelerV2.yml | 2 +- .github/workflows/build.yml | 50 +- .github/workflows/codeql.yml-disabled | 79 --- .github/workflows/dependency-review.yml | 2 +- .github/workflows/deploy-on-v2-commit.yml | 24 +- ...l => frontend-backend-licenses-update.yml} | 273 ++++++++- .github/workflows/licenses-update.yml | 105 ---- .github/workflows/multiOSReleases.yml | 10 +- .github/workflows/pre_commit.yml | 6 +- .github/workflows/push-docker-v2.yml | 1 - .github/workflows/push-docker.yml | 4 +- .github/workflows/releaseArtifacts.yml | 535 ------------------ .github/workflows/swagger.yml | 4 +- .github/workflows/sync_files_v2.yml | 3 +- .github/workflows/tauri-build.yml | 36 +- .github/workflows/testdriver.yml | 8 +- package-lock.json | 6 - 25 files changed, 396 insertions(+), 859 deletions(-) delete mode 100644 .github/workflows/codeql.yml-disabled rename .github/workflows/{frontend-licenses-update.yml => frontend-backend-licenses-update.yml} (50%) delete mode 100644 .github/workflows/licenses-update.yml delete mode 100644 .github/workflows/releaseArtifacts.yml delete mode 100644 package-lock.json diff --git a/.github/config/.files.yaml b/.github/config/.files.yaml index f866770b5..bb8b520fd 100644 --- a/.github/config/.files.yaml +++ b/.github/config/.files.yaml @@ -2,12 +2,9 @@ build: &build - build.gradle - app/(common|core|proprietary)/build.gradle -app: &app - - app/(common|core|proprietary)/src/main/java/** - openapi: &openapi - *build - - *app + - app/(common|core|proprietary)/src/main/java/** docker: &docker - Dockerfile @@ -34,9 +31,30 @@ project: &project - settings.gradle - frontend/** - docker/** + - scripts/RestartHelper.java frontend: &frontend - frontend/** - .github/workflows/testdriver.yml - testing/** - docker/** + - scripts/translations/*.py + - scripts/build-tauri-jlink.bat + - scripts/build-tauri-jlink.sh + - scripts/convert_cff_to_ttf.py + - scripts/harvest_type3_fonts.py + - scripts/ignore_translation.toml + - scripts/index_type3_catalogue.py + - scripts/summarize_type3_signatures.py + - scripts/type3_to_cff.py + - scripts/update_type3_library.py + +licenses-frontend: &licenses-frontend + - ".github/workflows/frontend-backend-licenses-update.yml" + - "frontend/package.json" + - "frontend/package-lock.json" + - "frontend/scripts/generate-licenses.js" + +licenses-backend: &licenses-backend + - ".github/workflows/frontend-backend-licenses-update.yml" + - *build \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3ba752efa..84cb0eb1f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,53 +6,65 @@ version: 2 updates: - package-ecosystem: "gradle" # See documentation for possible values - directory: "/" # Location of package manifests + directories: + - "/" # Location of package manifests + - "/app/common" + - "/app/core" + - "/app/proprietary" schedule: interval: "weekly" - open-pull-requests-limit: 10 rebase-strategy: "auto" - package-ecosystem: "docker" directory: "/" # Location of Dockerfile schedule: interval: "weekly" + rebase-strategy: "auto" - package-ecosystem: github-actions directory: / schedule: interval: weekly + rebase-strategy: "auto" - package-ecosystem: npm directory: /devTools schedule: interval: "weekly" + rebase-strategy: "auto" - package-ecosystem: docker directory: /docker/backend schedule: interval: "weekly" + rebase-strategy: "auto" - package-ecosystem: docker directory: /docker/embedded schedule: interval: "weekly" + rebase-strategy: "auto" - package-ecosystem: docker directory: /docker/frontend schedule: interval: "weekly" + rebase-strategy: "auto" - package-ecosystem: npm directory: /frontend schedule: interval: "weekly" + rebase-strategy: "auto" - package-ecosystem: cargo directory: /frontend/src-tauri schedule: interval: "weekly" + rebase-strategy: "auto" - package-ecosystem: pip directory: /testing/cucumber schedule: interval: "weekly" + rebase-strategy: "auto" diff --git a/.github/labeler-config-srvaroa.yml b/.github/labeler-config-srvaroa.yml index 6c9e029bd..ab370b6e2 100644 --- a/.github/labeler-config-srvaroa.yml +++ b/.github/labeler-config-srvaroa.yml @@ -46,20 +46,21 @@ labels: - label: 'API' title: '.*openapi.*|.*swagger.*|.*api.*' - - label: 'v2' - base-branch: 'V2' + - label: 'v3' + base-branch: 'V3' - label: 'Translation' files: - - 'app/core/src/main/resources/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}.properties' + - 'frontend/public/locales/[a-zA-Z]{2}-[a-zA-Z\-]{2,7}/translation.toml' - 'scripts/ignore_translation.toml' - - 'app/core/src/main/resources/templates/fragments/languages.html' - - '.github/scripts/check_language_properties.py' + - 'scripts/remove_translation_keys.sh' + - 'scripts/replace_translation_line.sh' + - 'scripts/translations/.*' + - '.github/scripts/check_language_toml.py' + - 'scripts/counter_translation_v3.py' - label: 'Front End' files: - - 'app/core/src/main/resources/templates/.*' - - 'app/proprietary/src/main/resources/templates/.*' - 'app/core/src/main/resources/static/.*' - 'app/proprietary/src/main/resources/static/.*' - 'app/core/src/main/java/stirling/software/SPDF/controller/web/.*' @@ -67,6 +68,11 @@ labels: - 'app/proprietary/src/main/java/stirling/software/proprietary/security/controller/web/.*' - 'frontend/**' + - label: 'Tauri' + files: + - 'frontend/src-tauri/**' + - 'frontend/src-tauri/.*' + - label: 'Java' files: - 'app/common/src/main/java/.*.java' diff --git a/.github/labels.yml b/.github/labels.yml index a6c354e58..a2d0ac4c5 100644 --- a/.github/labels.yml +++ b/.github/labels.yml @@ -84,6 +84,9 @@ - name: "v2" color: "FFFF00" description: "Issues or pull requests related to the v2 branch" +- name: "v3" + color: "FFA500" + description: "Issues or pull requests related to the v3 branch" - name: "wontfix" description: "This will not be worked on" color: "FFFFFF" @@ -187,3 +190,14 @@ - name: "break-change" color: "FF0000" description: "This PR introduces a breaking API change." +- name: "Rust" + color: "DEA584" + description: "Pull requests that update Rust code" + from_name: "rust" +- name: "Tauri" + color: "24C8FF" + description: "Pull requests that update Tauri code" + from_name: "tauri" +- name: "license-review-required" + color: "EDEDED" + description: "This PR requires a license review" \ No newline at end of file diff --git a/.github/workflows/PR-Auto-Deploy-V2.yml b/.github/workflows/PR-Auto-Deploy-V2.yml index 9ee582622..d5d01294a 100644 --- a/.github/workflows/PR-Auto-Deploy-V2.yml +++ b/.github/workflows/PR-Auto-Deploy-V2.yml @@ -134,7 +134,7 @@ jobs: script: | const { owner, repo } = context.repo; const prNumber = ${{ needs.check-pr.outputs.pr_number }}; - + // Delete previous V2 deployment comments to avoid clutter const { data: comments } = await github.rest.issues.listComments({ owner, @@ -157,7 +157,7 @@ jobs: comment_id: comment.id }); } - + // Create new deployment started comment const { data: newComment } = await github.rest.issues.createComment({ owner, @@ -173,7 +173,7 @@ jobs: repository: ${{ needs.check-pr.outputs.pr_repository }} ref: ${{ needs.check-pr.outputs.pr_ref }} token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: 0 # Fetch full history for commit hash detection + fetch-depth: 0 # Fetch full history for commit hash detection - name: Set up Docker Buildx uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 @@ -204,20 +204,20 @@ jobs: if [ -z "$BACKEND_HASH" ]; then BACKEND_HASH="no-backend-changes" fi - + echo "Frontend hash: $FRONTEND_HASH" echo "Backend hash: $BACKEND_HASH" - + echo "frontend_hash=$FRONTEND_HASH" >> $GITHUB_OUTPUT echo "backend_hash=$BACKEND_HASH" >> $GITHUB_OUTPUT - + # Short hashes for tags if [ "$FRONTEND_HASH" = "no-frontend-changes" ]; then echo "frontend_short=no-frontend" >> $GITHUB_OUTPUT else echo "frontend_short=${FRONTEND_HASH:0:8}" >> $GITHUB_OUTPUT fi - + if [ "$BACKEND_HASH" = "no-backend-changes" ]; then echo "backend_short=no-backend" >> $GITHUB_OUTPUT else @@ -280,7 +280,7 @@ jobs: # Use same port strategy as regular PRs - just the PR number V2_PORT=${{ needs.check-pr.outputs.pr_number }} BACKEND_PORT=$((V2_PORT + 10000)) # Backend on higher port to avoid conflicts - + # Create docker-compose for V2 with separate frontend and backend cat > docker-compose.yml << EOF version: '3.3' @@ -359,7 +359,7 @@ jobs: const { owner, repo } = context.repo; const prNumber = ${{ needs.check-pr.outputs.pr_number }}; const v2Port = ${{ steps.deploy.outputs.v2_port }}; - + // Delete the "deploying..." comment since we're posting the final result const deploymentStartedId = ${{ steps.deployment-started.outputs.result }}; if (deploymentStartedId) { @@ -374,7 +374,7 @@ jobs: console.log(`Could not delete deployment started comment: ${error.message}`); } } - + const deploymentUrl = `http://${{ secrets.VPS_HOST }}:${v2Port}`; const httpsUrl = `https://${v2Port}.ssl.stirlingpdf.cloud`; @@ -425,19 +425,19 @@ jobs: script: | const { owner, repo } = context.repo; const prNumber = ${{ github.event.pull_request.number }}; - + // Find and delete V2 deployment comments const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number: prNumber }); - + const v2Comments = comments.filter(c => c.body?.includes("## πŸš€ V2 Auto-Deployment Complete!") && c.user?.type === "Bot" ); - + for (const comment of v2Comments) { await github.rest.issues.deleteComment({ owner, diff --git a/.github/workflows/PR-Demo-Comment-with-react.yml b/.github/workflows/PR-Demo-Comment-with-react.yml index edb5f273a..0628279d1 100644 --- a/.github/workflows/PR-Demo-Comment-with-react.yml +++ b/.github/workflows/PR-Demo-Comment-with-react.yml @@ -151,7 +151,7 @@ jobs: ref: refs/pull/${{ needs.check-comment.outputs.pr_number }}/merge token: ${{ steps.setup-bot.outputs.token }} - - name: Set up JDK + - name: Set up JDK 21 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: java-version: "17" diff --git a/.github/workflows/PR-Demo-cleanup.yml b/.github/workflows/PR-Demo-cleanup.yml index 621322df7..9a9c22d23 100644 --- a/.github/workflows/PR-Demo-cleanup.yml +++ b/.github/workflows/PR-Demo-cleanup.yml @@ -96,7 +96,6 @@ jobs: const hasDeploymentComment = deploymentComments.length > 0; core.setOutput('present', (hasLabel || hasDeploymentComment) ? 'true' : 'false'); - - name: Set up SSH if: steps.remove-label-comment.outputs.present == 'true' run: | diff --git a/.github/workflows/ai_pr_title_review.yml b/.github/workflows/ai_pr_title_review.yml index 6dd4c0f04..d0c0cd10b 100644 --- a/.github/workflows/ai_pr_title_review.yml +++ b/.github/workflows/ai_pr_title_review.yml @@ -5,7 +5,7 @@ on: types: [opened, edited] branches: [main] -permissions: # required for secure-repo hardening +permissions: # required for secure-repo hardening contents: read jobs: diff --git a/.github/workflows/auto-labelerV2.yml b/.github/workflows/auto-labelerV2.yml index d776aa7ac..5da5a2fab 100644 --- a/.github/workflows/auto-labelerV2.yml +++ b/.github/workflows/auto-labelerV2.yml @@ -4,7 +4,7 @@ on: types: [opened, synchronize] branches: - main - - V2 + - V3 permissions: contents: read diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bfd1c1281..beb87d6d6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Build and Test Workflow on: pull_request: - branches: ["main", "V2", "V2-gha"] + branches: ["main"] workflow_dispatch: # cancel in-progress jobs if a new job is triggered @@ -27,15 +27,16 @@ jobs: timeout-minutes: 3 outputs: build: ${{ steps.changes.outputs.build }} - app: ${{ steps.changes.outputs.app }} project: ${{ steps.changes.outputs.project }} openapi: ${{ steps.changes.outputs.openapi }} + frontend: ${{ steps.changes.outputs.frontend }} steps: - name: Harden the runner (Audit all outbound calls) uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 with: egress-policy: audit - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Check for file changes uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 @@ -66,14 +67,12 @@ jobs: with: java-version: ${{ matrix.jdk-version }} distribution: "temurin" - - name: Setup Gradle - uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0 - with: - gradle-version: 8.14 + - name: Build with Gradle and spring security ${{ matrix.spring-security }} run: ./gradlew clean build -PnoSpotless env: DISABLE_ADDITIONAL_FEATURES: ${{ matrix.spring-security }} + - name: Check Test Reports Exist if: always() run: | @@ -91,6 +90,7 @@ jobs: exit 1 fi done + - name: Upload Test Reports if: always() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 @@ -117,18 +117,17 @@ jobs: - name: Checkout repository uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: - java-version: "17" + java-version: "21" distribution: "temurin" - - name: Setup Gradle - uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0 + - name: Generate OpenAPI documentation run: ./gradlew :stirling-pdf:generateOpenApiDocs env: DISABLE_ADDITIONAL_FEATURES: true - + - name: Upload OpenAPI Documentation uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: @@ -136,6 +135,8 @@ jobs: path: ./SwaggerDoc.json frontend-validation: + if: needs.files-changed.outputs.frontend == 'true' + needs: files-changed runs-on: ubuntu-latest steps: - name: Harden Runner @@ -147,8 +148,8 @@ jobs: - name: Set up Node.js uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: - node-version: '22' - cache: 'npm' + node-version: "22" + cache: "npm" cache-dependency-path: frontend/package-lock.json - name: Install frontend dependencies run: cd frontend && npm ci @@ -176,12 +177,14 @@ jobs: uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 with: egress-policy: audit + - name: Checkout repository uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - name: Set up JDK 17 + + - name: Set up JDK 21 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: - java-version: "17" + java-version: "21" distribution: "temurin" - name: check the licenses for compatibility @@ -223,10 +226,10 @@ jobs: - name: Checkout Repository uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - name: Set up Java 17 + - name: Set up JDK 21 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: - java-version: "17" + java-version: "21" distribution: "temurin" - name: Set up Docker Buildx @@ -241,7 +244,7 @@ jobs: uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 with: python-version: "3.12" - cache: 'pip' # caching pip dependencies + cache: "pip" # caching pip dependencies cache-dependency-path: ./testing/cucumber/requirements.txt - name: Pip requirements @@ -285,17 +288,12 @@ jobs: docker system prune -af || true echo "Disk space after cleanup:" && df -h - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: - java-version: "17" + java-version: "21" distribution: "temurin" - - name: Set up Gradle - uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0 - with: - gradle-version: 8.14 - - name: Build application run: ./gradlew clean build env: diff --git a/.github/workflows/codeql.yml-disabled b/.github/workflows/codeql.yml-disabled deleted file mode 100644 index ae54ec4b6..000000000 --- a/.github/workflows/codeql.yml-disabled +++ /dev/null @@ -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}}" diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 923123e94..c9bc1f8aa 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -26,4 +26,4 @@ jobs: - name: "Dependency Review" uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 with: - config-file: './.github/config/dependency-review-config.yml' + config-file: "./.github/config/dependency-review-config.yml" diff --git a/.github/workflows/deploy-on-v2-commit.yml b/.github/workflows/deploy-on-v2-commit.yml index 4309d5233..bfb536dee 100644 --- a/.github/workflows/deploy-on-v2-commit.yml +++ b/.github/workflows/deploy-on-v2-commit.yml @@ -36,26 +36,26 @@ jobs: if [ -z "$FRONTEND_HASH" ]; then FRONTEND_HASH="no-frontend-changes" fi - + # Get last commit that touched backend code, docker/backend, or docker/compose BACKEND_HASH=$(git log -1 --format="%H" -- app/ docker/backend/ docker/compose/ 2>/dev/null || echo "") if [ -z "$BACKEND_HASH" ]; then BACKEND_HASH="no-backend-changes" fi - + echo "Frontend hash: $FRONTEND_HASH" echo "Backend hash: $BACKEND_HASH" - + echo "frontend_hash=$FRONTEND_HASH" >> $GITHUB_OUTPUT echo "backend_hash=$BACKEND_HASH" >> $GITHUB_OUTPUT - + # Short hashes for tags if [ "$FRONTEND_HASH" = "no-frontend-changes" ]; then echo "frontend_short=no-frontend" >> $GITHUB_OUTPUT else echo "frontend_short=${FRONTEND_HASH:0:8}" >> $GITHUB_OUTPUT fi - + if [ "$BACKEND_HASH" = "no-backend-changes" ]; then echo "backend_short=no-backend" >> $GITHUB_OUTPUT else @@ -84,7 +84,6 @@ jobs: echo "Backend image needs to be built" fi - - name: Login to Docker Hub uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 with: @@ -103,7 +102,7 @@ jobs: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-latest build-args: VERSION_TAG=v2-alpha platforms: linux/amd64 - + - name: Build and push backend image if: steps.check-backend.outputs.exists == 'false' uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 @@ -117,18 +116,16 @@ jobs: build-args: VERSION_TAG=v2-alpha platforms: linux/amd64 - - name: Set up SSH run: | mkdir -p ~/.ssh/ echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key chmod 600 ../private.key - - name: Deploy to VPS on port 3000 run: | export UNIQUE_NAME=docker-compose-v2-$GITHUB_RUN_ID.yml - + cat > $UNIQUE_NAME << EOF version: '3.3' services: @@ -154,7 +151,7 @@ jobs: SWAGGER_SERVER_URL: "https://demo.stirlingpdf.cloud" baseUrl: "https://demo.stirlingpdf.cloud" restart: on-failure:5 - + frontend: container_name: stirling-v2-frontend image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:v2-frontend-${{ steps.commit-hashes.outputs.frontend_short }} @@ -166,10 +163,10 @@ jobs: - backend restart: on-failure:5 EOF - + # Copy to remote with unique name scp -i ../private.key -o StrictHostKeyChecking=no $UNIQUE_NAME ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }}:/tmp/$UNIQUE_NAME - + # SSH and rename/move atomically to avoid interference ssh -i ../private.key -o StrictHostKeyChecking=no ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << ENDSSH mkdir -p /stirling/V2/{data,config,logs} @@ -186,4 +183,3 @@ jobs: if: always() run: | rm -f ../private.key - diff --git a/.github/workflows/frontend-licenses-update.yml b/.github/workflows/frontend-backend-licenses-update.yml similarity index 50% rename from .github/workflows/frontend-licenses-update.yml rename to .github/workflows/frontend-backend-licenses-update.yml index 1bc56699f..2e6b84b03 100644 --- a/.github/workflows/frontend-licenses-update.yml +++ b/.github/workflows/frontend-backend-licenses-update.yml @@ -1,27 +1,47 @@ -name: Frontend License Report Workflow +name: License Report Workflow on: push: branches: - - V2 - paths: - - "frontend/package.json" - - "frontend/package-lock.json" - - "frontend/scripts/generate-licenses.js" + - main pull_request: branches: - - V2 - paths: - - ".github/workflows/frontend-licenses-update.yml" - - "frontend/package.json" - - "frontend/package-lock.json" - - "frontend/scripts/generate-licenses.js" + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref_name || github.ref }} + cancel-in-progress: true permissions: contents: read jobs: + files-changed: + name: detect what files changed + runs-on: ubuntu-latest + timeout-minutes: 3 + outputs: + licenses-frontend: ${{ steps.changes.outputs.licenses-frontend }} + licenses-backend: ${{ steps.changes.outputs.licenses-backend }} + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + + - name: Check for file changes + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: changes + with: + filters: .github/config/.files.yaml + generate-frontend-license-report: + if: needs.files-changed.outputs.licenses-frontend == 'true' + name: Generate Frontend License Report + needs: files-changed runs-on: ubuntu-latest permissions: contents: write @@ -29,12 +49,12 @@ jobs: repository-projects: write # Required for enabling automerge steps: - name: Harden Runner - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 + uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 with: egress-policy: audit - name: Checkout PR head (default) - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: fetch-depth: 0 persist-credentials: false @@ -49,7 +69,7 @@ jobs: - name: Checkout BASE branch (safe script) if: github.event_name == 'pull_request' - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 with: ref: ${{ github.event.pull_request.base.sha }} path: base @@ -59,8 +79,8 @@ jobs: - name: Set up Node.js uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 with: - node-version: '22' - cache: 'npm' + node-version: "22" + cache: "npm" cache-dependency-path: frontend/package-lock.json - name: Install frontend dependencies @@ -121,7 +141,7 @@ jobs: script: | const { owner, repo } = context.repo; const prNumber = context.issue.number; - + // Get all comments on the PR const { data: comments } = await github.rest.issues.listComments({ owner, @@ -129,13 +149,13 @@ jobs: issue_number: prNumber, per_page: 100 }); - + // Filter for license check comments const licenseComments = comments.filter(comment => comment.body.includes('## βœ… Frontend License Check Passed') || comment.body.includes('## ❌ Frontend License Check Failed') ); - + // Delete old license check comments for (const comment of licenseComments) { console.log(`Deleting old license check comment: ${comment.id}`); @@ -175,9 +195,9 @@ jobs: const { owner, repo } = context.repo; const prNumber = context.issue.number; const hasWarnings = process.env.LICENSE_WARNINGS_EXIST === 'true'; - + let commentBody; - + if (hasWarnings) { // Read warnings file to get specific issues const fs = require('fs'); @@ -205,7 +225,7 @@ jobs: The frontend license report has been updated successfully.`; } - + await github.rest.issues.createComment({ owner, repo, @@ -233,7 +253,7 @@ jobs: PR_BODY="Auto-generated by ${{ steps.setup-bot.outputs.app-slug }}[bot] This PR updates the frontend license report based on changes to package.json dependencies." - + if [ "${{ env.LICENSE_WARNINGS_EXIST }}" = "true" ]; then PR_BODY="$PR_BODY @@ -245,7 +265,7 @@ jobs: Please review these licenses to ensure they are acceptable for your use case." fi - + echo "PR_BODY<> $GITHUB_ENV echo "$PR_BODY" >> $GITHUB_ENV echo "EOF" >> $GITHUB_ENV @@ -261,7 +281,7 @@ jobs: author: ${{ steps.setup-bot.outputs.committer }} signoff: true branch: update-frontend-3rd-party-licenses - base: V2 + base: main title: "Update Frontend 3rd Party Licenses" body: ${{ env.PR_BODY }} labels: Licenses,github-actions,frontend @@ -280,3 +300,204 @@ jobs: run: gh pr edit "${{ steps.cpr.outputs.pull-request-number }}" --add-label "license-review-required" env: GH_TOKEN: ${{ steps.setup-bot.outputs.token }} + + generate-backend-license-report: + if: needs.files-changed.outputs.licenses-backend == 'true' + needs: files-changed + name: Generate Backend License Report + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + repository-projects: write # Required for enabling automerge + steps: + - name: Harden Runner + uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Setup GitHub App Bot + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) + id: setup-bot + uses: ./.github/actions/setup-bot + with: + app-id: ${{ secrets.GH_APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + + - name: Set up JDK 21 + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 + with: + java-version: "21" + distribution: "temurin" + + - name: Check licenses and generate report + id: license-check + run: | + ./gradlew clean checkLicense generateLicenseReport || echo "LICENSE_CHECK_FAILED=true" >> $GITHUB_ENV + env: + DISABLE_ADDITIONAL_FEATURES: false + STIRLING_PDF_DESKTOP_UI: true + + - name: Check for license compatibility issues + run: | + if [ -f build/reports/dependency-license/dependencies-without-allowed-license.json ] && \ + jq '.dependenciesWithoutAllowedLicenses | length > 0' build/reports/dependency-license/dependencies-without-allowed-license.json | grep -q true; then + echo "LICENSE_WARNINGS_EXIST=true" >> $GITHUB_ENV + else + echo "LICENSE_WARNINGS_EXIST=false" >> $GITHUB_ENV + fi + if: always() + + - name: Upload artifact on license issues + if: env.LICENSE_WARNINGS_EXIST == 'true' + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: backend-dependencies-without-allowed-license.json + path: build/reports/dependency-license/dependencies-without-allowed-license.json + + - name: Move license file + if: env.LICENSE_CHECK_FAILED != 'true' && env.LICENSE_WARNINGS_EXIST == 'false' + run: | + mkdir -p app/core/src/main/resources/static + cp build/reports/dependency-license/index.json app/core/src/main/resources/static/3rdPartyLicenses.json + + - name: Delete previous backend license check comments + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + github-token: ${{ steps.setup-bot.outputs.token }} + script: | + const { owner, repo } = context.repo; + const prNumber = context.issue.number; + + const { data: comments } = await github.rest.issues.listComments({ + owner, + repo, + issue_number: prNumber, + per_page: 100 + }); + + const backendLicenseComments = comments.filter(comment => + comment.body.includes('## βœ… Backend License Check Passed') || + comment.body.includes('## ❌ Backend License Check Failed') + ); + + for (const comment of backendLicenseComments) { + console.log(`Deleting old backend license comment: ${comment.id}`); + await github.rest.issues.deleteComment({ + owner, + repo, + comment_id: comment.id + }); + } + + - name: Comment on PR - Backend License Check Results + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + github-token: ${{ steps.setup-bot.outputs.token }} + script: | + const hasWarnings = process.env.LICENSE_WARNINGS_EXIST === 'true'; + const fs = require('fs'); + let warningDetails = ''; + + if (hasWarnings) { + try { + const warningsFile = 'build/reports/dependency-license/dependencies-without-allowed-license.json'; + if (fs.existsSync(warningsFile)) { + const data = JSON.parse(fs.readFileSync(warningsFile, 'utf8')); + if (data.length > 0) { + warningDetails = data.map(dep => `- **${dep.moduleName}@${dep.moduleVersion}** – ${dep.moduleLicenses.map(l => l.licenseName).join(', ')}`).join('\n'); + } + } + } catch (e) { + warningDetails = 'Unable to parse warning details.'; + } + } + + let commentBody; + if (hasWarnings) { + commentBody = `## ❌ Backend License Check Failed + + The backend license check has detected dependencies with incompatible or unallowed licenses: + + ${warningDetails || 'See uploaded artifact for details.'} + + **Action Required:** Please review these licenses and resolve before merging. + + _This check will fail the PR until license issues are resolved._`; + } else { + commentBody = `## βœ… Backend License Check Passed + + All backend dependencies have valid and allowed licenses. + + The backend license report has been updated successfully.`; + } + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: commentBody + }); + + - name: Fail workflow if license warnings exist (PR only) + if: github.event_name == 'pull_request' && env.LICENSE_WARNINGS_EXIST == 'true' + run: | + echo "❌ Backend license warnings detected. Failing the workflow." + exit 1 + + - name: Commit changes (push only) + if: github.event_name == 'push' && env.LICENSE_WARNINGS_EXIST == 'false' + run: | + git config user.name "${{ steps.setup-bot.outputs.committer }}" + git config user.email "${{ steps.setup-bot.outputs.committer-email || 'bot@github.com' }}" + git add app/core/src/main/resources/static/3rdPartyLicenses.json + git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV + + - name: Prepare PR body (push only) + if: github.event_name == 'push' && env.CHANGES_DETECTED == 'true' + run: | + PR_BODY="Auto-generated by ${{ steps.setup-bot.outputs.app-slug }}[bot]\n\nThis PR updates the backend license report based on dependency changes." + if [ "${{ env.LICENSE_WARNINGS_EXIST }}" = "true" ]; then + PR_BODY="$PR_BODY\n\n## ⚠️ License Compatibility Warnings\n\nIncompatible licenses detected – manual review required before merge." + fi + echo "PR_BODY<> $GITHUB_ENV + echo "$PR_BODY" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Create Pull Request (push only) + if: github.event_name == 'push' && env.CHANGES_DETECTED == 'true' + id: cpr + uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 + with: + token: ${{ steps.setup-bot.outputs.token }} + commit-message: "Update Backend 3rd Party Licenses" + committer: ${{ steps.setup-bot.outputs.committer }} + author: ${{ steps.setup-bot.outputs.committer }} + signoff: true + branch: update-backend-3rd-party-licenses + base: main + title: "Update Backend 3rd Party Licenses" + body: ${{ env.PR_BODY }} + labels: Licenses,github-actions,backend + delete-branch: true + sign-commits: true + + - name: Enable Pull Request Automerge (push only, no warnings) + if: github.event_name == 'push' && steps.cpr.outputs.pull-request-operation == 'created' && env.LICENSE_WARNINGS_EXIST == 'false' + run: gh pr merge --squash --auto "${{ steps.cpr.outputs.pull-request-number }}" + env: + GH_TOKEN: ${{ steps.setup-bot.outputs.token }} + + - name: Add review required label (push only, with warnings) + if: github.event_name == 'push' && steps.cpr.outputs.pull-request-operation == 'created' && env.LICENSE_WARNINGS_EXIST == 'true' + run: gh pr edit "${{ steps.cpr.outputs.pull-request-number }}" --add-label "license-review-required" + env: + GH_TOKEN: ${{ steps.setup-bot.outputs.token }} diff --git a/.github/workflows/licenses-update.yml b/.github/workflows/licenses-update.yml deleted file mode 100644 index 6ec74cb1d..000000000 --- a/.github/workflows/licenses-update.yml +++ /dev/null @@ -1,105 +0,0 @@ -name: License Report Workflow - -on: - push: - branches: - - main - paths: - - "build.gradle" - -# cancel in-progress jobs if a new job is triggered -# This is useful to avoid running multiple builds for the same branch if a new commit is pushed -# or a pull request is updated. -# It helps to save resources and time by ensuring that only the latest commit is built and tested -# This is particularly useful for long-running jobs that may take a while to complete. -# The `group` is set to a combination of the workflow name, event name, and branch name. -# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of -# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened. -concurrency: - group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref_name || github.ref }} - cancel-in-progress: true - -permissions: - contents: read - -jobs: - generate-license-report: - runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - repository-projects: write # Required for enabling automerge - steps: - - name: Harden Runner - uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 - with: - egress-policy: audit - - - name: Check out code - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - with: - fetch-depth: 0 - - - name: Setup GitHub App Bot - id: setup-bot - uses: ./.github/actions/setup-bot - with: - app-id: ${{ secrets.GH_APP_ID }} - private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - - - name: Set up JDK 17 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 - with: - java-version: "17" - distribution: "temurin" - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0 - - - name: Check licenses for compatibility - run: ./gradlew clean checkLicense - env: - DISABLE_ADDITIONAL_FEATURES: false - STIRLING_PDF_DESKTOP_UI: true - - - name: Upload artifact on failure - if: failure() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - with: - name: dependencies-without-allowed-license.json - path: build/reports/dependency-license/dependencies-without-allowed-license.json - retention-days: 3 - - - name: Move and rename license file - run: | - mv build/reports/dependency-license/index.json app/core/src/main/resources/static/3rdPartyLicenses.json - - - name: Commit changes - run: | - git add app/core/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@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0 - with: - token: ${{ steps.setup-bot.outputs.token }} - commit-message: "Update 3rd Party Licenses" - committer: ${{ steps.setup-bot.outputs.committer }} - author: ${{ steps.setup-bot.outputs.committer }} - signoff: true - branch: update-3rd-party-licenses - title: "Update 3rd Party Licenses" - body: | - Auto-generated by ${{ steps.setup-bot.outputs.app-slug }}[bot] - 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.setup-bot.outputs.token }} diff --git a/.github/workflows/multiOSReleases.yml b/.github/workflows/multiOSReleases.yml index 29f0e213d..34f9e6f7f 100644 --- a/.github/workflows/multiOSReleases.yml +++ b/.github/workflows/multiOSReleases.yml @@ -22,7 +22,7 @@ on: - macos - linux push: - branches: [main, V2, V2-demo, V2-master] + branches: [main, V2-master] release: types: [created] @@ -126,8 +126,8 @@ jobs: if: matrix.variant.build_frontend == true uses: actions/setup-node@v4 with: - node-version: 20 - cache: 'npm' + node-version: 22 + cache: "npm" cache-dependency-path: frontend/package-lock.json - name: Build JAR @@ -178,8 +178,8 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: 20 - cache: 'npm' + node-version: 22 + cache: "npm" cache-dependency-path: frontend/package-lock.json - name: Setup Rust diff --git a/.github/workflows/pre_commit.yml b/.github/workflows/pre_commit.yml index 7977d3e37..05b8def67 100644 --- a/.github/workflows/pre_commit.yml +++ b/.github/workflows/pre_commit.yml @@ -41,7 +41,7 @@ jobs: uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0 with: python-version: 3.12 - cache: 'pip' # caching pip dependencies + cache: "pip" # caching pip dependencies cache-dependency-path: ./.github/scripts/requirements_pre_commit.txt - name: Run Pre-Commit Hooks @@ -51,10 +51,10 @@ jobs: - run: pre-commit run --all-files -c .pre-commit-config.yaml continue-on-error: true - - name: Set up JDK + - name: Set up JDK 21 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: - java-version: 17 + java-version: 21 distribution: "temurin" - name: Build with Gradle diff --git a/.github/workflows/push-docker-v2.yml b/.github/workflows/push-docker-v2.yml index 3f2e18134..f82564417 100644 --- a/.github/workflows/push-docker-v2.yml +++ b/.github/workflows/push-docker-v2.yml @@ -5,7 +5,6 @@ on: push: branches: - V2-master - - V1_V2_merge # cancel in-progress jobs if a new job is triggered # This is useful to avoid running multiple builds for the same branch if a new commit is pushed diff --git a/.github/workflows/push-docker.yml b/.github/workflows/push-docker.yml index eb4277071..6d0afe96e 100644 --- a/.github/workflows/push-docker.yml +++ b/.github/workflows/push-docker.yml @@ -37,10 +37,10 @@ jobs: - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: - java-version: "17" + java-version: "21" distribution: "temurin" - uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0 diff --git a/.github/workflows/releaseArtifacts.yml b/.github/workflows/releaseArtifacts.yml deleted file mode 100644 index 7fdb11056..000000000 --- a/.github/workflows/releaseArtifacts.yml +++ /dev/null @@ -1,535 +0,0 @@ -name: Release Artifacts - -on: - workflow_dispatch: - inputs: - platform: - description: "Platform to build (windows, macos, linux, or all)" - required: true - default: "all" - type: choice - options: - - all - - windows - - macos - - linux - push: - branches: [main, V2, V2-demo] - -permissions: - contents: read - -jobs: - determine-matrix: - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} - version: ${{ steps.versionNumber.outputs.versionNumber }} - steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - - name: Get version number - id: versionNumber - run: | - VERSION=$(grep "^version =" build.gradle | awk -F'"' '{print $2}') - echo "versionNumber=$VERSION" >> $GITHUB_OUTPUT - - - name: Determine build matrix - id: set-matrix - run: | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - case "${{ github.event.inputs.platform }}" in - "windows") - echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"}]}' >> $GITHUB_OUTPUT - ;; - "macos") - echo 'matrix={"include":[{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"}]}' >> $GITHUB_OUTPUT - ;; - "linux") - echo 'matrix={"include":[{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT - ;; - *) - echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"},{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT - ;; - esac - else - # For push events, build all platforms - echo 'matrix={"include":[{"platform":"windows-latest","args":"--target x86_64-pc-windows-msvc","name":"windows-x86_64"},{"platform":"macos-15","args":"--target aarch64-apple-darwin","name":"macos-aarch64"},{"platform":"macos-15-intel","args":"--target x86_64-apple-darwin","name":"macos-x86_64"},{"platform":"ubuntu-22.04","args":"","name":"linux-x86_64"}]}' >> $GITHUB_OUTPUT - fi - - build: - needs: determine-matrix - strategy: - fail-fast: false - matrix: ${{ fromJson(needs.determine-matrix.outputs.matrix) }} - runs-on: ${{ matrix.platform }} - env: - SM_API_KEY: ${{ secrets.SM_API_KEY }} - WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }} - steps: - - name: Harden Runner - uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2 - with: - egress-policy: audit - - - name: Checkout repository - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - - name: Install dependencies (ubuntu only) - if: matrix.platform == 'ubuntu-22.04' - run: | - sudo apt-get update - sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libjavascriptcoregtk-4.0-dev libsoup2.4-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'npm' - cache-dependency-path: frontend/package-lock.json - - - name: Setup Rust - uses: dtolnay/rust-toolchain@stable - with: - toolchain: stable - targets: ${{ (matrix.platform == 'macos-15' || matrix.platform == 'macos-15-intel') && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} - - - name: Set up JDK 21 - uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 - with: - java-version: "21" - distribution: "temurin" - - - name: Build Java backend with JLink - working-directory: ./ - shell: bash - run: | - chmod +x ./gradlew - echo "πŸ”§ Building Stirling-PDF JAR..." - ./gradlew clean build -x spotlessApply -x spotlessCheck -x test -x sonarqube - - # Find the built JAR - STIRLING_JAR=$(ls app/core/build/libs/stirling-pdf-*.jar | head -n 1) - echo "βœ… Built JAR: $STIRLING_JAR" - - # Create Tauri directories - mkdir -p ./frontend/src-tauri/libs - mkdir -p ./frontend/src-tauri/runtime - - # Copy JAR to Tauri libs - cp "$STIRLING_JAR" ./frontend/src-tauri/libs/ - echo "βœ… JAR copied to Tauri libs" - - # Analyze JAR dependencies for jlink modules - echo "πŸ” Analyzing JAR dependencies..." - if command -v jdeps &> /dev/null; then - DETECTED_MODULES=$(jdeps --print-module-deps --ignore-missing-deps "$STIRLING_JAR" 2>/dev/null || echo "") - if [ -n "$DETECTED_MODULES" ]; then - echo "πŸ“‹ jdeps detected modules: $DETECTED_MODULES" - MODULES="$DETECTED_MODULES,java.compiler,java.instrument,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported" - else - echo "⚠️ jdeps analysis failed, using predefined modules" - MODULES="java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported" - fi - else - echo "⚠️ jdeps not available, using predefined modules" - MODULES="java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported" - fi - - # Create custom JRE with jlink - echo "πŸ”§ Creating custom JRE with jlink..." - echo "πŸ“‹ Using modules: $MODULES" - - # Remove any existing JRE - rm -rf ./frontend/src-tauri/runtime/jre - - # Create the custom JRE - jlink \ - --add-modules "$MODULES" \ - --strip-debug \ - --compress=2 \ - --no-header-files \ - --no-man-pages \ - --output ./frontend/src-tauri/runtime/jre - - if [ ! -d "./frontend/src-tauri/runtime/jre" ]; then - echo "❌ Failed to create JLink runtime" - exit 1 - fi - - # Test the bundled runtime - if [ -f "./frontend/src-tauri/runtime/jre/bin/java" ]; then - RUNTIME_VERSION=$(./frontend/src-tauri/runtime/jre/bin/java --version 2>&1 | head -n 1) - echo "βœ… Custom JRE created successfully: $RUNTIME_VERSION" - else - echo "❌ Custom JRE executable not found" - exit 1 - fi - - # Calculate runtime size - RUNTIME_SIZE=$(du -sh ./frontend/src-tauri/runtime/jre | cut -f1) - echo "πŸ“Š Custom JRE size: $RUNTIME_SIZE" - env: - DISABLE_ADDITIONAL_FEATURES: true - - - name: Install frontend dependencies - working-directory: ./frontend - run: npm install - - # DigiCert KeyLocker Setup (Cloud HSM) - - name: Setup DigiCert KeyLocker - id: digicert-setup - if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' && github.ref == 'refs/heads/main' }} - uses: digicert/ssm-code-signing@v1.1.0 - env: - SM_API_KEY: ${{ secrets.SM_API_KEY }} - SM_CLIENT_CERT_FILE_B64: ${{ secrets.SM_CLIENT_CERT_FILE_B64 }} - SM_CLIENT_CERT_PASSWORD: ${{ secrets.SM_CLIENT_CERT_PASSWORD }} - SM_KEYPAIR_ALIAS: ${{ secrets.SM_KEYPAIR_ALIAS }} - SM_HOST: ${{ secrets.SM_HOST }} - - - name: Setup DigiCert KeyLocker Certificate - if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' && github.ref == 'refs/heads/main' }} - shell: pwsh - run: | - Write-Host "Setting up DigiCert KeyLocker environment..." - - # Decode client certificate - $certBytes = [Convert]::FromBase64String("${{ secrets.SM_CLIENT_CERT_FILE_B64 }}") - $certPath = "D:\Certificate_pkcs12.p12" - [IO.File]::WriteAllBytes($certPath, $certBytes) - - # Set environment variables - echo "SM_CLIENT_CERT_FILE=D:\Certificate_pkcs12.p12" >> $env:GITHUB_ENV - echo "SM_HOST=${{ secrets.SM_HOST }}" >> $env:GITHUB_ENV - echo "SM_API_KEY=${{ secrets.SM_API_KEY }}" >> $env:GITHUB_ENV - echo "SM_CLIENT_CERT_PASSWORD=${{ secrets.SM_CLIENT_CERT_PASSWORD }}" >> $env:GITHUB_ENV - echo "SM_KEYPAIR_ALIAS=${{ secrets.SM_KEYPAIR_ALIAS }}" >> $env:GITHUB_ENV - - # Get PKCS11 config path from DigiCert action - $pkcs11Config = $env:PKCS11_CONFIG - if ($pkcs11Config) { - Write-Host "Found PKCS11_CONFIG: $pkcs11Config" - echo "PKCS11_CONFIG=$pkcs11Config" >> $env:GITHUB_ENV - } else { - Write-Host "PKCS11_CONFIG not set by DigiCert action, using default path" - $defaultPath = "C:\Users\RUNNER~1\AppData\Local\Temp\smtools-windows-x64\pkcs11properties.cfg" - if (Test-Path $defaultPath) { - Write-Host "Found config at default path: $defaultPath" - echo "PKCS11_CONFIG=$defaultPath" >> $env:GITHUB_ENV - } else { - Write-Host "Warning: Could not find PKCS11 config file" - } - } - - # Traditional PFX Certificate Import (fallback if KeyLocker not configured) - - name: Import Windows Code Signing Certificate - if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY == '' && github.ref == 'refs/heads/main' }} - env: - WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }} - WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} - shell: powershell - run: | - if ($env:WINDOWS_CERTIFICATE) { - Write-Host "Importing Windows Code Signing Certificate..." - - # Decode base64 certificate and save to file - $certBytes = [Convert]::FromBase64String($env:WINDOWS_CERTIFICATE) - $certPath = Join-Path $env:RUNNER_TEMP "certificate.pfx" - [IO.File]::WriteAllBytes($certPath, $certBytes) - - # Import certificate to CurrentUser\My store - $cert = Import-PfxCertificate -FilePath $certPath -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -AsPlainText -Force) - - # Extract and set thumbprint as environment variable - $thumbprint = $cert.Thumbprint - Write-Host "Certificate imported with thumbprint: $thumbprint" - echo "WINDOWS_CERTIFICATE_THUMBPRINT=$thumbprint" >> $env:GITHUB_ENV - - # Clean up certificate file - Remove-Item $certPath - - Write-Host "Windows certificate import completed." - } else { - Write-Host "⚠️ WINDOWS_CERTIFICATE secret not set - building unsigned binary" - } - - - name: Import Apple Developer Certificate - if: matrix.platform == 'macos-15' || matrix.platform == 'macos-15-intel' - env: - APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - run: | - echo "Importing Apple Developer Certificate..." - echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12 - # Create temporary keychain - KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db - KEYCHAIN_PASSWORD=$(openssl rand -base64 32) - security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH - security set-keychain-settings -lut 21600 $KEYCHAIN_PATH - security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH - # Import certificate - security import certificate.p12 -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH - security list-keychain -d user -s $KEYCHAIN_PATH - security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH - # Clean up - rm certificate.p12 - - - name: Verify Certificate - if: matrix.platform == 'macos-15' || matrix.platform == 'macos-15-intel' - run: | - echo "Verifying Apple Developer Certificate..." - KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db - CERT_INFO=$(security find-identity -v -p codesigning $KEYCHAIN_PATH | grep "Developer ID Application") - echo "Certificate Info: $CERT_INFO" - CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}') - echo "Certificate ID: $CERT_ID" - echo "APPLE_SIGNING_IDENTITY=$CERT_ID" >> $GITHUB_ENV - echo "Certificate imported successfully." - - - name: Build Tauri app - uses: tauri-apps/tauri-action@v0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - APPLE_SIGNING_IDENTITY: ${{ env.APPLE_SIGNING_IDENTITY }} - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} - APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} - APPIMAGETOOL_SIGN_PASSPHRASE: ${{ secrets.APPIMAGETOOL_SIGN_PASSPHRASE }} - TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} - TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} - VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY: ${{ secrets.VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY }} - VITE_SAAS_SERVER_URL: ${{ secrets.VITE_SAAS_SERVER_URL }} - # Only enable Windows signing in Tauri when on main - SIGN: ${{ github.ref == 'refs/heads/main' && (env.SM_API_KEY == '' && env.WINDOWS_CERTIFICATE != '') && '1' || '0' }} - CI: true - with: - projectPath: ./frontend - tauriScript: npx tauri - args: ${{ matrix.args }} - - # Sign with DigiCert KeyLocker (post-build) - - name: Sign Windows binaries with DigiCert KeyLocker - if: ${{ matrix.platform == 'windows-latest' && env.SM_API_KEY != '' && github.ref == 'refs/heads/main' }} - shell: pwsh - run: | - Write-Host "=== DigiCert KeyLocker Signing ===" - - # Test smctl connectivity first - Write-Host "Testing smctl connection..." - $healthCheck = & smctl healthcheck 2>&1 - if ($LASTEXITCODE -eq 0) { - Write-Host "[SUCCESS] Connected to DigiCert KeyLocker" - } else { - Write-Host "[ERROR] Failed to connect to DigiCert KeyLocker" - Write-Host $healthCheck - exit 1 - } - Write-Host "" - - # Sync certificates to Windows certificate store - Write-Host "Syncing certificates to Windows certificate store..." - $syncOutput = & smctl windows certsync 2>&1 - Write-Host "Cert sync result: $syncOutput" - Write-Host "" - - # Find only the files we need to sign (not build scripts) - $filesToSign = @() - - # Main application executable - $mainExe = Get-ChildItem -Path "./frontend/src-tauri/target/x86_64-pc-windows-msvc/release" -Filter "stirling-pdf.exe" -File -ErrorAction SilentlyContinue - if ($mainExe) { $filesToSign += $mainExe } - - # MSI installer - $msiFiles = Get-ChildItem -Path "./frontend/src-tauri/target" -Filter "*.msi" -Recurse -File - $filesToSign += $msiFiles - - if ($filesToSign.Count -eq 0) { - Write-Host "[ERROR] No files found to sign" - exit 1 - } - - Write-Host "Found $($filesToSign.Count) files to sign:" - foreach ($f in $filesToSign) { Write-Host " - $($f.Name)" } - Write-Host "" - - $signedCount = 0 - foreach ($file in $filesToSign) { - Write-Host "Signing: $($file.Name)" - - # Get PKCS11 config file path (set by DigiCert action) - $pkcs11Config = $env:PKCS11_CONFIG - if (-not $pkcs11Config) { - Write-Host "[ERROR] PKCS11_CONFIG environment variable not set" - Write-Host "DigiCert KeyLocker action may not have run correctly" - exit 1 - } - - Write-Host "Using PKCS11 config: $pkcs11Config" - - # Try signing with certificate fingerprint first (if available) - $fingerprint = "${{ secrets.SM_CODE_SIGNING_CERT_SHA1_HASH }}" - if ($fingerprint -and $fingerprint -ne "") { - Write-Host "Attempting to sign with certificate fingerprint..." - $output = & smctl sign --fingerprint "$fingerprint" --input "$($file.FullName)" --config-file "$pkcs11Config" --verbose 2>&1 - $exitCode = $LASTEXITCODE - } else { - Write-Host "No fingerprint provided, using keypair alias..." - # Use smctl to sign with keypair alias - $output = & smctl sign --keypair-alias "${{ secrets.SM_KEYPAIR_ALIAS }}" --input "$($file.FullName)" --config-file "$pkcs11Config" --verbose 2>&1 - $exitCode = $LASTEXITCODE - } - - Write-Host "Exit code: $exitCode" - Write-Host "Output: $output" - - # Check if output contains "FAILED" even with exit code 0 - if ($output -match "FAILED" -or $output -match "error" -or $output -match "Error") { - Write-Host "" - Write-Host "[ERROR] Signing failed for $($file.Name)" - Write-Host "[ERROR] smctl returned success but output indicates failure" - exit 1 - } - - if ($exitCode -ne 0) { - Write-Host "[ERROR] Failed to sign $($file.Name)" - Write-Host "Full error output:" - Write-Host $output - exit 1 - } - - $signedCount++ - Write-Host "[SUCCESS] Signed: $($file.Name)" - Write-Host "" - } - - Write-Host "=== Summary ===" - Write-Host "[SUCCESS] Signed $signedCount/$($filesToSign.Count) files successfully" - - - name: Rename artifacts - shell: bash - run: | - mkdir -p ./dist - cd ./frontend/src-tauri/target - - # Find and rename artifacts based on platform - if [ "${{ matrix.platform }}" = "windows-latest" ]; then - find . -name "*.exe" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.exe" \; - find . -name "*.msi" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.msi" \; - elif [ "${{ matrix.platform }}" = "macos-15" ] || [ "${{ matrix.platform }}" = "macos-15-intel" ]; then - find . -name "*.dmg" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.dmg" \; - find . -name "*.app" -exec cp -r {} "../../../dist/Stirling-PDF-${{ matrix.name }}.app" \; - else - find . -name "*.deb" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.deb" \; - find . -name "*.AppImage" -exec cp {} "../../../dist/Stirling-PDF-${{ matrix.name }}.AppImage" \; - fi - - - name: Upload build artifacts - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: Stirling-PDF-${{ matrix.name }} - path: ./dist/* - retention-days: 30 - - sign_verify: - needs: build - runs-on: ubuntu-latest - if: success() - strategy: - fail-fast: false - matrix: - name: [windows-x86_64, macos-aarch64, macos-x86_64, linux-x86_64] - steps: - - name: Harden Runner - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 - with: - egress-policy: audit - - - name: Download build artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - name: Stirling-PDF-${{ matrix.name }} - - - name: Display structure of downloaded files - run: ls -R - - - name: Install Cosign - uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0 - - - name: Generate key pair - run: cosign generate-key-pair - - - name: Sign and generate attestations - shell: bash - run: | - # Sign all artifacts for this platform - for file in *; do - if [ -f "$file" ] && [[ ! "$file" =~ \.(sig|intoto\.jsonl)$ ]]; then - echo "Signing: $file" - - # Sign the artifact - cosign sign-blob \ - --key ./cosign.key \ - --yes \ - --output-signature "${file}.sig" \ - "$file" - - # Generate attestation - cosign attest-blob \ - --predicate - \ - --key ./cosign.key \ - --yes \ - --output-attestation "${file}.intoto.jsonl" \ - "$file" - - # Verify the signature - cosign verify-blob \ - --key ./cosign.pub \ - --signature "${file}.sig" \ - "$file" - - echo "βœ… Signed and verified: $file" - fi - done - - - name: Upload signed artifacts - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - with: - name: Stirling-PDF-${{ matrix.name }}-signed - path: | - * - !cosign.key - !cosign.pub - retention-days: 30 - - release: - needs: [determine-matrix, build, sign_verify] - runs-on: ubuntu-latest - if: github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/main' - permissions: - contents: write - steps: - - name: Harden Runner - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 - with: - egress-policy: audit - - - name: Download all signed artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - with: - pattern: Stirling-PDF-*-signed - path: ./artifacts - - - name: Display structure of downloaded files - run: ls -R ./artifacts - - - name: Create GitHub Release - uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 - with: - tag_name: v${{ needs.determine-matrix.outputs.version }} - generate_release_notes: true - files: ./artifacts/**/* - draft: false - prerelease: false diff --git a/.github/workflows/swagger.yml b/.github/workflows/swagger.yml index 0fc542496..d0702ea7b 100644 --- a/.github/workflows/swagger.yml +++ b/.github/workflows/swagger.yml @@ -33,10 +33,10 @@ jobs: - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: - java-version: "17" + java-version: "21" distribution: "temurin" - uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0 diff --git a/.github/workflows/sync_files_v2.yml b/.github/workflows/sync_files_v2.yml index d72ba8a9d..f47235c52 100644 --- a/.github/workflows/sync_files_v2.yml +++ b/.github/workflows/sync_files_v2.yml @@ -5,7 +5,6 @@ on: push: branches: - main - - syncLangTest paths: - "build.gradle" - "README.md" @@ -117,4 +116,4 @@ jobs: add-paths: | README.md frontend/public/locales/*/translation.toml - scripts/ignore_translation.toml \ No newline at end of file + scripts/ignore_translation.toml diff --git a/.github/workflows/tauri-build.yml b/.github/workflows/tauri-build.yml index d28683950..dea68a60b 100644 --- a/.github/workflows/tauri-build.yml +++ b/.github/workflows/tauri-build.yml @@ -14,14 +14,14 @@ on: - macos - linux pull_request: - branches: [main, V2, V2-tauri-windows] + branches: [main, V2-tauri-windows] paths: - - 'frontend/src-tauri/**' - - 'frontend/src/desktop/**' - - 'frontend/tsconfig.desktop.json' - - '.github/workflows/tauri-build.yml' + - "frontend/src-tauri/**" + - "frontend/src/desktop/**" + - "frontend/tsconfig.desktop.json" + - ".github/workflows/tauri-build.yml" push: - branches: [main, V2] + branches: [main] permissions: contents: read @@ -83,8 +83,8 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: 20 - cache: 'npm' + node-version: 22 + cache: "npm" cache-dependency-path: frontend/package-lock.json - name: Setup Rust @@ -111,15 +111,15 @@ jobs: # Find the built JAR STIRLING_JAR=$(ls app/core/build/libs/stirling-pdf-*.jar | head -n 1) echo "βœ… Built JAR: $STIRLING_JAR" - + # Create Tauri directories mkdir -p ./frontend/src-tauri/libs mkdir -p ./frontend/src-tauri/runtime - + # Copy JAR to Tauri libs cp "$STIRLING_JAR" ./frontend/src-tauri/libs/ echo "βœ… JAR copied to Tauri libs" - + # Analyze JAR dependencies for jlink modules echo "πŸ” Analyzing JAR dependencies..." if command -v jdeps &> /dev/null; then @@ -135,14 +135,14 @@ jobs: echo "⚠️ jdeps not available, using predefined modules" MODULES="java.base,java.compiler,java.desktop,java.instrument,java.logging,java.management,java.naming,java.net.http,java.prefs,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.transaction.xa,java.xml,java.xml.crypto,jdk.crypto.ec,jdk.crypto.cryptoki,jdk.unsupported" fi - + # Create custom JRE with jlink (always rebuild) echo "πŸ”§ Creating custom JRE with jlink..." echo "πŸ“‹ Using modules: $MODULES" - + # Remove any existing JRE rm -rf ./frontend/src-tauri/runtime/jre - + # Create the custom JRE jlink \ --add-modules "$MODULES" \ @@ -151,12 +151,12 @@ jobs: --no-header-files \ --no-man-pages \ --output ./frontend/src-tauri/runtime/jre - + if [ ! -d "./frontend/src-tauri/runtime/jre" ]; then echo "❌ Failed to create JLink runtime" exit 1 fi - + # Test the bundled runtime if [ -f "./frontend/src-tauri/runtime/jre/bin/java" ]; then RUNTIME_VERSION=$(./frontend/src-tauri/runtime/jre/bin/java --version 2>&1 | head -n 1) @@ -165,7 +165,7 @@ jobs: echo "❌ Custom JRE executable not found" exit 1 fi - + # Calculate runtime size RUNTIME_SIZE=$(du -sh ./frontend/src-tauri/runtime/jre | cut -f1) echo "πŸ“Š Custom JRE size: $RUNTIME_SIZE" @@ -579,7 +579,7 @@ jobs: name: Stirling-PDF-${{ matrix.name }} path: ./dist/* retention-days: 7 - + - name: Verify build artifacts shell: bash run: | diff --git a/.github/workflows/testdriver.yml b/.github/workflows/testdriver.yml index 59bf2824f..0efb202a8 100644 --- a/.github/workflows/testdriver.yml +++ b/.github/workflows/testdriver.yml @@ -32,11 +32,11 @@ jobs: - name: Checkout repository uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 - - name: Set up JDK + - name: Set up JDK 21 uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 with: - java-version: '17' - distribution: 'temurin' + java-version: "21" + distribution: "temurin" - name: Setup Gradle uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0 @@ -149,7 +149,7 @@ jobs: - name: Set up Node uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 with: - cache: 'npm' + cache: "npm" cache-dependency-path: frontend/package-lock.json - name: Run TestDriver.ai diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 9ae7c67c8..000000000 --- a/package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Stirling-PDF", - "lockfileVersion": 3, - "requires": true, - "packages": {} -}