@@ -7174,14 +7174,28 @@ class Command {
7174
7174
return cmdStr;
7175
7175
}
7176
7176
}
7177
+ /**
7178
+ * Sanitizes an input into a string so it can be passed into issueCommand safely
7179
+ * @param input input to sanitize into a string
7180
+ */
7181
+ function toCommandValue(input) {
7182
+ if (input === null || input === undefined) {
7183
+ return '';
7184
+ }
7185
+ else if (typeof input === 'string' || input instanceof String) {
7186
+ return input;
7187
+ }
7188
+ return JSON.stringify(input);
7189
+ }
7190
+ exports.toCommandValue = toCommandValue;
7177
7191
function escapeData(s) {
7178
- return (s || '' )
7192
+ return toCommandValue(s )
7179
7193
.replace(/%/g, '%25')
7180
7194
.replace(/\r/g, '%0D')
7181
7195
.replace(/\n/g, '%0A');
7182
7196
}
7183
7197
function escapeProperty(s) {
7184
- return (s || '' )
7198
+ return toCommandValue(s )
7185
7199
.replace(/%/g, '%25')
7186
7200
.replace(/\r/g, '%0D')
7187
7201
.replace(/\n/g, '%0A')
@@ -9190,11 +9204,13 @@ var ExitCode;
9190
9204
/**
9191
9205
* Sets env variable for this action and future actions in the job
9192
9206
* @param name the name of the variable to set
9193
- * @param val the value of the variable
9207
+ * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
9194
9208
*/
9209
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9195
9210
function exportVariable(name, val) {
9196
- process.env[name] = val;
9197
- command_1.issueCommand('set-env', { name }, val);
9211
+ const convertedVal = command_1.toCommandValue(val);
9212
+ process.env[name] = convertedVal;
9213
+ command_1.issueCommand('set-env', { name }, convertedVal);
9198
9214
}
9199
9215
exports.exportVariable = exportVariable;
9200
9216
/**
@@ -9233,12 +9249,22 @@ exports.getInput = getInput;
9233
9249
* Sets the value of an output.
9234
9250
*
9235
9251
* @param name name of the output to set
9236
- * @param value value to store
9252
+ * @param value value to store. Non-string values will be converted to a string via JSON.stringify
9237
9253
*/
9254
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9238
9255
function setOutput(name, value) {
9239
9256
command_1.issueCommand('set-output', { name }, value);
9240
9257
}
9241
9258
exports.setOutput = setOutput;
9259
+ /**
9260
+ * Enables or disables the echoing of commands into stdout for the rest of the step.
9261
+ * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
9262
+ *
9263
+ */
9264
+ function setCommandEcho(enabled) {
9265
+ command_1.issue('echo', enabled ? 'on' : 'off');
9266
+ }
9267
+ exports.setCommandEcho = setCommandEcho;
9242
9268
//-----------------------------------------------------------------------
9243
9269
// Results
9244
9270
//-----------------------------------------------------------------------
@@ -9272,18 +9298,18 @@ function debug(message) {
9272
9298
exports.debug = debug;
9273
9299
/**
9274
9300
* Adds an error issue
9275
- * @param message error issue message
9301
+ * @param message error issue message. Errors will be converted to string via toString()
9276
9302
*/
9277
9303
function error(message) {
9278
- command_1.issue('error', message);
9304
+ command_1.issue('error', message instanceof Error ? message.toString() : message );
9279
9305
}
9280
9306
exports.error = error;
9281
9307
/**
9282
9308
* Adds an warning issue
9283
- * @param message warning issue message
9309
+ * @param message warning issue message. Errors will be converted to string via toString()
9284
9310
*/
9285
9311
function warning(message) {
9286
- command_1.issue('warning', message);
9312
+ command_1.issue('warning', message instanceof Error ? message.toString() : message );
9287
9313
}
9288
9314
exports.warning = warning;
9289
9315
/**
@@ -9341,8 +9367,9 @@ exports.group = group;
9341
9367
* Saves state for current action, the state can only be retrieved by this action's post job execution.
9342
9368
*
9343
9369
* @param name name of the state to store
9344
- * @param value value to store
9370
+ * @param value value to store. Non-string values will be converted to a string via JSON.stringify
9345
9371
*/
9372
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9346
9373
function saveState(name, value) {
9347
9374
command_1.issueCommand('save-state', { name }, value);
9348
9375
}
@@ -9694,6 +9721,7 @@ var HttpCodes;
9694
9721
HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout";
9695
9722
HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict";
9696
9723
HttpCodes[HttpCodes["Gone"] = 410] = "Gone";
9724
+ HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests";
9697
9725
HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError";
9698
9726
HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented";
9699
9727
HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
@@ -9718,8 +9746,18 @@ function getProxyUrl(serverUrl) {
9718
9746
return proxyUrl ? proxyUrl.href : '';
9719
9747
}
9720
9748
exports.getProxyUrl = getProxyUrl;
9721
- const HttpRedirectCodes = [HttpCodes.MovedPermanently, HttpCodes.ResourceMoved, HttpCodes.SeeOther, HttpCodes.TemporaryRedirect, HttpCodes.PermanentRedirect];
9722
- const HttpResponseRetryCodes = [HttpCodes.BadGateway, HttpCodes.ServiceUnavailable, HttpCodes.GatewayTimeout];
9749
+ const HttpRedirectCodes = [
9750
+ HttpCodes.MovedPermanently,
9751
+ HttpCodes.ResourceMoved,
9752
+ HttpCodes.SeeOther,
9753
+ HttpCodes.TemporaryRedirect,
9754
+ HttpCodes.PermanentRedirect
9755
+ ];
9756
+ const HttpResponseRetryCodes = [
9757
+ HttpCodes.BadGateway,
9758
+ HttpCodes.ServiceUnavailable,
9759
+ HttpCodes.GatewayTimeout
9760
+ ];
9723
9761
const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];
9724
9762
const ExponentialBackoffCeiling = 10;
9725
9763
const ExponentialBackoffTimeSlice = 5;
@@ -9844,18 +9882,22 @@ class HttpClient {
9844
9882
*/
9845
9883
async request(verb, requestUrl, data, headers) {
9846
9884
if (this._disposed) {
9847
- throw new Error(" Client has already been disposed." );
9885
+ throw new Error(' Client has already been disposed.' );
9848
9886
}
9849
9887
let parsedUrl = url.parse(requestUrl);
9850
9888
let info = this._prepareRequest(verb, parsedUrl, headers);
9851
9889
// Only perform retries on reads since writes may not be idempotent.
9852
- let maxTries = (this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1) ? this._maxRetries + 1 : 1;
9890
+ let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1
9891
+ ? this._maxRetries + 1
9892
+ : 1;
9853
9893
let numTries = 0;
9854
9894
let response;
9855
9895
while (numTries < maxTries) {
9856
9896
response = await this.requestRaw(info, data);
9857
9897
// Check if it's an authentication challenge
9858
- if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) {
9898
+ if (response &&
9899
+ response.message &&
9900
+ response.message.statusCode === HttpCodes.Unauthorized) {
9859
9901
let authenticationHandler;
9860
9902
for (let i = 0; i < this.handlers.length; i++) {
9861
9903
if (this.handlers[i].canHandleAuthentication(response)) {
@@ -9873,21 +9915,32 @@ class HttpClient {
9873
9915
}
9874
9916
}
9875
9917
let redirectsRemaining = this._maxRedirects;
9876
- while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1
9877
- && this._allowRedirects
9878
- && redirectsRemaining > 0) {
9879
- const redirectUrl = response.message.headers[" location" ];
9918
+ while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 &&
9919
+ this._allowRedirects &&
9920
+ redirectsRemaining > 0) {
9921
+ const redirectUrl = response.message.headers[' location' ];
9880
9922
if (!redirectUrl) {
9881
9923
// if there's no location to redirect to, we won't
9882
9924
break;
9883
9925
}
9884
9926
let parsedRedirectUrl = url.parse(redirectUrl);
9885
- if (parsedUrl.protocol == 'https:' && parsedUrl.protocol != parsedRedirectUrl.protocol && !this._allowRedirectDowngrade) {
9886
- 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.");
9927
+ if (parsedUrl.protocol == 'https:' &&
9928
+ parsedUrl.protocol != parsedRedirectUrl.protocol &&
9929
+ !this._allowRedirectDowngrade) {
9930
+ 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.');
9887
9931
}
9888
9932
// we need to finish reading the response before reassigning response
9889
9933
// which will leak the open socket.
9890
9934
await response.readBody();
9935
+ // strip authorization header if redirected to a different hostname
9936
+ if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
9937
+ for (let header in headers) {
9938
+ // header names are case insensitive
9939
+ if (header.toLowerCase() === 'authorization') {
9940
+ delete headers[header];
9941
+ }
9942
+ }
9943
+ }
9891
9944
// let's make the request with the new redirectUrl
9892
9945
info = this._prepareRequest(verb, parsedRedirectUrl, headers);
9893
9946
response = await this.requestRaw(info, data);
@@ -9938,8 +9991,8 @@ class HttpClient {
9938
9991
*/
9939
9992
requestRawWithCallback(info, data, onResult) {
9940
9993
let socket;
9941
- if (typeof ( data) === 'string') {
9942
- info.options.headers[" Content-Length" ] = Buffer.byteLength(data, 'utf8');
9994
+ if (typeof data === 'string') {
9995
+ info.options.headers[' Content-Length' ] = Buffer.byteLength(data, 'utf8');
9943
9996
}
9944
9997
let callbackCalled = false;
9945
9998
let handleResult = (err, res) => {
@@ -9952,7 +10005,7 @@ class HttpClient {
9952
10005
let res = new HttpClientResponse(msg);
9953
10006
handleResult(null, res);
9954
10007
});
9955
- req.on('socket', ( sock) => {
10008
+ req.on('socket', sock => {
9956
10009
socket = sock;
9957
10010
});
9958
10011
// If we ever get disconnected, we want the socket to timeout eventually
@@ -9967,10 +10020,10 @@ class HttpClient {
9967
10020
// res should have headers
9968
10021
handleResult(err, null);
9969
10022
});
9970
- if (data && typeof ( data) === 'string') {
10023
+ if (data && typeof data === 'string') {
9971
10024
req.write(data, 'utf8');
9972
10025
}
9973
- if (data && typeof ( data) !== 'string') {
10026
+ if (data && typeof data !== 'string') {
9974
10027
data.on('close', function () {
9975
10028
req.end();
9976
10029
});
@@ -9997,31 +10050,34 @@ class HttpClient {
9997
10050
const defaultPort = usingSsl ? 443 : 80;
9998
10051
info.options = {};
9999
10052
info.options.host = info.parsedUrl.hostname;
10000
- info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort;
10001
- info.options.path = (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
10053
+ info.options.port = info.parsedUrl.port
10054
+ ? parseInt(info.parsedUrl.port)
10055
+ : defaultPort;
10056
+ info.options.path =
10057
+ (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
10002
10058
info.options.method = method;
10003
10059
info.options.headers = this._mergeHeaders(headers);
10004
10060
if (this.userAgent != null) {
10005
- info.options.headers[" user-agent" ] = this.userAgent;
10061
+ info.options.headers[' user-agent' ] = this.userAgent;
10006
10062
}
10007
10063
info.options.agent = this._getAgent(info.parsedUrl);
10008
10064
// gives handlers an opportunity to participate
10009
10065
if (this.handlers) {
10010
- this.handlers.forEach(( handler) => {
10066
+ this.handlers.forEach(handler => {
10011
10067
handler.prepareRequest(info.options);
10012
10068
});
10013
10069
}
10014
10070
return info;
10015
10071
}
10016
10072
_mergeHeaders(headers) {
10017
- const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {});
10073
+ const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (( c[k.toLowerCase()] = obj[k]) , c), {});
10018
10074
if (this.requestOptions && this.requestOptions.headers) {
10019
10075
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));
10020
10076
}
10021
10077
return lowercaseKeys(headers || {});
10022
10078
}
10023
10079
_getExistingOrDefaultHeader(additionalHeaders, header, _default) {
10024
- const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {});
10080
+ const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (( c[k.toLowerCase()] = obj[k]) , c), {});
10025
10081
let clientHeader;
10026
10082
if (this.requestOptions && this.requestOptions.headers) {
10027
10083
clientHeader = lowercaseKeys(this.requestOptions.headers)[header];
@@ -10059,7 +10115,7 @@ class HttpClient {
10059
10115
proxyAuth: proxyUrl.auth,
10060
10116
host: proxyUrl.hostname,
10061
10117
port: proxyUrl.port
10062
- },
10118
+ }
10063
10119
};
10064
10120
let tunnelAgent;
10065
10121
const overHttps = proxyUrl.protocol === 'https:';
@@ -10086,7 +10142,9 @@ class HttpClient {
10086
10142
// we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process
10087
10143
// http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options
10088
10144
// we have to cast it to any and change it directly
10089
- agent.options = Object.assign(agent.options || {}, { rejectUnauthorized: false });
10145
+ agent.options = Object.assign(agent.options || {}, {
10146
+ rejectUnauthorized: false
10147
+ });
10090
10148
}
10091
10149
return agent;
10092
10150
}
@@ -10147,7 +10205,7 @@ class HttpClient {
10147
10205
msg = contents;
10148
10206
}
10149
10207
else {
10150
- msg = " Failed request: (" + statusCode + ")" ;
10208
+ msg = ' Failed request: (' + statusCode + ')' ;
10151
10209
}
10152
10210
let err = new Error(msg);
10153
10211
// attach statusCode and body obj (if available) to the error object
@@ -27832,12 +27890,10 @@ function getProxyUrl(reqUrl) {
27832
27890
}
27833
27891
let proxyVar;
27834
27892
if (usingSsl) {
27835
- proxyVar = process.env["https_proxy"] ||
27836
- process.env["HTTPS_PROXY"];
27893
+ proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY'];
27837
27894
}
27838
27895
else {
27839
- proxyVar = process.env["http_proxy"] ||
27840
- process.env["HTTP_PROXY"];
27896
+ proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY'];
27841
27897
}
27842
27898
if (proxyVar) {
27843
27899
proxyUrl = url.parse(proxyVar);
@@ -27849,7 +27905,7 @@ function checkBypass(reqUrl) {
27849
27905
if (!reqUrl.hostname) {
27850
27906
return false;
27851
27907
}
27852
- let noProxy = process.env[" no_proxy" ] || process.env[" NO_PROXY" ] || '';
27908
+ let noProxy = process.env[' no_proxy' ] || process.env[' NO_PROXY' ] || '';
27853
27909
if (!noProxy) {
27854
27910
return false;
27855
27911
}
@@ -27870,7 +27926,10 @@ function checkBypass(reqUrl) {
27870
27926
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);
27871
27927
}
27872
27928
// Compare request host against noproxy
27873
- for (let upperNoProxyItem of noProxy.split(',').map(x => x.trim().toUpperCase()).filter(x => x)) {
27929
+ for (let upperNoProxyItem of noProxy
27930
+ .split(',')
27931
+ .map(x => x.trim().toUpperCase())
27932
+ .filter(x => x)) {
27874
27933
if (upperReqHosts.some(x => x === upperNoProxyItem)) {
27875
27934
return true;
27876
27935
}
0 commit comments