[CELEBORN-2432] Cache sbt launcher and dependencies in SBT CI workflow - #3812
[CELEBORN-2432] Cache sbt launcher and dependencies in SBT CI workflow#3812yew1eb wants to merge 3 commits into
Conversation
…workflow The sbt CI jobs previously downloaded the sbt launcher and the whole dependency set on every run of every matrix job, exposing them to network flakes (sbt-launch download failures, corrupted jar downloads). Cache build/*.jar, ~/.sbt and the coursier cache with keys derived from the build files, following the pattern used by Spark's build_and_test.yml.
There was a problem hiding this comment.
Pull request overview
Adds dependency caching to the SBT GitHub Actions workflow to reduce repeated downloads across CI runs, improving build stability (fewer network flakes) and speeding up subsequent runs.
Changes:
- Adds
actions/cache@v4to each SBT CI job. - Caches the downloaded SBT launcher (
build/*.jar) plus SBT/Coursier home directories (~/.sbt,~/.cache/coursier).
Suppressed comments (6)
.github/workflows/sbt.yml:179
- The cache key is currently shared across different JDK / Scala / Spark/Flink matrix variants and only hashes a subset of the SBT build definition. Because GitHub Actions caches are immutable once saved, the first job that saves this key can “freeze” an incomplete cache, and later variants will keep re-downloading missing artifacts without ever being able to save them. Consider (1) including the SBT build definition files (project//*.scala, project//*.sbt, version.sbt, plugins.sbt) in hashFiles and (2) scoping the key by the relevant matrix dimensions (java/scala/spark/flink) while keeping restore-keys broad for reuse.
key: sbt-${{ hashFiles('**/pom.xml', 'project/build.properties', 'build/sbt', 'build/sbt-launch-lib.bash') }}
restore-keys: |
sbt-
.github/workflows/sbt.yml:231
- The cache key is currently shared across different JDK / Scala / Spark/Flink matrix variants and only hashes a subset of the SBT build definition. Because GitHub Actions caches are immutable once saved, the first job that saves this key can “freeze” an incomplete cache, and later variants will keep re-downloading missing artifacts without ever being able to save them. Consider (1) including the SBT build definition files (project//*.scala, project//*.sbt, version.sbt, plugins.sbt) in hashFiles and (2) scoping the key by the relevant matrix dimensions (java/scala/spark/flink) while keeping restore-keys broad for reuse.
key: sbt-${{ hashFiles('**/pom.xml', 'project/build.properties', 'build/sbt', 'build/sbt-launch-lib.bash') }}
restore-keys: |
sbt-
.github/workflows/sbt.yml:273
- The cache key is currently shared across different JDK / Scala / Spark/Flink matrix variants and only hashes a subset of the SBT build definition. Because GitHub Actions caches are immutable once saved, the first job that saves this key can “freeze” an incomplete cache, and later variants will keep re-downloading missing artifacts without ever being able to save them. Consider (1) including the SBT build definition files (project//*.scala, project//*.sbt, version.sbt, plugins.sbt) in hashFiles and (2) scoping the key by the relevant matrix dimensions (java/scala/spark/flink) while keeping restore-keys broad for reuse.
key: sbt-${{ hashFiles('**/pom.xml', 'project/build.properties', 'build/sbt', 'build/sbt-launch-lib.bash') }}
restore-keys: |
sbt-
.github/workflows/sbt.yml:316
- The cache key is currently shared across different JDK / Scala / Spark/Flink matrix variants and only hashes a subset of the SBT build definition. Because GitHub Actions caches are immutable once saved, the first job that saves this key can “freeze” an incomplete cache, and later variants will keep re-downloading missing artifacts without ever being able to save them. Consider (1) including the SBT build definition files (project//*.scala, project//*.sbt, version.sbt, plugins.sbt) in hashFiles and (2) scoping the key by the relevant matrix dimensions (java/scala/spark/flink) while keeping restore-keys broad for reuse.
key: sbt-${{ hashFiles('**/pom.xml', 'project/build.properties', 'build/sbt', 'build/sbt-launch-lib.bash') }}
restore-keys: |
sbt-
.github/workflows/sbt.yml:354
- The cache key is currently shared across different JDK / Scala / Spark/Flink matrix variants and only hashes a subset of the SBT build definition. Because GitHub Actions caches are immutable once saved, the first job that saves this key can “freeze” an incomplete cache, and later variants will keep re-downloading missing artifacts without ever being able to save them. Consider (1) including the SBT build definition files (project//*.scala, project//*.sbt, version.sbt, plugins.sbt) in hashFiles and (2) scoping the key by the relevant matrix dimensions (java/scala/spark/flink) while keeping restore-keys broad for reuse.
key: sbt-${{ hashFiles('**/pom.xml', 'project/build.properties', 'build/sbt', 'build/sbt-launch-lib.bash') }}
restore-keys: |
sbt-
.github/workflows/sbt.yml:392
- The cache key is currently shared across different JDK / Scala / Spark/Flink matrix variants and only hashes a subset of the SBT build definition. Because GitHub Actions caches are immutable once saved, the first job that saves this key can “freeze” an incomplete cache, and later variants will keep re-downloading missing artifacts without ever being able to save them. Consider (1) including the SBT build definition files (project//*.scala, project//*.sbt, version.sbt, plugins.sbt) in hashFiles and (2) scoping the key by the relevant matrix dimensions (java/scala/spark/flink) while keeping restore-keys broad for reuse.
key: sbt-${{ hashFiles('**/pom.xml', 'project/build.properties', 'build/sbt', 'build/sbt-launch-lib.bash') }}
restore-keys: |
sbt-
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| key: sbt-${{ hashFiles('**/pom.xml', 'project/build.properties', 'build/sbt', 'build/sbt-launch-lib.bash') }} | ||
| restore-keys: | | ||
| sbt- |
There was a problem hiding this comment.
Addressed: the cache key is now scoped by job and matrix dimensions (sbt-${{ github.job }}-${{ matrix.java }}-${{ matrix.scala }}-${{ matrix.spark }}${{ matrix.flink }}-...), and hashFiles covers the SBT build definition files (project/**/*.scala, project/**/*.sbt) instead of pom.xml.
|
IIRC actions/setup-java provides some built-in cache for building systems, does that work? BTW, you can customize |
setup-java's |
What changes were proposed in this pull request?
Add an actions/cache step to every job in sbt.yml, caching:
Keys are derived from hashFiles of the poms and build scripts, so downloads only happen when the build files change. This follows the pattern used by Spark's
build_and_test.yml.Why are the changes needed?
The sbt CI jobs currently configure no caching at all: every run of every matrix job (~40 jobs) re-downloads the sbt launcher and the entire dependency set, which exposes CI to network flakes. Recent examples on PR CI and on main:
org.scalactic.ScalacticBundle caused by java.io.IOException: Stream closed (corrupted jar download)
Does this PR resolve a correctness bug?
Does this PR introduce any user-facing change?
How was this patch tested?
Workflow-only change; the PR's own CI run exercises the new cache steps (first run populates the cache, subsequent runs hit it).