Unverified Commit 481dfec0 authored by Christopher Fujino's avatar Christopher Fujino Committed by GitHub

[flutter_conductor] Support publishing to multiple channels (#94770)

parent 3b1e3ba7
......@@ -16,7 +16,7 @@ const List<String> kBaseReleaseChannels = <String>['stable', 'beta', 'dev'];
const List<String> kReleaseChannels = <String>[...kBaseReleaseChannels, FrameworkRepository.defaultBranch];
const List<String> KReleaseIncrements = <String>['y', 'z', 'm', 'n'];
const List<String> kReleaseIncrements = <String>['y', 'z', 'm', 'n'];
const String kReleaseDocumentationUrl = 'https://github.com/flutter/flutter/wiki/Flutter-Cherrypick-Process';
......@@ -28,6 +28,10 @@ final RegExp releaseCandidateBranchRegex = RegExp(
r'flutter-(\d+)\.(\d+)-candidate\.(\d+)',
);
/// Whether all releases published to the beta channel should be mirrored to
/// dev.
const bool kSynchronizeDevWithBeta = true;
/// Cast a dynamic to String and trim.
String stdoutToString(dynamic input) {
final String str = input as String;
......
......@@ -48,7 +48,7 @@ class NextCommand extends Command<void> {
String get description => 'Proceed to the next release phase.';
@override
Future<void> run() async {
Future<void> run() {
final File stateFile = checkouts.fileSystem.file(argResults![kStateOption]);
if (!stateFile.existsSync()) {
throw ConductorException(
......@@ -57,7 +57,7 @@ class NextCommand extends Command<void> {
}
final pb.ConductorState state = state_import.readStateFromFile(stateFile);
await NextContext(
return NextContext(
autoAccept: argResults![kYesFlag] as bool,
checkouts: checkouts,
force: argResults![kForceFlag] as bool,
......@@ -324,29 +324,37 @@ class NextContext extends Context {
previousCheckoutLocation: state.framework.checkoutPath,
);
final String headRevision = await framework.reverseParse('HEAD');
if (autoAccept == false) {
// dryRun: true means print out git command
await framework.pushRef(
final List<String> releaseRefs = <String>[state.releaseChannel];
if (kSynchronizeDevWithBeta && state.releaseChannel == 'beta') {
releaseRefs.add('dev');
}
for (final String releaseRef in releaseRefs) {
if (autoAccept == false) {
// dryRun: true means print out git command
await framework.pushRef(
fromRef: headRevision,
toRef: state.releaseChannel,
toRef: releaseRef,
remote: state.framework.upstream.url,
force: force,
dryRun: true,
);
);
final bool response = await prompt('Are you ready to publish this release?');
if (!response) {
stdio.printError('Aborting command.');
updateState(state, stdio.logs);
return;
final bool response = await prompt(
'Are you ready to publish version ${state.releaseVersion} to $releaseRef?',
);
if (!response) {
stdio.printError('Aborting command.');
updateState(state, stdio.logs);
return;
}
}
}
await framework.pushRef(
await framework.pushRef(
fromRef: headRevision,
toRef: state.releaseChannel,
toRef: releaseRef,
remote: state.framework.upstream.url,
force: force,
);
);
}
break;
case pb.ReleasePhase.VERIFY_RELEASE:
stdio.printStatus(
......
......@@ -93,7 +93,7 @@ class StartCommand extends Command<void> {
kIncrementOption,
help: 'Specifies which part of the x.y.z version number to increment. Required.',
valueHelp: 'level',
allowed: KReleaseIncrements,
allowed: kReleaseIncrements,
allowedHelp: <String, String>{
'y': 'Indicates the first dev release after a beta release.',
'z': 'Indicates a hotfix to a stable release.',
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import './globals.dart' show ConductorException, KReleaseIncrements, releaseCandidateBranchRegex;
import './globals.dart' show ConductorException, kReleaseIncrements, releaseCandidateBranchRegex;
/// Possible string formats that `flutter --version` can return.
enum VersionType {
......@@ -262,7 +262,7 @@ class Version {
/// Will throw a [ConductorException] if the version is not possible given the
/// [candidateBranch] and [incrementLetter].
void ensureValid(String candidateBranch, String incrementLetter) {
if (!KReleaseIncrements.contains(incrementLetter)) {
if (!kReleaseIncrements.contains(incrementLetter)) {
throw ConductorException('Invalid incrementLetter: $incrementLetter');
}
final RegExpMatch? branchMatch = releaseCandidateBranchRegex.firstMatch(candidateBranch);
......
......@@ -48,7 +48,7 @@ class TestStdio extends Stdio {
@override
String readLineSync() {
if (stdin.isEmpty) {
throw Exception('Unexpected call to readLineSync!');
throw Exception('Unexpected call to readLineSync! Last stdout was ${logs.last}');
}
return stdin.removeAt(0);
}
......
......@@ -966,6 +966,8 @@ void main() {
});
test('updates currentPhase if user responds yes', () async {
stdio.stdin.add('y');
// for kSynchronizeDevWithBeta
stdio.stdin.add('y');
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
const FakeCommand(
......@@ -981,6 +983,10 @@ void main() {
const FakeCommand(
command: <String>['git', 'push', FrameworkRepository.defaultUpstream, '$revision1:$releaseChannel'],
),
// for kSynchronizeDevWithBeta
const FakeCommand(
command: <String>['git', 'push', FrameworkRepository.defaultUpstream, '$revision1:dev'],
),
]);
writeStateToFile(
fileSystem.file(stateFile),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment