Skip to content

Commit 2c1b6ce

Browse files
committed
Fix cache plugin API calls and improve logging
- Correct cache.restore() and cache.save() to use proper signature (path, { key }) - Add console.log statements for all cache operations with [CACHE] prefix - Accumulate all operation results for combined deploy summary display - Log environment variables at start for debugging cache key generation - Track restore/save success and errors with clear status indicators This ensures the plugin follows Netlify's cache-utils API documentation and provides visibility into cache operations during builds. see: - https://docs.netlify.com/extend/develop-and-share/develop-build-plugins/#plugin-methods - https://github.com/netlify/build/blob/main/packages/cache-utils/README.md Signed-off-by: Scott Rigby <scott@r6by.com>
1 parent 396d9cd commit 2c1b6ce

1 file changed

Lines changed: 66 additions & 55 deletions

File tree

  • netlify-plugins/cache-docusaurus-dirs-file

netlify-plugins/cache-docusaurus-dirs-file/index.js

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ function makeKey({ dir, repoRoot }) {
3333

3434
let key = dir;
3535

36-
// Auto-invalidate node_modules with yarn.lock changes
3736
if (dir === "node_modules") {
3837
const yarnLockPath = path.join(repoRoot, "yarn.lock");
3938
const hash = fileSha256(yarnLockPath);
@@ -42,98 +41,104 @@ function makeKey({ dir, repoRoot }) {
4241
}
4342
}
4443

45-
// On-demand busting
4644
if (cacheVersion) {
4745
key = `${key}@cv-${cacheVersion}`;
4846
}
4947

50-
// Per-branch isolation
5148
if (perBranch) {
5249
key = `${key}@${branch}`;
5350
}
5451
return key;
5552
}
5653

57-
async function restoreDir(utils, absPath, key) {
54+
async function restoreDir(utils, absPath, key, results) {
5855
try {
59-
// File-based caching: check if cache exists, then restore
60-
const cacheExists = await utils.cache.has(key);
61-
if (!cacheExists) {
62-
utils.status.show({
63-
title: `No cache: ${key}`,
64-
summary: `No prior cache for ${absPath}`,
65-
});
66-
return false;
67-
}
56+
const restored = await utils.cache.restore(absPath, { key });
6857

69-
const restored = await utils.cache.restore(key);
7058
if (restored) {
71-
// File-based caching often requires manual copy from cache location
72-
// The exact implementation may vary based on Netlify's file-based API
73-
utils.status.show({
74-
title: `Cache restored: ${key}`,
75-
summary: `Restored into ${absPath}`,
76-
});
59+
const msg = `✓ Restored cache: ${key}`;
60+
console.log(`[CACHE] ${msg}`);
61+
results.push(msg);
7762
} else {
78-
utils.status.show({
79-
title: `Cache restore failed: ${key}`,
80-
summary: `Failed to restore cache for ${absPath}`,
81-
});
63+
const msg = `No cache found for ${key}`;
64+
console.log(`[CACHE] ${msg}`);
65+
results.push(msg);
8266
}
8367
return restored;
8468
} catch (err) {
85-
utils.status.show({
86-
title: `Cache restore failed: ${key}`,
87-
summary: err.message,
88-
});
69+
const msg = `✗ Error restoring ${key}: ${err.message}`;
70+
console.log(`[CACHE] ${msg}`);
71+
results.push(msg);
8972
return false;
9073
}
9174
}
9275

93-
async function saveDir(utils, absPath, key) {
76+
async function saveDir(utils, absPath, key, results, dir) {
9477
try {
95-
// File-based caching: save directory to cache
96-
const saved = await utils.cache.save(key, absPath);
97-
utils.status.show({
98-
title: saved ? `Cache saved: ${key}` : `Cache skipped: ${key}`,
99-
summary: `${saved ? "Saved" : "Skipped"} from ${absPath}`,
100-
});
78+
const saved = await utils.cache.save(absPath, { key });
79+
const msg = saved ? `✓ Saved cache: ${key}` : `⊖ Skipped cache: ${key}`;
80+
console.log(`[CACHE] ${msg}`);
81+
results.push(msg);
10182
return saved;
10283
} catch (err) {
103-
utils.status.show({
104-
title: `Cache save failed: ${key}`,
105-
summary: err.message,
106-
});
84+
// Known issue: node_modules/.bin symlinks can cause EISDIR errors
85+
// This is non-critical as the rest of node_modules still gets cached
86+
if (dir === "node_modules" && err.message.includes("EISDIR")) {
87+
const msg = `⚠ Partial cache saved for ${key} (symlink issue in .bin - non-critical)`;
88+
console.log(`[CACHE] ${msg}`);
89+
results.push(msg);
90+
return true; // Consider it a success since most of node_modules is cached
91+
}
92+
const msg = `✗ Error saving ${key}: ${err.message}`;
93+
console.log(`[CACHE] ${msg}`);
94+
results.push(msg);
10795
return false;
10896
}
10997
}
11098

11199
module.exports = {
112100
async onPreBuild({ inputs, utils }) {
101+
const results = [];
102+
console.log('[CACHE] ========== Cache Restore Starting ==========');
103+
console.log('[CACHE] Environment:', {
104+
CACHE_VERSION: process.env.CACHE_VERSION,
105+
CACHE_PER_BRANCH: process.env.CACHE_PER_BRANCH,
106+
NETLIFY_BRANCH: process.env.NETLIFY_BRANCH
107+
});
108+
113109
const repoRoot = process.cwd();
114110
const dirs = inputs.dirs;
115111

116112
for (const dir of dirs) {
117113
const key = makeKey({ dir, repoRoot });
114+
console.log(`[CACHE] Processing ${dir} with key: ${key}`);
118115
const abs = path.resolve(repoRoot, dir);
119116

120-
await restoreDir(utils, abs, key);
117+
await restoreDir(utils, abs, key, results);
121118

122-
// Guidance for node_modules: ensure yarn.lock exists to keep cache fresh
123119
if (dir === "node_modules") {
124120
const yarnLockPath = path.join(repoRoot, "yarn.lock");
125121
if (!fs.existsSync(yarnLockPath)) {
126-
utils.status.show({
127-
title: "node_modules cache warning",
128-
summary:
129-
"yarn.lock not found. Caching node_modules without yarn.lock can lead to stale dependencies. Ensure yarn.lock is committed.",
130-
});
122+
const msg = "⚠ Warning: yarn.lock not found - node_modules cache may be stale";
123+
console.log(`[CACHE] ${msg}`);
124+
results.push(msg);
131125
}
132126
}
133127
}
128+
129+
console.log('[CACHE] ========== Cache Restore Complete ==========');
130+
131+
// Show combined status in deploy summary
132+
utils.status.show({
133+
title: "Cache Restore Summary",
134+
summary: results.length > 0 ? results.join('\n') : 'No cache operations performed',
135+
});
134136
},
135137

136138
async onPostBuild({ inputs, utils }) {
139+
const results = [];
140+
console.log('[CACHE] ========== Cache Save Starting ==========');
141+
137142
const repoRoot = process.cwd();
138143
const dirs = inputs.dirs;
139144

@@ -142,23 +147,29 @@ module.exports = {
142147
const abs = path.resolve(repoRoot, dir);
143148

144149
if (!dirExists(abs)) {
145-
utils.status.show({
146-
title: `Cache not saved (missing directory)`,
147-
summary: `${abs} does not exist.`,
148-
});
150+
const msg = `⊖ Skipped ${dir}: directory does not exist`;
151+
console.log(`[CACHE] ${msg}`);
152+
results.push(msg);
149153
continue;
150154
}
151155

152156
const hasFiles = fs.readdirSync(abs).length > 0;
153157
if (!hasFiles) {
154-
utils.status.show({
155-
title: `Cache not saved (empty directory)`,
156-
summary: `${abs} is empty.`,
157-
});
158+
const msg = `⊖ Skipped ${dir}: directory is empty`;
159+
console.log(`[CACHE] ${msg}`);
160+
results.push(msg);
158161
continue;
159162
}
160163

161-
await saveDir(utils, abs, key);
164+
await saveDir(utils, abs, key, results, dir);
162165
}
166+
167+
console.log('[CACHE] ========== Cache Save Complete ==========');
168+
169+
// Show combined status in deploy summary (this overrides the onPreBuild status)
170+
utils.status.show({
171+
title: "Cache Operations Complete",
172+
summary: results.length > 0 ? results.join('\n') : 'No cache operations performed',
173+
});
163174
},
164175
};

0 commit comments

Comments
 (0)