Skip to content

Commit 8ef323d

Browse files
committed
ci(experiment): cache devcontainer node_modules across runs
1 parent c645045 commit 8ef323d

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

.github/workflows/experiment-devcontainer-proof.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@ jobs:
5252
# "unknown cache importer: gha" and the build goes fully cold.
5353
uses: docker/setup-buildx-action@v3
5454

55+
- name: Cache devcontainer node_modules
56+
# Image-layer caching alone doesn't help us, because the
57+
# devcontainer's `node_modules` lives in a named Docker volume that
58+
# is created fresh per run (volumes don't survive across CI jobs).
59+
# postCreateCommand then runs `pnpm install` from scratch on every
60+
# run, which dominates the build step's wall time. We cache the
61+
# contents of that volume here and restore them into the volume
62+
# before devcontainers/ci starts the container, so postCreateCommand
63+
# sees an already-populated node_modules and pnpm install is a no-op
64+
# (lockfile-equal).
65+
id: nm-cache
66+
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
67+
with:
68+
path: nm-cache
69+
key: dc-nm-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
70+
71+
- name: Pre-populate devcontainer node_modules volume
72+
if: steps.nm-cache.outputs.cache-hit == 'true'
73+
run: |
74+
# The volume name follows devcontainer.json's
75+
# source=toolhive-node-modules-${localWorkspaceFolderBasename}.
76+
# In CI the workspace basename is always `toolhive-studio`.
77+
VOLUME=toolhive-node-modules-toolhive-studio
78+
docker volume create "$VOLUME" >/dev/null
79+
docker run --rm \
80+
-v "$PWD/nm-cache:/src:ro" \
81+
-v "$VOLUME:/dst" \
82+
alpine:3 sh -c 'cp -a /src/. /dst/'
83+
5584
- name: Build & start devcontainer (cached via gha)
5685
uses: devcontainers/ci@v0.3
5786
with:
@@ -168,6 +197,21 @@ jobs:
168197
echo "::warning::type-check failed"
169198
fi
170199
200+
- name: Dump devcontainer node_modules for cache
201+
# Runs only on cache miss. Populates nm-cache/ with the volume
202+
# contents so actions/cache's post-step picks it up for next time.
203+
# Multiple containers can mount the same named volume simultaneously,
204+
# so this doesn't disturb the running devcontainer.
205+
if: always() && steps.nm-cache.outputs.cache-hit != 'true'
206+
run: |
207+
VOLUME=toolhive-node-modules-toolhive-studio
208+
rm -rf nm-cache && mkdir -p nm-cache
209+
docker run --rm \
210+
-v "$VOLUME:/src:ro" \
211+
-v "$PWD/nm-cache:/dst" \
212+
alpine:3 sh -c 'cp -a /src/. /dst/'
213+
echo "::notice::node_modules dumped: $(du -sh nm-cache | cut -f1)"
214+
171215
- name: Upload screenshots
172216
if: always()
173217
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7

0 commit comments

Comments
 (0)