Skip to content

Commit

Permalink
feat(presets): allow sub presets for gitlab (#6238)
Browse files Browse the repository at this point in the history
  • Loading branch information
viceice authored Jun 9, 2020
1 parent 51a4a72 commit 997909d
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 77 deletions.
34 changes: 26 additions & 8 deletions lib/config/presets/gitlab/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ Array [
"user-agent": "https://github.com/renovatebot/renovate",
},
"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 [
Object {
"headers": Object {
Expand All @@ -45,12 +45,32 @@ Array [
"user-agent": "https://github.com/renovatebot/renovate",
},
"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 [
Object {
"headers": Object {
Expand All @@ -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`] = `
Array [
Object {
Expand All @@ -87,7 +105,7 @@ Array [
"user-agent": "https://github.com/renovatebot/renovate",
},
"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",
},
]
`;
Expand All @@ -112,7 +130,7 @@ Array [
"user-agent": "https://github.com/renovatebot/renovate",
},
"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",
},
]
`;
52 changes: 20 additions & 32 deletions lib/config/presets/gitlab/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as httpMock from '../../../../test/httpMock';
import { getName } from '../../../../test/util';
import { PLATFORM_FAILURE } from '../../../constants/error-messages';
import { PRESET_DEP_NOT_FOUND } from '../util';
import * as gitlab from '.';

const gitlabApiHost = 'https://gitlab.com';
Expand All @@ -16,38 +18,30 @@ describe(getName(__filename), () => {
});

describe('getPreset()', () => {
it('throws if no content', async () => {
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 () => {
it('throws platform-failure', async () => {
httpMock.scope(gitlabApiHost).get(`${basePath}/branches`).reply(500);
await expect(
gitlab.getPreset({
packageName: 'some/repo',
presetName: 'non-default',
})
).rejects.toThrow();
).rejects.toThrow(PLATFORM_FAILURE);
expect(httpMock.getTrace()).toMatchSnapshot();
});

it('throws if fails to parse', async () => {
it('throws if missing', async () => {
httpMock
.scope(gitlabApiHost)
.get(`${basePath}/branches`)
.twice()
.reply(200, [])
.get(`${basePath}/files/renovate.json?ref=master`)
.reply(200, { content: Buffer.from('not json').toString('base64') });

.get(`${basePath}/files/default.json/raw?ref=master`)
.reply(404, null)
.get(`${basePath}/files/renovate.json/raw?ref=master`)
.reply(404, null);
await expect(
gitlab.getPreset({ packageName: 'some/repo' })
).rejects.toThrow();
).rejects.toThrow(PRESET_DEP_NOT_FOUND);
expect(httpMock.getTrace()).toMatchSnapshot();
});

Expand All @@ -64,14 +58,8 @@ describe(getName(__filename), () => {
default: true,
},
])
.get(`${basePath}/files/renovate.json?ref=master`)
.reply(
200,
{
content: Buffer.from('{"foo":"bar"}').toString('base64'),
},
{}
);
.get(`${basePath}/files/default.json/raw?ref=master`)
.reply(200, { foo: 'bar' }, {});

const content = await gitlab.getPreset({ packageName: 'some/repo' });
expect(content).toEqual({ foo: 'bar' });
Expand All @@ -90,10 +78,10 @@ describe(getName(__filename), () => {
default: true,
},
])
.get(`${basePath}/files/renovate.json?ref=devel`)
.reply(200, { content: Buffer.from('{}').toString('base64') });
.get(`${basePath}/files/some.json/raw?ref=devel`)
.reply(200, { preset: { file: {} } });
expect(
await gitlab.getPresetFromEndpoint('some/repo', 'default')
await gitlab.getPresetFromEndpoint('some/repo', 'some/preset/file')
).toEqual({});
expect(httpMock.getTrace()).toMatchSnapshot();
});
Expand All @@ -108,15 +96,15 @@ describe(getName(__filename), () => {
default: true,
},
])
.get(`${basePath}/files/renovate.json?ref=devel`)
.get(`${basePath}/files/some.json/raw?ref=devel`)
.reply(404);
await expect(
gitlab.getPresetFromEndpoint(
'some/repo',
'default',
'some/preset/file',
'https://gitlab.example.org/api/v4'
)
).rejects.toThrow();
).rejects.toThrow(PRESET_DEP_NOT_FOUND);
expect(httpMock.getTrace()).toMatchSnapshot();
});
});
Expand Down
73 changes: 36 additions & 37 deletions lib/config/presets/gitlab/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { PLATFORM_FAILURE } from '../../../constants/error-messages';
import { logger } from '../../../logger';
import type { GitLabBranch } from '../../../types/platform/gitlab';
import { GitlabHttp } from '../../../util/http/gitlab';
import { ensureTrailingSlash } from '../../../util/url';
import { Preset, PresetConfig } from '../common';
import { PRESET_DEP_NOT_FOUND, fetchPreset } from '../util';

const gitlabApi = new GitlabHttp();
export const Endpoint = 'https://gitlab.com/api/v4/';

async function getDefaultBranchName(
urlEncodedPkgName: string,
endpoint: string
): Promise<string> {
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;
let defautlBranchName = 'master';
for (const branch of branches) {
Expand All @@ -28,48 +27,48 @@ async function getDefaultBranchName(
return defautlBranchName;
}

export async function getPresetFromEndpoint(
pkgName: string,
presetName: string,
endpoint = 'https://gitlab.com/api/v4/'
export async function fetchJSONFile(
repo: string,
fileName: string,
endpoint: string
): 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 {
const urlEncodedPkgName = encodeURIComponent(pkgName);
const urlEncodedRepo = encodeURIComponent(repo);
const urlEncodedPkgName = encodeURIComponent(fileName);
const defautlBranchName = await getDefaultBranchName(
urlEncodedPkgName,
urlEncodedRepo,
endpoint
);

const presetUrl = `${endpoint}projects/${urlEncodedPkgName}/repository/files/renovate.json?ref=${defautlBranchName}`;
res = Buffer.from(
(await gitlabApi.getJson<{ content: string }>(presetUrl)).body.content,
'base64'
).toString();
const url = `${endpoint}projects/${urlEncodedRepo}/repository/files/${urlEncodedPkgName}/raw?ref=${defautlBranchName}`;
return (await gitlabApi.getJson<Preset>(url)).body;
} catch (err) {
logger.debug({ err }, 'Failed to retrieve renovate.json from repo');
throw new Error('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');
if (err.message === PLATFORM_FAILURE) {
throw err;
}
logger.debug(
{ statusCode: err.statusCode },
`Failed to retrieve ${fileName} from repo`
);
throw new Error(PRESET_DEP_NOT_FOUND);
}
}

export async function getPresetFromEndpoint(
pkgName: string,
presetName: string,
endpoint = Endpoint
): Promise<Preset> {
return fetchPreset({
pkgName,
filePreset: presetName,
endpoint,
fetch: fetchJSONFile,
});
}

export function getPreset({
packageName: pkgName,
presetName = 'default',
}: PresetConfig): Promise<Preset> {
return getPresetFromEndpoint(pkgName, presetName);
return getPresetFromEndpoint(pkgName, presetName, Endpoint);
}
4 changes: 4 additions & 0 deletions lib/types/platform/gitlab/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type GitLabBranch = {
default: boolean;
name: string;
};

0 comments on commit 997909d

Please sign in to comment.