| // Copyright 2023 The Chromium 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:async'; |
| import 'dart:io'; |
| |
| import 'package:args/command_runner.dart'; |
| import 'package:devtools_tool/utils.dart'; |
| import 'package:io/io.dart'; |
| |
| class ReleaseHelperCommand extends Command { |
| ReleaseHelperCommand() { |
| argParser.addFlag( |
| 'use-current-branch', |
| negatable: false, |
| help: |
| 'Uses the current branch as the base for the release, instead of a fresh copy of master. For use when developing.', |
| ); |
| } |
| @override |
| String get description => |
| 'Creates a release version of devtools from the master branch, and pushes up a draft PR.'; |
| |
| @override |
| String get name => 'release-helper'; |
| |
| @override |
| FutureOr? run() async { |
| final processManager = ProcessManager(); |
| |
| final useCurrentBranch = argResults!['use-current-branch']!; |
| final currentBranchResult = await processManager.runProcess( |
| CliCommand.git(['rev-parse', '--abbrev-ref', 'HEAD']), |
| ); |
| final initialBranch = currentBranchResult.stdout.trim(); |
| String? releaseBranch; |
| |
| try { |
| Directory.current = pathFromRepoRoot(""); |
| final remoteUpstream = await findRemote( |
| processManager, |
| remoteId: 'flutter/devtools.git', |
| ); |
| |
| final gitStatusResult = await processManager.runProcess( |
| CliCommand.git(['status', '-s']), |
| ); |
| final gitStatus = gitStatusResult.stdout; |
| if (gitStatus.isNotEmpty) { |
| throw "Error: Make sure your working directory is clean before running the helper"; |
| } |
| |
| releaseBranch = |
| 'release_helper_branch_${DateTime.now().millisecondsSinceEpoch}'; |
| |
| if (!useCurrentBranch) { |
| print("Preparing the release branch."); |
| await processManager.runProcess( |
| CliCommand.git(['fetch', remoteUpstream, 'master']), |
| ); |
| } |
| |
| await processManager.runProcess( |
| CliCommand.git( |
| [ |
| 'checkout', |
| '-b', |
| releaseBranch, |
| if (useCurrentBranch) '$remoteUpstream/master', |
| ], |
| ), |
| ); |
| |
| print("Ensuring ./tool packages are ready."); |
| Directory.current = pathFromRepoRoot("tool"); |
| await processManager.runProcess( |
| CliCommand.dart(['pub', 'get']), |
| workingDirectory: pathFromRepoRoot("tool"), |
| ); |
| |
| print("Setting the release version."); |
| await processManager.runProcess( |
| CliCommand.tool(['update-version', 'auto', '--type', 'release']), |
| ); |
| |
| final getNewVersionResult = await processManager.runProcess( |
| CliCommand.tool( |
| ['update-version', 'current-version', '|', 'tail', '-1'], |
| ), |
| ); |
| |
| final newVersion = getNewVersionResult.stdout.trim(); |
| |
| final commitMessage = "Prepare for release $newVersion"; |
| |
| await processManager.runAll( |
| commands: [ |
| CliCommand.git(['commit', '-a', '-m', commitMessage]), |
| CliCommand.git(['push', '-u', remoteUpstream, releaseBranch]), |
| ], |
| ); |
| |
| print('Creating the PR.'); |
| final prURL = await processManager.runProcess( |
| CliCommand( |
| 'gh', |
| [ |
| 'pr', |
| 'create', |
| '--repo', |
| 'flutter/devtools', |
| '--draft', |
| '--title', |
| commitMessage, |
| '--fill', |
| ], |
| ), |
| ); |
| |
| print('Your Draft release PR can be found at: ${prURL.stdout.trim()}'); |
| print('DONE'); |
| print( |
| 'Build, run and test this release using: `devtools_tool serve`', |
| ); |
| } catch (e) { |
| print(e); |
| |
| // try to bring the caller back to their original branch |
| await processManager.runProcess( |
| CliCommand.git(['checkout', initialBranch]), |
| ); |
| |
| // try to clean up the temporary branch we made |
| if (releaseBranch != null) { |
| await Process.run('git', [ |
| 'branch', |
| '-D', |
| releaseBranch, |
| ]); |
| } |
| } |
| } |
| } |