From ddbce7defa7446edfc40ea2ddab8bc7718c2eed4 Mon Sep 17 00:00:00 2001
From: Danek Duvall <duvall@comfychair.org>
Date: Thu, 26 Oct 2023 11:18:11 -0700
Subject: [PATCH] fix(nuget): gracefully accept a lack of a PackageBaseAddress
 resource (#25355)

---
 lib/modules/datasource/nuget/index.spec.ts | 59 ++++++++++++++++++++++
 lib/modules/datasource/nuget/v3.ts         | 10 ++++
 2 files changed, 69 insertions(+)

diff --git a/lib/modules/datasource/nuget/index.spec.ts b/lib/modules/datasource/nuget/index.spec.ts
index 816bbd16bb..b1c05b17bf 100644
--- a/lib/modules/datasource/nuget/index.spec.ts
+++ b/lib/modules/datasource/nuget/index.spec.ts
@@ -2,6 +2,7 @@ import { mockDeep } from 'jest-mock-extended';
 import { getPkgReleases } from '..';
 import { Fixtures } from '../../../../test/fixtures';
 import * as httpMock from '../../../../test/http-mock';
+import { logger } from '../../../../test/util';
 import * as _hostRules from '../../../util/host-rules';
 import { id as versioning } from '../../versioning/nuget';
 import { parseRegistryUrl } from './common';
@@ -243,6 +244,64 @@ describe('modules/datasource/nuget/index', () => {
       expect(res).toBeNull();
     });
 
+    it('logs instead of triggering a TypeError when PackageBaseAddress is missing from service index', async () => {
+      const nugetIndex = `
+        {
+          "version": "3.0.0",
+          "resources": [
+            {
+              "@id": "https://api.nuget.org/v3/metadata",
+              "@type": "RegistrationsBaseUrl/3.0.0-beta",
+              "comment": "Get package metadata."
+            }
+          ]
+        }
+      `;
+      const nunitRegistration = `
+        {
+          "count": 1,
+          "items": [
+            {
+              "@id": "https://api.nuget.org/v3/metadata/nunit/5.0.json",
+              "lower": "5.0",
+              "upper": "5.0",
+              "count": 1,
+              "items": [
+                {
+                  "@id": "foo",
+                  "packageContent": "foo",
+                  "catalogEntry": {
+                    "id": "nunit",
+                    "version": "5.0"
+                  }
+                }
+              ]
+            }
+          ]
+        }
+      `;
+
+      httpMock
+        .scope('https://api.nuget.org')
+        .get('/v3/index.json')
+        .twice()
+        .reply(200, nugetIndex)
+        .get('/v3/metadata/nunit/index.json')
+        .reply(200, nunitRegistration);
+      const res = await getPkgReleases({
+        ...configV3,
+      });
+      expect(res).not.toBeNull();
+      expect(res!.releases).toHaveLength(1);
+      expect(logger.logger.debug).toHaveBeenCalledWith(
+        {
+          url: 'https://api.nuget.org/v3/index.json',
+          servicesIndexRaw: JSON.parse(nugetIndex),
+        },
+        'no PackageBaseAddress services found'
+      );
+    });
+
     it('returns null for non 200 (v3v2)', async () => {
       httpMock.scope('https://api.nuget.org').get('/v3/index.json').reply(500);
       httpMock
diff --git a/lib/modules/datasource/nuget/v3.ts b/lib/modules/datasource/nuget/v3.ts
index eb5e088c11..5da279f235 100644
--- a/lib/modules/datasource/nuget/v3.ts
+++ b/lib/modules/datasource/nuget/v3.ts
@@ -68,6 +68,16 @@ export async function getResourceUrl(
           ? semver.compare(x.version, y.version)
           : /* istanbul ignore next: hard to test */ 0
       );
+
+    if (services.length === 0) {
+      await packageCache.set(cacheNamespace, resultCacheKey, null, 60);
+      logger.debug(
+        { url, servicesIndexRaw },
+        `no ${resourceType} services found`
+      );
+      return null;
+    }
+
     const { serviceId, version } = services.pop()!;
 
     // istanbul ignore if
-- 
GitLab