Skip to content
This repository was archived by the owner on Jan 27, 2026. It is now read-only.

Commit 611e23a

Browse files
authored
fix: role retrieval bug in the metadata command, and introduce backstage support-versions check during export. (#2661)
* fix: wrong role retrieval which could break the metadata command behavior. Signed-off-by: David Festal <dfestal@redhat.com> * fix: add a backstage supported version check and fix Signed-off-by: David Festal <dfestal@redhat.com> * Fix maintainability issues raised by Sonar Signed-off-by: David Festal <dfestal@redhat.com> --------- Signed-off-by: David Festal <dfestal@redhat.com>
1 parent 95af580 commit 611e23a

File tree

4 files changed

+59
-4
lines changed

4 files changed

+59
-4
lines changed

.changeset/giant-spies-tap.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@janus-idp/cli": patch
3+
---
4+
5+
Fix wrong role retrieval which could break the `metadata` command behavior.

.changeset/swift-plums-join.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@janus-idp/cli": patch
3+
---
4+
5+
Check backstage the `support-versions` field value during export, and fix it if possible while emitting a warning.

packages/cli/src/commands/export-dynamic-plugin/command.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { PackageRoles } from '@backstage/cli-node';
1919
import chalk from 'chalk';
2020
import { OptionValues } from 'commander';
2121
import fs from 'fs-extra';
22+
import * as semver from 'semver';
2223

2324
import path from 'path';
2425

@@ -74,5 +75,49 @@ export async function command(opts: OptionValues): Promise<void> {
7475
});
7576
}
7677

78+
await checkBackstageSupportedVersions(targetPath);
79+
7780
await applyDevOptions(opts, rawPkg.name, roleInfo, targetPath);
7881
}
82+
83+
async function checkBackstageSupportedVersions(targetPath: string) {
84+
const targetPackageFile = path.join(targetPath, 'package.json');
85+
const targetPackage = await fs.readJSON(targetPackageFile);
86+
const supportedVersions: string | undefined =
87+
targetPackage.backstage?.['supported-versions'];
88+
const backstageJson = path.join(paths.targetRoot, '/backstage.json');
89+
if (!fs.existsSync(backstageJson)) {
90+
return;
91+
}
92+
const backstageVersion: string = (await fs.readJSON(backstageJson)).version;
93+
if (supportedVersions) {
94+
const singleVersionInSupportedVersions = semver.valid(
95+
supportedVersions,
96+
true,
97+
);
98+
const supportedVersionsRange = singleVersionInSupportedVersions
99+
? `~${supportedVersions}`
100+
: supportedVersions;
101+
102+
if (semver.subset(`~${backstageVersion}`, supportedVersionsRange)) {
103+
return;
104+
}
105+
const errorMessage = `The ${chalk.cyan('backstage.supported-versions')} field in the package descriptor is not compatible with the backstage version specified in the ${chalk.cyan('backstage.json')} file: ${chalk.cyan(supportedVersions)} vs ${chalk.cyan(backstageVersion)}.`;
106+
if (!singleVersionInSupportedVersions) {
107+
throw new Error(errorMessage);
108+
}
109+
Task.log(
110+
chalk.yellow(
111+
`${errorMessage}\nOverriding it with ${chalk.cyan(backstageVersion)}.`,
112+
),
113+
);
114+
} else {
115+
Task.log(
116+
`Filling ${chalk.cyan('supported-versions')} with ${chalk.cyan(backstageVersion)}.`,
117+
);
118+
}
119+
targetPackage.backstage['supported-versions'] = backstageVersion;
120+
await fs.writeJSON(targetPackageFile, targetPackage, {
121+
spaces: 2,
122+
});
123+
}

packages/cli/src/commands/package-dynamic-plugins/command.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export async function command(opts: OptionValues): Promise<void> {
3737
paths.resolveTarget('package.json'),
3838
)) as PackageJson;
3939
const workspacePackageRole =
40-
PackageRoles.detectRoleFromPackage(workspacePackage);
40+
PackageRoles.getRoleFromPackage(workspacePackage);
4141
const workspacePackageRoleInfo =
4242
workspacePackageRole !== undefined
4343
? PackageRoles.getRoleInfo(workspacePackageRole)
@@ -166,13 +166,13 @@ export async function command(opts: OptionValues): Promise<void> {
166166
);
167167
} catch (err) {
168168
Task.log(
169-
`Encountered an error parsing configuration at ${pluginConfigPath}, no example configuration will be displayed`,
169+
`Encountered an error parsing configuration at ${pluginConfigPath}, no example configuration will be displayed. The error was ${err}`,
170170
);
171171
}
172172
}
173173
} catch (err) {
174174
Task.log(
175-
`Encountered an error copying static assets for plugin ${packageFilePath}, the plugin will not be packaged. The error was ${err}`,
175+
`Encountered an error copying static assets for plugin ${packageFilePath}, the plugin will not be packaged. The error was ${err}`,
176176
);
177177
}
178178
}
@@ -279,7 +279,7 @@ async function discoverPluginPackages() {
279279
packageJsonFilePaths.map(async packageFilePath => {
280280
const packageJson = (await fs.readJson(packageFilePath)) as PackageJson;
281281
const packageRole = PackageRoles.getRoleFromPackage(packageJson);
282-
const packageRoleInfo = PackageRoles.getRoleInfo(packageRole || '');
282+
const packageRoleInfo = PackageRoles.getRoleInfo(packageRole ?? '');
283283
const packageDirectory = path.dirname(packageFilePath);
284284
return {
285285
packageDirectory,

0 commit comments

Comments
 (0)