Update cache-save.ts to support @actions/cache v3.0.0 lib

Made package.json and package-lock.json to use @actions/cache v3.0.0,
updated logic of the cache-save operation and added unit-tests
This commit is contained in:
IvanZosimov 2022-06-28 15:17:50 +02:00
parent ffcd00020c
commit 01408cef88
6 changed files with 858 additions and 577 deletions

View File

@ -212,6 +212,59 @@ describe('run', () => {
); );
expect(setFailedSpy).not.toHaveBeenCalled(); expect(setFailedSpy).not.toHaveBeenCalled();
}); });
it('saves with -1 cacheId , should not fail workflow', async () => {
inputs['cache'] = 'poetry';
getStateSpy.mockImplementation((name: string) => {
if (name === State.STATE_CACHE_PRIMARY_KEY) {
return poetryLockHash;
} else if (name === State.CACHE_PATHS) {
return JSON.stringify([__dirname]);
} else {
return requirementsHash;
}
});
saveCacheSpy.mockImplementation(() => {
return -1;
});
await run();
expect(getInputSpy).toHaveBeenCalled();
expect(getStateSpy).toHaveBeenCalledTimes(3);
expect(infoSpy).not.toHaveBeenCalled();
expect(saveCacheSpy).toHaveBeenCalled();
expect(infoSpy).not.toHaveBeenLastCalledWith(
`Cache saved with the key: ${poetryLockHash}`
);
expect(setFailedSpy).not.toHaveBeenCalled();
});
it('saves with error from toolkit, should fail workflow', async () => {
inputs['cache'] = 'npm';
getStateSpy.mockImplementation((name: string) => {
if (name === State.STATE_CACHE_PRIMARY_KEY) {
return poetryLockHash;
} else if (name === State.CACHE_PATHS) {
return JSON.stringify([__dirname]);
} else {
return requirementsHash;
}
});
saveCacheSpy.mockImplementation(() => {
throw new cache.ValidationError('Validation failed');
});
await run();
expect(getInputSpy).toHaveBeenCalled();
expect(getStateSpy).toHaveBeenCalledTimes(3);
expect(infoSpy).not.toHaveBeenCalledWith();
expect(saveCacheSpy).toHaveBeenCalled();
expect(setFailedSpy).toHaveBeenCalled();
});
}); });
afterEach(() => { afterEach(() => {

View File

@ -90,17 +90,18 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
checkKey(key); checkKey(key);
} }
const compressionMethod = yield utils.getCompressionMethod(); const compressionMethod = yield utils.getCompressionMethod();
// path are needed to compute version let archivePath = '';
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
const archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
try { try {
// path are needed to compute version
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
// Download the cache from the cache entry // Download the cache from the cache entry
yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options); yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options);
if (core.isDebug()) { if (core.isDebug()) {
@ -110,6 +111,17 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`);
yield tar_1.extractTar(archivePath, compressionMethod); yield tar_1.extractTar(archivePath, compressionMethod);
core.info('Cache restored successfully'); core.info('Cache restored successfully');
return cacheEntry.cacheKey;
}
catch (error) {
const typedError = error;
if (typedError.name === ValidationError.name) {
throw error;
}
else {
// Supress all non-validation cache related errors because caching should be optional
core.warning(`Failed to restore: ${error.message}`);
}
} }
finally { finally {
// Try to delete the archive to save space // Try to delete the archive to save space
@ -120,7 +132,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.debug(`Failed to delete archive: ${error}`); core.debug(`Failed to delete archive: ${error}`);
} }
} }
return cacheEntry.cacheKey; return undefined;
}); });
} }
exports.restoreCache = restoreCache; exports.restoreCache = restoreCache;
@ -138,10 +150,13 @@ function saveCache(paths, key, options) {
checkPaths(paths); checkPaths(paths);
checkKey(key); checkKey(key);
const compressionMethod = yield utils.getCompressionMethod(); const compressionMethod = yield utils.getCompressionMethod();
let cacheId = null; let cacheId = -1;
const cachePaths = yield utils.resolvePaths(paths); const cachePaths = yield utils.resolvePaths(paths);
core.debug('Cache Paths:'); core.debug('Cache Paths:');
core.debug(`${JSON.stringify(cachePaths)}`); core.debug(`${JSON.stringify(cachePaths)}`);
if (cachePaths.length === 0) {
throw new Error(`Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.`);
}
const archiveFolder = yield utils.createTempDirectory(); const archiveFolder = yield utils.createTempDirectory();
const archivePath = path.join(archiveFolder, utils.getCacheFileName(compressionMethod)); const archivePath = path.join(archiveFolder, utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`); core.debug(`Archive Path: ${archivePath}`);
@ -174,6 +189,18 @@ function saveCache(paths, key, options) {
core.debug(`Saving Cache (ID: ${cacheId})`); core.debug(`Saving Cache (ID: ${cacheId})`);
yield cacheHttpClient.saveCache(cacheId, archivePath, options); yield cacheHttpClient.saveCache(cacheId, archivePath, options);
} }
catch (error) {
const typedError = error;
if (typedError.name === ValidationError.name) {
throw error;
}
else if (typedError.name === ReserveCacheError.name) {
core.info(`Failed to save: ${typedError.message}`);
}
else {
core.warning(`Failed to save: ${typedError.message}`);
}
}
finally { finally {
// Try to delete the archive to save space // Try to delete the archive to save space
try { try {
@ -214,8 +241,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const http_client_1 = __nccwpck_require__(7320); const http_client_1 = __nccwpck_require__(1825);
const auth_1 = __nccwpck_require__(7093); const auth_1 = __nccwpck_require__(2001);
const crypto = __importStar(__nccwpck_require__(6113)); const crypto = __importStar(__nccwpck_require__(6113));
const fs = __importStar(__nccwpck_require__(7147)); const fs = __importStar(__nccwpck_require__(7147));
const url_1 = __nccwpck_require__(7310); const url_1 = __nccwpck_require__(7310);
@ -647,7 +674,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const http_client_1 = __nccwpck_require__(7320); const http_client_1 = __nccwpck_require__(1825);
const storage_blob_1 = __nccwpck_require__(4100); const storage_blob_1 = __nccwpck_require__(4100);
const buffer = __importStar(__nccwpck_require__(4300)); const buffer = __importStar(__nccwpck_require__(4300));
const fs = __importStar(__nccwpck_require__(7147)); const fs = __importStar(__nccwpck_require__(7147));
@ -885,7 +912,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const http_client_1 = __nccwpck_require__(7320); const http_client_1 = __nccwpck_require__(1825);
const constants_1 = __nccwpck_require__(8840); const constants_1 = __nccwpck_require__(8840);
function isSuccessStatusCode(statusCode) { function isSuccessStatusCode(statusCode) {
if (!statusCode) { if (!statusCode) {
@ -962,7 +989,7 @@ function retryTypedResponse(name, method, maxAttempts = constants_1.DefaultRetry
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
return yield retry(name, method, (response) => response.statusCode, maxAttempts, delay, return yield retry(name, method, (response) => response.statusCode, maxAttempts, delay,
// If the error object contains the statusCode property, extract it and return // If the error object contains the statusCode property, extract it and return
// an ITypedResponse<T> so it can be processed by the retry logic. // an TypedResponse<T> so it can be processed by the retry logic.
(error) => { (error) => {
if (error instanceof http_client_1.HttpClientError) { if (error instanceof http_client_1.HttpClientError) {
return { return {
@ -1120,6 +1147,8 @@ function createTar(archiveFolder, sourceDirectories, compressionMethod) {
...getCompressionProgram(), ...getCompressionProgram(),
'-cf', '-cf',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'--exclude',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P', '-P',
'-C', '-C',
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
@ -2292,28 +2321,41 @@ exports.SearchState = SearchState;
/***/ }), /***/ }),
/***/ 7093: /***/ 2001:
/***/ ((__unused_webpack_module, exports) => { /***/ (function(__unused_webpack_module, exports) {
"use strict"; "use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0;
class BasicCredentialHandler { class BasicCredentialHandler {
constructor(username, password) { constructor(username, password) {
this.username = username; this.username = username;
this.password = password; this.password = password;
} }
prepareRequest(options) { prepareRequest(options) {
options.headers['Authorization'] = if (!options.headers) {
'Basic ' + throw Error('The request has no headers');
Buffer.from(this.username + ':' + this.password).toString('base64'); }
options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`;
} }
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response) { canHandleAuthentication() {
return false; return false;
} }
handleAuthentication(httpClient, requestInfo, objs) { handleAuthentication() {
return null; return __awaiter(this, void 0, void 0, function* () {
throw new Error('not implemented');
});
} }
} }
exports.BasicCredentialHandler = BasicCredentialHandler; exports.BasicCredentialHandler = BasicCredentialHandler;
@ -2324,14 +2366,19 @@ class BearerCredentialHandler {
// currently implements pre-authorization // currently implements pre-authorization
// TODO: support preAuth = false where it hooks on 401 // TODO: support preAuth = false where it hooks on 401
prepareRequest(options) { prepareRequest(options) {
options.headers['Authorization'] = 'Bearer ' + this.token; if (!options.headers) {
throw Error('The request has no headers');
}
options.headers['Authorization'] = `Bearer ${this.token}`;
} }
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response) { canHandleAuthentication() {
return false; return false;
} }
handleAuthentication(httpClient, requestInfo, objs) { handleAuthentication() {
return null; return __awaiter(this, void 0, void 0, function* () {
throw new Error('not implemented');
});
} }
} }
exports.BearerCredentialHandler = BearerCredentialHandler; exports.BearerCredentialHandler = BearerCredentialHandler;
@ -2342,32 +2389,66 @@ class PersonalAccessTokenCredentialHandler {
// currently implements pre-authorization // currently implements pre-authorization
// TODO: support preAuth = false where it hooks on 401 // TODO: support preAuth = false where it hooks on 401
prepareRequest(options) { prepareRequest(options) {
options.headers['Authorization'] = if (!options.headers) {
'Basic ' + Buffer.from('PAT:' + this.token).toString('base64'); throw Error('The request has no headers');
}
options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`;
} }
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response) { canHandleAuthentication() {
return false; return false;
} }
handleAuthentication(httpClient, requestInfo, objs) { handleAuthentication() {
return null; return __awaiter(this, void 0, void 0, function* () {
throw new Error('not implemented');
});
} }
} }
exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler; exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler;
//# sourceMappingURL=auth.js.map
/***/ }), /***/ }),
/***/ 7320: /***/ 1825:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict"; "use strict";
/* eslint-disable @typescript-eslint/no-explicit-any */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const http = __nccwpck_require__(3685); exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0;
const https = __nccwpck_require__(5687); const http = __importStar(__nccwpck_require__(3685));
const pm = __nccwpck_require__(7326); const https = __importStar(__nccwpck_require__(5687));
let tunnel; const pm = __importStar(__nccwpck_require__(4977));
const tunnel = __importStar(__nccwpck_require__(4294));
var HttpCodes; var HttpCodes;
(function (HttpCodes) { (function (HttpCodes) {
HttpCodes[HttpCodes["OK"] = 200] = "OK"; HttpCodes[HttpCodes["OK"] = 200] = "OK";
@ -2412,7 +2493,7 @@ var MediaTypes;
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
*/ */
function getProxyUrl(serverUrl) { function getProxyUrl(serverUrl) {
let proxyUrl = pm.getProxyUrl(new URL(serverUrl)); const proxyUrl = pm.getProxyUrl(new URL(serverUrl));
return proxyUrl ? proxyUrl.href : ''; return proxyUrl ? proxyUrl.href : '';
} }
exports.getProxyUrl = getProxyUrl; exports.getProxyUrl = getProxyUrl;
@ -2445,20 +2526,22 @@ class HttpClientResponse {
this.message = message; this.message = message;
} }
readBody() { readBody() {
return new Promise(async (resolve, reject) => { return __awaiter(this, void 0, void 0, function* () {
let output = Buffer.alloc(0); return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
this.message.on('data', (chunk) => { let output = Buffer.alloc(0);
output = Buffer.concat([output, chunk]); this.message.on('data', (chunk) => {
}); output = Buffer.concat([output, chunk]);
this.message.on('end', () => { });
resolve(output.toString()); this.message.on('end', () => {
}); resolve(output.toString());
});
}));
}); });
} }
} }
exports.HttpClientResponse = HttpClientResponse; exports.HttpClientResponse = HttpClientResponse;
function isHttps(requestUrl) { function isHttps(requestUrl) {
let parsedUrl = new URL(requestUrl); const parsedUrl = new URL(requestUrl);
return parsedUrl.protocol === 'https:'; return parsedUrl.protocol === 'https:';
} }
exports.isHttps = isHttps; exports.isHttps = isHttps;
@ -2501,141 +2584,169 @@ class HttpClient {
} }
} }
options(requestUrl, additionalHeaders) { options(requestUrl, additionalHeaders) {
return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});
});
} }
get(requestUrl, additionalHeaders) { get(requestUrl, additionalHeaders) {
return this.request('GET', requestUrl, null, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('GET', requestUrl, null, additionalHeaders || {});
});
} }
del(requestUrl, additionalHeaders) { del(requestUrl, additionalHeaders) {
return this.request('DELETE', requestUrl, null, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('DELETE', requestUrl, null, additionalHeaders || {});
});
} }
post(requestUrl, data, additionalHeaders) { post(requestUrl, data, additionalHeaders) {
return this.request('POST', requestUrl, data, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('POST', requestUrl, data, additionalHeaders || {});
});
} }
patch(requestUrl, data, additionalHeaders) { patch(requestUrl, data, additionalHeaders) {
return this.request('PATCH', requestUrl, data, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('PATCH', requestUrl, data, additionalHeaders || {});
});
} }
put(requestUrl, data, additionalHeaders) { put(requestUrl, data, additionalHeaders) {
return this.request('PUT', requestUrl, data, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('PUT', requestUrl, data, additionalHeaders || {});
});
} }
head(requestUrl, additionalHeaders) { head(requestUrl, additionalHeaders) {
return this.request('HEAD', requestUrl, null, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('HEAD', requestUrl, null, additionalHeaders || {});
});
} }
sendStream(verb, requestUrl, stream, additionalHeaders) { sendStream(verb, requestUrl, stream, additionalHeaders) {
return this.request(verb, requestUrl, stream, additionalHeaders); return __awaiter(this, void 0, void 0, function* () {
return this.request(verb, requestUrl, stream, additionalHeaders);
});
} }
/** /**
* Gets a typed object from an endpoint * Gets a typed object from an endpoint
* Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise
*/ */
async getJson(requestUrl, additionalHeaders = {}) { getJson(requestUrl, additionalHeaders = {}) {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); return __awaiter(this, void 0, void 0, function* () {
let res = await this.get(requestUrl, additionalHeaders); additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
return this._processResponse(res, this.requestOptions); const res = yield this.get(requestUrl, additionalHeaders);
return this._processResponse(res, this.requestOptions);
});
} }
async postJson(requestUrl, obj, additionalHeaders = {}) { postJson(requestUrl, obj, additionalHeaders = {}) {
let data = JSON.stringify(obj, null, 2); return __awaiter(this, void 0, void 0, function* () {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); const data = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
let res = await this.post(requestUrl, data, additionalHeaders); additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
return this._processResponse(res, this.requestOptions); const res = yield this.post(requestUrl, data, additionalHeaders);
return this._processResponse(res, this.requestOptions);
});
} }
async putJson(requestUrl, obj, additionalHeaders = {}) { putJson(requestUrl, obj, additionalHeaders = {}) {
let data = JSON.stringify(obj, null, 2); return __awaiter(this, void 0, void 0, function* () {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); const data = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
let res = await this.put(requestUrl, data, additionalHeaders); additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
return this._processResponse(res, this.requestOptions); const res = yield this.put(requestUrl, data, additionalHeaders);
return this._processResponse(res, this.requestOptions);
});
} }
async patchJson(requestUrl, obj, additionalHeaders = {}) { patchJson(requestUrl, obj, additionalHeaders = {}) {
let data = JSON.stringify(obj, null, 2); return __awaiter(this, void 0, void 0, function* () {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); const data = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
let res = await this.patch(requestUrl, data, additionalHeaders); additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
return this._processResponse(res, this.requestOptions); const res = yield this.patch(requestUrl, data, additionalHeaders);
return this._processResponse(res, this.requestOptions);
});
} }
/** /**
* Makes a raw http request. * Makes a raw http request.
* All other methods such as get, post, patch, and request ultimately call this. * All other methods such as get, post, patch, and request ultimately call this.
* Prefer get, del, post and patch * Prefer get, del, post and patch
*/ */
async request(verb, requestUrl, data, headers) { request(verb, requestUrl, data, headers) {
if (this._disposed) { return __awaiter(this, void 0, void 0, function* () {
throw new Error('Client has already been disposed.'); if (this._disposed) {
} throw new Error('Client has already been disposed.');
let parsedUrl = new URL(requestUrl);
let info = this._prepareRequest(verb, parsedUrl, headers);
// Only perform retries on reads since writes may not be idempotent.
let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1
? this._maxRetries + 1
: 1;
let numTries = 0;
let response;
while (numTries < maxTries) {
response = await this.requestRaw(info, data);
// Check if it's an authentication challenge
if (response &&
response.message &&
response.message.statusCode === HttpCodes.Unauthorized) {
let authenticationHandler;
for (let i = 0; i < this.handlers.length; i++) {
if (this.handlers[i].canHandleAuthentication(response)) {
authenticationHandler = this.handlers[i];
break;
}
}
if (authenticationHandler) {
return authenticationHandler.handleAuthentication(this, info, data);
}
else {
// We have received an unauthorized response but have no handlers to handle it.
// Let the response return to the caller.
return response;
}
} }
let redirectsRemaining = this._maxRedirects; const parsedUrl = new URL(requestUrl);
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 && let info = this._prepareRequest(verb, parsedUrl, headers);
this._allowRedirects && // Only perform retries on reads since writes may not be idempotent.
redirectsRemaining > 0) { const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb)
const redirectUrl = response.message.headers['location']; ? this._maxRetries + 1
if (!redirectUrl) { : 1;
// if there's no location to redirect to, we won't let numTries = 0;
break; let response;
} do {
let parsedRedirectUrl = new URL(redirectUrl); response = yield this.requestRaw(info, data);
if (parsedUrl.protocol == 'https:' && // Check if it's an authentication challenge
parsedUrl.protocol != parsedRedirectUrl.protocol && if (response &&
!this._allowRedirectDowngrade) { response.message &&
throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.'); response.message.statusCode === HttpCodes.Unauthorized) {
} let authenticationHandler;
// we need to finish reading the response before reassigning response for (const handler of this.handlers) {
// which will leak the open socket. if (handler.canHandleAuthentication(response)) {
await response.readBody(); authenticationHandler = handler;
// strip authorization header if redirected to a different hostname break;
if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
for (let header in headers) {
// header names are case insensitive
if (header.toLowerCase() === 'authorization') {
delete headers[header];
} }
} }
if (authenticationHandler) {
return authenticationHandler.handleAuthentication(this, info, data);
}
else {
// We have received an unauthorized response but have no handlers to handle it.
// Let the response return to the caller.
return response;
}
} }
// let's make the request with the new redirectUrl let redirectsRemaining = this._maxRedirects;
info = this._prepareRequest(verb, parsedRedirectUrl, headers); while (response.message.statusCode &&
response = await this.requestRaw(info, data); HttpRedirectCodes.includes(response.message.statusCode) &&
redirectsRemaining--; this._allowRedirects &&
} redirectsRemaining > 0) {
if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) { const redirectUrl = response.message.headers['location'];
// If not a retry code, return immediately instead of retrying if (!redirectUrl) {
return response; // if there's no location to redirect to, we won't
} break;
numTries += 1; }
if (numTries < maxTries) { const parsedRedirectUrl = new URL(redirectUrl);
await response.readBody(); if (parsedUrl.protocol === 'https:' &&
await this._performExponentialBackoff(numTries); parsedUrl.protocol !== parsedRedirectUrl.protocol &&
} !this._allowRedirectDowngrade) {
} throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');
return response; }
// we need to finish reading the response before reassigning response
// which will leak the open socket.
yield response.readBody();
// strip authorization header if redirected to a different hostname
if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
for (const header in headers) {
// header names are case insensitive
if (header.toLowerCase() === 'authorization') {
delete headers[header];
}
}
}
// let's make the request with the new redirectUrl
info = this._prepareRequest(verb, parsedRedirectUrl, headers);
response = yield this.requestRaw(info, data);
redirectsRemaining--;
}
if (!response.message.statusCode ||
!HttpResponseRetryCodes.includes(response.message.statusCode)) {
// If not a retry code, return immediately instead of retrying
return response;
}
numTries += 1;
if (numTries < maxTries) {
yield response.readBody();
yield this._performExponentialBackoff(numTries);
}
} while (numTries < maxTries);
return response;
});
} }
/** /**
* Needs to be called if keepAlive is set to true in request options. * Needs to be called if keepAlive is set to true in request options.
@ -2652,14 +2763,22 @@ class HttpClient {
* @param data * @param data
*/ */
requestRaw(info, data) { requestRaw(info, data) {
return new Promise((resolve, reject) => { return __awaiter(this, void 0, void 0, function* () {
let callbackForResult = function (err, res) { return new Promise((resolve, reject) => {
if (err) { function callbackForResult(err, res) {
reject(err); if (err) {
reject(err);
}
else if (!res) {
// If `err` is not passed, then `res` must be passed.
reject(new Error('Unknown error'));
}
else {
resolve(res);
}
} }
resolve(res); this.requestRawWithCallback(info, data, callbackForResult);
}; });
this.requestRawWithCallback(info, data, callbackForResult);
}); });
} }
/** /**
@ -2669,21 +2788,24 @@ class HttpClient {
* @param onResult * @param onResult
*/ */
requestRawWithCallback(info, data, onResult) { requestRawWithCallback(info, data, onResult) {
let socket;
if (typeof data === 'string') { if (typeof data === 'string') {
if (!info.options.headers) {
info.options.headers = {};
}
info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
} }
let callbackCalled = false; let callbackCalled = false;
let handleResult = (err, res) => { function handleResult(err, res) {
if (!callbackCalled) { if (!callbackCalled) {
callbackCalled = true; callbackCalled = true;
onResult(err, res); onResult(err, res);
} }
}; }
let req = info.httpModule.request(info.options, (msg) => { const req = info.httpModule.request(info.options, (msg) => {
let res = new HttpClientResponse(msg); const res = new HttpClientResponse(msg);
handleResult(null, res); handleResult(undefined, res);
}); });
let socket;
req.on('socket', sock => { req.on('socket', sock => {
socket = sock; socket = sock;
}); });
@ -2692,12 +2814,12 @@ class HttpClient {
if (socket) { if (socket) {
socket.end(); socket.end();
} }
handleResult(new Error('Request timeout: ' + info.options.path), null); handleResult(new Error(`Request timeout: ${info.options.path}`));
}); });
req.on('error', function (err) { req.on('error', function (err) {
// err has statusCode property // err has statusCode property
// res should have headers // res should have headers
handleResult(err, null); handleResult(err);
}); });
if (data && typeof data === 'string') { if (data && typeof data === 'string') {
req.write(data, 'utf8'); req.write(data, 'utf8');
@ -2718,7 +2840,7 @@ class HttpClient {
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
*/ */
getAgent(serverUrl) { getAgent(serverUrl) {
let parsedUrl = new URL(serverUrl); const parsedUrl = new URL(serverUrl);
return this._getAgent(parsedUrl); return this._getAgent(parsedUrl);
} }
_prepareRequest(method, requestUrl, headers) { _prepareRequest(method, requestUrl, headers) {
@ -2742,21 +2864,19 @@ class HttpClient {
info.options.agent = this._getAgent(info.parsedUrl); info.options.agent = this._getAgent(info.parsedUrl);
// gives handlers an opportunity to participate // gives handlers an opportunity to participate
if (this.handlers) { if (this.handlers) {
this.handlers.forEach(handler => { for (const handler of this.handlers) {
handler.prepareRequest(info.options); handler.prepareRequest(info.options);
}); }
} }
return info; return info;
} }
_mergeHeaders(headers) { _mergeHeaders(headers) {
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
if (this.requestOptions && this.requestOptions.headers) { if (this.requestOptions && this.requestOptions.headers) {
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers)); return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {}));
} }
return lowercaseKeys(headers || {}); return lowercaseKeys(headers || {});
} }
_getExistingOrDefaultHeader(additionalHeaders, header, _default) { _getExistingOrDefaultHeader(additionalHeaders, header, _default) {
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
let clientHeader; let clientHeader;
if (this.requestOptions && this.requestOptions.headers) { if (this.requestOptions && this.requestOptions.headers) {
clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; clientHeader = lowercaseKeys(this.requestOptions.headers)[header];
@ -2765,8 +2885,8 @@ class HttpClient {
} }
_getAgent(parsedUrl) { _getAgent(parsedUrl) {
let agent; let agent;
let proxyUrl = pm.getProxyUrl(parsedUrl); const proxyUrl = pm.getProxyUrl(parsedUrl);
let useProxy = proxyUrl && proxyUrl.hostname; const useProxy = proxyUrl && proxyUrl.hostname;
if (this._keepAlive && useProxy) { if (this._keepAlive && useProxy) {
agent = this._proxyAgent; agent = this._proxyAgent;
} }
@ -2774,29 +2894,22 @@ class HttpClient {
agent = this._agent; agent = this._agent;
} }
// if agent is already assigned use that agent. // if agent is already assigned use that agent.
if (!!agent) { if (agent) {
return agent; return agent;
} }
const usingSsl = parsedUrl.protocol === 'https:'; const usingSsl = parsedUrl.protocol === 'https:';
let maxSockets = 100; let maxSockets = 100;
if (!!this.requestOptions) { if (this.requestOptions) {
maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets;
} }
if (useProxy) { // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis.
// If using proxy, need tunnel if (proxyUrl && proxyUrl.hostname) {
if (!tunnel) {
tunnel = __nccwpck_require__(4294);
}
const agentOptions = { const agentOptions = {
maxSockets: maxSockets, maxSockets,
keepAlive: this._keepAlive, keepAlive: this._keepAlive,
proxy: { proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && {
...((proxyUrl.username || proxyUrl.password) && { proxyAuth: `${proxyUrl.username}:${proxyUrl.password}`
proxyAuth: `${proxyUrl.username}:${proxyUrl.password}` })), { host: proxyUrl.hostname, port: proxyUrl.port })
}),
host: proxyUrl.hostname,
port: proxyUrl.port
}
}; };
let tunnelAgent; let tunnelAgent;
const overHttps = proxyUrl.protocol === 'https:'; const overHttps = proxyUrl.protocol === 'https:';
@ -2811,7 +2924,7 @@ class HttpClient {
} }
// if reusing agent across request and tunneling agent isn't assigned create a new agent // if reusing agent across request and tunneling agent isn't assigned create a new agent
if (this._keepAlive && !agent) { if (this._keepAlive && !agent) {
const options = { keepAlive: this._keepAlive, maxSockets: maxSockets }; const options = { keepAlive: this._keepAlive, maxSockets };
agent = usingSsl ? new https.Agent(options) : new http.Agent(options); agent = usingSsl ? new https.Agent(options) : new http.Agent(options);
this._agent = agent; this._agent = agent;
} }
@ -2830,109 +2943,117 @@ class HttpClient {
return agent; return agent;
} }
_performExponentialBackoff(retryNumber) { _performExponentialBackoff(retryNumber) {
retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); return __awaiter(this, void 0, void 0, function* () {
const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);
return new Promise(resolve => setTimeout(() => resolve(), ms)); const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);
return new Promise(resolve => setTimeout(() => resolve(), ms));
});
} }
static dateTimeDeserializer(key, value) { _processResponse(res, options) {
if (typeof value === 'string') { return __awaiter(this, void 0, void 0, function* () {
let a = new Date(value); return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
if (!isNaN(a.valueOf())) { const statusCode = res.message.statusCode || 0;
return a; const response = {
} statusCode,
} result: null,
return value; headers: {}
} };
async _processResponse(res, options) { // not found leads to null obj returned
return new Promise(async (resolve, reject) => { if (statusCode === HttpCodes.NotFound) {
const statusCode = res.message.statusCode; resolve(response);
const response = { }
statusCode: statusCode, // get the result from the body
result: null, function dateTimeDeserializer(key, value) {
headers: {} if (typeof value === 'string') {
}; const a = new Date(value);
// not found leads to null obj returned if (!isNaN(a.valueOf())) {
if (statusCode == HttpCodes.NotFound) { return a;
resolve(response); }
} }
let obj; return value;
let contents; }
// get the result from the body let obj;
try { let contents;
contents = await res.readBody(); try {
if (contents && contents.length > 0) { contents = yield res.readBody();
if (options && options.deserializeDates) { if (contents && contents.length > 0) {
obj = JSON.parse(contents, HttpClient.dateTimeDeserializer); if (options && options.deserializeDates) {
obj = JSON.parse(contents, dateTimeDeserializer);
}
else {
obj = JSON.parse(contents);
}
response.result = obj;
}
response.headers = res.message.headers;
}
catch (err) {
// Invalid resource (contents not json); leaving result obj null
}
// note that 3xx redirects are handled by the http layer.
if (statusCode > 299) {
let msg;
// if exception/error in body, attempt to get better error
if (obj && obj.message) {
msg = obj.message;
}
else if (contents && contents.length > 0) {
// it may be the case that the exception is in the body message as string
msg = contents;
} }
else { else {
obj = JSON.parse(contents); msg = `Failed request: (${statusCode})`;
} }
response.result = obj; const err = new HttpClientError(msg, statusCode);
} err.result = response.result;
response.headers = res.message.headers; reject(err);
}
catch (err) {
// Invalid resource (contents not json); leaving result obj null
}
// note that 3xx redirects are handled by the http layer.
if (statusCode > 299) {
let msg;
// if exception/error in body, attempt to get better error
if (obj && obj.message) {
msg = obj.message;
}
else if (contents && contents.length > 0) {
// it may be the case that the exception is in the body message as string
msg = contents;
} }
else { else {
msg = 'Failed request: (' + statusCode + ')'; resolve(response);
} }
let err = new HttpClientError(msg, statusCode); }));
err.result = response.result;
reject(err);
}
else {
resolve(response);
}
}); });
} }
} }
exports.HttpClient = HttpClient; exports.HttpClient = HttpClient;
const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
//# sourceMappingURL=index.js.map
/***/ }), /***/ }),
/***/ 7326: /***/ 4977:
/***/ ((__unused_webpack_module, exports) => { /***/ ((__unused_webpack_module, exports) => {
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.checkBypass = exports.getProxyUrl = void 0;
function getProxyUrl(reqUrl) { function getProxyUrl(reqUrl) {
let usingSsl = reqUrl.protocol === 'https:'; const usingSsl = reqUrl.protocol === 'https:';
let proxyUrl;
if (checkBypass(reqUrl)) { if (checkBypass(reqUrl)) {
return proxyUrl; return undefined;
} }
let proxyVar; const proxyVar = (() => {
if (usingSsl) { if (usingSsl) {
proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY']; return process.env['https_proxy'] || process.env['HTTPS_PROXY'];
}
else {
return process.env['http_proxy'] || process.env['HTTP_PROXY'];
}
})();
if (proxyVar) {
return new URL(proxyVar);
} }
else { else {
proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY']; return undefined;
} }
if (proxyVar) {
proxyUrl = new URL(proxyVar);
}
return proxyUrl;
} }
exports.getProxyUrl = getProxyUrl; exports.getProxyUrl = getProxyUrl;
function checkBypass(reqUrl) { function checkBypass(reqUrl) {
if (!reqUrl.hostname) { if (!reqUrl.hostname) {
return false; return false;
} }
let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''; const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
if (!noProxy) { if (!noProxy) {
return false; return false;
} }
@ -2948,12 +3069,12 @@ function checkBypass(reqUrl) {
reqPort = 443; reqPort = 443;
} }
// Format the request hostname and hostname with port // Format the request hostname and hostname with port
let upperReqHosts = [reqUrl.hostname.toUpperCase()]; const upperReqHosts = [reqUrl.hostname.toUpperCase()];
if (typeof reqPort === 'number') { if (typeof reqPort === 'number') {
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);
} }
// Compare request host against noproxy // Compare request host against noproxy
for (let upperNoProxyItem of noProxy for (const upperNoProxyItem of noProxy
.split(',') .split(',')
.map(x => x.trim().toUpperCase()) .map(x => x.trim().toUpperCase())
.filter(x => x)) { .filter(x => x)) {
@ -2964,7 +3085,7 @@ function checkBypass(reqUrl) {
return false; return false;
} }
exports.checkBypass = checkBypass; exports.checkBypass = checkBypass;
//# sourceMappingURL=proxy.js.map
/***/ }), /***/ }),
@ -57624,19 +57745,11 @@ function saveCache(packageManager) {
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`); core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
return; return;
} }
try { const cacheId = yield cache.saveCache(cachePaths, primaryKey);
yield cache.saveCache(cachePaths, primaryKey); if (cacheId == -1) {
core.info(`Cache saved with the key: ${primaryKey}`); return;
}
catch (error) {
const err = error;
if (err.name === cache.ReserveCacheError.name) {
core.info(err.message);
}
else {
throw error;
}
} }
core.info(`Cache saved with the key: ${primaryKey}`);
}); });
} }
function isCacheDirectoryExists(cacheDirectory) { function isCacheDirectoryExists(cacheDirectory) {

657
dist/setup/index.js vendored
View File

@ -90,17 +90,18 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
checkKey(key); checkKey(key);
} }
const compressionMethod = yield utils.getCompressionMethod(); const compressionMethod = yield utils.getCompressionMethod();
// path are needed to compute version let archivePath = '';
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
const archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
try { try {
// path are needed to compute version
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys, paths, {
compressionMethod
});
if (!(cacheEntry === null || cacheEntry === void 0 ? void 0 : cacheEntry.archiveLocation)) {
// Cache not found
return undefined;
}
archivePath = path.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`);
// Download the cache from the cache entry // Download the cache from the cache entry
yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options); yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options);
if (core.isDebug()) { if (core.isDebug()) {
@ -110,6 +111,17 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`); core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`);
yield tar_1.extractTar(archivePath, compressionMethod); yield tar_1.extractTar(archivePath, compressionMethod);
core.info('Cache restored successfully'); core.info('Cache restored successfully');
return cacheEntry.cacheKey;
}
catch (error) {
const typedError = error;
if (typedError.name === ValidationError.name) {
throw error;
}
else {
// Supress all non-validation cache related errors because caching should be optional
core.warning(`Failed to restore: ${error.message}`);
}
} }
finally { finally {
// Try to delete the archive to save space // Try to delete the archive to save space
@ -120,7 +132,7 @@ function restoreCache(paths, primaryKey, restoreKeys, options) {
core.debug(`Failed to delete archive: ${error}`); core.debug(`Failed to delete archive: ${error}`);
} }
} }
return cacheEntry.cacheKey; return undefined;
}); });
} }
exports.restoreCache = restoreCache; exports.restoreCache = restoreCache;
@ -138,10 +150,13 @@ function saveCache(paths, key, options) {
checkPaths(paths); checkPaths(paths);
checkKey(key); checkKey(key);
const compressionMethod = yield utils.getCompressionMethod(); const compressionMethod = yield utils.getCompressionMethod();
let cacheId = null; let cacheId = -1;
const cachePaths = yield utils.resolvePaths(paths); const cachePaths = yield utils.resolvePaths(paths);
core.debug('Cache Paths:'); core.debug('Cache Paths:');
core.debug(`${JSON.stringify(cachePaths)}`); core.debug(`${JSON.stringify(cachePaths)}`);
if (cachePaths.length === 0) {
throw new Error(`Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.`);
}
const archiveFolder = yield utils.createTempDirectory(); const archiveFolder = yield utils.createTempDirectory();
const archivePath = path.join(archiveFolder, utils.getCacheFileName(compressionMethod)); const archivePath = path.join(archiveFolder, utils.getCacheFileName(compressionMethod));
core.debug(`Archive Path: ${archivePath}`); core.debug(`Archive Path: ${archivePath}`);
@ -174,6 +189,18 @@ function saveCache(paths, key, options) {
core.debug(`Saving Cache (ID: ${cacheId})`); core.debug(`Saving Cache (ID: ${cacheId})`);
yield cacheHttpClient.saveCache(cacheId, archivePath, options); yield cacheHttpClient.saveCache(cacheId, archivePath, options);
} }
catch (error) {
const typedError = error;
if (typedError.name === ValidationError.name) {
throw error;
}
else if (typedError.name === ReserveCacheError.name) {
core.info(`Failed to save: ${typedError.message}`);
}
else {
core.warning(`Failed to save: ${typedError.message}`);
}
}
finally { finally {
// Try to delete the archive to save space // Try to delete the archive to save space
try { try {
@ -214,8 +241,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const http_client_1 = __nccwpck_require__(7320); const http_client_1 = __nccwpck_require__(1825);
const auth_1 = __nccwpck_require__(7093); const auth_1 = __nccwpck_require__(2001);
const crypto = __importStar(__nccwpck_require__(6113)); const crypto = __importStar(__nccwpck_require__(6113));
const fs = __importStar(__nccwpck_require__(7147)); const fs = __importStar(__nccwpck_require__(7147));
const url_1 = __nccwpck_require__(7310); const url_1 = __nccwpck_require__(7310);
@ -647,7 +674,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const http_client_1 = __nccwpck_require__(7320); const http_client_1 = __nccwpck_require__(1825);
const storage_blob_1 = __nccwpck_require__(4100); const storage_blob_1 = __nccwpck_require__(4100);
const buffer = __importStar(__nccwpck_require__(4300)); const buffer = __importStar(__nccwpck_require__(4300));
const fs = __importStar(__nccwpck_require__(7147)); const fs = __importStar(__nccwpck_require__(7147));
@ -885,7 +912,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const http_client_1 = __nccwpck_require__(7320); const http_client_1 = __nccwpck_require__(1825);
const constants_1 = __nccwpck_require__(8840); const constants_1 = __nccwpck_require__(8840);
function isSuccessStatusCode(statusCode) { function isSuccessStatusCode(statusCode) {
if (!statusCode) { if (!statusCode) {
@ -962,7 +989,7 @@ function retryTypedResponse(name, method, maxAttempts = constants_1.DefaultRetry
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
return yield retry(name, method, (response) => response.statusCode, maxAttempts, delay, return yield retry(name, method, (response) => response.statusCode, maxAttempts, delay,
// If the error object contains the statusCode property, extract it and return // If the error object contains the statusCode property, extract it and return
// an ITypedResponse<T> so it can be processed by the retry logic. // an TypedResponse<T> so it can be processed by the retry logic.
(error) => { (error) => {
if (error instanceof http_client_1.HttpClientError) { if (error instanceof http_client_1.HttpClientError) {
return { return {
@ -1120,6 +1147,8 @@ function createTar(archiveFolder, sourceDirectories, compressionMethod) {
...getCompressionProgram(), ...getCompressionProgram(),
'-cf', '-cf',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'--exclude',
cacheFileName.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
'-P', '-P',
'-C', '-C',
workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'), workingDirectory.replace(new RegExp(`\\${path.sep}`, 'g'), '/'),
@ -2292,28 +2321,41 @@ exports.SearchState = SearchState;
/***/ }), /***/ }),
/***/ 7093: /***/ 2001:
/***/ ((__unused_webpack_module, exports) => { /***/ (function(__unused_webpack_module, exports) {
"use strict"; "use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0;
class BasicCredentialHandler { class BasicCredentialHandler {
constructor(username, password) { constructor(username, password) {
this.username = username; this.username = username;
this.password = password; this.password = password;
} }
prepareRequest(options) { prepareRequest(options) {
options.headers['Authorization'] = if (!options.headers) {
'Basic ' + throw Error('The request has no headers');
Buffer.from(this.username + ':' + this.password).toString('base64'); }
options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`;
} }
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response) { canHandleAuthentication() {
return false; return false;
} }
handleAuthentication(httpClient, requestInfo, objs) { handleAuthentication() {
return null; return __awaiter(this, void 0, void 0, function* () {
throw new Error('not implemented');
});
} }
} }
exports.BasicCredentialHandler = BasicCredentialHandler; exports.BasicCredentialHandler = BasicCredentialHandler;
@ -2324,14 +2366,19 @@ class BearerCredentialHandler {
// currently implements pre-authorization // currently implements pre-authorization
// TODO: support preAuth = false where it hooks on 401 // TODO: support preAuth = false where it hooks on 401
prepareRequest(options) { prepareRequest(options) {
options.headers['Authorization'] = 'Bearer ' + this.token; if (!options.headers) {
throw Error('The request has no headers');
}
options.headers['Authorization'] = `Bearer ${this.token}`;
} }
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response) { canHandleAuthentication() {
return false; return false;
} }
handleAuthentication(httpClient, requestInfo, objs) { handleAuthentication() {
return null; return __awaiter(this, void 0, void 0, function* () {
throw new Error('not implemented');
});
} }
} }
exports.BearerCredentialHandler = BearerCredentialHandler; exports.BearerCredentialHandler = BearerCredentialHandler;
@ -2342,32 +2389,66 @@ class PersonalAccessTokenCredentialHandler {
// currently implements pre-authorization // currently implements pre-authorization
// TODO: support preAuth = false where it hooks on 401 // TODO: support preAuth = false where it hooks on 401
prepareRequest(options) { prepareRequest(options) {
options.headers['Authorization'] = if (!options.headers) {
'Basic ' + Buffer.from('PAT:' + this.token).toString('base64'); throw Error('The request has no headers');
}
options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`;
} }
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response) { canHandleAuthentication() {
return false; return false;
} }
handleAuthentication(httpClient, requestInfo, objs) { handleAuthentication() {
return null; return __awaiter(this, void 0, void 0, function* () {
throw new Error('not implemented');
});
} }
} }
exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler; exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler;
//# sourceMappingURL=auth.js.map
/***/ }), /***/ }),
/***/ 7320: /***/ 1825:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict"; "use strict";
/* eslint-disable @typescript-eslint/no-explicit-any */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const http = __nccwpck_require__(3685); exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0;
const https = __nccwpck_require__(5687); const http = __importStar(__nccwpck_require__(3685));
const pm = __nccwpck_require__(7326); const https = __importStar(__nccwpck_require__(5687));
let tunnel; const pm = __importStar(__nccwpck_require__(4977));
const tunnel = __importStar(__nccwpck_require__(4294));
var HttpCodes; var HttpCodes;
(function (HttpCodes) { (function (HttpCodes) {
HttpCodes[HttpCodes["OK"] = 200] = "OK"; HttpCodes[HttpCodes["OK"] = 200] = "OK";
@ -2412,7 +2493,7 @@ var MediaTypes;
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
*/ */
function getProxyUrl(serverUrl) { function getProxyUrl(serverUrl) {
let proxyUrl = pm.getProxyUrl(new URL(serverUrl)); const proxyUrl = pm.getProxyUrl(new URL(serverUrl));
return proxyUrl ? proxyUrl.href : ''; return proxyUrl ? proxyUrl.href : '';
} }
exports.getProxyUrl = getProxyUrl; exports.getProxyUrl = getProxyUrl;
@ -2445,20 +2526,22 @@ class HttpClientResponse {
this.message = message; this.message = message;
} }
readBody() { readBody() {
return new Promise(async (resolve, reject) => { return __awaiter(this, void 0, void 0, function* () {
let output = Buffer.alloc(0); return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
this.message.on('data', (chunk) => { let output = Buffer.alloc(0);
output = Buffer.concat([output, chunk]); this.message.on('data', (chunk) => {
}); output = Buffer.concat([output, chunk]);
this.message.on('end', () => { });
resolve(output.toString()); this.message.on('end', () => {
}); resolve(output.toString());
});
}));
}); });
} }
} }
exports.HttpClientResponse = HttpClientResponse; exports.HttpClientResponse = HttpClientResponse;
function isHttps(requestUrl) { function isHttps(requestUrl) {
let parsedUrl = new URL(requestUrl); const parsedUrl = new URL(requestUrl);
return parsedUrl.protocol === 'https:'; return parsedUrl.protocol === 'https:';
} }
exports.isHttps = isHttps; exports.isHttps = isHttps;
@ -2501,141 +2584,169 @@ class HttpClient {
} }
} }
options(requestUrl, additionalHeaders) { options(requestUrl, additionalHeaders) {
return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});
});
} }
get(requestUrl, additionalHeaders) { get(requestUrl, additionalHeaders) {
return this.request('GET', requestUrl, null, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('GET', requestUrl, null, additionalHeaders || {});
});
} }
del(requestUrl, additionalHeaders) { del(requestUrl, additionalHeaders) {
return this.request('DELETE', requestUrl, null, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('DELETE', requestUrl, null, additionalHeaders || {});
});
} }
post(requestUrl, data, additionalHeaders) { post(requestUrl, data, additionalHeaders) {
return this.request('POST', requestUrl, data, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('POST', requestUrl, data, additionalHeaders || {});
});
} }
patch(requestUrl, data, additionalHeaders) { patch(requestUrl, data, additionalHeaders) {
return this.request('PATCH', requestUrl, data, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('PATCH', requestUrl, data, additionalHeaders || {});
});
} }
put(requestUrl, data, additionalHeaders) { put(requestUrl, data, additionalHeaders) {
return this.request('PUT', requestUrl, data, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('PUT', requestUrl, data, additionalHeaders || {});
});
} }
head(requestUrl, additionalHeaders) { head(requestUrl, additionalHeaders) {
return this.request('HEAD', requestUrl, null, additionalHeaders || {}); return __awaiter(this, void 0, void 0, function* () {
return this.request('HEAD', requestUrl, null, additionalHeaders || {});
});
} }
sendStream(verb, requestUrl, stream, additionalHeaders) { sendStream(verb, requestUrl, stream, additionalHeaders) {
return this.request(verb, requestUrl, stream, additionalHeaders); return __awaiter(this, void 0, void 0, function* () {
return this.request(verb, requestUrl, stream, additionalHeaders);
});
} }
/** /**
* Gets a typed object from an endpoint * Gets a typed object from an endpoint
* Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise
*/ */
async getJson(requestUrl, additionalHeaders = {}) { getJson(requestUrl, additionalHeaders = {}) {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); return __awaiter(this, void 0, void 0, function* () {
let res = await this.get(requestUrl, additionalHeaders); additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
return this._processResponse(res, this.requestOptions); const res = yield this.get(requestUrl, additionalHeaders);
return this._processResponse(res, this.requestOptions);
});
} }
async postJson(requestUrl, obj, additionalHeaders = {}) { postJson(requestUrl, obj, additionalHeaders = {}) {
let data = JSON.stringify(obj, null, 2); return __awaiter(this, void 0, void 0, function* () {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); const data = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
let res = await this.post(requestUrl, data, additionalHeaders); additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
return this._processResponse(res, this.requestOptions); const res = yield this.post(requestUrl, data, additionalHeaders);
return this._processResponse(res, this.requestOptions);
});
} }
async putJson(requestUrl, obj, additionalHeaders = {}) { putJson(requestUrl, obj, additionalHeaders = {}) {
let data = JSON.stringify(obj, null, 2); return __awaiter(this, void 0, void 0, function* () {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); const data = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
let res = await this.put(requestUrl, data, additionalHeaders); additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
return this._processResponse(res, this.requestOptions); const res = yield this.put(requestUrl, data, additionalHeaders);
return this._processResponse(res, this.requestOptions);
});
} }
async patchJson(requestUrl, obj, additionalHeaders = {}) { patchJson(requestUrl, obj, additionalHeaders = {}) {
let data = JSON.stringify(obj, null, 2); return __awaiter(this, void 0, void 0, function* () {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); const data = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
let res = await this.patch(requestUrl, data, additionalHeaders); additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
return this._processResponse(res, this.requestOptions); const res = yield this.patch(requestUrl, data, additionalHeaders);
return this._processResponse(res, this.requestOptions);
});
} }
/** /**
* Makes a raw http request. * Makes a raw http request.
* All other methods such as get, post, patch, and request ultimately call this. * All other methods such as get, post, patch, and request ultimately call this.
* Prefer get, del, post and patch * Prefer get, del, post and patch
*/ */
async request(verb, requestUrl, data, headers) { request(verb, requestUrl, data, headers) {
if (this._disposed) { return __awaiter(this, void 0, void 0, function* () {
throw new Error('Client has already been disposed.'); if (this._disposed) {
} throw new Error('Client has already been disposed.');
let parsedUrl = new URL(requestUrl);
let info = this._prepareRequest(verb, parsedUrl, headers);
// Only perform retries on reads since writes may not be idempotent.
let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1
? this._maxRetries + 1
: 1;
let numTries = 0;
let response;
while (numTries < maxTries) {
response = await this.requestRaw(info, data);
// Check if it's an authentication challenge
if (response &&
response.message &&
response.message.statusCode === HttpCodes.Unauthorized) {
let authenticationHandler;
for (let i = 0; i < this.handlers.length; i++) {
if (this.handlers[i].canHandleAuthentication(response)) {
authenticationHandler = this.handlers[i];
break;
}
}
if (authenticationHandler) {
return authenticationHandler.handleAuthentication(this, info, data);
}
else {
// We have received an unauthorized response but have no handlers to handle it.
// Let the response return to the caller.
return response;
}
} }
let redirectsRemaining = this._maxRedirects; const parsedUrl = new URL(requestUrl);
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 && let info = this._prepareRequest(verb, parsedUrl, headers);
this._allowRedirects && // Only perform retries on reads since writes may not be idempotent.
redirectsRemaining > 0) { const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb)
const redirectUrl = response.message.headers['location']; ? this._maxRetries + 1
if (!redirectUrl) { : 1;
// if there's no location to redirect to, we won't let numTries = 0;
break; let response;
} do {
let parsedRedirectUrl = new URL(redirectUrl); response = yield this.requestRaw(info, data);
if (parsedUrl.protocol == 'https:' && // Check if it's an authentication challenge
parsedUrl.protocol != parsedRedirectUrl.protocol && if (response &&
!this._allowRedirectDowngrade) { response.message &&
throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.'); response.message.statusCode === HttpCodes.Unauthorized) {
} let authenticationHandler;
// we need to finish reading the response before reassigning response for (const handler of this.handlers) {
// which will leak the open socket. if (handler.canHandleAuthentication(response)) {
await response.readBody(); authenticationHandler = handler;
// strip authorization header if redirected to a different hostname break;
if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
for (let header in headers) {
// header names are case insensitive
if (header.toLowerCase() === 'authorization') {
delete headers[header];
} }
} }
if (authenticationHandler) {
return authenticationHandler.handleAuthentication(this, info, data);
}
else {
// We have received an unauthorized response but have no handlers to handle it.
// Let the response return to the caller.
return response;
}
} }
// let's make the request with the new redirectUrl let redirectsRemaining = this._maxRedirects;
info = this._prepareRequest(verb, parsedRedirectUrl, headers); while (response.message.statusCode &&
response = await this.requestRaw(info, data); HttpRedirectCodes.includes(response.message.statusCode) &&
redirectsRemaining--; this._allowRedirects &&
} redirectsRemaining > 0) {
if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) { const redirectUrl = response.message.headers['location'];
// If not a retry code, return immediately instead of retrying if (!redirectUrl) {
return response; // if there's no location to redirect to, we won't
} break;
numTries += 1; }
if (numTries < maxTries) { const parsedRedirectUrl = new URL(redirectUrl);
await response.readBody(); if (parsedUrl.protocol === 'https:' &&
await this._performExponentialBackoff(numTries); parsedUrl.protocol !== parsedRedirectUrl.protocol &&
} !this._allowRedirectDowngrade) {
} throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');
return response; }
// we need to finish reading the response before reassigning response
// which will leak the open socket.
yield response.readBody();
// strip authorization header if redirected to a different hostname
if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
for (const header in headers) {
// header names are case insensitive
if (header.toLowerCase() === 'authorization') {
delete headers[header];
}
}
}
// let's make the request with the new redirectUrl
info = this._prepareRequest(verb, parsedRedirectUrl, headers);
response = yield this.requestRaw(info, data);
redirectsRemaining--;
}
if (!response.message.statusCode ||
!HttpResponseRetryCodes.includes(response.message.statusCode)) {
// If not a retry code, return immediately instead of retrying
return response;
}
numTries += 1;
if (numTries < maxTries) {
yield response.readBody();
yield this._performExponentialBackoff(numTries);
}
} while (numTries < maxTries);
return response;
});
} }
/** /**
* Needs to be called if keepAlive is set to true in request options. * Needs to be called if keepAlive is set to true in request options.
@ -2652,14 +2763,22 @@ class HttpClient {
* @param data * @param data
*/ */
requestRaw(info, data) { requestRaw(info, data) {
return new Promise((resolve, reject) => { return __awaiter(this, void 0, void 0, function* () {
let callbackForResult = function (err, res) { return new Promise((resolve, reject) => {
if (err) { function callbackForResult(err, res) {
reject(err); if (err) {
reject(err);
}
else if (!res) {
// If `err` is not passed, then `res` must be passed.
reject(new Error('Unknown error'));
}
else {
resolve(res);
}
} }
resolve(res); this.requestRawWithCallback(info, data, callbackForResult);
}; });
this.requestRawWithCallback(info, data, callbackForResult);
}); });
} }
/** /**
@ -2669,21 +2788,24 @@ class HttpClient {
* @param onResult * @param onResult
*/ */
requestRawWithCallback(info, data, onResult) { requestRawWithCallback(info, data, onResult) {
let socket;
if (typeof data === 'string') { if (typeof data === 'string') {
if (!info.options.headers) {
info.options.headers = {};
}
info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
} }
let callbackCalled = false; let callbackCalled = false;
let handleResult = (err, res) => { function handleResult(err, res) {
if (!callbackCalled) { if (!callbackCalled) {
callbackCalled = true; callbackCalled = true;
onResult(err, res); onResult(err, res);
} }
}; }
let req = info.httpModule.request(info.options, (msg) => { const req = info.httpModule.request(info.options, (msg) => {
let res = new HttpClientResponse(msg); const res = new HttpClientResponse(msg);
handleResult(null, res); handleResult(undefined, res);
}); });
let socket;
req.on('socket', sock => { req.on('socket', sock => {
socket = sock; socket = sock;
}); });
@ -2692,12 +2814,12 @@ class HttpClient {
if (socket) { if (socket) {
socket.end(); socket.end();
} }
handleResult(new Error('Request timeout: ' + info.options.path), null); handleResult(new Error(`Request timeout: ${info.options.path}`));
}); });
req.on('error', function (err) { req.on('error', function (err) {
// err has statusCode property // err has statusCode property
// res should have headers // res should have headers
handleResult(err, null); handleResult(err);
}); });
if (data && typeof data === 'string') { if (data && typeof data === 'string') {
req.write(data, 'utf8'); req.write(data, 'utf8');
@ -2718,7 +2840,7 @@ class HttpClient {
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
*/ */
getAgent(serverUrl) { getAgent(serverUrl) {
let parsedUrl = new URL(serverUrl); const parsedUrl = new URL(serverUrl);
return this._getAgent(parsedUrl); return this._getAgent(parsedUrl);
} }
_prepareRequest(method, requestUrl, headers) { _prepareRequest(method, requestUrl, headers) {
@ -2742,21 +2864,19 @@ class HttpClient {
info.options.agent = this._getAgent(info.parsedUrl); info.options.agent = this._getAgent(info.parsedUrl);
// gives handlers an opportunity to participate // gives handlers an opportunity to participate
if (this.handlers) { if (this.handlers) {
this.handlers.forEach(handler => { for (const handler of this.handlers) {
handler.prepareRequest(info.options); handler.prepareRequest(info.options);
}); }
} }
return info; return info;
} }
_mergeHeaders(headers) { _mergeHeaders(headers) {
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
if (this.requestOptions && this.requestOptions.headers) { if (this.requestOptions && this.requestOptions.headers) {
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers)); return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {}));
} }
return lowercaseKeys(headers || {}); return lowercaseKeys(headers || {});
} }
_getExistingOrDefaultHeader(additionalHeaders, header, _default) { _getExistingOrDefaultHeader(additionalHeaders, header, _default) {
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
let clientHeader; let clientHeader;
if (this.requestOptions && this.requestOptions.headers) { if (this.requestOptions && this.requestOptions.headers) {
clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; clientHeader = lowercaseKeys(this.requestOptions.headers)[header];
@ -2765,8 +2885,8 @@ class HttpClient {
} }
_getAgent(parsedUrl) { _getAgent(parsedUrl) {
let agent; let agent;
let proxyUrl = pm.getProxyUrl(parsedUrl); const proxyUrl = pm.getProxyUrl(parsedUrl);
let useProxy = proxyUrl && proxyUrl.hostname; const useProxy = proxyUrl && proxyUrl.hostname;
if (this._keepAlive && useProxy) { if (this._keepAlive && useProxy) {
agent = this._proxyAgent; agent = this._proxyAgent;
} }
@ -2774,29 +2894,22 @@ class HttpClient {
agent = this._agent; agent = this._agent;
} }
// if agent is already assigned use that agent. // if agent is already assigned use that agent.
if (!!agent) { if (agent) {
return agent; return agent;
} }
const usingSsl = parsedUrl.protocol === 'https:'; const usingSsl = parsedUrl.protocol === 'https:';
let maxSockets = 100; let maxSockets = 100;
if (!!this.requestOptions) { if (this.requestOptions) {
maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets;
} }
if (useProxy) { // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis.
// If using proxy, need tunnel if (proxyUrl && proxyUrl.hostname) {
if (!tunnel) {
tunnel = __nccwpck_require__(4294);
}
const agentOptions = { const agentOptions = {
maxSockets: maxSockets, maxSockets,
keepAlive: this._keepAlive, keepAlive: this._keepAlive,
proxy: { proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && {
...((proxyUrl.username || proxyUrl.password) && { proxyAuth: `${proxyUrl.username}:${proxyUrl.password}`
proxyAuth: `${proxyUrl.username}:${proxyUrl.password}` })), { host: proxyUrl.hostname, port: proxyUrl.port })
}),
host: proxyUrl.hostname,
port: proxyUrl.port
}
}; };
let tunnelAgent; let tunnelAgent;
const overHttps = proxyUrl.protocol === 'https:'; const overHttps = proxyUrl.protocol === 'https:';
@ -2811,7 +2924,7 @@ class HttpClient {
} }
// if reusing agent across request and tunneling agent isn't assigned create a new agent // if reusing agent across request and tunneling agent isn't assigned create a new agent
if (this._keepAlive && !agent) { if (this._keepAlive && !agent) {
const options = { keepAlive: this._keepAlive, maxSockets: maxSockets }; const options = { keepAlive: this._keepAlive, maxSockets };
agent = usingSsl ? new https.Agent(options) : new http.Agent(options); agent = usingSsl ? new https.Agent(options) : new http.Agent(options);
this._agent = agent; this._agent = agent;
} }
@ -2830,109 +2943,117 @@ class HttpClient {
return agent; return agent;
} }
_performExponentialBackoff(retryNumber) { _performExponentialBackoff(retryNumber) {
retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); return __awaiter(this, void 0, void 0, function* () {
const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);
return new Promise(resolve => setTimeout(() => resolve(), ms)); const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);
return new Promise(resolve => setTimeout(() => resolve(), ms));
});
} }
static dateTimeDeserializer(key, value) { _processResponse(res, options) {
if (typeof value === 'string') { return __awaiter(this, void 0, void 0, function* () {
let a = new Date(value); return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
if (!isNaN(a.valueOf())) { const statusCode = res.message.statusCode || 0;
return a; const response = {
} statusCode,
} result: null,
return value; headers: {}
} };
async _processResponse(res, options) { // not found leads to null obj returned
return new Promise(async (resolve, reject) => { if (statusCode === HttpCodes.NotFound) {
const statusCode = res.message.statusCode; resolve(response);
const response = { }
statusCode: statusCode, // get the result from the body
result: null, function dateTimeDeserializer(key, value) {
headers: {} if (typeof value === 'string') {
}; const a = new Date(value);
// not found leads to null obj returned if (!isNaN(a.valueOf())) {
if (statusCode == HttpCodes.NotFound) { return a;
resolve(response); }
} }
let obj; return value;
let contents; }
// get the result from the body let obj;
try { let contents;
contents = await res.readBody(); try {
if (contents && contents.length > 0) { contents = yield res.readBody();
if (options && options.deserializeDates) { if (contents && contents.length > 0) {
obj = JSON.parse(contents, HttpClient.dateTimeDeserializer); if (options && options.deserializeDates) {
obj = JSON.parse(contents, dateTimeDeserializer);
}
else {
obj = JSON.parse(contents);
}
response.result = obj;
}
response.headers = res.message.headers;
}
catch (err) {
// Invalid resource (contents not json); leaving result obj null
}
// note that 3xx redirects are handled by the http layer.
if (statusCode > 299) {
let msg;
// if exception/error in body, attempt to get better error
if (obj && obj.message) {
msg = obj.message;
}
else if (contents && contents.length > 0) {
// it may be the case that the exception is in the body message as string
msg = contents;
} }
else { else {
obj = JSON.parse(contents); msg = `Failed request: (${statusCode})`;
} }
response.result = obj; const err = new HttpClientError(msg, statusCode);
} err.result = response.result;
response.headers = res.message.headers; reject(err);
}
catch (err) {
// Invalid resource (contents not json); leaving result obj null
}
// note that 3xx redirects are handled by the http layer.
if (statusCode > 299) {
let msg;
// if exception/error in body, attempt to get better error
if (obj && obj.message) {
msg = obj.message;
}
else if (contents && contents.length > 0) {
// it may be the case that the exception is in the body message as string
msg = contents;
} }
else { else {
msg = 'Failed request: (' + statusCode + ')'; resolve(response);
} }
let err = new HttpClientError(msg, statusCode); }));
err.result = response.result;
reject(err);
}
else {
resolve(response);
}
}); });
} }
} }
exports.HttpClient = HttpClient; exports.HttpClient = HttpClient;
const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
//# sourceMappingURL=index.js.map
/***/ }), /***/ }),
/***/ 7326: /***/ 4977:
/***/ ((__unused_webpack_module, exports) => { /***/ ((__unused_webpack_module, exports) => {
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.checkBypass = exports.getProxyUrl = void 0;
function getProxyUrl(reqUrl) { function getProxyUrl(reqUrl) {
let usingSsl = reqUrl.protocol === 'https:'; const usingSsl = reqUrl.protocol === 'https:';
let proxyUrl;
if (checkBypass(reqUrl)) { if (checkBypass(reqUrl)) {
return proxyUrl; return undefined;
} }
let proxyVar; const proxyVar = (() => {
if (usingSsl) { if (usingSsl) {
proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY']; return process.env['https_proxy'] || process.env['HTTPS_PROXY'];
}
else {
return process.env['http_proxy'] || process.env['HTTP_PROXY'];
}
})();
if (proxyVar) {
return new URL(proxyVar);
} }
else { else {
proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY']; return undefined;
} }
if (proxyVar) {
proxyUrl = new URL(proxyVar);
}
return proxyUrl;
} }
exports.getProxyUrl = getProxyUrl; exports.getProxyUrl = getProxyUrl;
function checkBypass(reqUrl) { function checkBypass(reqUrl) {
if (!reqUrl.hostname) { if (!reqUrl.hostname) {
return false; return false;
} }
let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''; const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
if (!noProxy) { if (!noProxy) {
return false; return false;
} }
@ -2948,12 +3069,12 @@ function checkBypass(reqUrl) {
reqPort = 443; reqPort = 443;
} }
// Format the request hostname and hostname with port // Format the request hostname and hostname with port
let upperReqHosts = [reqUrl.hostname.toUpperCase()]; const upperReqHosts = [reqUrl.hostname.toUpperCase()];
if (typeof reqPort === 'number') { if (typeof reqPort === 'number') {
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);
} }
// Compare request host against noproxy // Compare request host against noproxy
for (let upperNoProxyItem of noProxy for (const upperNoProxyItem of noProxy
.split(',') .split(',')
.map(x => x.trim().toUpperCase()) .map(x => x.trim().toUpperCase())
.filter(x => x)) { .filter(x => x)) {
@ -2964,7 +3085,7 @@ function checkBypass(reqUrl) {
return false; return false;
} }
exports.checkBypass = checkBypass; exports.checkBypass = checkBypass;
//# sourceMappingURL=proxy.js.map
/***/ }), /***/ }),

34
package-lock.json generated
View File

@ -9,7 +9,7 @@
"version": "4.0.0", "version": "4.0.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/cache": "^2.0.2", "@actions/cache": "^3.0.0",
"@actions/core": "^1.2.3", "@actions/core": "^1.2.3",
"@actions/exec": "^1.1.0", "@actions/exec": "^1.1.0",
"@actions/glob": "^0.2.0", "@actions/glob": "^0.2.0",
@ -31,14 +31,14 @@
} }
}, },
"node_modules/@actions/cache": { "node_modules/@actions/cache": {
"version": "2.0.2", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.0.0.tgz",
"integrity": "sha512-K1DCaW/OtHj5mV7hI7HEXiceX3rM4Nc0iG2hfYsrkEy6GiOeqlCC/LyICrBZIRDM6+vSrS12tg1ORl4hghomBA==", "integrity": "sha512-GL9CT1Fnu+pqs8TTB621q8Xa8Cilw2n9MwvbgMedetH7L1q2n6jY61gzbwGbKgtVbp3gVJ12aNMi4osSGXx3KQ==",
"dependencies": { "dependencies": {
"@actions/core": "^1.2.6", "@actions/core": "^1.2.6",
"@actions/exec": "^1.0.1", "@actions/exec": "^1.0.1",
"@actions/glob": "^0.1.0", "@actions/glob": "^0.1.0",
"@actions/http-client": "^1.0.9", "@actions/http-client": "^2.0.1",
"@actions/io": "^1.0.1", "@actions/io": "^1.0.1",
"@azure/ms-rest-js": "^2.6.0", "@azure/ms-rest-js": "^2.6.0",
"@azure/storage-blob": "^12.8.0", "@azure/storage-blob": "^12.8.0",
@ -56,11 +56,11 @@
} }
}, },
"node_modules/@actions/cache/node_modules/@actions/http-client": { "node_modules/@actions/cache/node_modules/@actions/http-client": {
"version": "1.0.11", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"dependencies": { "dependencies": {
"tunnel": "0.0.6" "tunnel": "^0.0.6"
} }
}, },
"node_modules/@actions/cache/node_modules/semver": { "node_modules/@actions/cache/node_modules/semver": {
@ -11337,14 +11337,14 @@
}, },
"dependencies": { "dependencies": {
"@actions/cache": { "@actions/cache": {
"version": "2.0.2", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/@actions/cache/-/cache-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-3.0.0.tgz",
"integrity": "sha512-K1DCaW/OtHj5mV7hI7HEXiceX3rM4Nc0iG2hfYsrkEy6GiOeqlCC/LyICrBZIRDM6+vSrS12tg1ORl4hghomBA==", "integrity": "sha512-GL9CT1Fnu+pqs8TTB621q8Xa8Cilw2n9MwvbgMedetH7L1q2n6jY61gzbwGbKgtVbp3gVJ12aNMi4osSGXx3KQ==",
"requires": { "requires": {
"@actions/core": "^1.2.6", "@actions/core": "^1.2.6",
"@actions/exec": "^1.0.1", "@actions/exec": "^1.0.1",
"@actions/glob": "^0.1.0", "@actions/glob": "^0.1.0",
"@actions/http-client": "^1.0.9", "@actions/http-client": "^2.0.1",
"@actions/io": "^1.0.1", "@actions/io": "^1.0.1",
"@azure/ms-rest-js": "^2.6.0", "@azure/ms-rest-js": "^2.6.0",
"@azure/storage-blob": "^12.8.0", "@azure/storage-blob": "^12.8.0",
@ -11362,11 +11362,11 @@
} }
}, },
"@actions/http-client": { "@actions/http-client": {
"version": "1.0.11", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"requires": { "requires": {
"tunnel": "0.0.6" "tunnel": "^0.0.6"
} }
}, },
"semver": { "semver": {

View File

@ -9,7 +9,7 @@
"format": "prettier --write \"{,!(node_modules)/**/}*.ts\"", "format": "prettier --write \"{,!(node_modules)/**/}*.ts\"",
"format-check": "prettier --check \"{,!(node_modules)/**/}*.ts\"", "format-check": "prettier --check \"{,!(node_modules)/**/}*.ts\"",
"release": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts && git add -f dist/", "release": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts && git add -f dist/",
"test": "jest" "test": "jest --coverage"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -23,7 +23,7 @@
"author": "GitHub", "author": "GitHub",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/cache": "^2.0.2", "@actions/cache": "^3.0.0",
"@actions/core": "^1.2.3", "@actions/core": "^1.2.3",
"@actions/exec": "^1.1.0", "@actions/exec": "^1.1.0",
"@actions/glob": "^0.2.0", "@actions/glob": "^0.2.0",

View File

@ -43,17 +43,11 @@ async function saveCache(packageManager: string) {
return; return;
} }
try { const cacheId = await cache.saveCache(cachePaths, primaryKey);
await cache.saveCache(cachePaths, primaryKey); if (cacheId == -1) {
core.info(`Cache saved with the key: ${primaryKey}`); return;
} catch (error) {
const err = error as Error;
if (err.name === cache.ReserveCacheError.name) {
core.info(err.message);
} else {
throw error;
}
} }
core.info(`Cache saved with the key: ${primaryKey}`);
} }
function isCacheDirectoryExists(cacheDirectory: string[]) { function isCacheDirectoryExists(cacheDirectory: string[]) {