rework rebase logic
This commit is contained in:
parent
507d0a9edf
commit
4508ab7d4a
3 changed files with 75 additions and 943 deletions
836
dist/index.js
vendored
836
dist/index.js
vendored
|
@ -55,7 +55,6 @@ exports.tryFetch = tryFetch;
|
|||
exports.buildBranchCommits = buildBranchCommits;
|
||||
exports.createOrUpdateBranch = createOrUpdateBranch;
|
||||
const core = __importStar(__nccwpck_require__(7484));
|
||||
const uuid_1 = __nccwpck_require__(2048);
|
||||
const utils = __importStar(__nccwpck_require__(9277));
|
||||
const CHERRYPICK_EMPTY = 'The previous cherry-pick is now empty, possibly due to conflict resolution.';
|
||||
const NOTHING_TO_COMMIT = 'nothing to commit, working tree clean';
|
||||
|
@ -178,13 +177,27 @@ function createOrUpdateBranch(git, commitMessage, base, branch, branchRemoteName
|
|||
if (workingBaseType == WorkingBaseType.Commit && !base) {
|
||||
throw new Error(`When in 'detached HEAD' state, 'base' must be supplied.`);
|
||||
}
|
||||
// If the base is not specified it is assumed to be the working base.
|
||||
base = base ? base : workingBase;
|
||||
let action = 'none';
|
||||
let hasDiffWithBase = false;
|
||||
const baseRemote = 'origin';
|
||||
// Save the working base changes to a temporary branch
|
||||
const tempBranch = (0, uuid_1.v4)();
|
||||
yield git.checkout(tempBranch, 'HEAD');
|
||||
// Commit any uncommitted changes
|
||||
if (workingBase != branch) {
|
||||
if (!(yield tryFetch(git, branchRemoteName, branch, 0))) {
|
||||
// The pull request branch does not exist
|
||||
core.info(`Pull request branch '${branch}' does not exist yet.`);
|
||||
// Create the pull request branch
|
||||
yield git.checkout(branch, base);
|
||||
action = 'created';
|
||||
core.info(`Created branch '${branch}'`);
|
||||
// Check if the pull request branch is ahead of the base
|
||||
}
|
||||
else {
|
||||
// The pull request branch exists
|
||||
core.info(`Pull request branch '${branch}' already exists as remote branch '${branchRemoteName}/${branch}'`);
|
||||
// Checkout the pull request branch
|
||||
yield git.checkout(branch);
|
||||
}
|
||||
}
|
||||
// Commit any changes
|
||||
if (yield git.isDirty(true, addPaths)) {
|
||||
core.info('Uncommitted changes found. Adding a commit.');
|
||||
const aopts = ['add'];
|
||||
|
@ -206,128 +219,34 @@ function createOrUpdateBranch(git, commitMessage, base, branch, branchRemoteName
|
|||
throw new Error(`Unexpected error: ${commitResult.stderr}`);
|
||||
}
|
||||
}
|
||||
// Stash any uncommitted tracked and untracked changes
|
||||
const stashed = yield git.stashPush(['--include-untracked']);
|
||||
// Reset the working base
|
||||
// Commits made during the workflow will be removed
|
||||
if (workingBaseType == WorkingBaseType.Branch) {
|
||||
core.info(`Resetting working base branch '${workingBase}'`);
|
||||
yield git.checkout(workingBase);
|
||||
yield git.exec(['reset', '--hard', `${baseRemote}/${workingBase}`]);
|
||||
}
|
||||
// If the working base is not the base, rebase the temp branch commits
|
||||
// This will also be true if the working base type is a commit
|
||||
if (workingBase != base) {
|
||||
core.info(`Rebasing commits made to ${workingBaseType} '${workingBase}' on to base branch '${base}'`);
|
||||
const fetchArgs = ['--force'];
|
||||
if (branchRemoteName != 'fork') {
|
||||
// If pushing to a fork we cannot shallow fetch otherwise the 'shallow update not allowed' error occurs
|
||||
fetchArgs.push('--depth=1');
|
||||
}
|
||||
// Checkout the actual base
|
||||
yield git.fetch([`${base}:${base}`], baseRemote, fetchArgs);
|
||||
yield git.checkout(base);
|
||||
// Cherrypick commits from the temporary branch starting from the working base
|
||||
const commits = yield git.revList([`${workingBase}..${tempBranch}`, '.'], ['--reverse']);
|
||||
for (const commit of splitLines(commits)) {
|
||||
const result = yield git.cherryPick(['--strategy=recursive', '--strategy-option=theirs', commit], true);
|
||||
if (result.exitCode != 0 && !result.stderr.includes(CHERRYPICK_EMPTY)) {
|
||||
throw new Error(`Unexpected error: ${result.stderr}`);
|
||||
}
|
||||
}
|
||||
// Reset the temp branch to the working index
|
||||
yield git.checkout(tempBranch, 'HEAD');
|
||||
// Reset the base
|
||||
yield git.fetch([`${base}:${base}`], baseRemote, fetchArgs);
|
||||
}
|
||||
// Determine the fetch depth for the pull request branch (best effort)
|
||||
const tempBranchCommitsAhead = yield commitsAhead(git, base, tempBranch);
|
||||
const fetchDepth = tempBranchCommitsAhead > 0
|
||||
? tempBranchCommitsAhead + FETCH_DEPTH_MARGIN
|
||||
: FETCH_DEPTH_MARGIN;
|
||||
let action = 'none';
|
||||
let hasDiffWithBase = false;
|
||||
// Try to fetch the pull request branch
|
||||
if (!(yield tryFetch(git, branchRemoteName, branch, fetchDepth))) {
|
||||
// The pull request branch does not exist
|
||||
core.info(`Pull request branch '${branch}' does not exist yet.`);
|
||||
// Create the pull request branch
|
||||
yield git.checkout(branch, tempBranch);
|
||||
// Check if the pull request branch is ahead of the base
|
||||
hasDiffWithBase = yield isAhead(git, base, branch);
|
||||
if (hasDiffWithBase) {
|
||||
action = 'created';
|
||||
core.info(`Created branch '${branch}'`);
|
||||
}
|
||||
else {
|
||||
core.info(`Branch '${branch}' is not ahead of base '${base}' and will not be created`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The pull request branch exists
|
||||
core.info(`Pull request branch '${branch}' already exists as remote branch '${branchRemoteName}/${branch}'`);
|
||||
// Checkout the pull request branch
|
||||
yield git.checkout(branch);
|
||||
// Reset the branch if one of the following conditions is true.
|
||||
// - If the branch differs from the recreated temp branch.
|
||||
// - If the number of commits ahead of the base branch differs between the branch and
|
||||
// temp branch. This catches a case where the base branch has been force pushed to
|
||||
// a new commit.
|
||||
// - If the recreated temp branch is not ahead of the base. This means there will be
|
||||
// no pull request diff after the branch is reset. This will reset any undeleted
|
||||
// branches after merging. In particular, it catches a case where the branch was
|
||||
// squash merged but not deleted. We need to reset to make sure it doesn't appear
|
||||
// to have a diff with the base due to different commits for the same changes.
|
||||
// - If the diff of the commits ahead of the base branch differs between the branch and
|
||||
// temp branch. This catches a case where changes have been partially merged to the
|
||||
// base. The overall diff is the same, but the branch needs to be rebased to show
|
||||
// the correct diff.
|
||||
//
|
||||
// For changes on base this reset is equivalent to a rebase of the pull request branch.
|
||||
const branchCommitsAhead = yield commitsAhead(git, base, branch);
|
||||
if ((yield git.hasDiff([`${branch}..${tempBranch}`])) ||
|
||||
branchCommitsAhead != tempBranchCommitsAhead ||
|
||||
!(tempBranchCommitsAhead > 0) || // !isAhead
|
||||
(yield commitsHaveDiff(git, branch, tempBranch, tempBranchCommitsAhead))) {
|
||||
core.info(`Resetting '${branch}'`);
|
||||
// Alternatively, git switch -C branch tempBranch
|
||||
yield git.checkout(branch, tempBranch);
|
||||
}
|
||||
// Check if the pull request branch has been updated
|
||||
// If the branch was reset or updated it will be ahead
|
||||
// It may be behind if a reset now results in no diff with the base
|
||||
if (!(yield isEven(git, `${branchRemoteName}/${branch}`, branch))) {
|
||||
action = 'updated';
|
||||
core.info(`Updated branch '${branch}'`);
|
||||
}
|
||||
else {
|
||||
action = 'not-updated';
|
||||
core.info(`Branch '${branch}' is even with its remote and will not be updated`);
|
||||
}
|
||||
// Check if the pull request branch is ahead of the base
|
||||
hasDiffWithBase = yield isAhead(git, base, branch);
|
||||
// Check if the pull request branch is behind the base branch
|
||||
let wasRebased = false;
|
||||
yield git.exec(['fetch', baseRemote, base]);
|
||||
if (yield isBehind(git, base, branch)) {
|
||||
// Rebase the current branch onto the base branch
|
||||
core.info(`Pull request branch '${branch}' is behind base branch '${base}'.`);
|
||||
yield git.exec(['pull', '--rebase', baseRemote, base]);
|
||||
core.info(`Rebased '${branch}' commits ontop of '${base}'.`);
|
||||
wasRebased = true;
|
||||
}
|
||||
hasDiffWithBase = yield isAhead(git, base, branch);
|
||||
// If the base is not specified it is assumed to be the working base.
|
||||
base = base ? base : workingBase;
|
||||
// Get the base and head SHAs
|
||||
const baseSha = yield git.revParse(base);
|
||||
const baseCommit = yield git.getCommit(baseSha);
|
||||
const headSha = yield git.revParse(branch);
|
||||
let branchCommits = [];
|
||||
if (hasDiffWithBase) {
|
||||
action = 'updated';
|
||||
// Build the branch commits
|
||||
branchCommits = yield buildBranchCommits(git, base, branch);
|
||||
}
|
||||
// Delete the temporary branch
|
||||
yield git.exec(['branch', '--delete', '--force', tempBranch]);
|
||||
// Checkout the working base to leave the local repository as it was found
|
||||
yield git.checkout(workingBase);
|
||||
// Restore any stashed changes
|
||||
if (stashed) {
|
||||
yield git.stashPop();
|
||||
}
|
||||
return {
|
||||
action: action,
|
||||
base: base,
|
||||
hasDiffWithBase: hasDiffWithBase,
|
||||
wasRebased: wasRebased,
|
||||
baseCommit: baseCommit,
|
||||
headSha: headSha,
|
||||
branchCommits: branchCommits
|
||||
|
@ -526,11 +445,7 @@ function createPullRequest(inputs) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
yield git.push([
|
||||
'--force-with-lease',
|
||||
branchRemoteName,
|
||||
`${inputs.branch}:refs/heads/${inputs.branch}`
|
||||
]);
|
||||
yield git.push(result.wasRebased ? [`--force-with-lease`, branchRemoteName, inputs.branch] : []);
|
||||
}
|
||||
core.endGroup();
|
||||
}
|
||||
|
@ -29022,687 +28937,6 @@ if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) {
|
|||
exports.debug = debug; // for test
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 2048:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
Object.defineProperty(exports, "NIL", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _nil.default;
|
||||
}
|
||||
}));
|
||||
Object.defineProperty(exports, "parse", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _parse.default;
|
||||
}
|
||||
}));
|
||||
Object.defineProperty(exports, "stringify", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _stringify.default;
|
||||
}
|
||||
}));
|
||||
Object.defineProperty(exports, "v1", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _v.default;
|
||||
}
|
||||
}));
|
||||
Object.defineProperty(exports, "v3", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _v2.default;
|
||||
}
|
||||
}));
|
||||
Object.defineProperty(exports, "v4", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _v3.default;
|
||||
}
|
||||
}));
|
||||
Object.defineProperty(exports, "v5", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _v4.default;
|
||||
}
|
||||
}));
|
||||
Object.defineProperty(exports, "validate", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _validate.default;
|
||||
}
|
||||
}));
|
||||
Object.defineProperty(exports, "version", ({
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _version.default;
|
||||
}
|
||||
}));
|
||||
|
||||
var _v = _interopRequireDefault(__nccwpck_require__(6415));
|
||||
|
||||
var _v2 = _interopRequireDefault(__nccwpck_require__(1697));
|
||||
|
||||
var _v3 = _interopRequireDefault(__nccwpck_require__(4676));
|
||||
|
||||
var _v4 = _interopRequireDefault(__nccwpck_require__(9771));
|
||||
|
||||
var _nil = _interopRequireDefault(__nccwpck_require__(7723));
|
||||
|
||||
var _version = _interopRequireDefault(__nccwpck_require__(5868));
|
||||
|
||||
var _validate = _interopRequireDefault(__nccwpck_require__(6200));
|
||||
|
||||
var _stringify = _interopRequireDefault(__nccwpck_require__(7597));
|
||||
|
||||
var _parse = _interopRequireDefault(__nccwpck_require__(7267));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 216:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _crypto = _interopRequireDefault(__nccwpck_require__(6982));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function md5(bytes) {
|
||||
if (Array.isArray(bytes)) {
|
||||
bytes = Buffer.from(bytes);
|
||||
} else if (typeof bytes === 'string') {
|
||||
bytes = Buffer.from(bytes, 'utf8');
|
||||
}
|
||||
|
||||
return _crypto.default.createHash('md5').update(bytes).digest();
|
||||
}
|
||||
|
||||
var _default = md5;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 4221:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _crypto = _interopRequireDefault(__nccwpck_require__(6982));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var _default = {
|
||||
randomUUID: _crypto.default.randomUUID
|
||||
};
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 7723:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
var _default = '00000000-0000-0000-0000-000000000000';
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 7267:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _validate = _interopRequireDefault(__nccwpck_require__(6200));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function parse(uuid) {
|
||||
if (!(0, _validate.default)(uuid)) {
|
||||
throw TypeError('Invalid UUID');
|
||||
}
|
||||
|
||||
let v;
|
||||
const arr = new Uint8Array(16); // Parse ########-....-....-....-............
|
||||
|
||||
arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
|
||||
arr[1] = v >>> 16 & 0xff;
|
||||
arr[2] = v >>> 8 & 0xff;
|
||||
arr[3] = v & 0xff; // Parse ........-####-....-....-............
|
||||
|
||||
arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;
|
||||
arr[5] = v & 0xff; // Parse ........-....-####-....-............
|
||||
|
||||
arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;
|
||||
arr[7] = v & 0xff; // Parse ........-....-....-####-............
|
||||
|
||||
arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;
|
||||
arr[9] = v & 0xff; // Parse ........-....-....-....-############
|
||||
// (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
|
||||
|
||||
arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;
|
||||
arr[11] = v / 0x100000000 & 0xff;
|
||||
arr[12] = v >>> 24 & 0xff;
|
||||
arr[13] = v >>> 16 & 0xff;
|
||||
arr[14] = v >>> 8 & 0xff;
|
||||
arr[15] = v & 0xff;
|
||||
return arr;
|
||||
}
|
||||
|
||||
var _default = parse;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 7879:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 2973:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = rng;
|
||||
|
||||
var _crypto = _interopRequireDefault(__nccwpck_require__(6982));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate
|
||||
|
||||
let poolPtr = rnds8Pool.length;
|
||||
|
||||
function rng() {
|
||||
if (poolPtr > rnds8Pool.length - 16) {
|
||||
_crypto.default.randomFillSync(rnds8Pool);
|
||||
|
||||
poolPtr = 0;
|
||||
}
|
||||
|
||||
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
||||
}
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 507:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _crypto = _interopRequireDefault(__nccwpck_require__(6982));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function sha1(bytes) {
|
||||
if (Array.isArray(bytes)) {
|
||||
bytes = Buffer.from(bytes);
|
||||
} else if (typeof bytes === 'string') {
|
||||
bytes = Buffer.from(bytes, 'utf8');
|
||||
}
|
||||
|
||||
return _crypto.default.createHash('sha1').update(bytes).digest();
|
||||
}
|
||||
|
||||
var _default = sha1;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 7597:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
exports.unsafeStringify = unsafeStringify;
|
||||
|
||||
var _validate = _interopRequireDefault(__nccwpck_require__(6200));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
/**
|
||||
* Convert array of 16 byte values to UUID string format of the form:
|
||||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
*/
|
||||
const byteToHex = [];
|
||||
|
||||
for (let i = 0; i < 256; ++i) {
|
||||
byteToHex.push((i + 0x100).toString(16).slice(1));
|
||||
}
|
||||
|
||||
function unsafeStringify(arr, offset = 0) {
|
||||
// Note: Be careful editing this code! It's been tuned for performance
|
||||
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
|
||||
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
||||
}
|
||||
|
||||
function stringify(arr, offset = 0) {
|
||||
const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one
|
||||
// of the following:
|
||||
// - One or more input array values don't map to a hex octet (leading to
|
||||
// "undefined" in the uuid)
|
||||
// - Invalid input values for the RFC `version` or `variant` fields
|
||||
|
||||
if (!(0, _validate.default)(uuid)) {
|
||||
throw TypeError('Stringified UUID is invalid');
|
||||
}
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
var _default = stringify;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 6415:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _rng = _interopRequireDefault(__nccwpck_require__(2973));
|
||||
|
||||
var _stringify = __nccwpck_require__(7597);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
// **`v1()` - Generate time-based UUID**
|
||||
//
|
||||
// Inspired by https://github.com/LiosK/UUID.js
|
||||
// and http://docs.python.org/library/uuid.html
|
||||
let _nodeId;
|
||||
|
||||
let _clockseq; // Previous uuid creation time
|
||||
|
||||
|
||||
let _lastMSecs = 0;
|
||||
let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details
|
||||
|
||||
function v1(options, buf, offset) {
|
||||
let i = buf && offset || 0;
|
||||
const b = buf || new Array(16);
|
||||
options = options || {};
|
||||
let node = options.node || _nodeId;
|
||||
let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not
|
||||
// specified. We do this lazily to minimize issues related to insufficient
|
||||
// system entropy. See #189
|
||||
|
||||
if (node == null || clockseq == null) {
|
||||
const seedBytes = options.random || (options.rng || _rng.default)();
|
||||
|
||||
if (node == null) {
|
||||
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
|
||||
node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
|
||||
}
|
||||
|
||||
if (clockseq == null) {
|
||||
// Per 4.2.2, randomize (14 bit) clockseq
|
||||
clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
|
||||
}
|
||||
} // UUID timestamps are 100 nano-second units since the Gregorian epoch,
|
||||
// (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
|
||||
// time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
|
||||
// (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
|
||||
|
||||
|
||||
let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock
|
||||
// cycle to simulate higher resolution clock
|
||||
|
||||
let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs)
|
||||
|
||||
const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression
|
||||
|
||||
if (dt < 0 && options.clockseq === undefined) {
|
||||
clockseq = clockseq + 1 & 0x3fff;
|
||||
} // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
|
||||
// time interval
|
||||
|
||||
|
||||
if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
|
||||
nsecs = 0;
|
||||
} // Per 4.2.1.2 Throw error if too many uuids are requested
|
||||
|
||||
|
||||
if (nsecs >= 10000) {
|
||||
throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
|
||||
}
|
||||
|
||||
_lastMSecs = msecs;
|
||||
_lastNSecs = nsecs;
|
||||
_clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
|
||||
|
||||
msecs += 12219292800000; // `time_low`
|
||||
|
||||
const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
|
||||
b[i++] = tl >>> 24 & 0xff;
|
||||
b[i++] = tl >>> 16 & 0xff;
|
||||
b[i++] = tl >>> 8 & 0xff;
|
||||
b[i++] = tl & 0xff; // `time_mid`
|
||||
|
||||
const tmh = msecs / 0x100000000 * 10000 & 0xfffffff;
|
||||
b[i++] = tmh >>> 8 & 0xff;
|
||||
b[i++] = tmh & 0xff; // `time_high_and_version`
|
||||
|
||||
b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
|
||||
|
||||
b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
|
||||
|
||||
b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low`
|
||||
|
||||
b[i++] = clockseq & 0xff; // `node`
|
||||
|
||||
for (let n = 0; n < 6; ++n) {
|
||||
b[i + n] = node[n];
|
||||
}
|
||||
|
||||
return buf || (0, _stringify.unsafeStringify)(b);
|
||||
}
|
||||
|
||||
var _default = v1;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 1697:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _v = _interopRequireDefault(__nccwpck_require__(2930));
|
||||
|
||||
var _md = _interopRequireDefault(__nccwpck_require__(216));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const v3 = (0, _v.default)('v3', 0x30, _md.default);
|
||||
var _default = v3;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 2930:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports.URL = exports.DNS = void 0;
|
||||
exports["default"] = v35;
|
||||
|
||||
var _stringify = __nccwpck_require__(7597);
|
||||
|
||||
var _parse = _interopRequireDefault(__nccwpck_require__(7267));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function stringToBytes(str) {
|
||||
str = unescape(encodeURIComponent(str)); // UTF8 escape
|
||||
|
||||
const bytes = [];
|
||||
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
bytes.push(str.charCodeAt(i));
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
|
||||
exports.DNS = DNS;
|
||||
const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
|
||||
exports.URL = URL;
|
||||
|
||||
function v35(name, version, hashfunc) {
|
||||
function generateUUID(value, namespace, buf, offset) {
|
||||
var _namespace;
|
||||
|
||||
if (typeof value === 'string') {
|
||||
value = stringToBytes(value);
|
||||
}
|
||||
|
||||
if (typeof namespace === 'string') {
|
||||
namespace = (0, _parse.default)(namespace);
|
||||
}
|
||||
|
||||
if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) {
|
||||
throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
|
||||
} // Compute hash of namespace and value, Per 4.3
|
||||
// Future: Use spread syntax when supported on all platforms, e.g. `bytes =
|
||||
// hashfunc([...namespace, ... value])`
|
||||
|
||||
|
||||
let bytes = new Uint8Array(16 + value.length);
|
||||
bytes.set(namespace);
|
||||
bytes.set(value, namespace.length);
|
||||
bytes = hashfunc(bytes);
|
||||
bytes[6] = bytes[6] & 0x0f | version;
|
||||
bytes[8] = bytes[8] & 0x3f | 0x80;
|
||||
|
||||
if (buf) {
|
||||
offset = offset || 0;
|
||||
|
||||
for (let i = 0; i < 16; ++i) {
|
||||
buf[offset + i] = bytes[i];
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
return (0, _stringify.unsafeStringify)(bytes);
|
||||
} // Function#name is not settable on some platforms (#270)
|
||||
|
||||
|
||||
try {
|
||||
generateUUID.name = name; // eslint-disable-next-line no-empty
|
||||
} catch (err) {} // For CommonJS default export support
|
||||
|
||||
|
||||
generateUUID.DNS = DNS;
|
||||
generateUUID.URL = URL;
|
||||
return generateUUID;
|
||||
}
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 4676:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _native = _interopRequireDefault(__nccwpck_require__(4221));
|
||||
|
||||
var _rng = _interopRequireDefault(__nccwpck_require__(2973));
|
||||
|
||||
var _stringify = __nccwpck_require__(7597);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function v4(options, buf, offset) {
|
||||
if (_native.default.randomUUID && !buf && !options) {
|
||||
return _native.default.randomUUID();
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
||||
|
||||
|
||||
rnds[6] = rnds[6] & 0x0f | 0x40;
|
||||
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
|
||||
|
||||
if (buf) {
|
||||
offset = offset || 0;
|
||||
|
||||
for (let i = 0; i < 16; ++i) {
|
||||
buf[offset + i] = rnds[i];
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
return (0, _stringify.unsafeStringify)(rnds);
|
||||
}
|
||||
|
||||
var _default = v4;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 9771:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _v = _interopRequireDefault(__nccwpck_require__(2930));
|
||||
|
||||
var _sha = _interopRequireDefault(__nccwpck_require__(507));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
const v5 = (0, _v.default)('v5', 0x50, _sha.default);
|
||||
var _default = v5;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 6200:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _regex = _interopRequireDefault(__nccwpck_require__(7879));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function validate(uuid) {
|
||||
return typeof uuid === 'string' && _regex.default.test(uuid);
|
||||
}
|
||||
|
||||
var _default = validate;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 5868:
|
||||
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({
|
||||
value: true
|
||||
}));
|
||||
exports["default"] = void 0;
|
||||
|
||||
var _validate = _interopRequireDefault(__nccwpck_require__(6200));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function version(uuid) {
|
||||
if (!(0, _validate.default)(uuid)) {
|
||||
throw TypeError('Invalid UUID');
|
||||
}
|
||||
|
||||
return parseInt(uuid.slice(14, 15), 16);
|
||||
}
|
||||
|
||||
var _default = version;
|
||||
exports["default"] = _default;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 2613:
|
||||
|
|
|
@ -161,6 +161,7 @@ interface CreateOrUpdateBranchResult {
|
|||
action: string
|
||||
base: string
|
||||
hasDiffWithBase: boolean
|
||||
wasRebased: boolean
|
||||
baseCommit: Commit
|
||||
headSha: string
|
||||
branchCommits: Commit[]
|
||||
|
@ -184,14 +185,30 @@ export async function createOrUpdateBranch(
|
|||
throw new Error(`When in 'detached HEAD' state, 'base' must be supplied.`)
|
||||
}
|
||||
|
||||
// If the base is not specified it is assumed to be the working base.
|
||||
base = base ? base : workingBase
|
||||
let action = 'none'
|
||||
let hasDiffWithBase = false
|
||||
const baseRemote = 'origin'
|
||||
|
||||
// Save the working base changes to a temporary branch
|
||||
const tempBranch = uuidv4()
|
||||
await git.checkout(tempBranch, 'HEAD')
|
||||
// Commit any uncommitted changes
|
||||
if (workingBase != branch) {
|
||||
if (!(await tryFetch(git, branchRemoteName, branch, 0))) {
|
||||
// The pull request branch does not exist
|
||||
core.info(`Pull request branch '${branch}' does not exist yet.`)
|
||||
// Create the pull request branch
|
||||
await git.checkout(branch, base)
|
||||
action = 'created'
|
||||
core.info(`Created branch '${branch}'`)
|
||||
// Check if the pull request branch is ahead of the base
|
||||
} else {
|
||||
// The pull request branch exists
|
||||
core.info(
|
||||
`Pull request branch '${branch}' already exists as remote branch '${branchRemoteName}/${branch}'`
|
||||
)
|
||||
// Checkout the pull request branch
|
||||
await git.checkout(branch)
|
||||
}
|
||||
}
|
||||
|
||||
// Commit any changes
|
||||
if (await git.isDirty(true, addPaths)) {
|
||||
core.info('Uncommitted changes found. Adding a commit.')
|
||||
const aopts = ['add']
|
||||
|
@ -215,129 +232,21 @@ export async function createOrUpdateBranch(
|
|||
}
|
||||
}
|
||||
|
||||
// Stash any uncommitted tracked and untracked changes
|
||||
const stashed = await git.stashPush(['--include-untracked'])
|
||||
|
||||
// Reset the working base
|
||||
// Commits made during the workflow will be removed
|
||||
if (workingBaseType == WorkingBaseType.Branch) {
|
||||
core.info(`Resetting working base branch '${workingBase}'`)
|
||||
await git.checkout(workingBase)
|
||||
await git.exec(['reset', '--hard', `${baseRemote}/${workingBase}`])
|
||||
// Check if the pull request branch is behind the base branch
|
||||
let wasRebased = false;
|
||||
await git.exec(['fetch', baseRemote, base])
|
||||
if (await isBehind(git, base, branch)) {
|
||||
// Rebase the current branch onto the base branch
|
||||
core.info(`Pull request branch '${branch}' is behind base branch '${base}'.`)
|
||||
await git.exec(['pull', '--rebase', baseRemote, base])
|
||||
core.info(`Rebased '${branch}' commits ontop of '${base}'.`)
|
||||
wasRebased = true;
|
||||
}
|
||||
|
||||
// If the working base is not the base, rebase the temp branch commits
|
||||
// This will also be true if the working base type is a commit
|
||||
if (workingBase != base) {
|
||||
core.info(
|
||||
`Rebasing commits made to ${workingBaseType} '${workingBase}' on to base branch '${base}'`
|
||||
)
|
||||
const fetchArgs = ['--force']
|
||||
if (branchRemoteName != 'fork') {
|
||||
// If pushing to a fork we cannot shallow fetch otherwise the 'shallow update not allowed' error occurs
|
||||
fetchArgs.push('--depth=1')
|
||||
}
|
||||
// Checkout the actual base
|
||||
await git.fetch([`${base}:${base}`], baseRemote, fetchArgs)
|
||||
await git.checkout(base)
|
||||
// Cherrypick commits from the temporary branch starting from the working base
|
||||
const commits = await git.revList(
|
||||
[`${workingBase}..${tempBranch}`, '.'],
|
||||
['--reverse']
|
||||
)
|
||||
for (const commit of splitLines(commits)) {
|
||||
const result = await git.cherryPick(
|
||||
['--strategy=recursive', '--strategy-option=theirs', commit],
|
||||
true
|
||||
)
|
||||
if (result.exitCode != 0 && !result.stderr.includes(CHERRYPICK_EMPTY)) {
|
||||
throw new Error(`Unexpected error: ${result.stderr}`)
|
||||
}
|
||||
}
|
||||
// Reset the temp branch to the working index
|
||||
await git.checkout(tempBranch, 'HEAD')
|
||||
// Reset the base
|
||||
await git.fetch([`${base}:${base}`], baseRemote, fetchArgs)
|
||||
}
|
||||
hasDiffWithBase = await isAhead(git, base, branch)
|
||||
|
||||
// Determine the fetch depth for the pull request branch (best effort)
|
||||
const tempBranchCommitsAhead = await commitsAhead(git, base, tempBranch)
|
||||
const fetchDepth =
|
||||
tempBranchCommitsAhead > 0
|
||||
? tempBranchCommitsAhead + FETCH_DEPTH_MARGIN
|
||||
: FETCH_DEPTH_MARGIN
|
||||
|
||||
let action = 'none'
|
||||
let hasDiffWithBase = false
|
||||
|
||||
// Try to fetch the pull request branch
|
||||
if (!(await tryFetch(git, branchRemoteName, branch, fetchDepth))) {
|
||||
// The pull request branch does not exist
|
||||
core.info(`Pull request branch '${branch}' does not exist yet.`)
|
||||
// Create the pull request branch
|
||||
await git.checkout(branch, tempBranch)
|
||||
// Check if the pull request branch is ahead of the base
|
||||
hasDiffWithBase = await isAhead(git, base, branch)
|
||||
if (hasDiffWithBase) {
|
||||
action = 'created'
|
||||
core.info(`Created branch '${branch}'`)
|
||||
} else {
|
||||
core.info(
|
||||
`Branch '${branch}' is not ahead of base '${base}' and will not be created`
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// The pull request branch exists
|
||||
core.info(
|
||||
`Pull request branch '${branch}' already exists as remote branch '${branchRemoteName}/${branch}'`
|
||||
)
|
||||
// Checkout the pull request branch
|
||||
await git.checkout(branch)
|
||||
|
||||
// Reset the branch if one of the following conditions is true.
|
||||
// - If the branch differs from the recreated temp branch.
|
||||
// - If the number of commits ahead of the base branch differs between the branch and
|
||||
// temp branch. This catches a case where the base branch has been force pushed to
|
||||
// a new commit.
|
||||
// - If the recreated temp branch is not ahead of the base. This means there will be
|
||||
// no pull request diff after the branch is reset. This will reset any undeleted
|
||||
// branches after merging. In particular, it catches a case where the branch was
|
||||
// squash merged but not deleted. We need to reset to make sure it doesn't appear
|
||||
// to have a diff with the base due to different commits for the same changes.
|
||||
// - If the diff of the commits ahead of the base branch differs between the branch and
|
||||
// temp branch. This catches a case where changes have been partially merged to the
|
||||
// base. The overall diff is the same, but the branch needs to be rebased to show
|
||||
// the correct diff.
|
||||
//
|
||||
// For changes on base this reset is equivalent to a rebase of the pull request branch.
|
||||
const branchCommitsAhead = await commitsAhead(git, base, branch)
|
||||
if (
|
||||
(await git.hasDiff([`${branch}..${tempBranch}`])) ||
|
||||
branchCommitsAhead != tempBranchCommitsAhead ||
|
||||
!(tempBranchCommitsAhead > 0) || // !isAhead
|
||||
(await commitsHaveDiff(git, branch, tempBranch, tempBranchCommitsAhead))
|
||||
) {
|
||||
core.info(`Resetting '${branch}'`)
|
||||
// Alternatively, git switch -C branch tempBranch
|
||||
await git.checkout(branch, tempBranch)
|
||||
}
|
||||
|
||||
// Check if the pull request branch has been updated
|
||||
// If the branch was reset or updated it will be ahead
|
||||
// It may be behind if a reset now results in no diff with the base
|
||||
if (!(await isEven(git, `${branchRemoteName}/${branch}`, branch))) {
|
||||
action = 'updated'
|
||||
core.info(`Updated branch '${branch}'`)
|
||||
} else {
|
||||
action = 'not-updated'
|
||||
core.info(
|
||||
`Branch '${branch}' is even with its remote and will not be updated`
|
||||
)
|
||||
}
|
||||
|
||||
// Check if the pull request branch is ahead of the base
|
||||
hasDiffWithBase = await isAhead(git, base, branch)
|
||||
}
|
||||
// If the base is not specified it is assumed to be the working base.
|
||||
base = base ? base : workingBase
|
||||
|
||||
// Get the base and head SHAs
|
||||
const baseSha = await git.revParse(base)
|
||||
|
@ -346,25 +255,16 @@ export async function createOrUpdateBranch(
|
|||
|
||||
let branchCommits: Commit[] = []
|
||||
if (hasDiffWithBase) {
|
||||
action = 'updated'
|
||||
// Build the branch commits
|
||||
branchCommits = await buildBranchCommits(git, base, branch)
|
||||
}
|
||||
|
||||
// Delete the temporary branch
|
||||
await git.exec(['branch', '--delete', '--force', tempBranch])
|
||||
|
||||
// Checkout the working base to leave the local repository as it was found
|
||||
await git.checkout(workingBase)
|
||||
|
||||
// Restore any stashed changes
|
||||
if (stashed) {
|
||||
await git.stashPop()
|
||||
}
|
||||
|
||||
return {
|
||||
action: action,
|
||||
base: base,
|
||||
hasDiffWithBase: hasDiffWithBase,
|
||||
wasRebased: wasRebased,
|
||||
baseCommit: baseCommit,
|
||||
headSha: headSha,
|
||||
branchCommits: branchCommits
|
||||
|
|
|
@ -227,11 +227,9 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||
await git.stashPop()
|
||||
}
|
||||
} else {
|
||||
await git.push([
|
||||
'--force-with-lease',
|
||||
branchRemoteName,
|
||||
`${inputs.branch}:refs/heads/${inputs.branch}`
|
||||
])
|
||||
await git.push(
|
||||
result.wasRebased ? [`--force-with-lease`, branchRemoteName, inputs.branch] : []
|
||||
)
|
||||
}
|
||||
core.endGroup()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue