This is an automated email from the ASF dual-hosted git repository.

jamesfredley pushed a commit to branch perf/8.0.x-ci-wall-clock-regression
in repository https://gitbox.apache.org/repos/asf/grails-core.git

commit 57a387c0325712b395d76520f138b06a9656dd69
Author: James Fredley <[email protected]>
AuthorDate: Fri Aug 7 22:00:50 2026 -0400

    Parallelize critical CI test workloads
    
    Split Groovy Joint validation across three deterministic test shards and
    the Windows JDK 25 core build across two shards while retaining one complete
    build in shard zero. Restore dependency-only caches in every shard and allow
    only full-build jobs to save them.
    
    Assisted-by: opencode:gpt-5.6-sol
---
 .github/workflows/gradle.yml                | 35 +++++++++++++++++++++++---
 .github/workflows/groovy-joint-workflow.yml | 39 ++++++++++++++++++++++++++---
 2 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index 253e6dd314..09eadf1994 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -123,19 +123,38 @@ jobs:
           -PskipCodeStyle
   build:
     if: ${{ !contains(github.event.head_commit.message, '[skip tests]') }}
-    name: 'Build Grails-Core'
+    name: 'Build Grails-Core (${{ matrix.job_name }})'
     strategy:
       fail-fast: false
       matrix:
         include:
           - os: ubuntu-latest
             java: 21
+            job_name: Ubuntu JDK 21
+            gradle_task: 'build :grails-shell-cli:installDist groovydoc'
+            cache_writer: true
           - os: ubuntu-latest
             java: 25
+            job_name: Ubuntu JDK 25
+            gradle_task: 'build :grails-shell-cli:installDist groovydoc'
+            cache_writer: false
           - os: macos-latest
             java: 21
+            job_name: macOS JDK 21
+            gradle_task: 'build :grails-shell-cli:installDist groovydoc'
+            cache_writer: true
           - os: windows-latest
             java: 25
+            job_name: Windows JDK 25 shard 0
+            gradle_task: 'build :grails-shell-cli:installDist groovydoc'
+            shard_arguments: '-PtestShardCount=2 -PtestShardIndex=0'
+            cache_writer: true
+          - os: windows-latest
+            java: 25
+            job_name: Windows JDK 25 shard 1
+            gradle_task: testShard
+            shard_arguments: '-PtestShardCount=2 -PtestShardIndex=1'
+            cache_writer: false
     runs-on: ${{ matrix.os }}
     steps:
       - name: "Output Agent IP" # in the event RAO blocks this agent, this can 
be used to debug it
@@ -148,7 +167,8 @@ jobs:
           distribution: liberica
           java-version: ${{ matrix.java }}
       - name: "🗄️ Restore dependency jar cache"
-        uses: actions/cache@v4
+        id: dependency-cache
+        uses: actions/cache/restore@v4
         with:
           # Cache only downloaded dependency jars and wrapper distributions, 
never Grails build outputs.
           # Keyed by branch version so each release branch maintains its own 
warm cache.
@@ -172,11 +192,20 @@ jobs:
         # and included automatically on JDK 25+. So the Java 21 entries build 
everything
         # except the island and the Java 25 entries build the full graph - no 
flag needed.
         run: >
-          ./gradlew build :grails-shell-cli:installDist groovydoc
+          ./gradlew ${{ matrix.gradle_task }}
           --continue
           --stacktrace
           -PonlyCoreTests
           -PskipCodeStyle
+          ${{ matrix.shard_arguments }}
+      - name: "🗄️ Save dependency jar cache"
+        if: ${{ success() && matrix.cache_writer && 
steps.dependency-cache.outputs.cache-hit != 'true' }}
+        uses: actions/cache/save@v4
+        with:
+          path: |
+            ~/.gradle/caches/modules-2
+            ~/.gradle/wrapper
+          key: gradle-deps-${{ runner.os }}-${{ github.base_ref || 
github.ref_name }}-${{ hashFiles('**/dependencies.gradle', 
'**/gradle-wrapper.properties') }}
   buildRerunTasks:
     if: ${{ !contains(github.event.head_commit.message, '[skip tests]') }}
     name: 'Build Grails-Core Rerunning all Tasks'
diff --git a/.github/workflows/groovy-joint-workflow.yml 
b/.github/workflows/groovy-joint-workflow.yml
index fb4e801918..0a60223549 100644
--- a/.github/workflows/groovy-joint-workflow.yml
+++ b/.github/workflows/groovy-joint-workflow.yml
@@ -102,6 +102,17 @@ jobs:
           retention-days: 1
   build_grails:
     needs: [build_groovy]
+    name: "Build Grails with Groovy snapshot (shard ${{ matrix.shard_index }})"
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - shard_index: 0
+            gradle_task: build
+          - shard_index: 1
+            gradle_task: testShard
+          - shard_index: 2
+            gradle_task: testShard
     runs-on: ubuntu-latest
     services:
       mongodb:
@@ -133,10 +144,22 @@ jobs:
         with:
           java-version: 21
           distribution: liberica
+      - name: "🗄️ Restore dependency jar cache"
+        id: dependency-cache
+        uses: actions/cache/restore@v4
+        with:
+          # Cache only downloaded dependency jars and wrapper distributions, 
never Grails build outputs.
+          # Keyed by branch version so each release branch maintains its own 
warm cache.
+          path: |
+            ~/.gradle/caches/modules-2
+            ~/.gradle/wrapper
+          key: gradle-deps-${{ runner.os }}-${{ github.base_ref || 
github.ref_name }}-${{ hashFiles('**/dependencies.gradle', 
'**/gradle-wrapper.properties') }}
+          restore-keys: |
+            gradle-deps-${{ runner.os }}-${{ github.base_ref || 
github.ref_name }}-
       - name: "🐘 Setup Gradle"
         uses: 
gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
         with:
-          cache-disabled: true # this workflow rebuilds Groovy each run; a 
Gradle home cache is not useful here
+          cache-disabled: true # dependency jars are cached by the explicit 
branch-keyed step above
           develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY  }}
       - name: "🔍 Setup TestLens"
         uses: 
testlens-app/setup-testlens@3f82d2dc6cd5c03f02ce5f7885a21195d85f8d14 # v1.9.3
@@ -155,12 +178,22 @@ jobs:
         # which is incompatible with the Groovy 4.x snapshot this job swaps in 
above.
         # See https://github.com/apache/grails-core/issues/15613.
         run: >
-          ./gradlew build
+          ./gradlew ${{ matrix.gradle_task }}
           --continue
           --stacktrace
           -x groovydoc
           -PskipCodeStyle
           -PskipMicronautProjects
           -PmaxTestParallel=3
+          -PtestShardCount=3
+          -PtestShardIndex=${{ matrix.shard_index }}
         env:
-          GRAILS_INCLUDE_MAVEN_LOCAL: true
\ No newline at end of file
+          GRAILS_INCLUDE_MAVEN_LOCAL: true
+      - name: "🗄️ Save dependency jar cache"
+        if: ${{ success() && matrix.shard_index == 0 && 
steps.dependency-cache.outputs.cache-hit != 'true' }}
+        uses: actions/cache/save@v4
+        with:
+          path: |
+            ~/.gradle/caches/modules-2
+            ~/.gradle/wrapper
+          key: gradle-deps-${{ runner.os }}-${{ github.base_ref || 
github.ref_name }}-${{ hashFiles('**/dependencies.gradle', 
'**/gradle-wrapper.properties') }}

Reply via email to