@@ -262,6 +262,24 @@ function getBackendDir(e2eRoot: string): string {
262262 ) ;
263263}
264264
265+ // Bind-mount the devcontainer's persistent coursier/ivy cache volumes (see
266+ // .devcontainer/*/devcontainer.json) into sbt containers as their dependency
267+ // caches, so `sbt update`/`run` reuse artifacts already fetched from Maven
268+ // Central across container/image rebuilds instead of re-downloading them.
269+ // Falls back to no extra mounts when run outside that devcontainer.
270+ function sbtCacheBindMounts ( ) : { source : string ; target : string ; mode : "rw" } [ ] {
271+ const coursierCacheDir = process . env . DEVENV_COURSIER_CACHE_MOUNT_DIR ;
272+ const ivyCacheDir = process . env . DEVENV_IVY_CACHE_MOUNT_DIR ;
273+ const mounts : { source : string ; target : string ; mode : "rw" } [ ] = [ ] ;
274+ if ( coursierCacheDir ) {
275+ mounts . push ( { source : coursierCacheDir , target : "/root/.cache/coursier" , mode : "rw" } ) ;
276+ }
277+ if ( ivyCacheDir ) {
278+ mounts . push ( { source : ivyCacheDir , target : "/root/.ivy2" , mode : "rw" } ) ;
279+ }
280+ return mounts ;
281+ }
282+
265283function buildDatastoreImage (
266284 e2eRoot : string ,
267285 imageTag : string ,
@@ -300,6 +318,7 @@ export async function startDatastore(
300318 // baking it into the image. Read-write because sbt writes target/ dirs.
301319 . withBindMounts ( [
302320 { source : backendDir , target : "/workflow-backend" , mode : "rw" } ,
321+ ...sbtCacheBindMounts ( ) ,
303322 ] )
304323 . withLogConsumer ( createLogConsumer ( "datastore" , streamLogs ) )
305324 . withExposedPorts ( 9095 )
@@ -376,6 +395,7 @@ export async function startWorkflow(
376395 // webpack write target/ and public/build into it.
377396 . withBindMounts ( [
378397 { source : repoRoot , target : "/workflow-frontend" , mode : "rw" } ,
398+ ...sbtCacheBindMounts ( ) ,
379399 ] )
380400 . withEnvironment ( {
381401 AWS_ENDPOINT_URL_S3 : `http://${ S3_ENDPOINT_HOST } :${ LOCALSTACK_PORT } ` ,
0 commit comments