Skip to content

Commit 48eb6ab

Browse files
committed
update
1 parent e486575 commit 48eb6ab

File tree

5 files changed

+87
-76
lines changed

5 files changed

+87
-76
lines changed

.github/workflows/batch_release_pr.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: "Creates Batch Release for go_router package"
1+
name: "Creates Batch Release for A Package"
22

33
on:
44
repository_dispatch:
@@ -19,14 +19,14 @@ jobs:
1919
run: |
2020
git config --global user.name ${{ secrets.USER_NAME }}
2121
git config --global user.email ${{ secrets.USER_EMAIL }}
22-
dart ./script/tool/lib/src/main.dart branch-for-batch-release --packages=${{ github.event.client_payload.package }} --branch=${{ env.BRANCH_NAME }}"
22+
dart ./script/tool/lib/src/main.dart branch-for-batch-release --packages=${{ github.event.client_payload.package }} --branch=${{ env.BRANCH_NAME }} --remote=origin
2323
- name: Create Pull Request
2424
uses: peter-evans/create-pull-request@v7
2525
with:
2626
token: ${{ secrets.GITHUB_TOKEN }}
27-
commit-message: "Batch release PR for ${{ github.event.client_payload.package }} package"
28-
title: "Batch Release PR for ${{ github.event.client_payload.package }} package"
29-
body: "This PR was created automatically to batch release the ${{ github.event.client_payload.package }} package."
27+
commit-message: "[${{ github.event.client_payload.package }}] Batch release"
28+
title: "[${{ github.event.client_payload.package }}] Batch release"
29+
body: "This PR was created automatically to batch release the `${{ github.event.client_payload.package }}`."
3030
branch: ${{ env.BRANCH_NAME }}
3131
base: release
3232

.github/workflows/go_router_batch.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
name: "Creates Batch Release for go_router package"
1+
name: "Creates Batch Release for go_router"
22

33
on:
44
schedule:
5-
- cron: "0 0 * * *"
5+
# Run every Monday at 8:00 AM
6+
- cron: "0 8 * * 1"
67

78
jobs:
89
dispatch_release_pr:
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This file is for test purposes only.
22
# TODO(chuntai): remove this file before publishing.
33
changelog: |
4-
- Added 'batch' option to CI config for go_router package.
5-
- Updated GitHub Actions workflow for batch releases of go_router.
4+
- Adds 'batch' option to CI config for go_router package.
5+
- Updates GitHub Actions workflow for batch releases of go_router.
66
version: major
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# This file is for test purposes only.
22
# TODO(chuntai): remove this file before publishing.
33
changelog: |
4-
- Added 'batch' option to CI config for go_router package.
5-
- Updated GitHub Actions workflow for batch releases of go_router.
6-
version: major
4+
- Adds some other features
5+
version: minor

script/tool/lib/src/branch_for_batch_release_command.dart

Lines changed: 75 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ import 'common/output_utils.dart';
1616
import 'common/package_command.dart';
1717
import 'common/repository_package.dart';
1818

19-
const int _kExitPackageMalformed = 2;
20-
const int _kGitFailedToPush = 3;
19+
const int _kExitPackageMalformed = 3;
20+
const int _kGitFailedToPush = 4;
2121

22+
// The template file name used to draft a pending changelog file.
23+
// This file will not be picked up by the batch release process.
2224
const String _kTemplateFileName = 'template.yaml';
2325

2426
/// A command to create a remote branch with release changes for a single package.
@@ -46,7 +48,8 @@ class BranchForBatchReleaseCommand extends PackageCommand {
4648

4749
@override
4850
Future<void> run() async {
49-
final String branchName = argResults!['branch'] as String;
51+
final String branchName = getStringArg('branch');
52+
final String remoteName = getStringArg('remote');
5053

5154
final List<RepositoryPackage> packages = await getTargetPackages()
5255
.map((PackageEnumerationEntry e) => e.package)
@@ -60,7 +63,7 @@ class BranchForBatchReleaseCommand extends PackageCommand {
6063
final GitDir repository = await gitDir;
6164

6265
print('Parsing package "${package.displayName}"...');
63-
final PendingChangelogs pendingChangelogs =
66+
final _PendingChangelogs pendingChangelogs =
6467
await _getPendingChangelogs(package);
6568
if (pendingChangelogs.entries.isEmpty) {
6669
print('No pending changelogs found for ${package.displayName}.');
@@ -69,7 +72,12 @@ class BranchForBatchReleaseCommand extends PackageCommand {
6972

7073
final Pubspec pubspec =
7174
Pubspec.parse(package.pubspecFile.readAsStringSync());
72-
final ReleaseInfo releaseInfo =
75+
if (pubspec.version == null || pubspec.version!.major < 1) {
76+
printError(
77+
'This script only supports packages with version >= 1.0.0. Current version: ${pubspec.version}. Package: ${package.displayName}.');
78+
throw ToolExit(_kExitPackageMalformed);
79+
}
80+
final _ReleaseInfo releaseInfo =
7381
_getReleaseInfo(pendingChangelogs.entries, pubspec.version!);
7482

7583
if (releaseInfo.newVersion == null) {
@@ -78,17 +86,17 @@ class BranchForBatchReleaseCommand extends PackageCommand {
7886
return;
7987
}
8088

81-
print('Creating and pushing release branch...');
82-
await _pushBranch(
89+
await _createReleaseBranch(
8390
git: repository,
8491
package: package,
8592
branchName: branchName,
8693
pendingChangelogFiles: pendingChangelogs.files,
8794
releaseInfo: releaseInfo,
95+
remoteName: remoteName,
8896
);
8997
}
9098

91-
Future<PendingChangelogs> _getPendingChangelogs(
99+
Future<_PendingChangelogs> _getPendingChangelogs(
92100
RepositoryPackage package) async {
93101
final Directory pendingChangelogsDir =
94102
package.directory.childDirectory('pending_changelogs');
@@ -104,60 +112,47 @@ class BranchForBatchReleaseCommand extends PackageCommand {
104112
f.basename.endsWith('.yaml') && f.basename != _kTemplateFileName)
105113
.toList();
106114
try {
107-
final List<PendingChangelogEntry> entries = pendingChangelogFiles
108-
.map<PendingChangelogEntry>(
109-
(File f) => PendingChangelogEntry.parse(f.readAsStringSync()))
115+
final List<_PendingChangelogEntry> entries = pendingChangelogFiles
116+
.map<_PendingChangelogEntry>(
117+
(File f) => _PendingChangelogEntry.parse(f.readAsStringSync()))
110118
.toList();
111-
return PendingChangelogs(entries, pendingChangelogFiles);
119+
return _PendingChangelogs(entries, pendingChangelogFiles);
112120
} on FormatException catch (e) {
113121
printError('Malformed pending changelog file: $e');
114122
throw ToolExit(_kExitPackageMalformed);
115123
}
116124
}
117125

118-
ReleaseInfo _getReleaseInfo(
119-
List<PendingChangelogEntry> pendingChangelogEntries, Version oldVersion) {
126+
_ReleaseInfo _getReleaseInfo(
127+
List<_PendingChangelogEntry> pendingChangelogEntries,
128+
Version oldVersion) {
120129
final List<String> changelogs = <String>[];
121-
int versionIndex = VersionChange.skip.index;
122-
for (final PendingChangelogEntry entry in pendingChangelogEntries) {
130+
int versionIndex = _VersionChange.skip.index;
131+
for (final _PendingChangelogEntry entry in pendingChangelogEntries) {
123132
changelogs.add(entry.changelog);
124133
versionIndex = math.min(versionIndex, entry.version.index);
125134
}
126-
final VersionChange effectiveVersionChange =
127-
VersionChange.values[versionIndex];
128-
129-
Version? newVersion;
130-
switch (effectiveVersionChange) {
131-
case VersionChange.skip:
132-
break;
133-
case VersionChange.major:
134-
newVersion = Version(
135-
oldVersion.major + 1,
136-
0,
137-
0,
138-
);
139-
case VersionChange.minor:
140-
newVersion = Version(
141-
oldVersion.major,
142-
oldVersion.minor + 1,
143-
0,
144-
);
145-
case VersionChange.patch:
146-
newVersion = Version(
147-
oldVersion.major,
148-
oldVersion.minor,
149-
oldVersion.patch + 1,
150-
);
151-
}
152-
return ReleaseInfo(newVersion, changelogs);
135+
final _VersionChange effectiveVersionChange =
136+
_VersionChange.values[versionIndex];
137+
138+
final Version? newVersion = switch (effectiveVersionChange) {
139+
_VersionChange.skip => null,
140+
_VersionChange.major => Version(oldVersion.major + 1, 0, 0),
141+
_VersionChange.minor =>
142+
Version(oldVersion.major, oldVersion.minor + 1, 0),
143+
_VersionChange.patch =>
144+
Version(oldVersion.major, oldVersion.minor, oldVersion.patch + 1),
145+
};
146+
return _ReleaseInfo(newVersion, changelogs);
153147
}
154148

155-
Future<void> _pushBranch({
149+
Future<void> _createReleaseBranch({
156150
required GitDir git,
157151
required RepositoryPackage package,
158152
required String branchName,
159153
required List<File> pendingChangelogFiles,
160-
required ReleaseInfo releaseInfo,
154+
required _ReleaseInfo releaseInfo,
155+
required String remoteName,
161156
}) async {
162157
print(' Creating new branch "$branchName"...');
163158
final io.ProcessResult checkoutResult =
@@ -168,16 +163,23 @@ class BranchForBatchReleaseCommand extends PackageCommand {
168163
throw ToolExit(_kGitFailedToPush);
169164
}
170165

171-
print(' Updating pubspec.yaml to version ${releaseInfo.newVersion}...');
172-
// Update pubspec.yaml.
166+
_updatePubspec(package, releaseInfo.newVersion!);
167+
_updateChangelog(package, releaseInfo);
168+
await _removePendingChangelogs(git, pendingChangelogFiles);
169+
await _stageAndCommitChanges(git, package);
170+
await _pushBranch(git, remoteName, branchName);
171+
}
172+
173+
void _updatePubspec(RepositoryPackage package, Version newVersion) {
174+
print(' Updating pubspec.yaml to version $newVersion...');
173175
final YamlEditor editablePubspec =
174176
YamlEditor(package.pubspecFile.readAsStringSync());
175-
editablePubspec
176-
.update(<String>['version'], releaseInfo.newVersion.toString());
177+
editablePubspec.update(<String>['version'], newVersion.toString());
177178
package.pubspecFile.writeAsStringSync(editablePubspec.toString());
179+
}
178180

181+
void _updateChangelog(RepositoryPackage package, _ReleaseInfo releaseInfo) {
179182
print(' Updating CHANGELOG.md...');
180-
// Update CHANGELOG.md.
181183
final String newHeader = '## ${releaseInfo.newVersion}';
182184
final List<String> newEntries = releaseInfo.changelogs;
183185

@@ -191,7 +193,10 @@ class BranchForBatchReleaseCommand extends PackageCommand {
191193
newChangelog.write(oldChangelogContent);
192194

193195
package.changelogFile.writeAsStringSync(newChangelog.toString());
196+
}
194197

198+
Future<void> _removePendingChangelogs(
199+
GitDir git, List<File> pendingChangelogFiles) async {
195200
print(' Removing pending changelog files...');
196201
for (final File file in pendingChangelogFiles) {
197202
final io.ProcessResult rmResult =
@@ -201,7 +206,10 @@ class BranchForBatchReleaseCommand extends PackageCommand {
201206
throw ToolExit(_kGitFailedToPush);
202207
}
203208
}
209+
}
204210

211+
Future<void> _stageAndCommitChanges(
212+
GitDir git, RepositoryPackage package) async {
205213
print(' Staging changes...');
206214
final io.ProcessResult addResult = await git.runCommand(
207215
<String>['add', package.pubspecFile.path, package.changelogFile.path]);
@@ -220,10 +228,13 @@ class BranchForBatchReleaseCommand extends PackageCommand {
220228
printError('Failed to commit: ${commitResult.stderr}');
221229
throw ToolExit(_kGitFailedToPush);
222230
}
231+
}
223232

233+
Future<void> _pushBranch(
234+
GitDir git, String remoteName, String branchName) async {
224235
print(' Pushing to remote...');
225236
final io.ProcessResult pushResult =
226-
await git.runCommand(<String>['push', 'origin', branchName]);
237+
await git.runCommand(<String>['push', remoteName, branchName]);
227238
if (pushResult.exitCode != 0) {
228239
printError('Failed to push to $branchName: ${pushResult.stderr}');
229240
throw ToolExit(_kGitFailedToPush);
@@ -232,21 +243,21 @@ class BranchForBatchReleaseCommand extends PackageCommand {
232243
}
233244

234245
/// A data class for pending changelogs.
235-
class PendingChangelogs {
246+
class _PendingChangelogs {
236247
/// Creates a new instance.
237-
PendingChangelogs(this.entries, this.files);
248+
_PendingChangelogs(this.entries, this.files);
238249

239250
/// The parsed pending changelog entries.
240-
final List<PendingChangelogEntry> entries;
251+
final List<_PendingChangelogEntry> entries;
241252

242253
/// The files that the pending changelog entries were parsed from.
243254
final List<File> files;
244255
}
245256

246257
/// A data class for processed release information.
247-
class ReleaseInfo {
258+
class _ReleaseInfo {
248259
/// Creates a new instance.
249-
ReleaseInfo(this.newVersion, this.changelogs);
260+
_ReleaseInfo(this.newVersion, this.changelogs);
250261

251262
/// The new version for the release, or null if there is no version change.
252263
final Version? newVersion;
@@ -256,7 +267,7 @@ class ReleaseInfo {
256267
}
257268

258269
/// The type of version change for a release.
259-
enum VersionChange {
270+
enum _VersionChange {
260271
/// A major version change (e.g., 1.2.3 -> 2.0.0).
261272
major,
262273

@@ -271,12 +282,12 @@ enum VersionChange {
271282
}
272283

273284
/// Represents a single entry in the pending changelog.
274-
class PendingChangelogEntry {
285+
class _PendingChangelogEntry {
275286
/// Creates a new pending changelog entry.
276-
PendingChangelogEntry({required this.changelog, required this.version});
287+
_PendingChangelogEntry({required this.changelog, required this.version});
277288

278289
/// Creates a PendingChangelogEntry from a YAML string.
279-
factory PendingChangelogEntry.parse(String yamlContent) {
290+
factory _PendingChangelogEntry.parse(String yamlContent) {
280291
final dynamic yaml = loadYaml(yamlContent);
281292
if (yaml is! YamlMap) {
282293
throw FormatException(
@@ -294,18 +305,18 @@ class PendingChangelogEntry {
294305
if (versionString == null) {
295306
throw const FormatException('Missing "version" key.');
296307
}
297-
final VersionChange version = VersionChange.values.firstWhere(
298-
(VersionChange e) => e.name == versionString,
308+
final _VersionChange version = _VersionChange.values.firstWhere(
309+
(_VersionChange e) => e.name == versionString,
299310
orElse: () =>
300311
throw FormatException('Invalid version type: $versionString'),
301312
);
302313

303-
return PendingChangelogEntry(changelog: changelog, version: version);
314+
return _PendingChangelogEntry(changelog: changelog, version: version);
304315
}
305316

306317
/// The changelog messages for this entry.
307318
final String changelog;
308319

309320
/// The type of version change for this entry.
310-
final VersionChange version;
321+
final _VersionChange version;
311322
}

0 commit comments

Comments
 (0)