From b149e9429030ac8aa53d939390faccc8272e7d03 Mon Sep 17 00:00:00 2001 From: Phil Kuang Date: Fri, 15 Oct 2021 16:08:06 -0400 Subject: [PATCH] fix(catalog:register): support optional locations Signed-off-by: Phil Kuang --- .changeset/fair-jeans-heal.md | 5 ++ .../actions/builtin/catalog/register.test.ts | 38 ++++++++++++++ .../actions/builtin/catalog/register.ts | 52 +++++++++++++------ 3 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 .changeset/fair-jeans-heal.md diff --git a/.changeset/fair-jeans-heal.md b/.changeset/fair-jeans-heal.md new file mode 100644 index 0000000000..48c0adbfc2 --- /dev/null +++ b/.changeset/fair-jeans-heal.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Allow `catalog:register` action to register optional locations 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 eb704c729e..e1f8823487 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 @@ -174,4 +174,42 @@ describe('catalog:register', () => { 'http://foo/var', ); }); + + it('should ignore failures when dry running the location in the catalog if `optional` is set', async () => { + addLocation + .mockResolvedValueOnce({ + entities: [], + }) + .mockRejectedValueOnce(new Error('Not found')); + await action.handler({ + ...mockContext, + input: { + catalogInfoUrl: 'http://foo/var', + optional: true, + }, + }); + + 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( + 'catalogInfoUrl', + 'http://foo/var', + ); + }); }); 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 9d4961bfd9..0c08131925 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/register.ts @@ -27,8 +27,8 @@ export function createCatalogRegisterAction(options: { const { catalogClient, integrations } = options; return createTemplateAction< - | { catalogInfoUrl: string } - | { repoContentsUrl: string; catalogInfoPath?: string } + | { catalogInfoUrl: string; optional?: boolean } + | { repoContentsUrl: string; catalogInfoPath?: string; optional?: boolean } >({ id: 'catalog:register', description: @@ -46,6 +46,12 @@ export function createCatalogRegisterAction(options: { 'An absolute URL pointing to the catalog info file location', type: 'string', }, + optional: { + title: 'Optional', + description: + 'Permit the registered location to optionally exist. Default: false', + type: 'boolean', + }, }, }, { @@ -64,6 +70,12 @@ export function createCatalogRegisterAction(options: { 'A relative path from the repo root pointing to the catalog info file, defaults to /catalog-info.yaml', type: 'string', }, + optional: { + title: 'Optional', + description: + 'Permit the registered location to optionally exist. Default: false', + type: 'boolean', + }, }, }, ], @@ -100,22 +112,30 @@ export function createCatalogRegisterAction(options: { }, 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 > 0) { - const { entities } = result; - const entity = - entities.find(e => !e.metadata.name.startsWith('generated-')) ?? - entities[0]; - ctx.output('entityRef', stringifyEntityRef(entity)); + try { + const result = await catalogClient.addLocation( + { + dryRun: true, + type: 'url', + target: catalogInfoUrl, + }, + ctx.token ? { token: ctx.token } : {}, + ); + + 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)); + } + } catch (e) { + if (!input.optional) { + throw e; + } } + ctx.output('catalogInfoUrl', catalogInfoUrl); }, });