diff --git a/script/tool/lib/src/validators/version_and_changelog_validator.dart b/script/tool/lib/src/validators/version_and_changelog_validator.dart index 58a34f8fd2f..58e79a15b72 100644 --- a/script/tool/lib/src/validators/version_and_changelog_validator.dart +++ b/script/tool/lib/src/validators/version_and_changelog_validator.dart @@ -634,6 +634,18 @@ ${_indentation}The first version listed in CHANGELOG.md is $fromChangeLog. errors.add('pubspec.yaml version changed'); } } + + final bool hasPromote = allChangelogs.any( + (PendingChangelogEntry entry) => entry.version == VersionChange.promote, + ); + if (hasPromote) { + final Version version = package.parsePubspec().version!; + if (version.major != 0) { + printError('"promote" is only valid for pre-1.0 packages.'); + errors.add('Invalid promote version change for post-1.0 package'); + } + } + return versionChanged; } diff --git a/script/tool/test/validate_command_version_test.dart b/script/tool/test/validate_command_version_test.dart index 682d4705837..7084d8e9e1b 100644 --- a/script/tool/test/validate_command_version_test.dart +++ b/script/tool/test/validate_command_version_test.dart @@ -1836,6 +1836,95 @@ packages/package/pending_changelogs/some_change.yaml expect(output, containsAllInOrder([contains('No issues found!')])); }); + + test('fails for batch release package with version promote on post-1.0 package', () async { + final RepositoryPackage package = createFakePackage( + 'package', + packagesDir, + version: '1.0.0', + ); + package.ciConfigFile.writeAsStringSync(''' +release: + batch: true +'''); + package.libDirectory.childFile('foo.dart').writeAsStringSync('void foo() {}'); + final Directory pendingChangelogs = package.directory.childDirectory('pending_changelogs'); + pendingChangelogs.createSync(); + pendingChangelogs.childFile('some_change.yaml').writeAsStringSync(''' +changelog: "Promoting" +version: promote +'''); + + gitProcessRunner.mockProcessesForExecutable['git-diff'] = [ + FakeProcessInfo( + MockProcess( + stdout: ''' +packages/package/lib/foo.dart +packages/package/pending_changelogs/some_change.yaml +''', + ), + ), + ]; + gitProcessRunner.mockProcessesForExecutable['git-show'] = [ + FakeProcessInfo(MockProcess(stdout: 'version: 1.0.0')), + ]; + + Error? commandError; + final List output = await runCapturingPrint( + runner, + ['validate', '--base-sha=main', '--check-for-missing-changes'], + errorHandler: (Error e) { + commandError = e; + }, + ); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([contains('"promote" is only valid for pre-1.0 packages.')]), + ); + }); + + test('passes for batch release package with version promote on pre-1.0 package', () async { + final RepositoryPackage package = createFakePackage( + 'package', + packagesDir, + version: '0.9.0', + ); + package.ciConfigFile.writeAsStringSync(''' +release: + batch: true +'''); + package.libDirectory.childFile('foo.dart').writeAsStringSync('void foo() {}'); + final Directory pendingChangelogs = package.directory.childDirectory('pending_changelogs'); + pendingChangelogs.createSync(); + pendingChangelogs.childFile('some_change.yaml').writeAsStringSync(''' +changelog: "Promoting" +version: promote +'''); + + gitProcessRunner.mockProcessesForExecutable['git-diff'] = [ + FakeProcessInfo( + MockProcess( + stdout: ''' +packages/package/lib/foo.dart +packages/package/pending_changelogs/some_change.yaml +''', + ), + ), + ]; + gitProcessRunner.mockProcessesForExecutable['git-show'] = [ + FakeProcessInfo(MockProcess(stdout: 'version: 0.9.0')), + ]; + + final List output = await runCapturingPrint(runner, [ + 'validate', + '--base-sha=main', + '--check-for-missing-changes', + ]); + + expect(output, containsAllInOrder([contains('No issues found!')])); + }); }); });