@@ -71153,10 +71153,19 @@ const restoreCache = (packageManager, cacheDependencyPath) => __awaiter(void 0,
7115371153 if (!fileHash) {
7115471154 throw new Error('Some specified paths were not resolved, unable to cache dependencies.');
7115571155 }
71156- const primaryKey = `node-cache-${platform}-${packageManager}-${fileHash}`;
71156+ const keyPrefix = `node-cache-${platform}-${packageManager}`;
71157+ const primaryKey = `${keyPrefix}-${fileHash}`;
7115771158 core.debug(`primary key is ${primaryKey}`);
7115871159 core.saveState(constants_1.State.CachePrimaryKey, primaryKey);
71159- const cacheKey = yield cache.restoreCache(cachePaths, primaryKey);
71160+ const isManagedByYarnBerry = yield cache_utils_1.repoHasYarnBerryManagedDependencies(packageManagerInfo, cacheDependencyPath);
71161+ let cacheKey;
71162+ if (isManagedByYarnBerry) {
71163+ core.info('All dependencies are managed locally by yarn3, the previous cache can be used');
71164+ cacheKey = yield cache.restoreCache(cachePaths, primaryKey, [keyPrefix]);
71165+ }
71166+ else {
71167+ cacheKey = yield cache.restoreCache(cachePaths, primaryKey);
71168+ }
7116071169 core.setOutput('cache-hit', Boolean(cacheKey));
7116171170 if (!cacheKey) {
7116271171 core.info(`${packageManager} cache is not found`);
@@ -71217,7 +71226,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
7121771226 return (mod && mod.__esModule) ? mod : { "default": mod };
7121871227};
7121971228Object.defineProperty(exports, "__esModule", ({ value: true }));
71220- exports.isCacheFeatureAvailable = exports.isGhes = exports.getCacheDirectories = exports.getPackageManagerInfo = exports.getCommandOutputNotEmpty = exports.getCommandOutput = exports.supportedPackageManagers = void 0;
71229+ exports.isCacheFeatureAvailable = exports.isGhes = exports.repoHasYarnBerryManagedDependencies = exports. getCacheDirectories = exports.resetProjectDirectoriesMemoized = exports.getPackageManagerInfo = exports.getCommandOutputNotEmpty = exports.getCommandOutput = exports.supportedPackageManagers = void 0;
7122171230const core = __importStar(__nccwpck_require__(2186));
7122271231const exec = __importStar(__nccwpck_require__(1514));
7122371232const cache = __importStar(__nccwpck_require__(7799));
@@ -71286,6 +71295,19 @@ const getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, void
7128671295 }
7128771296});
7128871297exports.getPackageManagerInfo = getPackageManagerInfo;
71298+ /**
71299+ * getProjectDirectoriesFromCacheDependencyPath is called twice during `restoreCache`
71300+ * - first through `getCacheDirectories`
71301+ * - second from `repoHasYarn3ManagedCache`
71302+ *
71303+ * it contains expensive IO operation and thus should be memoized
71304+ */
71305+ let projectDirectoriesMemoized = null;
71306+ /**
71307+ * unit test must reset memoized variables
71308+ */
71309+ const resetProjectDirectoriesMemoized = () => (projectDirectoriesMemoized = null);
71310+ exports.resetProjectDirectoriesMemoized = resetProjectDirectoriesMemoized;
7128971311/**
7129071312 * Expands (converts) the string input `cache-dependency-path` to list of directories that
7129171313 * may be project roots
@@ -71294,6 +71316,9 @@ exports.getPackageManagerInfo = getPackageManagerInfo;
7129471316 * @return list of directories and possible
7129571317 */
7129671318const getProjectDirectoriesFromCacheDependencyPath = (cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () {
71319+ if (projectDirectoriesMemoized !== null) {
71320+ return projectDirectoriesMemoized;
71321+ }
7129771322 const globber = yield glob.create(cacheDependencyPath);
7129871323 const cacheDependenciesPaths = yield globber.glob();
7129971324 const existingDirectories = cacheDependenciesPaths
@@ -71302,6 +71327,7 @@ const getProjectDirectoriesFromCacheDependencyPath = (cacheDependencyPath) => __
7130271327 .filter(directory => fs_1.default.lstatSync(directory).isDirectory());
7130371328 if (!existingDirectories.length)
7130471329 core.warning(`No existing directories found containing cache-dependency-path="${cacheDependencyPath}"`);
71330+ projectDirectoriesMemoized = existingDirectories;
7130571331 return existingDirectories;
7130671332});
7130771333/**
@@ -71314,7 +71340,7 @@ const getProjectDirectoriesFromCacheDependencyPath = (cacheDependencyPath) => __
7131471340const getCacheDirectoriesFromCacheDependencyPath = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () {
7131571341 const projectDirectories = yield getProjectDirectoriesFromCacheDependencyPath(cacheDependencyPath);
7131671342 const cacheFoldersPaths = yield Promise.all(projectDirectories.map((projectDirectory) => __awaiter(void 0, void 0, void 0, function* () {
71317- const cacheFolderPath = packageManagerInfo.getCacheFolderPath(projectDirectory);
71343+ const cacheFolderPath = yield packageManagerInfo.getCacheFolderPath(projectDirectory);
7131871344 core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"`);
7131971345 return cacheFolderPath;
7132071346 })));
@@ -71348,6 +71374,56 @@ const getCacheDirectories = (packageManagerInfo, cacheDependencyPath) => __await
7134871374 return getCacheDirectoriesForRootProject(packageManagerInfo);
7134971375});
7135071376exports.getCacheDirectories = getCacheDirectories;
71377+ /**
71378+ * A function to check if the directory is a yarn project configured to manage
71379+ * obsolete dependencies in the local cache
71380+ * @param directory - a path to the folder
71381+ * @return - true if the directory's project is yarn managed
71382+ * - if there's .yarn/cache folder do not mess with the dependencies kept in the repo, return false
71383+ * - global cache is not managed by yarn @see https://yarnpkg.com/features/offline-cache, return false
71384+ * - if local cache is not explicitly enabled (not yarn3), return false
71385+ * - return true otherwise
71386+ */
71387+ const projectHasYarnBerryManagedDependencies = (directory) => __awaiter(void 0, void 0, void 0, function* () {
71388+ const workDir = directory || process.env.GITHUB_WORKSPACE || '.';
71389+ core.debug(`check if "${workDir}" has locally managed yarn3 dependencies`);
71390+ // if .yarn/cache directory exists the cache is managed by version control system
71391+ const yarnCacheFile = path_1.default.join(workDir, '.yarn', 'cache');
71392+ if (fs_1.default.existsSync(yarnCacheFile) &&
71393+ fs_1.default.lstatSync(yarnCacheFile).isDirectory()) {
71394+ core.debug(`"${workDir}" has .yarn/cache - dependencies are kept in the repository`);
71395+ return Promise.resolve(false);
71396+ }
71397+ // NOTE: yarn1 returns 'undefined' with return code = 0
71398+ const enableGlobalCache = yield exports.getCommandOutput('yarn config get enableGlobalCache', workDir);
71399+ // only local cache is not managed by yarn
71400+ const managed = enableGlobalCache.includes('false');
71401+ if (managed) {
71402+ core.debug(`"${workDir}" dependencies are managed by yarn 3 locally`);
71403+ return true;
71404+ }
71405+ else {
71406+ core.debug(`"${workDir}" dependencies are not managed by yarn 3 locally`);
71407+ return false;
71408+ }
71409+ });
71410+ /**
71411+ * A function to report the repo contains Yarn managed projects
71412+ * @param packageManagerInfo - used to make sure current package manager is yarn
71413+ * @param cacheDependencyPath - either a single string or multiline string with possible glob patterns
71414+ * expected to be the result of `core.getInput('cache-dependency-path')`
71415+ * @return - true if all project directories configured to be Yarn managed
71416+ */
71417+ const repoHasYarnBerryManagedDependencies = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () {
71418+ if (packageManagerInfo.name !== 'yarn')
71419+ return false;
71420+ const yarnDirs = cacheDependencyPath
71421+ ? yield getProjectDirectoriesFromCacheDependencyPath(cacheDependencyPath)
71422+ : [''];
71423+ const isManagedList = yield Promise.all(yarnDirs.map(projectHasYarnBerryManagedDependencies));
71424+ return isManagedList.every(Boolean);
71425+ });
71426+ exports.repoHasYarnBerryManagedDependencies = repoHasYarnBerryManagedDependencies;
7135171427function isGhes() {
7135271428 const ghUrl = new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
7135371429 return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
0 commit comments