From 8df079681ebb0e764c01e8116dd2e9d6fd3c4e00 Mon Sep 17 00:00:00 2001 From: AmateurMind Date: Thu, 5 Mar 2026 07:22:50 +0530 Subject: [PATCH] fix(catalog-backend-module-gitlab): use correct GitLab API parameter 'topic' instead of 'topics' The GitLab Projects API expects the query parameter 'topic' (singular), but the GitlabDiscoveryEntityProvider was passing 'topics' (plural), causing project filtering by topics to silently fail. - Updated ListProjectOptions interface to use 'topic' instead of 'topics' - Updated GitlabDiscoveryEntityProvider to send 'topic' parameter - Added regression test verifying topic parameter is passed correctly - Fixed template literal formatting in client.ts Fixes #33110 Signed-off-by: AmateurMind --- .changeset/fix-gitlab-topic-filter.md | 5 ++ .../src/lib/client.ts | 2 +- .../GitlabDiscoveryEntityProvider.test.ts | 64 +++++++++++++++++++ .../GitlabDiscoveryEntityProvider.ts | 2 +- 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 .changeset/fix-gitlab-topic-filter.md diff --git a/.changeset/fix-gitlab-topic-filter.md b/.changeset/fix-gitlab-topic-filter.md new file mode 100644 index 0000000000..5d56dcd232 --- /dev/null +++ b/.changeset/fix-gitlab-topic-filter.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-gitlab': patch +--- + +Fixed GitLab project topic filtering by using correct API parameter 'topic' instead of 'topics' diff --git a/plugins/catalog-backend-module-gitlab/src/lib/client.ts b/plugins/catalog-backend-module-gitlab/src/lib/client.ts index df211e4bd0..95b0b4afa7 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/client.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/client.ts @@ -41,7 +41,7 @@ interface ListProjectOptions extends CommonListOptions { archived?: boolean; group?: string; membership?: boolean; - topics?: string; + topic?: string; last_activity_after?: string; } diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts index 3dc979e776..90ee56d5b8 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts @@ -827,3 +827,67 @@ describe('GitlabDiscoveryEntityProvider - simple parameter', () => { }); }); }); + +describe('GitlabDiscoveryEntityProvider - topic parameter', () => { + it('should pass topic (singular) when topics (plural) is configured', async () => { + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'example.com', + apiBaseUrl: 'https://example.com/api/v4', + token: 'test-token', + }, + ], + }, + catalog: { + providers: { + gitlab: { + 'test-id': { + host: 'example.com', + group: 'test-group', + topics: ['topic1', 'topic2'], + }, + }, + }, + }, + }); + + const schedule = new PersistingTaskRunner(); + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + refresh: jest.fn(), + }; + + const provider = GitlabDiscoveryEntityProvider.fromConfig(config, { + logger, + schedule, + })[0]; + + // Mock the GitLabClient listProjects method to verify parameters + const mockListProjects = jest.fn().mockResolvedValue({ + items: [], + nextPage: undefined, + }); + + (provider as any).gitLabClient.listProjects = mockListProjects; + + await provider.connect(entityProviderConnection); + await provider.refresh(logger); + + expect(mockListProjects).toHaveBeenCalledWith({ + group: 'test-group', + page: undefined, + per_page: 50, + archived: false, + topic: 'topic1,topic2', // Correct singular 'topic' parameter + simple: true, + }); + // Verify the old incorrect 'topics' key is NOT present + expect(mockListProjects).not.toHaveBeenCalledWith( + expect.objectContaining({ + topics: expect.anything(), + }), + ); + }); +}); diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts index 40936a4d77..92f4ac797a 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts @@ -383,7 +383,7 @@ export class GitlabDiscoveryEntityProvider implements EntityProvider { per_page: 50, ...(!this.config.includeArchivedRepos && { archived: false }), ...(this.config.membership && { membership: true }), - ...(this.config.topics && { topics: this.config.topics }), + ...(this.config.topics && { topic: this.config.topics }), // Only use simple=true when we don't need to skip forked repos. // The simple=true parameter reduces response size by returning fewer fields, // but it excludes the 'forked_from_project' field which is required for fork detection.