From c7ce76729883d156dc4510821b5f8d293646e3d1 Mon Sep 17 00:00:00 2001 From: Craigory Coppola Date: Fri, 5 May 2023 15:45:55 -0400 Subject: [PATCH] feat(repo): add CI check for valid codeowners patterns (#16729) --- .circleci/config.yml | 2 +- CODEOWNERS | 14 ++++++----- package.json | 2 ++ scripts/check-codeowners.ts | 49 +++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 scripts/check-codeowners.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index 06ef8f7d7e..6ed175e56a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -194,7 +194,7 @@ jobs: pnpm nx-cloud record -- nx format:check --base=$NX_BASE --head=$NX_HEAD & pids+=($!) - pnpm nx run-many -t check-imports check-commit check-lock-files depcheck --parallel=1 --no-dte & + pnpm nx run-many -t check-imports check-commit check-lock-files depcheck check-codeowners --parallel=1 --no-dte & pids+=($!) pnpm nx affected --target=lint --base=$NX_BASE --head=$NX_HEAD --parallel=3 & diff --git a/CODEOWNERS b/CODEOWNERS index 0a607f6f43..a6624018dd 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -11,7 +11,7 @@ pnpm-lock.yaml @FrozenPandaz @vsavkin @AgentEnder @jaysoo @JamesHenry /docs @bcabanes @isaacplmann @juristr /docs/nx-cloud @StalkAltan @rarmatei @isaacplmann @juristr @bcabanes /graph/** @philipjfulcher @FrozenPandaz @bcabanes -/images/shared @bcabanes @isaacplmann @juristr +/images @bcabanes @isaacplmann @juristr /nx-dev/** @bcabanes @isaacplmann @juristr /typedoc-theme @bcabanes @isaacplmann @@ -76,7 +76,6 @@ pnpm-lock.yaml @FrozenPandaz @vsavkin @AgentEnder @jaysoo @JamesHenry /docs/shared/packages/web/** @jaysoo @mandarini @ndcunningham /docs/shared/packages/webpack/** @jaysoo @mandarini @ndcunningham /docs/shared/packages/esbuild/** @nartc @jaysoo @ndcunningham -/docs/shared/packages/rollup/** @jaysoo @mandarini @ndcunningham /docs/shared/packages/vite/** @jaysoo @mandarini @ndcunningham /packages/js/** @nartc @jaysoo @ndcunningham /e2e/js/** @nartc @jaysoo @ndcunningham @@ -121,14 +120,17 @@ pnpm-lock.yaml @FrozenPandaz @vsavkin @AgentEnder @jaysoo @JamesHenry /docs/generated/devkit/** @FrozenPandaz @AgentEnder /docs/generated/packages/devkit/** @FrozenPandaz @AgentEnder /packages/devkit/** @FrozenPandaz @AgentEnder -/packages/devkit/index.ts @FrozenPandaz @vsavkin +/packages/devkit/index.js @FrozenPandaz @vsavkin +/packages/devkit/index.d.ts @FrozenPandaz @vsavkin +/packages/devkit/public-api.ts @FrozenPandaz @vsavkin +/packages/devkit/nx.ts @FrozenPandaz @vsavkin /packages/devkit/src/utils/module-federation @jaysoo @Coly010 # Nx-Plugin /docs/generated/packages/plugin/** @AgentEnder @FrozenPandaz /docs/shared/packages/plugin/** @AgentEnder @FrozenPandaz @isaacplmann @juristr /packages/plugin/** @AgentEnder @FrozenPandaz -/e2e/nx-plugin/** @AgentEnder @FrozenPandaz +/e2e/plugin/** @AgentEnder @FrozenPandaz ## Core /docs/generated/packages/nx/** @vsavkin @FrozenPandaz @AgentEnder @@ -136,7 +138,7 @@ pnpm-lock.yaml @FrozenPandaz @vsavkin @AgentEnder @jaysoo @JamesHenry /packages/nx/** @vsavkin @FrozenPandaz @AgentEnder /packages/nx/src/adapter @AgentEnder @leosvelperez /packages/nx/src/native @vsavkin @FrozenPandaz @Cammisuli -/packages/nx/src/lock-file @meeroslav @FrozenPandaz +/packages/nx/src/plugins/js/lock-file @meeroslav @FrozenPandaz /packages/nx/src/command-line/init/implementation/angular/** @Coly010 @leosvelperez @FrozenPandaz /e2e/nx-init/src/nx-init-angular.test.ts @Coly010 @leosvelperez /packages/nx/src/command-line/init/implementation/react/** @jaysoo @xiongemi @mandarini @@ -170,7 +172,7 @@ pnpm-lock.yaml @FrozenPandaz @vsavkin @AgentEnder @jaysoo @JamesHenry # Global Files project.json @FrozenPandaz @vsavkin jest.config.ts @barbados-clemens @FrozenPandaz -jest.preset.ts @barbados-clemens @FrozenPandaz +jest.preset.js @barbados-clemens @FrozenPandaz # Overrides - These are applied last, so override any matches above. docs/generated/manifests/* @bcabanes @FrozenPandaz @jaysoo @AgentEnder @isaacplmann @juristr diff --git a/package.json b/package.json index 72554410ed..3ac14d420e 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "check-imports": "node ./scripts/check-imports.js", "check-lock-files": "node ./scripts/check-lock-files.js", "check-documentation-map": "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/documentation/map-link-checker.ts", + "check-codeowners": "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/check-codeowners.ts", "e2e-start-local-registry": "node ./scripts/e2e-start-local-registry.js", "e2e-build-package-publish": "ts-node -P ./scripts/tsconfig.e2e.json ./scripts/e2e-build-package-publish.ts", "nx-release": "ts-node -P ./scripts/tsconfig.release.json ./scripts/nx-release", @@ -339,6 +340,7 @@ "check-format", "check-imports", "check-lock-files", + "check-codeowners", "depcheck", "documentation" ] diff --git a/scripts/check-codeowners.ts b/scripts/check-codeowners.ts new file mode 100644 index 0000000000..73c16d6549 --- /dev/null +++ b/scripts/check-codeowners.ts @@ -0,0 +1,49 @@ +import * as fg from 'fast-glob'; +import * as path from 'path'; +import * as fs from 'fs'; +import { output } from '@nx/devkit'; + +async function main() { + const codeowners = fs.readFileSync( + path.join(__dirname, '../CODEOWNERS'), + 'utf-8' + ); + const codeownersLines = codeowners + .split('\n') + .filter((line) => line.trim().length > 0 && !line.startsWith('#')); + + const errors: string[] = []; + + for (const line of codeownersLines) { + // This is perhaps a bit naive, but it should + // work for all paths and patterns that do not + // contain spaces. + const specifiedPattern = line.split(' ')[0]; + let foundMatchingFiles = false; + + const patternsToCheck = specifiedPattern.startsWith('/') + ? [`.${specifiedPattern}`] + : [`./${specifiedPattern}`, `**/${specifiedPattern}`]; + + for (const pattern of patternsToCheck) { + foundMatchingFiles ||= + fg.sync(pattern, { + ignore: ['node_modules', 'dist', 'build', '.git'], + cwd: path.join(__dirname, '..'), + onlyFiles: false, + }).length > 0; + } + if (!foundMatchingFiles) { + errors.push(specifiedPattern); + } + } + if (errors.length > 0) { + output.error({ + title: `The following patterns in CODEOWNERS do not match any files:`, + bodyLines: errors.map((e) => `- ${e}`), + }); + process.exit(1); + } +} + +main();