export async function CherryPickCommitsAsync()

in src/services/cherryPickService.ts [20:109]


export async function CherryPickCommitsAsync(
  pullRequestContext: GitPullRequest,
  targetTopicBranchName: string,
  targetBranchName: string
): Promise<IRestClientResult<GitCherryPick>> {
  try {
    if (!targetTopicBranchName.startsWith("refs/heads")) {
      targetTopicBranchName = `refs/heads/${targetTopicBranchName}`;
    }

    if (!targetBranchName.startsWith("refs/heads")) {
      targetBranchName = `refs/heads/${targetBranchName}`;
    }

    const cherryPickSource: any = {
      pullRequestId: pullRequestContext.pullRequestId
    };

    const cherryPickRequestParams: GitAsyncRefOperationParameters = {
      generatedRefName: targetTopicBranchName,
      ontoRefName: targetBranchName,
      repository: pullRequestContext.repository,
      source: cherryPickSource
    };

    let cherryPick: GitCherryPick = await client.createCherryPick(
      cherryPickRequestParams,
      pullRequestContext.repository.project.id,
      pullRequestContext.repository.id
    );

    // Check for new status every second
    const intervalMs = 1000;
    const timeoutMs = Constants.RequestTimeoutSeconds * 1000;
    let retries = 0;
    let inProgress =
      cherryPick.status === GitAsyncOperationStatus.Queued ||
      cherryPick.status === GitAsyncOperationStatus.InProgress;

    while (inProgress && intervalMs * retries < timeoutMs) {
      await new Promise(resolve => setTimeout(resolve, intervalMs));

      cherryPick = await client.getCherryPick(
        pullRequestContext.repository.project.id,
        cherryPick.cherryPickId,
        pullRequestContext.repository.id
      );

      inProgress =
        cherryPick.status === GitAsyncOperationStatus.Queued ||
        cherryPick.status === GitAsyncOperationStatus.InProgress;

      retries++;
    }

    // If not complete, complain
    if (inProgress) {
      return { error: `Unable to cherry-pick to ${targetTopicBranchName}` };
    }

    if (cherryPick.status !== GitAsyncOperationStatus.Completed) {
      if (
        cherryPick.detailedStatus.conflict &&
        cherryPick.detailedStatus.currentCommitId
      ) {
        return {
          error: `There were conflicts when cherry-picking commit ${
            cherryPick.detailedStatus.currentCommitId
          }. This operation needs to be done locally.`
        };
      } else if (
        cherryPick.detailedStatus.failureMessage.toLowerCase() ===
        "invalidrefname"
      ) {
        return {
          error: `Invalid branch name: ${trimStart(
            targetTopicBranchName,
            "refs/heads/"
          )}`
        };
      }

      return { error: cherryPick.detailedStatus.failureMessage };
    }

    return { result: cherryPick };
  } catch (ex) {
    return { error: ex };
  }
}