diff --git a/.changeset/tricky-geckos-protect.md b/.changeset/tricky-geckos-protect.md new file mode 100644 index 0000000000000..c4e1abc58c1cd --- /dev/null +++ b/.changeset/tricky-geckos-protect.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Fixed a bug where the `catalog:register` action would not return any entity when running towards recent versions of the catalog. diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts index 68e2450ca0607..eb704c729ea0c 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.test.ts @@ -67,25 +67,98 @@ describe('catalog:register', () => { }); it('should register location in catalog', async () => { - addLocation.mockResolvedValue({ - entities: [ - { - metadata: { - namespace: 'default', - name: 'test', - }, - kind: 'Component', - } as Entity, - ], + addLocation + .mockResolvedValueOnce({ + entities: [], + }) + .mockResolvedValueOnce({ + entities: [ + { + metadata: { + namespace: 'default', + name: 'test', + }, + kind: 'Component', + } as Entity, + ], + }); + await action.handler({ + ...mockContext, + input: { + catalogInfoUrl: 'http://foo/var', + }, }); + + expect(addLocation).toHaveBeenNthCalledWith( + 1, + { + type: 'url', + target: 'http://foo/var', + }, + {}, + ); + expect(addLocation).toHaveBeenNthCalledWith( + 2, + { + dryRun: true, + type: 'url', + target: 'http://foo/var', + }, + {}, + ); + + expect(mockContext.output).toBeCalledWith( + 'entityRef', + 'component:default/test', + ); + expect(mockContext.output).toBeCalledWith( + 'catalogInfoUrl', + 'http://foo/var', + ); + }); + + it('should register location in catalog and return the entity and not the generated location', async () => { + addLocation + .mockResolvedValueOnce({ + entities: [], + }) + .mockResolvedValueOnce({ + entities: [ + { + metadata: { + namespace: 'default', + name: 'generated-1238', + }, + kind: 'Location', + } as Entity, + { + metadata: { + namespace: 'default', + name: 'test', + }, + kind: 'Component', + } as Entity, + ], + }); await action.handler({ ...mockContext, input: { catalogInfoUrl: 'http://foo/var', }, }); - expect(addLocation).toBeCalledWith( + + expect(addLocation).toHaveBeenNthCalledWith( + 1, + { + type: 'url', + target: 'http://foo/var', + }, + {}, + ); + expect(addLocation).toHaveBeenNthCalledWith( + 2, { + dryRun: true, type: 'url', target: 'http://foo/var', }, @@ -94,7 +167,7 @@ describe('catalog:register', () => { expect(mockContext.output).toBeCalledWith( 'entityRef', - 'Component:default/test', + 'component:default/test', ); expect(mockContext.output).toBeCalledWith( 'catalogInfoUrl', diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts index 70170b8b90322..9d4961bfd90f9 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts @@ -17,7 +17,7 @@ import { InputError } from '@backstage/errors'; import { ScmIntegrations } from '@backstage/integration'; import { CatalogApi } from '@backstage/catalog-client'; -import { getEntityName } from '@backstage/catalog-model'; +import { stringifyEntityRef } from '@backstage/catalog-model'; import { createTemplateAction } from '../../createTemplateAction'; export function createCatalogRegisterAction(options: { @@ -93,18 +93,30 @@ export function createCatalogRegisterAction(options: { ctx.logger.info(`Registering ${catalogInfoUrl} in the catalog`); + await catalogClient.addLocation( + { + type: 'url', + target: catalogInfoUrl, + }, + ctx.token ? { token: ctx.token } : {}, + ); const result = await catalogClient.addLocation( { + dryRun: true, type: 'url', target: catalogInfoUrl, }, ctx.token ? { token: ctx.token } : {}, ); - if (result.entities.length >= 1) { - const { kind, name, namespace } = getEntityName(result.entities[0]); - ctx.output('entityRef', `${kind}:${namespace}/${name}`); - ctx.output('catalogInfoUrl', catalogInfoUrl); + + if (result.entities.length > 0) { + const { entities } = result; + const entity = + entities.find(e => !e.metadata.name.startsWith('generated-')) ?? + entities[0]; + ctx.output('entityRef', stringifyEntityRef(entity)); } + ctx.output('catalogInfoUrl', catalogInfoUrl); }, }); }