diff --git a/lib/config/types.ts b/lib/config/types.ts index 7de52aecf0750e8f7f83ce69bd54091087921a87..04a02bc91b08c465c116c71cdd739918c07df53c 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -264,7 +264,7 @@ export interface RenovateConfig export interface CustomDatasourceConfig { defaultRegistryUrlTemplate?: string; - format?: 'json' | 'plain'; + format?: 'json' | 'plain' | 'yaml'; transformTemplates?: string[]; } diff --git a/lib/modules/datasource/custom/formats/yaml.ts b/lib/modules/datasource/custom/formats/yaml.ts new file mode 100644 index 0000000000000000000000000000000000000000..baf67f10308008729e89d6ec839d6d86acec35c3 --- /dev/null +++ b/lib/modules/datasource/custom/formats/yaml.ts @@ -0,0 +1,9 @@ +import yaml from 'js-yaml'; + +import type { Http } from '../../../../util/http'; + +export async function fetch(http: Http, url: string): Promise<unknown> { + const response = await http.get(url); + + return yaml.load(response.body); +} diff --git a/lib/modules/datasource/custom/index.spec.ts b/lib/modules/datasource/custom/index.spec.ts index e6edfe1227c53a8aa78b76039064ed44651bde34..05eb3cb685bbf5b14a56384c3d55d9a317d3946a 100644 --- a/lib/modules/datasource/custom/index.spec.ts +++ b/lib/modules/datasource/custom/index.spec.ts @@ -1,3 +1,4 @@ +import { codeBlock } from 'common-tags'; import { getPkgReleases } from '..'; import * as httpMock from '../../../../test/http-mock'; import { CustomDatasource } from './index'; @@ -198,6 +199,46 @@ describe('modules/datasource/custom/index', () => { expect(result).toBeNull(); }); + it('return releases for yaml API directly exposing in Renovate format', async () => { + const expected = { + releases: [ + { + version: '1.0.0', + }, + { + version: '2.0.0', + }, + { + version: '3.0.0', + }, + ], + }; + + const yaml = codeBlock` + releases: + - version: 1.0.0 + - version: 2.0.0 + - version: 3.0.0 + `; + + httpMock.scope('https://example.com').get('/v1').reply(200, yaml, { + 'Content-Type': 'text/yaml', + }); + + const result = await getPkgReleases({ + datasource: `${CustomDatasource.id}.foo`, + packageName: 'myPackage', + customDatasources: { + foo: { + defaultRegistryUrlTemplate: 'https://example.com/v1', + format: 'yaml', + }, + }, + }); + + expect(result).toEqual(expected); + }); + it('return release when templating registryUrl', async () => { const expected = { releases: [ diff --git a/lib/modules/datasource/custom/index.ts b/lib/modules/datasource/custom/index.ts index 166e7958fe3dfbb75af22817eae7c40747d256b2..6d7167504e1b2169662eb30eae7f757ec1347dd7 100644 --- a/lib/modules/datasource/custom/index.ts +++ b/lib/modules/datasource/custom/index.ts @@ -4,6 +4,7 @@ import { logger } from '../../../logger'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; import { fetch as plainFetch } from './formats/plain'; +import { fetch as yamlFetch } from './formats/yaml'; import { ReleaseResultZodSchema } from './schema'; import { getCustomConfig } from './utils'; @@ -31,6 +32,9 @@ export class CustomDatasource extends Datasource { case 'plain': response = await plainFetch(this.http, defaultRegistryUrlTemplate); break; + case 'yaml': + response = await yamlFetch(this.http, defaultRegistryUrlTemplate); + break; case 'json': response = (await this.http.getJson(defaultRegistryUrlTemplate)).body; } diff --git a/lib/modules/datasource/custom/readme.md b/lib/modules/datasource/custom/readme.md index 288856418c300b87912f6f85fd9dba79a620d92c..0105766b3f51e41e555d0afaa53d3c7509c48581 100644 --- a/lib/modules/datasource/custom/readme.md +++ b/lib/modules/datasource/custom/readme.md @@ -118,6 +118,39 @@ When Renovate receives this response with the `plain` format, it will convert it After the conversion, any `jsonata` rules defined in the `transformTemplates` section will be applied as usual to further process the JSON data. +### Yaml + +If `yaml` is used, response is parsed and converted into JSON for further processing. + +Suppose the body of the HTTP response is as follows: + +```yaml +releases: + - version: 1.0.0 + - version: 2.0.0 + - version: 3.0.0 +``` + +When Renovate receives this response with the `yaml` format, it will convert it into the following: + +```json +{ + "releases": [ + { + "version": "1.0.0" + }, + { + "version": "2.0.0" + }, + { + "version": "3.0.0" + } + ] +} +``` + +After the conversion, any `jsonata` rules defined in the `transformTemplates` section will be applied as usual to further process the JSON data. + ## Examples ### K3s