diff --git a/e2e-tests/images/datastore.Dockerfile b/e2e-tests/images/datastore.Dockerfile index b9ddb7abd..5827ab228 100644 --- a/e2e-tests/images/datastore.Dockerfile +++ b/e2e-tests/images/datastore.Dockerfile @@ -35,8 +35,10 @@ WORKDIR /workflow-backend # Install JVM tooling (java, sbt) via mise using the e2e environment. This is the # only thing baked into the image; all backend sources are bind-mounted at runtime. +# It also caches the mise cache directory to speed up subsequent builds. COPY .tool-versions ./ -RUN mise trust -a && mise install java sbt +RUN --mount=type=cache,target=/mise/cache,sharing=locked \ + mise trust -a && mise install java sbt EXPOSE 9095 diff --git a/e2e-tests/images/workflow-frontend.Dockerfile b/e2e-tests/images/workflow-frontend.Dockerfile index 56abb1257..be61bb480 100644 --- a/e2e-tests/images/workflow-frontend.Dockerfile +++ b/e2e-tests/images/workflow-frontend.Dockerfile @@ -35,8 +35,10 @@ WORKDIR /workflow-frontend # Install the toolchain (java, nodejs, sbt, aws-cli) via mise and enable corepack # so `yarn` is available. This is the only thing baked into the image; the repo # and its node_modules are bind-mounted at runtime. +# It also caches the mise cache directory to speed up subsequent builds. COPY .tool-versions ./ -RUN mise trust -a && mise install java nodejs sbt aws-cli \ +RUN --mount=type=cache,target=/mise/cache,sharing=locked \ + mise trust -a && mise install java nodejs sbt aws-cli \ && mise exec nodejs -- npm install -g corepack \ && mise exec nodejs -- corepack enable diff --git a/e2e-tests/setup/stack/containers.ts b/e2e-tests/setup/stack/containers.ts index 3207a5e8b..945afe0b0 100644 --- a/e2e-tests/setup/stack/containers.ts +++ b/e2e-tests/setup/stack/containers.ts @@ -262,6 +262,24 @@ function getBackendDir(e2eRoot: string): string { ); } +// Bind-mount the devcontainer's persistent coursier/ivy cache volumes (see +// .devcontainer/*/devcontainer.json) into sbt containers as their dependency +// caches, so `sbt update`/`run` reuse artifacts already fetched from Maven +// Central across container/image rebuilds instead of re-downloading them. +// Falls back to no extra mounts when run outside that devcontainer. +function sbtCacheBindMounts(): { source: string; target: string; mode: "rw" }[] { + const coursierCacheDir = process.env.DEVENV_COURSIER_CACHE_MOUNT_DIR; + const ivyCacheDir = process.env.DEVENV_IVY_CACHE_MOUNT_DIR; + const mounts: { source: string; target: string; mode: "rw" }[] = []; + if (coursierCacheDir) { + mounts.push({ source: coursierCacheDir, target: "/root/.cache/coursier", mode: "rw" }); + } + if (ivyCacheDir) { + mounts.push({ source: ivyCacheDir, target: "/root/.ivy2", mode: "rw" }); + } + return mounts; +} + function buildDatastoreImage( e2eRoot: string, imageTag: string, @@ -300,6 +318,7 @@ export async function startDatastore( // baking it into the image. Read-write because sbt writes target/ dirs. .withBindMounts([ { source: backendDir, target: "/workflow-backend", mode: "rw" }, + ...sbtCacheBindMounts(), ]) .withLogConsumer(createLogConsumer("datastore", streamLogs)) .withExposedPorts(9095) @@ -376,6 +395,7 @@ export async function startWorkflow( // webpack write target/ and public/build into it. .withBindMounts([ { source: repoRoot, target: "/workflow-frontend", mode: "rw" }, + ...sbtCacheBindMounts(), ]) .withEnvironment({ AWS_ENDPOINT_URL_S3: `http://${S3_ENDPOINT_HOST}:${LOCALSTACK_PORT}`,