Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caching on GHES #452

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .licenses/npm/@actions/cache.dep.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions __tests__/cache-restore.test.ts
Expand Up @@ -50,6 +50,7 @@ describe('cache-restore', () => {
let debugSpy: jest.SpyInstance;
let setOutputSpy: jest.SpyInstance;
let getCommandOutputSpy: jest.SpyInstance;
let isCacheActionAvailable: jest.SpyInstance;
let restoreCacheSpy: jest.SpyInstance;
let hashFilesSpy: jest.SpyInstance;

Expand Down Expand Up @@ -102,6 +103,9 @@ describe('cache-restore', () => {

// cache-utils
getCommandOutputSpy = jest.spyOn(utils, 'getCommandOutput');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change and L53 change is required? Because I think in restore restoreCache function we don't check isCacheActionAvailable functions. This we are checking in main.ts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thank you.

isCacheActionAvailable = jest.spyOn(utils, 'isCacheFeatureAvailable');
isCacheActionAvailable.mockImplementation(() => true);
});

describe('Validate provided package manager', () => {
Expand Down
4 changes: 4 additions & 0 deletions __tests__/cache-save.test.ts
Expand Up @@ -28,6 +28,7 @@ describe('run', () => {
let getStateSpy: jest.SpyInstance;
let saveCacheSpy: jest.SpyInstance;
let getCommandOutputSpy: jest.SpyInstance;
let isCacheActionAvailable: jest.SpyInstance;
let hashFilesSpy: jest.SpyInstance;
let existsSpy: jest.SpyInstance;

Expand Down Expand Up @@ -70,6 +71,9 @@ describe('run', () => {

// utils
getCommandOutputSpy = jest.spyOn(utils, 'getCommandOutput');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above comment. Is this change required here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thank you.

isCacheActionAvailable = jest.spyOn(utils, 'isCacheFeatureAvailable');
isCacheActionAvailable.mockImplementation(() => true);
});

afterEach(() => {
Expand Down
55 changes: 36 additions & 19 deletions __tests__/cache-utils.test.ts
@@ -1,37 +1,26 @@
import * as core from '@actions/core';
import * as cache from '@actions/cache';
import path from 'path';
import * as utils from '../src/cache-utils';
import {PackageManagerInfo} from '../src/cache-utils';
import {PackageManagerInfo, isCacheFeatureAvailable} from '../src/cache-utils';

describe('cache-utils', () => {
const commonPath = '/some/random/path';
const versionYarn1 = '1.2.3';
const versionYarn2 = '2.3.4';

let debugSpy: jest.SpyInstance;
let getCommandOutputSpy: jest.SpyInstance;

function getPackagePath(name: string) {
if (name === utils.supportedPackageManagers.npm.getCacheFolderCommand) {
return `${commonPath}/npm`;
} else if (
name === utils.supportedPackageManagers.pnpm.getCacheFolderCommand
) {
return `${commonPath}/pnpm`;
} else {
if (name === utils.supportedPackageManagers.yarn1.getCacheFolderCommand) {
return `${commonPath}/yarn1`;
} else {
return `${commonPath}/yarn2`;
}
}
}
let isFeatureAvailable: jest.SpyInstance;
let info: jest.SpyInstance;

beforeEach(() => {
process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data');
debugSpy = jest.spyOn(core, 'debug');
debugSpy.mockImplementation(msg => {});

info = jest.spyOn(core, 'info');

isFeatureAvailable = jest.spyOn(cache, 'isFeatureAvailable');

getCommandOutputSpy = jest.spyOn(utils, 'getCommandOutput');
});

Expand All @@ -51,7 +40,35 @@ describe('cache-utils', () => {
});
});

it('isCacheFeatureAvailable is false', () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the description, Please add whether the scenario is of GHES or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thank you.

isFeatureAvailable.mockImplementation(() => false);
process.env['GITHUB_SERVER_URL'] = 'https://www.test.com';

expect(isCacheFeatureAvailable()).toBe(false);
expect(info).toHaveBeenCalledWith(
'[warning]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.'
);
});

it('isCacheFeatureAvailable is false', () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thank you.

isFeatureAvailable.mockImplementation(() => false);
process.env['GITHUB_SERVER_URL'] = '';

expect(isCacheFeatureAvailable()).toBe(false);
expect(info).toHaveBeenCalledWith(
'[warning]An internal error has occurred in cache backend. Please check https://www.githubstatus.com/ for any ongoing issue in actions.'
);
});

it('isCacheFeatureAvailable is true', () => {
isFeatureAvailable.mockImplementation(() => true);

expect(isCacheFeatureAvailable()).toBe(true);
expect(info).not.toHaveBeenCalled();
});

afterEach(() => {
process.env['GITHUB_SERVER_URL'] = '';
jest.resetAllMocks();
jest.clearAllMocks();
});
Expand Down
40 changes: 35 additions & 5 deletions dist/cache-save/index.js
Expand Up @@ -3139,10 +3139,7 @@ const options_1 = __webpack_require__(248);
const requestUtils_1 = __webpack_require__(826);
const versionSalt = '1.0';
function getCacheApiUrl(resource) {
// Ideally we just use ACTIONS_CACHE_URL
const baseUrl = (process.env['ACTIONS_CACHE_URL'] ||
process.env['ACTIONS_RUNTIME_URL'] ||
'').replace('pipelines', 'artifactcache');
const baseUrl = process.env['ACTIONS_CACHE_URL'] || '';
if (!baseUrl) {
throw new Error('Cache Service Url not found, unable to restore cache.');
}
Expand Down Expand Up @@ -3811,6 +3808,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(__webpack_require__(470));
const exec = __importStar(__webpack_require__(986));
const cache = __importStar(__webpack_require__(692));
exports.supportedPackageManagers = {
npm: {
lockFilePatterns: ['package-lock.json', 'yarn.lock'],
Expand Down Expand Up @@ -3875,6 +3873,28 @@ exports.getCacheDirectoryPath = (packageManagerInfo, packageManager) => __awaite
core.debug(`${packageManager} path is ${stdOut}`);
return stdOut;
});
function logWarning(message) {
const warningPrefix = '[warning]';
core.info(`${warningPrefix}${message}`);
}
function isGhes() {
const ghUrl = new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
}
exports.isGhes = isGhes;
function isCacheFeatureAvailable() {
if (!cache.isFeatureAvailable()) {
if (isGhes()) {
logWarning('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.');
}
else {
logWarning('An internal error has occurred in cache backend. Please check https://www.githubstatus.com/ for any ongoing issue in actions.');
}
return false;
}
return true;
}
exports.isCacheFeatureAvailable = isCacheFeatureAvailable;


/***/ }),
Expand Down Expand Up @@ -5703,7 +5723,8 @@ function downloadCacheStorageSDK(archiveLocation, archivePath, options) {
//
// If the file exceeds the buffer maximum length (~1 GB on 32-bit systems and ~2 GB
// on 64-bit systems), split the download into multiple segments
const maxSegmentSize = buffer.constants.MAX_LENGTH;
// ~2 GB = 2147483647, beyond this, we start getting out of range error. So, capping it accordingly.
const maxSegmentSize = Math.min(2147483647, buffer.constants.MAX_LENGTH);
const downloadProgress = new DownloadProgress(contentLength);
const fd = fs.openSync(archivePath, 'w');
try {
Expand Down Expand Up @@ -43258,6 +43279,15 @@ function checkKey(key) {
throw new ValidationError(`Key Validation Error: ${key} cannot contain commas.`);
}
}
/**
* isFeatureAvailable to check the presence of Actions cache service
*
* @returns boolean return true if Actions cache service feature is available, otherwise false
*/
function isFeatureAvailable() {
return !!process.env['ACTIONS_CACHE_URL'];
}
exports.isFeatureAvailable = isFeatureAvailable;
/**
* Restores cache from keys
*
Expand Down
50 changes: 38 additions & 12 deletions dist/setup/index.js
Expand Up @@ -5410,10 +5410,7 @@ const options_1 = __webpack_require__(161);
const requestUtils_1 = __webpack_require__(246);
const versionSalt = '1.0';
function getCacheApiUrl(resource) {
// Ideally we just use ACTIONS_CACHE_URL
const baseUrl = (process.env['ACTIONS_CACHE_URL'] ||
process.env['ACTIONS_RUNTIME_URL'] ||
'').replace('pipelines', 'artifactcache');
const baseUrl = process.env['ACTIONS_CACHE_URL'] || '';
if (!baseUrl) {
throw new Error('Cache Service Url not found, unable to restore cache.');
}
Expand Down Expand Up @@ -6588,7 +6585,7 @@ const fs_1 = __importDefault(__webpack_require__(747));
const auth = __importStar(__webpack_require__(749));
const path = __importStar(__webpack_require__(622));
const cache_restore_1 = __webpack_require__(409);
const url_1 = __webpack_require__(835);
const cache_utils_1 = __webpack_require__(570);
const os = __webpack_require__(87);
function run() {
return __awaiter(this, void 0, void 0, function* () {
Expand All @@ -6610,7 +6607,7 @@ function run() {
}
if (version) {
let token = core.getInput('token');
let auth = !token || isGhes() ? undefined : `token ${token}`;
let auth = !token || cache_utils_1.isGhes() ? undefined : `token ${token}`;
let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE';
const checkLatest = (core.getInput('check-latest') || 'false').toUpperCase() === 'TRUE';
yield installer.getNode(version, stable, checkLatest, auth, arch);
Expand All @@ -6621,7 +6618,7 @@ function run() {
auth.configAuthentication(registryUrl, alwaysAuth);
}
if (cache) {
if (isGhes()) {
if (!cache_utils_1.isCacheFeatureAvailable()) {
throw new Error('Caching is not supported on GHES');
}
const cacheDependencyPath = core.getInput('cache-dependency-path');
Expand All @@ -6638,10 +6635,6 @@ function run() {
});
}
exports.run = run;
function isGhes() {
const ghUrl = new url_1.URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
}
function resolveVersionInput() {
let version = core.getInput('node-version');
const versionFileInput = core.getInput('node-version-file');
Expand Down Expand Up @@ -9525,7 +9518,8 @@ function downloadCacheStorageSDK(archiveLocation, archivePath, options) {
//
// If the file exceeds the buffer maximum length (~1 GB on 32-bit systems and ~2 GB
// on 64-bit systems), split the download into multiple segments
const maxSegmentSize = buffer.constants.MAX_LENGTH;
// ~2 GB = 2147483647, beyond this, we start getting out of range error. So, capping it accordingly.
const maxSegmentSize = Math.min(2147483647, buffer.constants.MAX_LENGTH);
const downloadProgress = new DownloadProgress(contentLength);
const fd = fs.openSync(archivePath, 'w');
try {
Expand Down Expand Up @@ -46070,6 +46064,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(__webpack_require__(470));
const exec = __importStar(__webpack_require__(986));
const cache = __importStar(__webpack_require__(638));
exports.supportedPackageManagers = {
npm: {
lockFilePatterns: ['package-lock.json', 'yarn.lock'],
Expand Down Expand Up @@ -46134,6 +46129,28 @@ exports.getCacheDirectoryPath = (packageManagerInfo, packageManager) => __awaite
core.debug(`${packageManager} path is ${stdOut}`);
return stdOut;
});
function logWarning(message) {
const warningPrefix = '[warning]';
core.info(`${warningPrefix}${message}`);
}
function isGhes() {
const ghUrl = new URL(process.env['GITHUB_SERVER_URL'] || 'https://github.com');
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
}
exports.isGhes = isGhes;
function isCacheFeatureAvailable() {
if (!cache.isFeatureAvailable()) {
if (isGhes()) {
logWarning('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.');
}
else {
logWarning('An internal error has occurred in cache backend. Please check https://www.githubstatus.com/ for any ongoing issue in actions.');
}
return false;
}
return true;
}
exports.isCacheFeatureAvailable = isCacheFeatureAvailable;


/***/ }),
Expand Down Expand Up @@ -47526,6 +47543,15 @@ function checkKey(key) {
throw new ValidationError(`Key Validation Error: ${key} cannot contain commas.`);
}
}
/**
* isFeatureAvailable to check the presence of Actions cache service
*
* @returns boolean return true if Actions cache service feature is available, otherwise false
*/
function isFeatureAvailable() {
return !!process.env['ACTIONS_CACHE_URL'];
}
exports.isFeatureAvailable = isFeatureAvailable;
/**
* Restores cache from keys
*
Expand Down
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -23,7 +23,7 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/cache": "^1.0.8",
"@actions/cache": "^2.0.0",
"@actions/core": "^1.6.0",
"@actions/exec": "^1.1.0",
"@actions/github": "^1.1.0",
Expand Down