add support for ghes caching

This commit is contained in:
Dmitry Shibanov 2022-03-29 11:29:58 +02:00
parent bed538bd04
commit 7af0f4d168
9 changed files with 161 additions and 57 deletions

View file

@ -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;
@ -102,6 +103,9 @@ describe('cache-restore', () => {
// cache-utils
getCommandOutputSpy = jest.spyOn(utils, 'getCommandOutput');
isCacheActionAvailable = jest.spyOn(utils, 'isCacheFeatureAvailable');
isCacheActionAvailable.mockImplementation(() => true);
});
describe('Validate provided package manager', () => {

View file

@ -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;
@ -70,6 +71,9 @@ describe('run', () => {
// utils
getCommandOutputSpy = jest.spyOn(utils, 'getCommandOutput');
isCacheActionAvailable = jest.spyOn(utils, 'isCacheFeatureAvailable');
isCacheActionAvailable.mockImplementation(() => true);
});
afterEach(() => {

View file

@ -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');
});
@ -51,7 +40,35 @@ describe('cache-utils', () => {
});
});
it('isCacheFeatureAvailable is false', () => {
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', () => {
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();
});

View file

@ -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.');
}
@ -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'],
@ -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;
/***/ }),
@ -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 {
@ -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
*

50
dist/setup/index.js vendored
View file

@ -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.');
}
@ -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* () {
@ -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);
@ -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');
@ -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');
@ -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 {
@ -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'],
@ -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;
/***/ }),
@ -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
*

22
package-lock.json generated
View file

@ -9,7 +9,7 @@
"version": "2.0.0",
"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",
@ -32,17 +32,17 @@
}
},
"node_modules/@actions/cache": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-1.0.8.tgz",
"integrity": "sha512-GWNNB67w93HGJRQXlsV56YqrdAuDoP3esK/mo5mzU8WoDCVjtQgJGsTdkYUX7brswtT7xnI30bWNo1WLKQ8FZQ==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-2.0.0.tgz",
"integrity": "sha512-d7n8ul6HjWX6oDrNEPoqn8ZvqyyDhp9Uek6WOxALyxGVsXU+8+ND+viD3UfrXVWfs/GQiqI5Eq4cOozZj0yRFQ==",
"dependencies": {
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.1",
"@actions/glob": "^0.1.0",
"@actions/http-client": "^1.0.9",
"@actions/io": "^1.0.1",
"@azure/ms-rest-js": "^2.0.7",
"@azure/storage-blob": "^12.1.2",
"@azure/ms-rest-js": "^2.6.0",
"@azure/storage-blob": "^12.8.0",
"semver": "^6.1.0",
"uuid": "^3.3.3"
}
@ -5077,17 +5077,17 @@
},
"dependencies": {
"@actions/cache": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-1.0.8.tgz",
"integrity": "sha512-GWNNB67w93HGJRQXlsV56YqrdAuDoP3esK/mo5mzU8WoDCVjtQgJGsTdkYUX7brswtT7xnI30bWNo1WLKQ8FZQ==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-2.0.0.tgz",
"integrity": "sha512-d7n8ul6HjWX6oDrNEPoqn8ZvqyyDhp9Uek6WOxALyxGVsXU+8+ND+viD3UfrXVWfs/GQiqI5Eq4cOozZj0yRFQ==",
"requires": {
"@actions/core": "^1.2.6",
"@actions/exec": "^1.0.1",
"@actions/glob": "^0.1.0",
"@actions/http-client": "^1.0.9",
"@actions/io": "^1.0.1",
"@azure/ms-rest-js": "^2.0.7",
"@azure/storage-blob": "^12.1.2",
"@azure/ms-rest-js": "^2.6.0",
"@azure/storage-blob": "^12.8.0",
"semver": "^6.1.0",
"uuid": "^3.3.3"
},

View file

@ -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",

View file

@ -1,5 +1,6 @@
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as cache from '@actions/cache';
type SupportedPackageManagers = {
[prop: string]: PackageManagerInfo;
@ -95,3 +96,32 @@ export const getCacheDirectoryPath = async (
return stdOut;
};
function logWarning(message: string): void {
const warningPrefix = '[warning]';
core.info(`${warningPrefix}${message}`);
}
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 {
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;
}

View file

@ -4,7 +4,7 @@ import fs from 'fs';
import * as auth from './authutil';
import * as path from 'path';
import {restoreCache} from './cache-restore';
import {URL} from 'url';
import {isGhes, isCacheFeatureAvailable} from './cache-utils';
import os = require('os');
export async function run() {
@ -46,7 +46,7 @@ export async function run() {
}
if (cache) {
if (isGhes()) {
if (!isCacheFeatureAvailable()) {
throw new Error('Caching is not supported on GHES');
}
const cacheDependencyPath = core.getInput('cache-dependency-path');
@ -66,13 +66,6 @@ export async function run() {
}
}
function isGhes(): boolean {
const ghUrl = new URL(
process.env['GITHUB_SERVER_URL'] || 'https://github.com'
);
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
}
function resolveVersionInput(): string {
let version = core.getInput('node-version');
const versionFileInput = core.getInput('node-version-file');