mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 23:16:26 +00:00
feat(datasource/galaxy-collection): support ansible automation hub (#25675)
Co-authored-by: Rhys Arkins <rhys@arkins.net> Co-authored-by: Sebastian Poxhofer <secustor@users.noreply.github.com> Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
This commit is contained in:
parent
3d47d2a615
commit
f7faaa4918
4 changed files with 125 additions and 6 deletions
|
@ -2,7 +2,40 @@
|
||||||
|
|
||||||
exports[`modules/datasource/galaxy-collection/index getReleases processes real data 1`] = `
|
exports[`modules/datasource/galaxy-collection/index getReleases processes real data 1`] = `
|
||||||
{
|
{
|
||||||
"registryUrl": "https://galaxy.ansible.com",
|
"registryUrl": "https://galaxy.ansible.com/api",
|
||||||
|
"releases": [
|
||||||
|
{
|
||||||
|
"dependencies": {},
|
||||||
|
"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/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/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",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`modules/datasource/galaxy-collection/index getReleases processes real data with automation hub URL 1`] = `
|
||||||
|
{
|
||||||
|
"registryUrl": "https://my.automationhub.local/api/galaxy/content/published",
|
||||||
"releases": [
|
"releases": [
|
||||||
{
|
{
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
|
|
|
@ -18,9 +18,9 @@ const communityKubernetesDetails0111 = Fixtures.get(
|
||||||
'community_kubernetes_version_details_0.11.1.json',
|
'community_kubernetes_version_details_0.11.1.json',
|
||||||
);
|
);
|
||||||
|
|
||||||
const baseUrl = 'https://galaxy.ansible.com';
|
const baseUrl = 'https://galaxy.ansible.com/api/';
|
||||||
const collectionAPIPath =
|
const collectionAPIPath =
|
||||||
'api/v3/plugin/ansible/content/published/collections/index';
|
'v3/plugin/ansible/content/published/collections/index';
|
||||||
|
|
||||||
const datasource = GalaxyCollectionDatasource.id;
|
const datasource = GalaxyCollectionDatasource.id;
|
||||||
|
|
||||||
|
@ -163,5 +163,47 @@ describe('modules/datasource/galaxy-collection/index', () => {
|
||||||
expect(res).toBeDefined();
|
expect(res).toBeDefined();
|
||||||
expect(res?.releases).toHaveLength(3);
|
expect(res?.releases).toHaveLength(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns null but matches automation hub URL', async () => {
|
||||||
|
httpMock
|
||||||
|
.scope('https://my.automationhub.local/api/galaxy/content/community/')
|
||||||
|
.get(`/v3/plugin/ansible/content/community/collections/index/foo/bar/`)
|
||||||
|
.reply(500);
|
||||||
|
await expect(
|
||||||
|
getPkgReleases({
|
||||||
|
datasource,
|
||||||
|
packageName: 'foo.bar',
|
||||||
|
registryUrls: [
|
||||||
|
'https://my.automationhub.local/api/galaxy/content/community/',
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('processes real data with automation hub URL', async () => {
|
||||||
|
httpMock
|
||||||
|
.scope('https://my.automationhub.local/api/galaxy/content/published/')
|
||||||
|
.get(`/${collectionAPIPath}/community/kubernetes/`)
|
||||||
|
.reply(200, communityKubernetesBase)
|
||||||
|
.get(`/${collectionAPIPath}/community/kubernetes/versions/`)
|
||||||
|
.reply(200, communityKubernetesVersions)
|
||||||
|
.get(`/${collectionAPIPath}/community/kubernetes/versions/1.2.1/`)
|
||||||
|
.reply(200, communityKubernetesDetails121)
|
||||||
|
.get(`/${collectionAPIPath}/community/kubernetes/versions/1.2.0/`)
|
||||||
|
.reply(200, communityKubernetesDetails120)
|
||||||
|
.get(`/${collectionAPIPath}/community/kubernetes/versions/0.11.1/`)
|
||||||
|
.reply(200, communityKubernetesDetails0111);
|
||||||
|
const res = await getPkgReleases({
|
||||||
|
datasource,
|
||||||
|
packageName: 'community.kubernetes',
|
||||||
|
registryUrls: [
|
||||||
|
'https://my.automationhub.local/api/galaxy/content/published/',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
expect(res).toMatchSnapshot();
|
||||||
|
expect(res).not.toBeNull();
|
||||||
|
expect(res).toBeDefined();
|
||||||
|
expect(res?.releases).toHaveLength(3);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,12 +2,17 @@ import is from '@sindresorhus/is';
|
||||||
import { logger } from '../../../logger';
|
import { logger } from '../../../logger';
|
||||||
import { cache } from '../../../util/cache/package/decorator';
|
import { cache } from '../../../util/cache/package/decorator';
|
||||||
import * as p from '../../../util/promises';
|
import * as p from '../../../util/promises';
|
||||||
|
import { regEx } from '../../../util/regex';
|
||||||
import { ensureTrailingSlash, joinUrlParts } from '../../../util/url';
|
import { ensureTrailingSlash, joinUrlParts } from '../../../util/url';
|
||||||
import * as pep440Versioning from '../../versioning/pep440';
|
import * as pep440Versioning from '../../versioning/pep440';
|
||||||
import { Datasource } from '../datasource';
|
import { Datasource } from '../datasource';
|
||||||
import type { GetReleasesConfig, Release, ReleaseResult } from '../types';
|
import type { GetReleasesConfig, Release, ReleaseResult } from '../types';
|
||||||
import { GalaxyV3, GalaxyV3DetailedVersion, GalaxyV3Versions } from './schema';
|
import { GalaxyV3, GalaxyV3DetailedVersion, GalaxyV3Versions } from './schema';
|
||||||
|
|
||||||
|
const repositoryRegex = regEx(
|
||||||
|
/^\S+\/api\/galaxy\/content\/(?<repository>[^/]+)/,
|
||||||
|
);
|
||||||
|
|
||||||
export class GalaxyCollectionDatasource extends Datasource {
|
export class GalaxyCollectionDatasource extends Datasource {
|
||||||
static readonly id = 'galaxy-collection';
|
static readonly id = 'galaxy-collection';
|
||||||
|
|
||||||
|
@ -15,9 +20,11 @@ export class GalaxyCollectionDatasource extends Datasource {
|
||||||
super(GalaxyCollectionDatasource.id);
|
super(GalaxyCollectionDatasource.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
override readonly customRegistrySupport = false;
|
override readonly customRegistrySupport = true;
|
||||||
|
|
||||||
override readonly defaultRegistryUrls = ['https://galaxy.ansible.com'];
|
override readonly registryStrategy = 'hunt';
|
||||||
|
|
||||||
|
override readonly defaultRegistryUrls = ['https://galaxy.ansible.com/api/'];
|
||||||
|
|
||||||
override readonly defaultVersioning = pep440Versioning.id;
|
override readonly defaultVersioning = pep440Versioning.id;
|
||||||
|
|
||||||
|
@ -31,10 +38,15 @@ export class GalaxyCollectionDatasource extends Datasource {
|
||||||
}: GetReleasesConfig): Promise<ReleaseResult | null> {
|
}: GetReleasesConfig): Promise<ReleaseResult | null> {
|
||||||
const [namespace, projectName] = packageName.split('.');
|
const [namespace, projectName] = packageName.split('.');
|
||||||
|
|
||||||
|
const repository =
|
||||||
|
repositoryRegex.exec(registryUrl!)?.groups?.repository ?? 'published';
|
||||||
|
|
||||||
const baseUrl = ensureTrailingSlash(
|
const baseUrl = ensureTrailingSlash(
|
||||||
joinUrlParts(
|
joinUrlParts(
|
||||||
registryUrl!,
|
registryUrl!,
|
||||||
'api/v3/plugin/ansible/content/published/collections/index',
|
'v3/plugin/ansible/content',
|
||||||
|
repository,
|
||||||
|
'collections/index',
|
||||||
namespace,
|
namespace,
|
||||||
projectName,
|
projectName,
|
||||||
),
|
),
|
||||||
|
|
32
lib/modules/datasource/galaxy-collection/readme.md
Normal file
32
lib/modules/datasource/galaxy-collection/readme.md
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
By default, the `galaxy-collection` datasource checks for dependencies on `https://galaxy.ansible.com`.
|
||||||
|
But you can override the default if you want.
|
||||||
|
|
||||||
|
Set your own registries by:
|
||||||
|
|
||||||
|
- setting a `source` in your `requirements.yaml` file, _or_
|
||||||
|
- writing a `packageRule` to set a new `registryURLs`
|
||||||
|
|
||||||
|
Then you can use Renovate with a private automation hub.
|
||||||
|
|
||||||
|
```yaml title="Example config for requirements.yaml"
|
||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: community.general
|
||||||
|
version: 3.0.0
|
||||||
|
source: https://hub.mydomain.com/api/galaxy/content/community/
|
||||||
|
```
|
||||||
|
|
||||||
|
```json title="Example config for renovate.json"
|
||||||
|
{
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"matchDatasources": ["galaxy-collection"],
|
||||||
|
"registryUrls": [
|
||||||
|
"https://hub.mydomain.com/api/galaxy/content/community/",
|
||||||
|
"https://hub.mydomain.com/api/galaxy/content/certified/",
|
||||||
|
"https://hub.mydomain.com/api/galaxy/content/myprivaterepo/"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
Loading…
Reference in a new issue