diff --git a/plugins/catalog-backend-module-azure/src/events/analyzeAzureDevOpsWebhookEvent.test.ts b/plugins/catalog-backend-module-azure/src/events/analyzeAzureDevOpsWebhookEvent.test.ts index 4a520aa5fb..943e7ac9f1 100644 --- a/plugins/catalog-backend-module-azure/src/events/analyzeAzureDevOpsWebhookEvent.test.ts +++ b/plugins/catalog-backend-module-azure/src/events/analyzeAzureDevOpsWebhookEvent.test.ts @@ -83,43 +83,43 @@ describe('analyzeAzureDevOpsWebhookEvent', () => { events: [ { type: 'location.created', - url: `${baseRepository.remoteUrl}?path=/catalog-info.yaml&version=GBmain`, + url: `${baseRepository.remoteUrl}?path=/catalog-info.yaml`, context: { commitUrl: `${baseRepository.remoteUrl}/commit/1111111111111111111111111111111111111111`, }, }, { type: 'location.updated', - url: `${baseRepository.remoteUrl}?path=/service.yaml&version=GBmain`, + url: `${baseRepository.remoteUrl}?path=/service.yaml`, context: { commitUrl: `${baseRepository.remoteUrl}/commit/1111111111111111111111111111111111111111`, }, }, { type: 'location.deleted', - url: `${baseRepository.remoteUrl}?path=/obsolete.yaml&version=GBmain`, + url: `${baseRepository.remoteUrl}?path=/obsolete.yaml`, context: { commitUrl: `${baseRepository.remoteUrl}/commit/1111111111111111111111111111111111111111`, }, }, { type: 'location.moved', - fromUrl: `${baseRepository.remoteUrl}?path=/old-name.yaml&version=GBmain`, - toUrl: `${baseRepository.remoteUrl}?path=/new-name.yaml&version=GBmain`, + fromUrl: `${baseRepository.remoteUrl}?path=/old-name.yaml`, + toUrl: `${baseRepository.remoteUrl}?path=/new-name.yaml`, context: { commitUrl: `${baseRepository.remoteUrl}/commit/1111111111111111111111111111111111111111`, }, }, { type: 'location.deleted', - url: `${baseRepository.remoteUrl}?path=/catalog-out.yaml&version=GBmain`, + url: `${baseRepository.remoteUrl}?path=/catalog-out.yaml`, context: { commitUrl: `${baseRepository.remoteUrl}/commit/1111111111111111111111111111111111111111`, }, }, { type: 'location.created', - url: `${baseRepository.remoteUrl}?path=/catalog-in.yaml&version=GBmain`, + url: `${baseRepository.remoteUrl}?path=/catalog-in.yaml`, context: { commitUrl: `${baseRepository.remoteUrl}/commit/1111111111111111111111111111111111111111`, }, @@ -128,17 +128,13 @@ describe('analyzeAzureDevOpsWebhookEvent', () => { }); }); - it('does not double-encode branch names containing slashes', async () => { - const repoWithSlashBranch = { - ...baseRepository, - defaultBranch: 'refs/heads/feature/my-branch', - }; + it('omits version parameter to match default provider URL format', async () => { await expect( analyzeAzureDevOpsWebhookEvent( 'git.push', withPushEvent({ - repository: repoWithSlashBranch, - refUpdates: [{ name: 'refs/heads/feature/my-branch' }], + repository: baseRepository, + refUpdates: [{ name: 'refs/heads/main' }], commits: [ { commitId: 'abc', @@ -155,7 +151,7 @@ describe('analyzeAzureDevOpsWebhookEvent', () => { events: [ { type: 'location.created', - url: `${baseRepository.remoteUrl}?path=/catalog-info.yaml&version=GBfeature/my-branch`, + url: `${baseRepository.remoteUrl}?path=/catalog-info.yaml`, context: { commitUrl: `${baseRepository.remoteUrl}/commit/abc` }, }, ], diff --git a/plugins/catalog-backend-module-azure/src/events/analyzeAzureDevOpsWebhookEvent.ts b/plugins/catalog-backend-module-azure/src/events/analyzeAzureDevOpsWebhookEvent.ts index 9b7f246e12..284c9837a8 100644 --- a/plugins/catalog-backend-module-azure/src/events/analyzeAzureDevOpsWebhookEvent.ts +++ b/plugins/catalog-backend-module-azure/src/events/analyzeAzureDevOpsWebhookEvent.ts @@ -147,13 +147,6 @@ function normalizePath(path: string | undefined): string | undefined { return path.startsWith('/') ? path : `/${path}`; } -function branchNameFromRef(ref: string | undefined): string | undefined { - if (!ref) { - return undefined; - } - return ref.replace(/^refs\/heads\//, ''); -} - function getRepository(resource: JsonObject | undefined): AzureRepository { const repository = asObject(resource?.repository); return { @@ -166,7 +159,6 @@ function getRepository(resource: JsonObject | undefined): AzureRepository { function toLocationUrl(options: { remoteUrl: string | undefined; path: string; - branchRef: string | undefined; }): string | undefined { if (!options.remoteUrl) { return undefined; @@ -174,14 +166,15 @@ function toLocationUrl(options: { // Match the URL format produced by AzureDevOpsEntityProvider.createObjectUrl // which uses encodeURI on the full URL string with path and version as raw - // query parameter values. Using URL/searchParams would produce different - // encoding (e.g. %2F for slashes in branch names) and fail to match existing - // catalog location targets. - const branch = branchNameFromRef(options.branchRef); - let fullUrl = `${options.remoteUrl}?path=${options.path}`; - if (branch) { - fullUrl += `&version=GB${branch}`; - } + // query parameter values. + // + // The version parameter is intentionally omitted here because the entity + // provider only includes it when the user explicitly configures a `branch` + // in the provider config. Since we cannot know at analysis time whether a + // branch was configured, omitting version matches the default provider + // behavior and avoids URL mismatches that would prevent SCM events from + // triggering catalog refreshes. + const fullUrl = `${options.remoteUrl}?path=${options.path}`; return encodeURI(fullUrl); } @@ -200,12 +193,11 @@ function toCommitUrl( function toCatalogScmEventForPathState(options: { repository: AzureRepository; - branchRef: string | undefined; path: string; pathState: PushPathState; isRelevantPath: (path: string) => boolean; }): CatalogScmEvent[] { - const { repository, branchRef, path, pathState, isRelevantPath } = options; + const { repository, path, pathState, isRelevantPath } = options; const commitUrl = toCommitUrl(repository, pathState.commit); const context = commitUrl ? { commitUrl } : undefined; @@ -215,12 +207,10 @@ function toCatalogScmEventForPathState(options: { const fromUrl = toLocationUrl({ remoteUrl: repository.remoteUrl, path: pathState.fromPath, - branchRef, }); const toUrl = toLocationUrl({ remoteUrl: repository.remoteUrl, path, - branchRef, }); if (fromRelevant && toRelevant && fromUrl && toUrl) { @@ -242,7 +232,6 @@ function toCatalogScmEventForPathState(options: { const url = toLocationUrl({ remoteUrl: repository.remoteUrl, path, - branchRef, }); if (!url) { return []; @@ -446,13 +435,9 @@ async function onPushEvent( }; } - const branchRef = - repository.defaultBranch ?? asString(refUpdates[0]?.name) ?? undefined; - const events = Array.from(state.entries()).flatMap(([path, pathState]) => toCatalogScmEventForPathState({ repository, - branchRef, path, pathState, isRelevantPath: options.isRelevantPath, @@ -539,6 +524,11 @@ async function onRepositoryEvent( * - `git.push` — translates file-level adds, modifications, and deletions on * the default branch into catalog SCM events for paths matching * `isRelevantPath`. + * - `git.repo.created` — emits a `repository.created` event. + * - `git.repo.deleted` — emits a `repository.deleted` event. + * - `git.repo.statuschanged` — emits a `repository.updated` event. + * - `git.repo.renamed` — emits a `repository.moved` event with the old and + * new repository URLs. * * @alpha */