Skip to content

Commit

Permalink
feat(report-portal): added report portal frontend and backend plugins
Browse files Browse the repository at this point in the history
Signed-off-by: Yash Oswal <[email protected]>

feat(report-portal): add global page for report portal plugin (#1)

- added Instances Page
- added Projects Page
- added Launches Page
- Updated Report Portal API
- Added api pagination for table
- fixed tsc and lint issues in backend plugin
- added Readme files for both plugins
- added report portal icon componet (#2)

fix(report-portal): Fixed search for projects page (#3)

- fix(report-portal): Fixed search for projects page
- Added request to add button on instances page
- Updated readme

- fix(report-portal): yarn tsc issue

---------

Signed-off-by: Yash Oswal <[email protected]>
  • Loading branch information
yashoswalyo committed Jun 19, 2024
1 parent 2a2eccb commit d894726
Show file tree
Hide file tree
Showing 58 changed files with 2,317 additions and 24 deletions.
1 change: 1 addition & 0 deletions plugins/report-portal-backend/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
8 changes: 8 additions & 0 deletions plugins/report-portal-backend/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
approvers:
- yashoswalyo
- riginoommen
- deshmukhmayur
reviewers:
- yashoswalyo
- riginoommen
- deshmukhmayur
75 changes: 75 additions & 0 deletions plugins/report-portal-backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# report-portal

Welcome to the report-portal backend plugin!

_This plugin was created through the Backstage CLI_

## Getting started

Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn
start` in the root directory, and then navigating to [/report-portal](http://localhost:3000/report-portal).

You can also serve the plugin in isolation by running `yarn start` in the plugin directory.
This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads.
It is only meant for local development, and the setup for it can be found inside the [/dev](/dev) directory.

## Installation

- Install the plugin
```shell
yarn workspace backend add @appdev-platform/backstage-plugin-report-portal-backend
```
- Update the following files

- Create `/packages/backend/src/plugins/report-portal.ts` and add following code:

```ts
import { createRouter } from '@appdev-platform/backstage-plugin-report-portal-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
return await createRouter({ logger: env.logger, config: env.config });
}
```
- Add following lines to `/packages/backend/src/index.ts`:
```ts
import reportPortal from './plugins/report-portal';
async function main() {
// add the files to create backend router
const reportPortalEnv = useHotMemoize(module, () =>
createEnv('report-portal'),
);
apiRouter.use('/report-portal', await reportPortal(reportPortalEnv));
}
```
- Add below configuration to `app-config.yaml`:
```yaml
reportPortal:
# under integrations you can configure-
# multiple instances of report portal
integrations:
# host address of your instance
# for e.g: report-portal.mycorp.com
- host: ${REPORT_PORTAL_HOST}
# Baser API url of your instance
# for e.g: https://report-portal.mycorp.com/api/
baseUrl: ${REPORT_PORTAL_BASE_URL}
# Get the API key from profile page of your instance
# for e.g: Bearer fae22be1-0000-0000-8392-de1635eed9f4
token: ${REPORT_PORTAL_TOKEN}
# (optional) Filter the projects by type
# Default: "INTERNAL"
filterType: 'INTERNAL'
```
6 changes: 6 additions & 0 deletions plugins/report-portal-backend/app-config.janus-idp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
reportPortal:
integrations:
- host: ${REPORT_PORTAL_HOST}
baseUrl: ${REPORT_PORTAL_BASE_URL}
token: ${REPORT_PORTAL_TOKEN}
filterType: ${REPORT_PORTAL_FILTER_TYPE}
28 changes: 28 additions & 0 deletions plugins/report-portal-backend/config.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export interface Config {
/**
* Configuration values for Report Portal plugin
*/
reportPortal: {
integrations: Array<{
/**
* Host of report portal url
* @visibility frontend
*/
host: string;
/**
* Base api url for report portal instance
*/
baseUrl: string;
/**
* The Api token that will be used to
* @visibility secret
*/
token: string;
/**
* Filter type to apply for current host
* @visibility frontend
*/
filterType: string;
}>;
};
}
82 changes: 82 additions & 0 deletions plugins/report-portal-backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"name": "@appdev-platform/backstage-plugin-report-portal-backend",
"version": "0.1.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"publishConfig": {
"access": "public",
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts"
},
"backstage": {
"role": "backend-plugin"
},
"exports": {
".": "./src/index.ts",
"./alpha": "./src/alpha.ts",
"./package.json": "./package.json"
},
"typesVersions": {
"*": {
"alpha": [
"src/alpha.ts"
],
"package.json": [
"package.json"
]
}
},
"scripts": {
"build": "backstage-cli package build",
"clean": "backstage-cli package clean",
"export-dynamic": "janus-cli package export-dynamic-plugin",
"lint": "backstage-cli package lint",
"postpack": "backstage-cli package postpack",
"postversion": "yarn run export-dynamic",
"prepack": "backstage-cli package prepack",
"start": "backstage-cli package start",
"test": "backstage-cli package test --passWithNoTests --coverage",
"tsc": "tsc"
},
"dependencies": {
"@backstage/backend-common": "^0.21.0",
"@backstage/backend-plugin-api": "^0.6.6",
"@backstage/backend-plugin-manager": "npm:@janus-idp/[email protected]",
"@backstage/config": "^1.1.1",
"@types/express": "^*",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"http-proxy-middleware": "^2.0.6",
"node-fetch": "^2.6.7",
"winston": "^3.2.1",
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "0.23.0",
"@janus-idp/cli": "1.7.1",
"@types/supertest": "2.0.12",
"msw": "1.0.0",
"supertest": "6.2.4"
},
"files": [
"dist",
"config.d.ts",
"dist-dynamic/*.*",
"dist-dynamic/dist/**",
"dist-dynamic/alpha/*",
"app-config.janus-idp.yaml"
],
"configSchema": "config.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/appdev-platform/backstage-plugins",
"directory": "plugins/report-portal-backend"
},
"keywords": [
"backstage",
"plugin"
],
"homepage": "https://janus-idp.io/",
"bugs": "https://github.com/appdev-platform/backstage-plugins/issues"
}
1 change: 1 addition & 0 deletions plugins/report-portal-backend/src/alpha.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { reportPortalPlugin as default } from './plugin';
11 changes: 11 additions & 0 deletions plugins/report-portal-backend/src/dynamic/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { BackendDynamicPluginInstaller } from '@backstage/backend-plugin-manager';

import { createRouter } from '../service/router';

export const dynamicPluginInstaller: BackendDynamicPluginInstaller = {
kind: 'legacy',
router: {
pluginID: 'report-portal',
createPlugin: createRouter,
},
};
8 changes: 8 additions & 0 deletions plugins/report-portal-backend/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* The report-portal backend plugin.
*
* @packageDocumentation
*/

export * from './dynamic/index';
export * from './service/router';
33 changes: 33 additions & 0 deletions plugins/report-portal-backend/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { loggerToWinstonLogger } from '@backstage/backend-common';
import {
coreServices,
createBackendPlugin,
} from '@backstage/backend-plugin-api';

import { createRouter } from './service/router';

/**
* The report-portal backend plugin.
*
* @alpha
*/
export const reportPortalPlugin = createBackendPlugin({
pluginId: 'report-portal',
register(env) {
env.registerInit({
deps: {
logger: coreServices.logger,
config: coreServices.rootConfig,
http: coreServices.httpRouter,
},
async init({ config, logger, http }) {
http.use(() =>
createRouter({
config: config,
logger: loggerToWinstonLogger(logger),
}),
);
},
});
},
});
19 changes: 19 additions & 0 deletions plugins/report-portal-backend/src/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getRootLogger } from '@backstage/backend-common';

import yn from 'yn';

import { startStandaloneServer } from './service/standaloneServer';

const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();

startStandaloneServer({ port, enableCors, logger }).catch(err => {
logger.error('Standalone server failed:', err);
process.exit(1);
});

process.on('SIGINT', () => {
logger.info('CTRL+C pressed; exiting.');
process.exit(0);
});
28 changes: 28 additions & 0 deletions plugins/report-portal-backend/src/service/router.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';

import express from 'express';

import { createRouter } from './router';

describe('createRouter', () => {
let app: express.Express;

beforeAll(async () => {
const router = await createRouter({
logger: getVoidLogger(),
config: new ConfigReader({ reportPortal: { integrations: [] } }),
});
app = express().use(router);
});

beforeEach(() => {
jest.resetAllMocks();
});

describe('just a test', () => {
it('returns ok', async () => {
expect(app).toBeDefined();
});
});
});
56 changes: 56 additions & 0 deletions plugins/report-portal-backend/src/service/router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { errorHandler } from '@backstage/backend-common';
import { Config } from '@backstage/config';

import express from 'express';
import Router from 'express-promise-router';
import { createProxyMiddleware } from 'http-proxy-middleware';
import { Logger } from 'winston';

export interface RouterOptions {
logger: Logger;
config: Config;
}

export async function createRouter(
options: RouterOptions,
): Promise<express.Router> {
const { config } = options;
const hostsConfig = config.getConfigArray('reportPortal.integrations');

const router = Router();
router.use(express.json());

router.get('/*', (req, res, next) => {
const hostName = req.query.host;
if (!hostName) {
res.status(500).json({ message: 'Oops, I think you forgot something?' });
return;
}
const reqConfig = hostsConfig
.find(instance => instance.getString('host') === hostName)
?.get() as PluginConfig;

const proxy = createProxyMiddleware({
target: reqConfig.baseUrl,
changeOrigin: true,
secure: false,
headers: {
Authorization: reqConfig.token,
},
pathRewrite: {
['/api/report-portal']: '',
},
});

proxy(req, res, next);
});

router.use(errorHandler());
return router;
}

type PluginConfig = {
host: string;
baseUrl: string;
token: string;
};
Loading

0 comments on commit d894726

Please sign in to comment.