UNPKG

backport

Version:

A CLI tool that automates the process of backporting commits

137 lines 6.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTargetBranchFromLabel = exports.getPullRequestStates = void 0; const lodash_1 = require("lodash"); const filterEmpty_1 = require("../../utils/filterEmpty"); const commitFormatters_1 = require("../github/commitFormatters"); const getSourcePullRequest_1 = require("./getSourcePullRequest"); const isPullRequestCrossReferencedEvent_1 = require("./isPullRequestCrossReferencedEvent"); function mergeByKey(obj1, obj2, key) { const merged = (0, lodash_1.merge)((0, lodash_1.keyBy)(obj1, key), (0, lodash_1.keyBy)(obj2, key)); const a = (0, lodash_1.values)(merged); return a; } function getPullRequestStates({ sourceCommit, branchLabelMapping, }) { const sourcePullRequest = (0, getSourcePullRequest_1.getSourcePullRequest)(sourceCommit); // if there is no source pull request the commit was pushed directly to the source branch // in that case there will be no labels, and thus not possible to deduce the expected target branches if (!sourcePullRequest) { return []; } const createdTargetPullRequests = getCreatedTargetPullRequests(sourceCommit); // if there's no `branchLabelMapping`, it's not possible to determine the missing target branches if (!branchLabelMapping) { return createdTargetPullRequests; } const targetBranchesFromLabels = getTargetBranchesFromLabels(sourcePullRequest, branchLabelMapping); const allTargetBranches = mergeByKey(targetBranchesFromLabels, createdTargetPullRequests, 'branch'); return allTargetBranches.map((res) => { if (res.state) { return { ...res, state: res.state }; } // MERGED (source branch) if (res.isSourceBranch) { return { ...res, state: 'MERGED', url: sourcePullRequest.url, number: sourcePullRequest.number, mergeCommit: sourcePullRequest.mergeCommit ? { message: sourcePullRequest.mergeCommit.message, sha: sourcePullRequest.mergeCommit.sha, } : undefined, }; } // NOT_CREATED return { ...res, state: 'NOT_CREATED' }; }); } exports.getPullRequestStates = getPullRequestStates; function getCreatedTargetPullRequests(sourceCommit) { const sourcePullRequest = (0, getSourcePullRequest_1.getSourcePullRequest)(sourceCommit); if (!sourcePullRequest) { return []; } const sourceCommitMessage = (0, commitFormatters_1.getFirstLine)(sourceCommit.message); return (sourcePullRequest.timelineItems.edges ?? []) .filter(filterEmpty_1.filterNil) .filter(isPullRequestCrossReferencedEvent_1.isPullRequestCrossReferencedEvent) .filter((item) => { const { targetPullRequest } = item.node; // ignore closed PRs if (targetPullRequest.state === 'CLOSED') { return false; } // at least one of the commits in `targetPullRequest` should match the merge commit from the source pull request const didCommitMatch = targetPullRequest.commits.edges?.some((commitEdge) => { const targetCommit = commitEdge?.node?.targetCommit; if (!targetCommit) { return false; } const matchingRepoName = sourceCommit.repository.name === targetPullRequest.repository.name; const matchingRepoOwner = sourceCommit.repository.owner.login === targetPullRequest.repository.owner.login; const targetCommitMessage = (0, commitFormatters_1.getFirstLine)(targetCommit.message); const matchingMessage = targetCommitMessage === sourceCommitMessage; return matchingRepoName && matchingRepoOwner && matchingMessage; }); const titleIncludesMessage = targetPullRequest.title.includes(sourceCommitMessage); const titleIncludesNumber = targetPullRequest.title.includes(sourcePullRequest.number.toString()); return didCommitMatch || (titleIncludesMessage && titleIncludesNumber); }) .map((item) => { const { targetPullRequest } = item.node; return { url: targetPullRequest.url, number: targetPullRequest.number, branch: targetPullRequest.baseRefName, state: targetPullRequest.state, mergeCommit: targetPullRequest.targetMergeCommit ? { sha: targetPullRequest.targetMergeCommit.sha, message: targetPullRequest.targetMergeCommit.message, } : undefined, }; }); } function getTargetBranchesFromLabels(sourcePullRequest, branchLabelMapping) { const targetBranchesFromLabels = sourcePullRequest.labels?.nodes ?.map((label) => label?.name) .filter(filterEmpty_1.filterNil) .map((label) => { const res = getTargetBranchFromLabel({ branchLabelMapping, label }); if (res) { const { branchLabelMappingKey, targetBranch } = res; const isSourceBranch = targetBranch === sourcePullRequest.baseRefName; return { branch: targetBranch, label, branchLabelMappingKey, isSourceBranch, }; } }) .filter(filterEmpty_1.filterNil); return (0, lodash_1.uniqBy)(targetBranchesFromLabels, ({ branch }) => branch); } function getTargetBranchFromLabel({ branchLabelMapping, label, }) { // only get first match const result = Object.entries(branchLabelMapping).find(([key]) => { const regex = new RegExp(key); const isMatch = label.match(regex) !== null; return isMatch; }); if (result) { const [branchLabelMappingKey, branchLabelMappingValue] = result; const regex = new RegExp(branchLabelMappingKey); const targetBranch = label.replace(regex, branchLabelMappingValue); if (targetBranch) { return { targetBranch, branchLabelMappingKey }; } } } exports.getTargetBranchFromLabel = getTargetBranchFromLabel; //# sourceMappingURL=getPullRequestStates.js.map