From 15f88c73490b02fcb11ef63702435590cb9a0165 Mon Sep 17 00:00:00 2001 From: denis0001-dev Date: Mon, 14 Sep 2026 14:41:47 +0300 Subject: [PATCH] Fix Gradle build directory cache for UP-TO-DATE incremental builds. Cache project .gradle/ and root build/ (execution history + outputs), restore git mtimes after checkout, skip set-version when unchanged, and bump cache keys to v2 with build-jar restore fallback. Co-authored-by: Cursor --- .github/actions/cache-gradle-build/action.yml | 10 ++++-- .github/actions/restore-git-mtimes/action.yml | 12 +++++++ .../save-gradle-build-cache/action.yml | 4 ++- .github/actions/set-version/action.yml | 6 ++++ .github/workflows/release.yml | 34 +++++++++++-------- 5 files changed, 48 insertions(+), 18 deletions(-) create mode 100644 .github/actions/restore-git-mtimes/action.yml diff --git a/.github/actions/cache-gradle-build/action.yml b/.github/actions/cache-gradle-build/action.yml index e814245..73a01e4 100644 --- a/.github/actions/cache-gradle-build/action.yml +++ b/.github/actions/cache-gradle-build/action.yml @@ -1,5 +1,5 @@ name: Restore Gradle build directories -description: Restore module build/ trees for faster CI Gradle jobs +description: Restore project .gradle/, build/ trees for faster CI Gradle jobs inputs: scope: @@ -21,11 +21,15 @@ runs: id: cache with: path: | + .gradle + build app/desktop/build app/shared/build app/android/build utils/shared/build utils/android/build - key: gradle-build-${{ runner.os }}-${{ runner.arch }}-v1-${{ inputs.scope }}-${{ hashFiles('gradle/libs.versions.toml', 'settings.gradle.kts', 'gradle.properties', 'app/desktop/build.gradle.kts', 'app/desktop/proguard-rules.pro', 'app/shared/build.gradle.kts', 'app/android/build.gradle.kts', 'utils/shared/build.gradle.kts', 'utils/android/build.gradle.kts') }} + key: gradle-build-${{ runner.os }}-${{ runner.arch }}-v2-${{ inputs.scope }}-${{ hashFiles('gradle/libs.versions.toml', 'settings.gradle.kts', 'gradle.properties', 'build.gradle.kts', 'app/desktop/build.gradle.kts', 'app/desktop/proguard-rules.pro', 'app/shared/build.gradle.kts', 'app/android/build.gradle.kts', 'utils/shared/build.gradle.kts', 'utils/android/build.gradle.kts') }} restore-keys: | - gradle-build-${{ runner.os }}-${{ runner.arch }}-v1- + gradle-build-${{ runner.os }}-${{ runner.arch }}-v2-${{ inputs.scope }}- + gradle-build-${{ runner.os }}-${{ runner.arch }}-v2-build-jar- + gradle-build-${{ runner.os }}-${{ runner.arch }}-v2- diff --git a/.github/actions/restore-git-mtimes/action.yml b/.github/actions/restore-git-mtimes/action.yml new file mode 100644 index 0000000..e6dadea --- /dev/null +++ b/.github/actions/restore-git-mtimes/action.yml @@ -0,0 +1,12 @@ +name: Restore git mtimes +description: Reset tracked file timestamps from git so Gradle incremental builds can be UP-TO-DATE after checkout + +runs: + using: composite + steps: + - name: Restore mtimes + shell: bash + run: | + set -euo pipefail + python3 -m pip install --disable-pip-version-check --quiet git-restore-mtime + python3 -m git_restore_mtime diff --git a/.github/actions/save-gradle-build-cache/action.yml b/.github/actions/save-gradle-build-cache/action.yml index 4c345ff..2e50405 100644 --- a/.github/actions/save-gradle-build-cache/action.yml +++ b/.github/actions/save-gradle-build-cache/action.yml @@ -1,5 +1,5 @@ name: Save Gradle build directories -description: Save module build/ trees after a Gradle build +description: Save project .gradle/, build/ trees after a Gradle build inputs: primary-key: @@ -14,6 +14,8 @@ runs: with: key: ${{ inputs.primary-key }} path: | + .gradle + build app/desktop/build app/shared/build app/android/build diff --git a/.github/actions/set-version/action.yml b/.github/actions/set-version/action.yml index c5d1ebf..7500b45 100644 --- a/.github/actions/set-version/action.yml +++ b/.github/actions/set-version/action.yml @@ -18,6 +18,12 @@ runs: VERSION_CODE=1 fi GRADLE_FILE="build.gradle.kts" + CURRENT_NAME="$(sed -n 's/.*extra\["versionName"\] = "\([^"]*\)".*/\1/p' "$GRADLE_FILE" | head -n 1)" + CURRENT_CODE="$(sed -n 's/.*extra\["versionCode"\] = \([0-9]*\).*/\1/p' "$GRADLE_FILE" | head -n 1)" + if [[ "$CURRENT_NAME" == "$VERSION" && "$CURRENT_CODE" == "$VERSION_CODE" ]]; then + echo "versionName=$VERSION versionCode=$VERSION_CODE (unchanged)" + exit 0 + fi sed -i.bak "s/extra\\[\"versionName\"\\] = \"[^\"]*\"/extra[\"versionName\"] = \"$VERSION\"/" "$GRADLE_FILE" sed -i.bak "s/extra\\[\"versionCode\"\\] = [0-9]*/extra[\"versionCode\"] = $VERSION_CODE/" "$GRADLE_FILE" rm -f "$GRADLE_FILE.bak" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 066ca42..b12edb0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -80,10 +80,11 @@ jobs: FROMCHAT_PREBUILT_PROGUARD: "0" steps: - uses: actions/checkout@v5 - - uses: ./.github/actions/setup-java-gradle + - uses: ./.github/actions/restore-git-mtimes - uses: ./.github/actions/set-version with: version: ${{ needs.resolve-version.outputs.version }} + - uses: ./.github/actions/setup-java-gradle - uses: ./.github/actions/cache-gradle-build id: gradle-build-cache with: @@ -108,10 +109,11 @@ jobs: timeout-minutes: 30 steps: - uses: actions/checkout@v5 - - uses: ./.github/actions/setup-java-gradle + - uses: ./.github/actions/restore-git-mtimes - uses: ./.github/actions/set-version with: version: ${{ needs.resolve-version.outputs.version }} + - uses: ./.github/actions/setup-java-gradle - uses: ./.github/actions/cache-gradle-build id: gradle-build-cache with: @@ -164,6 +166,10 @@ jobs: timeout-minutes: 60 steps: - uses: actions/checkout@v5 + - uses: ./.github/actions/restore-git-mtimes + - uses: ./.github/actions/set-version + with: + version: ${{ needs.resolve-version.outputs.version }} - name: Ensure ARM64 packaging JDK if: matrix.arch == 'arm64' shell: cmd @@ -178,9 +184,6 @@ jobs: gradle-version: wrapper cache-read-only: true add-job-summary: on-failure - - uses: ./.github/actions/set-version - with: - version: ${{ needs.resolve-version.outputs.version }} - uses: ./.github/actions/cache-gradle-build id: gradle-build-cache with: @@ -237,6 +240,10 @@ jobs: timeout-minutes: 60 steps: - uses: actions/checkout@v5 + - uses: ./.github/actions/restore-git-mtimes + - uses: ./.github/actions/set-version + with: + version: ${{ needs.resolve-version.outputs.version }} - uses: ./.github/actions/setup-java-gradle if: matrix.arch == 'x64' with: @@ -246,9 +253,6 @@ jobs: if: matrix.arch == 'arm64' with: cache-read-only: "true" - - uses: ./.github/actions/set-version - with: - version: ${{ needs.resolve-version.outputs.version }} - uses: ./.github/actions/cache-gradle-build id: gradle-build-cache with: @@ -310,12 +314,13 @@ jobs: timeout-minutes: 45 steps: - uses: actions/checkout@v5 - - uses: ./.github/actions/setup-java-gradle - with: - cache-read-only: "true" + - uses: ./.github/actions/restore-git-mtimes - uses: ./.github/actions/set-version with: version: ${{ needs.resolve-version.outputs.version }} + - uses: ./.github/actions/setup-java-gradle + with: + cache-read-only: "true" - uses: ./.github/actions/cache-gradle-build id: gradle-build-cache with: @@ -361,13 +366,14 @@ jobs: timeout-minutes: 60 steps: - uses: actions/checkout@v5 + - uses: ./.github/actions/restore-git-mtimes + - uses: ./.github/actions/set-version + with: + version: ${{ needs.resolve-version.outputs.version }} - uses: ./.github/actions/setup-java-gradle with: cache-read-only: "true" - uses: android-actions/setup-android@v4 - - uses: ./.github/actions/set-version - with: - version: ${{ needs.resolve-version.outputs.version }} - uses: ./.github/actions/cache-gradle-build id: gradle-build-cache with: