From 935c646e897a5b1e976927f807998abc860e8dde Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 15 Mar 2026 01:12:43 +0100 Subject: [PATCH] Fix CLI module discovery and create-app test mock Resolve CLI module entry points relative to the target project root rather than relying on bare module name resolution. This ensures modules are found even when the CLI package is symlinked from a separate location, such as in the E2E test workspace setup. Also add the missing cli-module-* entries to the create-app tasks test mock that were omitted in a previous commit. Signed-off-by: Patrik Oldsberg Made-with: Cursor --- packages/cli/src/index.ts | 4 ++-- packages/cli/src/wiring/discoverCliModules.ts | 9 ++++++--- packages/create-app/src/lib/tasks.test.ts | 11 +++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 489287c3f2..f5056f8ba3 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -24,8 +24,8 @@ import { discoverCliModules } from './wiring/discoverCliModules'; const discoveredModules = discoverCliModules(); if (discoveredModules.length > 0) { - for (const moduleName of discoveredModules) { - initializer.add(import(moduleName)); + for (const resolvedPath of discoveredModules) { + initializer.add(import(resolvedPath)); } } else { // No CLI modules found in the project root; fall back to the built-in diff --git a/packages/cli/src/wiring/discoverCliModules.ts b/packages/cli/src/wiring/discoverCliModules.ts index dac80c1344..fb5e8c7469 100644 --- a/packages/cli/src/wiring/discoverCliModules.ts +++ b/packages/cli/src/wiring/discoverCliModules.ts @@ -23,8 +23,10 @@ import { resolve as resolvePath } from 'node:path'; * Scans the target project root's package.json for dependencies that are CLI * modules (packages with `backstage.role === 'cli-module'`). * - * Returns the names of discovered CLI module packages, or an empty array if - * none are found or the project root cannot be read. + * Returns the resolved entry point paths of discovered CLI module packages, + * or an empty array if none are found or the project root cannot be read. + * The paths are resolved relative to the project root to ensure they can be + * imported regardless of where the CLI code itself is located. */ export function discoverCliModules(): string[] { const rootDir = targetPaths.rootDir; @@ -54,7 +56,8 @@ export function discoverCliModules(): string[] { }); const depPkg = JSON.parse(fs.readFileSync(depPkgPath, 'utf8')); if (PackageRoles.getRoleFromPackage(depPkg) === 'cli-module') { - modules.push(depName); + const resolvedPath = require.resolve(depName, { paths: [rootDir] }); + modules.push(resolvedPath); } } catch { // Skip packages that can't be resolved or read diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index be6852e3ab..0115790b81 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -50,6 +50,17 @@ jest.mock('./versions', () => ({ packageVersions: { root: '1.2.3', '@backstage/cli': '1.0.0', + '@backstage/cli-module-auth': '1.0.0', + '@backstage/cli-module-build': '1.0.0', + '@backstage/cli-module-config': '1.0.0', + '@backstage/cli-module-create-github-app': '1.0.0', + '@backstage/cli-module-info': '1.0.0', + '@backstage/cli-module-lint': '1.0.0', + '@backstage/cli-module-maintenance': '1.0.0', + '@backstage/cli-module-migrate': '1.0.0', + '@backstage/cli-module-new': '1.0.0', + '@backstage/cli-module-test-jest': '1.0.0', + '@backstage/cli-module-translations': '1.0.0', '@backstage/backend-defaults': '1.0.0', '@backstage/backend-tasks': '1.0.0', '@backstage/catalog-model': '1.0.0',