From 4a99883048843fbb7504bd7cd47fb7b73540156c Mon Sep 17 00:00:00 2001 From: Rhys Arkins <rhys@arkins.net> Date: Wed, 16 Jun 2021 15:53:50 +0200 Subject: [PATCH] feat(platform): getIssue (#10453) --- .../__snapshots__/gitea-helper.spec.ts.snap | 15 +++++++++ lib/platform/gitea/gitea-helper.spec.ts | 13 ++++++++ lib/platform/gitea/gitea-helper.ts | 10 ++++++ lib/platform/gitea/index.spec.ts | 14 +++++++++ lib/platform/gitea/index.ts | 25 +++++++++++++-- lib/platform/github/index.ts | 31 +++++++++++++------ lib/platform/gitlab/index.ts | 31 +++++++++++++------ lib/platform/types.ts | 1 + 8 files changed, 119 insertions(+), 21 deletions(-) diff --git a/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap b/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap index 9d40fd5b7d..500591aef7 100644 --- a/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap +++ b/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap @@ -456,6 +456,21 @@ Array [ ] `; +exports[`platform/gitea/gitea-helper getIssue should call /api/v1/repos/[repo]/issues/[issue] endpoint 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "host": "gitea.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://gitea.renovatebot.com/api/v1/repos/some/repo/issues/7", + }, +] +`; + exports[`platform/gitea/gitea-helper getOrgLabels should call /api/v1/orgs/[org]/labels endpoint 1`] = ` Array [ Object { diff --git a/lib/platform/gitea/gitea-helper.spec.ts b/lib/platform/gitea/gitea-helper.spec.ts index 225dcc3e55..4095b539dc 100644 --- a/lib/platform/gitea/gitea-helper.spec.ts +++ b/lib/platform/gitea/gitea-helper.spec.ts @@ -508,6 +508,19 @@ describe(getName(), () => { }); }); + describe('getIssue', () => { + it('should call /api/v1/repos/[repo]/issues/[issue] endpoint', async () => { + httpMock + .scope(baseUrl) + .get(`/repos/${mockRepo.full_name}/issues/${mockIssue.number}`) + .reply(200, mockIssue); + + const res = await ght.getIssue(mockRepo.full_name, mockIssue.number); + expect(res).toEqual(mockIssue); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + }); + describe('getRepoLabels', () => { it('should call /api/v1/repos/[repo]/labels endpoint', async () => { httpMock diff --git a/lib/platform/gitea/gitea-helper.ts b/lib/platform/gitea/gitea-helper.ts index f0c9a0b36c..88e2bec406 100644 --- a/lib/platform/gitea/gitea-helper.ts +++ b/lib/platform/gitea/gitea-helper.ts @@ -400,6 +400,16 @@ export async function searchIssues( return res.body; } +export async function getIssue( + repoPath: string, + idx: number, + options?: GiteaHttpOptions +): Promise<Issue> { + const url = `repos/${repoPath}/issues/${idx}`; + const res = await giteaHttp.getJson<Issue>(url, options); + return res.body; +} + export async function getRepoLabels( repoPath: string, options?: GiteaHttpOptions diff --git a/lib/platform/gitea/index.spec.ts b/lib/platform/gitea/index.spec.ts index 8d42f712ec..d5ab8c01d8 100644 --- a/lib/platform/gitea/index.spec.ts +++ b/lib/platform/gitea/index.spec.ts @@ -905,10 +905,24 @@ describe(getName(), () => { }); }); + describe('getIssue', () => { + it('should return the issue', async () => { + const mockIssue = mockIssues.find((i) => i.number === 1); + helper.getIssue.mockResolvedValueOnce(mockIssue); + await initFakeRepo(); + + expect(await gitea.getIssue(mockIssue.number)).toHaveProperty( + 'number', + mockIssue.number + ); + }); + }); + describe('findIssue', () => { it('should return existing open issue', async () => { const mockIssue = mockIssues.find((i) => i.title === 'open-issue'); helper.searchIssues.mockResolvedValueOnce(mockIssues); + helper.getIssue.mockResolvedValueOnce(mockIssue); await initFakeRepo(); expect(await gitea.findIssue(mockIssue.title)).toHaveProperty( diff --git a/lib/platform/gitea/index.ts b/lib/platform/gitea/index.ts index a09a65b261..0458ff5758 100644 --- a/lib/platform/gitea/index.ts +++ b/lib/platform/gitea/index.ts @@ -587,16 +587,34 @@ const platform: Platform = { return config.issueList; }, + async getIssue(number: number, useCache = true): Promise<Issue> { + try { + const body = ( + await helper.getIssue(config.repository, number, { + useCache, + }) + ).body; + return { + number, + body, + }; + } catch (err) /* istanbul ignore next */ { + logger.debug({ err, number }, 'Error getting issue'); + return null; + } + }, + async findIssue(title: string): Promise<Issue> { const issueList = await platform.getIssueList(); const issue = issueList.find( (i) => i.state === 'open' && i.title === title ); - if (issue) { - logger.debug(`Found Issue #${issue.number}`); + if (!issue) { + return null; } - return issue ?? null; + logger.debug(`Found Issue #${issue.number}`); + return platform.getIssue(issue.number); }, async ensureIssue({ @@ -836,6 +854,7 @@ export const { getBranchPr, getBranchStatus, getBranchStatusCheck, + getIssue, getRawFile, getJsonFile, getIssueList, diff --git a/lib/platform/github/index.ts b/lib/platform/github/index.ts index ec07b15125..0363732eee 100644 --- a/lib/platform/github/index.ts +++ b/lib/platform/github/index.ts @@ -1105,6 +1105,27 @@ export async function getIssueList(): Promise<Issue[]> { return config.issueList; } +export async function getIssue( + number: number, + useCache = true +): Promise<Issue | null> { + try { + const issueBody = ( + await githubApi.getJson<{ body: string }>( + `repos/${config.parentRepo || config.repository}/issues/${number}`, + { useCache } + ) + ).body.body; + return { + number, + body: issueBody, + }; + } catch (err) /* istanbul ignore next */ { + logger.debug({ err, number }, 'Error getting issue'); + return null; + } +} + export async function findIssue(title: string): Promise<Issue | null> { logger.debug(`findIssue(${title})`); const [issue] = (await getIssueList()).filter( @@ -1114,15 +1135,7 @@ export async function findIssue(title: string): Promise<Issue | null> { return null; } logger.debug(`Found issue ${issue.number}`); - const issueBody = ( - await githubApi.getJson<{ body: string }>( - `repos/${config.parentRepo || config.repository}/issues/${issue.number}` - ) - ).body.body; - return { - number: issue.number, - body: issueBody, - }; + return getIssue(issue.number); } async function closeIssue(issueNumber: number): Promise<void> { diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts index 748b072c16..da190b1089 100755 --- a/lib/platform/gitlab/index.ts +++ b/lib/platform/gitlab/index.ts @@ -753,23 +753,36 @@ export async function getIssueList(): Promise<GitlabIssue[]> { return config.issueList; } -export async function findIssue(title: string): Promise<Issue | null> { - logger.debug(`findIssue(${title})`); +export async function getIssue( + number: number, + useCache = true +): Promise<Issue | null> { try { - const issueList = await getIssueList(); - const issue = issueList.find((i) => i.title === title); - if (!issue) { - return null; - } const issueBody = ( await gitlabApi.getJson<{ description: string }>( - `projects/${config.repository}/issues/${issue.iid}` + `projects/${config.repository}/issues/${number}`, + { useCache } ) ).body.description; return { - number: issue.iid, + number, body: issueBody, }; + } catch (err) /* istanbul ignore next */ { + logger.debug({ err, number }, 'Error getting issue'); + return null; + } +} + +export async function findIssue(title: string): Promise<Issue | null> { + logger.debug(`findIssue(${title})`); + try { + const issueList = await getIssueList(); + const issue = issueList.find((i) => i.title === title); + if (!issue) { + return null; + } + return getIssue(issue.iid); } catch (err) /* istanbul ignore next */ { logger.warn('Error finding issue'); return null; diff --git a/lib/platform/types.ts b/lib/platform/types.ts index 240425ace7..dc73dda229 100644 --- a/lib/platform/types.ts +++ b/lib/platform/types.ts @@ -139,6 +139,7 @@ export type EnsureIssueResult = 'updated' | 'created'; export interface Platform { findIssue(title: string): Promise<Issue | null>; getIssueList(): Promise<Issue[]>; + getIssue?(number: number, useCache?: boolean): Promise<Issue>; getVulnerabilityAlerts(): Promise<VulnerabilityAlert[]>; getRawFile(fileName: string, repo?: string): Promise<string | null>; getJsonFile(fileName: string, repo?: string): Promise<any | null>; -- GitLab