From 1e06afd80c16f344f483da725a1ba0e72d9ae3f2 Mon Sep 17 00:00:00 2001 From: Thomas Cardonne Date: Thu, 8 May 2025 12:14:05 +0200 Subject: [PATCH] feat(backend-defaults): use isGlob in GithubUrlReader to match glob patterns Signed-off-by: Thomas Cardonne --- .changeset/cool-groups-fail.md | 8 ++++++++ docs/integrations/github/discovery.md | 2 +- packages/backend-defaults/package.json | 2 ++ .../entrypoints/urlReader/lib/GithubUrlReader.test.ts | 11 +++++++++++ .../src/entrypoints/urlReader/lib/GithubUrlReader.ts | 3 ++- yarn.lock | 2 ++ 6 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 .changeset/cool-groups-fail.md diff --git a/.changeset/cool-groups-fail.md b/.changeset/cool-groups-fail.md new file mode 100644 index 0000000000..459358676b --- /dev/null +++ b/.changeset/cool-groups-fail.md @@ -0,0 +1,8 @@ +--- +'@backstage/backend-defaults': patch +--- + +`GithubUrlReader`'s search detects glob-patterns supported by `minimatch`, instead of just detecting +`*` and `?` characters. + +For example, this allows to search for patterns like `{C,c}atalog-info.yaml`. diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index 354569cdb6..c1dfd62ce5 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -148,7 +148,7 @@ If you do so, `default` will be used as provider ID. - **`catalogPath`** _(optional)_: Default: `/catalog-info.yaml`. Path where to look for `catalog-info.yaml` files. - You can use wildcards - `*` or `**` - to search the path and/or the filename. + You can use wildcards - `*`, `**` or a glob pattern supported by [`minimatch`](https://github.com/isaacs/minimatch) - to search the path and/or the filename. Wildcards cannot be used if the `validateLocationsExist` option is set to `true`. - **`filters`** _(optional)_: - **`branch`** _(optional)_: diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 093ebdc422..c865f66067 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -163,6 +163,7 @@ "fs-extra": "^11.2.0", "git-url-parse": "^15.0.0", "helmet": "^6.0.0", + "is-glob": "^4.0.3", "jose": "^5.0.0", "keyv": "^5.2.1", "knex": "^3.0.0", @@ -200,6 +201,7 @@ "@types/compression": "^1.7.5", "@types/concat-stream": "^2.0.0", "@types/http-errors": "^2.0.0", + "@types/is-glob": "^4.0.2", "@types/node-forge": "^1.3.0", "@types/pg-format": "^1.0.5", "@types/yauzl": "^2.10.0", diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts index 4e1c5a2d08..861b3ad7cb 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts @@ -923,6 +923,17 @@ describe('GithubUrlReader', () => { await expect(r5.files[0].content()).resolves.toEqual( Buffer.from('# Test\n'), ); + + const r6 = await reader.search( + `${baseUrl}/backstage/mock/tree/main/{M,m}kdocs.yml`, + ); + expect(r6.files.length).toBe(1); + expect(r6.files[0].url).toBe( + `${baseUrl}/backstage/mock/tree/main/mkdocs.yml`, + ); + await expect(r6.files[0].content()).resolves.toEqual( + Buffer.from('site_name: Test\n'), + ); } // eslint-disable-next-line jest/expect-expect diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.ts index 1dbade8477..fe0bd08fec 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.ts @@ -45,6 +45,7 @@ import { import { ReadTreeResponseFactory, ReaderFactory } from './types'; import { ReadUrlResponseFactory } from './ReadUrlResponseFactory'; import { parseLastModified } from './util'; +import isGlob from 'is-glob'; export type GhRepoResponse = RestEndpointMethodTypes['repos']['get']['response']['data']; @@ -186,7 +187,7 @@ export class GithubUrlReader implements UrlReaderService { const { filepath } = parseGitUrl(url); // If it's a direct URL we use readUrl instead - if (!filepath?.match(/[*?]/)) { + if (!isGlob(filepath)) { try { const data = await this.readUrl(url, options); diff --git a/yarn.lock b/yarn.lock index f700a3af06..800d6463b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3587,6 +3587,7 @@ __metadata: "@types/cors": "npm:^2.8.6" "@types/express": "npm:^4.17.6" "@types/http-errors": "npm:^2.0.0" + "@types/is-glob": "npm:^4.0.2" "@types/node-forge": "npm:^1.3.0" "@types/pg-format": "npm:^1.0.5" "@types/yauzl": "npm:^2.10.0" @@ -3605,6 +3606,7 @@ __metadata: git-url-parse: "npm:^15.0.0" helmet: "npm:^6.0.0" http-errors: "npm:^2.0.0" + is-glob: "npm:^4.0.3" jose: "npm:^5.0.0" keyv: "npm:^5.2.1" knex: "npm:^3.0.0"