Skip to content

Commit 7376e4a

Browse files
committed
[ci] Adds repo checks for batch release
1 parent 6f2dd54 commit 7376e4a

File tree

7 files changed

+633
-217
lines changed

7 files changed

+633
-217
lines changed

script/tool/lib/src/branch_for_batch_release_command.dart

Lines changed: 19 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import 'dart:math' as math;
88
import 'package:file/file.dart';
99
import 'package:git/git.dart';
1010
import 'package:pub_semver/pub_semver.dart';
11-
import 'package:yaml/yaml.dart';
1211
import 'package:yaml_edit/yaml_edit.dart';
1312

1413
import 'common/core.dart';
@@ -19,9 +18,6 @@ import 'common/repository_package.dart';
1918
const int _kExitPackageMalformed = 3;
2019
const int _kGitFailedToPush = 4;
2120

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.
24-
const String _kTemplateFileName = 'template.yaml';
2521

2622
/// A command to create a remote branch with release changes for a single package.
2723
class BranchForBatchReleaseCommand extends PackageCommand {
@@ -69,8 +65,13 @@ class BranchForBatchReleaseCommand extends PackageCommand {
6965
final GitDir repository = await gitDir;
7066

7167
print('Parsing package "${package.displayName}"...');
72-
final _PendingChangelogs pendingChangelogs =
73-
await _getPendingChangelogs(package);
68+
final PendingChangelogs pendingChangelogs = package.getPendingChangelogs();
69+
if (pendingChangelogs.errors.isNotEmpty) {
70+
printError(
71+
'Failed to read pending changelogs for ${package.displayName}:');
72+
pendingChangelogs.errors.forEach(printError);
73+
throw ToolExit(_kExitPackageMalformed);
74+
}
7475
if (pendingChangelogs.entries.isEmpty) {
7576
print('No pending changelogs found for ${package.displayName}.');
7677
return;
@@ -96,67 +97,36 @@ class BranchForBatchReleaseCommand extends PackageCommand {
9697
git: repository,
9798
package: package,
9899
branchName: branchName,
99-
pendingChangelogFiles: pendingChangelogs.files,
100+
pendingChangelogFiles: pendingChangelogs.entries
101+
.map<File>((PendingChangelogEntry e) => e.file)
102+
.toList(),
100103
releaseInfo: releaseInfo,
101104
remoteName: remoteName,
102105
);
103106
}
104107

105-
/// Returns the parsed changelog entries for the given package.
106-
///
107-
/// This method read through the files in the pending_changelogs folder
108-
/// and parsed each file as a changelog entry.
109-
///
110-
/// Throws a [ToolExit] if the package does not have a pending_changelogs folder.
111-
Future<_PendingChangelogs> _getPendingChangelogs(
112-
RepositoryPackage package) async {
113-
final Directory pendingChangelogsDir =
114-
package.directory.childDirectory('pending_changelogs');
115-
if (!pendingChangelogsDir.existsSync()) {
116-
printError(
117-
'No pending_changelogs folder found for ${package.displayName}.');
118-
throw ToolExit(_kExitPackageMalformed);
119-
}
120-
final List<File> pendingChangelogFiles = pendingChangelogsDir
121-
.listSync()
122-
.whereType<File>()
123-
.where((File f) =>
124-
f.basename.endsWith('.yaml') && f.basename != _kTemplateFileName)
125-
.toList();
126-
try {
127-
final List<_PendingChangelogEntry> entries = pendingChangelogFiles
128-
.map<_PendingChangelogEntry>(
129-
(File f) => _PendingChangelogEntry.parse(f.readAsStringSync()))
130-
.toList();
131-
return _PendingChangelogs(entries, pendingChangelogFiles);
132-
} on FormatException catch (e) {
133-
printError('Malformed pending changelog file: $e');
134-
throw ToolExit(_kExitPackageMalformed);
135-
}
136-
}
137-
138108
/// Returns the release info for the given package.
139109
///
140110
/// This method read through the parsed changelog entries decide the new version
141111
/// by following the version change rules. See [_VersionChange] for more details.
142112
_ReleaseInfo _getReleaseInfo(
143-
List<_PendingChangelogEntry> pendingChangelogEntries,
113+
List<PendingChangelogEntry> pendingChangelogEntries,
144114
Version oldVersion) {
145115
final List<String> changelogs = <String>[];
146-
int versionIndex = _VersionChange.skip.index;
147-
for (final _PendingChangelogEntry entry in pendingChangelogEntries) {
116+
int versionIndex = VersionChange.skip.index;
117+
for (final PendingChangelogEntry entry in pendingChangelogEntries) {
148118
changelogs.add(entry.changelog);
149119
versionIndex = math.min(versionIndex, entry.version.index);
150120
}
151-
final _VersionChange effectiveVersionChange =
152-
_VersionChange.values[versionIndex];
121+
final VersionChange effectiveVersionChange =
122+
VersionChange.values[versionIndex];
153123

154124
final Version? newVersion = switch (effectiveVersionChange) {
155-
_VersionChange.skip => null,
156-
_VersionChange.major => Version(oldVersion.major + 1, 0, 0),
157-
_VersionChange.minor =>
125+
VersionChange.skip => null,
126+
VersionChange.major => Version(oldVersion.major + 1, 0, 0),
127+
VersionChange.minor =>
158128
Version(oldVersion.major, oldVersion.minor + 1, 0),
159-
_VersionChange.patch =>
129+
VersionChange.patch =>
160130
Version(oldVersion.major, oldVersion.minor, oldVersion.patch + 1),
161131
};
162132
return _ReleaseInfo(newVersion, changelogs);
@@ -266,17 +236,7 @@ class BranchForBatchReleaseCommand extends PackageCommand {
266236
}
267237
}
268238

269-
/// A data class for pending changelogs.
270-
class _PendingChangelogs {
271-
/// Creates a new instance.
272-
_PendingChangelogs(this.entries, this.files);
273-
274-
/// The parsed pending changelog entries.
275-
final List<_PendingChangelogEntry> entries;
276239

277-
/// The files that the pending changelog entries were parsed from.
278-
final List<File> files;
279-
}
280240

281241
/// A data class for processed release information.
282242
class _ReleaseInfo {
@@ -289,62 +249,3 @@ class _ReleaseInfo {
289249
/// The combined changelog entries.
290250
final List<String> changelogs;
291251
}
292-
293-
/// The type of version change for a release.
294-
///
295-
/// The order of the enum values is important as it is used to determine which version
296-
/// take priority when multiple version changes are specified. The top most value
297-
/// (the samller the index) has the highest priority.
298-
enum _VersionChange {
299-
/// A major version change (e.g., 1.2.3 -> 2.0.0).
300-
major,
301-
302-
/// A minor version change (e.g., 1.2.3 -> 1.3.0).
303-
minor,
304-
305-
/// A patch version change (e.g., 1.2.3 -> 1.2.4).
306-
patch,
307-
308-
/// No version change.
309-
skip,
310-
}
311-
312-
/// Represents a single entry in the pending changelog.
313-
class _PendingChangelogEntry {
314-
/// Creates a new pending changelog entry.
315-
_PendingChangelogEntry({required this.changelog, required this.version});
316-
317-
/// Creates a PendingChangelogEntry from a YAML string.
318-
factory _PendingChangelogEntry.parse(String yamlContent) {
319-
final dynamic yaml = loadYaml(yamlContent);
320-
if (yaml is! YamlMap) {
321-
throw FormatException(
322-
'Expected a YAML map, but found ${yaml.runtimeType}.');
323-
}
324-
325-
final dynamic changelogYaml = yaml['changelog'];
326-
if (changelogYaml is! String) {
327-
throw FormatException(
328-
'Expected "changelog" to be a string, but found ${changelogYaml.runtimeType}.');
329-
}
330-
final String changelog = changelogYaml.trim();
331-
332-
final String? versionString = yaml['version'] as String?;
333-
if (versionString == null) {
334-
throw const FormatException('Missing "version" key.');
335-
}
336-
final _VersionChange version = _VersionChange.values.firstWhere(
337-
(_VersionChange e) => e.name == versionString,
338-
orElse: () =>
339-
throw FormatException('Invalid version type: $versionString'),
340-
);
341-
342-
return _PendingChangelogEntry(changelog: changelog, version: version);
343-
}
344-
345-
/// The changelog messages for this entry.
346-
final String changelog;
347-
348-
/// The type of version change for this entry.
349-
final _VersionChange version;
350-
}

0 commit comments

Comments
 (0)