setup-node/src/cache-utils.ts

142 lines
3.6 KiB
TypeScript
Raw Normal View History

import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as cache from '@actions/cache';
2023-04-10 16:52:10 +02:00
import path from 'path';
type SupportedPackageManagers = {
[prop: string]: PackageManagerInfo;
};
export interface PackageManagerInfo {
lockFilePatterns: Array<string>;
getCacheFolderCommand: string;
}
export const supportedPackageManagers: SupportedPackageManagers = {
npm: {
lockFilePatterns: ['package-lock.json', 'npm-shrinkwrap.json', 'yarn.lock'],
getCacheFolderCommand: 'npm config get cache'
},
2021-06-30 16:44:51 +01:00
pnpm: {
lockFilePatterns: ['pnpm-lock.yaml'],
2022-07-13 16:20:39 +02:00
getCacheFolderCommand: 'pnpm store path --silent'
2021-06-30 16:44:51 +01:00
},
yarn1: {
lockFilePatterns: ['yarn.lock'],
getCacheFolderCommand: 'yarn cache dir'
},
yarn2: {
lockFilePatterns: ['yarn.lock'],
getCacheFolderCommand: 'yarn config get cacheFolder'
}
};
2023-04-10 16:52:10 +02:00
export const getCommandOutput = async (
toolCommand: string,
cwd: string | null
) => {
let {stdout, stderr, exitCode} = await exec.getExecOutput(
toolCommand,
undefined,
2023-04-10 16:52:10 +02:00
{ignoreReturnCode: true, ...(cwd !== null && {cwd})}
);
if (exitCode) {
stderr = !stderr.trim()
? `The '${toolCommand}' command failed with exit code: ${exitCode}`
: stderr;
throw new Error(stderr);
}
2021-06-30 16:44:51 +01:00
return stdout.trim();
};
2023-04-11 08:38:20 +02:00
export const getPackageManagerWorkingDir = (): string | null => {
2023-04-10 16:52:10 +02:00
const cache = core.getInput('cache');
if (cache !== 'yarn') {
return null;
}
const cacheDependencyPath = core.getInput('cache-dependency-path');
return cacheDependencyPath ? path.dirname(cacheDependencyPath) : null;
};
2023-04-24 11:19:22 +02:00
export const getPackageManagerCommandOutput = (command: string) =>
getCommandOutput(command, getPackageManagerWorkingDir());
2023-04-19 16:15:09 +02:00
export const getPackageManagerVersion = async (
packageManager: string,
command: string
) => {
2023-04-24 11:19:22 +02:00
const stdOut = await getPackageManagerCommandOutput(
`${packageManager} ${command}`
2023-04-10 16:52:10 +02:00
);
if (!stdOut) {
throw new Error(`Could not retrieve version of ${packageManager}`);
}
return stdOut;
};
export const getPackageManagerInfo = async (packageManager: string) => {
if (packageManager === 'npm') {
return supportedPackageManagers.npm;
2021-06-30 16:44:51 +01:00
} else if (packageManager === 'pnpm') {
return supportedPackageManagers.pnpm;
} else if (packageManager === 'yarn') {
const yarnVersion = await getPackageManagerVersion('yarn', '--version');
core.debug(`Consumed yarn version is ${yarnVersion}`);
if (yarnVersion.startsWith('1.')) {
return supportedPackageManagers.yarn1;
} else {
return supportedPackageManagers.yarn2;
}
} else {
return null;
}
};
export const getCacheDirectoryPath = async (
packageManagerInfo: PackageManagerInfo,
packageManager: string
) => {
2023-04-24 11:19:22 +02:00
const stdOut = await getPackageManagerCommandOutput(
packageManagerInfo.getCacheFolderCommand
2021-07-15 12:43:19 +01:00
);
if (!stdOut) {
throw new Error(`Could not get cache folder path for ${packageManager}`);
}
core.debug(`${packageManager} path is ${stdOut}`);
2022-07-13 16:20:39 +02:00
return stdOut.trim();
};
export function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
);
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
}
export function isCacheFeatureAvailable(): boolean {
2022-12-09 11:41:54 +01:00
if (cache.isFeatureAvailable()) return true;
2022-12-09 12:05:59 +01:00
if (isGhes()) {
core.warning(
2022-12-09 11:41:54 +01:00
'Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.'
);
2022-12-09 12:05:59 +01:00
return false;
}
2022-12-09 11:41:54 +01:00
core.warning(
'The runner was not able to contact the cache service. Caching will be skipped'
);
2022-12-09 11:41:54 +01:00
return false;
}