Skip to content
Snippets Groups Projects
Unverified Commit 997909d6 authored by Michael Kriese's avatar Michael Kriese Committed by GitHub
Browse files

feat(presets): allow sub presets for gitlab (#6238)

parent 51a4a720
No related branches found
No related tags found
No related merge requests found
...@@ -20,12 +20,12 @@ Array [ ...@@ -20,12 +20,12 @@ Array [
"user-agent": "https://github.com/renovatebot/renovate", "user-agent": "https://github.com/renovatebot/renovate",
}, },
"method": "GET", "method": "GET",
"url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/files/renovate.json?ref=master", "url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/files/default.json/raw?ref=master",
}, },
] ]
`; `;
exports[`config/presets/gitlab/index getPreset() throws if fails to parse 1`] = ` exports[`config/presets/gitlab/index getPreset() throws if missing 1`] = `
Array [ Array [
Object { Object {
"headers": Object { "headers": Object {
...@@ -45,12 +45,32 @@ Array [ ...@@ -45,12 +45,32 @@ Array [
"user-agent": "https://github.com/renovatebot/renovate", "user-agent": "https://github.com/renovatebot/renovate",
}, },
"method": "GET", "method": "GET",
"url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/files/renovate.json?ref=master", "url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/files/default.json/raw?ref=master",
},
Object {
"headers": Object {
"accept": "application/json",
"accept-encoding": "gzip, deflate",
"host": "gitlab.com",
"user-agent": "https://github.com/renovatebot/renovate",
},
"method": "GET",
"url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/branches",
},
Object {
"headers": Object {
"accept": "application/json",
"accept-encoding": "gzip, deflate",
"host": "gitlab.com",
"user-agent": "https://github.com/renovatebot/renovate",
},
"method": "GET",
"url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/files/renovate.json/raw?ref=master",
}, },
] ]
`; `;
exports[`config/presets/gitlab/index getPreset() throws if no content 1`] = ` exports[`config/presets/gitlab/index getPreset() throws platform-failure 1`] = `
Array [ Array [
Object { Object {
"headers": Object { "headers": Object {
...@@ -65,8 +85,6 @@ Array [ ...@@ -65,8 +85,6 @@ Array [
] ]
`; `;
exports[`config/presets/gitlab/index getPreset() throws if not default 1`] = `Array []`;
exports[`config/presets/gitlab/index getPresetFromEndpoint() uses custom endpoint 1`] = ` exports[`config/presets/gitlab/index getPresetFromEndpoint() uses custom endpoint 1`] = `
Array [ Array [
Object { Object {
...@@ -87,7 +105,7 @@ Array [ ...@@ -87,7 +105,7 @@ Array [
"user-agent": "https://github.com/renovatebot/renovate", "user-agent": "https://github.com/renovatebot/renovate",
}, },
"method": "GET", "method": "GET",
"url": "https://gitlab.example.org/api/v4/projects/some%2Frepo/repository/files/renovate.json?ref=devel", "url": "https://gitlab.example.org/api/v4/projects/some%2Frepo/repository/files/some.json/raw?ref=devel",
}, },
] ]
`; `;
...@@ -112,7 +130,7 @@ Array [ ...@@ -112,7 +130,7 @@ Array [
"user-agent": "https://github.com/renovatebot/renovate", "user-agent": "https://github.com/renovatebot/renovate",
}, },
"method": "GET", "method": "GET",
"url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/files/renovate.json?ref=devel", "url": "https://gitlab.com/api/v4/projects/some%2Frepo/repository/files/some.json/raw?ref=devel",
}, },
] ]
`; `;
import * as httpMock from '../../../../test/httpMock'; import * as httpMock from '../../../../test/httpMock';
import { getName } from '../../../../test/util'; import { getName } from '../../../../test/util';
import { PLATFORM_FAILURE } from '../../../constants/error-messages';
import { PRESET_DEP_NOT_FOUND } from '../util';
import * as gitlab from '.'; import * as gitlab from '.';
const gitlabApiHost = 'https://gitlab.com'; const gitlabApiHost = 'https://gitlab.com';
...@@ -16,38 +18,30 @@ describe(getName(__filename), () => { ...@@ -16,38 +18,30 @@ describe(getName(__filename), () => {
}); });
describe('getPreset()', () => { describe('getPreset()', () => {
it('throws if no content', async () => { it('throws platform-failure', async () => {
httpMock.scope(gitlabApiHost).get(`${basePath}/branches`).reply(500, {}); httpMock.scope(gitlabApiHost).get(`${basePath}/branches`).reply(500);
await expect(
gitlab.getPreset({
packageName: 'some/repo',
presetName: 'default',
})
).rejects.toThrow();
expect(httpMock.getTrace()).toMatchSnapshot();
});
it('throws if not default', async () => {
await expect( await expect(
gitlab.getPreset({ gitlab.getPreset({
packageName: 'some/repo', packageName: 'some/repo',
presetName: 'non-default', presetName: 'non-default',
}) })
).rejects.toThrow(); ).rejects.toThrow(PLATFORM_FAILURE);
expect(httpMock.getTrace()).toMatchSnapshot(); expect(httpMock.getTrace()).toMatchSnapshot();
}); });
it('throws if fails to parse', async () => { it('throws if missing', async () => {
httpMock httpMock
.scope(gitlabApiHost) .scope(gitlabApiHost)
.get(`${basePath}/branches`) .get(`${basePath}/branches`)
.twice()
.reply(200, []) .reply(200, [])
.get(`${basePath}/files/renovate.json?ref=master`) .get(`${basePath}/files/default.json/raw?ref=master`)
.reply(200, { content: Buffer.from('not json').toString('base64') }); .reply(404, null)
.get(`${basePath}/files/renovate.json/raw?ref=master`)
.reply(404, null);
await expect( await expect(
gitlab.getPreset({ packageName: 'some/repo' }) gitlab.getPreset({ packageName: 'some/repo' })
).rejects.toThrow(); ).rejects.toThrow(PRESET_DEP_NOT_FOUND);
expect(httpMock.getTrace()).toMatchSnapshot(); expect(httpMock.getTrace()).toMatchSnapshot();
}); });
...@@ -64,14 +58,8 @@ describe(getName(__filename), () => { ...@@ -64,14 +58,8 @@ describe(getName(__filename), () => {
default: true, default: true,
}, },
]) ])
.get(`${basePath}/files/renovate.json?ref=master`) .get(`${basePath}/files/default.json/raw?ref=master`)
.reply( .reply(200, { foo: 'bar' }, {});
200,
{
content: Buffer.from('{"foo":"bar"}').toString('base64'),
},
{}
);
const content = await gitlab.getPreset({ packageName: 'some/repo' }); const content = await gitlab.getPreset({ packageName: 'some/repo' });
expect(content).toEqual({ foo: 'bar' }); expect(content).toEqual({ foo: 'bar' });
...@@ -90,10 +78,10 @@ describe(getName(__filename), () => { ...@@ -90,10 +78,10 @@ describe(getName(__filename), () => {
default: true, default: true,
}, },
]) ])
.get(`${basePath}/files/renovate.json?ref=devel`) .get(`${basePath}/files/some.json/raw?ref=devel`)
.reply(200, { content: Buffer.from('{}').toString('base64') }); .reply(200, { preset: { file: {} } });
expect( expect(
await gitlab.getPresetFromEndpoint('some/repo', 'default') await gitlab.getPresetFromEndpoint('some/repo', 'some/preset/file')
).toEqual({}); ).toEqual({});
expect(httpMock.getTrace()).toMatchSnapshot(); expect(httpMock.getTrace()).toMatchSnapshot();
}); });
...@@ -108,15 +96,15 @@ describe(getName(__filename), () => { ...@@ -108,15 +96,15 @@ describe(getName(__filename), () => {
default: true, default: true,
}, },
]) ])
.get(`${basePath}/files/renovate.json?ref=devel`) .get(`${basePath}/files/some.json/raw?ref=devel`)
.reply(404); .reply(404);
await expect( await expect(
gitlab.getPresetFromEndpoint( gitlab.getPresetFromEndpoint(
'some/repo', 'some/repo',
'default', 'some/preset/file',
'https://gitlab.example.org/api/v4' 'https://gitlab.example.org/api/v4'
) )
).rejects.toThrow(); ).rejects.toThrow(PRESET_DEP_NOT_FOUND);
expect(httpMock.getTrace()).toMatchSnapshot(); expect(httpMock.getTrace()).toMatchSnapshot();
}); });
}); });
......
import { PLATFORM_FAILURE } from '../../../constants/error-messages';
import { logger } from '../../../logger'; import { logger } from '../../../logger';
import type { GitLabBranch } from '../../../types/platform/gitlab';
import { GitlabHttp } from '../../../util/http/gitlab'; import { GitlabHttp } from '../../../util/http/gitlab';
import { ensureTrailingSlash } from '../../../util/url';
import { Preset, PresetConfig } from '../common'; import { Preset, PresetConfig } from '../common';
import { PRESET_DEP_NOT_FOUND, fetchPreset } from '../util';
const gitlabApi = new GitlabHttp(); const gitlabApi = new GitlabHttp();
export const Endpoint = 'https://gitlab.com/api/v4/';
async function getDefaultBranchName( async function getDefaultBranchName(
urlEncodedPkgName: string, urlEncodedPkgName: string,
endpoint: string endpoint: string
): Promise<string> { ): Promise<string> {
const branchesUrl = `${endpoint}projects/${urlEncodedPkgName}/repository/branches`; const branchesUrl = `${endpoint}projects/${urlEncodedPkgName}/repository/branches`;
type GlBranch = {
default: boolean;
name: string;
}[];
const res = await gitlabApi.getJson<GlBranch>(branchesUrl); const res = await gitlabApi.getJson<GitLabBranch[]>(branchesUrl);
const branches = res.body; const branches = res.body;
let defautlBranchName = 'master'; let defautlBranchName = 'master';
for (const branch of branches) { for (const branch of branches) {
...@@ -28,48 +27,48 @@ async function getDefaultBranchName( ...@@ -28,48 +27,48 @@ async function getDefaultBranchName(
return defautlBranchName; return defautlBranchName;
} }
export async function getPresetFromEndpoint( export async function fetchJSONFile(
pkgName: string, repo: string,
presetName: string, fileName: string,
endpoint = 'https://gitlab.com/api/v4/' endpoint: string
): Promise<Preset> { ): Promise<Preset> {
// eslint-disable-next-line no-param-reassign
endpoint = ensureTrailingSlash(endpoint);
if (presetName !== 'default') {
// TODO: proper error contructor
throw new Error(
// { pkgName, presetName },
'Sub-preset names are not supported with Gitlab datasource'
);
}
let res: string;
try { try {
const urlEncodedPkgName = encodeURIComponent(pkgName); const urlEncodedRepo = encodeURIComponent(repo);
const urlEncodedPkgName = encodeURIComponent(fileName);
const defautlBranchName = await getDefaultBranchName( const defautlBranchName = await getDefaultBranchName(
urlEncodedPkgName, urlEncodedRepo,
endpoint endpoint
); );
const url = `${endpoint}projects/${urlEncodedRepo}/repository/files/${urlEncodedPkgName}/raw?ref=${defautlBranchName}`;
const presetUrl = `${endpoint}projects/${urlEncodedPkgName}/repository/files/renovate.json?ref=${defautlBranchName}`; return (await gitlabApi.getJson<Preset>(url)).body;
res = Buffer.from(
(await gitlabApi.getJson<{ content: string }>(presetUrl)).body.content,
'base64'
).toString();
} catch (err) { } catch (err) {
logger.debug({ err }, 'Failed to retrieve renovate.json from repo'); if (err.message === PLATFORM_FAILURE) {
throw new Error('dep not found'); throw err;
}
logger.debug(
{ statusCode: err.statusCode },
`Failed to retrieve ${fileName} from repo`
);
throw new Error(PRESET_DEP_NOT_FOUND);
} }
try {
return JSON.parse(res);
} catch (err) /* istanbul ignore next */ {
logger.debug('Failed to parse renovate.json');
throw new Error('invalid preset JSON');
} }
export async function getPresetFromEndpoint(
pkgName: string,
presetName: string,
endpoint = Endpoint
): Promise<Preset> {
return fetchPreset({
pkgName,
filePreset: presetName,
endpoint,
fetch: fetchJSONFile,
});
} }
export function getPreset({ export function getPreset({
packageName: pkgName, packageName: pkgName,
presetName = 'default', presetName = 'default',
}: PresetConfig): Promise<Preset> { }: PresetConfig): Promise<Preset> {
return getPresetFromEndpoint(pkgName, presetName); return getPresetFromEndpoint(pkgName, presetName, Endpoint);
} }
export type GitLabBranch = {
default: boolean;
name: string;
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment