Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds a script for the release steps of dwds and webdev #2049

Merged
merged 16 commits into from
Mar 24, 2023
21 changes: 7 additions & 14 deletions dwds/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,13 @@ the example app and connect to DWDS.

## Step 2: Publish DWDS to pub

- Make sure you are on the Dart stable SDK version (check with `dart --version`)
- From each of the subdirectories (`/dwds`, `/frontend_server_client`,
`/frontend_server_common`, and `/webdev`) update dependencies with
`dart pub upgrade`
- Update the version number in `dwds/pubspec.yaml` and `dwds/CHANGELOG.md`
- From `/dwds` run `dart run build_runner build`, this will build and update the
version in `/dwds/lib/src/version.dart`
- Submit a PR with those changes (example PR:
https://github.com/dart-lang/webdev/pull/1456). _Note: Ensure your PR doesn’t
have any dependency overrides._
- Once the PR is submitted, pull from master and `run dart pub publish`
- Finally, go to https://github.com/dart-lang/webdev/releases and create a new
release, eg https://github.com/dart-lang/webdev/releases/tag/dwds-v12.0.0. You
might need to delete some of the content of the autogenerated notes.
- From the `/tool` directory in the mono-repo root, run: `dart run release.dart -p dwds`
- Submit a PR with those changes (example PR: https://github.com/dart-lang/webdev/pull/1456)
- Once the PR is submitted, go to https://github.com/dart-lang/webdev/releases and create a new
release, eg https://github.com/dart-lang/webdev/releases/tag/dwds-v12.0.0. This should trigger
the auto-publisher. Verify that the package is published.
- From the `/tool` directory in the mono-repo root, run: `dart run release.dart --reset -p dwds`
- Submit a PR with those changes.

> _Note: To have the right permissions for publishing, you need to be invited to
> the tools.dart.dev. A member of the Dart team should be able to add you at
Expand Down
9 changes: 9 additions & 0 deletions tool/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: tool
publish_to: none
description: >-
Common tools for the mono-repo.
environment:
sdk: ">=3.0.0-134.0.dev <4.0.0"

dev_dependencies:
args: ^2.4.0
287 changes: 287 additions & 0 deletions tool/release.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. 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:args/args.dart';

const _packageOption = 'package';
const _versionOption = 'version';
const _resetFlag = 'reset';
const _skipStableCheckFlag = 'skipStableCheck';

/// Note: Must be run from the /tool directory.
///
/// To prepare DWDS for release:
/// `dart run release.dart -p dwds`
///
/// To prepare WebDev for release:
/// `dart run release.dart -p webdev`
///
/// To reset DWDS after a release:
/// `dart run release.dart --reset -p dwds -v -[[dev version]]`
///
/// To reset WebDev after a release:
/// `dart run release.dart --reset -p webdev -v -[[dev version]]`

void main(List<String> arguments) async {
final parser = ArgParser()
..addOption(
_packageOption,
abbr: 'p',
allowed: [
'webdev',
'dwds',
],
)
..addOption(_versionOption, abbr: 'v')
..addFlag(_resetFlag, abbr: 'r')
..addFlag(_skipStableCheckFlag, abbr: 's');

final argResults = parser.parse(arguments);
final package = argResults[_packageOption] as String?;
if (package == null) {
_logWarning('Please specify package with either --p=dwds or --p=webdev');
return;
}

final isReset = argResults[_resetFlag] as bool?;
final newVersion = argResults[_versionOption] as String?;
final skipStableCheck = argResults[_skipStableCheckFlag] as bool?;

int exitCode;
if (isReset == true) {
exitCode = runReset(
package: package,
newVersion: newVersion,
);
} else {
exitCode = await runRelease(
package: package,
newVersion: newVersion,
skipStableCheck: skipStableCheck,
);
}
if (exitCode != 0) {
_logWarning('Run terminated unexpectedly with exit code: $exitCode');
}
}

int runReset({
required String package,
String? newVersion,
}) {
// Check that a new dev version has been provided.
final currentVersion = _readVersionFile(package);
if (newVersion == null || !newVersion.contains('dev')) {
_logInfo(
'''
Please provide the next dev version for $package, e.g. -v 3.0.1-dev
Current version is $currentVersion.
''',
);
return 1;
}

// Update the version strings in CHANGELOG and pubspec.yaml.
_updateVersionStrings(
package,
currentVersion: currentVersion,
nextVersion: newVersion,
isReset: true,
);

return 0;
}

Future<int> runRelease({
required String package,
String? newVersion,
bool? skipStableCheck,
}) async {
// Check that we are on a stable version of Dart.
if (skipStableCheck != true) {
final checkVersionProcess = await Process.run('dart', ['--version']);
final versionInfo = checkVersionProcess.stdout as String;
if (!versionInfo.contains('stable')) {
_logWarning(
'''
Expected to be on stable version of Dart, instead on:
$versionInfo
To skip this check, re-run with --skipStableCheck
''',
);
return checkVersionProcess.exitCode;
}
}

// Update the pinned version of DWDS for webdev releases.
if (package == 'webdev') {
_logInfo('Updating pinned version of DWDS.');
await _updateDwdsPin(package);
}

// Run dart pub upgrade.
for (final packagePath in [
'../dwds',
'../webdev',
'../frontend_server_common',
'../frontend_server_client',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add ../test_common and all the test projects in the fixtures as well?

Copy link
Contributor Author

@elliette elliette Mar 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added test_common! To be honest, I've never run dart pub upgrade from the other test packages before publishing (I'm actually not clear why this was part of the manual process, but included it since it is one of the things we did when publishing manually)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will catch CI breaks if something goes wrong with constraint resolution (CI always runs pub upgrade)

'../test_common',
]) {
_logInfo('Upgrading pub packages for $packagePath');
final pubUpgradeProcess = await Process.run(
'dart',
[
'pub',
'upgrade',
],
workingDirectory: packagePath,
);
final upgradeErrors = pubUpgradeProcess.stderr as String;
if (upgradeErrors.isNotEmpty) {
_logWarning(upgradeErrors);
return pubUpgradeProcess.exitCode;
}
}

// Update the version strings in CHANGELOG and pubspec.yaml.
final currentVersion = _readVersionFile(package);
final nextVersion = newVersion ?? _removeDev(currentVersion);
_updateVersionStrings(
package,
currentVersion: currentVersion,
nextVersion: nextVersion,
);

// Build the package.
final exitCode = _buildPackage(package);
return exitCode;
}

Future<int> _buildPackage(String package) async {
_logInfo('Building $package');
final buildProcess = await Process.run(
'dart',
['run', 'build_runner', 'build'],
workingDirectory: '../$package',
);

final buildErrors = buildProcess.stderr as String;
if (buildErrors.isNotEmpty) {
_logWarning(buildErrors);
}
return buildProcess.exitCode;
}

void _updateVersionStrings(
String package, {
required String nextVersion,
required String currentVersion,
bool isReset = false,
}) {
_logInfo('Updating $package from $currentVersion to $nextVersion');
final pubspec = File('../$package/pubspec.yaml');
final changelog = File('../$package/CHANGELOG.md');
if (isReset) {
_addNewLine(changelog, newLine: '## $nextVersion');
_replaceInFile(pubspec, query: currentVersion, replaceWith: nextVersion);
} else {
for (final file in [pubspec, changelog]) {
_replaceInFile(file, query: currentVersion, replaceWith: nextVersion);
}
}
}

void _addNewLine(
File file, {
required String newLine,
}) {
final newLines = [newLine, '', ...file.readAsLinesSync()];
final content = newLines.joinWithNewLine();
return file.writeAsStringSync(content);
}

void _replaceInFile(
File file, {
required String query,
required String replaceWith,
}) {
final newLines = <String>[];
for (final line in file.readAsLinesSync()) {
if (line.contains(query)) {
newLines.add(line.replaceAll(query, replaceWith));
} else {
newLines.add(line);
}
}
final content = newLines.joinWithNewLine();
return file.writeAsStringSync(content);
}

String _readVersionFile(String package) {
final versionFile = File('../$package/lib/src/version.dart');
final lines = versionFile.readAsLinesSync();
for (final line in lines) {
if (line.startsWith('const packageVersion =')) {
final version = line
.split('=')
.last
.split('')
.where((char) => char != ';' && char != "'" && char != '"')
.join('');
return version.trim();
}
}
throw Exception('Could not read version in $package/lib/src/version.dart');
}

String _removeDev(String devVersion) {
if (!devVersion.contains('dev')) {
throw Exception('$devVersion is not a dev version.');
}
return devVersion.split('-dev').first;
}

Future<void> _updateDwdsPin(String package) async {
final pubOutdatedProcess = await Process.run(
'dart',
[
'pub',
'outdated',
'--no-dependency-overrides',
],
workingDirectory: '../$package',
);
final lines = pubOutdatedProcess.stdout.split('\n') as List<String>;
for (final line in lines) {
if (line.trim().startsWith('dwds')) {
final segments =
line.trim().split(' ').where((segment) => segment != ' ');
final nextVersion = segments.last;
final currentVersion =
segments.lastWhere((segment) => segment.startsWith('*')).substring(1);
_logInfo('Changing DWDS pin from $currentVersion to $nextVersion');
_replaceInFile(
File('../$package/pubspec.yaml'),
query: currentVersion,
replaceWith: nextVersion,
);
}
}
}

void _logInfo(String message) {
stdout.writeln(message);
}

void _logWarning(String warning) {
stderr.writeln(warning);
}

extension JoinExtension on List<String> {
String joinWithNewLine() {
return '${join('\n')}\n';
}
}
26 changes: 9 additions & 17 deletions webdev/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
## Instructions on releasing Webdev

- Make sure you are on the Dart stable SDK version (check with `dart --version`)
- Update the DWDS version in `/webdev/pubspec.yaml` to match the newly released
DWDS version, and update the Webdev version to the new version number. Also,
comment out the dependency_override so that Webdev is now depending on the
version of DWDS on pub (which should have just been published) instead of the
local version.
- Update `/webdev/CHANGELOG.md` to match the new webdev version
- From `/webdev`, run `dart pub upgrade`
- From `/webdev` run `dart run build_runner build`, this will build and update
the version in `webdev/lib/src/version.dart`
- Before submitting your PR, test that everything is working by following
- From the `/tool` directory in the mono-repo root, run: `dart run release.dart -p webdev`
- Open a PR with those changes (example PR:
https://github.com/dart-lang/webdev/pull/1498)
- Note: Before submitting your PR, test that everything is working by following
instructions in the `webdev/example` [README](/example/README.md) to run the
example app and connect to Dart DevTools.
- Submit a PR with those changes (example PR:
https://github.com/dart-lang/webdev/pull/1498)
- Once the PR is submitted, pull from master and run `dart pub publish`
- Finally, go to https://github.com/dart-lang/webdev/releases and create a new
release, eg https://github.com/dart-lang/webdev/releases/tag/webdev-v2.7.8.
You might need to delete some of the content of the autogenerated notes.
- Once the PR is submitted, go to https://github.com/dart-lang/webdev/releases and create a new
release, eg https://github.com/dart-lang/webdev/releases/tag/webdev-3.0.0. This should trigger
the auto-publisher. Verify that the package is published.
- From the `/tool` directory in the mono-repo root, run: `dart run release.dart --reset -p webdev`
- Submit a PR with those changes.