[tool] Only run postsubmit on changed packages (#6516)

This commit is contained in:
stuartmorgan
2022-09-30 10:53:12 -04:00
committed by GitHub
parent 70ff6821af
commit d231b240f1
5 changed files with 71 additions and 34 deletions

View File

@ -1,5 +1,9 @@
## 0.11.1 ## 12.0
* Changes the behavior of `--packages-for-branch` on main/master to run for
packages changed in the last commit, rather than running for all packages.
This allows CI to test the same filtered set of packages in post-submit as are
tested in presubmit.
* Adds a `fix` command to run `dart fix --apply` in target packages. * Adds a `fix` command to run `dart fix --apply` in target packages.
## 0.11 ## 0.11

View File

@ -103,7 +103,7 @@ class GitVersionFinder {
<String>['merge-base', '--fork-point', 'FETCH_HEAD', 'HEAD'], <String>['merge-base', '--fork-point', 'FETCH_HEAD', 'HEAD'],
throwOnError: false); throwOnError: false);
final String stdout = (baseShaFromMergeBase.stdout as String? ?? '').trim(); final String stdout = (baseShaFromMergeBase.stdout as String? ?? '').trim();
final String stderr = (baseShaFromMergeBase.stdout as String? ?? '').trim(); final String stderr = (baseShaFromMergeBase.stderr as String? ?? '').trim();
if (stderr.isNotEmpty || stdout.isEmpty) { if (stderr.isNotEmpty || stdout.isEmpty) {
baseShaFromMergeBase = await baseGitDir baseShaFromMergeBase = await baseGitDir
.runCommand(<String>['merge-base', 'FETCH_HEAD', 'HEAD']); .runCommand(<String>['merge-base', 'FETCH_HEAD', 'HEAD']);

View File

@ -84,9 +84,8 @@ abstract class PackageCommand extends Command<void> {
'Cannot be combined with $_packagesArg.\n', 'Cannot be combined with $_packagesArg.\n',
hide: true); hide: true);
argParser.addFlag(_packagesForBranchArg, argParser.addFlag(_packagesForBranchArg,
help: help: 'This runs on all packages changed in the last commit on main '
'This runs on all packages (equivalent to no package selection flag)\n' '(or master), and behaves like --run-on-changed-packages on '
'on main (or master), and behaves like --run-on-changed-packages on '
'any other branch.\n\n' 'any other branch.\n\n'
'Cannot be combined with $_packagesArg.\n\n' 'Cannot be combined with $_packagesArg.\n\n'
'This is intended for use in CI.\n', 'This is intended for use in CI.\n',
@ -311,9 +310,9 @@ abstract class PackageCommand extends Command<void> {
Set<String> packages = Set<String>.from(getStringListArg(_packagesArg)); Set<String> packages = Set<String>.from(getStringListArg(_packagesArg));
final bool runOnChangedPackages; final GitVersionFinder? changedFileFinder;
if (getBoolArg(_runOnChangedPackagesArg)) { if (getBoolArg(_runOnChangedPackagesArg)) {
runOnChangedPackages = true; changedFileFinder = await retrieveVersionFinder();
} else if (getBoolArg(_packagesForBranchArg)) { } else if (getBoolArg(_packagesForBranchArg)) {
final String? branch = await _getBranch(); final String? branch = await _getBranch();
if (branch == null) { if (branch == null) {
@ -321,24 +320,28 @@ abstract class PackageCommand extends Command<void> {
'only be used in a git repository.'); 'only be used in a git repository.');
throw ToolExit(exitInvalidArguments); throw ToolExit(exitInvalidArguments);
} else { } else {
runOnChangedPackages = branch != 'master' && branch != 'main'; // Configure the change finder the correct mode for the branch.
// Log the mode for auditing what was intended to run. final bool lastCommitOnly = branch == 'main' || branch == 'master';
print('--$_packagesForBranchArg: running on ' if (lastCommitOnly) {
'${runOnChangedPackages ? 'changed' : 'all'} packages'); // Log the mode to make it easier to audit logs to see that the
// intended diff was used.
print('--$_packagesForBranchArg: running on default branch; '
'using parent commit as the diff base.');
changedFileFinder = GitVersionFinder(await gitDir, 'HEAD~');
} else {
changedFileFinder = await retrieveVersionFinder();
}
} }
} else { } else {
runOnChangedPackages = false; changedFileFinder = null;
} }
final Set<String> excludedPackageNames = getExcludedPackageNames(); if (changedFileFinder != null) {
final String baseSha = await changedFileFinder.getBaseSha();
if (runOnChangedPackages) {
final GitVersionFinder gitVersionFinder = await retrieveVersionFinder();
final String baseSha = await gitVersionFinder.getBaseSha();
print( print(
'Running for all packages that have changed relative to "$baseSha"\n'); 'Running for all packages that have diffs relative to "$baseSha"\n');
final List<String> changedFiles = final List<String> changedFiles =
await gitVersionFinder.getChangedFiles(); await changedFileFinder.getChangedFiles();
if (!_changesRequireFullTest(changedFiles)) { if (!_changesRequireFullTest(changedFiles)) {
packages = _getChangedPackageNames(changedFiles); packages = _getChangedPackageNames(changedFiles);
} }
@ -362,6 +365,7 @@ abstract class PackageCommand extends Command<void> {
.childDirectory('third_party') .childDirectory('third_party')
.childDirectory('packages'); .childDirectory('packages');
final Set<String> excludedPackageNames = getExcludedPackageNames();
for (final Directory dir in <Directory>[ for (final Directory dir in <Directory>[
packagesDir, packagesDir,
if (thirdPartyPackagesDirectory.existsSync()) thirdPartyPackagesDirectory, if (thirdPartyPackagesDirectory.existsSync()) thirdPartyPackagesDirectory,

View File

@ -1,7 +1,7 @@
name: flutter_plugin_tools name: flutter_plugin_tools
description: Productivity utils for flutter/plugins and flutter/packages description: Productivity utils for flutter/plugins and flutter/packages
repository: https://github.com/flutter/plugins/tree/main/script/tool repository: https://github.com/flutter/plugins/tree/main/script/tool
version: 0.11.0 version: 0.12.0
dependencies: dependencies:
args: ^2.1.0 args: ^2.1.0

View File

@ -523,7 +523,7 @@ packages/plugin1/CHANGELOG
output, output,
containsAllInOrder(<Matcher>[ containsAllInOrder(<Matcher>[
contains( contains(
'Running for all packages that have changed relative to "main"'), 'Running for all packages that have diffs relative to "main"'),
])); ]));
expect(command.plugins, unorderedEquals(<String>[plugin1.path])); expect(command.plugins, unorderedEquals(<String>[plugin1.path]));
@ -732,13 +732,17 @@ packages/b_package/lib/src/foo.dart
}); });
group('--packages-for-branch', () { group('--packages-for-branch', () {
test('only tests changed packages on a branch', () async { test('only tests changed packages relative to the merge base on a branch',
() async {
processRunner.mockProcessesForExecutable['git-diff'] = <Process>[ processRunner.mockProcessesForExecutable['git-diff'] = <Process>[
MockProcess(stdout: 'packages/plugin1/plugin1.dart'), MockProcess(stdout: 'packages/plugin1/plugin1.dart'),
]; ];
processRunner.mockProcessesForExecutable['git-rev-parse'] = <Process>[ processRunner.mockProcessesForExecutable['git-rev-parse'] = <Process>[
MockProcess(stdout: 'a-branch'), MockProcess(stdout: 'a-branch'),
]; ];
processRunner.mockProcessesForExecutable['git-merge-base'] = <Process>[
MockProcess(stdout: 'abc123'),
];
final RepositoryPackage plugin1 = final RepositoryPackage plugin1 =
createFakePlugin('plugin1', packagesDir); createFakePlugin('plugin1', packagesDir);
createFakePlugin('plugin2', packagesDir); createFakePlugin('plugin2', packagesDir);
@ -750,11 +754,20 @@ packages/b_package/lib/src/foo.dart
expect( expect(
output, output,
containsAllInOrder(<Matcher>[ containsAllInOrder(<Matcher>[
contains('--packages-for-branch: running on changed packages'), contains(
'Running for all packages that have diffs relative to "abc123"'),
])); ]));
// Ensure that it's diffing against the merge-base.
expect(
processRunner.recordedCalls,
contains(
const ProcessCall(
'git-diff', <String>['--name-only', 'abc123', 'HEAD'], null),
));
}); });
test('tests all packages on main', () async { test('only tests changed packages relative to the previous commit on main',
() async {
processRunner.mockProcessesForExecutable['git-diff'] = <Process>[ processRunner.mockProcessesForExecutable['git-diff'] = <Process>[
MockProcess(stdout: 'packages/plugin1/plugin1.dart'), MockProcess(stdout: 'packages/plugin1/plugin1.dart'),
]; ];
@ -763,19 +776,27 @@ packages/b_package/lib/src/foo.dart
]; ];
final RepositoryPackage plugin1 = final RepositoryPackage plugin1 =
createFakePlugin('plugin1', packagesDir); createFakePlugin('plugin1', packagesDir);
final RepositoryPackage plugin2 =
createFakePlugin('plugin2', packagesDir); createFakePlugin('plugin2', packagesDir);
final List<String> output = await runCapturingPrint( final List<String> output = await runCapturingPrint(
runner, <String>['sample', '--packages-for-branch']); runner, <String>['sample', '--packages-for-branch']);
expect(command.plugins, expect(command.plugins, unorderedEquals(<String>[plugin1.path]));
unorderedEquals(<String>[plugin1.path, plugin2.path]));
expect( expect(
output, output,
containsAllInOrder(<Matcher>[ containsAllInOrder(<Matcher>[
contains('--packages-for-branch: running on all packages'), contains('--packages-for-branch: running on default branch; '
'using parent commit as the diff base'),
contains(
'Running for all packages that have diffs relative to "HEAD~"'),
])); ]));
// Ensure that it's diffing against the prior commit.
expect(
processRunner.recordedCalls,
contains(
const ProcessCall(
'git-diff', <String>['--name-only', 'HEAD~', 'HEAD'], null),
));
}); });
test('tests all packages on master', () async { test('tests all packages on master', () async {
@ -787,19 +808,27 @@ packages/b_package/lib/src/foo.dart
]; ];
final RepositoryPackage plugin1 = final RepositoryPackage plugin1 =
createFakePlugin('plugin1', packagesDir); createFakePlugin('plugin1', packagesDir);
final RepositoryPackage plugin2 =
createFakePlugin('plugin2', packagesDir); createFakePlugin('plugin2', packagesDir);
final List<String> output = await runCapturingPrint( final List<String> output = await runCapturingPrint(
runner, <String>['sample', '--packages-for-branch']); runner, <String>['sample', '--packages-for-branch']);
expect(command.plugins, expect(command.plugins, unorderedEquals(<String>[plugin1.path]));
unorderedEquals(<String>[plugin1.path, plugin2.path]));
expect( expect(
output, output,
containsAllInOrder(<Matcher>[ containsAllInOrder(<Matcher>[
contains('--packages-for-branch: running on all packages'), contains('--packages-for-branch: running on default branch; '
'using parent commit as the diff base'),
contains(
'Running for all packages that have diffs relative to "HEAD~"'),
])); ]));
// Ensure that it's diffing against the prior commit.
expect(
processRunner.recordedCalls,
contains(
const ProcessCall(
'git-diff', <String>['--name-only', 'HEAD~', 'HEAD'], null),
));
}); });
test('throws if getting the branch fails', () async { test('throws if getting the branch fails', () async {