diff --git a/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap b/lib/platform/gitea/__snapshots__/gitea-helper.spec.ts.snap index 9d40fd5b7d4d7d1423331901205b4ec1640dad44..500591aef747539252de31b01c35b0951d7a386e 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 225dcc3e5518ab33b140e672431c029af163faab..4095b539dc8004931ecf8018008351ce0ca66195 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 f0c9a0b36c12833d378a3cee3b23c6d544a39ed8..88e2bec406546311add2b229f6c36a3e2cbd9215 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 8d42f712ec1ba855aca4d0466934a43329f44150..d5ab8c01d8dcd1ca2cfb1af2ffe2a00650250f6f 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 a09a65b261d490e3893a0b40377afefc3534d27e..0458ff5758f7fe17a94c68a52e0eca3b2ddac9ee 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 ec07b151259977e53d55c5ae29137c8874586279..0363732eee9cc61fa7bc41f1e98b7c45bfbad532 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 748b072c16b8701daa7c2f95f133e4758010bf55..da190b10893409da0906d8ade34020f8422e1d60 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 240425ace74b9ff8481cd59c05d28ea23e6642e2..dc73dda2298009adc455b927d33f4f2fee128cc8 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>;