From b4911ac176c3400e84fdd901d28a1f9ca13e2ed0 Mon Sep 17 00:00:00 2001 From: Sergey Dolin Date: Mon, 26 Jun 2023 09:42:12 +0200 Subject: [PATCH] Rename functions & add e2e tests --- .github/workflows/e2e-cache.yml | 56 ++++++++++++++++++- ...rojects.sh => prepare-yarn-subprojects.sh} | 7 ++- dist/cache-save/index.js | 30 +++++++--- dist/setup/index.js | 42 ++++++++++---- src/cache-restore.ts | 17 ++++-- src/cache-utils.ts | 36 +++++++++--- 6 files changed, 152 insertions(+), 36 deletions(-) rename __tests__/{prepare-subprojects.sh => prepare-yarn-subprojects.sh} (83%) diff --git a/.github/workflows/e2e-cache.yml b/.github/workflows/e2e-cache.yml index 901ed87cc..c66b63bf0 100644 --- a/.github/workflows/e2e-cache.yml +++ b/.github/workflows/e2e-cache.yml @@ -146,7 +146,7 @@ jobs: - uses: actions/checkout@v3 - name: prepare sub-projects - run: __tests__/prepare-subprojects.sh + run: __tests__/prepare-yarn-subprojects.sh yarn1 # expect # - no errors @@ -161,3 +161,57 @@ jobs: cache-dependency-path: | **/*.lock yarn.lock + + yarn-subprojects-berry-local: + name: Test yarn subprojects all locally managed + strategy: + matrix: + node-version: [12, 14, 16] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: prepare sub-projects + run: __tests__/prepare-yarn-subprojects.sh + + # expect + # - no errors + # - log + # ##[info]All dependencies are managed locally by yarn3, the previous cache can be used + # ##[debug]["node-cache-Linux-yarn-401024703386272f1a950c9f014cbb1bb79a7a5b6e1fb00e8b90d06734af41ee","node-cache-Linux-yarn"] + - name: Setup Node + uses: ./ + with: + node-version: ${{ matrix.node-version }} + cache: 'yarn' + cache-dependency-path: | + sub2/*.lock + sub3/*.lock + + yarn-subprojects-berry-global: + name: Test yarn subprojects some locally managed + strategy: + matrix: + node-version: [12, 14, 16] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: prepare sub-projects + run: __tests__/prepare-yarn-subprojects.sh global + + # expect + # - no errors + # - log must + # ##[debug]"/home/runner/work/setup-node-test/setup-node-test/sub2" dependencies are managed by yarn 3 locally + # ##[debug]"/home/runner/work/setup-node-test/setup-node-test/sub3" dependencies are not managed by yarn 3 locally + - name: Setup Node + uses: ./ + with: + node-version: ${{ matrix.node-version }} + cache: 'yarn' + cache-dependency-path: | + sub2/*.lock + sub3/*.lock diff --git a/__tests__/prepare-subprojects.sh b/__tests__/prepare-yarn-subprojects.sh similarity index 83% rename from __tests__/prepare-subprojects.sh rename to __tests__/prepare-yarn-subprojects.sh index 447cc531a..2054e2941 100755 --- a/__tests__/prepare-subprojects.sh +++ b/__tests__/prepare-yarn-subprojects.sh @@ -33,6 +33,10 @@ EOT yarn set version 3.5.1 yarn install +if [ x$1 = 'xglobal' ];then + echo enableGlobalCache + echo 'enableGlobalCache: true' >> .yarnrc.yml +elif [ x$1 = 'xyarn1' ];then echo "create yarn1 project in the root" cd .. cat <package.json @@ -45,4 +49,5 @@ cat <package.json } EOT yarn set version 1.22.19 -yarn install \ No newline at end of file +yarn install +fi \ No newline at end of file diff --git a/dist/cache-save/index.js b/dist/cache-save/index.js index adcf2d4b1..a32351953 100644 --- a/dist/cache-save/index.js +++ b/dist/cache-save/index.js @@ -60434,7 +60434,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.isCacheFeatureAvailable = exports.isGhes = exports.repoHasYarn3ManagedCache = exports.getCacheDirectories = exports.resetProjectDirectoriesMemoized = exports.getPackageManagerInfo = exports.getCommandOutputNotEmpty = exports.getCommandOutput = exports.supportedPackageManagers = void 0; +exports.isCacheFeatureAvailable = exports.isGhes = exports.repoHasYarnBerryManagedDependencies = exports.getCacheDirectories = exports.resetProjectDirectoriesMemoized = exports.getPackageManagerInfo = exports.getCommandOutputNotEmpty = exports.getCommandOutput = exports.supportedPackageManagers = void 0; const core = __importStar(__nccwpck_require__(2186)); const exec = __importStar(__nccwpck_require__(1514)); const cache = __importStar(__nccwpck_require__(7799)); @@ -60548,7 +60548,7 @@ const getProjectDirectoriesFromCacheDependencyPath = (cacheDependencyPath) => __ const getCacheDirectoriesFromCacheDependencyPath = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { const projectDirectories = yield getProjectDirectoriesFromCacheDependencyPath(cacheDependencyPath); const cacheFoldersPaths = yield Promise.all(projectDirectories.map((projectDirectory) => __awaiter(void 0, void 0, void 0, function* () { - const cacheFolderPath = packageManagerInfo.getCacheFolderPath(projectDirectory); + const cacheFolderPath = yield packageManagerInfo.getCacheFolderPath(projectDirectory); core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"`); return cacheFolderPath; }))); @@ -60592,16 +60592,28 @@ exports.getCacheDirectories = getCacheDirectories; * - if local cache is not explicitly enabled (not yarn3), return false * - return true otherwise */ -const isCacheManagedByYarn3 = (directory) => __awaiter(void 0, void 0, void 0, function* () { +const projectHasYarnBerryManagedDependencies = (directory) => __awaiter(void 0, void 0, void 0, function* () { const workDir = directory || process.env.GITHUB_WORKSPACE || '.'; + core.debug(`check if "${workDir}" has locally managed yarn3 dependencies`); // if .yarn/cache directory exists the cache is managed by version control system const yarnCacheFile = path_1.default.join(workDir, '.yarn', 'cache'); - if (fs_1.default.existsSync(yarnCacheFile) && fs_1.default.lstatSync(yarnCacheFile).isDirectory()) + if (fs_1.default.existsSync(yarnCacheFile) && + fs_1.default.lstatSync(yarnCacheFile).isDirectory()) { + core.debug(`"${workDir}" has .yarn/cache - dependencies are kept in the repository`); return Promise.resolve(false); - // NOTE: yarn1 returns 'undefined' with rc = 0 + } + // NOTE: yarn1 returns 'undefined' with return code = 0 const enableGlobalCache = yield exports.getCommandOutput('yarn config get enableGlobalCache', workDir); // only local cache is not managed by yarn - return enableGlobalCache === 'false'; + const managed = enableGlobalCache.includes('false'); + if (managed) { + core.debug(`"${workDir}" dependencies are managed by yarn 3 locally`); + return true; + } + else { + core.debug(`"${workDir}" dependencies are not managed by yarn 3 locally`); + return false; + } }); /** * A function to report the repo contains Yarn managed projects @@ -60610,16 +60622,16 @@ const isCacheManagedByYarn3 = (directory) => __awaiter(void 0, void 0, void 0, f * expected to be the result of `core.getInput('cache-dependency-path')` * @return - true if all project directories configured to be Yarn managed */ -const repoHasYarn3ManagedCache = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { +const repoHasYarnBerryManagedDependencies = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { if (packageManagerInfo.name !== 'yarn') return false; const yarnDirs = cacheDependencyPath ? yield getProjectDirectoriesFromCacheDependencyPath(cacheDependencyPath) : ['']; - const isManagedList = yield Promise.all(yarnDirs.map(isCacheManagedByYarn3)); + const isManagedList = yield Promise.all(yarnDirs.map(projectHasYarnBerryManagedDependencies)); return isManagedList.every(Boolean); }); -exports.repoHasYarn3ManagedCache = repoHasYarn3ManagedCache; +exports.repoHasYarnBerryManagedDependencies = repoHasYarnBerryManagedDependencies; function isGhes() { const ghUrl = new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com'); return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM'; diff --git a/dist/setup/index.js b/dist/setup/index.js index 0bbe9052f..b776c5619 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -71157,9 +71157,15 @@ const restoreCache = (packageManager, cacheDependencyPath) => __awaiter(void 0, const primaryKey = `${keyPrefix}-${fileHash}`; core.debug(`primary key is ${primaryKey}`); core.saveState(constants_1.State.CachePrimaryKey, primaryKey); - const cacheKey = (yield cache_utils_1.repoHasYarn3ManagedCache(packageManagerInfo, cacheDependencyPath)) - ? yield cache.restoreCache(cachePaths, primaryKey, [keyPrefix]) - : yield cache.restoreCache(cachePaths, primaryKey); + const isManagedByYarn3 = yield cache_utils_1.repoHasYarnBerryManagedDependencies(packageManagerInfo, cacheDependencyPath); + let cacheKey; + if (isManagedByYarn3) { + core.info('All dependencies are managed locally by yarn3, the previous cache can be used'); + cacheKey = yield cache.restoreCache(cachePaths, primaryKey, [keyPrefix]); + } + else { + cacheKey = yield cache.restoreCache(cachePaths, primaryKey); + } core.setOutput('cache-hit', Boolean(cacheKey)); if (!cacheKey) { core.info(`${packageManager} cache is not found`); @@ -71220,7 +71226,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.isCacheFeatureAvailable = exports.isGhes = exports.repoHasYarn3ManagedCache = exports.getCacheDirectories = exports.resetProjectDirectoriesMemoized = exports.getPackageManagerInfo = exports.getCommandOutputNotEmpty = exports.getCommandOutput = exports.supportedPackageManagers = void 0; +exports.isCacheFeatureAvailable = exports.isGhes = exports.repoHasYarnBerryManagedDependencies = exports.getCacheDirectories = exports.resetProjectDirectoriesMemoized = exports.getPackageManagerInfo = exports.getCommandOutputNotEmpty = exports.getCommandOutput = exports.supportedPackageManagers = void 0; const core = __importStar(__nccwpck_require__(2186)); const exec = __importStar(__nccwpck_require__(1514)); const cache = __importStar(__nccwpck_require__(7799)); @@ -71334,7 +71340,7 @@ const getProjectDirectoriesFromCacheDependencyPath = (cacheDependencyPath) => __ const getCacheDirectoriesFromCacheDependencyPath = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { const projectDirectories = yield getProjectDirectoriesFromCacheDependencyPath(cacheDependencyPath); const cacheFoldersPaths = yield Promise.all(projectDirectories.map((projectDirectory) => __awaiter(void 0, void 0, void 0, function* () { - const cacheFolderPath = packageManagerInfo.getCacheFolderPath(projectDirectory); + const cacheFolderPath = yield packageManagerInfo.getCacheFolderPath(projectDirectory); core.debug(`${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"`); return cacheFolderPath; }))); @@ -71378,16 +71384,28 @@ exports.getCacheDirectories = getCacheDirectories; * - if local cache is not explicitly enabled (not yarn3), return false * - return true otherwise */ -const isCacheManagedByYarn3 = (directory) => __awaiter(void 0, void 0, void 0, function* () { +const projectHasYarnBerryManagedDependencies = (directory) => __awaiter(void 0, void 0, void 0, function* () { const workDir = directory || process.env.GITHUB_WORKSPACE || '.'; + core.debug(`check if "${workDir}" has locally managed yarn3 dependencies`); // if .yarn/cache directory exists the cache is managed by version control system const yarnCacheFile = path_1.default.join(workDir, '.yarn', 'cache'); - if (fs_1.default.existsSync(yarnCacheFile) && fs_1.default.lstatSync(yarnCacheFile).isDirectory()) + if (fs_1.default.existsSync(yarnCacheFile) && + fs_1.default.lstatSync(yarnCacheFile).isDirectory()) { + core.debug(`"${workDir}" has .yarn/cache - dependencies are kept in the repository`); return Promise.resolve(false); - // NOTE: yarn1 returns 'undefined' with rc = 0 + } + // NOTE: yarn1 returns 'undefined' with return code = 0 const enableGlobalCache = yield exports.getCommandOutput('yarn config get enableGlobalCache', workDir); // only local cache is not managed by yarn - return enableGlobalCache === 'false'; + const managed = enableGlobalCache.includes('false'); + if (managed) { + core.debug(`"${workDir}" dependencies are managed by yarn 3 locally`); + return true; + } + else { + core.debug(`"${workDir}" dependencies are not managed by yarn 3 locally`); + return false; + } }); /** * A function to report the repo contains Yarn managed projects @@ -71396,16 +71414,16 @@ const isCacheManagedByYarn3 = (directory) => __awaiter(void 0, void 0, void 0, f * expected to be the result of `core.getInput('cache-dependency-path')` * @return - true if all project directories configured to be Yarn managed */ -const repoHasYarn3ManagedCache = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { +const repoHasYarnBerryManagedDependencies = (packageManagerInfo, cacheDependencyPath) => __awaiter(void 0, void 0, void 0, function* () { if (packageManagerInfo.name !== 'yarn') return false; const yarnDirs = cacheDependencyPath ? yield getProjectDirectoriesFromCacheDependencyPath(cacheDependencyPath) : ['']; - const isManagedList = yield Promise.all(yarnDirs.map(isCacheManagedByYarn3)); + const isManagedList = yield Promise.all(yarnDirs.map(projectHasYarnBerryManagedDependencies)); return isManagedList.every(Boolean); }); -exports.repoHasYarn3ManagedCache = repoHasYarn3ManagedCache; +exports.repoHasYarnBerryManagedDependencies = repoHasYarnBerryManagedDependencies; function isGhes() { const ghUrl = new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com'); return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM'; diff --git a/src/cache-restore.ts b/src/cache-restore.ts index 3342ddc30..283cdd412 100644 --- a/src/cache-restore.ts +++ b/src/cache-restore.ts @@ -8,7 +8,7 @@ import {State} from './constants'; import { getCacheDirectories, getPackageManagerInfo, - repoHasYarn3ManagedCache, + repoHasYarnBerryManagedDependencies, PackageManagerInfo } from './cache-utils'; @@ -44,12 +44,19 @@ export const restoreCache = async ( core.saveState(State.CachePrimaryKey, primaryKey); - const cacheKey = (await repoHasYarn3ManagedCache( + const isManagedByYarn3 = await repoHasYarnBerryManagedDependencies( packageManagerInfo, cacheDependencyPath - )) - ? await cache.restoreCache(cachePaths, primaryKey, [keyPrefix]) - : await cache.restoreCache(cachePaths, primaryKey); + ); + let cacheKey: string | undefined; + if (isManagedByYarn3) { + core.info( + 'All dependencies are managed locally by yarn3, the previous cache can be used' + ); + cacheKey = await cache.restoreCache(cachePaths, primaryKey, [keyPrefix]); + } else { + cacheKey = await cache.restoreCache(cachePaths, primaryKey); + } core.setOutput('cache-hit', Boolean(cacheKey)); diff --git a/src/cache-utils.ts b/src/cache-utils.ts index c7f55670d..8d25c36d5 100644 --- a/src/cache-utils.ts +++ b/src/cache-utils.ts @@ -171,8 +171,9 @@ const getCacheDirectoriesFromCacheDependencyPath = async ( ); const cacheFoldersPaths = await Promise.all( projectDirectories.map(async projectDirectory => { - const cacheFolderPath = - packageManagerInfo.getCacheFolderPath(projectDirectory); + const cacheFolderPath = await packageManagerInfo.getCacheFolderPath( + projectDirectory + ); core.debug( `${packageManagerInfo.name}'s cache folder "${cacheFolderPath}" configured for the directory "${projectDirectory}"` ); @@ -231,21 +232,38 @@ export const getCacheDirectories = async ( * - if local cache is not explicitly enabled (not yarn3), return false * - return true otherwise */ -const isCacheManagedByYarn3 = async (directory: string): Promise => { +const projectHasYarnBerryManagedDependencies = async ( + directory: string +): Promise => { const workDir = directory || process.env.GITHUB_WORKSPACE || '.'; + core.debug(`check if "${workDir}" has locally managed yarn3 dependencies`); // if .yarn/cache directory exists the cache is managed by version control system const yarnCacheFile = path.join(workDir, '.yarn', 'cache'); - if (fs.existsSync(yarnCacheFile) && fs.lstatSync(yarnCacheFile).isDirectory()) + if ( + fs.existsSync(yarnCacheFile) && + fs.lstatSync(yarnCacheFile).isDirectory() + ) { + core.debug( + `"${workDir}" has .yarn/cache - dependencies are kept in the repository` + ); return Promise.resolve(false); + } - // NOTE: yarn1 returns 'undefined' with rc = 0 + // NOTE: yarn1 returns 'undefined' with return code = 0 const enableGlobalCache = await getCommandOutput( 'yarn config get enableGlobalCache', workDir ); // only local cache is not managed by yarn - return enableGlobalCache === 'false'; + const managed = enableGlobalCache.includes('false'); + if (managed) { + core.debug(`"${workDir}" dependencies are managed by yarn 3 locally`); + return true; + } else { + core.debug(`"${workDir}" dependencies are not managed by yarn 3 locally`); + return false; + } }; /** @@ -255,7 +273,7 @@ const isCacheManagedByYarn3 = async (directory: string): Promise => { * expected to be the result of `core.getInput('cache-dependency-path')` * @return - true if all project directories configured to be Yarn managed */ -export const repoHasYarn3ManagedCache = async ( +export const repoHasYarnBerryManagedDependencies = async ( packageManagerInfo: PackageManagerInfo, cacheDependencyPath: string ): Promise => { @@ -265,7 +283,9 @@ export const repoHasYarn3ManagedCache = async ( ? await getProjectDirectoriesFromCacheDependencyPath(cacheDependencyPath) : ['']; - const isManagedList = await Promise.all(yarnDirs.map(isCacheManagedByYarn3)); + const isManagedList = await Promise.all( + yarnDirs.map(projectHasYarnBerryManagedDependencies) + ); return isManagedList.every(Boolean); };