Skip to content

Add conditional JDK caching - #1201

Merged
brunoborges merged 16 commits into
mainfrom
brunoborges-add-jdk-cache-input
Aug 5, 2026
Merged

Add conditional JDK caching#1201
brunoborges merged 16 commits into
mainfrom
brunoborges-add-jdk-cache-input

Conversation

@brunoborges

@brunoborges brunoborges commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add cache-jdk with a conditional default: explicit values win; otherwise JDK caching is enabled only when cache is non-empty
  • make force-download bypass runner tool-cache lookup and JDK cache restore while still registering the exact downloaded JDK for best-effort post-job save when JDK caching is enabled
  • isolate JDK cache keys by verification identity: unverified, bundled-key verified, and SHA-256-fingerprinted normalized custom keys; raw key material is never stored or logged
  • preserve operating system, architecture, distribution, package type, exact version, release identity, multiple-JDK, and jdk-file content dimensions
  • document read-only, latest/check-latest, force-download, cache failure fallback, and concurrent immutable save behavior
  • regenerate setup and cleanup dist bundles

Effective cache matrix

cache cache-jdk Dependency cache JDK cache
absent absent off off
absent true off on
absent false off off
maven absent on on
maven true on on
maven false on off

Validation

  • targeted JDK cache suites: 23 tests passed
  • full suite: 39 suites / 1,244 tests passed
  • format check, lint, build, and deterministic dist check passed

The existing Maven benchmark results still apply because cache: maven implicitly enables JDK caching when cache-jdk is omitted.

Cache resolved JDK tool-cache entries by exact platform and release identity, with a default-on cache-jdk input and explicit opt-out.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 4, 2026 23:02
@brunoborges
brunoborges requested a review from a team as a code owner August 4, 2026 23:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces default-on caching of downloaded JDK installations (cache-jdk, opt-out via cache-jdk: false) and wires that caching into both the setup (restore-before-download) and post-action cleanup (save) flows, independently of dependency/wrapper caching.

Changes:

  • Add cache-jdk input (default true) and propagate it through setup orchestration into distribution installers.
  • Implement JDK restore/save behavior via a new src/jdk-cache.ts module and invoke it from installers + cleanup post step.
  • Update docs/tests and regenerate bundled dist/ artifacts to reflect the new behavior and input.
Show a summary per file
File Description
src/setup-java.ts Reads cache-jdk input and passes it through installer options.
src/jdk-cache.ts New module to restore/save tool-cache-backed JDK installs via Actions cache.
src/distributions/local/installer.ts Adds JDK cache restore path for local jdk-file installs (keyed by content hash).
src/distributions/base-models.ts Extends installer options with cacheJdk.
src/distributions/base-installer.ts Restores JDK cache before download; adds tool-cache path helpers and release identity.
src/constants.ts Adds INPUT_CACHE_JDK constant.
src/cleanup-java.ts Saves dependency cache and/or JDK cache in post step, honoring cache-read-only.
README.md Documents cache-jdk and expands cache-read-only semantics to include JDK caches.
package.json Updates release script to include additional cleanup bundle outputs.
action.yml Adds cache-jdk input with default true; broadens cache-read-only description.
tests/setup-java.test.ts Ensures cacheJdk is propagated and modules aren’t initialized when disabled.
tests/jdk-cache.test.ts New unit tests for JDK cache keying, restore, and save behavior.
tests/distributors/base-installer.test.ts Verifies restore-before-download behavior when cacheJdk is enabled.
tests/cleanup-java.test.ts Adds coverage for saving JDK caches independently and honoring cache-jdk: false.
dist/setup/index.js Regenerated bundle reflecting new input and wiring.
dist/setup/971.index.js Regenerated bundled dependency chunk changes (cache/core exports, etc.).
dist/setup/779.index.js New bundled chunk for jdk-cache + cache-feature.
dist/setup/242.index.js Regenerated bundled JavaBase with JDK caching logic and helpers.
dist/setup/19.index.js Regenerated bundled local installer with JDK cache restore + file hashing.
dist/cleanup/314.index.js New bundled cleanup chunk including saveJdkCaches.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 14/21 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread src/jdk-cache.ts
Comment thread src/distributions/base-installer.ts
@brunoborges

Copy link
Copy Markdown
Contributor Author

JDK cache benchmark results

Result: real warm-path benefit, with a storage tradeoff. Across 5 isolated, sequential samples, the candidate reduced median warm setup-java time from 7s to 3s (4s / 57% faster) and median total warm job time from 24s to 18s (6s / 25% faster). The paired warm setup delta was -5s median (range -10s to -2s); all 5 samples favored the candidate. The paired total-job delta was -6s median (range -11s to -1s).

Method

  • Baseline: actions/setup-java@881ee1636f070602b6d83c30ed0640b9c129c20d (main / PR base)
  • Candidate: actions/setup-java@ee3e6d82d384258a6d9050ed5f8ef34d9d9acc06 (exact PR head), with cache-jdk omitted to test the default-on behavior
  • ubuntu-24.04, Microsoft OpenJDK 17.0.19, x64, Spring PetClinic f182358d02e4a68e52bdbabf55ca7800288511e7, Maven compile
  • Identical dependency/wrapper/build settings; variant- and run-specific Maven cache keys
  • One cold and one dependent warm job per variant. Runs were sequential and all five benchmark caches were deleted before the next dispatch because the JDK key is release-derived and cannot be salted. Final repository cache count: 0.
Run Baseline cold setup/post/job (s) Candidate cold setup/post/job (s) Baseline warm setup/job (s) Candidate warm setup/job (s) JDK cache (MiB)
30958913886 5/2/42 12/6/52 8/26 3/20 175.3
30959023308 6/5/46 7/3/46 7/24 2/18 175.3
30959122087 6/3/39 8/5/50 7/24 5/23 175.3
30959220116 6/4/43 5/3/38 13/28 3/17 175.3
30959348365 6/6/44 9/5/51 7/24 3/18 175.3

Cache behavior and costs

Every candidate cold log reported JDK cache is not found, downloaded Microsoft JDK 17.0.19, and saved the same release-derived key. Every candidate warm log (5/5) explicitly reported JDK cache restored from key; every baseline warm log downloaded the JDK again. Maven dependency and wrapper caches also restored on both variants.

The JDK adds 175.3 MiB compressed per JDK identity. Maven dependencies were 154.2 MiB and the wrapper 8.7 MiB per isolated variant, so candidate cache storage was about 338.2 MiB vs 162.9 MiB for baseline (+175.3 MiB / +108% in this case). Candidate cold post-cache time was 3-6s (median 5s) versus 2-6s (median 4s); parallel cache saves and network variance make that 1s median difference inconclusive. Median cold total job time was 50s vs 43s (+7s), but paired deltas ranged from -5s to +11s.

For the action steps alone, the paired median cold setup+post overhead was about 2s, versus a 5s paired median warm setup saving, so the feature generally breaks even on the first warm reuse. Using noisier total-job medians gives a break-even around 1-2 warm jobs. All measured jobs still round to one billed Linux minute, so this does not reduce per-job billed minutes in this short workload; it improves latency/runner occupancy. Cache quota pressure and eviction are the main tradeoffs, especially across many OS/architecture/distribution/version identities.

With n=5, the approximate 95% paired-mean confidence interval is a 1.5-8.9s warm setup saving and 1.6-10.4s total-job saving. Limitations: one Linux runner image, one JDK distribution/version, small sample, and normal hosted-runner/network variance. The consistent 5/5 restore wins and non-overlapping setup ranges (candidate 2-5s, baseline 7-13s) support a real benefit for downloaded JDKs.

Reusable harness: actions/setup-java-benchmarks#10, final benchmark branch commit fe91a0d. Raw JSON/CSV artifacts are attached to each workflow run.

brunoborges and others added 7 commits August 4, 2026 19:33
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@brunoborges brunoborges changed the title Add default JDK caching Add conditional JDK caching Aug 5, 2026
brunoborges and others added 8 commits August 4, 2026 20:30
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use one normalized runner OS dimension, reset the internal cache key schema for the unreleased feature, and align documentation, tests, and bundles.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use the established RUNNER_OS value directly and retain process.platform only as a non-Actions fallback.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Bind each JDK cache key to the installation identity it was computed for,
keep post-job saves best-effort per entry, and state the real reuse and
verification guarantee in the documentation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Bring in brace-expansion 5.0.9 (#1202) plus the accompanying dependency
metadata cleanup and the java-package contract test update for the
README table format.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Rename '## Caching dependencies' to '## Caching' and add a what-gets-cached
overview table covering the dependency, wrapper, and JDK caches. Lead with the
common 'cache: maven' example and the dependency-cache material, and demote JDK
caching into its own subsection.

Also corrects the IMPORTANT callout, which implied JDK caching required an
explicit opt-in; it is enabled implicitly whenever 'cache' is set.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Remove pull-request framing that compared behavior to `main`; state the
  tool-cache and `jdkfile` behavior directly and unconditionally.
- Clarify that the JDK cache is a separate cache *entry* from the dependency
  and wrapper caches, while its *enablement* is coupled to `cache`, so the
  opening paragraph agrees with the enablement matrix.
- Cite the actions/setup-java-benchmarks repository instead of an open PR and
  a self-referential PR comment, keeping the measured figures and caveats.
- Keep the `cache`/`cache-jdk` matrix only in docs/advanced-usage.md and
  summarize the rules in prose in README.md to avoid divergence.
- Describe the guarantee that a cache key is only saved with the installation
  it was computed for, instead of documenting inode/size/timestamp internals.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: e2755464-4e83-47b6-ba71-731bb481b418
@brunoborges
brunoborges merged commit 955f34f into main Aug 5, 2026
85 checks passed
@brunoborges
brunoborges deleted the brunoborges-add-jdk-cache-input branch August 5, 2026 01:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants