From 4a8860f1ebe27e39bde6b331154265be8dc28d3f Mon Sep 17 00:00:00 2001
From: Sebastian Poxhofer <secustor@users.noreply.github.com>
Date: Mon, 16 Oct 2023 18:57:45 +0200
Subject: [PATCH] feat(datasource/galaxy): use schema validation and migrate to
 new hostname (#25216)

---
 .../galaxy/__snapshots__/index.spec.ts.snap   |  4 +--
 lib/modules/datasource/galaxy/index.spec.ts   |  2 +-
 lib/modules/datasource/galaxy/index.ts        | 26 ++++++-------------
 lib/modules/datasource/galaxy/schema.ts       | 19 ++++++++++++++
 lib/modules/datasource/galaxy/types.ts        | 12 ---------
 5 files changed, 30 insertions(+), 33 deletions(-)
 create mode 100644 lib/modules/datasource/galaxy/schema.ts
 delete mode 100644 lib/modules/datasource/galaxy/types.ts

diff --git a/lib/modules/datasource/galaxy/__snapshots__/index.spec.ts.snap b/lib/modules/datasource/galaxy/__snapshots__/index.spec.ts.snap
index 5e28d5c3c1..0503963c3f 100644
--- a/lib/modules/datasource/galaxy/__snapshots__/index.spec.ts.snap
+++ b/lib/modules/datasource/galaxy/__snapshots__/index.spec.ts.snap
@@ -2,8 +2,8 @@
 
 exports[`modules/datasource/galaxy/index getReleases processes real data 1`] = `
 {
-  "dependencyUrl": "https://old-galaxy.ansible.com/yatesr/timezone",
-  "registryUrl": "https://old-galaxy.ansible.com/",
+  "dependencyUrl": "https://galaxy.ansible.com/yatesr/timezone",
+  "registryUrl": "https://galaxy.ansible.com/",
   "releases": [
     {
       "releaseTimestamp": "2015-11-17T00:43:42.000Z",
diff --git a/lib/modules/datasource/galaxy/index.spec.ts b/lib/modules/datasource/galaxy/index.spec.ts
index 97bf675fb1..7654329bef 100644
--- a/lib/modules/datasource/galaxy/index.spec.ts
+++ b/lib/modules/datasource/galaxy/index.spec.ts
@@ -4,7 +4,7 @@ import * as httpMock from '../../../../test/http-mock';
 import { EXTERNAL_HOST_ERROR } from '../../../constants/error-messages';
 import { GalaxyDatasource } from '.';
 
-const baseUrl = 'https://old-galaxy.ansible.com/';
+const baseUrl = 'https://galaxy.ansible.com/';
 
 describe('modules/datasource/galaxy/index', () => {
   describe('getReleases', () => {
diff --git a/lib/modules/datasource/galaxy/index.ts b/lib/modules/datasource/galaxy/index.ts
index dc913245e9..26cdf87b54 100644
--- a/lib/modules/datasource/galaxy/index.ts
+++ b/lib/modules/datasource/galaxy/index.ts
@@ -1,10 +1,10 @@
+import is from '@sindresorhus/is';
 import { logger } from '../../../logger';
 import { cache } from '../../../util/cache/package/decorator';
-import type { HttpResponse } from '../../../util/http/types';
 import * as pep440Versioning from '../../versioning/pep440';
 import { Datasource } from '../datasource';
 import type { GetReleasesConfig, Release, ReleaseResult } from '../types';
-import type { GalaxyResult } from './types';
+import { GalaxyV1 } from './schema';
 
 export class GalaxyDatasource extends Datasource {
   static readonly id = 'galaxy';
@@ -15,7 +15,7 @@ export class GalaxyDatasource extends Datasource {
 
   override readonly customRegistrySupport = false;
 
-  override readonly defaultRegistryUrls = ['https://old-galaxy.ansible.com/'];
+  override readonly defaultRegistryUrls = ['https://galaxy.ansible.com/'];
 
   override readonly defaultVersioning = pep440Versioning.id;
 
@@ -32,25 +32,15 @@ export class GalaxyDatasource extends Datasource {
     const userName = lookUp[0];
     const projectName = lookUp[1];
 
-    // TODO: types (#22198)
     const galaxyAPIUrl = `${registryUrl}api/v1/roles/?owner__username=${userName}&name=${projectName}`;
     const galaxyProjectUrl = `${registryUrl}${userName}/${projectName}`;
 
-    let raw: HttpResponse<GalaxyResult> | null = null;
+    let body: GalaxyV1 | null = null;
     try {
-      raw = await this.http.getJson<GalaxyResult>(galaxyAPIUrl);
+      const raw = await this.http.getJson(galaxyAPIUrl, GalaxyV1);
+      body = raw.body;
     } catch (err) {
-      this.handleGenericErrors(err);
-    }
-
-    const body = raw?.body;
-
-    if (!body) {
-      logger.warn(
-        { dependency: packageName },
-        `Received invalid data from ${galaxyAPIUrl}`
-      );
-      return null;
+      throw this.handleGenericErrors(err);
     }
 
     // istanbul ignore if
@@ -78,7 +68,7 @@ export class GalaxyDatasource extends Datasource {
 
     result.dependencyUrl = galaxyProjectUrl;
     const { github_user: user, github_repo: repo } = resultObject;
-    if (typeof user === 'string' && typeof repo === 'string') {
+    if (is.nonEmptyString(user) && is.nonEmptyString(repo)) {
       result.sourceUrl = `https://github.com/${user}/${repo}`;
     }
 
diff --git a/lib/modules/datasource/galaxy/schema.ts b/lib/modules/datasource/galaxy/schema.ts
new file mode 100644
index 0000000000..3cfbe6a9cc
--- /dev/null
+++ b/lib/modules/datasource/galaxy/schema.ts
@@ -0,0 +1,19 @@
+import { z } from 'zod';
+
+export type GalaxyV1 = z.infer<typeof GalaxyV1>;
+export const GalaxyV1 = z.object({
+  results: z.array(
+    z.object({
+      summary_fields: z.object({
+        versions: z.array(
+          z.object({
+            name: z.string(),
+            release_date: z.string(),
+          })
+        ),
+      }),
+      github_user: z.string().optional(),
+      github_repo: z.string().optional(),
+    })
+  ),
+});
diff --git a/lib/modules/datasource/galaxy/types.ts b/lib/modules/datasource/galaxy/types.ts
deleted file mode 100644
index 5b3dbf9918..0000000000
--- a/lib/modules/datasource/galaxy/types.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export interface GalaxyResult {
-  results: {
-    summary_fields: {
-      versions: {
-        name: string;
-        release_date: string;
-      }[];
-    };
-    github_user: string;
-    github_repo: string;
-  }[];
-}
-- 
GitLab