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