Skip to content

Commit 6601704

Browse files
committed
ci: convert cypress scripts to CommonJS:
Verification Results - Direct module loading: ✅ Works perfectly - Incremental validation: ✅ Processes files correctly - Subprocess calls: ✅ No EPIPE errors - Cache functionality: ✅ Operating normally 🔧 Technical Details - All modules now use CommonJS require() statements - Proper module.exports for compatibility - File extensions changed to .cjs to work with type: module in package.json - Maintained all existing functionality and error handling
1 parent eac1acf commit 6601704

File tree

6 files changed

+941
-19
lines changed

6 files changed

+941
-19
lines changed

.github/scripts/cache-manager.cjs

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Simple Cache Manager for Link Validation Results
5+
* Uses GitHub Actions cache API or local file storage
6+
*/
7+
8+
const fs = require('fs');
9+
const path = require('path');
10+
const crypto = require('crypto');
11+
const process = require('process');
12+
13+
const CACHE_VERSION = 'v1';
14+
const CACHE_KEY_PREFIX = 'link-validation';
15+
const LOCAL_CACHE_DIR = path.join(process.cwd(), '.cache', 'link-validation');
16+
17+
/**
18+
* Simple cache interface
19+
*/
20+
class CacheManager {
21+
constructor(options = {}) {
22+
this.useGitHubCache =
23+
options.useGitHubCache !== false && process.env.GITHUB_ACTIONS;
24+
this.localCacheDir = options.localCacheDir || LOCAL_CACHE_DIR;
25+
26+
// Configurable cache TTL - default 30 days, support environment variable
27+
this.cacheTTLDays =
28+
options.cacheTTLDays || parseInt(process.env.LINK_CACHE_TTL_DAYS) || 30;
29+
this.maxAge = this.cacheTTLDays * 24 * 60 * 60 * 1000;
30+
31+
if (!this.useGitHubCache) {
32+
this.ensureLocalCacheDir();
33+
}
34+
}
35+
36+
ensureLocalCacheDir() {
37+
if (!fs.existsSync(this.localCacheDir)) {
38+
fs.mkdirSync(this.localCacheDir, { recursive: true });
39+
}
40+
}
41+
42+
generateCacheKey(filePath, fileHash) {
43+
const pathHash = crypto
44+
.createHash('sha256')
45+
.update(filePath)
46+
.digest('hex')
47+
.substring(0, 8);
48+
return `${CACHE_KEY_PREFIX}-${CACHE_VERSION}-${pathHash}-${fileHash}`;
49+
}
50+
51+
async get(filePath, fileHash) {
52+
if (this.useGitHubCache) {
53+
return await this.getFromGitHubCache(filePath, fileHash);
54+
} else {
55+
return await this.getFromLocalCache(filePath, fileHash);
56+
}
57+
}
58+
59+
async set(filePath, fileHash, results) {
60+
if (this.useGitHubCache) {
61+
return await this.setToGitHubCache(filePath, fileHash, results);
62+
} else {
63+
return await this.setToLocalCache(filePath, fileHash, results);
64+
}
65+
}
66+
67+
async getFromGitHubCache(filePath, fileHash) {
68+
// TODO: This method is a placeholder for GitHub Actions cache integration
69+
// GitHub Actions cache is handled directly in the workflow via actions/cache
70+
// This method should either be implemented or removed in future versions
71+
console.warn(
72+
'[PLACEHOLDER] getFromGitHubCache: Using placeholder implementation - always returns null'
73+
);
74+
return null;
75+
}
76+
77+
async setToGitHubCache(filePath, fileHash, results) {
78+
// TODO: This method is a placeholder for GitHub Actions cache integration
79+
// GitHub Actions cache is handled directly in the workflow via actions/cache
80+
// This method should either be implemented or removed in future versions
81+
console.warn(
82+
'[PLACEHOLDER] setToGitHubCache: Using placeholder implementation - always returns true'
83+
);
84+
return true;
85+
}
86+
87+
async getFromLocalCache(filePath, fileHash) {
88+
const cacheKey = this.generateCacheKey(filePath, fileHash);
89+
const cacheFile = path.join(this.localCacheDir, `${cacheKey}.json`);
90+
91+
if (!fs.existsSync(cacheFile)) {
92+
return null;
93+
}
94+
95+
try {
96+
const content = fs.readFileSync(cacheFile, 'utf8');
97+
const cached = JSON.parse(content);
98+
99+
// TTL check using configured cache duration
100+
const age = Date.now() - new Date(cached.cachedAt).getTime();
101+
102+
if (age > this.maxAge) {
103+
fs.unlinkSync(cacheFile);
104+
return null;
105+
}
106+
107+
return cached.results;
108+
} catch (error) {
109+
// Clean up corrupted cache
110+
try {
111+
fs.unlinkSync(cacheFile);
112+
} catch {
113+
// Ignore cleanup errors
114+
}
115+
return null;
116+
}
117+
}
118+
119+
async setToLocalCache(filePath, fileHash, results) {
120+
const cacheKey = this.generateCacheKey(filePath, fileHash);
121+
const cacheFile = path.join(this.localCacheDir, `${cacheKey}.json`);
122+
123+
const cacheData = {
124+
filePath,
125+
fileHash,
126+
results,
127+
cachedAt: new Date().toISOString(),
128+
};
129+
130+
try {
131+
fs.writeFileSync(cacheFile, JSON.stringify(cacheData, null, 2));
132+
return true;
133+
} catch (error) {
134+
console.warn(`Cache save failed: ${error.message}`);
135+
return false;
136+
}
137+
}
138+
139+
async cleanup() {
140+
if (this.useGitHubCache) {
141+
return { removed: 0, note: 'GitHub Actions cache auto-managed' };
142+
}
143+
144+
let removed = 0;
145+
if (!fs.existsSync(this.localCacheDir)) {
146+
return { removed };
147+
}
148+
149+
const files = fs.readdirSync(this.localCacheDir);
150+
151+
for (const file of files) {
152+
if (!file.endsWith('.json')) continue;
153+
154+
const filePath = path.join(this.localCacheDir, file);
155+
try {
156+
const stat = fs.statSync(filePath);
157+
if (Date.now() - stat.mtime.getTime() > this.maxAge) {
158+
fs.unlinkSync(filePath);
159+
removed++;
160+
}
161+
} catch {
162+
// Remove corrupted files
163+
try {
164+
fs.unlinkSync(filePath);
165+
removed++;
166+
} catch {
167+
// Ignore errors
168+
}
169+
}
170+
}
171+
172+
return { removed };
173+
}
174+
}
175+
176+
module.exports = CacheManager;
177+
module.exports.CacheManager = CacheManager;

0 commit comments

Comments
 (0)