Unverified Commit d9634155 authored by Casey Hillers's avatar Casey Hillers Committed by GitHub

[conductor] Remove PublishChannel and use MPA command (#135884)

Move more of the playbook into conductor. The MPA command inputs are prone to human error.
parent e141d0a4
...@@ -18,7 +18,7 @@ const List<String> kReleaseChannels = <String>[...kBaseReleaseChannels, Framewor ...@@ -18,7 +18,7 @@ const List<String> kReleaseChannels = <String>[...kBaseReleaseChannels, Framewor
const String kReleaseDocumentationUrl = 'https://github.com/flutter/flutter/wiki/Flutter-Cherrypick-Process'; const String kReleaseDocumentationUrl = 'https://github.com/flutter/flutter/wiki/Flutter-Cherrypick-Process';
const String kLuciPackagingConsoleLink = 'https://ci.chromium.org/p/flutter/g/packaging/console'; const String kLuciPackagingConsoleLink = 'https://ci.chromium.org/p/dart-internal/g/flutter_packaging/console';
const String kWebsiteReleasesUrl = 'https://docs.flutter.dev/development/tools/sdk/releases'; const String kWebsiteReleasesUrl = 'https://docs.flutter.dev/development/tools/sdk/releases';
......
...@@ -141,15 +141,12 @@ class NextContext extends Context { ...@@ -141,15 +141,12 @@ class NextContext extends Context {
} }
await pushWorkingBranch(engine, state.engine); await pushWorkingBranch(engine, state.engine);
case pb.ReleasePhase.CODESIGN_ENGINE_BINARIES: case pb.ReleasePhase.VERIFY_ENGINE_CI:
stdio.printStatus(<String>[ stdio.printStatus('You must validate post-submit CI for your engine PR and merge it');
'You must validate pre-submit CI for your engine PR, merge it, and codesign',
'binaries before proceeding.\n',
].join('\n'));
if (!autoAccept) { if (!autoAccept) {
// TODO(fujino): actually test if binaries have been codesigned on macOS
final bool response = await prompt( final bool response = await prompt(
'Has CI passed for the engine PR and binaries been codesigned?', 'Has CI passed for the engine PR?\n\n'
'${state_import.luciConsoleLink(state.releaseChannel, 'engine')}'
); );
if (!response) { if (!response) {
stdio.printError('Aborting command.'); stdio.printError('Aborting command.');
...@@ -190,10 +187,10 @@ class NextContext extends Context { ...@@ -190,10 +187,10 @@ class NextContext extends Context {
addFirst: true, addFirst: true,
); );
// append to list of cherrypicks so we know a PR is required // append to list of cherrypicks so we know a PR is required
state.framework.cherrypicks.add(pb.Cherrypick( state.framework.cherrypicks.add(pb.Cherrypick.create()
appliedRevision: revision, ..appliedRevision = revision
state: pb.CherrypickState.COMPLETED, ..state = pb.CherrypickState.COMPLETED
)); );
} }
stdio.printStatus('Rolling new engine hash $engineRevision to framework checkout...'); stdio.printStatus('Rolling new engine hash $engineRevision to framework checkout...');
needsCommit = await framework.updateEngineRevision(engineRevision); needsCommit = await framework.updateEngineRevision(engineRevision);
...@@ -203,10 +200,10 @@ class NextContext extends Context { ...@@ -203,10 +200,10 @@ class NextContext extends Context {
addFirst: true, addFirst: true,
); );
// append to list of cherrypicks so we know a PR is required // append to list of cherrypicks so we know a PR is required
state.framework.cherrypicks.add(pb.Cherrypick( state.framework.cherrypicks.add(pb.Cherrypick.create()
appliedRevision: revision, ..appliedRevision = revision
state: pb.CherrypickState.COMPLETED, ..state = pb.CherrypickState.COMPLETED
)); );
} }
final List<pb.Cherrypick> unappliedCherrypicks = <pb.Cherrypick>[]; final List<pb.Cherrypick> unappliedCherrypicks = <pb.Cherrypick>[];
...@@ -250,83 +247,18 @@ class NextContext extends Context { ...@@ -250,83 +247,18 @@ class NextContext extends Context {
await pushWorkingBranch(framework, state.framework); await pushWorkingBranch(framework, state.framework);
case pb.ReleasePhase.PUBLISH_VERSION: case pb.ReleasePhase.PUBLISH_VERSION:
stdio.printStatus('Please ensure that you have merged your framework PR and that'); final String command = '''
stdio.printStatus('post-submit CI has finished successfully.\n'); tool-proxy-cli --tool_proxy=/abns/dart-eng-tool-proxy/prod-dart-eng-tool-proxy-tool-proxy.annealed-tool-proxy \\
final Remote frameworkUpstream = Remote( --block_on_mpa -I flutter_release \\
name: RemoteName.upstream, :git_branch ${state.framework.candidateBranch} \\
url: state.framework.upstream.url, :release_channel ${state.releaseChannel} \\
); :tag ${state.releaseVersion} \\
final FrameworkRepository framework = FrameworkRepository( :force false
checkouts, ''';
// We explicitly want to check out the merged version from upstream stdio.printStatus('Please ensure that you have merged your framework PR');
initialRef: '${frameworkUpstream.name}/${state.framework.candidateBranch}', stdio.printStatus('and post-submit CI has finished successfully.\n');
upstreamRemote: frameworkUpstream, stdio.printStatus('Run the following command, and ask a Googler');
previousCheckoutLocation: state.framework.checkoutPath, stdio.printStatus('to review the request\n\n$command');
);
final String frameworkHead = await framework.reverseParse('HEAD');
final Remote engineUpstream = Remote(
name: RemoteName.upstream,
url: state.engine.upstream.url,
);
final EngineRepository engine = EngineRepository(
checkouts,
// We explicitly want to check out the merged version from upstream
initialRef: '${engineUpstream.name}/${state.engine.candidateBranch}',
upstreamRemote: engineUpstream,
previousCheckoutLocation: state.engine.checkoutPath,
);
final String engineHead = await engine.reverseParse('HEAD');
if (!autoAccept) {
final bool response = await prompt(
'Are you ready to tag commit $frameworkHead as ${state.releaseVersion}\n'
'and push to remote ${state.framework.upstream.url}?',
);
if (!response) {
stdio.printError('Aborting command.');
updateState(state, stdio.logs);
return;
}
}
await framework.tag(frameworkHead, state.releaseVersion, frameworkUpstream.name);
await engine.tag(engineHead, state.releaseVersion, engineUpstream.name);
case pb.ReleasePhase.PUBLISH_CHANNEL:
final Remote upstream = Remote(
name: RemoteName.upstream,
url: state.framework.upstream.url,
);
final FrameworkRepository framework = FrameworkRepository(
checkouts,
// We explicitly want to check out the merged version from upstream
initialRef: '${upstream.name}/${state.framework.candidateBranch}',
upstreamRemote: upstream,
previousCheckoutLocation: state.framework.checkoutPath,
);
final String headRevision = await framework.reverseParse('HEAD');
if (!autoAccept) {
// dryRun: true means print out git command
await framework.pushRef(
fromRef: headRevision,
toRef: state.releaseChannel,
remote: state.framework.upstream.url,
force: force,
dryRun: true,
);
final bool response = await prompt(
'Are you ready to publish version ${state.releaseVersion} to ${state.releaseChannel}?',
);
if (!response) {
stdio.printError('Aborting command.');
updateState(state, stdio.logs);
return;
}
}
await framework.pushRef(
fromRef: headRevision,
toRef: state.releaseChannel,
remote: state.framework.upstream.url,
force: force,
);
case pb.ReleasePhase.VERIFY_RELEASE: case pb.ReleasePhase.VERIFY_RELEASE:
stdio.printStatus( stdio.printStatus(
'The current status of packaging builds can be seen at:\n' 'The current status of packaging builds can be seen at:\n'
......
...@@ -2,39 +2,36 @@ ...@@ -2,39 +2,36 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/// //
// Generated code. Do not modify. // Generated code. Do not modify.
// source: conductor_state.proto // source: conductor_state.proto
// //
// @dart = 2.12 // @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields
// ignore_for_file: UNDEFINED_SHOWN_NAME // ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
import 'dart:core' as $core; import 'dart:core' as $core;
import 'package:protobuf/protobuf.dart' as $pb; import 'package:protobuf/protobuf.dart' as $pb;
class ReleasePhase extends $pb.ProtobufEnum { class ReleasePhase extends $pb.ProtobufEnum {
static const ReleasePhase APPLY_ENGINE_CHERRYPICKS = static const ReleasePhase APPLY_ENGINE_CHERRYPICKS =
ReleasePhase._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'APPLY_ENGINE_CHERRYPICKS'); ReleasePhase._(0, _omitEnumNames ? '' : 'APPLY_ENGINE_CHERRYPICKS');
static const ReleasePhase CODESIGN_ENGINE_BINARIES = static const ReleasePhase VERIFY_ENGINE_CI = ReleasePhase._(1, _omitEnumNames ? '' : 'VERIFY_ENGINE_CI');
ReleasePhase._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CODESIGN_ENGINE_BINARIES'); static const ReleasePhase APPLY_FRAMEWORK_CHERRYPICKS =
static const ReleasePhase APPLY_FRAMEWORK_CHERRYPICKS = ReleasePhase._( ReleasePhase._(2, _omitEnumNames ? '' : 'APPLY_FRAMEWORK_CHERRYPICKS');
2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'APPLY_FRAMEWORK_CHERRYPICKS'); static const ReleasePhase PUBLISH_VERSION = ReleasePhase._(3, _omitEnumNames ? '' : 'PUBLISH_VERSION');
static const ReleasePhase PUBLISH_VERSION = static const ReleasePhase VERIFY_RELEASE = ReleasePhase._(5, _omitEnumNames ? '' : 'VERIFY_RELEASE');
ReleasePhase._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PUBLISH_VERSION'); static const ReleasePhase RELEASE_COMPLETED = ReleasePhase._(6, _omitEnumNames ? '' : 'RELEASE_COMPLETED');
static const ReleasePhase PUBLISH_CHANNEL =
ReleasePhase._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PUBLISH_CHANNEL');
static const ReleasePhase VERIFY_RELEASE =
ReleasePhase._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'VERIFY_RELEASE');
static const ReleasePhase RELEASE_COMPLETED =
ReleasePhase._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RELEASE_COMPLETED');
static const $core.List<ReleasePhase> values = <ReleasePhase>[ static const $core.List<ReleasePhase> values = <ReleasePhase>[
APPLY_ENGINE_CHERRYPICKS, APPLY_ENGINE_CHERRYPICKS,
CODESIGN_ENGINE_BINARIES, VERIFY_ENGINE_CI,
APPLY_FRAMEWORK_CHERRYPICKS, APPLY_FRAMEWORK_CHERRYPICKS,
PUBLISH_VERSION, PUBLISH_VERSION,
PUBLISH_CHANNEL,
VERIFY_RELEASE, VERIFY_RELEASE,
RELEASE_COMPLETED, RELEASE_COMPLETED,
]; ];
...@@ -46,14 +43,11 @@ class ReleasePhase extends $pb.ProtobufEnum { ...@@ -46,14 +43,11 @@ class ReleasePhase extends $pb.ProtobufEnum {
} }
class CherrypickState extends $pb.ProtobufEnum { class CherrypickState extends $pb.ProtobufEnum {
static const CherrypickState PENDING = static const CherrypickState PENDING = CherrypickState._(0, _omitEnumNames ? '' : 'PENDING');
CherrypickState._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PENDING');
static const CherrypickState PENDING_WITH_CONFLICT = static const CherrypickState PENDING_WITH_CONFLICT =
CherrypickState._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PENDING_WITH_CONFLICT'); CherrypickState._(1, _omitEnumNames ? '' : 'PENDING_WITH_CONFLICT');
static const CherrypickState COMPLETED = static const CherrypickState COMPLETED = CherrypickState._(2, _omitEnumNames ? '' : 'COMPLETED');
CherrypickState._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'COMPLETED'); static const CherrypickState ABANDONED = CherrypickState._(3, _omitEnumNames ? '' : 'ABANDONED');
static const CherrypickState ABANDONED =
CherrypickState._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ABANDONED');
static const $core.List<CherrypickState> values = <CherrypickState>[ static const $core.List<CherrypickState> values = <CherrypickState>[
PENDING, PENDING,
...@@ -69,14 +63,10 @@ class CherrypickState extends $pb.ProtobufEnum { ...@@ -69,14 +63,10 @@ class CherrypickState extends $pb.ProtobufEnum {
} }
class ReleaseType extends $pb.ProtobufEnum { class ReleaseType extends $pb.ProtobufEnum {
static const ReleaseType STABLE_INITIAL = static const ReleaseType STABLE_INITIAL = ReleaseType._(0, _omitEnumNames ? '' : 'STABLE_INITIAL');
ReleaseType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'STABLE_INITIAL'); static const ReleaseType STABLE_HOTFIX = ReleaseType._(1, _omitEnumNames ? '' : 'STABLE_HOTFIX');
static const ReleaseType STABLE_HOTFIX = static const ReleaseType BETA_INITIAL = ReleaseType._(2, _omitEnumNames ? '' : 'BETA_INITIAL');
ReleaseType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'STABLE_HOTFIX'); static const ReleaseType BETA_HOTFIX = ReleaseType._(3, _omitEnumNames ? '' : 'BETA_HOTFIX');
static const ReleaseType BETA_INITIAL =
ReleaseType._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BETA_INITIAL');
static const ReleaseType BETA_HOTFIX =
ReleaseType._(3, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BETA_HOTFIX');
static const $core.List<ReleaseType> values = <ReleaseType>[ static const $core.List<ReleaseType> values = <ReleaseType>[
STABLE_INITIAL, STABLE_INITIAL,
...@@ -90,3 +80,5 @@ class ReleaseType extends $pb.ProtobufEnum { ...@@ -90,3 +80,5 @@ class ReleaseType extends $pb.ProtobufEnum {
const ReleaseType._($core.int v, $core.String n) : super(v, n); const ReleaseType._($core.int v, $core.String n) : super(v, n);
} }
const _omitEnumNames = $core.bool.fromEnvironment('protobuf.omit_enum_names');
...@@ -2,11 +2,16 @@ ...@@ -2,11 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/// //
// Generated code. Do not modify. // Generated code. Do not modify.
// source: conductor_state.proto // source: conductor_state.proto
// //
// @dart = 2.12 // @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package
// ignore_for_file: annotate_overrides, camel_case_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes
// ignore_for_file: non_constant_identifier_names, prefer_final_fields
// ignore_for_file: unnecessary_import, unnecessary_this, unused_import
export 'conductor_state.pb.dart'; export 'conductor_state.pb.dart';
...@@ -11,16 +11,16 @@ message Remote { ...@@ -11,16 +11,16 @@ message Remote {
enum ReleasePhase { enum ReleasePhase {
// Release was started with `conductor start` and repositories cloned. // Release was started with `conductor start` and repositories cloned.
APPLY_ENGINE_CHERRYPICKS = 0; APPLY_ENGINE_CHERRYPICKS = 0;
CODESIGN_ENGINE_BINARIES = 1;
// Verify engine CI is green before opening framework PR.
VERIFY_ENGINE_CI = 1;
APPLY_FRAMEWORK_CHERRYPICKS = 2; APPLY_FRAMEWORK_CHERRYPICKS = 2;
// Git tag applied to framework RC branch HEAD and pushed upstream. // Git tag applied to framework RC branch HEAD and pushed upstream.
PUBLISH_VERSION = 3; PUBLISH_VERSION = 3;
// RC branch HEAD pushed to upstream release branch. reserved 4; // Formerly PUBLISH_CHANNEL, merged into PUBLISH_VERSION.
//
// For example, flutter-1.2-candidate.3 -> upstream/beta
PUBLISH_CHANNEL = 4;
// Package artifacts verified to exist on cloud storage. // Package artifacts verified to exist on cloud storage.
VERIFY_RELEASE = 5; VERIFY_RELEASE = 5;
......
...@@ -310,16 +310,24 @@ class StartContext extends Context { ...@@ -310,16 +310,24 @@ class StartContext extends Context {
} }
final String engineHead = await engine.reverseParse('HEAD'); final String engineHead = await engine.reverseParse('HEAD');
state.engine = pb.Repository( state.engine = (pb.Repository.create()
candidateBranch: candidateBranch, ..candidateBranch = candidateBranch
workingBranch: workingBranchName, ..workingBranch = workingBranchName
startingGitHead: engineHead, ..startingGitHead = engineHead
currentGitHead: engineHead, ..currentGitHead = engineHead
checkoutPath: (await engine.checkoutDirectory).path, ..checkoutPath = (await engine.checkoutDirectory).path
dartRevision: dartRevision, ..upstream = (pb.Remote.create()
upstream: pb.Remote(name: 'upstream', url: engine.upstreamRemote.url), ..name = 'upstream'
mirror: pb.Remote(name: 'mirror', url: engine.mirrorRemote!.url), ..url = engine.upstreamRemote.url
)
..mirror = (pb.Remote.create()
..name = 'mirror'
..url = engine.mirrorRemote!.url
)
); );
if (dartRevision != null && dartRevision!.isNotEmpty) {
state.engine.dartRevision = dartRevision!;
}
await framework.newBranch(workingBranchName); await framework.newBranch(workingBranchName);
...@@ -362,14 +370,20 @@ class StartContext extends Context { ...@@ -362,14 +370,20 @@ class StartContext extends Context {
state.releaseVersion = nextVersion.toString(); state.releaseVersion = nextVersion.toString();
state.framework = pb.Repository( state.framework = (pb.Repository.create()
candidateBranch: candidateBranch, ..candidateBranch = candidateBranch
workingBranch: workingBranchName, ..workingBranch = workingBranchName
startingGitHead: frameworkHead, ..startingGitHead = frameworkHead
currentGitHead: frameworkHead, ..currentGitHead = frameworkHead
checkoutPath: (await framework.checkoutDirectory).path, ..checkoutPath = (await framework.checkoutDirectory).path
upstream: pb.Remote(name: 'upstream', url: framework.upstreamRemote.url), ..upstream = (pb.Remote.create()
mirror: pb.Remote(name: 'mirror', url: framework.mirrorRemote!.url), ..name = 'upstream'
..url = framework.upstreamRemote.url
)
..mirror = (pb.Remote.create()
..name = 'mirror'
..url = framework.mirrorRemote!.url
)
); );
state.currentPhase = ReleasePhase.APPLY_ENGINE_CHERRYPICKS; state.currentPhase = ReleasePhase.APPLY_ENGINE_CHERRYPICKS;
......
...@@ -50,7 +50,7 @@ const String stablePostReleaseMsg = """ ...@@ -50,7 +50,7 @@ const String stablePostReleaseMsg = """
String luciConsoleLink(String channel, String groupName) { String luciConsoleLink(String channel, String groupName) {
assert( assert(
globals.kReleaseChannels.contains(channel), globals.kReleaseChannels.contains(channel),
'channel $channel not recognized', 'channel "$channel" not recognized',
); );
assert( assert(
<String>['flutter', 'engine', 'packaging'].contains(groupName), <String>['flutter', 'engine', 'packaging'].contains(groupName),
...@@ -177,10 +177,10 @@ String phaseInstructions(pb.ConductorState state) { ...@@ -177,10 +177,10 @@ String phaseInstructions(pb.ConductorState state) {
'\t${cherrypick.trunkRevision}', '\t${cherrypick.trunkRevision}',
'See ${globals.kReleaseDocumentationUrl} for more information.', 'See ${globals.kReleaseDocumentationUrl} for more information.',
].join('\n'); ].join('\n');
case ReleasePhase.CODESIGN_ENGINE_BINARIES: case ReleasePhase.VERIFY_ENGINE_CI:
if (!requiresEnginePR(state)) { if (!requiresEnginePR(state)) {
return 'You must now codesign the engine binaries for commit ' return 'You must verify engine CI has passed: '
'${state.engine.startingGitHead}.'; '${luciConsoleLink(state.releaseChannel, 'engine')}';
} }
// User's working branch was pushed to their mirror, but a PR needs to be // User's working branch was pushed to their mirror, but a PR needs to be
// opened on GitHub. // opened on GitHub.
...@@ -231,8 +231,6 @@ String phaseInstructions(pb.ConductorState state) { ...@@ -231,8 +231,6 @@ String phaseInstructions(pb.ConductorState state) {
'verify pre-submit CI builds on your pull request are successful, merge your ', 'verify pre-submit CI builds on your pull request are successful, merge your ',
'pull request, validate post-submit CI.', 'pull request, validate post-submit CI.',
].join('\n'); ].join('\n');
case ReleasePhase.PUBLISH_CHANNEL:
return 'Issue `conductor next` to publish your release to the release branch.';
case ReleasePhase.VERIFY_RELEASE: case ReleasePhase.VERIFY_RELEASE:
return 'Release archive packages must be verified on cloud storage: ${luciConsoleLink(state.releaseChannel, 'packaging')}'; return 'Release archive packages must be verified on cloud storage: ${luciConsoleLink(state.releaseChannel, 'packaging')}';
case ReleasePhase.RELEASE_COMPLETED: case ReleasePhase.RELEASE_COMPLETED:
...@@ -286,11 +284,20 @@ String githubAccount(String remoteUrl) { ...@@ -286,11 +284,20 @@ String githubAccount(String remoteUrl) {
/// Will throw a [ConductorException] if [ReleasePhase.RELEASE_COMPLETED] is /// Will throw a [ConductorException] if [ReleasePhase.RELEASE_COMPLETED] is
/// passed as an argument, as there is no next phase. /// passed as an argument, as there is no next phase.
ReleasePhase getNextPhase(ReleasePhase currentPhase) { ReleasePhase getNextPhase(ReleasePhase currentPhase) {
final ReleasePhase? nextPhase = ReleasePhase.valueOf(currentPhase.value + 1); switch (currentPhase) {
if (nextPhase == null) { case ReleasePhase.PUBLISH_VERSION:
throw globals.ConductorException('There is no next ReleasePhase!'); return ReleasePhase.VERIFY_RELEASE;
case ReleasePhase.APPLY_ENGINE_CHERRYPICKS:
case ReleasePhase.VERIFY_ENGINE_CI:
case ReleasePhase.APPLY_FRAMEWORK_CHERRYPICKS:
case ReleasePhase.VERIFY_RELEASE:
case ReleasePhase.RELEASE_COMPLETED:
final ReleasePhase? nextPhase = ReleasePhase.valueOf(currentPhase.value + 1);
if (nextPhase != null) {
return nextPhase;
}
} }
return nextPhase; throw globals.ConductorException('There is no next ReleasePhase!');
} }
// Indent two spaces. // Indent two spaces.
......
...@@ -31,25 +31,27 @@ void main() { ...@@ -31,25 +31,27 @@ void main() {
late pb.ConductorState state; late pb.ConductorState state;
setUp(() { setUp(() {
state = pb.ConductorState( state = (pb.ConductorState.create()
engine: pb.Repository( ..engine = (pb.Repository.create()
candidateBranch: candidateBranch, ..candidateBranch = candidateBranch
cherrypicks: <pb.Cherrypick>[ ..cherrypicks.addAll(<pb.Cherrypick>[
pb.Cherrypick(trunkRevision: engineCherrypick1), pb.Cherrypick.create()
pb.Cherrypick(trunkRevision: engineCherrypick2), ..trunkRevision = engineCherrypick1,
], pb.Cherrypick.create()
dartRevision: dartRevision, ..trunkRevision = engineCherrypick2,
workingBranch: workingBranch, ])
), ..dartRevision = dartRevision
framework: pb.Repository( ..workingBranch = workingBranch
candidateBranch: candidateBranch, )
cherrypicks: <pb.Cherrypick>[ ..framework = (pb.Repository.create()
pb.Cherrypick(trunkRevision: frameworkCherrypick), ..candidateBranch = candidateBranch
], ..cherrypicks.add(pb.Cherrypick.create()
workingBranch: workingBranch, ..trunkRevision = frameworkCherrypick
), )
releaseChannel: releaseChannel, ..workingBranch = workingBranch
releaseVersion: releaseVersion, )
..releaseChannel = releaseChannel
..releaseVersion = releaseVersion
); );
}); });
......
This diff is collapsed.
...@@ -15,24 +15,23 @@ void main() { ...@@ -15,24 +15,23 @@ void main() {
final File stateFile = fileSystem.file('/path/to/statefile.json') final File stateFile = fileSystem.file('/path/to/statefile.json')
..createSync(recursive: true); ..createSync(recursive: true);
const String candidateBranch = 'flutter-2.3-candidate.0'; const String candidateBranch = 'flutter-2.3-candidate.0';
final pb.ConductorState state = pb.ConductorState( final pb.ConductorState state = pb.ConductorState.create()
releaseChannel: 'stable', ..releaseChannel = 'stable'
releaseVersion: '2.3.4', ..releaseVersion = '2.3.4'
engine: pb.Repository( ..engine = (pb.Repository.create()
candidateBranch: candidateBranch, ..candidateBranch = candidateBranch
upstream: pb.Remote( ..upstream = (pb.Remote.create()
name: 'upstream', ..name = 'upstream'
url: 'git@github.com:flutter/engine.git', ..url = 'git@github.com:flutter/engine.git'
), )
), )
framework: pb.Repository( ..framework = (pb.Repository.create()
candidateBranch: candidateBranch, ..candidateBranch = candidateBranch
upstream: pb.Remote( ..upstream = (pb.Remote.create()
name: 'upstream', ..name = 'upstream'
url: 'git@github.com:flutter/flutter.git', ..url = 'git@github.com:flutter/flutter.git'
), )
), );
);
writeStateToFile( writeStateToFile(
stateFile, stateFile,
state, state,
......
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