mirror of
https://code.forgejo.org/actions/git-backporting
synced 2025-03-14 22:27:02 +01:00
fix: --no-squash on single-commit GitLab MR (#93)
Due to off-by-one error in GitLabMapper, --no-squash was not effective on an MR containing single commit. Fix by using the same condition as GitHubMapper.
This commit is contained in:
parent
b7df1f80dc
commit
300fa91a8a
7 changed files with 376 additions and 165 deletions
206
dist/cli/index.js
vendored
206
dist/cli/index.js
vendored
|
@ -1165,8 +1165,8 @@ class GitLabMapper {
|
|||
sourceRepo: await this.mapSourceRepo(mr),
|
||||
targetRepo: await this.mapTargetRepo(mr),
|
||||
// if commits list is provided use that as source
|
||||
nCommits: (commits && commits.length > 1) ? commits.length : 1,
|
||||
commits: (commits && commits.length > 1) ? commits : this.getSha(mr)
|
||||
nCommits: (commits && commits.length > 0) ? commits.length : 1,
|
||||
commits: (commits && commits.length > 0) ? commits : this.getSha(mr)
|
||||
};
|
||||
}
|
||||
getSha(mr) {
|
||||
|
@ -5847,6 +5847,29 @@ var Writable = (__nccwpck_require__(2781).Writable);
|
|||
var assert = __nccwpck_require__(9491);
|
||||
var debug = __nccwpck_require__(1133);
|
||||
|
||||
// Whether to use the native URL object or the legacy url module
|
||||
var useNativeURL = false;
|
||||
try {
|
||||
assert(new URL());
|
||||
}
|
||||
catch (error) {
|
||||
useNativeURL = error.code === "ERR_INVALID_URL";
|
||||
}
|
||||
|
||||
// URL fields to preserve in copy operations
|
||||
var preservedUrlFields = [
|
||||
"auth",
|
||||
"host",
|
||||
"hostname",
|
||||
"href",
|
||||
"path",
|
||||
"pathname",
|
||||
"port",
|
||||
"protocol",
|
||||
"query",
|
||||
"search",
|
||||
];
|
||||
|
||||
// Create handlers that pass events from native requests
|
||||
var events = ["abort", "aborted", "connect", "error", "socket", "timeout"];
|
||||
var eventHandlers = Object.create(null);
|
||||
|
@ -5856,19 +5879,20 @@ events.forEach(function (event) {
|
|||
};
|
||||
});
|
||||
|
||||
// Error types with codes
|
||||
var InvalidUrlError = createErrorType(
|
||||
"ERR_INVALID_URL",
|
||||
"Invalid URL",
|
||||
TypeError
|
||||
);
|
||||
// Error types with codes
|
||||
var RedirectionError = createErrorType(
|
||||
"ERR_FR_REDIRECTION_FAILURE",
|
||||
"Redirected request failed"
|
||||
);
|
||||
var TooManyRedirectsError = createErrorType(
|
||||
"ERR_FR_TOO_MANY_REDIRECTS",
|
||||
"Maximum number of redirects exceeded"
|
||||
"Maximum number of redirects exceeded",
|
||||
RedirectionError
|
||||
);
|
||||
var MaxBodyLengthExceededError = createErrorType(
|
||||
"ERR_FR_MAX_BODY_LENGTH_EXCEEDED",
|
||||
|
@ -5879,6 +5903,9 @@ var WriteAfterEndError = createErrorType(
|
|||
"write after end"
|
||||
);
|
||||
|
||||
// istanbul ignore next
|
||||
var destroy = Writable.prototype.destroy || noop;
|
||||
|
||||
// An HTTP(S) request that can be redirected
|
||||
function RedirectableRequest(options, responseCallback) {
|
||||
// Initialize the request
|
||||
|
@ -5900,7 +5927,13 @@ function RedirectableRequest(options, responseCallback) {
|
|||
// React to responses of native requests
|
||||
var self = this;
|
||||
this._onNativeResponse = function (response) {
|
||||
try {
|
||||
self._processResponse(response);
|
||||
}
|
||||
catch (cause) {
|
||||
self.emit("error", cause instanceof RedirectionError ?
|
||||
cause : new RedirectionError({ cause: cause }));
|
||||
}
|
||||
};
|
||||
|
||||
// Perform the first request
|
||||
|
@ -5909,10 +5942,17 @@ function RedirectableRequest(options, responseCallback) {
|
|||
RedirectableRequest.prototype = Object.create(Writable.prototype);
|
||||
|
||||
RedirectableRequest.prototype.abort = function () {
|
||||
abortRequest(this._currentRequest);
|
||||
destroyRequest(this._currentRequest);
|
||||
this._currentRequest.abort();
|
||||
this.emit("abort");
|
||||
};
|
||||
|
||||
RedirectableRequest.prototype.destroy = function (error) {
|
||||
destroyRequest(this._currentRequest, error);
|
||||
destroy.call(this, error);
|
||||
return this;
|
||||
};
|
||||
|
||||
// Writes buffered data to the current native request
|
||||
RedirectableRequest.prototype.write = function (data, encoding, callback) {
|
||||
// Writing is not allowed if end has been called
|
||||
|
@ -6025,6 +6065,7 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
|
|||
self.removeListener("abort", clearTimer);
|
||||
self.removeListener("error", clearTimer);
|
||||
self.removeListener("response", clearTimer);
|
||||
self.removeListener("close", clearTimer);
|
||||
if (callback) {
|
||||
self.removeListener("timeout", callback);
|
||||
}
|
||||
|
@ -6051,6 +6092,7 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
|
|||
this.on("abort", clearTimer);
|
||||
this.on("error", clearTimer);
|
||||
this.on("response", clearTimer);
|
||||
this.on("close", clearTimer);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
@ -6109,8 +6151,7 @@ RedirectableRequest.prototype._performRequest = function () {
|
|||
var protocol = this._options.protocol;
|
||||
var nativeProtocol = this._options.nativeProtocols[protocol];
|
||||
if (!nativeProtocol) {
|
||||
this.emit("error", new TypeError("Unsupported protocol " + protocol));
|
||||
return;
|
||||
throw new TypeError("Unsupported protocol " + protocol);
|
||||
}
|
||||
|
||||
// If specified, use the agent corresponding to the protocol
|
||||
|
@ -6202,15 +6243,14 @@ RedirectableRequest.prototype._processResponse = function (response) {
|
|||
}
|
||||
|
||||
// The response is a redirect, so abort the current request
|
||||
abortRequest(this._currentRequest);
|
||||
destroyRequest(this._currentRequest);
|
||||
// Discard the remainder of the response to avoid waiting for data
|
||||
response.destroy();
|
||||
|
||||
// RFC7231§6.4: A client SHOULD detect and intervene
|
||||
// in cyclical redirections (i.e., "infinite" redirection loops).
|
||||
if (++this._redirectCount > this._options.maxRedirects) {
|
||||
this.emit("error", new TooManyRedirectsError());
|
||||
return;
|
||||
throw new TooManyRedirectsError();
|
||||
}
|
||||
|
||||
// Store the request headers if applicable
|
||||
|
@ -6244,33 +6284,23 @@ RedirectableRequest.prototype._processResponse = function (response) {
|
|||
var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
|
||||
|
||||
// If the redirect is relative, carry over the host of the last request
|
||||
var currentUrlParts = url.parse(this._currentUrl);
|
||||
var currentUrlParts = parseUrl(this._currentUrl);
|
||||
var currentHost = currentHostHeader || currentUrlParts.host;
|
||||
var currentUrl = /^\w+:/.test(location) ? this._currentUrl :
|
||||
url.format(Object.assign(currentUrlParts, { host: currentHost }));
|
||||
|
||||
// Determine the URL of the redirection
|
||||
var redirectUrl;
|
||||
try {
|
||||
redirectUrl = url.resolve(currentUrl, location);
|
||||
}
|
||||
catch (cause) {
|
||||
this.emit("error", new RedirectionError({ cause: cause }));
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the redirected request
|
||||
debug("redirecting to", redirectUrl);
|
||||
var redirectUrl = resolveUrl(location, currentUrl);
|
||||
debug("redirecting to", redirectUrl.href);
|
||||
this._isRedirect = true;
|
||||
var redirectUrlParts = url.parse(redirectUrl);
|
||||
Object.assign(this._options, redirectUrlParts);
|
||||
spreadUrlObject(redirectUrl, this._options);
|
||||
|
||||
// Drop confidential headers when redirecting to a less secure protocol
|
||||
// or to a different domain that is not a superdomain
|
||||
if (redirectUrlParts.protocol !== currentUrlParts.protocol &&
|
||||
redirectUrlParts.protocol !== "https:" ||
|
||||
redirectUrlParts.host !== currentHost &&
|
||||
!isSubdomain(redirectUrlParts.host, currentHost)) {
|
||||
if (redirectUrl.protocol !== currentUrlParts.protocol &&
|
||||
redirectUrl.protocol !== "https:" ||
|
||||
redirectUrl.host !== currentHost &&
|
||||
!isSubdomain(redirectUrl.host, currentHost)) {
|
||||
removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
|
||||
}
|
||||
|
||||
|
@ -6285,23 +6315,12 @@ RedirectableRequest.prototype._processResponse = function (response) {
|
|||
method: method,
|
||||
headers: requestHeaders,
|
||||
};
|
||||
try {
|
||||
beforeRedirect(this._options, responseDetails, requestDetails);
|
||||
}
|
||||
catch (err) {
|
||||
this.emit("error", err);
|
||||
return;
|
||||
}
|
||||
this._sanitizeOptions(this._options);
|
||||
}
|
||||
|
||||
// Perform the redirected request
|
||||
try {
|
||||
this._performRequest();
|
||||
}
|
||||
catch (cause) {
|
||||
this.emit("error", new RedirectionError({ cause: cause }));
|
||||
}
|
||||
};
|
||||
|
||||
// Wraps the key/value object of protocols with redirect functionality
|
||||
|
@ -6321,27 +6340,16 @@ function wrap(protocols) {
|
|||
|
||||
// Executes a request, following redirects
|
||||
function request(input, options, callback) {
|
||||
// Parse parameters
|
||||
if (isString(input)) {
|
||||
var parsed;
|
||||
try {
|
||||
parsed = urlToOptions(new URL(input));
|
||||
// Parse parameters, ensuring that input is an object
|
||||
if (isURL(input)) {
|
||||
input = spreadUrlObject(input);
|
||||
}
|
||||
catch (err) {
|
||||
/* istanbul ignore next */
|
||||
parsed = url.parse(input);
|
||||
}
|
||||
if (!isString(parsed.protocol)) {
|
||||
throw new InvalidUrlError({ input });
|
||||
}
|
||||
input = parsed;
|
||||
}
|
||||
else if (URL && (input instanceof URL)) {
|
||||
input = urlToOptions(input);
|
||||
else if (isString(input)) {
|
||||
input = spreadUrlObject(parseUrl(input));
|
||||
}
|
||||
else {
|
||||
callback = options;
|
||||
options = input;
|
||||
options = validateUrl(input);
|
||||
input = { protocol: protocol };
|
||||
}
|
||||
if (isFunction(options)) {
|
||||
|
@ -6380,27 +6388,57 @@ function wrap(protocols) {
|
|||
return exports;
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
function noop() { /* empty */ }
|
||||
|
||||
// from https://github.com/nodejs/node/blob/master/lib/internal/url.js
|
||||
function urlToOptions(urlObject) {
|
||||
var options = {
|
||||
protocol: urlObject.protocol,
|
||||
hostname: urlObject.hostname.startsWith("[") ?
|
||||
/* istanbul ignore next */
|
||||
urlObject.hostname.slice(1, -1) :
|
||||
urlObject.hostname,
|
||||
hash: urlObject.hash,
|
||||
search: urlObject.search,
|
||||
pathname: urlObject.pathname,
|
||||
path: urlObject.pathname + urlObject.search,
|
||||
href: urlObject.href,
|
||||
};
|
||||
if (urlObject.port !== "") {
|
||||
options.port = Number(urlObject.port);
|
||||
function parseUrl(input) {
|
||||
var parsed;
|
||||
/* istanbul ignore else */
|
||||
if (useNativeURL) {
|
||||
parsed = new URL(input);
|
||||
}
|
||||
return options;
|
||||
else {
|
||||
// Ensure the URL is valid and absolute
|
||||
parsed = validateUrl(url.parse(input));
|
||||
if (!isString(parsed.protocol)) {
|
||||
throw new InvalidUrlError({ input });
|
||||
}
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function resolveUrl(relative, base) {
|
||||
/* istanbul ignore next */
|
||||
return useNativeURL ? new URL(relative, base) : parseUrl(url.resolve(base, relative));
|
||||
}
|
||||
|
||||
function validateUrl(input) {
|
||||
if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
|
||||
throw new InvalidUrlError({ input: input.href || input });
|
||||
}
|
||||
if (/^\[/.test(input.host) && !/^\[[:0-9a-f]+\](:\d+)?$/i.test(input.host)) {
|
||||
throw new InvalidUrlError({ input: input.href || input });
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
function spreadUrlObject(urlObject, target) {
|
||||
var spread = target || {};
|
||||
for (var key of preservedUrlFields) {
|
||||
spread[key] = urlObject[key];
|
||||
}
|
||||
|
||||
// Fix IPv6 hostname
|
||||
if (spread.hostname.startsWith("[")) {
|
||||
spread.hostname = spread.hostname.slice(1, -1);
|
||||
}
|
||||
// Ensure port is a number
|
||||
if (spread.port !== "") {
|
||||
spread.port = Number(spread.port);
|
||||
}
|
||||
// Concatenate path
|
||||
spread.path = spread.search ? spread.pathname + spread.search : spread.pathname;
|
||||
|
||||
return spread;
|
||||
}
|
||||
|
||||
function removeMatchingHeaders(regex, headers) {
|
||||
|
@ -6426,17 +6464,25 @@ function createErrorType(code, message, baseClass) {
|
|||
|
||||
// Attach constructor and set default properties
|
||||
CustomError.prototype = new (baseClass || Error)();
|
||||
CustomError.prototype.constructor = CustomError;
|
||||
CustomError.prototype.name = "Error [" + code + "]";
|
||||
Object.defineProperties(CustomError.prototype, {
|
||||
constructor: {
|
||||
value: CustomError,
|
||||
enumerable: false,
|
||||
},
|
||||
name: {
|
||||
value: "Error [" + code + "]",
|
||||
enumerable: false,
|
||||
},
|
||||
});
|
||||
return CustomError;
|
||||
}
|
||||
|
||||
function abortRequest(request) {
|
||||
function destroyRequest(request, error) {
|
||||
for (var event of events) {
|
||||
request.removeListener(event, eventHandlers[event]);
|
||||
}
|
||||
request.on("error", noop);
|
||||
request.abort();
|
||||
request.destroy(error);
|
||||
}
|
||||
|
||||
function isSubdomain(subdomain, domain) {
|
||||
|
@ -6457,6 +6503,10 @@ function isBuffer(value) {
|
|||
return typeof value === "object" && ("length" in value);
|
||||
}
|
||||
|
||||
function isURL(value) {
|
||||
return URL && value instanceof URL;
|
||||
}
|
||||
|
||||
// Exports
|
||||
module.exports = wrap({ http: http, https: https });
|
||||
module.exports.wrap = wrap;
|
||||
|
|
206
dist/gha/index.js
vendored
206
dist/gha/index.js
vendored
|
@ -1135,8 +1135,8 @@ class GitLabMapper {
|
|||
sourceRepo: await this.mapSourceRepo(mr),
|
||||
targetRepo: await this.mapTargetRepo(mr),
|
||||
// if commits list is provided use that as source
|
||||
nCommits: (commits && commits.length > 1) ? commits.length : 1,
|
||||
commits: (commits && commits.length > 1) ? commits : this.getSha(mr)
|
||||
nCommits: (commits && commits.length > 0) ? commits.length : 1,
|
||||
commits: (commits && commits.length > 0) ? commits : this.getSha(mr)
|
||||
};
|
||||
}
|
||||
getSha(mr) {
|
||||
|
@ -7578,6 +7578,29 @@ var Writable = (__nccwpck_require__(2781).Writable);
|
|||
var assert = __nccwpck_require__(9491);
|
||||
var debug = __nccwpck_require__(1133);
|
||||
|
||||
// Whether to use the native URL object or the legacy url module
|
||||
var useNativeURL = false;
|
||||
try {
|
||||
assert(new URL());
|
||||
}
|
||||
catch (error) {
|
||||
useNativeURL = error.code === "ERR_INVALID_URL";
|
||||
}
|
||||
|
||||
// URL fields to preserve in copy operations
|
||||
var preservedUrlFields = [
|
||||
"auth",
|
||||
"host",
|
||||
"hostname",
|
||||
"href",
|
||||
"path",
|
||||
"pathname",
|
||||
"port",
|
||||
"protocol",
|
||||
"query",
|
||||
"search",
|
||||
];
|
||||
|
||||
// Create handlers that pass events from native requests
|
||||
var events = ["abort", "aborted", "connect", "error", "socket", "timeout"];
|
||||
var eventHandlers = Object.create(null);
|
||||
|
@ -7587,19 +7610,20 @@ events.forEach(function (event) {
|
|||
};
|
||||
});
|
||||
|
||||
// Error types with codes
|
||||
var InvalidUrlError = createErrorType(
|
||||
"ERR_INVALID_URL",
|
||||
"Invalid URL",
|
||||
TypeError
|
||||
);
|
||||
// Error types with codes
|
||||
var RedirectionError = createErrorType(
|
||||
"ERR_FR_REDIRECTION_FAILURE",
|
||||
"Redirected request failed"
|
||||
);
|
||||
var TooManyRedirectsError = createErrorType(
|
||||
"ERR_FR_TOO_MANY_REDIRECTS",
|
||||
"Maximum number of redirects exceeded"
|
||||
"Maximum number of redirects exceeded",
|
||||
RedirectionError
|
||||
);
|
||||
var MaxBodyLengthExceededError = createErrorType(
|
||||
"ERR_FR_MAX_BODY_LENGTH_EXCEEDED",
|
||||
|
@ -7610,6 +7634,9 @@ var WriteAfterEndError = createErrorType(
|
|||
"write after end"
|
||||
);
|
||||
|
||||
// istanbul ignore next
|
||||
var destroy = Writable.prototype.destroy || noop;
|
||||
|
||||
// An HTTP(S) request that can be redirected
|
||||
function RedirectableRequest(options, responseCallback) {
|
||||
// Initialize the request
|
||||
|
@ -7631,7 +7658,13 @@ function RedirectableRequest(options, responseCallback) {
|
|||
// React to responses of native requests
|
||||
var self = this;
|
||||
this._onNativeResponse = function (response) {
|
||||
try {
|
||||
self._processResponse(response);
|
||||
}
|
||||
catch (cause) {
|
||||
self.emit("error", cause instanceof RedirectionError ?
|
||||
cause : new RedirectionError({ cause: cause }));
|
||||
}
|
||||
};
|
||||
|
||||
// Perform the first request
|
||||
|
@ -7640,10 +7673,17 @@ function RedirectableRequest(options, responseCallback) {
|
|||
RedirectableRequest.prototype = Object.create(Writable.prototype);
|
||||
|
||||
RedirectableRequest.prototype.abort = function () {
|
||||
abortRequest(this._currentRequest);
|
||||
destroyRequest(this._currentRequest);
|
||||
this._currentRequest.abort();
|
||||
this.emit("abort");
|
||||
};
|
||||
|
||||
RedirectableRequest.prototype.destroy = function (error) {
|
||||
destroyRequest(this._currentRequest, error);
|
||||
destroy.call(this, error);
|
||||
return this;
|
||||
};
|
||||
|
||||
// Writes buffered data to the current native request
|
||||
RedirectableRequest.prototype.write = function (data, encoding, callback) {
|
||||
// Writing is not allowed if end has been called
|
||||
|
@ -7756,6 +7796,7 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
|
|||
self.removeListener("abort", clearTimer);
|
||||
self.removeListener("error", clearTimer);
|
||||
self.removeListener("response", clearTimer);
|
||||
self.removeListener("close", clearTimer);
|
||||
if (callback) {
|
||||
self.removeListener("timeout", callback);
|
||||
}
|
||||
|
@ -7782,6 +7823,7 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
|
|||
this.on("abort", clearTimer);
|
||||
this.on("error", clearTimer);
|
||||
this.on("response", clearTimer);
|
||||
this.on("close", clearTimer);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
@ -7840,8 +7882,7 @@ RedirectableRequest.prototype._performRequest = function () {
|
|||
var protocol = this._options.protocol;
|
||||
var nativeProtocol = this._options.nativeProtocols[protocol];
|
||||
if (!nativeProtocol) {
|
||||
this.emit("error", new TypeError("Unsupported protocol " + protocol));
|
||||
return;
|
||||
throw new TypeError("Unsupported protocol " + protocol);
|
||||
}
|
||||
|
||||
// If specified, use the agent corresponding to the protocol
|
||||
|
@ -7933,15 +7974,14 @@ RedirectableRequest.prototype._processResponse = function (response) {
|
|||
}
|
||||
|
||||
// The response is a redirect, so abort the current request
|
||||
abortRequest(this._currentRequest);
|
||||
destroyRequest(this._currentRequest);
|
||||
// Discard the remainder of the response to avoid waiting for data
|
||||
response.destroy();
|
||||
|
||||
// RFC7231§6.4: A client SHOULD detect and intervene
|
||||
// in cyclical redirections (i.e., "infinite" redirection loops).
|
||||
if (++this._redirectCount > this._options.maxRedirects) {
|
||||
this.emit("error", new TooManyRedirectsError());
|
||||
return;
|
||||
throw new TooManyRedirectsError();
|
||||
}
|
||||
|
||||
// Store the request headers if applicable
|
||||
|
@ -7975,33 +8015,23 @@ RedirectableRequest.prototype._processResponse = function (response) {
|
|||
var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
|
||||
|
||||
// If the redirect is relative, carry over the host of the last request
|
||||
var currentUrlParts = url.parse(this._currentUrl);
|
||||
var currentUrlParts = parseUrl(this._currentUrl);
|
||||
var currentHost = currentHostHeader || currentUrlParts.host;
|
||||
var currentUrl = /^\w+:/.test(location) ? this._currentUrl :
|
||||
url.format(Object.assign(currentUrlParts, { host: currentHost }));
|
||||
|
||||
// Determine the URL of the redirection
|
||||
var redirectUrl;
|
||||
try {
|
||||
redirectUrl = url.resolve(currentUrl, location);
|
||||
}
|
||||
catch (cause) {
|
||||
this.emit("error", new RedirectionError({ cause: cause }));
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the redirected request
|
||||
debug("redirecting to", redirectUrl);
|
||||
var redirectUrl = resolveUrl(location, currentUrl);
|
||||
debug("redirecting to", redirectUrl.href);
|
||||
this._isRedirect = true;
|
||||
var redirectUrlParts = url.parse(redirectUrl);
|
||||
Object.assign(this._options, redirectUrlParts);
|
||||
spreadUrlObject(redirectUrl, this._options);
|
||||
|
||||
// Drop confidential headers when redirecting to a less secure protocol
|
||||
// or to a different domain that is not a superdomain
|
||||
if (redirectUrlParts.protocol !== currentUrlParts.protocol &&
|
||||
redirectUrlParts.protocol !== "https:" ||
|
||||
redirectUrlParts.host !== currentHost &&
|
||||
!isSubdomain(redirectUrlParts.host, currentHost)) {
|
||||
if (redirectUrl.protocol !== currentUrlParts.protocol &&
|
||||
redirectUrl.protocol !== "https:" ||
|
||||
redirectUrl.host !== currentHost &&
|
||||
!isSubdomain(redirectUrl.host, currentHost)) {
|
||||
removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
|
||||
}
|
||||
|
||||
|
@ -8016,23 +8046,12 @@ RedirectableRequest.prototype._processResponse = function (response) {
|
|||
method: method,
|
||||
headers: requestHeaders,
|
||||
};
|
||||
try {
|
||||
beforeRedirect(this._options, responseDetails, requestDetails);
|
||||
}
|
||||
catch (err) {
|
||||
this.emit("error", err);
|
||||
return;
|
||||
}
|
||||
this._sanitizeOptions(this._options);
|
||||
}
|
||||
|
||||
// Perform the redirected request
|
||||
try {
|
||||
this._performRequest();
|
||||
}
|
||||
catch (cause) {
|
||||
this.emit("error", new RedirectionError({ cause: cause }));
|
||||
}
|
||||
};
|
||||
|
||||
// Wraps the key/value object of protocols with redirect functionality
|
||||
|
@ -8052,27 +8071,16 @@ function wrap(protocols) {
|
|||
|
||||
// Executes a request, following redirects
|
||||
function request(input, options, callback) {
|
||||
// Parse parameters
|
||||
if (isString(input)) {
|
||||
var parsed;
|
||||
try {
|
||||
parsed = urlToOptions(new URL(input));
|
||||
// Parse parameters, ensuring that input is an object
|
||||
if (isURL(input)) {
|
||||
input = spreadUrlObject(input);
|
||||
}
|
||||
catch (err) {
|
||||
/* istanbul ignore next */
|
||||
parsed = url.parse(input);
|
||||
}
|
||||
if (!isString(parsed.protocol)) {
|
||||
throw new InvalidUrlError({ input });
|
||||
}
|
||||
input = parsed;
|
||||
}
|
||||
else if (URL && (input instanceof URL)) {
|
||||
input = urlToOptions(input);
|
||||
else if (isString(input)) {
|
||||
input = spreadUrlObject(parseUrl(input));
|
||||
}
|
||||
else {
|
||||
callback = options;
|
||||
options = input;
|
||||
options = validateUrl(input);
|
||||
input = { protocol: protocol };
|
||||
}
|
||||
if (isFunction(options)) {
|
||||
|
@ -8111,27 +8119,57 @@ function wrap(protocols) {
|
|||
return exports;
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
function noop() { /* empty */ }
|
||||
|
||||
// from https://github.com/nodejs/node/blob/master/lib/internal/url.js
|
||||
function urlToOptions(urlObject) {
|
||||
var options = {
|
||||
protocol: urlObject.protocol,
|
||||
hostname: urlObject.hostname.startsWith("[") ?
|
||||
/* istanbul ignore next */
|
||||
urlObject.hostname.slice(1, -1) :
|
||||
urlObject.hostname,
|
||||
hash: urlObject.hash,
|
||||
search: urlObject.search,
|
||||
pathname: urlObject.pathname,
|
||||
path: urlObject.pathname + urlObject.search,
|
||||
href: urlObject.href,
|
||||
};
|
||||
if (urlObject.port !== "") {
|
||||
options.port = Number(urlObject.port);
|
||||
function parseUrl(input) {
|
||||
var parsed;
|
||||
/* istanbul ignore else */
|
||||
if (useNativeURL) {
|
||||
parsed = new URL(input);
|
||||
}
|
||||
return options;
|
||||
else {
|
||||
// Ensure the URL is valid and absolute
|
||||
parsed = validateUrl(url.parse(input));
|
||||
if (!isString(parsed.protocol)) {
|
||||
throw new InvalidUrlError({ input });
|
||||
}
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
function resolveUrl(relative, base) {
|
||||
/* istanbul ignore next */
|
||||
return useNativeURL ? new URL(relative, base) : parseUrl(url.resolve(base, relative));
|
||||
}
|
||||
|
||||
function validateUrl(input) {
|
||||
if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
|
||||
throw new InvalidUrlError({ input: input.href || input });
|
||||
}
|
||||
if (/^\[/.test(input.host) && !/^\[[:0-9a-f]+\](:\d+)?$/i.test(input.host)) {
|
||||
throw new InvalidUrlError({ input: input.href || input });
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
function spreadUrlObject(urlObject, target) {
|
||||
var spread = target || {};
|
||||
for (var key of preservedUrlFields) {
|
||||
spread[key] = urlObject[key];
|
||||
}
|
||||
|
||||
// Fix IPv6 hostname
|
||||
if (spread.hostname.startsWith("[")) {
|
||||
spread.hostname = spread.hostname.slice(1, -1);
|
||||
}
|
||||
// Ensure port is a number
|
||||
if (spread.port !== "") {
|
||||
spread.port = Number(spread.port);
|
||||
}
|
||||
// Concatenate path
|
||||
spread.path = spread.search ? spread.pathname + spread.search : spread.pathname;
|
||||
|
||||
return spread;
|
||||
}
|
||||
|
||||
function removeMatchingHeaders(regex, headers) {
|
||||
|
@ -8157,17 +8195,25 @@ function createErrorType(code, message, baseClass) {
|
|||
|
||||
// Attach constructor and set default properties
|
||||
CustomError.prototype = new (baseClass || Error)();
|
||||
CustomError.prototype.constructor = CustomError;
|
||||
CustomError.prototype.name = "Error [" + code + "]";
|
||||
Object.defineProperties(CustomError.prototype, {
|
||||
constructor: {
|
||||
value: CustomError,
|
||||
enumerable: false,
|
||||
},
|
||||
name: {
|
||||
value: "Error [" + code + "]",
|
||||
enumerable: false,
|
||||
},
|
||||
});
|
||||
return CustomError;
|
||||
}
|
||||
|
||||
function abortRequest(request) {
|
||||
function destroyRequest(request, error) {
|
||||
for (var event of events) {
|
||||
request.removeListener(event, eventHandlers[event]);
|
||||
}
|
||||
request.on("error", noop);
|
||||
request.abort();
|
||||
request.destroy(error);
|
||||
}
|
||||
|
||||
function isSubdomain(subdomain, domain) {
|
||||
|
@ -8188,6 +8234,10 @@ function isBuffer(value) {
|
|||
return typeof value === "object" && ("length" in value);
|
||||
}
|
||||
|
||||
function isURL(value) {
|
||||
return URL && value instanceof URL;
|
||||
}
|
||||
|
||||
// Exports
|
||||
module.exports = wrap({ http: http, https: https });
|
||||
module.exports.wrap = wrap;
|
||||
|
|
|
@ -41,8 +41,8 @@ export default class GitLabMapper implements GitResponseMapper<MergeRequestSchem
|
|||
sourceRepo: await this.mapSourceRepo(mr),
|
||||
targetRepo: await this.mapTargetRepo(mr),
|
||||
// if commits list is provided use that as source
|
||||
nCommits: (commits && commits.length > 1) ? commits.length : 1,
|
||||
commits: (commits && commits.length > 1) ? commits : this.getSha(mr)
|
||||
nCommits: (commits && commits.length > 0) ? commits.length : 1,
|
||||
commits: (commits && commits.length > 0) ? commits : this.getSha(mr)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -504,6 +504,50 @@ describe("cli runner", () => {
|
|||
);
|
||||
});
|
||||
|
||||
test("single commit without squash", async () => {
|
||||
addProcessArgs([
|
||||
"-tb",
|
||||
"target",
|
||||
"-pr",
|
||||
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
|
||||
"--no-squash",
|
||||
]);
|
||||
|
||||
await runner.execute();
|
||||
|
||||
const cwd = process.cwd() + "/bp";
|
||||
|
||||
expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
|
||||
expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
|
||||
|
||||
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
|
||||
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
|
||||
|
||||
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
|
||||
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-e4dd336");
|
||||
|
||||
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
|
||||
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11", undefined, undefined);
|
||||
|
||||
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
|
||||
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336");
|
||||
|
||||
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
|
||||
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
|
||||
owner: "superuser",
|
||||
repo: "backporting-example",
|
||||
head: "bp-target-e4dd336",
|
||||
base: "target",
|
||||
title: "[target] Update test.txt",
|
||||
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
|
||||
reviewers: ["superuser"],
|
||||
assignees: [],
|
||||
labels: [],
|
||||
comments: [],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("multiple commits without squash", async () => {
|
||||
addProcessArgs([
|
||||
"-tb",
|
||||
|
|
|
@ -427,6 +427,48 @@ describe("gha runner", () => {
|
|||
);
|
||||
});
|
||||
|
||||
test("single commit without squash", async () => {
|
||||
spyGetInput({
|
||||
"target-branch": "target",
|
||||
"pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
|
||||
"no-squash": "true",
|
||||
});
|
||||
|
||||
await runner.execute();
|
||||
|
||||
const cwd = process.cwd() + "/bp";
|
||||
|
||||
expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
|
||||
expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
|
||||
|
||||
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
|
||||
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
|
||||
|
||||
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
|
||||
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-e4dd336");
|
||||
|
||||
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
|
||||
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11", undefined, undefined);
|
||||
|
||||
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
|
||||
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336");
|
||||
|
||||
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
|
||||
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
|
||||
owner: "superuser",
|
||||
repo: "backporting-example",
|
||||
head: "bp-target-e4dd336",
|
||||
base: "target",
|
||||
title: "[target] Update test.txt",
|
||||
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
|
||||
reviewers: ["superuser"],
|
||||
assignees: [],
|
||||
labels: [],
|
||||
comments: [],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("multiple commits without squash", async () => {
|
||||
spyGetInput({
|
||||
"target-branch": "target",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
|
||||
import { Moctokit } from "@kie/mock-github";
|
||||
import { TARGET_OWNER, REPO, MERGED_PR_FIXTURE, OPEN_PR_FIXTURE, NOT_MERGED_PR_FIXTURE, NOT_FOUND_PR_NUMBER, MULT_COMMITS_PR_FIXTURE, MULT_COMMITS_PR_COMMITS, NEW_PR_URL, NEW_PR_NUMBER } from "./github-data";
|
||||
import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, NESTED_NAMESPACE_MR, OPEN_MR, OPEN_PR_COMMITS, PROJECT_EXAMPLE, NESTED_PROJECT_EXAMPLE, SUPERUSER} from "./gitlab-data";
|
||||
import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, NESTED_NAMESPACE_MR, OPEN_MR, OPEN_PR_COMMITS, PROJECT_EXAMPLE, NESTED_PROJECT_EXAMPLE, SUPERUSER, MERGED_SQUASHED_MR_COMMITS } from "./gitlab-data";
|
||||
|
||||
// high number, for each test we are not expecting
|
||||
// to send more than 3 reqs per api endpoint
|
||||
|
@ -30,6 +30,8 @@ export const getAxiosMocked = (url: string) => {
|
|||
data = NESTED_PROJECT_EXAMPLE;
|
||||
} else if (url.endsWith("users?username=superuser")) {
|
||||
data = [SUPERUSER];
|
||||
} else if (url.endsWith("merge_requests/1/commits")) {
|
||||
data = MERGED_SQUASHED_MR_COMMITS;
|
||||
} else if (url.endsWith("merge_requests/2/commits")) {
|
||||
data = OPEN_PR_COMMITS;
|
||||
}
|
||||
|
|
|
@ -689,6 +689,29 @@ export const CLOSED_NOT_MERGED_MR = {
|
|||
}
|
||||
};
|
||||
|
||||
export const MERGED_SQUASHED_MR_COMMITS = [
|
||||
{
|
||||
"id":"e4dd336a4a20f394df6665994df382fb1d193a11",
|
||||
"short_id":"e4dd336a",
|
||||
"created_at":"2023-06-29T09:59:10.000Z",
|
||||
"parent_ids":[
|
||||
|
||||
],
|
||||
"title":"Add new file",
|
||||
"message":"Add new file",
|
||||
"author_name":"Super User",
|
||||
"author_email":"superuser@email.com",
|
||||
"authored_date":"2023-06-29T09:59:10.000Z",
|
||||
"committer_name":"Super User",
|
||||
"committer_email":"superuser@email.com",
|
||||
"committed_date":"2023-06-29T09:59:10.000Z",
|
||||
"trailers":{
|
||||
|
||||
},
|
||||
"web_url":"https://gitlab.com/superuser/backporting-example/-/commit/e4dd336a4a20f394df6665994df382fb1d193a11"
|
||||
},
|
||||
];
|
||||
|
||||
export const OPEN_PR_COMMITS = [
|
||||
{
|
||||
"id":"974519f65c9e0ed65277cd71026657a09fca05e7",
|
||||
|
|
Loading…
Add table
Reference in a new issue