Fix template name collision between new and legacy frontend plugin templates

The legacy frontend plugin template had the same name (`frontend-plugin`) as
the new frontend plugin template, causing a conflict error when both were shown
(e.g. when the frontend system could not be auto-detected). Rename the legacy
template to `frontend-plugin-legacy` so both can coexist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Vincenzo Scamporlino <vincenzos@spotify.com>
This commit is contained in:
Vincenzo Scamporlino
2026-03-30 23:22:03 +02:00
parent feaf3d1ade
commit e38bcefb99
4 changed files with 14 additions and 26 deletions
+1 -1
View File
@@ -2,4 +2,4 @@
'@backstage/cli-module-new': patch
---
Rename the legacy `frontend-plugin` to `legacy-frontend-plugin`
Rename the legacy `frontend-plugin` to `frontend-plugin-legacy`
@@ -374,14 +374,14 @@ describe('loadPortableTemplateConfig', () => {
},
node_modules: Object.fromEntries(
defaultTemplates.map(t => {
// Match the real behavior: both frontend-plugin and legacy-frontend-plugin
// have the same template name "frontend-plugin"
const name = t.endsWith('/legacy-frontend-plugin')
? 'frontend-plugin'
? 'frontend-plugin-legacy'
: basename(t);
return [
t,
{ [TEMPLATE_FILE_NAME]: `name: ${name}\nrole: web-library\n` },
{
[TEMPLATE_FILE_NAME]: `name: ${name}\nrole: web-library\n`,
},
];
}),
),
@@ -398,14 +398,7 @@ describe('loadPortableTemplateConfig', () => {
expect(templateNames).toContain('frontend-plugin-module');
expect(templateNames).toContain('backend-plugin');
// Legacy template should be filtered out
expect(templateNames).not.toContain('legacy-frontend-plugin');
// The frontend-plugin in the list should be from the new template, not legacy
const frontendPlugin = config.templatePointers.find(
t => t.name === 'frontend-plugin',
);
expect(frontendPlugin?.target).toContain('/frontend-plugin/');
expect(frontendPlugin?.target).not.toContain('/legacy-frontend-plugin/');
expect(templateNames).not.toContain('frontend-plugin-legacy');
});
it('should filter out new frontend templates for legacy frontend system apps', async () => {
@@ -424,11 +417,13 @@ describe('loadPortableTemplateConfig', () => {
node_modules: Object.fromEntries(
defaultTemplates.map(t => {
const name = t.endsWith('/legacy-frontend-plugin')
? 'frontend-plugin'
? 'frontend-plugin-legacy'
: basename(t);
return [
t,
{ [TEMPLATE_FILE_NAME]: `name: ${name}\nrole: web-library\n` },
{
[TEMPLATE_FILE_NAME]: `name: ${name}\nrole: web-library\n`,
},
];
}),
),
@@ -441,17 +436,12 @@ describe('loadPortableTemplateConfig', () => {
expect(config.isUsingDefaultTemplates).toBe(true);
const templateNames = config.templatePointers.map(t => t.name);
// Legacy template should be present (shown as "frontend-plugin")
expect(templateNames).toContain('frontend-plugin');
// Legacy template should be present
expect(templateNames).toContain('frontend-plugin-legacy');
expect(templateNames).toContain('backend-plugin');
// New frontend templates should be filtered out
expect(templateNames).not.toContain('frontend-plugin');
expect(templateNames).not.toContain('frontend-plugin-module');
// The frontend-plugin in the list should be from the legacy template
const frontendPlugin = config.templatePointers.find(
t => t.name === 'frontend-plugin',
);
expect(frontendPlugin?.target).toContain('/legacy-frontend-plugin/');
});
it('should not filter templates when using explicit configuration', async () => {
@@ -177,8 +177,6 @@ export async function loadPortableTemplateConfig(
);
// Auto-filter frontend templates based on detected frontend system.
// This must happen before the conflict check since both the new and legacy
// frontend plugin templates have the same name, but only one will be shown.
if (isUsingDefaultTemplates) {
const frontendSystem = await detectFrontendSystem(basePath);
templatePointerEntries = filterTemplateEntriesForFrontendSystem(
@@ -1,4 +1,4 @@
name: legacy-frontend-plugin
name: frontend-plugin-legacy
role: frontend-plugin
description: A new frontend plugin (legacy system)
values: