diff --git a/.changeset/orange-beans-float.md b/.changeset/orange-beans-float.md new file mode 100644 index 0000000000..7e31277890 --- /dev/null +++ b/.changeset/orange-beans-float.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-github': patch +--- + +Fix bug in root repo import where catalog-info.yaml.hcl file is found by search and breaks the import diff --git a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts index b745dd37ba..e5c7eb5896 100644 --- a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts +++ b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.test.ts @@ -112,7 +112,7 @@ describe('GithubLocationAnalyzer', () => { it('should analyze', async () => { octokit.search.code.mockImplementation((opts: { q: string }) => { - if (opts.q === 'filename:catalog-info.yaml repo:foo/bar') { + if (opts.q === 'filename:catalog-info.yaml extension:yaml repo:foo/bar') { return Promise.resolve({ data: { items: [{ path: 'catalog-info.yaml' }], total_count: 1 }, }); @@ -139,7 +139,7 @@ describe('GithubLocationAnalyzer', () => { it('should use the provided entity filename for search', async () => { octokit.search.code.mockImplementation((opts: { q: string }) => { - if (opts.q === 'filename:anvil.yaml repo:foo/bar') { + if (opts.q === 'filename:anvil.yaml extension:yaml repo:foo/bar') { return Promise.resolve({ data: { items: [{ path: 'anvil.yaml' }], total_count: 1 }, }); @@ -162,4 +162,30 @@ describe('GithubLocationAnalyzer', () => { target: 'https://github.com/foo/bar/blob/my_default_branch/anvil.yaml', }); }); + + it('should use the provided entity file extension in search query only if present', async () => { + octokit.search.code.mockImplementation((opts: { q: string }) => { + if (opts.q === 'filename:.gitignore repo:foo/bar') { + return Promise.resolve({ + data: { items: [{ path: '.gitignore' }], total_count: 1 }, + }); + } + return Promise.reject(); + }); + + const analyzer = new GithubLocationAnalyzer({ + discovery: mockDiscoveryApi, + auth: mockAuthService, + config, + }); + const result = await analyzer.analyze({ + url: 'https://github.com/foo/bar', + catalogFilename: '.gitignore', + }); + + expect(result.existing[0].location).toEqual({ + type: 'url', + target: 'https://github.com/foo/bar/blob/my_default_branch/.gitignore', + }); + }); }); diff --git a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts index 2648b1bcdc..7e6ac73054 100644 --- a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts +++ b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts @@ -22,7 +22,7 @@ import { ScmIntegrations, } from '@backstage/integration'; import { Octokit } from '@octokit/rest'; -import { trimEnd } from 'lodash'; +import { isEmpty, trimEnd } from 'lodash'; import parseGitUrl from 'git-url-parse'; import { AnalyzeOptions, @@ -35,6 +35,7 @@ import { } from '@backstage/backend-common'; import { Config } from '@backstage/config'; import { AuthService } from '@backstage/backend-plugin-api'; +import { extname } from 'path'; /** @public */ export type GithubLocationAnalyzerOptions = { @@ -76,8 +77,12 @@ export class GithubLocationAnalyzer implements ScmLocationAnalyzer { const { owner, name: repo } = parseGitUrl(url); const catalogFile = catalogFilename || 'catalog-info.yaml'; + const extension = extname(catalogFile); + const extensionQuery = !isEmpty(extension) + ? `extension:${extension.replace('.', '')}` + : ''; - const query = `filename:${catalogFile} repo:${owner}/${repo}`; + const query = `filename:${catalogFile} ${extensionQuery} repo:${owner}/${repo}`; const integration = this.integrations.github.byUrl(url); if (!integration) {