Commit Graph

1838 Commits

Author SHA1 Message Date
Patrik Oldsberg 4d081452b1 Address review feedback from freben
- Use cli-defaults instead of listing individual CLI modules in
  create-app template and root package.json
- Move nodeTransform config files from cli-module-build to cli-node
  to avoid cross-module direct imports
- Rename cli-module-create-github-app to cli-module-github
- Start createCliModule init chain with Promise.resolve()
- Deduplicate exitWithError in runCliModule.ts
- Extract shared isCommandNodeHidden to @internal/cli
- Add explanatory comment for fromArray deduplication field
- Restore error for cli role packages missing bin in runCliExtraction

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-16 12:55:22 +01:00
Patrik Oldsberg 7879215cca Add CLI module deduplication and improve conflict reporting
Individual CLI modules now silently take precedence over array-sourced
modules (e.g. from cli-defaults) when their commands overlap. Conflict
errors between non-array modules include both package names for easier
debugging.

Commands reference their parent module instead of storing a raw package
name string. createCliModule now validates that packageJson has a name.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-15 21:16:00 +01:00
Patrik Oldsberg 7781ae5911 Add @backstage/cli-defaults package
Introduces a new `@backstage/cli-defaults` package that re-exports all
standard CLI modules as a single array, simplifying dependency management
for consumers. The CLI's `CliInitializer` is updated to support array
exports alongside single module exports. The create-app template,
changesets, and CLI fallback are updated to use `@backstage/cli-defaults`
instead of listing 11 individual modules.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-15 15:01:35 +01:00
Patrik Oldsberg 7db7ca5714 Convert discovered module paths to file URLs for Windows compatibility
On Windows, require.resolve() returns paths like D:\...\index.cjs.js
which when passed to import() causes ERR_UNSUPPORTED_ESM_URL_SCHEME
because the D: prefix is interpreted as a URL protocol. Use
pathToFileURL() to produce proper file:// URLs.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-15 13:35:12 +01:00
Patrik Oldsberg 935c646e89 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 <poldsberg@gmail.com>
Made-with: Cursor
2026-03-15 01:12:43 +01:00
Patrik Oldsberg d806b0cc9f Add automatic discovery of CLI modules from project dependencies
The CLI now scans the project root's dependencies and devDependencies
for packages with the cli-module role, loading them automatically.
Falls back to the built-in set with a deprecation warning when no
modules are found. Updated create-app templates and the monorepo root
to include all CLI modules as explicit devDependencies.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:43 +01:00
Patrik Oldsberg a151ad0814 Split CLI modules into separate packages
Extract each CLI module from packages/cli/src/modules/ into its own
package under packages/cli-module-*. This enables independent versioning
and clearer dependency boundaries for each CLI capability.

Module mapping:
- auth → @backstage/cli-module-auth
- build → @backstage/cli-module-build
- config → @backstage/cli-module-config
- create-github-app → @backstage/cli-module-create-github-app
- info → @backstage/cli-module-info
- lint → @backstage/cli-module-lint
- maintenance → @backstage/cli-module-maintenance
- migrate → @backstage/cli-module-migrate
- new → @backstage/cli-module-new
- test → @backstage/cli-module-test-jest
- translations → @backstage/cli-module-translations

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:43 +01:00
Patrik Oldsberg 18012b5802 Rename CliPlugin to CliModule and cli-plugin role to cli-module
Rename createCliPlugin to createCliModule, CliPlugin to CliModule, and
the cli-plugin package role to cli-module to better distinguish CLI
modules from other plugin types.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:43 +01:00
Patrik Oldsberg 1929a95b97 Rename BackstageCommand to CliCommand and CommandContext to CliCommandContext
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:43 +01:00
Patrik Oldsberg 7d055ef0c4 Merge cli-plugin-api into cli-node
Move createCliPlugin and related types from the standalone
@backstage/cli-plugin-api package into @backstage/cli-node and
remove the now-empty package.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:43 +01:00
Patrik Oldsberg a90939e138 Use opaque types for command graph nodes
Switch CommandGraph and CliInitializer to use OpaqueCommandTreeNode and
OpaqueCommandLeafNode from @internal/cli instead of raw $$type markers.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:42 +01:00
Patrik Oldsberg 28a438a9f2 Add documentation to cli-plugin-api and remove CliFeature type
Add thorough TSDoc comments to createCliPlugin, BackstageCommand,
CommandContext, and CliPlugin. Remove the CliFeature type alias in
favor of using CliPlugin directly.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:42 +01:00
Patrik Oldsberg 7e6ad01a21 Refine cli-plugin-api: use packageJson, inline types, rename context fields
Replace pluginId with packageJson input for createCliPlugin, remove
CommandExecuteFn type alias by inlining it, and rename
CommandContext.info.description to info.name.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:42 +01:00
Patrik Oldsberg 2e5f189cfa Add @internal/cli package for opaque CLI types
Move OpaqueCliPlugin to a new @internal/cli inline package, following the
same pattern as @internal/frontend. Both cli-plugin-api and cli import it
directly, and it gets bundled into their dists at build time.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:42 +01:00
Patrik Oldsberg d6caf7f13b Slim cli-plugin-api to only export createCliPlugin
Move error handling and lazy utilities back to @backstage/cli since they
are host-only concerns. The cli-plugin-api internals subpath provides
isCliPlugin and initializeCliPlugin for the CLI host.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:42 +01:00
Patrik Oldsberg 0be3eab18b cli: initial cli-plugin-api
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-14 12:40:42 +01:00
Patrik Oldsberg 94a885a2ef Add cli-plugin package role
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-03-14 12:39:21 +01:00
Patrik Oldsberg feaf449008 cli: enable --no- prefix negation for boolean flags
Bump cleye to ^2.3.0 (which pulls in type-flag 4.1.0) and enable
booleanFlagNegation: true in all cli() invocations so that boolean
flags automatically support --no-<flag> prefix negation.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-10 17:20:38 +01:00
Ben Lambert d0f4cd215b feat(cli): add auth commands for OIDC login (#32920)
* feat(cli): add auth commands for OIDC login

Signed-off-by: benjdlambert <ben@blam.sh>

* address PR review feedback

- move CIMD check before callback server start
- add try/finally for callback server cleanup
- validate URLs with human-readable errors
- deduplicate config URL candidates
- preserve selected flag on re-authentication
- delete accessToken on logout
- log token refresh to stderr in show command
- fix command descriptions to reference CIMD not DCR
- type keytar as optionalDependency, rename storage paths
- add auth-backend changeset

Signed-off-by: benjdlambert <ben@blam.sh>

* migrate auth module from yargs to cleye pattern

Signed-off-by: benjdlambert <ben@blam.sh>

* address PR review feedback

- consolidate storage imports in auth.ts
- add withMetadataLock to setSelectedInstance
- skip file permission tests on Windows
- clarify changeset endpoint path

Signed-off-by: benjdlambert <ben@blam.sh>

* address review feedback from Rugvip and Copilot

- use stdout for user-facing messages instead of stderr
- remove clientSecret remnants from logout
- make refresh_token optional in token response schema
- add timeout to CIMD metadata fetch
- pass same state to callback server and authorize URL
- remove inaccurate test comment

Signed-off-by: benjdlambert <ben@blam.sh>

* validate state in callback server, add CIMD endpoint tests

- localServer now validates the OAuth state parameter in the request
  handler and returns 400 on mismatch
- Added tests for the CIMD metadata endpoint in OidcRouter covering
  both disabled and enabled cases

Signed-off-by: benjdlambert <ben@blam.sh>

* revert validateRequest to use Zod error details

Signed-off-by: benjdlambert <ben@blam.sh>

* fix callback server hanging by closing keep-alive connections

Signed-off-by: benjdlambert <ben@blam.sh>

* rename secret store service prefix to backstage-cli:auth-instance

Signed-off-by: benjdlambert <ben@blam.sh>

---------

Signed-off-by: benjdlambert <ben@blam.sh>
2026-03-10 13:28:25 +00:00
Johan Persson d14b6e07f1 feat(org,catalog-graph)!: migrate MembersListCard, OwnershipCard, and CatalogGraphCard to BUI (#33177)
* feat(org): migrate MembersListCard to BUI EntityInfoCard

Signed-off-by: Johan Persson <johanopersson@gmail.com>

* feat(org)!: migrate OwnershipCard to BUI EntityInfoCard

Replaced MUI InfoCard with BUI EntityInfoCard in OwnershipCard.
Removed the `variant` and `maxScrollHeight` props since card sizing
and scrolling are now handled by the BUI layout. Wrapped body content
in a flex column div to keep the relations toggle pinned while the
grid scrolls. Updated app-legacy and create-app templates to remove
the dropped `variant` prop.

Signed-off-by: Johan Persson <johanopersson@gmail.com>

* feat(catalog-graph)!: migrate CatalogGraphCard to BUI EntityInfoCard

Replace MUI InfoCard with BUI EntityInfoCard in CatalogGraphCard.
The `variant` prop is removed — card sizing is now handled by the
BUI layout system. The deep link is replaced with a footer Link.

Remove `variant="gridItem"` from all EntityCatalogGraphCard usages
in app-legacy and create-app templates.

Signed-off-by: Johan Persson <johanopersson@gmail.com>

* feat(catalog-react): export useEntityRoute hook

Signed-off-by: Johan Persson <johanopersson@gmail.com>

* fix(cli): update translation extraction test for renamed org keys

Signed-off-by: Johan Persson <johanopersson@gmail.com>

---------

Signed-off-by: Johan Persson <johanopersson@gmail.com>
2026-03-06 16:19:31 +01:00
Patrik Oldsberg d9fb094376 Merge pull request #33061 from backstage/rugvip/migrate-cli-to-cleye
cli: migrate remaining commands from commander to cleye
2026-03-06 15:59:09 +01:00
Patrik Oldsberg 08b0a7f933 Add deprecation warnings for camelCase flag usage
Log a warning to stderr when users pass the camelCase form of flags
that now have kebab-case as the canonical spelling. The old forms
still work (type-flag handles both natively) but users should migrate.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-06 15:13:58 +01:00
Patrik Oldsberg c28e6a7b1c Remove unnecessary deprecation warnings for camelCase flags
type-flag natively supports both camelCase and kebab-case for all
flags, so no deprecation warnings or normalization are needed for
casing variants. Only the --alwaysYarnPack alias (a genuinely
different name) still requires normalization in buildWorkspace.

Also inlined flagDefs at each call site and updated the changeset
to reflect that both flag forms work transparently.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-06 14:52:11 +01:00
Patrik Oldsberg 8da1817584 Inline deprecation warnings and fix package lint parameters
Remove the central warnDeprecatedFlags helper and replace with
module-specific deprecation checks at each call site. This avoids
cross-module dependencies and makes the deprecated flag mappings
explicit where they are consumed.

Also fix buildWorkspace.ts to emit the deprecation warning during
flag normalization (where the old flags are actually intercepted),
and add positional parameter declaration to package lint so that
directories show in help output.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-06 13:50:43 +01:00
Patrik Oldsberg a4e59024c0 Add support for experimental commands in the CLI module API
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-06 13:17:46 +01:00
Patrik Oldsberg 80f1779980 Fix buildWorkspace flag normalization for =value forms
Handle --alwaysPack=value and --alwaysYarnPack=value variants in the
legacy flag normalization, not just the bare flag forms.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-04 10:13:57 +01:00
Patrik Oldsberg e8173b3012 Address review feedback: role.ts, repo start params, test coverage
- Remove unnecessary optional chaining on getRoleInfo().role since it
  throws for unknown roles.
- Add parameters declaration to repo start so [packages...] shows in
  help output.
- Add tests verifying cleye strips Backstage flags from args before
  forwarding to Jest, including legacy camelCase flag support.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-04 10:10:31 +01:00
Patrik Oldsberg 629e9f5558 Add deprecation warnings for old camelCase flag names
Instead of a hard breaking change, the old camelCase flag names
(--baseVersion, --successCache, --successCacheDir, --alwaysPack) still
work via type-flag's built-in camelCase/kebab-case mapping, but now
print a deprecation warning pointing to the new kebab-case spelling.

Downgrades the changeset from minor (breaking) to patch.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-03 11:11:26 +01:00
Patrik Oldsberg b45ee80104 Keep boolean | string for inspect types, map in command handlers
Move the empty-string-to-boolean conversion from cleye's String type
into the command handlers so that startPackage/runBackend keep their
existing boolean | string interface.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-03 11:11:26 +01:00
Patrik Oldsberg 2946e8e4c6 Remove custom inspect flag handling, switch repo test to cleye
- Use cleye's `type: String` for --inspect/--inspect-brk instead of
  custom extractInspectFlags pre-processing in both package start and
  repo start commands.
- Switch repo test from node:util parseArgs to cleye so that --help
  shows Backstage-specific flags rather than dumping Jest's full help.
- Fix create-github-app help output to include <github-org> positional.
- Update downstream inspect types from `boolean | string` to `string`.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-03 11:11:26 +01:00
Patrik Oldsberg 18d09fe581 Address Copilot review feedback
- Handle --inspect/--inspect-brk optional host value by extracting
  them from raw args before passing to cleye (supports both bare
  --inspect and --inspect=host:port forms)
- Change require flag from [String] to String in package start since
  downstream only accepts a single value
- Preserve legacy --alwaysYarnPack alias in build-workspace command
- Update changeset to mention camelCase → kebab-case flag changes

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-03-03 11:11:26 +01:00
Patrik Oldsberg f01dbf301e Use shell-quote for script argument parsing
Replace custom splitShellArgs with shell-quote's parse() for proper
shell argument tokenization in createScriptOptionsParser.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-03-03 11:11:26 +01:00
Patrik Oldsberg eb73feac15 Address review feedback and regenerate API reports
- Handle quoted arguments in createScriptOptionsParser using a proper
  shell-like splitter instead of naive whitespace splitting
- Pass CommandContext directly in bump tests instead of using a helper
- Regenerate cli-report.md

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-03-03 11:11:26 +01:00
Patrik Oldsberg ff4a45ac01 Migrate remaining CLI commands from commander to cleye
All command handlers in the CLI now use cleye or node:util.parseArgs
for argument parsing instead of commander. The top-level command
registration in CliInitializer still uses commander, but all individual
command implementations are now independent of it.

Modules migrated: build, lint, test, maintenance, migrate, new, and
create-github-app. Also replaced createScriptOptionsParser in both
build and lint modules to use node:util.parseArgs instead of commander.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-03-03 11:11:26 +01:00
Patrik Oldsberg 11764eff33 cli: remove stale lib/lazy.ts from previous stash
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-02 20:50:26 +01:00
Patrik Oldsberg e8a5a20f7d cli: split pack.ts into prepack.ts and postpack.ts
Each file now has a default export matching the CommandExecuteFn
pattern, removing the need for import wrapping in the loader.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-02 20:49:56 +01:00
Patrik Oldsberg f867152e8b cli: fix prepack and postpack commands CJS compat
Switch the prepack and postpack commands from using a direct
dynamic import() to the execute.loader pattern, which properly
handles CJS double-wrapping of module exports.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-03-02 17:33:35 +01:00
Patrik Oldsberg 03f7e74fe1 Merge pull request #33036 from backstage/rugvip/cli-execute-loader
cli: add lazy loader pattern for command execution
2026-02-27 15:36:12 +01:00
Patrik Oldsberg acb2714ca8 Merge pull request #33025 from backstage/rugvip/move-transform-tests
cli: move transform tests into the build module
2026-02-27 14:08:22 +01:00
Gabriel Dugny 3187a7a441 Merge remote-tracking branch 'origin/master' into package-workspaces 2026-02-27 12:05:03 +01:00
Patrik Oldsberg 2481126013 Remove setBlocking calls and simplify file-redirect approach
Remove fragile process.stdout._handle.setBlocking calls from CLI test
commands. Revert the preload workaround in repo-tools since the root
cause is removed.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-02-27 08:48:19 +01:00
Patrik Oldsberg fab449cf9e cli: lint fix
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
2026-02-27 00:08:18 +01:00
Patrik Oldsberg d5779e525c Fix CLI report generation and --help handling for loader-based commands
Add cleye-based --help handling to all commands using the loader pattern.
Update the CLI report parser to support cleye's USAGE: and FLAGS: sections.
Revert accidental backstage.role addition to eslint-plugin.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-02-26 20:31:55 +01:00
Patrik Oldsberg 0d2d0f2e07 Add lazy loader pattern for CLI command execution
Extend `BackstageCommand.execute` to accept either a direct function or a
`{ loader }` object for lazy loading command implementations. Convert
several build and migrate commands to use the new pattern. Switch from
`program.parse` to `program.parseAsync` to properly await async actions.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-02-26 19:56:57 +01:00
Patrik Oldsberg 264159ef21 Move transform tests into the build module
Move the transform tests from packages/cli/src/tests/transforms/ into
packages/cli/src/modules/build/tests/transforms/ so that the build
module is self-contained and can eventually become its own package.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-02-26 13:27:30 +01:00
Patrik Oldsberg beab3cc456 cli: eliminate src/lib/ directory and last cross-module import
Split version.ts into two locations:
- Template version provider moved to modules/new/lib/version.ts
- CLI version info moved to wiring/version.ts

Remove publishPreflightCheck from repo fix command (still runs during
package prepack). Fix build module self-references to use shorter
within-module paths.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-02-25 23:36:30 +01:00
Patrik Oldsberg 09eb6b5187 Address further review feedback
- Rename hasYarnPlugin -> hasBackstageYarnPlugin for clarity
- Change SuccessCache.create to accept an options object

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-02-25 20:17:47 +01:00
Patrik Oldsberg 968570bbb5 Address review feedback
- Remove cli changeset, piggy-back on existing ones
- Rename getHasYarnPlugin -> hasYarnPlugin(workspaceDir?)
- Make SuccessCache constructor private, add static create()
- Consolidate duplicate @backstage/cli-node imports

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-02-25 20:17:47 +01:00
Patrik Oldsberg 3c811bf8a9 cli-node, cli: move yarnPlugin and SuccessCache to cli-node
Move `getHasYarnPlugin` and `SuccessCache` from `@backstage/cli` internal
modules to `@backstage/cli-node` as public exports, making them available
for reuse by other CLI tooling.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
2026-02-25 20:17:22 +01:00
Patrik Oldsberg a611d22986 Merge pull request #33007 from backstage/rugvip/cli-split-loadCliConfig
cli: split loadCliConfig into separate build and config implementations
2026-02-25 19:52:50 +01:00