mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-02 21:03:34 +03:00
# Description of Changes This PR refactors Gradle caching across the GitHub Actions workflows to improve cache reuse, reduce dependency resolution overhead, and shorten CI execution times. ### What was changed - Replaced multiple `gradle/actions/setup-gradle` steps with a unified `actions/cache`-based Gradle User Home cache strategy. - Standardized cache paths across workflows to include: - `~/.gradle/caches` - `~/.gradle/wrapper` - Introduced consistent cache keys using: - Runner OS - Runner architecture - JDK version - Hashes of Gradle wrapper, version catalog, Gradle build files, and project build scripts. - Added restore keys to maximize cache hit rates across similar environments. - Added a new **`gradle-cache-prime`** job in the main build workflow that: - Restores or creates the shared Gradle cache. - Resolves backend dependencies before downstream jobs execute. - Makes the populated cache available to subsequent jobs. - Updated workflow dependencies so Gradle-based jobs wait for the cache priming job before execution. - Simplified and unified Gradle cache handling across numerous CI workflows, including backend builds, OpenAPI generation, database migration tests, Docker tests, Tauri builds, Swagger generation, enterprise builds, release workflows, and license generation. - Updated workflow comments to reflect the new caching strategy and shared cache behavior. ### Why the change was made The previous workflows used a mixture of Gradle setup actions and partial dependency caches, leading to duplicated dependency downloads, inconsistent cache behavior, and longer CI runtimes. Consolidating all workflows onto a shared Gradle User Home cache with a dedicated cache priming job improves cache reuse, reduces unnecessary dependency resolution, and makes CI execution more consistent. --- ## 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/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 run `task check` to verify linters, typechecks, and tests pass - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing) for more details.
183 lines
7.4 KiB
YAML
183 lines
7.4 KiB
YAML
name: Docker Compose Cucumber tests
|
|
|
|
# Reusable workflow called from build.yml when project / docker / testing
|
|
# sources change. Boots the docker-compose stack and runs the cucumber
|
|
# scenarios in testing/cucumber.
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
docker-base-changed:
|
|
description: "Whether the docker base image changed (forwarded from files-changed)."
|
|
required: false
|
|
type: string
|
|
default: "false"
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
docker-compose-tests:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
actions: write
|
|
contents: read
|
|
checks: write
|
|
|
|
steps:
|
|
- name: Harden Runner
|
|
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
|
|
with:
|
|
egress-policy: audit
|
|
|
|
- name: Checkout Repository
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
|
|
- name: Set up JDK 25
|
|
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
|
with:
|
|
java-version: "25"
|
|
distribution: "temurin"
|
|
|
|
- name: Cache Gradle User Home
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: |
|
|
~/.gradle/caches
|
|
~/.gradle/wrapper
|
|
key: gradle-${{ runner.os }}-${{ runner.arch }}-jdk-25-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties', 'gradle/libs.versions.toml', 'settings.gradle', 'build.gradle', 'app/**/build.gradle', 'gradle/**/*.gradle') }}
|
|
restore-keys: |
|
|
gradle-${{ runner.os }}-${{ runner.arch }}-jdk-25-
|
|
gradle-${{ runner.os }}-${{ runner.arch }}-
|
|
|
|
# When the PR changes the base image, test.sh builds it locally
|
|
# (stirling-pdf-base:local) into the daemon image store. A buildx
|
|
# container builder can't see that store, so skip it here and let
|
|
# `docker buildx build` fall back to the default docker driver, which
|
|
# resolves the local base. The gha cache backend is also skipped (its
|
|
# runtime token isn't exposed) since the docker driver can't use it.
|
|
- name: Set up Docker Buildx
|
|
if: inputs.docker-base-changed != 'true'
|
|
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
|
|
|
|
# Expose ACTIONS_RUNTIME_TOKEN / ACTIONS_RESULTS_URL for docker buildx type=gha cache backend.
|
|
- name: Expose GitHub runtime for Buildx cache
|
|
if: inputs.docker-base-changed != 'true'
|
|
uses: crazy-max/ghaction-github-runtime@04d248b84655b509d8c44dc1d6f990c879747487 # v4.0.0
|
|
|
|
- name: Install Docker Compose
|
|
run: |
|
|
sudo curl -SL "https://github.com/docker/compose/releases/download/v2.39.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
|
sudo chmod +x /usr/local/bin/docker-compose
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
with:
|
|
python-version: "3.12"
|
|
cache: "pip" # caching pip dependencies
|
|
cache-dependency-path: ./testing/cucumber/requirements.txt
|
|
|
|
- name: Pip requirements
|
|
run: |
|
|
pip install --require-hashes --only-binary=:all: -r ./testing/cucumber/requirements.txt
|
|
|
|
- name: Extract JaCoCo agent for cucumber coverage
|
|
# Stages build/jacoco/jacocoagent.jar where the coverage override
|
|
# file bind-mounts it into the cucumber container. The agent jar
|
|
# never goes into the published image - this is host-only.
|
|
run: ./gradlew copyJacocoAgent -PnoSpotless
|
|
|
|
- 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
|
|
env:
|
|
MAVEN_USER: ${{ secrets.MAVEN_USER }}
|
|
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
|
|
MAVEN_PUBLIC_URL: ${{ secrets.MAVEN_PUBLIC_URL }}
|
|
DOCKER_BASE_CHANGED: ${{ inputs.docker-base-changed }}
|
|
# Tells test.sh to layer testing/compose/docker-compose-coverage.override.yml
|
|
# over the cucumber compose so the container starts with the
|
|
# JaCoCo agent attached via JAVA_CUSTOM_OPTS.
|
|
STIRLING_PDF_TEST_COVERAGE: "1"
|
|
|
|
- name: Generate cucumber JaCoCo report
|
|
# `if: always()` so a behave failure still produces partial
|
|
# coverage from whatever endpoints did run. The exec file only
|
|
# exists when the container shut down cleanly - guard so the step
|
|
# is silent on the (rare) crash path.
|
|
if: always()
|
|
id: cucumber-coverage
|
|
run: |
|
|
if [ -s testing/cucumber-coverage/cucumber.exec ]; then
|
|
./gradlew jacocoReportFromExec \
|
|
-PexecFile=testing/cucumber-coverage/cucumber.exec \
|
|
-PreportDir=build/reports/jacoco/cucumber \
|
|
-PnoSpotless
|
|
echo "report=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "::warning::No cucumber .exec at testing/cucumber-coverage/cucumber.exec (container may have crashed before flushing)"
|
|
echo "report=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Install defusedxml for coverage summary
|
|
# coverage-summary.py parses JaCoCo XML through defusedxml -
|
|
# see the script header for context.
|
|
if: always() && steps.cucumber-coverage.outputs.report == 'true'
|
|
run: python -m pip install --quiet defusedxml
|
|
|
|
- name: Cucumber coverage step summary
|
|
if: always() && steps.cucumber-coverage.outputs.report == 'true'
|
|
run: |
|
|
python scripts/coverage-summary.py \
|
|
--title "Cucumber (docker) JaCoCo coverage" \
|
|
--jacoco "cucumber=build/reports/jacoco/cucumber/jacocoTestReport.xml" \
|
|
--github-step-summary
|
|
|
|
- name: Upload cucumber JaCoCo report
|
|
if: always() && steps.cucumber-coverage.outputs.report == 'true'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: jacoco-cucumber-${{ github.run_id }}
|
|
path: build/reports/jacoco/cucumber/
|
|
retention-days: 7
|
|
|
|
- name: Upload raw cucumber .exec for aggregate merge
|
|
# Picked up by the coverage-aggregate workflow via the
|
|
# `jacoco-exec-*` artifact name pattern.
|
|
if: always() && steps.cucumber-coverage.outputs.report == 'true'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: jacoco-exec-cucumber
|
|
path: testing/cucumber-coverage/cucumber.exec
|
|
retention-days: 7
|
|
if-no-files-found: warn
|
|
|
|
- name: Upload Cucumber Report
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: cucumber-report
|
|
path: testing/cucumber/report.html
|
|
retention-days: 7
|
|
if-no-files-found: warn
|
|
|
|
- name: Upload Test Reports
|
|
if: always()
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: docker-compose-test-reports
|
|
path: testing/reports/
|
|
retention-days: 7
|
|
if-no-files-found: warn
|
|
|
|
- name: Cucumber Test Report
|
|
if: always()
|
|
uses: dorny/test-reporter@a43b3a5f7366b97d083190328d2c652e1a8b6aa2 # v3.0.0
|
|
with:
|
|
name: Cucumber Tests
|
|
path: testing/cucumber/junit/*.xml
|
|
reporter: java-junit
|
|
fail-on-error: false
|