From c17fa10182574f52491ecdf1295a526f9d62e781 Mon Sep 17 00:00:00 2001 From: Yuri Titi Date: Tue, 7 Mar 2023 16:11:02 -0300 Subject: [PATCH] feat(@backstage/plugin-catalog-backend-module-azure): Add branch filter support Signed-off-by: Yuri Titi --- .changeset/modern-colts-exercise.md | 5 +++ docs/integrations/azure/discovery.md | 9 +++-- .../src/lib/azure.ts | 1 + .../AzureDevOpsEntityProvider.test.ts | 40 +++++++++++++++++-- .../providers/AzureDevOpsEntityProvider.ts | 10 +++-- .../src/providers/config.test.ts | 24 ++++++++++- .../src/providers/config.ts | 2 + .../src/providers/types.ts | 1 + 8 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 .changeset/modern-colts-exercise.md diff --git a/.changeset/modern-colts-exercise.md b/.changeset/modern-colts-exercise.md new file mode 100644 index 0000000000..d869945870 --- /dev/null +++ b/.changeset/modern-colts-exercise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-azure': minor +--- + +Add branch filter support diff --git a/docs/integrations/azure/discovery.md b/docs/integrations/azure/discovery.md index 6cb135900e..d96b7d84ab 100644 --- a/docs/integrations/azure/discovery.md +++ b/docs/integrations/azure/discovery.md @@ -61,6 +61,7 @@ catalog: host: selfhostedazure.yourcompany.com organization: myorg project: myproject + branch: development ``` The parameters available are: @@ -70,6 +71,7 @@ The parameters available are: - **`project:`** _(optional)_ Your project slug. Wildcards are supported as show on the examples above. If not set, all projects will be searched. For a project name containing spaces, use both single and double quotes as in `project: '"My Project Name"'`. - **`repository:`** _(optional)_ The repository name. Wildcards are supported as show on the examples above. If not set, all repositories will be searched. - **`path:`** _(optional)_ Where to find catalog-info.yaml files. Defaults to /catalog-info.yaml. +- **`branch:`** _(optional)_ The branch name to use. - **`schedule`** _(optional)_: - **`frequency`**: How often you want the task to run. The system does its best to avoid overlapping invocations. @@ -80,9 +82,10 @@ The parameters available are: - **`scope`** _(optional)_: `'global'` or `'local'`. Sets the scope of concurrency control. -_Note:_ the path parameter follows the same rules as the search on Azure DevOps -web interface. For more details visit the -[official search documentation](https://docs.microsoft.com/en-us/azure/devops/project/search/get-started-search?view=azure-devops). +_Note:_ + +- The path parameter follows the same rules as the search on Azure DevOps web interface. For more details visit the [official search documentation](https://docs.microsoft.com/en-us/azure/devops/project/search/get-started-search?view=azure-devops). +- The branch parameters need that the branch desired it`s added on 'Searchable branches' on Azure DevOps Repositories As this provider is not one of the default providers, you will first need to install the Azure catalog plugin: diff --git a/plugins/catalog-backend-module-azure/src/lib/azure.ts b/plugins/catalog-backend-module-azure/src/lib/azure.ts index 0c96d133d3..714090d5bc 100644 --- a/plugins/catalog-backend-module-azure/src/lib/azure.ts +++ b/plugins/catalog-backend-module-azure/src/lib/azure.ts @@ -34,6 +34,7 @@ export interface CodeSearchResultItem { project: { name: string; }; + branch?: string; } const isCloud = (host: string) => host === 'dev.azure.com'; diff --git a/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.test.ts b/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.test.ts index dff1164899..53919b9bb4 100644 --- a/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.test.ts +++ b/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.test.ts @@ -105,9 +105,13 @@ describe('AzureDevOpsEntityProvider', () => { await (taskDef.fn as () => Promise)(); const expectedEntities = codeSearchResults.map(item => { - const url = encodeURI( - `${expectedBaseUrl}/_git/${item.repository.name}?path=${item.path}`, - ); + const url = item.branch + ? encodeURI( + `${expectedBaseUrl}/_git/${item.repository.name}?path=${item.path}&version=GBmybranch`, + ) + : encodeURI( + `${expectedBaseUrl}/_git/${item.repository.name}?path=${item.path}`, + ); return { entity: { apiVersion: 'backstage.io/v1alpha1', @@ -177,6 +181,36 @@ describe('AzureDevOpsEntityProvider', () => { ); }); + // eslint-disable-next-line jest/expect-expect + it('single mutation when repos use branch filter', async () => { + return expectMutation( + 'allReposSingleFile', + { + organization: 'myorganization', + project: 'myproject', + branch: 'mybranch', + }, + [ + { + fileName: 'catalog-info.yaml', + path: '/catalog-info.yaml', + repository: { + name: 'myrepo', + }, + project: { + name: 'myproject', + }, + branch: 'mybranch', + }, + ], + 'https://dev.azure.com/myorganization/myproject', + { + 'myrepo?path=/catalog-info.yaml': + 'generated-589e8cc47341987c7a34f5291791151fa64f7754', + }, + ); + }); + // eslint-disable-next-line jest/expect-expect it('single mutation when multiple repos have multiple files', async () => { return expectMutation( diff --git a/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.ts b/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.ts index 788b9c2f05..457a9e74f2 100644 --- a/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.ts +++ b/plugins/catalog-backend-module-azure/src/providers/AzureDevOpsEntityProvider.ts @@ -177,8 +177,12 @@ export class AzureDevOpsEntityProvider implements EntityProvider { private createObjectUrl(file: CodeSearchResultItem): string { const baseUrl = `https://${this.config.host}/${this.config.organization}/${file.project.name}`; - return encodeURI( - `${baseUrl}/_git/${file.repository.name}?path=${file.path}`, - ); + + let fullUrl = `${baseUrl}/_git/${file.repository.name}?path=${file.path}`; + if (this.config.branch) { + fullUrl += `&version=GB${this.config.branch}`; + } + + return encodeURI(fullUrl); } } diff --git a/plugins/catalog-backend-module-azure/src/providers/config.test.ts b/plugins/catalog-backend-module-azure/src/providers/config.test.ts index a09079f1c3..02dbaab90e 100644 --- a/plugins/catalog-backend-module-azure/src/providers/config.test.ts +++ b/plugins/catalog-backend-module-azure/src/providers/config.test.ts @@ -44,17 +44,30 @@ describe('readAzureDevOpsConfigs', () => { }, }, }; + const provider5 = { + host: 'azure.mycompany.com', + organization: 'mycompany', + project: 'myproject', + branch: 'mybranch', + }; + const config = { catalog: { providers: { - azureDevOps: { provider1, provider2, provider3, provider4 }, + azureDevOps: { + provider1, + provider2, + provider3, + provider4, + provider5, + }, }, }, }; const actual = readAzureDevOpsConfigs(new ConfigReader(config)); - expect(actual).toHaveLength(4); + expect(actual).toHaveLength(5); expect(actual[0]).toEqual({ ...provider1, path: '/catalog-info.yaml', @@ -85,5 +98,12 @@ describe('readAzureDevOpsConfigs', () => { frequency: Duration.fromISO(provider4.schedule.frequency), }, }); + expect(actual[4]).toEqual({ + ...provider5, + branch: 'mybranch', + path: '/catalog-info.yaml', + repository: '*', + id: 'provider5', + }); }); }); diff --git a/plugins/catalog-backend-module-azure/src/providers/config.ts b/plugins/catalog-backend-module-azure/src/providers/config.ts index c84c242488..3c10a50863 100644 --- a/plugins/catalog-backend-module-azure/src/providers/config.ts +++ b/plugins/catalog-backend-module-azure/src/providers/config.ts @@ -41,6 +41,7 @@ function readAzureDevOpsConfig(id: string, config: Config): AzureDevOpsConfig { const project = config.getString('project'); const host = config.getOptionalString('host') || 'dev.azure.com'; const repository = config.getOptionalString('repository') || '*'; + const branch = config.getOptionalString('branch'); const path = config.getOptionalString('path') || '/catalog-info.yaml'; const schedule = config.has('schedule') @@ -53,6 +54,7 @@ function readAzureDevOpsConfig(id: string, config: Config): AzureDevOpsConfig { organization, project, repository, + branch, path, schedule, }; diff --git a/plugins/catalog-backend-module-azure/src/providers/types.ts b/plugins/catalog-backend-module-azure/src/providers/types.ts index b22a8551a5..3cd827b380 100644 --- a/plugins/catalog-backend-module-azure/src/providers/types.ts +++ b/plugins/catalog-backend-module-azure/src/providers/types.ts @@ -22,6 +22,7 @@ export type AzureDevOpsConfig = { organization: string; project: string; repository: string; + branch?: string; path: string; schedule?: TaskScheduleDefinition; };