From 4afbc171801c1351cb4a89b1884861abe531b2dc Mon Sep 17 00:00:00 2001 From: Yash Oswal Date: Thu, 13 Jun 2024 19:51:34 +0530 Subject: [PATCH] feat(feedback): add support for jira component (#1813) - if jira/component is found in metadata annotations then add component field while creating jira ticket Signed-off-by: YashOswalYO --- .../feedback-backend/dist-dynamic/yarn.lock | 18 +++---- .../src/api/jiraApiService.test.ts | 8 +++- .../src/api/jiraApiService.ts | 48 ++++++++++++++----- .../feedback-backend/src/service/router.ts | 15 ++++-- 4 files changed, 64 insertions(+), 25 deletions(-) diff --git a/plugins/feedback-backend/dist-dynamic/yarn.lock b/plugins/feedback-backend/dist-dynamic/yarn.lock index e73701baa1..fc814dd49f 100644 --- a/plugins/feedback-backend/dist-dynamic/yarn.lock +++ b/plugins/feedback-backend/dist-dynamic/yarn.lock @@ -41,9 +41,9 @@ "@types/node" "*" "@types/express-serve-static-core@^4.17.33": - version "4.19.1" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.1.tgz#57d34698bb580720fd6e3c360d4b2fdef579b979" - integrity sha512-ej0phymbFLoCB26dbbq5PGScsf2JAJ4IJHjG10LalgUV36XKTmA4GdA+PVllKvRk0sEKt64X8975qFnkSi0hqA== + version "4.19.3" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz#e469a13e4186c9e1c0418fb17be8bc8ff1b19a7a" + integrity sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg== dependencies: "@types/node" "*" "@types/qs" "*" @@ -71,9 +71,9 @@ integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/node@*": - version "20.12.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.12.tgz#7cbecdf902085cec634fdb362172dfe12b8f2050" - integrity sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw== + version "20.14.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.2.tgz#a5f4d2bcb4b6a87bffcaa717718c5a0f208f4a18" + integrity sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q== dependencies: undici-types "~5.26.4" @@ -761,9 +761,9 @@ tr46@~0.0.3: integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + version "2.6.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== type-is@~1.6.18: version "1.6.18" diff --git a/plugins/feedback-backend/src/api/jiraApiService.test.ts b/plugins/feedback-backend/src/api/jiraApiService.test.ts index abf07344ba..fc03b214f0 100644 --- a/plugins/feedback-backend/src/api/jiraApiService.test.ts +++ b/plugins/feedback-backend/src/api/jiraApiService.test.ts @@ -1,3 +1,6 @@ +import { getRootLogger } from '@backstage/backend-common'; +import { LoggerService } from '@backstage/backend-plugin-api'; + import { rest } from 'msw'; import { setupServer } from 'msw/node'; @@ -26,6 +29,9 @@ const handlers = [ res(ctx.json(mockJiraTicketDetailsResp)), ), ]; +const logger: LoggerService = getRootLogger().child({ + service: 'feedback-backend', +}); describe('JIRA issue', () => { const mswMockServer = setupServer(); @@ -33,7 +39,7 @@ describe('JIRA issue', () => { mswMockServer.listen({ onUnhandledRequest: 'warn' }); const jiraHost = mockConfig.feedback.integrations.jira[0].host; const jiraToken = mockConfig.feedback.integrations.jira[0].token; - const jiraService = new JiraApiService(jiraHost, jiraToken); + const jiraService = new JiraApiService(jiraHost, jiraToken, logger); it('createJiraTicket', async () => { const data = await jiraService.createJiraTicket({ diff --git a/plugins/feedback-backend/src/api/jiraApiService.ts b/plugins/feedback-backend/src/api/jiraApiService.ts index f1a26d940d..a581535e46 100644 --- a/plugins/feedback-backend/src/api/jiraApiService.ts +++ b/plugins/feedback-backend/src/api/jiraApiService.ts @@ -1,14 +1,18 @@ +import { LoggerService } from '@backstage/backend-plugin-api'; + import axios from 'axios'; /** * @param host * @param authToken + * @param logger * @param hostType */ export class JiraApiService { constructor( private host: string, private authToken: string, + private logger: LoggerService, private hostType: string = 'SERVER', ) {} @@ -19,9 +23,17 @@ export class JiraApiService { tag: string; feedbackType: string; reporter?: string; + jiraComponent?: string; }): Promise => { - const { projectKey, summary, description, tag, feedbackType, reporter } = - options; + const { + projectKey, + summary, + description, + tag, + feedbackType, + reporter, + jiraComponent, + } = options; const requestBody = { fields: { ...(reporter && { @@ -41,19 +53,31 @@ export class JiraApiService { issuetype: { name: feedbackType === 'BUG' ? 'Bug' : 'Task', }, + ...(jiraComponent && { + components: [ + { + name: jiraComponent, + }, + ], + }), }, }; - const resp = await axios.post( - `${this.host}/rest/api/latest/issue`, - requestBody, - { - headers: { - Authorization: this.authToken, - 'Content-Type': 'application/json', + try { + const resp = await axios.post( + `${this.host}/rest/api/latest/issue`, + requestBody, + { + headers: { + Authorization: this.authToken, + 'Content-Type': 'application/json', + }, }, - }, - ); - return resp.data; + ); + return resp.data; + } catch (err: any) { + this.logger.error('Error:', err); + return {}; + } }; getJiraUsernameByEmail = async ( diff --git a/plugins/feedback-backend/src/service/router.ts b/plugins/feedback-backend/src/service/router.ts index 4985d2964f..b734980d47 100644 --- a/plugins/feedback-backend/src/service/router.ts +++ b/plugins/feedback-backend/src/service/router.ts @@ -137,7 +137,12 @@ export async function createRouter( const hostType = serviceConfig.getOptionalString('hostType'); const projectKey = entityRef.metadata.annotations['jira/project-key']; - const jiraService = new JiraApiService(host, authToken, hostType); + const jiraService = new JiraApiService( + host, + authToken, + logger, + hostType, + ); const jiraUsername = reporterEmail ? await jiraService.getJiraUsernameByEmail(reporterEmail) : undefined; @@ -160,9 +165,12 @@ export async function createRouter( tag: reqData.tag!.toLowerCase().split(' ').join('-'), feedbackType: reqData.feedbackType, reporter: jiraUsername, + jiraComponent: entityRef.metadata.annotations['jira/component'], }); - reqData.ticketUrl = `${host}/browse/${resp.key}`; - await feedbackDB.updateFeedback(reqData); + if (resp.key) { + reqData.ticketUrl = `${host}/browse/${resp.key}`; + await feedbackDB.updateFeedback(reqData); + } } if (type.toUpperCase() === 'MAIL' || replyTo) { @@ -292,6 +300,7 @@ export async function createRouter( const resp = await new JiraApiService( host, authToken, + logger, ).getTicketDetails(ticketId); return res.status(200).json({ data: { ...resp },