diff --git a/.github/actions/setup-java-gradle/action.yml b/.github/actions/setup-java-gradle/action.yml new file mode 100644 index 00000000000..8f1f95487d3 --- /dev/null +++ b/.github/actions/setup-java-gradle/action.yml @@ -0,0 +1,147 @@ +name: Setup Java and Gradle +description: Set up Java and trusted Gradle caching for CI jobs + +inputs: + enable-kvm: + description: Whether to enable KVM on Linux + required: false + default: "false" + isolate-gradle-home: + description: Whether to use a run-scoped Gradle user home + required: false + default: "false" + +runs: + using: composite + steps: + - name: Set up JDK 21 + uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0 + with: + java-version: "21" + distribution: temurin + + - name: Configure isolated Gradle user home + if: ${{ inputs.isolate-gradle-home == 'true' }} + shell: bash + run: | # zizmor: ignore[github-env] all path components are supplied by GitHub runner metadata. + gradle_user_home="${RUNNER_TEMP}/gradle-home-${GITHUB_RUN_ID}-${GITHUB_JOB}-${GITHUB_RUN_ATTEMPT}" + echo "GRADLE_USER_HOME=${gradle_user_home}" >> "$GITHUB_ENV" + + - name: Resolve Gradle cache policy + id: cache_policy + shell: bash + env: + EVENT_NAME: ${{ github.event_name }} + REF: ${{ github.ref }} + REPOSITORY: ${{ github.repository }} + PR_BASE_REF: ${{ github.event.pull_request.base.ref }} + PR_HEAD_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name }} + MERGE_GROUP_BASE_REF: ${{ github.event.merge_group.base_ref }} + run: | + enabled=false + read_only=false + + # Only the trusted develop lifecycle can restore or save Gradle state. + if [[ "${EVENT_NAME}" == "push" && "${REF}" == "refs/heads/develop" ]]; then + enabled=true + elif [[ "${EVENT_NAME}" == "pull_request" && + "${PR_BASE_REF}" == "develop" && + "${PR_HEAD_REPOSITORY}" == "${REPOSITORY}" ]]; then + enabled=true + elif [[ "${EVENT_NAME}" == "merge_group" && + "${MERGE_GROUP_BASE_REF}" == "refs/heads/develop" ]]; then + enabled=true + read_only=true + fi + + echo "enabled=${enabled}" >> "$GITHUB_OUTPUT" + echo "read_only=${read_only}" >> "$GITHUB_OUTPUT" + + - name: Detect WarpBuild runner + id: cache_backend + shell: bash + run: | + if [[ -n "${WARPBUILD_RUNNER_VERIFICATION_TOKEN-}" ]]; then + echo "warp=true" >> "$GITHUB_OUTPUT" + else + echo "warp=false" >> "$GITHUB_OUTPUT" + fi + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0 + with: + # Gradle caching is handled exclusively by WarpCache on Warp runners. + # Selecting the basic provider keeps the proprietary provider unloaded. + cache-provider: basic + cache-disabled: true + + - name: Restore and save Warp Gradle state + if: ${{ steps.cache_policy.outputs.enabled == 'true' && steps.cache_policy.outputs.read_only != 'true' && steps.cache_backend.outputs.warp == 'true' }} + uses: WarpBuilds/cache@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 + with: + path: | + ~/.gradle/caches/*/generated-gradle-jars + ~/.gradle/caches/*/kotlin-dsl + ~/.gradle/caches/*/scripts + ~/.gradle/caches/modules-2 + ~/.gradle/caches/transforms-* + ~/.gradle/caches/jars-* + ~/.gradle/wrapper + key: warp-gradle-state-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/gradle.properties', '**/*.versions.toml', '**/buildSrc/**/*.kt', '**/build-logic/**/*.kt') }} + restore-keys: | + warp-gradle-state-${{ runner.os }}-${{ runner.arch }}- + + - name: Restore read-only Warp Gradle state + if: ${{ steps.cache_policy.outputs.enabled == 'true' && steps.cache_policy.outputs.read_only == 'true' && steps.cache_backend.outputs.warp == 'true' }} + uses: WarpBuilds/cache/restore@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 + with: + path: | + ~/.gradle/caches/*/generated-gradle-jars + ~/.gradle/caches/*/kotlin-dsl + ~/.gradle/caches/*/scripts + ~/.gradle/caches/modules-2 + ~/.gradle/caches/transforms-* + ~/.gradle/caches/jars-* + ~/.gradle/wrapper + key: warp-gradle-state-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/gradle.properties', '**/*.versions.toml', '**/buildSrc/**/*.kt', '**/build-logic/**/*.kt') }} + restore-keys: | + warp-gradle-state-${{ runner.os }}-${{ runner.arch }}- + + - name: Restore and save Warp Gradle task outputs + if: ${{ steps.cache_policy.outputs.enabled == 'true' && steps.cache_policy.outputs.read_only != 'true' && steps.cache_backend.outputs.warp == 'true' }} + uses: WarpBuilds/cache@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 + with: + path: ~/.gradle/caches/build-cache-* + key: warp-gradle-build-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/gradle.properties', '**/*.versions.toml', '**/buildSrc/**/*.kt', '**/build-logic/**/*.kt') }}-${{ github.sha }} + restore-keys: | + warp-gradle-build-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/gradle.properties', '**/*.versions.toml', '**/buildSrc/**/*.kt', '**/build-logic/**/*.kt') }}- + warp-gradle-build-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- + + - name: Restore read-only Warp Gradle task outputs + if: ${{ steps.cache_policy.outputs.enabled == 'true' && steps.cache_policy.outputs.read_only == 'true' && steps.cache_backend.outputs.warp == 'true' }} + uses: WarpBuilds/cache/restore@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 + with: + path: ~/.gradle/caches/build-cache-* + key: warp-gradle-build-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/gradle.properties', '**/*.versions.toml', '**/buildSrc/**/*.kt', '**/build-logic/**/*.kt') }}-${{ github.sha }} + restore-keys: | + warp-gradle-build-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/gradle.properties', '**/*.versions.toml', '**/buildSrc/**/*.kt', '**/build-logic/**/*.kt') }}- + warp-gradle-build-${{ runner.os }}-${{ runner.arch }}-${{ github.job }}- + + - name: Enable Gradle build cache + if: ${{ steps.cache_policy.outputs.enabled == 'true' && steps.cache_backend.outputs.warp == 'true' }} + shell: bash + run: | # zizmor: ignore[github-env] line breaks are rejected before the trusted value is preserved. + if [[ "${GRADLE_OPTS-}" == *$'\n'* || "${GRADLE_OPTS-}" == *$'\r'* ]]; then + echo "::error::GRADLE_OPTS must not contain line breaks" + exit 1 + fi + gradle_opts="${GRADLE_OPTS:+${GRADLE_OPTS} }-Dorg.gradle.caching=true" + printf 'GRADLE_OPTS=%s\n' "${gradle_opts}" >> "$GITHUB_ENV" + + - name: Enable KVM + if: ${{ inputs.enable-kvm == 'true' && runner.os == 'Linux' }} + shell: bash + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm diff --git a/.github/workflows/build-unified.yml b/.github/workflows/build-unified.yml index c83a73190df..c51d9bd321c 100644 --- a/.github/workflows/build-unified.yml +++ b/.github/workflows/build-unified.yml @@ -74,7 +74,6 @@ jobs: name: Lint needs: [workflow-security] runs-on: warp-ubuntu-2404-x64-8x - # Override JVM args from gradle.properties which sets 10GB heap steps: - name: Checkout uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 @@ -82,24 +81,9 @@ jobs: persist-credentials: false submodules: recursive # Needed in order to fetch Kalium sources for building fetch-depth: 1 # Keep the large Kalium submodule checkout shallow - - name: Set up JDK 21 - uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0 - with: - java-version: '21' - distribution: 'temurin' - - uses: WarpBuilds/cache@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Validate Gradle wrapper - uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0 + - name: Set up Java and Gradle + uses: ./.github/actions/setup-java-gradle - name: Run Linter - env: - GRADLE_OPTS: "-Xmx6G -XX:+UseParallelGC -XX:MaxMetaspaceSize=2g" run: make lint - name: Cleanup Gradle Cache # Remove some files from the Gradle cache, so they aren't cached by GitHub Actions. @@ -119,21 +103,8 @@ jobs: persist-credentials: false submodules: recursive # Needed in order to fetch Kalium sources for building fetch-depth: 1 # Keep the large Kalium submodule checkout shallow - - name: Set up JDK 21 - uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0 - with: - java-version: '21' - distribution: 'temurin' - - uses: WarpBuilds/cache@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Validate Gradle wrapper - uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0 + - name: Set up Java and Gradle + uses: ./.github/actions/setup-java-gradle - name: Run Detekt run: make style - name: Cleanup Gradle Cache @@ -154,24 +125,9 @@ jobs: persist-credentials: false submodules: recursive # Needed in order to fetch Kalium sources for building fetch-depth: 1 # Keep the large Kalium submodule checkout shallow - - name: Set up JDK 21 - uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0 - with: - java-version: '21' - distribution: 'temurin' - - uses: WarpBuilds/cache@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Validate Gradle wrapper - uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0 + - name: Set up Java and Gradle + uses: ./.github/actions/setup-java-gradle - name: Run Compose stability check - env: - GRADLE_OPTS: "-Xmx6G -XX:+UseParallelGC -XX:MaxMetaspaceSize=2g" run: make compose-stability - name: Cleanup Gradle Cache # Remove some files from the Gradle cache, so they aren't cached by GitHub Actions. @@ -224,12 +180,8 @@ jobs: submodules: recursive fetch-depth: 1 # Keep the large Kalium submodule checkout shallow - - name: Set up JDK 21 - uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0 - with: - java-version: '21' - distribution: 'temurin' - cache: gradle + - name: Set up Java and Gradle + uses: ./.github/actions/setup-java-gradle - name: Setup Keystore uses: ./.github/actions/setup-keystore diff --git a/.github/workflows/generate-baseline-profile.yml b/.github/workflows/generate-baseline-profile.yml index f954d80ef8e..55a68359e9b 100644 --- a/.github/workflows/generate-baseline-profile.yml +++ b/.github/workflows/generate-baseline-profile.yml @@ -44,15 +44,10 @@ jobs: fetch-depth: 1 # Keep the large Kalium submodule checkout shallow submodules: recursive - - name: Set up Java 21 - uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5 + - name: Set up Java and Gradle + uses: ./.github/actions/setup-java-gradle with: - distribution: temurin - java-version: "21" - cache: gradle - - - name: Validate Gradle wrapper - uses: gradle/actions/wrapper-validation@3f131e8634966bd73d06cc69884922b02e6faf92 # v6 + isolate-gradle-home: true - name: Set up Android SDK uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4 @@ -120,3 +115,8 @@ jobs: app/src/main/baseline-prof.txt app/src/main/startup-prof.txt delete-branch: false + + - name: Stop isolated Gradle daemons + if: always() + continue-on-error: true + run: ./gradlew --stop diff --git a/.github/workflows/generate-screenshots.yml b/.github/workflows/generate-screenshots.yml index f02125701d4..213706c7c47 100644 --- a/.github/workflows/generate-screenshots.yml +++ b/.github/workflows/generate-screenshots.yml @@ -25,23 +25,8 @@ jobs: - name: Checkout Kalium submodule run: git submodule update --init --recursive --depth=1 - - name: Set up JDK 21 - uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5 - with: - java-version: '21' - distribution: 'temurin' - - - uses: WarpBuilds/cache@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - - name: Validate Gradle wrapper - uses: gradle/actions/wrapper-validation@3f131e8634966bd73d06cc69884922b02e6faf92 # v6 + - name: Set up Java and Gradle + uses: ./.github/actions/setup-java-gradle - name: Install Git LFS run: | diff --git a/.github/workflows/gradle-run-ui-tests.yml b/.github/workflows/gradle-run-ui-tests.yml index 933f87f048c..e2b9406adca 100644 --- a/.github/workflows/gradle-run-ui-tests.yml +++ b/.github/workflows/gradle-run-ui-tests.yml @@ -40,29 +40,10 @@ jobs: echo "Disk space after cleanup:" df -h - - name: Set up JDK 21 - uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5 + - name: Set up Java and Gradle + uses: ./.github/actions/setup-java-gradle with: - java-version: '21' - distribution: 'temurin' - - - uses: WarpBuilds/cache@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - - name: Validate Gradle wrapper - uses: gradle/actions/wrapper-validation@3f131e8634966bd73d06cc69884922b02e6faf92 # v6 - - - name: Enable KVM group perms - run: | - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm + enable-kvm: true - name: AVD cache uses: WarpBuilds/cache@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 diff --git a/.github/workflows/gradle-run-unit-tests.yml b/.github/workflows/gradle-run-unit-tests.yml index 14c2c8232b4..0d28b0102e8 100644 --- a/.github/workflows/gradle-run-unit-tests.yml +++ b/.github/workflows/gradle-run-unit-tests.yml @@ -28,21 +28,8 @@ jobs: submodules: recursive # Needed in order to fetch Kalium sources for building fetch-depth: 1 # Keep the large Kalium submodule checkout shallow - - name: Set up JDK 21 - uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5 - with: - java-version: '21' - distribution: 'temurin' - - uses: WarpBuilds/cache@40f3443ae7b70e568d6e2070ea897f3df94d7553 # v1 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - name: Validate Gradle wrapper - uses: gradle/actions/wrapper-validation@3f131e8634966bd73d06cc69884922b02e6faf92 # v6 + - name: Set up Java and Gradle + uses: ./.github/actions/setup-java-gradle - name: Test Build Logic run: make unit-tests/build-logic diff --git a/.github/workflows/qa-android-critical-flow-tests.yml b/.github/workflows/qa-android-critical-flow-tests.yml index 674889f073b..7873be48765 100644 --- a/.github/workflows/qa-android-critical-flow-tests.yml +++ b/.github/workflows/qa-android-critical-flow-tests.yml @@ -261,12 +261,10 @@ jobs: submodules: recursive persist-credentials: false - - name: Set up Java 21 - uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5 + - name: Set up Java and Gradle + uses: ./.github/actions/setup-java-gradle with: - distribution: temurin - java-version: "21" - cache: gradle + isolate-gradle-home: true - name: Set up Android SDK (ANDROID_HOME + adb) uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4 @@ -548,3 +546,8 @@ jobs: ALLURE_RESULTS_MERGED_DIR: ${{ runner.temp }}/allure-results-merged ALLURE_REPORT_DIR: ${{ runner.temp }}/allure-report run: make qa-ui-report cmd=cleanup-workspace + + - name: Stop isolated Gradle daemons + if: always() + continue-on-error: true + run: ./gradlew --stop diff --git a/.github/workflows/qa-android-ui-test-manual-deflake.yml b/.github/workflows/qa-android-ui-test-manual-deflake.yml index 08ebdbcba36..85b0e0ab0f2 100644 --- a/.github/workflows/qa-android-ui-test-manual-deflake.yml +++ b/.github/workflows/qa-android-ui-test-manual-deflake.yml @@ -105,12 +105,10 @@ jobs: submodules: recursive persist-credentials: false - - name: Set up Java 21 - uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5 + - name: Set up Java and Gradle + uses: ./.github/actions/setup-java-gradle with: - distribution: temurin - java-version: "21" - cache: gradle + isolate-gradle-home: true - name: Set up Android SDK (ANDROID_HOME + adb) uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4 @@ -400,3 +398,8 @@ jobs: ALLURE_RESULTS_MERGED_DIR: ${{ runner.temp }}/allure-results-merged ALLURE_REPORT_DIR: ${{ runner.temp }}/allure-report run: make qa-ui-report cmd=cleanup-workspace + + - name: Stop isolated Gradle daemons + if: always() + continue-on-error: true + run: ./gradlew --stop