diff --git a/.github/workflows/experiment-with-gradle-profiler.yaml b/.github/workflows/experiment-with-gradle-profiler.yaml index a1aa1e7..194d491 100644 --- a/.github/workflows/experiment-with-gradle-profiler.yaml +++ b/.github/workflows/experiment-with-gradle-profiler.yaml @@ -31,6 +31,31 @@ on: required: false type: boolean default: true + configuration_cache: + description: "Gradle configuration cache behavior" + type: choice + required: false + default: 'off' + options: + - 'off' + - 'disabled' + - 'on' + - 'on-no-entry' + - 'warn' + - 'warn-no-entry' + - 'read-only' + - 'read-only-no-entry' + project_isolation: + description: "Gradle Isolated Projects behavior" + type: choice + required: false + default: 'off' + options: + - 'off' + - 'on' + - 'on-no-entry' + - 'diagnostics' + - 'diagnostics-no-entry' os_args: description: "Operating system configurations for variants" type: string @@ -91,6 +116,8 @@ jobs: experiment-id: "profiler-${{ github.repository_owner }}-${{ github.run_number }}" variant: ${{ matrix.config.variant }} class: ${{ github.event.inputs.class }} + configuration-cache: "${{ github.event.inputs.configuration_cache }}" + project-isolation: "${{ github.event.inputs.project_isolation }}" cache-url: ${{ secrets.CI_URL_CACHE_NODE }} warmups: 1 clean-between-iterations: ${{ github.event.inputs.clean_between_iterations }} diff --git a/.github/workflows/experiment.yaml b/.github/workflows/experiment.yaml index a4c17ad..e204bf3 100644 --- a/.github/workflows/experiment.yaml +++ b/.github/workflows/experiment.yaml @@ -41,6 +41,35 @@ on: - 'remote task cache - transforms cache' - 'remote task cache + dependencies cache - transforms cache' - 'dependencies cache - javaCompile cache' + configuration_cache: + description: "Gradle configuration cache behavior" + type: choice + required: true + default: 'off' + options: + - 'off' + - 'disabled' + - 'on' + - 'on-no-entry' + - 'warn' + - 'warn-no-entry' + - 'read-only' + - 'read-only-no-entry' + project_isolation: + description: "Gradle Isolated Projects behavior" + type: choice + required: true + default: 'off' + options: + - 'off' + - 'on' + - 'on-no-entry' + - 'diagnostics' + - 'diagnostics-no-entry' + configuration_cache_included_builds: + description: "Comma-separated included build paths whose build outputs should be saved with the configuration cache" + required: false + default: "buildSrc,build-logic,build-logic/*" os_args: description: "Operating system configurations for variants" type: string @@ -112,7 +141,12 @@ jobs: cache-exclude-script: "${{ env.cache_exclude_content }}" task: "${{ github.event.inputs.task }}" mode: "${{ github.event.inputs.mode }}" - experiment-id: "${{ github.run_number }}" + configuration-cache: "${{ github.event.inputs.configuration_cache }}" + project-isolation: "${{ github.event.inputs.project_isolation }}" + configuration-cache-key: "configuration-cache-${{ runner.os }}-${{ github.repository_owner }}-${{ github.run_number }}-${{ matrix.config.index }}" + configuration-cache-included-builds: "${{ github.event.inputs.configuration_cache_included_builds }}" + gradle-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} + experiment-id: "${{ github.repository_owner }}-${{ github.run_number }}" variant: ${{ matrix.config.variant }} api-key: ${{ secrets.DV_ACCESS_KEY }} repository: ${{ github.event.inputs.repository }} @@ -148,8 +182,13 @@ jobs: with: task: "${{ github.event.inputs.task }}" mode: "${{ github.event.inputs.mode }}" + configuration-cache: "${{ github.event.inputs.configuration_cache }}" + project-isolation: "${{ github.event.inputs.project_isolation }}" + configuration-cache-key: "configuration-cache-${{ runner.os }}-${{ github.repository_owner }}-${{ github.run_number }}-${{ matrix.config.index }}" + configuration-cache-included-builds: "${{ github.event.inputs.configuration_cache_included_builds }}" + gradle-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} experiment-id: "${{ github.repository_owner }}-${{ github.run_number }}" - execution-number: ${{ github.run_number }} + execution-number: ${{ github.repository_owner }}-${{ github.run_number }} variant: ${{ matrix.config.variant }} api-key: ${{ secrets.DV_ACCESS_KEY }} cache-excludes: ${{ steps.seed.outputs.cache-excludes }} @@ -183,8 +222,13 @@ jobs: with: task: "${{ github.event.inputs.task }}" mode: "${{ github.event.inputs.mode }}" + configuration-cache: "${{ github.event.inputs.configuration_cache }}" + project-isolation: "${{ github.event.inputs.project_isolation }}" + configuration-cache-key: "configuration-cache-${{ runner.os }}-${{ github.repository_owner }}-${{ github.run_number }}-${{ matrix.config.index }}" + configuration-cache-included-builds: "${{ github.event.inputs.configuration_cache_included_builds }}" + gradle-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} experiment-id: "${{ github.repository_owner }}-${{ github.run_number }}" - execution-number: ${{ github.run_number }} + execution-number: ${{ github.repository_owner }}-${{ github.run_number }} variant: ${{ matrix.config.variant }} api-key: ${{ secrets.DV_ACCESS_KEY }} repository: ${{ github.event.inputs.repository }} diff --git a/.github/workflows/runner-gradle-profiler/action.yaml b/.github/workflows/runner-gradle-profiler/action.yaml index 64a25e4..66beeb0 100644 --- a/.github/workflows/runner-gradle-profiler/action.yaml +++ b/.github/workflows/runner-gradle-profiler/action.yaml @@ -42,6 +42,14 @@ inputs: extra-args: description: 'Extra arguments to pass to the Gradle command' required: true + configuration-cache: + description: 'Gradle configuration cache behavior: off, disabled, on, on-no-entry, warn, warn-no-entry, read-only, or read-only-no-entry.' + required: false + default: 'off' + project-isolation: + description: 'Gradle Isolated Projects behavior: off, on, on-no-entry, diagnostics, or diagnostics-no-entry.' + required: false + default: 'off' cache-url: description: 'URL for the cache node, if applicable' required: true @@ -90,6 +98,59 @@ runs: EXTRA_ARG="${{ inputs.extra-args }}" fi + if [ "${{ inputs.configuration-cache }}" = "disabled" ] && [ "${{ inputs.project-isolation }}" != "off" ] && [ -n "${{ inputs.project-isolation }}" ]; then + echo "configuration-cache=disabled cannot be combined with project-isolation=${{ inputs.project-isolation }}." + echo "Gradle requires configuration cache when Isolated Projects is enabled." + exit 1 + fi + + case "${{ inputs.configuration-cache }}" in + "off"|"") + CONFIGURATION_CACHE_ARGS=() + ;; + "disabled") + CONFIGURATION_CACHE_ARGS=("--no-configuration-cache" "-Dorg.gradle.unsafe.isolated-projects=false") + ;; + "on"|"on-no-entry") + CONFIGURATION_CACHE_ARGS=("--configuration-cache") + ;; + "warn"|"warn-no-entry") + CONFIGURATION_CACHE_ARGS=("--configuration-cache" "--configuration-cache-problems=warn") + ;; + "read-only"|"read-only-no-entry") + CONFIGURATION_CACHE_ARGS=("--configuration-cache" "-Dorg.gradle.configuration-cache.read-only=true") + ;; + *) + echo "Unknown configuration cache option: ${{ inputs.configuration-cache }}" + exit 1 + ;; + esac + + case "${{ inputs.project-isolation }}" in + "off"|"") + PROJECT_ISOLATION_ARGS=() + ;; + "on"|"on-no-entry") + PROJECT_ISOLATION_ARGS=("--isolated-projects") + ;; + "diagnostics"|"diagnostics-no-entry") + PROJECT_ISOLATION_ARGS=("--isolated-projects" "-Dorg.gradle.unsafe.isolated-projects.diagnostics=true") + ;; + *) + echo "Unknown project isolation option: ${{ inputs.project-isolation }}" + exit 1 + ;; + esac + + GRADLE_ARGS="[\"$EXTRA_ARG\"" + for ARG in "${CONFIGURATION_CACHE_ARGS[@]}"; do + GRADLE_ARGS="$GRADLE_ARGS, \"$ARG\"" + done + for ARG in "${PROJECT_ISOLATION_ARGS[@]}"; do + GRADLE_ARGS="$GRADLE_ARGS, \"$ARG\"" + done + GRADLE_ARGS="$GRADLE_ARGS, \"-Dscan.tag.${{ inputs.experiment-id }}_${{ inputs.variant-prefix }}${{ inputs.variant }}\", \"-Dscan.tag.experiment\", \"-Dscan.tag.${{ inputs.experiment-id }}\"]" + # Gradle Profiler: cleanup-tasks run between iterations; [] = incremental re-runs if [ "${{ inputs.clean-between-iterations }}" = "true" ]; then CLEANUP_TASKS='["clean"]' @@ -103,7 +164,7 @@ runs: title = \"assemble\" tasks = [\"${{ inputs.task }}\"] cleanup-tasks = $CLEANUP_TASKS - gradle-args = [\"$EXTRA_ARG\", \"-Dscan.tag.${{ inputs.experiment-id }}_${{ inputs.variant-prefix }}${{ inputs.variant }}\", \"-Dscan.tag.experiment\", \"-Dscan.tag.${{ inputs.experiment-id }}\"] + gradle-args = $GRADLE_ARGS }" > scenario else echo "assemble { @@ -111,7 +172,7 @@ runs: tasks = [\"${{ inputs.task }}\"] cleanup-tasks = $CLEANUP_TASKS apply-abi-change-to = [${{ inputs.class }}] - gradle-args = [\"$EXTRA_ARG\", \"-Dscan.tag.${{ inputs.experiment-id }}_${{ inputs.variant-prefix }}${{ inputs.variant }}\", \"-Dscan.tag.experiment\", \"-Dscan.tag.${{ inputs.experiment-id }}\"] + gradle-args = $GRADLE_ARGS }" > scenario fi diff --git a/.github/workflows/runner-seed/action.yaml b/.github/workflows/runner-seed/action.yaml index 03eedec..8f8b15d 100644 --- a/.github/workflows/runner-seed/action.yaml +++ b/.github/workflows/runner-seed/action.yaml @@ -31,6 +31,24 @@ inputs: mode: description: 'Mode of execution relative to caching.' required: true + configuration-cache: + description: 'Gradle configuration cache behavior: off, disabled, on, on-no-entry, warn, warn-no-entry, read-only, or read-only-no-entry.' + required: false + default: 'off' + project-isolation: + description: 'Gradle Isolated Projects behavior: off, on, on-no-entry, diagnostics, or diagnostics-no-entry.' + required: false + default: 'off' + configuration-cache-key: + description: 'Cache key used to save the project configuration cache.' + required: false + configuration-cache-included-builds: + description: 'Comma-separated included build paths whose build outputs are required by the configuration cache.' + required: false + default: 'buildSrc,build-logic,build-logic/*' + gradle-encryption-key: + description: 'Stable Gradle configuration cache encryption key shared by seed and execution jobs.' + required: false extra-args: description: 'Extra arguments to pass to the Gradle command.' required: true @@ -125,15 +143,167 @@ runs: env: GRADLE_BUILD_ACTION_CACHE_KEY_JOB_INSTANCE: ${{ inputs.experiment-id }}-${{ inputs.variant }} + - name: Set Gradle Feature State + id: gradle-feature-state + run: | + feature_enabled=false + entry_mode=skip + no_entry=false + + case "${{ inputs.configuration-cache }}" in + "off"|"disabled"|"") + ;; + "on"|"warn"|"read-only") + feature_enabled=true + entry_mode=restore + ;; + "on-no-entry"|"warn-no-entry"|"read-only-no-entry") + feature_enabled=true + no_entry=true + ;; + *) + echo "Unknown configuration cache option: ${{ inputs.configuration-cache }}" + exit 1 + ;; + esac + + case "${{ inputs.project-isolation }}" in + "off"|"") + ;; + "on"|"diagnostics") + feature_enabled=true + entry_mode=restore + ;; + "on-no-entry"|"diagnostics-no-entry") + feature_enabled=true + no_entry=true + ;; + *) + echo "Unknown project isolation option: ${{ inputs.project-isolation }}" + exit 1 + ;; + esac + + if [ "$no_entry" = true ]; then + entry_mode=skip + fi + + echo "feature_enabled=$feature_enabled" >> "$GITHUB_OUTPUT" + echo "entry_mode=$entry_mode" >> "$GITHUB_OUTPUT" + shell: bash + + - name: Validate Configuration Cache Encryption Key + if: steps.gradle-feature-state.outputs.feature_enabled == 'true' + run: | + if [ -z "$CHECK_GRADLE_ENCRYPTION_KEY" ]; then + echo "GRADLE_ENCRYPTION_KEY is required when configuration cache or project isolation is enabled." + exit 1 + fi + shell: bash + env: + CHECK_GRADLE_ENCRYPTION_KEY: ${{ inputs.gradle-encryption-key }} + - uses: cdsap/build-process-watcher@v0.6.2 with: - remote_monitoring: 'true' + remote_monitoring: 'true' export_to_bigquery: 'true' + - name: Validate Gradle Feature Combination + run: | + if [ "${{ inputs.configuration-cache }}" = "disabled" ] && [ "${{ inputs.project-isolation }}" != "off" ] && [ -n "${{ inputs.project-isolation }}" ]; then + echo "configuration-cache=disabled cannot be combined with project-isolation=${{ inputs.project-isolation }}." + echo "Gradle requires configuration cache when Isolated Projects is enabled." + exit 1 + fi + shell: bash + + - name: Set Configuration Cache Paths + id: configuration-cache-paths + if: steps.gradle-feature-state.outputs.entry_mode == 'restore' && steps.gradle-feature-state.outputs.feature_enabled == 'true' && inputs.configuration-cache-key != '' + run: | + { + echo "paths<> "$GITHUB_OUTPUT" + shell: bash + + - name: Set Configuration Cache Arguments + id: configuration-cache-args + run: | + case "${{ inputs.configuration-cache }}" in + "off"|"") + echo "args=" >> "$GITHUB_OUTPUT" + ;; + "disabled") + echo "args=--no-configuration-cache -Dorg.gradle.unsafe.isolated-projects=false" >> "$GITHUB_OUTPUT" + ;; + "on"|"on-no-entry") + echo "args=--configuration-cache" >> "$GITHUB_OUTPUT" + ;; + "warn"|"warn-no-entry") + echo "args=--configuration-cache --configuration-cache-problems=warn" >> "$GITHUB_OUTPUT" + ;; + "read-only"|"read-only-no-entry") + echo "args=--configuration-cache -Dorg.gradle.configuration-cache.read-only=true" >> "$GITHUB_OUTPUT" + ;; + *) + echo "Unknown configuration cache option: ${{ inputs.configuration-cache }}" + exit 1 + ;; + esac + shell: bash + + - name: Set Project Isolation Arguments + id: project-isolation-args + run: | + case "${{ inputs.project-isolation }}" in + "off"|"") + echo "args=" >> "$GITHUB_OUTPUT" + ;; + "on"|"on-no-entry") + echo "args=--isolated-projects" >> "$GITHUB_OUTPUT" + ;; + "diagnostics"|"diagnostics-no-entry") + echo "args=--isolated-projects -Dorg.gradle.unsafe.isolated-projects.diagnostics=true" >> "$GITHUB_OUTPUT" + ;; + *) + echo "Unknown project isolation option: ${{ inputs.project-isolation }}" + exit 1 + ;; + esac + shell: bash + - name: Execute Gradle Build id: gradle-build run: | - ./gradlew ${{ inputs.task }} ${{ inputs.extra-args }} \ + ./gradlew ${{ inputs.task }} ${{ inputs.extra-args }} ${{ steps.configuration-cache-args.outputs.args }} ${{ steps.project-isolation-args.outputs.args }} \ -Dscan.tag.seed_${{ inputs.variant-prefix }}${{ inputs.variant }} \ -Dscan.tag.seed-"${{ inputs.mode }}" \ -Dscan.tag.seed \ @@ -141,7 +311,32 @@ runs: shell: bash env: DEVELOCITY_ACCESS_KEY: ${{ inputs.api-key }} + GRADLE_BUILD_ACTION_CACHE_KEY_JOB: 'seed' + GRADLE_ENCRYPTION_KEY: ${{ inputs.gradle-encryption-key }} CI_URL_CACHE_NODE: ${{ inputs.cache-url }} + - name: Prime Configuration Cache + id: prime-configuration-cache + if: steps.gradle-feature-state.outputs.entry_mode == 'restore' && steps.gradle-feature-state.outputs.feature_enabled == 'true' + run: | + ./gradlew ${{ inputs.task }} ${{ inputs.extra-args }} ${{ steps.configuration-cache-args.outputs.args }} ${{ steps.project-isolation-args.outputs.args }} \ + -Dscan.tag.${{ inputs.experiment-id }}_${{ inputs.variant-prefix }}${{ inputs.variant }} \ + -Dscan.tag."${{ inputs.mode }}" \ + -Dscan.tag.experiment \ + -Dscan.tag.${{ inputs.experiment-id }} + shell: bash + env: + DEVELOCITY_ACCESS_KEY: ${{ inputs.api-key }} + GRADLE_BUILD_ACTION_CACHE_KEY_JOB: 'seed' + GRADLE_ENCRYPTION_KEY: ${{ inputs.gradle-encryption-key }} + CI_URL_CACHE_NODE: ${{ inputs.cache-url }} + + - name: Save Configuration Cache + if: steps.gradle-feature-state.outputs.entry_mode == 'restore' && steps.gradle-feature-state.outputs.feature_enabled == 'true' && inputs.configuration-cache-key != '' + uses: actions/cache/save@v4 + with: + path: ${{ steps.configuration-cache-paths.outputs.paths }} + key: ${{ inputs.configuration-cache-key }} + - name: Finalize Step uses: actions/checkout@v4 diff --git a/.github/workflows/runner/action.yaml b/.github/workflows/runner/action.yaml index 90c3562..20b89ee 100644 --- a/.github/workflows/runner/action.yaml +++ b/.github/workflows/runner/action.yaml @@ -33,6 +33,24 @@ inputs: mode: description: 'Mode of execution relative to caching' required: true + configuration-cache: + description: 'Gradle configuration cache behavior: off, disabled, on, on-no-entry, warn, warn-no-entry, read-only, or read-only-no-entry.' + required: false + default: 'off' + project-isolation: + description: 'Gradle Isolated Projects behavior: off, on, on-no-entry, diagnostics, or diagnostics-no-entry.' + required: false + default: 'off' + configuration-cache-key: + description: 'Cache key used to restore the seeded project configuration cache.' + required: false + configuration-cache-included-builds: + description: 'Comma-separated included build paths whose build outputs are required by the configuration cache.' + required: false + default: 'buildSrc,build-logic,build-logic/*' + gradle-encryption-key: + description: 'Stable Gradle configuration cache encryption key shared by seed and execution jobs.' + required: false extra-args: description: 'Extra arguments to pass to the Gradle command' required: true @@ -69,14 +87,175 @@ runs: GRADLE_BUILD_ACTION_CACHE_KEY_JOB: 'seed' GRADLE_BUILD_ACTION_CACHE_KEY_JOB_INSTANCE: ${{ inputs.execution-number }}-${{ inputs.variant }} + - name: Set Gradle Feature State + id: gradle-feature-state + run: | + feature_enabled=false + entry_mode=skip + no_entry=false + + case "${{ inputs.configuration-cache }}" in + "off"|"disabled"|"") + ;; + "on"|"warn"|"read-only") + feature_enabled=true + entry_mode=restore + ;; + "on-no-entry"|"warn-no-entry"|"read-only-no-entry") + feature_enabled=true + no_entry=true + ;; + *) + echo "Unknown configuration cache option: ${{ inputs.configuration-cache }}" + exit 1 + ;; + esac + + case "${{ inputs.project-isolation }}" in + "off"|"") + ;; + "on"|"diagnostics") + feature_enabled=true + entry_mode=restore + ;; + "on-no-entry"|"diagnostics-no-entry") + feature_enabled=true + no_entry=true + ;; + *) + echo "Unknown project isolation option: ${{ inputs.project-isolation }}" + exit 1 + ;; + esac + + if [ "$no_entry" = true ]; then + entry_mode=skip + fi + + echo "feature_enabled=$feature_enabled" >> "$GITHUB_OUTPUT" + echo "entry_mode=$entry_mode" >> "$GITHUB_OUTPUT" + shell: bash + + - name: Validate Configuration Cache Encryption Key + if: steps.gradle-feature-state.outputs.feature_enabled == 'true' + run: | + if [ -z "$CHECK_GRADLE_ENCRYPTION_KEY" ]; then + echo "GRADLE_ENCRYPTION_KEY is required when configuration cache or project isolation is enabled." + exit 1 + fi + shell: bash + env: + CHECK_GRADLE_ENCRYPTION_KEY: ${{ inputs.gradle-encryption-key }} + + - name: Validate Gradle Feature Combination + run: | + if [ "${{ inputs.configuration-cache }}" = "disabled" ] && [ "${{ inputs.project-isolation }}" != "off" ] && [ -n "${{ inputs.project-isolation }}" ]; then + echo "configuration-cache=disabled cannot be combined with project-isolation=${{ inputs.project-isolation }}." + echo "Gradle requires configuration cache when Isolated Projects is enabled." + exit 1 + fi + shell: bash + + - name: Set Configuration Cache Paths + id: configuration-cache-paths + if: steps.gradle-feature-state.outputs.entry_mode == 'restore' && steps.gradle-feature-state.outputs.feature_enabled == 'true' && inputs.configuration-cache-key != '' + run: | + { + echo "paths<> "$GITHUB_OUTPUT" + shell: bash + - uses: cdsap/build-process-watcher@v0.6.2 with: - remote_monitoring: 'true' + remote_monitoring: 'true' export_to_bigquery: 'true' + + - name: Restore Configuration Cache + if: steps.gradle-feature-state.outputs.entry_mode == 'restore' && steps.gradle-feature-state.outputs.feature_enabled == 'true' && inputs.configuration-cache-key != '' + uses: actions/cache/restore@v4 + with: + path: ${{ steps.configuration-cache-paths.outputs.paths }} + key: ${{ inputs.configuration-cache-key }} + fail-on-cache-miss: false + + - name: Set Configuration Cache Arguments + id: configuration-cache-args + run: | + case "${{ inputs.configuration-cache }}" in + "off"|"") + echo "args=" >> "$GITHUB_OUTPUT" + ;; + "disabled") + echo "args=--no-configuration-cache -Dorg.gradle.unsafe.isolated-projects=false" >> "$GITHUB_OUTPUT" + ;; + "on"|"on-no-entry") + echo "args=--configuration-cache" >> "$GITHUB_OUTPUT" + ;; + "warn"|"warn-no-entry") + echo "args=--configuration-cache --configuration-cache-problems=warn" >> "$GITHUB_OUTPUT" + ;; + "read-only"|"read-only-no-entry") + echo "args=--configuration-cache -Dorg.gradle.configuration-cache.read-only=true" >> "$GITHUB_OUTPUT" + ;; + *) + echo "Unknown configuration cache option: ${{ inputs.configuration-cache }}" + exit 1 + ;; + esac + shell: bash + + - name: Set Project Isolation Arguments + id: project-isolation-args + run: | + case "${{ inputs.project-isolation }}" in + "off"|"") + echo "args=" >> "$GITHUB_OUTPUT" + ;; + "on"|"on-no-entry") + echo "args=--isolated-projects" >> "$GITHUB_OUTPUT" + ;; + "diagnostics"|"diagnostics-no-entry") + echo "args=--isolated-projects -Dorg.gradle.unsafe.isolated-projects.diagnostics=true" >> "$GITHUB_OUTPUT" + ;; + *) + echo "Unknown project isolation option: ${{ inputs.project-isolation }}" + exit 1 + ;; + esac + shell: bash + - name: Execute Gradle Build id: gradle-build run: | - ./gradlew ${{ inputs.task }} ${{ inputs.extra-args }} \ + ./gradlew ${{ inputs.task }} ${{ inputs.extra-args }} ${{ steps.configuration-cache-args.outputs.args }} ${{ steps.project-isolation-args.outputs.args }} \ -Dscan.tag.${{ inputs.experiment-id }}_${{ inputs.variant-prefix }}${{ inputs.variant }} \ -Dscan.tag."${{ inputs.mode }}" \ -Dscan.tag.experiment \ @@ -85,4 +264,5 @@ runs: env: DEVELOCITY_ACCESS_KEY: ${{ inputs.api-key }} GRADLE_BUILD_ACTION_CACHE_KEY_JOB: 'seed' + GRADLE_ENCRYPTION_KEY: ${{ inputs.gradle-encryption-key }} CI_URL_CACHE_NODE: ${{ inputs.cache-url }} diff --git a/README.md b/README.md index 55e8b51..170189e 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,37 @@ This workflow executes Gradle tasks across two specified variants (branches) wit - `remote task cache + dependencies cache`: Combines remote task caching with dependency caching. - `remote task cache - transforms cache`: Caches task outputs remotely, excluding transforms cache. - `remote task cache + dependencies cache - transforms cache`: Combines remote task, dependency caching, and excludes transforms. - + + - `configuration_cache`: + - **Description**: Controls Gradle configuration cache usage independently of the selected task/dependency cache mode. In the standard experiment workflow, the seed job primes `.gradle/configuration-cache` with the same Gradle start parameters used by execution jobs, then saves it plus configured included-build outputs with a variant-specific key. Execution jobs restore that entry before running. In the Gradle Profiler workflow, the option is added to the generated scenario so profiler warmups and iterations can reuse the configuration cache in the same checkout. + - **Type**: `choice` + - **Default**: `off` + - **Options**: + - `off`: Do not pass configuration-cache arguments; target repository defaults still apply. + - `disabled`: Pass `--no-configuration-cache -Dorg.gradle.unsafe.isolated-projects=false` to force configuration cache off even when the target repository enables Isolated Projects in `gradle.properties`. + - `on`: Pass `--configuration-cache` and save/restore the explicit configuration-cache entry bundle in the standard workflow. + - `on-no-entry`: Pass `--configuration-cache` without saving or restoring the explicit configuration-cache entry bundle. + - `warn`: Pass `--configuration-cache --configuration-cache-problems=warn` and save/restore the explicit configuration-cache entry bundle in the standard workflow. + - `warn-no-entry`: Pass `--configuration-cache --configuration-cache-problems=warn` without saving or restoring the explicit configuration-cache entry bundle. + - `read-only`: Pass `--configuration-cache -Dorg.gradle.configuration-cache.read-only=true` and restore the explicit configuration-cache entry bundle in the standard workflow. + - `read-only-no-entry`: Pass `--configuration-cache -Dorg.gradle.configuration-cache.read-only=true` without restoring the explicit configuration-cache entry bundle. + - **Entry behavior**: The explicit configuration-cache entry bundle is shared by configuration cache and Isolated Projects. If either selected feature value ends in `-no-entry`, the standard workflow skips saving and restoring that bundle. + + - `project_isolation`: + - **Description**: Controls Gradle Isolated Projects independently of the selected task/dependency cache mode. Values without `-no-entry` save/restore the explicit configuration-cache entry bundle in the standard workflow because Isolated Projects requires configuration cache. + - **Type**: `choice` + - **Default**: `off` + - **Options**: + - `off`: Do not pass Isolated Projects arguments; target repository defaults still apply. + - `on`: Pass `--isolated-projects` and save/restore the explicit configuration-cache entry bundle in the standard workflow. + - `on-no-entry`: Pass `--isolated-projects` without saving or restoring the explicit configuration-cache entry bundle. + - `diagnostics`: Pass `--isolated-projects -Dorg.gradle.unsafe.isolated-projects.diagnostics=true` and save/restore the explicit configuration-cache entry bundle in the standard workflow. + - `diagnostics-no-entry`: Pass `--isolated-projects -Dorg.gradle.unsafe.isolated-projects.diagnostics=true` without saving or restoring the explicit configuration-cache entry bundle. + + - `configuration_cache_included_builds`: + - **Description**: Comma-separated included build paths whose `build` directories are saved and restored with the configuration cache. This is needed when a restored configuration-cache entry references compiled included-build outputs, such as `build-logic/build` or `build-logic/convention/build`. + - **Default**: `buildSrc,build-logic,build-logic/*` + - `os_args`: - **Description**: Defines the operating system settings for each variant, specifying which OS image to use during workflow execution. This is useful for testing builds across different environments. - **Type**: `string` @@ -127,6 +157,12 @@ Instead of using agents based on experiment iterations, the Gradle Profiler expe - **Description**: Number of iterations for the experiment. - **Required**: `false` - **Default**: `5` + - `configuration_cache`: + - **Description**: Controls Gradle configuration cache usage for the generated Gradle Profiler scenario. Use `on` for strict configuration-cache execution, `warn` while evaluating projects with remaining incompatibilities, `read-only` to reuse an existing entry without writing a new one, or `disabled` to force configuration cache off even when the target repository enables Isolated Projects. `*-no-entry` values are accepted for parity with the standard workflow and pass the same Gradle arguments as their base value. + - **Type**: `choice` + - **Required**: `false` + - **Default**: `off` + - **Options**: `off`, `disabled`, `on`, `on-no-entry`, `warn`, `warn-no-entry`, `read-only`, `read-only-no-entry` - `os_args`: - **Description**: Operating system configurations for variants. - **Type**: `string` diff --git a/docs/actions-inputs.md b/docs/actions-inputs.md index 626b1b8..ea4e1bd 100644 --- a/docs/actions-inputs.md +++ b/docs/actions-inputs.md @@ -40,6 +40,35 @@ This section details the inputs for the primary dispatchable workflows: `experim - Description: A JSON string to configure report generation. See the "Extra Report Arguments (`extra_report_args`)" section under "JSON Format Examples" for details on the keys. - `experiment.yaml`: Required: `true`. Default: `"{deploy_results:'false',experiment_title:'', open_ai_request:'true', report_enabled:'true',tasktype_report:'true',taskpath_report:'true',kotlin_build_report:'false',process_report:'false',resource_usage_report:'true',gc_report:'false',only_cacheable_outcome:'false',threshold_task_duration:'1000'}"`. - `experiment-with-gradle-profiler.yaml`: Required: `false`. Default: `"{deploy_results:'false',experiment_title:'',open_ai_request:'true',report_enabled:'true',tasktype_report:'true',taskpath_report:'true',kotlin_build_report:'false',process_report:'false',resource_usage_report:'true',gc_report:'false',only_cacheable_outcome:'false',threshold_task_duration:'1000'}"`. +- **`configuration_cache`**: + - Description: Controls Gradle configuration cache usage independently of the selected task/dependency cache mode. + - `experiment.yaml`: Required: `true`. Default: `'off'`. + - `experiment-with-gradle-profiler.yaml`: Required: `false`. Default: `'off'`. + - Options: + - `'off'`: Do not pass configuration-cache arguments; target repository defaults still apply. + - `'disabled'`: Pass `--no-configuration-cache -Dorg.gradle.unsafe.isolated-projects=false` to force configuration cache off even when the target repository enables Isolated Projects in `gradle.properties`. + - `'on'`: Pass `--configuration-cache` and save/restore the explicit configuration-cache entry bundle in the standard workflow. + - `'on-no-entry'`: Pass `--configuration-cache` without saving or restoring the explicit configuration-cache entry bundle. + - `'warn'`: Pass `--configuration-cache --configuration-cache-problems=warn` and save/restore the explicit configuration-cache entry bundle in the standard workflow. + - `'warn-no-entry'`: Pass `--configuration-cache --configuration-cache-problems=warn` without saving or restoring the explicit configuration-cache entry bundle. + - `'read-only'`: Pass `--configuration-cache -Dorg.gradle.configuration-cache.read-only=true` and restore the explicit configuration-cache entry bundle in the standard workflow. + - `'read-only-no-entry'`: Pass `--configuration-cache -Dorg.gradle.configuration-cache.read-only=true` without restoring the explicit configuration-cache entry bundle. + - Compatibility: `'disabled'` cannot be combined with `project_isolation` values other than `'off'`, because Gradle requires configuration cache when Isolated Projects is enabled. + - Reuse behavior: `experiment.yaml` primes `.gradle/configuration-cache` in each seed job with the same Gradle start parameters used by execution jobs, then restores the matching variant entry in execution jobs. If either `configuration_cache` or `project_isolation` ends in `-no-entry`, the standard workflow skips saving and restoring that shared bundle. `experiment-with-gradle-profiler.yaml` adds the selected arguments to the generated scenario so profiler warmups and iterations can reuse configuration in the same checkout. +- **`project_isolation`**: + - Description: Controls Gradle Isolated Projects independently of the selected task/dependency cache mode. Values without `-no-entry` save/restore the explicit configuration-cache entry bundle in the standard workflow because Isolated Projects requires configuration cache. + - `experiment.yaml`: Required: `true`. Default: `'off'`. + - `experiment-with-gradle-profiler.yaml`: Required: `false`. Default: `'off'`. + - Options: + - `'off'`: Do not pass Isolated Projects arguments; target repository defaults still apply. + - `'on'`: Pass `--isolated-projects` and save/restore the explicit configuration-cache entry bundle in the standard workflow. + - `'on-no-entry'`: Pass `--isolated-projects` without saving or restoring the explicit configuration-cache entry bundle. + - `'diagnostics'`: Pass `--isolated-projects -Dorg.gradle.unsafe.isolated-projects.diagnostics=true` and save/restore the explicit configuration-cache entry bundle in the standard workflow. + - `'diagnostics-no-entry'`: Pass `--isolated-projects -Dorg.gradle.unsafe.isolated-projects.diagnostics=true` without saving or restoring the explicit configuration-cache entry bundle. +- **`configuration_cache_included_builds`**: + - Description: Comma-separated included build paths whose build output directories must be saved and restored with the configuration cache. + - `experiment.yaml`: Required: `false`. Default: `"buildSrc,build-logic,build-logic/*"`. + - Reuse behavior: Each listed path contributes its `build` directory, for example `build-logic` adds `build-logic/build` and `build-logic/*` adds one-level nested outputs such as `build-logic/convention/build`. This preserves included-build classpath outputs referenced by restored configuration-cache entries. **Inputs Specific to `experiment.yaml`:** @@ -64,6 +93,7 @@ This section details the inputs for the primary dispatchable workflows: `experim - `'remote task cache + dependencies cache'` - `'remote task cache - transforms cache'` - `'remote task cache + dependencies cache - transforms cache'` + - `'dependencies cache - javaCompile cache'` **Inputs Specific to `experiment-with-gradle-profiler.yaml`:** @@ -169,6 +199,25 @@ This section describes the inputs for the reusable `report/action.yaml` workflow - Required: `true` (conditionally, if deploying). - Default: `""`. +## Reusable Workflow: Seed Runner Action (`.github/workflows/runner-seed/action.yaml`) + +This section lists the seed-action inputs that differ from or extend the standard runner. Other runner inputs such as `task`, `variant`, `repository`, `jdk_version`, `jdk_vendor`, `mode`, `extra-args`, and `cache-url` follow the same meaning as `runner/action.yaml`. + +- **`configuration-cache`**: + - Description: Gradle configuration cache behavior for the seed run (`off`, `disabled`, `on`, `on-no-entry`, `warn`, `warn-no-entry`, `read-only`, or `read-only-no-entry`). `disabled` forces configuration cache off and disables repo-level Isolated Projects with `-Dorg.gradle.unsafe.isolated-projects=false`. + - Required: `false`. + - Default: `off`. +- **`configuration-cache-key`**: + - Description: Variant-specific key used to save `.gradle/configuration-cache` for execution jobs. + - Required: `false`. +- **`configuration-cache-included-builds`**: + - Description: Comma-separated included build paths whose `build` directories are saved with the configuration cache. + - Required: `false`. + - Default: `buildSrc,build-logic,build-logic/*`. +- **`cache-exclude-script`**: + - Description: Optional script content for excluding specific Gradle User Home cache entries. + - Required: `false`. + ## Reusable Workflow: Runner Action (`.github/workflows/runner/action.yaml`) This section details inputs for the reusable `runner/action.yaml` workflow, which executes a single Gradle build iteration for the standard experiment. @@ -205,6 +254,17 @@ This section details inputs for the reusable `runner/action.yaml` workflow, whic - **`mode`**: - Description: Specifies the caching mode for this run (e.g., `no caching`, `local task cache`). - Required: `true`. +- **`configuration-cache`**: + - Description: Gradle configuration cache behavior for the run (`off`, `disabled`, `on`, `on-no-entry`, `warn`, `warn-no-entry`, `read-only`, or `read-only-no-entry`). `disabled` forces configuration cache off and disables repo-level Isolated Projects with `-Dorg.gradle.unsafe.isolated-projects=false`. + - Required: `false`. + - Default: `off`. +- **`configuration-cache-key`**: + - Description: Variant-specific key used to restore the configuration cache saved by the seed job. + - Required: `false`. +- **`configuration-cache-included-builds`**: + - Description: Comma-separated included build paths whose `build` directories are restored with the configuration cache. + - Required: `false`. + - Default: `buildSrc,build-logic,build-logic/*`. - **`extra-args`**: - Description: Any additional arguments to pass to the Gradle command. - Required: `true`. @@ -260,6 +320,10 @@ This section describes inputs for the reusable `runner-gradle-profiler/action.ya - **`extra-args`**: - Description: Any additional arguments to pass to the Gradle command. - Required: `true`. +- **`configuration-cache`**: + - Description: Gradle configuration cache behavior for the generated scenario (`off`, `disabled`, `on`, `on-no-entry`, `warn`, `warn-no-entry`, `read-only`, or `read-only-no-entry`). `disabled` forces configuration cache off and disables repo-level Isolated Projects with `-Dorg.gradle.unsafe.isolated-projects=false`. + - Required: `false`. + - Default: `off`. - **`cache-url`**: - Description: URL of the remote build cache node, if used. - Required: `true`. @@ -313,4 +377,4 @@ This JSON string configures various aspects of the reporting process. The exampl "only_cacheable_outcome": "false", "threshold_task_duration": "1000" } -``` \ No newline at end of file +```