const fs = require('fs') const path = require('path') const cache = require('@actions/cache') const core = require('@actions/core') const glob = require('@actions/glob') const config = require('./config') const { getFolderSize } = require('./util') async function run() { await stopRemoteCacheServer() await saveCaches() } async function stopRemoteCacheServer() { if (!config.remoteCache.enabled) { return } core.startGroup("Stop remote cache server") const pid = core.getState('remote-cache-server-pid') if (pid) { try { process.kill(pid, 'SIGTERM') core.info(`Stopped remote cache server with PID: ${pid}`) } catch (error) { core.error(`Failed to stop remote cache server with PID: ${pid}. Error: ${error}`) } } const logPath = config.remoteCache.logPath if (fs.existsSync(logPath)) { const logContent = fs.readFileSync(logPath, 'utf8') core.debug(`Remote cache server log:\n${logContent}`) } core.endGroup() } async function saveCaches() { await saveCache(config.bazeliskCache) await saveCache(config.diskCache) await saveCache(config.repositoryCache) await saveExternalCaches(config.externalCache) } async function saveExternalCaches(cacheConfig) { if (!cacheConfig.enabled) { return } const globber = await glob.create( `${config.paths.bazelExternal}/*`, { implicitDescendants: false } ) const externalPaths = await globber.glob() const savedCaches = [] for (const externalPath of externalPaths) { const size = await getFolderSize(externalPath) const sizeMB = (size / 1024 / 1024).toFixed(2) core.debug(`${externalPath} size is ${sizeMB}MB`) if (sizeMB >= cacheConfig.minSize) { const name = path.basename(externalPath) await saveCache({ enabled: cacheConfig[name]?.enabled ?? cacheConfig.default.enabled, files: cacheConfig[name]?.files || cacheConfig.default.files, name: cacheConfig.default.name(name), paths: cacheConfig.default.paths(name) }) savedCaches.push(name) } } if (savedCaches.length > 0) { const path = cacheConfig.manifest.path fs.writeFileSync(path, savedCaches.join('\n')) await saveCache({ enabled: true, files: cacheConfig.manifest.files, name: cacheConfig.manifest.name, paths: [path] }) } } async function saveCache(cacheConfig) { if (!cacheConfig.enabled) { return } const cacheHit = core.getState(`${cacheConfig.name}-cache-hit`) core.debug(`${cacheConfig.name}-cache-hit is ${cacheHit}`) if (cacheHit === 'true') { return } try { core.startGroup(`Save cache for ${cacheConfig.name}`) const paths = cacheConfig.paths const hash = await glob.hashFiles( cacheConfig.files.join('\n'), undefined, // We don't want to follow symlinks as it's extremely slow on macOS. { followSymbolicLinks: false } ) const key = `${config.baseCacheKey}-${cacheConfig.name}-${hash}` core.debug(`Attempting to save ${paths} cache to ${key}`) await cache.saveCache(paths, key) core.info('Successfully saved cache') } catch (error) { core.warning(error.stack) } finally { core.endGroup() } } run()