@@ -22,7 +22,8 @@ String luciConsoleLink(String channel, String groupName) {
2222 < String > ['flutter' , 'engine' , 'packaging' ].contains (groupName),
2323 'group named $groupName not recognized' ,
2424 );
25- final String consoleName = channel == 'master' ? groupName : '${channel }_$groupName ' ;
25+ final String consoleName =
26+ channel == 'master' ? groupName : '${channel }_$groupName ' ;
2627 return 'https://ci.chromium.org/p/flutter/g/$consoleName /console' ;
2728}
2829
@@ -43,15 +44,18 @@ String presentState(pb.ConductorState state) {
4344 buffer.writeln ('Release channel: ${state .releaseChannel }' );
4445 buffer.writeln ('Release version: ${state .releaseVersion }' );
4546 buffer.writeln ();
46- buffer.writeln ('Release started at: ${DateTime .fromMillisecondsSinceEpoch (state .createdDate .toInt ())}' );
47- buffer.writeln ('Last updated at: ${DateTime .fromMillisecondsSinceEpoch (state .lastUpdatedDate .toInt ())}' );
47+ buffer.writeln (
48+ 'Release started at: ${DateTime .fromMillisecondsSinceEpoch (state .createdDate .toInt ())}' );
49+ buffer.writeln (
50+ 'Last updated at: ${DateTime .fromMillisecondsSinceEpoch (state .lastUpdatedDate .toInt ())}' );
4851 buffer.writeln ();
4952 buffer.writeln ('Engine Repo' );
5053 buffer.writeln ('\t Candidate branch: ${state .engine .candidateBranch }' );
5154 buffer.writeln ('\t Starting git HEAD: ${state .engine .startingGitHead }' );
5255 buffer.writeln ('\t Current git HEAD: ${state .engine .currentGitHead }' );
5356 buffer.writeln ('\t Path to checkout: ${state .engine .checkoutPath }' );
54- buffer.writeln ('\t Post-submit LUCI dashboard: ${luciConsoleLink (state .releaseChannel , 'engine' )}' );
57+ buffer.writeln (
58+ '\t Post-submit LUCI dashboard: ${luciConsoleLink (state .releaseChannel , 'engine' )}' );
5559 if (state.engine.cherrypicks.isNotEmpty) {
5660 buffer.writeln ('${state .engine .cherrypicks .length } Engine Cherrypicks:' );
5761 for (final pb.Cherrypick cherrypick in state.engine.cherrypicks) {
@@ -60,17 +64,20 @@ String presentState(pb.ConductorState state) {
6064 } else {
6165 buffer.writeln ('0 Engine cherrypicks.' );
6266 }
63- if (state.engine.dartRevision != null && state.engine.dartRevision.isNotEmpty) {
67+ if (state.engine.dartRevision != null &&
68+ state.engine.dartRevision.isNotEmpty) {
6469 buffer.writeln ('New Dart SDK revision: ${state .engine .dartRevision }' );
6570 }
6671 buffer.writeln ('Framework Repo' );
6772 buffer.writeln ('\t Candidate branch: ${state .framework .candidateBranch }' );
6873 buffer.writeln ('\t Starting git HEAD: ${state .framework .startingGitHead }' );
6974 buffer.writeln ('\t Current git HEAD: ${state .framework .currentGitHead }' );
7075 buffer.writeln ('\t Path to checkout: ${state .framework .checkoutPath }' );
71- buffer.writeln ('\t Post-submit LUCI dashboard: ${luciConsoleLink (state .releaseChannel , 'flutter' )}' );
76+ buffer.writeln (
77+ '\t Post-submit LUCI dashboard: ${luciConsoleLink (state .releaseChannel , 'flutter' )}' );
7278 if (state.framework.cherrypicks.isNotEmpty) {
73- buffer.writeln ('${state .framework .cherrypicks .length } Framework Cherrypicks:' );
79+ buffer.writeln (
80+ '${state .framework .cherrypicks .length } Framework Cherrypicks:' );
7481 for (final pb.Cherrypick cherrypick in state.framework.cherrypicks) {
7582 buffer.writeln ('\t ${cherrypick .trunkRevision } - ${cherrypick .state }' );
7683 }
@@ -125,7 +132,8 @@ String phaseInstructions(pb.ConductorState state) {
125132 return < String > [
126133 'You must now manually apply the following engine cherrypicks to the checkout' ,
127134 'at ${state .engine .checkoutPath } in order:' ,
128- for (final pb.Cherrypick cherrypick in state.engine.cherrypicks) '\t ${cherrypick .trunkRevision }' ,
135+ for (final pb.Cherrypick cherrypick in state.engine.cherrypicks)
136+ '\t ${cherrypick .trunkRevision }' ,
129137 'See $kReleaseDocumentationUrl for more information.' ,
130138 ].join ('\n ' );
131139 case ReleasePhase .CODESIGN_ENGINE_BINARIES :
@@ -147,19 +155,24 @@ String phaseInstructions(pb.ConductorState state) {
147155 'validate post-submit CI, and then codesign the binaries on the merge commit.' ,
148156 ].join ('\n ' );
149157 case ReleasePhase .APPLY_FRAMEWORK_CHERRYPICKS :
150- final List <pb.Cherrypick > outstandingCherrypicks = state.framework.cherrypicks.where (
158+ final List <pb.Cherrypick > outstandingCherrypicks =
159+ state.framework.cherrypicks.where (
151160 (pb.Cherrypick cp) {
152- return cp.state == pb.CherrypickState .PENDING || cp.state == pb.CherrypickState .PENDING_WITH_CONFLICT ;
161+ return cp.state == pb.CherrypickState .PENDING ||
162+ cp.state == pb.CherrypickState .PENDING_WITH_CONFLICT ;
153163 },
154164 ).toList ();
155165 if (outstandingCherrypicks.isNotEmpty) {
156166 return < String > [
157167 'You must now manually apply the following framework cherrypicks to the checkout' ,
158168 'at ${state .framework .checkoutPath } in order:' ,
159- for (final pb.Cherrypick cherrypick in outstandingCherrypicks) '\t ${cherrypick .trunkRevision }' ,
169+ for (final pb.Cherrypick cherrypick in outstandingCherrypicks)
170+ '\t ${cherrypick .trunkRevision }' ,
160171 ].join ('\n ' );
161172 }
162- return < String > ['Either all cherrypicks have been auto-applied or there were none.' ].join ('\n ' );
173+ return < String > [
174+ 'Either all cherrypicks have been auto-applied or there were none.'
175+ ].join ('\n ' );
163176 case ReleasePhase .PUBLISH_VERSION :
164177 if (! requiresFrameworkPR (state)) {
165178 return 'Since there are no code changes in this release, no Framework '
@@ -182,7 +195,24 @@ String phaseInstructions(pb.ConductorState state) {
182195 case ReleasePhase .VERIFY_RELEASE :
183196 return 'Release archive packages must be verified on cloud storage: ${luciConsoleLink (state .releaseChannel , 'packaging' )}' ;
184197 case ReleasePhase .RELEASE_COMPLETED :
185- return 'This release has been completed.' ;
198+ if (state.releaseChannel == 'beta' ) {
199+ return < String > [
200+ 'Ensure the following post release steps are complete:' ,
201+ '\t 1. Post announcement to discord' ,
202+ '\t 2. Post announcement flutter release hotline chat room' ,
203+ '-----------------------------------------------------------------------' ,
204+ 'This release has been completed.'
205+ ].join ('\n ' );
206+ }
207+ return < String > [
208+ 'Ensure the following post release steps are complete:' ,
209+ '\t 1. Update hotfix to stable wiki following documentation best practices' ,
210+ '\t 2. Post announcement to flutter-announce group' ,
211+ '\t 3. Post announcement to discord' ,
212+ '\t 4. Post announcement flutter release hotline chat room' ,
213+ '-----------------------------------------------------------------------' ,
214+ 'This release has been completed.'
215+ ].join ('\n ' );
186216 }
187217 // For analyzer
188218 throw ConductorException ('Unimplemented phase ${state .currentPhase }' );
@@ -193,8 +223,8 @@ String phaseInstructions(pb.ConductorState state) {
193223/// First group = git host (currently must be github.com)
194224/// Second group = account name
195225/// Third group = repo name
196- final RegExp githubRemotePattern =
197- RegExp ( r'^(git@github\.com:|https?:\/\/github\.com\/)([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_-]+)(\.git)?$' );
226+ final RegExp githubRemotePattern = RegExp (
227+ r'^(git@github\.com:|https?:\/\/github\.com\/)([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_-]+)(\.git)?$' );
198228
199229/// Parses a Git remote URL and returns the account name.
200230///
@@ -271,8 +301,8 @@ bool requiresFrameworkPR(pb.ConductorState state) {
271301 if (requiresEnginePR (state)) {
272302 return true ;
273303 }
274- final bool hasRequiredCherrypicks =
275- state.framework.cherrypicks .any ((pb.Cherrypick cp) => cp.state != pb.CherrypickState .ABANDONED );
304+ final bool hasRequiredCherrypicks = state.framework.cherrypicks
305+ .any ((pb.Cherrypick cp) => cp.state != pb.CherrypickState .ABANDONED );
276306 if (hasRequiredCherrypicks) {
277307 return true ;
278308 }
0 commit comments