[ftr] Speed up FTR code owner check (#205093)

## Summary

Switch to one matcher w/ all code owner patterns rather than separate
matchers for each code owner pattern. Reduces the run time of
`scripts/check_ftr_code_owners.js` by ~10x.

### Before
```console
▶ node scripts/check_ftr_code_owners.js
 info Reading CODEOWNERS file
 info Checking ownership for 8653 test files (this will take a while)
 info Ownership check complete (took 18.89 s)
 succ All test files have a code owner. 🥳
```

#### After
```console
▶ node scripts/check_ftr_code_owners.js
 info Checked 8653 test files in 1.59s
 succ All test files have a code owner 🥳
```
This commit is contained in:
David Olaru 2025-01-02 17:10:20 +00:00 committed by GitHub
parent de0dc52824
commit a0eebb82c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 63 additions and 73 deletions

View file

@ -69,8 +69,6 @@ export { getUrl } from './src/jest/get_url';
export { runCheckJestConfigsCli } from './src/jest/run_check_jest_configs_cli';
export { runCheckFtrCodeOwnersCli } from './src/functional_test_runner/run_check_ftr_code_owners';
export { runJest } from './src/jest/run';
export * from './src/kbn_archiver_cli';

View file

@ -0,0 +1,48 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { run } from '@kbn/dev-cli-runner';
import { createFailError } from '@kbn/dev-cli-errors';
import { getRepoFiles } from '@kbn/get-repo-files';
import { getCodeOwnersEntries } from '@kbn/code-owners';
import ignore from 'ignore';
const TEST_DIRECTORIES = ['test', 'x-pack/test', 'x-pack/test_serverless'];
export async function checkFTRCodeOwnersCLI() {
await run(
async ({ log }) => {
const matcher = ignore().add(
getCodeOwnersEntries()
.filter((entry) => entry.teams.length > 0)
.map((entry) => entry.pattern)
);
const hasOwner = (path: string): boolean => matcher.test(path).ignored;
const testFiles = await getRepoFiles(TEST_DIRECTORIES);
const filesWithoutOwner = testFiles
.filter((repoPath) => !hasOwner(repoPath.repoRel))
.map((repoPath) => repoPath.repoRel);
log.info(`Checked ${testFiles.length} test files in ${process.uptime().toFixed(2)}s`);
if (filesWithoutOwner.length === 0) {
log.success(`All test files have a code owner 🥳`);
return;
}
log.write('Test files without a code owner:');
log.write(filesWithoutOwner.map((i) => ` - ${i}`).join('\n'));
throw createFailError(`Found ${filesWithoutOwner.length} test files without code owner`);
},
{
description: 'Check that all test files are covered by GitHub CODEOWNERS',
}
);
}

View file

@ -16,8 +16,8 @@ import { ToolingLog } from '@kbn/tooling-log';
import { getTimeReporter } from '@kbn/ci-stats-reporter';
import exitHook from 'exit-hook';
import { readConfigFile, EsVersion } from './lib';
import { FunctionalTestRunner } from './functional_test_runner';
import { readConfigFile, EsVersion } from '../lib';
import { FunctionalTestRunner } from '../functional_test_runner';
export function runFtrCli() {
const runStartTime = Date.now();

View file

@ -0,0 +1,11 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
export { runFtrCli } from './ftr';
export { checkFTRCodeOwnersCLI } from './code_owners';

View file

@ -18,6 +18,6 @@ export {
runCheckFtrConfigsCli,
DedicatedTaskRunner,
} from './lib';
export { runFtrCli } from './cli';
export * from './cli';
export * from './lib/docker_servers';
export * from './public_types';

View file

@ -1,67 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { run } from '@kbn/dev-cli-runner';
import { createFailError } from '@kbn/dev-cli-errors';
import { getRepoFiles } from '@kbn/get-repo-files';
import { getOwningTeamsForPath, getCodeOwnersEntries } from '@kbn/code-owners';
const TEST_DIRECTORIES = ['test', 'x-pack/test', 'x-pack/test_serverless'];
const fmtMs = (ms: number) => {
if (ms < 1000) {
return `${Math.round(ms)} ms`;
}
return `${(Math.round(ms) / 1000).toFixed(2)} s`;
};
const fmtList = (list: Iterable<string>) => [...list].map((i) => ` - ${i}`).join('\n');
export async function runCheckFtrCodeOwnersCli() {
run(
async ({ log }) => {
const start = performance.now();
const missingOwners = new Set<string>();
// cache codeowners for quicker lookup
log.info('Reading CODEOWNERS file');
const codeOwnersEntries = getCodeOwnersEntries();
const testFiles = await getRepoFiles(TEST_DIRECTORIES);
log.info(`Checking ownership for ${testFiles.length} test files (this will take a while)`);
for (const { repoRel } of testFiles) {
const owners = getOwningTeamsForPath(repoRel, codeOwnersEntries);
if (owners.length === 0) {
missingOwners.add(repoRel);
}
}
const timeSpent = fmtMs(performance.now() - start);
log.info(`Ownership check complete (took ${timeSpent})`);
if (missingOwners.size) {
log.error(
`The following test files do not have a GitHub code owner:\n${fmtList(missingOwners)}`
);
throw createFailError(
`Found ${missingOwners.size} test files without code owner (checked ${testFiles.length} test files in ${timeSpent})`
);
}
log.success(`All test files have a code owner. 🥳`);
},
{
description: 'Check that all test files are covered by GitHub CODEOWNERS',
}
);
}

View file

@ -8,4 +8,4 @@
*/
require('../src/setup_node_env');
require('@kbn/test').runCheckFtrCodeOwnersCli();
void require('@kbn/test').checkFTRCodeOwnersCLI();