UNPKG

backport

Version:

A CLI tool that automates the process of backporting commits

152 lines (147 loc) 5.45 kB
/** Parses raw GitHub API commit data into the Commit type used throughout the codebase. */ import { differenceBy } from 'lodash-es'; import { graphql } from '../../graphql/generated/index.js'; import { filterNil } from '../../utils/filter-empty.js'; import { parseRemoteConfigFile } from '../remote-config.js'; import { getPullRequestStates } from './get-pull-request-states.js'; import { getSourcePullRequest } from './get-source-pull-request.js'; function getSuggestedTargetBranches(sourceCommit, targetPullRequestStates, branchLabelMapping) { const missingPrs = getPullRequestStates({ sourceCommit, branchLabelMapping, }).filter((pr) => pr.state === 'NOT_CREATED' || pr.state === 'CLOSED'); const mergedPrs = targetPullRequestStates.filter((pr) => pr.state === 'MERGED'); return differenceBy(missingPrs, mergedPrs, (pr) => pr.label).map((pr) => pr.branch); } export function parseSourceCommit({ sourceCommit, options, }) { const sourcePullRequest = getSourcePullRequest(sourceCommit); const sourceCommitBranchLabelMapping = getSourceCommitBranchLabelMapping(sourceCommit); const branchLabelMapping = sourceCommitBranchLabelMapping ?? options.branchLabelMapping; const targetPullRequestStates = getPullRequestStates({ sourceCommit, branchLabelMapping, }); const suggestedTargetBranches = getSuggestedTargetBranches(sourceCommit, targetPullRequestStates, options.branchLabelMapping); return { author: sourceCommit.author, sourceCommit: { committedDate: String(sourceCommit.committedDate), message: sourceCommit.message, sha: String(sourceCommit.sha), branchLabelMapping: sourceCommitBranchLabelMapping, }, sourcePullRequest: sourcePullRequest ? { labels: sourcePullRequest.labels?.nodes ?.map((label) => label?.name) .filter(filterNil) ?? [], title: sourcePullRequest.title, number: sourcePullRequest.number, url: String(sourcePullRequest.url), mergeCommit: sourcePullRequest.mergeCommit ? { message: sourcePullRequest.mergeCommit.message, sha: String(sourcePullRequest.mergeCommit.sha), } : undefined, } : undefined, sourceBranch: sourcePullRequest?.baseRefName ?? options.sourceBranch, suggestedTargetBranches, targetPullRequestStates: targetPullRequestStates, }; } export const SourceCommitWithTargetPullRequestFragment = graphql(` fragment SourceCommitWithTargetPullRequestFragment on Commit { __typename # Source Commit repository { name owner { login } } sha: oid message committedDate author { name email } # Source pull request: PR where source commit was merged in. # first: 20 disambiguates when multiple PRs' head branches contain the SHA. associatedPullRequests(first: 20) { edges { node { title url number labels(first: 50) { nodes { name } } baseRefName # source merge commit (the commit that actually went into the source branch) mergeCommit { __typename ...RemoteConfigHistoryFragment sha: oid message } # (possible) backport pull requests referenced in the source pull request timelineItems(last: 20, itemTypes: CROSS_REFERENCED_EVENT) { edges { node { ... on CrossReferencedEvent { __typename targetPullRequest: source { __typename # Target PRs (backport PRs) ... on PullRequest { __typename # target merge commit: the backport commit that was merged into the target branch targetMergeCommit: mergeCommit { sha: oid message } repository { name owner { login } } url title state baseRefName number commits(first: 20) { edges { node { targetCommit: commit { message sha: oid } } } } } } } } } } } } } } `); function getSourceCommitBranchLabelMapping(sourceCommit) { const sourcePullRequest = getSourcePullRequest(sourceCommit); const remoteConfig = sourcePullRequest?.mergeCommit?.remoteConfigHistory.edges?.at(0)?.remoteConfig; if (remoteConfig) { return parseRemoteConfigFile(remoteConfig)?.branchLabelMapping; } } //# sourceMappingURL=parse-source-commit.js.map