@actions/cache 1.0.5 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +8 -8
- package/README.md +44 -44
- package/lib/cache.d.ts +26 -26
- package/lib/cache.js +164 -146
- package/lib/cache.js.map +1 -1
- package/lib/internal/cacheHttpClient.d.ts +8 -8
- package/lib/internal/cacheHttpClient.js +215 -214
- package/lib/internal/cacheHttpClient.js.map +1 -1
- package/lib/internal/cacheUtils.d.ts +11 -11
- package/lib/internal/cacheUtils.js +169 -169
- package/lib/internal/constants.d.ts +12 -12
- package/lib/internal/constants.js +23 -23
- package/lib/internal/downloadUtils.d.ts +74 -74
- package/lib/internal/downloadUtils.js +229 -229
- package/lib/internal/downloadUtils.js.map +1 -1
- package/lib/internal/requestUtils.d.ts +7 -7
- package/lib/internal/requestUtils.js +118 -118
- package/lib/internal/tar.d.ts +4 -3
- package/lib/internal/tar.js +163 -124
- package/lib/internal/tar.js.map +1 -1
- package/lib/options.d.ts +56 -56
- package/lib/options.js +61 -61
- package/package.json +55 -55
|
@@ -1,230 +1,230 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
12
|
-
if (mod && mod.__esModule) return mod;
|
|
13
|
-
var result = {};
|
|
14
|
-
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
|
15
|
-
result["default"] = mod;
|
|
16
|
-
return result;
|
|
17
|
-
};
|
|
18
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
const core = __importStar(require("@actions/core"));
|
|
20
|
-
const http_client_1 = require("@actions/http-client");
|
|
21
|
-
const storage_blob_1 = require("@azure/storage-blob");
|
|
22
|
-
const buffer = __importStar(require("buffer"));
|
|
23
|
-
const fs = __importStar(require("fs"));
|
|
24
|
-
const stream = __importStar(require("stream"));
|
|
25
|
-
const util = __importStar(require("util"));
|
|
26
|
-
const utils = __importStar(require("./cacheUtils"));
|
|
27
|
-
const constants_1 = require("./constants");
|
|
28
|
-
const requestUtils_1 = require("./requestUtils");
|
|
29
|
-
/**
|
|
30
|
-
* Pipes the body of a HTTP response to a stream
|
|
31
|
-
*
|
|
32
|
-
* @param response the HTTP response
|
|
33
|
-
* @param output the writable stream
|
|
34
|
-
*/
|
|
35
|
-
function pipeResponseToStream(response, output) {
|
|
36
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
-
const pipeline = util.promisify(stream.pipeline);
|
|
38
|
-
yield pipeline(response.message, output);
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Class for tracking the download state and displaying stats.
|
|
43
|
-
*/
|
|
44
|
-
class DownloadProgress {
|
|
45
|
-
constructor(contentLength) {
|
|
46
|
-
this.contentLength = contentLength;
|
|
47
|
-
this.segmentIndex = 0;
|
|
48
|
-
this.segmentSize = 0;
|
|
49
|
-
this.segmentOffset = 0;
|
|
50
|
-
this.receivedBytes = 0;
|
|
51
|
-
this.displayedComplete = false;
|
|
52
|
-
this.startTime = Date.now();
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Progress to the next segment. Only call this method when the previous segment
|
|
56
|
-
* is complete.
|
|
57
|
-
*
|
|
58
|
-
* @param segmentSize the length of the next segment
|
|
59
|
-
*/
|
|
60
|
-
nextSegment(segmentSize) {
|
|
61
|
-
this.segmentOffset = this.segmentOffset + this.segmentSize;
|
|
62
|
-
this.segmentIndex = this.segmentIndex + 1;
|
|
63
|
-
this.segmentSize = segmentSize;
|
|
64
|
-
this.receivedBytes = 0;
|
|
65
|
-
core.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`);
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Sets the number of bytes received for the current segment.
|
|
69
|
-
*
|
|
70
|
-
* @param receivedBytes the number of bytes received
|
|
71
|
-
*/
|
|
72
|
-
setReceivedBytes(receivedBytes) {
|
|
73
|
-
this.receivedBytes = receivedBytes;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Returns the total number of bytes transferred.
|
|
77
|
-
*/
|
|
78
|
-
getTransferredBytes() {
|
|
79
|
-
return this.segmentOffset + this.receivedBytes;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Returns true if the download is complete.
|
|
83
|
-
*/
|
|
84
|
-
isDone() {
|
|
85
|
-
return this.getTransferredBytes() === this.contentLength;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Prints the current download stats. Once the download completes, this will print one
|
|
89
|
-
* last line and then stop.
|
|
90
|
-
*/
|
|
91
|
-
display() {
|
|
92
|
-
if (this.displayedComplete) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
const transferredBytes = this.segmentOffset + this.receivedBytes;
|
|
96
|
-
const percentage = (100 * (transferredBytes / this.contentLength)).toFixed(1);
|
|
97
|
-
const elapsedTime = Date.now() - this.startTime;
|
|
98
|
-
const downloadSpeed = (transferredBytes /
|
|
99
|
-
(1024 * 1024) /
|
|
100
|
-
(elapsedTime / 1000)).toFixed(1);
|
|
101
|
-
core.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`);
|
|
102
|
-
if (this.isDone()) {
|
|
103
|
-
this.displayedComplete = true;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Returns a function used to handle TransferProgressEvents.
|
|
108
|
-
*/
|
|
109
|
-
onProgress() {
|
|
110
|
-
return (progress) => {
|
|
111
|
-
this.setReceivedBytes(progress.loadedBytes);
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Starts the timer that displays the stats.
|
|
116
|
-
*
|
|
117
|
-
* @param delayInMs the delay between each write
|
|
118
|
-
*/
|
|
119
|
-
startDisplayTimer(delayInMs = 1000) {
|
|
120
|
-
const displayCallback = () => {
|
|
121
|
-
this.display();
|
|
122
|
-
if (!this.isDone()) {
|
|
123
|
-
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Stops the timer that displays the stats. As this typically indicates the download
|
|
130
|
-
* is complete, this will display one last line, unless the last line has already
|
|
131
|
-
* been written.
|
|
132
|
-
*/
|
|
133
|
-
stopDisplayTimer() {
|
|
134
|
-
if (this.timeoutHandle) {
|
|
135
|
-
clearTimeout(this.timeoutHandle);
|
|
136
|
-
this.timeoutHandle = undefined;
|
|
137
|
-
}
|
|
138
|
-
this.display();
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
exports.DownloadProgress = DownloadProgress;
|
|
142
|
-
/**
|
|
143
|
-
* Download the cache using the Actions toolkit http-client
|
|
144
|
-
*
|
|
145
|
-
* @param archiveLocation the URL for the cache
|
|
146
|
-
* @param archivePath the local path where the cache is saved
|
|
147
|
-
*/
|
|
148
|
-
function downloadCacheHttpClient(archiveLocation, archivePath) {
|
|
149
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
-
const writeStream = fs.createWriteStream(archivePath);
|
|
151
|
-
const httpClient = new http_client_1.HttpClient('actions/cache');
|
|
152
|
-
const downloadResponse = yield requestUtils_1.retryHttpClientResponse('downloadCache', () => __awaiter(this, void 0, void 0, function* () { return httpClient.get(archiveLocation); }));
|
|
153
|
-
// Abort download if no traffic received over the socket.
|
|
154
|
-
downloadResponse.message.socket.setTimeout(constants_1.SocketTimeout, () => {
|
|
155
|
-
downloadResponse.message.destroy();
|
|
156
|
-
core.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`);
|
|
157
|
-
});
|
|
158
|
-
yield pipeResponseToStream(downloadResponse, writeStream);
|
|
159
|
-
// Validate download size.
|
|
160
|
-
const contentLengthHeader = downloadResponse.message.headers['content-length'];
|
|
161
|
-
if (contentLengthHeader) {
|
|
162
|
-
const expectedLength = parseInt(contentLengthHeader);
|
|
163
|
-
const actualLength = utils.
|
|
164
|
-
if (actualLength !== expectedLength) {
|
|
165
|
-
throw new Error(`Incomplete download. Expected file size: ${expectedLength}, actual file size: ${actualLength}`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
core.debug('Unable to validate download, no Content-Length header');
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
exports.downloadCacheHttpClient = downloadCacheHttpClient;
|
|
174
|
-
/**
|
|
175
|
-
* Download the cache using the Azure Storage SDK. Only call this method if the
|
|
176
|
-
* URL points to an Azure Storage endpoint.
|
|
177
|
-
*
|
|
178
|
-
* @param archiveLocation the URL for the cache
|
|
179
|
-
* @param archivePath the local path where the cache is saved
|
|
180
|
-
* @param options the download options with the defaults set
|
|
181
|
-
*/
|
|
182
|
-
function downloadCacheStorageSDK(archiveLocation, archivePath, options) {
|
|
183
|
-
var _a;
|
|
184
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
-
const client = new storage_blob_1.BlockBlobClient(archiveLocation, undefined, {
|
|
186
|
-
retryOptions: {
|
|
187
|
-
// Override the timeout used when downloading each 4 MB chunk
|
|
188
|
-
// The default is 2 min / MB, which is way too slow
|
|
189
|
-
tryTimeoutInMs: options.timeoutInMs
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
const properties = yield client.getProperties();
|
|
193
|
-
const contentLength = (_a = properties.contentLength) !== null && _a !== void 0 ? _a : -1;
|
|
194
|
-
if (contentLength < 0) {
|
|
195
|
-
// We should never hit this condition, but just in case fall back to downloading the
|
|
196
|
-
// file as one large stream
|
|
197
|
-
core.debug('Unable to determine content length, downloading file with http-client...');
|
|
198
|
-
yield downloadCacheHttpClient(archiveLocation, archivePath);
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
// Use downloadToBuffer for faster downloads, since internally it splits the
|
|
202
|
-
// file into 4 MB chunks which can then be parallelized and retried independently
|
|
203
|
-
//
|
|
204
|
-
// If the file exceeds the buffer maximum length (~1 GB on 32-bit systems and ~2 GB
|
|
205
|
-
// on 64-bit systems), split the download into multiple segments
|
|
206
|
-
const maxSegmentSize = buffer.constants.MAX_LENGTH;
|
|
207
|
-
const downloadProgress = new DownloadProgress(contentLength);
|
|
208
|
-
const fd = fs.openSync(archivePath, 'w');
|
|
209
|
-
try {
|
|
210
|
-
downloadProgress.startDisplayTimer();
|
|
211
|
-
while (!downloadProgress.isDone()) {
|
|
212
|
-
const segmentStart = downloadProgress.segmentOffset + downloadProgress.segmentSize;
|
|
213
|
-
const segmentSize = Math.min(maxSegmentSize, contentLength - segmentStart);
|
|
214
|
-
downloadProgress.nextSegment(segmentSize);
|
|
215
|
-
const result = yield client.downloadToBuffer(segmentStart, segmentSize, {
|
|
216
|
-
concurrency: options.downloadConcurrency,
|
|
217
|
-
onProgress: downloadProgress.onProgress()
|
|
218
|
-
});
|
|
219
|
-
fs.writeFileSync(fd, result);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
finally {
|
|
223
|
-
downloadProgress.stopDisplayTimer();
|
|
224
|
-
fs.closeSync(fd);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
exports.downloadCacheStorageSDK = downloadCacheStorageSDK;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
12
|
+
if (mod && mod.__esModule) return mod;
|
|
13
|
+
var result = {};
|
|
14
|
+
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
|
15
|
+
result["default"] = mod;
|
|
16
|
+
return result;
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
const core = __importStar(require("@actions/core"));
|
|
20
|
+
const http_client_1 = require("@actions/http-client");
|
|
21
|
+
const storage_blob_1 = require("@azure/storage-blob");
|
|
22
|
+
const buffer = __importStar(require("buffer"));
|
|
23
|
+
const fs = __importStar(require("fs"));
|
|
24
|
+
const stream = __importStar(require("stream"));
|
|
25
|
+
const util = __importStar(require("util"));
|
|
26
|
+
const utils = __importStar(require("./cacheUtils"));
|
|
27
|
+
const constants_1 = require("./constants");
|
|
28
|
+
const requestUtils_1 = require("./requestUtils");
|
|
29
|
+
/**
|
|
30
|
+
* Pipes the body of a HTTP response to a stream
|
|
31
|
+
*
|
|
32
|
+
* @param response the HTTP response
|
|
33
|
+
* @param output the writable stream
|
|
34
|
+
*/
|
|
35
|
+
function pipeResponseToStream(response, output) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
const pipeline = util.promisify(stream.pipeline);
|
|
38
|
+
yield pipeline(response.message, output);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Class for tracking the download state and displaying stats.
|
|
43
|
+
*/
|
|
44
|
+
class DownloadProgress {
|
|
45
|
+
constructor(contentLength) {
|
|
46
|
+
this.contentLength = contentLength;
|
|
47
|
+
this.segmentIndex = 0;
|
|
48
|
+
this.segmentSize = 0;
|
|
49
|
+
this.segmentOffset = 0;
|
|
50
|
+
this.receivedBytes = 0;
|
|
51
|
+
this.displayedComplete = false;
|
|
52
|
+
this.startTime = Date.now();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Progress to the next segment. Only call this method when the previous segment
|
|
56
|
+
* is complete.
|
|
57
|
+
*
|
|
58
|
+
* @param segmentSize the length of the next segment
|
|
59
|
+
*/
|
|
60
|
+
nextSegment(segmentSize) {
|
|
61
|
+
this.segmentOffset = this.segmentOffset + this.segmentSize;
|
|
62
|
+
this.segmentIndex = this.segmentIndex + 1;
|
|
63
|
+
this.segmentSize = segmentSize;
|
|
64
|
+
this.receivedBytes = 0;
|
|
65
|
+
core.debug(`Downloading segment at offset ${this.segmentOffset} with length ${this.segmentSize}...`);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sets the number of bytes received for the current segment.
|
|
69
|
+
*
|
|
70
|
+
* @param receivedBytes the number of bytes received
|
|
71
|
+
*/
|
|
72
|
+
setReceivedBytes(receivedBytes) {
|
|
73
|
+
this.receivedBytes = receivedBytes;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Returns the total number of bytes transferred.
|
|
77
|
+
*/
|
|
78
|
+
getTransferredBytes() {
|
|
79
|
+
return this.segmentOffset + this.receivedBytes;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns true if the download is complete.
|
|
83
|
+
*/
|
|
84
|
+
isDone() {
|
|
85
|
+
return this.getTransferredBytes() === this.contentLength;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Prints the current download stats. Once the download completes, this will print one
|
|
89
|
+
* last line and then stop.
|
|
90
|
+
*/
|
|
91
|
+
display() {
|
|
92
|
+
if (this.displayedComplete) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const transferredBytes = this.segmentOffset + this.receivedBytes;
|
|
96
|
+
const percentage = (100 * (transferredBytes / this.contentLength)).toFixed(1);
|
|
97
|
+
const elapsedTime = Date.now() - this.startTime;
|
|
98
|
+
const downloadSpeed = (transferredBytes /
|
|
99
|
+
(1024 * 1024) /
|
|
100
|
+
(elapsedTime / 1000)).toFixed(1);
|
|
101
|
+
core.info(`Received ${transferredBytes} of ${this.contentLength} (${percentage}%), ${downloadSpeed} MBs/sec`);
|
|
102
|
+
if (this.isDone()) {
|
|
103
|
+
this.displayedComplete = true;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Returns a function used to handle TransferProgressEvents.
|
|
108
|
+
*/
|
|
109
|
+
onProgress() {
|
|
110
|
+
return (progress) => {
|
|
111
|
+
this.setReceivedBytes(progress.loadedBytes);
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Starts the timer that displays the stats.
|
|
116
|
+
*
|
|
117
|
+
* @param delayInMs the delay between each write
|
|
118
|
+
*/
|
|
119
|
+
startDisplayTimer(delayInMs = 1000) {
|
|
120
|
+
const displayCallback = () => {
|
|
121
|
+
this.display();
|
|
122
|
+
if (!this.isDone()) {
|
|
123
|
+
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
this.timeoutHandle = setTimeout(displayCallback, delayInMs);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Stops the timer that displays the stats. As this typically indicates the download
|
|
130
|
+
* is complete, this will display one last line, unless the last line has already
|
|
131
|
+
* been written.
|
|
132
|
+
*/
|
|
133
|
+
stopDisplayTimer() {
|
|
134
|
+
if (this.timeoutHandle) {
|
|
135
|
+
clearTimeout(this.timeoutHandle);
|
|
136
|
+
this.timeoutHandle = undefined;
|
|
137
|
+
}
|
|
138
|
+
this.display();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.DownloadProgress = DownloadProgress;
|
|
142
|
+
/**
|
|
143
|
+
* Download the cache using the Actions toolkit http-client
|
|
144
|
+
*
|
|
145
|
+
* @param archiveLocation the URL for the cache
|
|
146
|
+
* @param archivePath the local path where the cache is saved
|
|
147
|
+
*/
|
|
148
|
+
function downloadCacheHttpClient(archiveLocation, archivePath) {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
const writeStream = fs.createWriteStream(archivePath);
|
|
151
|
+
const httpClient = new http_client_1.HttpClient('actions/cache');
|
|
152
|
+
const downloadResponse = yield requestUtils_1.retryHttpClientResponse('downloadCache', () => __awaiter(this, void 0, void 0, function* () { return httpClient.get(archiveLocation); }));
|
|
153
|
+
// Abort download if no traffic received over the socket.
|
|
154
|
+
downloadResponse.message.socket.setTimeout(constants_1.SocketTimeout, () => {
|
|
155
|
+
downloadResponse.message.destroy();
|
|
156
|
+
core.debug(`Aborting download, socket timed out after ${constants_1.SocketTimeout} ms`);
|
|
157
|
+
});
|
|
158
|
+
yield pipeResponseToStream(downloadResponse, writeStream);
|
|
159
|
+
// Validate download size.
|
|
160
|
+
const contentLengthHeader = downloadResponse.message.headers['content-length'];
|
|
161
|
+
if (contentLengthHeader) {
|
|
162
|
+
const expectedLength = parseInt(contentLengthHeader);
|
|
163
|
+
const actualLength = utils.getArchiveFileSizeInBytes(archivePath);
|
|
164
|
+
if (actualLength !== expectedLength) {
|
|
165
|
+
throw new Error(`Incomplete download. Expected file size: ${expectedLength}, actual file size: ${actualLength}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
core.debug('Unable to validate download, no Content-Length header');
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
exports.downloadCacheHttpClient = downloadCacheHttpClient;
|
|
174
|
+
/**
|
|
175
|
+
* Download the cache using the Azure Storage SDK. Only call this method if the
|
|
176
|
+
* URL points to an Azure Storage endpoint.
|
|
177
|
+
*
|
|
178
|
+
* @param archiveLocation the URL for the cache
|
|
179
|
+
* @param archivePath the local path where the cache is saved
|
|
180
|
+
* @param options the download options with the defaults set
|
|
181
|
+
*/
|
|
182
|
+
function downloadCacheStorageSDK(archiveLocation, archivePath, options) {
|
|
183
|
+
var _a;
|
|
184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
const client = new storage_blob_1.BlockBlobClient(archiveLocation, undefined, {
|
|
186
|
+
retryOptions: {
|
|
187
|
+
// Override the timeout used when downloading each 4 MB chunk
|
|
188
|
+
// The default is 2 min / MB, which is way too slow
|
|
189
|
+
tryTimeoutInMs: options.timeoutInMs
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
const properties = yield client.getProperties();
|
|
193
|
+
const contentLength = (_a = properties.contentLength) !== null && _a !== void 0 ? _a : -1;
|
|
194
|
+
if (contentLength < 0) {
|
|
195
|
+
// We should never hit this condition, but just in case fall back to downloading the
|
|
196
|
+
// file as one large stream
|
|
197
|
+
core.debug('Unable to determine content length, downloading file with http-client...');
|
|
198
|
+
yield downloadCacheHttpClient(archiveLocation, archivePath);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
// Use downloadToBuffer for faster downloads, since internally it splits the
|
|
202
|
+
// file into 4 MB chunks which can then be parallelized and retried independently
|
|
203
|
+
//
|
|
204
|
+
// If the file exceeds the buffer maximum length (~1 GB on 32-bit systems and ~2 GB
|
|
205
|
+
// on 64-bit systems), split the download into multiple segments
|
|
206
|
+
const maxSegmentSize = buffer.constants.MAX_LENGTH;
|
|
207
|
+
const downloadProgress = new DownloadProgress(contentLength);
|
|
208
|
+
const fd = fs.openSync(archivePath, 'w');
|
|
209
|
+
try {
|
|
210
|
+
downloadProgress.startDisplayTimer();
|
|
211
|
+
while (!downloadProgress.isDone()) {
|
|
212
|
+
const segmentStart = downloadProgress.segmentOffset + downloadProgress.segmentSize;
|
|
213
|
+
const segmentSize = Math.min(maxSegmentSize, contentLength - segmentStart);
|
|
214
|
+
downloadProgress.nextSegment(segmentSize);
|
|
215
|
+
const result = yield client.downloadToBuffer(segmentStart, segmentSize, {
|
|
216
|
+
concurrency: options.downloadConcurrency,
|
|
217
|
+
onProgress: downloadProgress.onProgress()
|
|
218
|
+
});
|
|
219
|
+
fs.writeFileSync(fd, result);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
finally {
|
|
223
|
+
downloadProgress.stopDisplayTimer();
|
|
224
|
+
fs.closeSync(fd);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
exports.downloadCacheStorageSDK = downloadCacheStorageSDK;
|
|
230
230
|
//# sourceMappingURL=downloadUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"downloadUtils.js","sourceRoot":"","sources":["../../src/internal/downloadUtils.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"downloadUtils.js","sourceRoot":"","sources":["../../src/internal/downloadUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { IHttpClientResponse, ITypedResponse } from '@actions/http-client/interfaces';
|
|
2
|
-
export declare function isSuccessStatusCode(statusCode?: number): boolean;
|
|
3
|
-
export declare function isServerErrorStatusCode(statusCode?: number): boolean;
|
|
4
|
-
export declare function isRetryableStatusCode(statusCode?: number): boolean;
|
|
5
|
-
export declare function retry<T>(name: string, method: () => Promise<T>, getStatusCode: (arg0: T) => number | undefined, maxAttempts?: number, delay?: number, onError?: ((arg0: Error) => T | undefined) | undefined): Promise<T>;
|
|
6
|
-
export declare function retryTypedResponse<T>(name: string, method: () => Promise<ITypedResponse<T>>, maxAttempts?: number, delay?: number): Promise<ITypedResponse<T>>;
|
|
7
|
-
export declare function retryHttpClientResponse
|
|
1
|
+
import { IHttpClientResponse, ITypedResponse } from '@actions/http-client/interfaces';
|
|
2
|
+
export declare function isSuccessStatusCode(statusCode?: number): boolean;
|
|
3
|
+
export declare function isServerErrorStatusCode(statusCode?: number): boolean;
|
|
4
|
+
export declare function isRetryableStatusCode(statusCode?: number): boolean;
|
|
5
|
+
export declare function retry<T>(name: string, method: () => Promise<T>, getStatusCode: (arg0: T) => number | undefined, maxAttempts?: number, delay?: number, onError?: ((arg0: Error) => T | undefined) | undefined): Promise<T>;
|
|
6
|
+
export declare function retryTypedResponse<T>(name: string, method: () => Promise<ITypedResponse<T>>, maxAttempts?: number, delay?: number): Promise<ITypedResponse<T>>;
|
|
7
|
+
export declare function retryHttpClientResponse(name: string, method: () => Promise<IHttpClientResponse>, maxAttempts?: number, delay?: number): Promise<IHttpClientResponse>;
|