diff --git a/.github/actions/cache-gradle-build/action.yml b/.github/actions/cache-gradle-build/action.yml index 6a64d0b..e814245 100644 --- a/.github/actions/cache-gradle-build/action.yml +++ b/.github/actions/cache-gradle-build/action.yml @@ -1,6 +1,11 @@ name: Restore Gradle build directories description: Restore module build/ trees for faster CI Gradle jobs +inputs: + scope: + description: Unique id for this job (part of the cache key; use restore-keys to reuse other scopes) + required: true + outputs: cache-hit: description: Whether an exact cache key match was restored @@ -21,6 +26,6 @@ runs: app/android/build utils/shared/build utils/android/build - key: gradle-build-${{ runner.os }}-${{ runner.arch }}-v1-${{ 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 }}-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') }} restore-keys: | gradle-build-${{ runner.os }}-${{ runner.arch }}-v1- diff --git a/.github/actions/save-gradle-build-cache/action.yml b/.github/actions/save-gradle-build-cache/action.yml index 0e96563..4c345ff 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 (always runs, even on cache hit) +description: Save module build/ trees after a Gradle build inputs: primary-key: @@ -10,6 +10,7 @@ runs: using: composite steps: - uses: actions/cache/save@v5 + continue-on-error: true with: key: ${{ inputs.primary-key }} path: | diff --git a/.github/actions/setup-java-gradle/action.yml b/.github/actions/setup-java-gradle/action.yml index d03afbd..3df13e8 100644 --- a/.github/actions/setup-java-gradle/action.yml +++ b/.github/actions/setup-java-gradle/action.yml @@ -6,6 +6,10 @@ inputs: description: Optional JDK architecture (x64). Omit for host default. required: false default: "" + cache-read-only: + description: Restore Gradle User Home only; do not save (avoids parallel cache write races). + required: false + default: "false" runs: using: composite @@ -19,6 +23,6 @@ runs: - uses: gradle/actions/setup-gradle@v5 with: gradle-version: wrapper - cache-read-only: false + cache-read-only: ${{ inputs.cache-read-only == 'true' }} cache-overwrite-existing: true add-job-summary: on-failure diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ccfeeab..c39c616 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -86,6 +86,8 @@ jobs: version: ${{ needs.resolve-version.outputs.version }} - uses: ./.github/actions/cache-gradle-build id: gradle-build-cache + with: + scope: build-jar - name: Compile and ProGuard release desktop jars run: ./gradlew :app:desktop:exportReleaseProguardForCi --no-daemon --console=plain - uses: ./.github/actions/save-gradle-build-cache @@ -112,6 +114,8 @@ jobs: version: ${{ needs.resolve-version.outputs.version }} - uses: ./.github/actions/cache-gradle-build id: gradle-build-cache + with: + scope: windows-installer - uses: dtolnay/rust-toolchain@stable with: targets: x86_64-pc-windows-msvc @@ -166,15 +170,21 @@ jobs: run: call scripts\ensure-windows-arm64-jdk.cmd - uses: ./.github/actions/setup-java-gradle if: matrix.arch == 'x64' + with: + cache-read-only: "true" - uses: gradle/actions/setup-gradle@v5 if: matrix.arch == 'arm64' with: 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: + scope: windows-package-${{ matrix.arch }} - uses: actions/download-artifact@v5 with: name: desktop-proguard @@ -205,6 +215,10 @@ jobs: name: windows-${{ matrix.arch }} path: app/desktop/build/distributions/release/*-windows-${{ matrix.arch }}.exe if-no-files-found: error + - uses: ./.github/actions/save-gradle-build-cache + if: always() + with: + primary-key: ${{ steps.gradle-build-cache.outputs.cache-primary-key }} macos: name: macOS (${{ matrix.label }}) @@ -227,13 +241,18 @@ jobs: if: matrix.arch == 'x64' with: java-architecture: x64 + cache-read-only: "true" - uses: ./.github/actions/setup-java-gradle 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: + scope: macos-${{ matrix.arch }} - uses: actions/download-artifact@v5 with: name: desktop-proguard @@ -266,7 +285,7 @@ jobs: path: app/desktop/build/distributions/release/*-macOS-${{ matrix.arch }}.dmg if-no-files-found: error - uses: ./.github/actions/save-gradle-build-cache - if: always() && matrix.arch == 'arm64' + if: always() with: primary-key: ${{ steps.gradle-build-cache.outputs.cache-primary-key }} @@ -292,11 +311,15 @@ jobs: steps: - uses: actions/checkout@v5 - uses: ./.github/actions/setup-java-gradle + 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: + scope: linux-${{ matrix.arch }} - uses: actions/download-artifact@v5 with: name: desktop-proguard @@ -327,7 +350,7 @@ jobs: app/desktop/build/distributions/release/*-linux-${{ matrix.arch }}.AppImage if-no-files-found: error - uses: ./.github/actions/save-gradle-build-cache - if: always() && matrix.arch == 'arm64' + if: always() with: primary-key: ${{ steps.gradle-build-cache.outputs.cache-primary-key }} @@ -339,11 +362,16 @@ jobs: steps: - uses: actions/checkout@v5 - 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: + scope: android - name: Cache Android SDK extras uses: actions/cache@v5 with: @@ -379,6 +407,10 @@ jobs: printf '%s' "$GOOGLE_SERVICES_JSON" | base64 -d > app/android/google-services.json - name: Build universal Android APK run: ./gradlew :app:android:assembleRelease --no-daemon --console=plain + - uses: ./.github/actions/save-gradle-build-cache + if: always() + with: + primary-key: ${{ steps.gradle-build-cache.outputs.cache-primary-key }} - name: Stage APK run: | mkdir -p release-staging