diff --git a/plugins/catalog-import/src/api/CatalogImportClient.test.ts b/plugins/catalog-import/src/api/CatalogImportClient.test.ts index 3c277bdf2a..df44ec94c4 100644 --- a/plugins/catalog-import/src/api/CatalogImportClient.test.ts +++ b/plugins/catalog-import/src/api/CatalogImportClient.test.ts @@ -556,6 +556,9 @@ describe('CatalogImportClient', () => { describe('submitPullRequest', () => { it('should create GitHub pull request', async () => { + catalogApi.validateEntity.mockResolvedValueOnce({ + valid: true, + }); await expect( catalogImportClient.submitPullRequest({ repositoryUrl: 'https://github.com/backstage/backstage', @@ -584,7 +587,7 @@ describe('CatalogImportClient', () => { location: 'https://github.com/backstage/backstage/blob/main/catalog-info.yaml', }); - + expect(catalogApi.validateEntity).toHaveBeenCalledTimes(1); expect( (new Octokit().git.createRef as any as jest.Mock).mock.calls[0][0], ).toEqual({ @@ -617,6 +620,9 @@ describe('CatalogImportClient', () => { }); }); it('Submit Pull Request with invalid component name', async () => { + const ErrorMessage = + 'Policy check failed for component:default/invalid name; caused by Error: "metadata.name" is not valid; expected a string that is sequences of [a-zA-Z0-9] separated by any of [-_.], at most 63 characters in total but found "invalid name". To learn more about catalog file format, visit: https://github.com/backstage/backstage/blob/master/docs/architecture-decisions/adr002-default-catalog-file-format.md'; + catalogApi.validateEntity.mockRejectedValueOnce(new Error(ErrorMessage)); await expect( catalogImportClient.submitPullRequest({ repositoryUrl: 'https://github.com/acme-corp/our-awesome-api', @@ -640,11 +646,12 @@ describe('CatalogImportClient', () => { title: 'A title/message', body: 'A body', }), - ).rejects.toThrow( - 'Component name: Must start and end with an alphanumeric character, and contain only alphanumeric characters, hyphens, underscores, and periods. Maximum length is 63 characters.', - ); + ).rejects.toThrow(ErrorMessage); }); it('should create GitHub pull request with custom filename and branch name', async () => { + catalogApi.validateEntity.mockResolvedValueOnce({ + valid: true, + }); const entityFilename = 'anvil.yaml'; const pullRequestBranchName = 'anvil-integration'; diff --git a/plugins/catalog-import/src/api/CatalogImportClient.ts b/plugins/catalog-import/src/api/CatalogImportClient.ts index faddd615d4..b76454eb17 100644 --- a/plugins/catalog-import/src/api/CatalogImportClient.ts +++ b/plugins/catalog-import/src/api/CatalogImportClient.ts @@ -177,30 +177,32 @@ the component will become available.\n\nFor more information, read an \ }): Promise<{ link: string; location: string }> { const { repositoryUrl, fileContent, title, body } = options; const parseData = YAML.parse(fileContent); - const { - metadata: { name }, - } = parseData; - if (!isValidComponentName(name)) { - throw new Error( - 'Component name: Must start and end with an alphanumeric character, and contain only alphanumeric characters, hyphens, underscores, and periods. Maximum length is 63 characters.', + try { + const validationResponse = await this.catalogApi.validateEntity( + parseData, + `url:${repositoryUrl}`, ); - } - const ghConfig = getGithubIntegrationConfig( - this.scmIntegrationsApi, - repositoryUrl, - ); - - if (ghConfig) { - return await this.submitGitHubPrToRepo({ - ...ghConfig, + if (!validationResponse.valid) { + throw new Error(validationResponse.errors[0].message); + } + const ghConfig = getGithubIntegrationConfig( + this.scmIntegrationsApi, repositoryUrl, - fileContent, - title, - body, - }); - } + ); - throw new Error('unimplemented!'); + if (ghConfig) { + return await this.submitGitHubPrToRepo({ + ...ghConfig, + repositoryUrl, + fileContent, + title, + body, + }); + } + throw new Error('unimplemented!'); + } catch (err) { + throw err; + } } // TODO: this could be part of the catalog api @@ -361,12 +363,3 @@ function formatHttpErrorMessage( ) { return `${message}, received http response status code ${error.status}: ${error.message}`; } - -function isValidComponentName(componentName: string) { - return ( - typeof componentName === 'string' && - componentName.length >= 1 && - componentName.length <= 63 && - /^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$/.test(componentName) - ); -}