blob: 7ee107353cf0c86e1b16268df977c9c35d0bff21 [file] [log] [blame]
// Copyright 2023 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io';
import 'package:auto_submit/action/revert_method.dart';
import 'package:auto_submit/configuration/repository_configuration.dart';
import 'package:auto_submit/git/cli_command.dart';
import 'package:auto_submit/git/utilities.dart';
import 'package:auto_submit/git/git_cli.dart';
import 'package:auto_submit/git/git_repository_manager.dart';
import 'package:auto_submit/requests/exceptions.dart';
import 'package:auto_submit/service/config.dart';
import 'package:auto_submit/service/github_service.dart';
import 'package:auto_submit/service/log.dart';
import 'package:auto_submit/service/revert_issue_body_formatter.dart';
import 'package:github/github.dart' as github;
import 'package:github/github.dart';
import 'package:retry/retry.dart';
class GitCliRevertMethod implements RevertMethod {
@override
Future<github.PullRequest?> createRevert(
Config config,
String initiatingAuthor,
github.PullRequest pullRequest,
) async {
final github.RepositorySlug slug = pullRequest.base!.repo!.slug();
final String commitSha = pullRequest.mergeCommitSha!;
// we will need to collect the pr number after the revert request is generated.
final RepositoryConfiguration repositoryConfiguration = await config.getRepositoryConfiguration(slug);
final String baseBranch = repositoryConfiguration.defaultBranch;
final String cloneToDirectory = '${slug.name}_$commitSha';
final GitRepositoryManager gitRepositoryManager = GitRepositoryManager(
slug: slug,
workingDirectory: Directory.current.path,
cloneToDirectory: cloneToDirectory,
gitCli: GitCli(GitAccessMethod.HTTP, CliCommand()),
);
// The exception is caught by the thrower.
try {
await gitRepositoryManager.cloneRepository();
await gitRepositoryManager.setupConfig();
await gitRepositoryManager.revertCommit(baseBranch, commitSha, slug, await config.generateGithubToken(slug));
} finally {
await gitRepositoryManager.deleteRepository();
}
final GitRevertBranchName gitRevertBranchName = GitRevertBranchName(commitSha);
final GithubService githubService = await config.createGithubService(slug);
const RetryOptions retryOptions =
RetryOptions(delayFactor: Duration(seconds: 1), maxDelay: Duration(seconds: 1), maxAttempts: 4);
Branch? branch;
// Attempt a few times to get the branch name. This may not be needed.
// Let the exception bubble up from here.
await retryOptions.retry(
() async {
branch = await githubService.getBranch(slug, gitRevertBranchName.branch);
},
retryIf: (Exception e) => e is NotFoundException,
);
log.info('found branch ${slug.fullName}/${branch!.name}, safe to create revert request of ${pullRequest.number!}.');
final RevertIssueBodyFormatter formatter = RevertIssueBodyFormatter(
slug: slug,
originalPrNumber: pullRequest.number!,
initiatingAuthor: initiatingAuthor,
originalPrTitle: pullRequest.title,
originalPrBody: pullRequest.body,
).format;
log.info('Attempting to create pull request with ${slug.fullName}/${gitRevertBranchName.branch}.');
final github.PullRequest revertPullRequest = await githubService.createPullRequest(
slug: slug,
title: formatter.revertPrTitle,
head: gitRevertBranchName.branch,
base: baseBranch,
draft: false,
body: formatter.revertPrBody,
);
log.info('pull request number is: ${slug.fullName}/${revertPullRequest.number}');
return revertPullRequest;
}
}