From d4301132945558a4dcb12a3df61c02496018c1fb Mon Sep 17 00:00:00 2001 From: Jesper Terkelsen Date: Thu, 4 Jun 2026 22:28:45 +0200 Subject: [PATCH] ci(pull-request-kotlin): persist Gradle build-cache across runs via split restore/save [NO-JIRA] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test job recompiled (~150s of KSP + Kotlin, main+test) on every run. Dependencies were cached, but setup-java's built-in 'gradle' cache keys on the gradle files and only saves on a cache MISS — so Gradle's build-cache (compiled task output) froze at first save and never accumulated, leaving every run to recompile from scratch. Switch to the split restore/save pattern and save on every run under a per-commit key, so the build-cache persists and unchanged KSP/Kotlin output returns FROM-CACHE instead of recompiling. The Sonar cache had the same freeze-on-fixed-key problem and gets the same treatment. Cache key is branch-scoped with a shared fallback: a PR restores its own branch's latest cache first (closest source -> best build-cache hit rate), else the most recent run. Caches are isolated per repository automatically (GitHub + runs-on), so no repo name is needed in the key. Saves run on always() so compiled output is cached even when tests fail. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/pull-request-kotlin.yml | 37 ++++++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pull-request-kotlin.yml b/.github/workflows/pull-request-kotlin.yml index 6ca4a46..7b896af 100644 --- a/.github/workflows/pull-request-kotlin.yml +++ b/.github/workflows/pull-request-kotlin.yml @@ -90,14 +90,27 @@ jobs: with: distribution: corretto java-version: ${{ inputs.java-version }} - cache: 'gradle' - - name: Cache SonarCloud packages - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + - name: Restore Gradle cache + id: gradle-cache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ github.head_ref }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-gradle-${{ github.head_ref }}- + ${{ runner.os }}-gradle- + - name: Restore SonarCloud cache + id: sonar-cache if: ${{ !inputs.skip-sonar }} + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: ~/.sonar/cache - key: ${{ runner.os }}-sonar - restore-keys: ${{ runner.os }}-sonar + key: ${{ runner.os }}-sonar-${{ github.head_ref }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-sonar-${{ github.head_ref }}- + ${{ runner.os }}-sonar- - name: Run linter env: GHL_USERNAME: ${{ secrets.GHL_USERNAME }} @@ -158,3 +171,17 @@ jobs: **/build/test-results/**/*.xml **/build/test-results/**/*.trx **/build/test-results/**/*.json + - name: Save Gradle cache + if: ${{ always() && steps.gradle-cache.outputs.cache-hit != 'true' }} + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ github.head_ref }}-${{ github.sha }} + - name: Save SonarCloud cache + if: ${{ always() && !inputs.skip-sonar && steps.sonar-cache.outputs.cache-hit != 'true' }} + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar-${{ github.head_ref }}-${{ github.sha }}