From 0668895546b1d1a67702180101524b54482d0dd8 Mon Sep 17 00:00:00 2001
From: Sebastian Poxhofer <secustor@users.noreply.github.com>
Date: Fri, 10 Nov 2023 21:48:27 +0100
Subject: [PATCH] feat(datasource/galaxy-collection): migrate from v2 to v3
 (#25239)

---
 .../community_kubernetes_base.json            |  24 ++-
 ...ity_kubernetes_version_details_0.11.1.json | 104 ++++++++----
 ...nity_kubernetes_version_details_1.2.0.json | 105 +++++++-----
 ...nity_kubernetes_version_details_1.2.1.json | 105 +++++++-----
 .../community_kubernetes_versions.json        |  32 +++-
 .../__snapshots__/index.spec.ts.snap          |  44 +----
 .../galaxy-collection/index.spec.ts           |  61 ++++---
 .../datasource/galaxy-collection/index.ts     | 152 +++++++++---------
 .../datasource/galaxy-collection/schema.ts    |  52 ++++++
 .../datasource/galaxy-collection/types.ts     |  31 ----
 10 files changed, 407 insertions(+), 303 deletions(-)
 create mode 100644 lib/modules/datasource/galaxy-collection/schema.ts
 delete mode 100644 lib/modules/datasource/galaxy-collection/types.ts

diff --git a/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_base.json b/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_base.json
index 8904d36459..f79b4ce631 100644
--- a/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_base.json
+++ b/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_base.json
@@ -1,18 +1,14 @@
 {
-  "id": 201,
-  "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/",
+  "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/",
+  "namespace": "community",
   "name": "kubernetes",
-  "namespace": {
-    "id": 17693,
-    "href": "https://galaxy.ansible.com/api/v1/namespaces/17693/",
-    "name": "community"
-  },
-  "versions_url": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/versions/",
-  "latest_version": {
-    "version": "1.2.1",
-    "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/versions/1.2.1/"
-  },
   "deprecated": false,
-  "created": "2020-02-05T10:08:00.780436-05:00",
-  "modified": "2021-04-01T09:06:02.676421-04:00"
+  "versions_url": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/",
+  "highest_version": {
+    "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/2.0.1/",
+    "version": "2.0.1"
+  },
+  "created_at": "2023-05-08T20:27:28.514620Z",
+  "updated_at": "2023-10-15T22:54:12.688681Z",
+  "download_count": 15712290
 }
diff --git a/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_0.11.1.json b/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_0.11.1.json
index e1177f6cf5..fcfd029e05 100644
--- a/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_0.11.1.json
+++ b/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_0.11.1.json
@@ -1,37 +1,28 @@
 {
-  "id": 2800,
-  "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/versions/0.11.1/",
-  "download_url": "https://galaxy.ansible.com/download/community-kubernetes-0.11.1.tar.gz",
+  "version": "0.11.1",
+  "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/0.11.1/",
+  "created_at": "2023-05-08T20:27:29.606154Z",
+  "updated_at": "2023-09-29T13:51:11.915940Z",
+  "requires_ansible": ">=2.9",
+  "marks": [],
   "artifact": {
     "filename": "community-kubernetes-0.11.1.tar.gz",
-    "size": 78870,
-    "sha256": "cd197084b32f8976394f269eb005bf475eff2122fddbb48380c76154ab4d4530"
-  },
-  "namespace": {
-    "id": 17693,
-    "href": "https://galaxy.ansible.com/api/v1/namespaces/17693/",
-    "name": "community"
+    "sha256": "cd197084b32f8976394f269eb005bf475eff2122fddbb48380c76154ab4d4530",
+    "size": 78870
   },
   "collection": {
-    "id": 201,
-    "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/",
-    "name": "kubernetes"
+    "id": "ec17eff8-7c2b-4687-aa14-ee5edab9bd62",
+    "name": "kubernetes",
+    "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/"
   },
-  "version": "0.11.1",
-  "hidden": false,
+  "download_url": "https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/community-kubernetes-0.11.1.tar.gz",
+  "name": "kubernetes",
+  "namespace": {
+    "name": "community",
+    "metadata_sha256": null
+  },
+  "signatures": [],
   "metadata": {
-    "name": "kubernetes",
-    "tags": [
-      "kubernetes",
-      "k8s",
-      "cloud",
-      "infrastructure",
-      "openshift",
-      "okd",
-      "cluster"
-    ],
-    "issues": "https://github.com/ansible-collections/community.kubernetes/issues",
-    "readme": "README.md",
     "authors": [
       "chouseknecht (https://github.com/chouseknecht)",
       "geerlingguy (https://www.jeffgeerling.com/)",
@@ -42,14 +33,57 @@
       "mmazur (https://github.com/mmazur)",
       "jamescassell (https://github.com/jamescassell)"
     ],
-    "license": [],
-    "version": "0.11.1",
+    "contents": [],
+    "dependencies": {},
+    "description": "Kubernetes Collection for Ansible.",
+    "documentation": "",
     "homepage": "",
-    "namespace": "community",
+    "issues": "https://github.com/ansible-collections/community.kubernetes/issues",
+    "license": [],
     "repository": "https://github.com/ansible-collections/community.kubernetes",
-    "description": "Kubernetes Collection for Ansible.",
-    "dependencies": {},
-    "license_file": "LICENSE",
-    "documentation": ""
-  }
+    "tags": [
+      "cluster",
+      "okd",
+      "k8s",
+      "cloud",
+      "kubernetes",
+      "openshift",
+      "infrastructure"
+    ]
+  },
+  "git_url": null,
+  "git_commit_sha": null,
+  "manifest": {
+    "format": 1,
+    "collection_info": {
+      "name": "kubernetes",
+      "issues": "https://github.com/ansible-collections/community.kubernetes/issues",
+      "authors": [
+        "chouseknecht (https://github.com/chouseknecht)",
+        "geerlingguy (https://www.jeffgeerling.com/)",
+        "maxamillion (https://github.com/maxamillion)",
+        "jmontleon (https://github.com/jmontleon)",
+        "fabianvf (https://github.com/fabianvf)",
+        "willthames (https://github.com/willthames)",
+        "mmazur (https://github.com/mmazur)",
+        "jamescassell (https://github.com/jamescassell)"
+      ],
+      "license": [],
+      "version": "0.11.1",
+      "homepage": "",
+      "namespace": "community",
+      "repository": "https://github.com/ansible-collections/community.kubernetes",
+      "description": "Kubernetes Collection for Ansible.",
+      "dependencies": {},
+      "documentation": ""
+    },
+    "file_manifest_file": {
+      "name": "FILES.json",
+      "ftype": "file",
+      "format": 1,
+      "chksum_type": "sha256",
+      "chksum_sha256": "d8b804d0cabd4891e1288f37378cbcdd321f1786fdcc8e86ee9c4dc97f20c9cc"
+    }
+  },
+  "files": {}
 }
diff --git a/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_1.2.0.json b/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_1.2.0.json
index 332e3c3cd2..f298d486f7 100644
--- a/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_1.2.0.json
+++ b/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_1.2.0.json
@@ -1,38 +1,28 @@
-
 {
-  "id": 6810,
-  "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/versions/1.2.0/",
-  "download_url": "https://galaxy.ansible.com/download/community-kubernetes-1.2.0.tar.gz",
+  "version": "1.2.0",
+  "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/1.2.0/",
+  "created_at": "2023-05-08T20:27:29.625001Z",
+  "updated_at": "2023-09-29T13:51:22.996480Z",
+  "requires_ansible": ">=2.9.17",
+  "marks": [],
   "artifact": {
     "filename": "community-kubernetes-1.2.0.tar.gz",
-    "size": 119746,
-    "sha256": "a53eaf6a51987d30cc48ebcd20f0102dae0f17a7a02071928381e5a62951a0ed"
-  },
-  "namespace": {
-    "id": 17693,
-    "href": "https://galaxy.ansible.com/api/v1/namespaces/17693/",
-    "name": "community"
+    "sha256": "a53eaf6a51987d30cc48ebcd20f0102dae0f17a7a02071928381e5a62951a0ed",
+    "size": 119746
   },
   "collection": {
-    "id": 201,
-    "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/",
-    "name": "kubernetes"
+    "id": "ec17eff8-7c2b-4687-aa14-ee5edab9bd62",
+    "name": "kubernetes",
+    "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/"
   },
-  "version": "1.2.0",
-  "hidden": false,
+  "download_url": "https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/community-kubernetes-1.2.0.tar.gz",
+  "name": "kubernetes",
+  "namespace": {
+    "name": "community",
+    "metadata_sha256": null
+  },
+  "signatures": [],
   "metadata": {
-    "name": "kubernetes",
-    "tags": [
-      "kubernetes",
-      "k8s",
-      "cloud",
-      "infrastructure",
-      "openshift",
-      "okd",
-      "cluster"
-    ],
-    "issues": "https://github.com/ansible-collections/community.kubernetes/issues",
-    "readme": "README.md",
     "authors": [
       "chouseknecht (https://github.com/chouseknecht)",
       "geerlingguy (https://www.jeffgeerling.com/)",
@@ -43,14 +33,57 @@
       "mmazur (https://github.com/mmazur)",
       "jamescassell (https://github.com/jamescassell)"
     ],
-    "license": [],
-    "version": "1.2.0",
+    "contents": [],
+    "dependencies": {},
+    "description": "Kubernetes Collection for Ansible.",
+    "documentation": "",
     "homepage": "",
-    "namespace": "community",
+    "issues": "https://github.com/ansible-collections/community.kubernetes/issues",
+    "license": [],
     "repository": "https://github.com/ansible-collections/community.kubernetes",
-    "description": "Kubernetes Collection for Ansible.",
-    "dependencies": {},
-    "license_file": "LICENSE",
-    "documentation": ""
-  }
+    "tags": [
+      "cluster",
+      "okd",
+      "k8s",
+      "cloud",
+      "kubernetes",
+      "openshift",
+      "infrastructure"
+    ]
+  },
+  "git_url": null,
+  "git_commit_sha": null,
+  "manifest": {
+    "format": 1,
+    "collection_info": {
+      "name": "kubernetes",
+      "issues": "https://github.com/ansible-collections/community.kubernetes/issues",
+      "authors": [
+        "chouseknecht (https://github.com/chouseknecht)",
+        "geerlingguy (https://www.jeffgeerling.com/)",
+        "maxamillion (https://github.com/maxamillion)",
+        "jmontleon (https://github.com/jmontleon)",
+        "fabianvf (https://github.com/fabianvf)",
+        "willthames (https://github.com/willthames)",
+        "mmazur (https://github.com/mmazur)",
+        "jamescassell (https://github.com/jamescassell)"
+      ],
+      "license": [],
+      "version": "1.2.0",
+      "homepage": "",
+      "namespace": "community",
+      "repository": "https://github.com/ansible-collections/community.kubernetes",
+      "description": "Kubernetes Collection for Ansible.",
+      "dependencies": {},
+      "documentation": ""
+    },
+    "file_manifest_file": {
+      "name": "FILES.json",
+      "ftype": "file",
+      "format": 1,
+      "chksum_type": "sha256",
+      "chksum_sha256": "f01d32a9d742c93b2fa52bee42e9af0a6275180d36efa607cbe84e4ca33236a6"
+    }
+  },
+  "files": {}
 }
diff --git a/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_1.2.1.json b/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_1.2.1.json
index 229fb2ff0d..29d40d8558 100644
--- a/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_1.2.1.json
+++ b/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_1.2.1.json
@@ -1,38 +1,28 @@
-
 {
-  "id": 8039,
-  "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/versions/1.2.1/",
-  "download_url": "https://galaxy.ansible.com/download/community-kubernetes-1.2.1.tar.gz",
+  "version": "1.2.1",
+  "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/1.2.1/",
+  "created_at": "2023-05-08T20:27:29.629269Z",
+  "updated_at": "2023-09-29T13:51:24.730687Z",
+  "requires_ansible": ">=2.9.17",
+  "marks": [],
   "artifact": {
     "filename": "community-kubernetes-1.2.1.tar.gz",
-    "size": 119908,
-    "sha256": "38e064bb32ee86781f0c6e56bd29fcfbaf48180f993e129185eb8420caabf223"
-  },
-  "namespace": {
-    "id": 17693,
-    "href": "https://galaxy.ansible.com/api/v1/namespaces/17693/",
-    "name": "community"
+    "sha256": "38e064bb32ee86781f0c6e56bd29fcfbaf48180f993e129185eb8420caabf223",
+    "size": 119908
   },
   "collection": {
-    "id": 201,
-    "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/",
-    "name": "kubernetes"
+    "id": "ec17eff8-7c2b-4687-aa14-ee5edab9bd62",
+    "name": "kubernetes",
+    "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/"
   },
-  "version": "1.2.1",
-  "hidden": false,
+  "download_url": "https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/community-kubernetes-1.2.1.tar.gz",
+  "name": "kubernetes",
+  "namespace": {
+    "name": "community",
+    "metadata_sha256": null
+  },
+  "signatures": [],
   "metadata": {
-    "name": "kubernetes",
-    "tags": [
-      "kubernetes",
-      "k8s",
-      "cloud",
-      "infrastructure",
-      "openshift",
-      "okd",
-      "cluster"
-    ],
-    "issues": "https://github.com/ansible-collections/community.kubernetes/issues",
-    "readme": "README.md",
     "authors": [
       "chouseknecht (https://github.com/chouseknecht)",
       "geerlingguy (https://www.jeffgeerling.com/)",
@@ -43,14 +33,57 @@
       "mmazur (https://github.com/mmazur)",
       "jamescassell (https://github.com/jamescassell)"
     ],
-    "license": [],
-    "version": "1.2.1",
+    "contents": [],
+    "dependencies": {},
+    "description": "Kubernetes Collection for Ansible.",
+    "documentation": "",
     "homepage": "",
-    "namespace": "community",
+    "issues": "https://github.com/ansible-collections/community.kubernetes/issues",
+    "license": [],
     "repository": "https://github.com/ansible-collections/community.kubernetes",
-    "description": "Kubernetes Collection for Ansible.",
-    "dependencies": {},
-    "license_file": "LICENSE",
-    "documentation": ""
-  }
+    "tags": [
+      "cluster",
+      "okd",
+      "k8s",
+      "cloud",
+      "kubernetes",
+      "openshift",
+      "infrastructure"
+    ]
+  },
+  "git_url": null,
+  "git_commit_sha": null,
+  "manifest": {
+    "format": 1,
+    "collection_info": {
+      "name": "kubernetes",
+      "issues": "https://github.com/ansible-collections/community.kubernetes/issues",
+      "authors": [
+        "chouseknecht (https://github.com/chouseknecht)",
+        "geerlingguy (https://www.jeffgeerling.com/)",
+        "maxamillion (https://github.com/maxamillion)",
+        "jmontleon (https://github.com/jmontleon)",
+        "fabianvf (https://github.com/fabianvf)",
+        "willthames (https://github.com/willthames)",
+        "mmazur (https://github.com/mmazur)",
+        "jamescassell (https://github.com/jamescassell)"
+      ],
+      "license": [],
+      "version": "1.2.1",
+      "homepage": "",
+      "namespace": "community",
+      "repository": "https://github.com/ansible-collections/community.kubernetes",
+      "description": "Kubernetes Collection for Ansible.",
+      "dependencies": {},
+      "documentation": ""
+    },
+    "file_manifest_file": {
+      "name": "FILES.json",
+      "ftype": "file",
+      "format": 1,
+      "chksum_type": "sha256",
+      "chksum_sha256": "3cac847544852a208167b48ee6fc56bcd62e44d871e13c11d46c466aff3cdbcc"
+    }
+  },
+  "files": {}
 }
diff --git a/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_versions.json b/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_versions.json
index 6d378cc853..63c9b9d053 100644
--- a/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_versions.json
+++ b/lib/modules/datasource/galaxy-collection/__fixtures__/community_kubernetes_versions.json
@@ -1,19 +1,37 @@
 {
-  "count": 3,
-  "next": null,
-  "previous": null,
-  "results": [
+  "meta": {
+    "count": 3
+  },
+  "links": {
+    "first": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/?limit=10&offset=0",
+    "previous": null,
+    "next": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/?limit=10&offset=10",
+    "last": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/?limit=10&offset=1"
+  },
+  "data": [
     {
       "version": "1.2.1",
-      "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/versions/1.2.1/"
+      "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/1.2.1/",
+      "created_at": "2023-05-08T20:27:29.629269Z",
+      "updated_at": "2023-09-29T13:51:24.730687Z",
+      "requires_ansible": ">=2.9.17",
+      "marks": []
     },
     {
       "version": "1.2.0",
-      "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/versions/1.2.0/"
+      "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/1.2.0/",
+      "created_at": "2023-05-08T20:27:29.625001Z",
+      "updated_at": "2023-09-29T13:51:22.996480Z",
+      "requires_ansible": ">=2.9.17",
+      "marks": []
     },
     {
       "version": "0.11.1",
-      "href": "https://galaxy.ansible.com/api/v2/collections/community/kubernetes/versions/0.11.1/"
+      "href": "/api/v3/plugin/ansible/content/published/collections/index/community/kubernetes/versions/0.11.1/",
+      "created_at": "2023-05-08T20:27:29.606154Z",
+      "updated_at": "2023-09-29T13:51:11.915940Z",
+      "requires_ansible": ">=2.9",
+      "marks": []
     }
   ]
 }
diff --git a/lib/modules/datasource/galaxy-collection/__snapshots__/index.spec.ts.snap b/lib/modules/datasource/galaxy-collection/__snapshots__/index.spec.ts.snap
index 75e6cf1e59..8000b0abe9 100644
--- a/lib/modules/datasource/galaxy-collection/__snapshots__/index.spec.ts.snap
+++ b/lib/modules/datasource/galaxy-collection/__snapshots__/index.spec.ts.snap
@@ -2,62 +2,32 @@
 
 exports[`modules/datasource/galaxy-collection/index getReleases processes real data 1`] = `
 {
-  "registryUrl": "https://old-galaxy.ansible.com/",
+  "registryUrl": "https://galaxy.ansible.com",
   "releases": [
     {
       "dependencies": {},
-      "downloadUrl": "https://galaxy.ansible.com/download/community-kubernetes-0.11.1.tar.gz",
+      "downloadUrl": "https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/community-kubernetes-0.11.1.tar.gz",
       "isDeprecated": false,
       "newDigest": "cd197084b32f8976394f269eb005bf475eff2122fddbb48380c76154ab4d4530",
+      "sourceUrl": "https://github.com/ansible-collections/community.kubernetes",
       "version": "0.11.1",
     },
     {
       "dependencies": {},
-      "downloadUrl": "https://galaxy.ansible.com/download/community-kubernetes-1.2.0.tar.gz",
+      "downloadUrl": "https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/community-kubernetes-1.2.0.tar.gz",
       "isDeprecated": false,
       "newDigest": "a53eaf6a51987d30cc48ebcd20f0102dae0f17a7a02071928381e5a62951a0ed",
+      "sourceUrl": "https://github.com/ansible-collections/community.kubernetes",
       "version": "1.2.0",
     },
     {
       "dependencies": {},
-      "downloadUrl": "https://galaxy.ansible.com/download/community-kubernetes-1.2.1.tar.gz",
+      "downloadUrl": "https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/community-kubernetes-1.2.1.tar.gz",
       "isDeprecated": false,
       "newDigest": "38e064bb32ee86781f0c6e56bd29fcfbaf48180f993e129185eb8420caabf223",
+      "sourceUrl": "https://github.com/ansible-collections/community.kubernetes",
       "version": "1.2.1",
     },
   ],
-  "sourceUrl": "https://github.com/ansible-collections/community.kubernetes",
-  "tags": [
-    "kubernetes",
-    "k8s",
-    "cloud",
-    "infrastructure",
-    "openshift",
-    "okd",
-    "cluster",
-  ],
-}
-`;
-
-exports[`modules/datasource/galaxy-collection/index getReleases returns only valid versions if a version detail fails 1`] = `
-{
-  "registryUrl": "https://old-galaxy.ansible.com/",
-  "releases": [
-    {
-      "dependencies": {},
-      "downloadUrl": "https://galaxy.ansible.com/download/community-kubernetes-0.11.1.tar.gz",
-      "isDeprecated": false,
-      "newDigest": "cd197084b32f8976394f269eb005bf475eff2122fddbb48380c76154ab4d4530",
-      "version": "0.11.1",
-    },
-    {
-      "dependencies": {},
-      "downloadUrl": "https://galaxy.ansible.com/download/community-kubernetes-1.2.0.tar.gz",
-      "isDeprecated": false,
-      "newDigest": "a53eaf6a51987d30cc48ebcd20f0102dae0f17a7a02071928381e5a62951a0ed",
-      "version": "1.2.0",
-    },
-  ],
-  "tags": undefined,
 }
 `;
diff --git a/lib/modules/datasource/galaxy-collection/index.spec.ts b/lib/modules/datasource/galaxy-collection/index.spec.ts
index 4fe355e057..12d93b0d41 100644
--- a/lib/modules/datasource/galaxy-collection/index.spec.ts
+++ b/lib/modules/datasource/galaxy-collection/index.spec.ts
@@ -18,14 +18,16 @@ const communityKubernetesDetails0111 = Fixtures.get(
   'community_kubernetes_version_details_0.11.1.json',
 );
 
-const baseUrl = 'https://old-galaxy.ansible.com';
+const baseUrl = 'https://galaxy.ansible.com';
+const collectionAPIPath =
+  'api/v3/plugin/ansible/content/published/collections/index';
 
 const datasource = GalaxyCollectionDatasource.id;
 
 describe('modules/datasource/galaxy-collection/index', () => {
   describe('getReleases', () => {
     it('returns null for 404 result', async () => {
-      httpMock.scope(baseUrl).get('/api/v2/collections/foo/bar/').reply(404);
+      httpMock.scope(baseUrl).get(`/${collectionAPIPath}/foo/bar/`).reply(404);
       expect(
         await getPkgReleases({
           datasource,
@@ -35,7 +37,7 @@ describe('modules/datasource/galaxy-collection/index', () => {
     });
 
     it('throws for remote host error', async () => {
-      httpMock.scope(baseUrl).get('/api/v2/collections/foo/bar/').reply(500);
+      httpMock.scope(baseUrl).get(`/${collectionAPIPath}/foo/bar/`).reply(500);
       await expect(
         getPkgReleases({
           datasource,
@@ -47,7 +49,7 @@ describe('modules/datasource/galaxy-collection/index', () => {
     it('returns null for unexpected data at base', async () => {
       httpMock
         .scope(baseUrl)
-        .get('/api/v2/collections/community/kubernetes/')
+        .get(`/${collectionAPIPath}/community/kubernetes/`)
         .reply(200, '');
       expect(
         await getPkgReleases({
@@ -60,9 +62,9 @@ describe('modules/datasource/galaxy-collection/index', () => {
     it('returns null for unexpected data at versions', async () => {
       httpMock
         .scope(baseUrl)
-        .get('/api/v2/collections/community/kubernetes/')
+        .get(`/${collectionAPIPath}/community/kubernetes/`)
         .reply(200, communityKubernetesBase)
-        .get('/api/v2/collections/community/kubernetes/versions/')
+        .get(`/${collectionAPIPath}/community/kubernetes/versions/`)
         .reply(200, '');
       expect(
         await getPkgReleases({
@@ -75,9 +77,9 @@ describe('modules/datasource/galaxy-collection/index', () => {
     it('throws error for remote host versions error', async () => {
       httpMock
         .scope(baseUrl)
-        .get('/api/v2/collections/community/kubernetes/')
+        .get(`/${collectionAPIPath}/community/kubernetes/`)
         .reply(200, communityKubernetesBase)
-        .get('/api/v2/collections/community/kubernetes/versions/')
+        .get(`/${collectionAPIPath}/community/kubernetes/versions/`)
         .reply(500);
       await expect(
         getPkgReleases({
@@ -87,28 +89,25 @@ describe('modules/datasource/galaxy-collection/index', () => {
       ).rejects.toThrow(EXTERNAL_HOST_ERROR);
     });
 
-    it('returns only valid versions if a version detail fails', async () => {
+    it('throws error for remote host detailed versions error', async () => {
       httpMock
         .scope(baseUrl)
-        .get('/api/v2/collections/community/kubernetes/')
+        .get(`/${collectionAPIPath}/community/kubernetes/`)
         .reply(200, communityKubernetesBase)
-        .get('/api/v2/collections/community/kubernetes/versions/')
+        .get(`/${collectionAPIPath}/community/kubernetes/versions/`)
         .reply(200, communityKubernetesVersions)
-        .get('/api/v2/collections/community/kubernetes/versions/1.2.1/')
-        .reply(200, '')
-        .get('/api/v2/collections/community/kubernetes/versions/1.2.0/')
+        .get(`/${collectionAPIPath}/community/kubernetes/versions/1.2.0/`)
         .reply(200, communityKubernetesDetails120)
-        .get('/api/v2/collections/community/kubernetes/versions/0.11.1/')
-        .reply(200, communityKubernetesDetails0111);
-
-      const res = await getPkgReleases({
-        datasource,
-        packageName: 'community.kubernetes',
-      });
-      expect(res).toMatchSnapshot();
-      expect(res).not.toBeNull();
-      expect(res).toBeDefined();
-      expect(res?.releases).toHaveLength(2);
+        .get(`/${collectionAPIPath}/community/kubernetes/versions/0.11.1/`)
+        .reply(200, communityKubernetesDetails0111)
+        .get(`/${collectionAPIPath}/community/kubernetes/versions/1.2.1/`)
+        .reply(500);
+      await expect(
+        getPkgReleases({
+          datasource,
+          packageName: 'community.kubernetes',
+        }),
+      ).rejects.toThrow(EXTERNAL_HOST_ERROR);
     });
 
     it('returns null for empty lookup', async () => {
@@ -132,7 +131,7 @@ describe('modules/datasource/galaxy-collection/index', () => {
     it('returns null for unknown error', async () => {
       httpMock
         .scope(baseUrl)
-        .get('/api/v2/collections/foo/bar/')
+        .get(`/${collectionAPIPath}/foo/bar/`)
         .replyWithError('some unknown error');
       expect(
         await getPkgReleases({
@@ -145,15 +144,15 @@ describe('modules/datasource/galaxy-collection/index', () => {
     it('processes real data', async () => {
       httpMock
         .scope(baseUrl)
-        .get('/api/v2/collections/community/kubernetes/')
+        .get(`/${collectionAPIPath}/community/kubernetes/`)
         .reply(200, communityKubernetesBase)
-        .get('/api/v2/collections/community/kubernetes/versions/')
+        .get(`/${collectionAPIPath}/community/kubernetes/versions/`)
         .reply(200, communityKubernetesVersions)
-        .get('/api/v2/collections/community/kubernetes/versions/1.2.1/')
+        .get(`/${collectionAPIPath}/community/kubernetes/versions/1.2.1/`)
         .reply(200, communityKubernetesDetails121)
-        .get('/api/v2/collections/community/kubernetes/versions/1.2.0/')
+        .get(`/${collectionAPIPath}/community/kubernetes/versions/1.2.0/`)
         .reply(200, communityKubernetesDetails120)
-        .get('/api/v2/collections/community/kubernetes/versions/0.11.1/')
+        .get(`/${collectionAPIPath}/community/kubernetes/versions/0.11.1/`)
         .reply(200, communityKubernetesDetails0111);
       const res = await getPkgReleases({
         datasource,
diff --git a/lib/modules/datasource/galaxy-collection/index.ts b/lib/modules/datasource/galaxy-collection/index.ts
index 7ea6363022..d73de1c2a1 100644
--- a/lib/modules/datasource/galaxy-collection/index.ts
+++ b/lib/modules/datasource/galaxy-collection/index.ts
@@ -1,16 +1,12 @@
 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 p from '../../../util/promises';
+import { ensureTrailingSlash, joinUrlParts } from '../../../util/url';
 import * as pep440Versioning from '../../versioning/pep440';
 import { Datasource } from '../datasource';
 import type { GetReleasesConfig, Release, ReleaseResult } from '../types';
-import type {
-  BaseProjectResult,
-  VersionsDetailResult,
-  VersionsProjectResult,
-} from './types';
+import { GalaxyV3, GalaxyV3DetailedVersion, GalaxyV3Versions } from './schema';
 
 export class GalaxyCollectionDatasource extends Datasource {
   static readonly id = 'galaxy-collection';
@@ -21,7 +17,7 @@ export class GalaxyCollectionDatasource 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;
 
@@ -35,91 +31,95 @@ export class GalaxyCollectionDatasource extends Datasource {
   }: GetReleasesConfig): Promise<ReleaseResult | null> {
     const [namespace, projectName] = packageName.split('.');
 
-    // TODO: types (#22198)
-    const baseUrl = `${registryUrl}api/v2/collections/${namespace}/${projectName}/`;
-
-    let baseUrlResponse: HttpResponse<BaseProjectResult>;
-    try {
-      baseUrlResponse = await this.http.getJson<BaseProjectResult>(baseUrl);
-    } catch (err) {
-      this.handleGenericErrors(err);
-    }
+    const baseUrl = ensureTrailingSlash(
+      joinUrlParts(
+        registryUrl!,
+        'api/v3/plugin/ansible/content/published/collections/index',
+        namespace,
+        projectName,
+      ),
+    );
 
-    if (!baseUrlResponse?.body) {
-      logger.warn(
-        { dependency: packageName },
-        `Received invalid data from ${baseUrl}`,
-      );
-      return null;
+    const { val: baseProject, err: baseErr } = await this.http
+      .getJsonSafe(baseUrl, GalaxyV3)
+      .onError((err) => {
+        logger.warn(
+          { datasource: this.id, packageName, err },
+          `Error fetching ${baseUrl}`,
+        );
+      })
+      .unwrap();
+    if (baseErr) {
+      this.handleGenericErrors(baseErr);
     }
 
-    const baseProject = baseUrlResponse.body;
-
-    const versionsUrl = `${baseUrl}versions/`;
-
-    let versionsUrlResponse: HttpResponse<VersionsProjectResult>;
-    try {
-      versionsUrlResponse =
-        await this.http.getJson<VersionsProjectResult>(versionsUrl);
-    } catch (err) {
-      this.handleGenericErrors(err);
+    const versionsUrl = ensureTrailingSlash(joinUrlParts(baseUrl, 'versions'));
+
+    const { val: rawReleases, err: versionsErr } = await this.http
+      .getJsonSafe(versionsUrl, GalaxyV3Versions)
+      .onError((err) => {
+        logger.warn(
+          { datasource: this.id, packageName, err },
+          `Error fetching ${versionsUrl}`,
+        );
+      })
+      .unwrap();
+    if (versionsErr) {
+      this.handleGenericErrors(versionsErr);
     }
 
-    const versionsProject = versionsUrlResponse.body;
-
-    const releases: Release[] = versionsProject.results.map((value) => {
-      const release: Release = {
-        version: value.version,
+    const releases = rawReleases.map((value) => {
+      return {
+        ...value,
         isDeprecated: baseProject.deprecated,
       };
-      return release;
     });
 
-    let newestVersionDetails: VersionsDetailResult | undefined;
     // asynchronously get release details
-    const enrichedReleases: (Release | null)[] = await p.map(
+    const enrichedReleases = await p.map(
       releases,
-      (basicRelease) =>
-        this.http
-          .getJson<VersionsDetailResult>(
-            `${versionsUrl}${basicRelease.version}/`,
-          )
-          .then(
-            (versionDetailResultResponse) => versionDetailResultResponse.body,
-          )
-          .then((versionDetails) => {
-            try {
-              const release: Release = {
-                version: basicRelease.version,
-                isDeprecated: !!basicRelease.isDeprecated,
-                downloadUrl: versionDetails.download_url,
-                newDigest: versionDetails.artifact.sha256,
-                dependencies: versionDetails.metadata.dependencies,
-              };
-
-              // save details of the newest release for use on the ReleaseResult object
-              if (basicRelease.version === baseProject.latest_version.version) {
-                newestVersionDetails = versionDetails;
-              }
-              return release;
-            } catch (err) {
-              logger.warn(
-                { dependency: packageName, err },
-                `Received invalid data from ${versionsUrl}${basicRelease.version}/`,
-              );
-              return null;
-            }
-          }),
+      (release) => this.getVersionDetails(packageName, versionsUrl, release),
+      { concurrency: 4 },
     );
+
     // filter failed versions
     const filteredReleases = enrichedReleases.filter(is.truthy);
     // extract base information which are only provided on the release from the newest release
-    const result: ReleaseResult = {
+
+    return {
       releases: filteredReleases,
-      sourceUrl: newestVersionDetails?.metadata.repository ?? null,
-      homepage: newestVersionDetails?.metadata.homepage,
-      tags: newestVersionDetails?.metadata.tags,
     };
-    return result;
+  }
+
+  @cache({
+    namespace: `datasource-${GalaxyCollectionDatasource.id}-detailed-version`,
+    key: (versionsUrl, basicRelease: Release) => basicRelease.version,
+    ttlMinutes: 10080, // 1 week
+  })
+  async getVersionDetails(
+    packageName: string,
+    versionsUrl: string,
+    basicRelease: Release,
+  ): Promise<Release> {
+    const detailedVersionUrl = ensureTrailingSlash(
+      joinUrlParts(versionsUrl, basicRelease.version),
+    );
+    const { val: rawDetailedVersion, err: versionsErr } = await this.http
+      .getJsonSafe(detailedVersionUrl, GalaxyV3DetailedVersion)
+      .onError((err) => {
+        logger.warn(
+          { datasource: this.id, packageName, err },
+          `Error fetching ${versionsUrl}`,
+        );
+      })
+      .unwrap();
+    if (versionsErr) {
+      this.handleGenericErrors(versionsErr);
+    }
+
+    return {
+      ...rawDetailedVersion,
+      isDeprecated: basicRelease.isDeprecated,
+    };
   }
 }
diff --git a/lib/modules/datasource/galaxy-collection/schema.ts b/lib/modules/datasource/galaxy-collection/schema.ts
new file mode 100644
index 0000000000..06be4898c5
--- /dev/null
+++ b/lib/modules/datasource/galaxy-collection/schema.ts
@@ -0,0 +1,52 @@
+import { z } from 'zod';
+
+export type GalaxyV3 = z.infer<typeof GalaxyV3>;
+export const GalaxyV3 = z.object({
+  deprecated: z.boolean(),
+  highest_version: z.object({
+    version: z.string(),
+  }),
+});
+
+export type GalaxyV3Versions = z.infer<typeof GalaxyV3Versions>;
+export const GalaxyV3Versions = z
+  .object({
+    data: z.array(
+      z.object({
+        version: z.string(),
+        created_at: z.string().datetime(),
+      }),
+    ),
+  })
+  .transform(({ data }) => {
+    return data.map((value) => {
+      return {
+        version: value.version,
+        releaseTimestamp: value.created_at,
+      };
+    });
+  });
+
+export type GalaxyV3DetailedVersion = z.infer<typeof GalaxyV3DetailedVersion>;
+export const GalaxyV3DetailedVersion = z
+  .object({
+    version: z.string(),
+    download_url: z.string(),
+    artifact: z.object({
+      sha256: z.string(),
+    }),
+    metadata: z.object({
+      homepage: z.string(),
+      repository: z.string(),
+      dependencies: z.record(z.string(), z.string()).optional(),
+    }),
+  })
+  .transform((value) => {
+    return {
+      version: value.version,
+      downloadUrl: value.download_url,
+      newDigest: value.artifact.sha256,
+      dependencies: value.metadata.dependencies,
+      sourceUrl: value.metadata.repository,
+    };
+  });
diff --git a/lib/modules/datasource/galaxy-collection/types.ts b/lib/modules/datasource/galaxy-collection/types.ts
deleted file mode 100644
index 7d8b321351..0000000000
--- a/lib/modules/datasource/galaxy-collection/types.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-export interface BaseProjectResult {
-  versions_url: string;
-  deprecated: boolean;
-  latest_version: {
-    version: string;
-  };
-}
-
-export interface VersionsProjectResult {
-  results: Versions[];
-}
-
-export interface VersionsDetailResult {
-  download_url: string;
-  artifact: {
-    filename: string;
-    size: bigint;
-    sha256: string;
-  };
-  metadata: {
-    homepage: string;
-    tags: Record<string, string>;
-    dependencies: Record<string, string>;
-    repository: string;
-  };
-}
-
-interface Versions {
-  version: string;
-  href: string;
-}
-- 
GitLab