diff --git a/.changeset/popular-rules-hang.md b/.changeset/popular-rules-hang.md new file mode 100644 index 0000000000..593cfcd3b6 --- /dev/null +++ b/.changeset/popular-rules-hang.md @@ -0,0 +1,11 @@ +--- +'example-app': patch +'example-backend': patch +'@backstage/plugin-scorecards': patch +'@backstage/plugin-tech-insights-backend': patch +'@backstage/plugin-tech-insights-common': patch +--- + +Removed unecessary check in @backstage/plugin-tech-insights-backend + +Added new property 'result' in every CheckResult in @backstage/plugin-tech-insights-common diff --git a/packages/app/package.json b/packages/app/package.json index 9a1fb108f6..82fdeb6d18 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -36,6 +36,7 @@ "@backstage/plugin-pagerduty": "0.3.17", "@backstage/plugin-rollbar": "^0.3.18", "@backstage/plugin-scaffolder": "^0.11.8", + "@backstage/plugin-scorecards": "^0.1.0", "@backstage/plugin-search": "^0.4.15", "@backstage/plugin-sentry": "^0.3.26", "@backstage/plugin-shortcuts": "^0.1.12", diff --git a/plugins/scorecards/.eslintrc.js b/plugins/scorecards/.eslintrc.js new file mode 100644 index 0000000000..13573efa9c --- /dev/null +++ b/plugins/scorecards/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint')], +}; diff --git a/plugins/scorecards/README.md b/plugins/scorecards/README.md new file mode 100644 index 0000000000..2ff9aaf1ab --- /dev/null +++ b/plugins/scorecards/README.md @@ -0,0 +1,52 @@ +# Scorecards + +This plugin represents scorecards which are rendered as a part of the default Backstage Tech Insights feature. +It provides UI for the scorecards as well as a check overview. + +## Installation + +### Install the plugin + +```bash +# From your Backstage root directory +cd packages/app +yarn add @backstage/plugin-scorecards +``` + +### Adding the plugin to your `packages/app` + +```tsx +// In packages/app/src/App.tsx + +import { EntityScorecardContent } from '@backstage/plugin-scorecards'; + +} />; +``` + +3. Add Scorecards overview page to the EntityPage: + +```tsx +// packages/app/src/components/catalog/EntityPage.tsx + +import { EntityScorecardContent } from '@backstage/plugin-scorecards'; + +const serviceEntityPage = ( + + + {overviewContent} + + + {cicdContent} + + ... + + + + ... + +); +``` + +## Links + +- [The Backstage homepage](https://backstage.io) diff --git a/plugins/scorecards/api-report.md b/plugins/scorecards/api-report.md new file mode 100644 index 0000000000..eb3ce4533b --- /dev/null +++ b/plugins/scorecards/api-report.md @@ -0,0 +1,27 @@ +## API Report File for "@backstage/plugin-scorecards" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { RouteRef } from '@backstage/core-plugin-api'; + +// Warning: (ae-missing-release-tag) "EntityScorecardContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const EntityScorecardContent: () => JSX.Element; + +// Warning: (ae-missing-release-tag) "scorecardsPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const scorecardsPlugin: BackstagePlugin< + { + root: RouteRef; + }, + {} +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/scorecards/dev/index.tsx b/plugins/scorecards/dev/index.tsx new file mode 100644 index 0000000000..559e92b969 --- /dev/null +++ b/plugins/scorecards/dev/index.tsx @@ -0,0 +1,27 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { createDevApp } from '@backstage/dev-utils'; +import { scorecardsPlugin, EntityScorecardContent } from '../src/plugin'; + +createDevApp() + .registerPlugin(scorecardsPlugin) + .addPage({ + element: , + title: 'Root Page', + path: '/scorecards', + }) + .render(); diff --git a/plugins/scorecards/package.json b/plugins/scorecards/package.json new file mode 100644 index 0000000000..4d104410da --- /dev/null +++ b/plugins/scorecards/package.json @@ -0,0 +1,52 @@ +{ + "name": "@backstage/plugin-scorecards", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "scripts": { + "build": "backstage-cli plugin:build", + "start": "backstage-cli plugin:serve", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "diff": "backstage-cli plugin:diff", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/core-components": "^0.7.2", + "@backstage/core-plugin-api": "^0.1.12", + "@backstage/theme": "^0.2.12", + "@material-ui/core": "^4.12.2", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "4.0.0-alpha.57", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-use": "^17.2.4", + "react-router-dom": "6.0.0-beta.0", + "@backstage/plugin-catalog-react": "^0.6.2", + "@backstage/plugin-tech-insights-common": "^0.1.0" + }, + "devDependencies": { + "@backstage/cli": "^0.8.1", + "@backstage/core-app-api": "^0.1.19", + "@backstage/dev-utils": "^0.2.12", + "@backstage/test-utils": "^0.1.20", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^11.2.5", + "@testing-library/user-event": "^13.1.8", + "@types/jest": "*", + "@types/node": "*", + "msw": "^0.35.0", + "cross-fetch": "^3.0.6" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/scorecards/src/api/ScorecardsApi.ts b/plugins/scorecards/src/api/ScorecardsApi.ts new file mode 100644 index 0000000000..83f34d4cf5 --- /dev/null +++ b/plugins/scorecards/src/api/ScorecardsApi.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createApiRef } from '@backstage/core-plugin-api'; +import { CheckResult } from '@backstage/plugin-tech-insights-common'; +import { Check } from './types'; +import { CheckResultRenderer } from '../components/CheckResultRenderer'; + +export const scorecardsApiRef = createApiRef({ + id: 'plugin.scorecards.service', + description: 'Used by the scorecards plugin to make requests', +}); + +export interface ScorecardsApi { + getScorecardsDefinition: ( + type: string, + value: CheckResult[], + ) => CheckResultRenderer | undefined; + getAllChecks(): Promise; + runChecks({ + namespace, + kind, + name, + checks, + }: { + namespace: string; + kind: string; + name: string; + checks?: Check[]; + }): Promise; +} diff --git a/plugins/scorecards/src/api/ScorecardsClient.ts b/plugins/scorecards/src/api/ScorecardsClient.ts new file mode 100644 index 0000000000..bdfc89dc09 --- /dev/null +++ b/plugins/scorecards/src/api/ScorecardsClient.ts @@ -0,0 +1,91 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ScorecardsApi } from './ScorecardsApi'; +import { CheckResult } from '@backstage/plugin-tech-insights-common'; +import { Check } from './types'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { + CheckResultRenderer, + defaultCheckResultRenderers, +} from '../components/CheckResultRenderer'; + +export type Options = { + discoveryApi: DiscoveryApi; + proxyPath?: string; +}; + +export class ScorecardsClient implements ScorecardsApi { + private readonly discoveryApi: DiscoveryApi; + private baseUrl: string = ''; + + constructor(options: Options) { + this.discoveryApi = options.discoveryApi; + } + + getScorecardsDefinition( + type: string, + value: CheckResult[], + ): CheckResultRenderer | undefined { + const resultRenderers = defaultCheckResultRenderers(value); + return resultRenderers.find(d => d.type === type); + } + + getBaseUrl: () => Promise = async () => { + if (!this.baseUrl) { + this.baseUrl = await this.discoveryApi.getBaseUrl('tech-insights'); + } + return this.baseUrl; + }; + + async getAllChecks(): Promise { + const url = await this.getBaseUrl(); + const allChecks = await fetch(`${url}/checks`); + const payload = await allChecks.json(); + if (!allChecks.ok) { + throw new Error(payload.errors[0]); + } + return payload; + } + + async runChecks({ + namespace, + kind, + name, + checks, + }: { + namespace: string; + kind: string; + name: string; + checks: Check[]; + }): Promise { + const url = await this.getBaseUrl(); + const allChecks = checks ? checks : await this.getAllChecks(); + const checkIds = allChecks.map((check: Check) => check.id); + const response = await fetch( + `${url}/checks/run/${namespace}/${kind}/${name}`, + { + method: 'POST', + body: JSON.stringify({ checks: checkIds }), + headers: { + 'Content-Type': 'application/json', + }, + }, + ); + const result = await response.json(); + return result; + } +} diff --git a/plugins/scorecards/src/api/index.ts b/plugins/scorecards/src/api/index.ts new file mode 100644 index 0000000000..afebc5432f --- /dev/null +++ b/plugins/scorecards/src/api/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './ScorecardsApi'; +export * from './ScorecardsClient'; diff --git a/plugins/scorecards/src/api/types.ts b/plugins/scorecards/src/api/types.ts new file mode 100644 index 0000000000..20071ba0c9 --- /dev/null +++ b/plugins/scorecards/src/api/types.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export type Check = { + id: string; + type: string; + name: string; + description: string; + factIds: string[]; +}; diff --git a/plugins/scorecards/src/components/BooleanCheck/BooleanCheck.tsx b/plugins/scorecards/src/components/BooleanCheck/BooleanCheck.tsx new file mode 100644 index 0000000000..3920538983 --- /dev/null +++ b/plugins/scorecards/src/components/BooleanCheck/BooleanCheck.tsx @@ -0,0 +1,62 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { makeStyles, List, ListItem, ListItemText } from '@material-ui/core'; +import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline'; +import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline'; +import { CheckResult } from '@backstage/plugin-tech-insights-common'; + +const useStyles = makeStyles(() => ({ + listItemText: { + paddingRight: '1rem', + flex: '0 1 auto', + }, + icon: { + marginLeft: 'auto', + }, +})); + +type Prop = { + checkResult: CheckResult[]; +}; + +const renderResult = (classes: any, result: Boolean) => { + return result ? ( + + ) : ( + + ); +}; + +export const BooleanCheck = ({ checkResult }: Prop) => { + const classes = useStyles(); + + return ( + + {checkResult!.map(check => ( + + + {renderResult(classes, check.result)} + + ))} + + ); +}; diff --git a/plugins/scorecards/src/components/BooleanCheck/index.ts b/plugins/scorecards/src/components/BooleanCheck/index.ts new file mode 100644 index 0000000000..729ab4d62e --- /dev/null +++ b/plugins/scorecards/src/components/BooleanCheck/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { BooleanCheck } from './BooleanCheck'; diff --git a/plugins/scorecards/src/components/CheckResultRenderer.tsx b/plugins/scorecards/src/components/CheckResultRenderer.tsx new file mode 100644 index 0000000000..adac458d74 --- /dev/null +++ b/plugins/scorecards/src/components/CheckResultRenderer.tsx @@ -0,0 +1,40 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CheckResult } from '@backstage/plugin-tech-insights-common'; +import React from 'react'; +import { BooleanCheck } from './BooleanCheck'; + +export type CheckResultRenderer = { + type: string; + title: string; + description: string; + component: React.ReactElement; +}; + +export function defaultCheckResultRenderers( + value: CheckResult[], +): CheckResultRenderer[] { + return [ + { + type: 'json-rules-engine', + title: 'Boolean scorecard', + description: + 'This card represents an overview of default boolean checks:', + component: , + }, + ]; +} diff --git a/plugins/scorecards/src/components/ScorecardsOverview/ChecksOverview.tsx b/plugins/scorecards/src/components/ScorecardsOverview/ChecksOverview.tsx new file mode 100644 index 0000000000..3c66226da9 --- /dev/null +++ b/plugins/scorecards/src/components/ScorecardsOverview/ChecksOverview.tsx @@ -0,0 +1,66 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { makeStyles, Grid, Typography } from '@material-ui/core'; +import { useApi } from '@backstage/core-plugin-api'; +import { Content, Page, InfoCard } from '@backstage/core-components'; +import { CheckResult } from '@backstage/plugin-tech-insights-common'; +import { scorecardsApiRef } from '../../api/ScorecardsApi'; + +const useStyles = makeStyles(() => ({ + contentScorecards: { + paddingLeft: 0, + paddingRight: 0, + }, + subheader: { + fontWeight: 'bold', + }, +})); + +type Checks = { + checks: CheckResult[]; +}; + +export const ChecksOverview = ({ checks }: Checks) => { + const classes = useStyles(); + const api = useApi(scorecardsApiRef); + const checkRenderType = api.getScorecardsDefinition( + checks[0].check.type, + checks, + ); + + if (checkRenderType) { + return ( + + + + + + {checkRenderType.description} + + + {checkRenderType.component} + + + + + + ); + } + + return <>; +}; diff --git a/plugins/scorecards/src/components/ScorecardsOverview/ScorecardsOverview.tsx b/plugins/scorecards/src/components/ScorecardsOverview/ScorecardsOverview.tsx new file mode 100644 index 0000000000..7bfd57be72 --- /dev/null +++ b/plugins/scorecards/src/components/ScorecardsOverview/ScorecardsOverview.tsx @@ -0,0 +1,41 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { useParams } from 'react-router-dom'; +import { useAsync } from 'react-use'; +import { Progress } from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; +import { ChecksOverview } from './ChecksOverview'; +import Alert from '@material-ui/lab/Alert'; +import { scorecardsApiRef } from '../../api/ScorecardsApi'; + +export const ScorecardsOverview = () => { + const api = useApi(scorecardsApiRef); + const { namespace, kind, name } = useParams(); + + const { value, loading, error } = useAsync( + async () => await api.runChecks({ namespace, kind, name }), + ); + + if (loading) { + return ; + } else if (error) { + return {error.message}; + } + + return ; +}; diff --git a/plugins/scorecards/src/components/ScorecardsOverview/index.ts b/plugins/scorecards/src/components/ScorecardsOverview/index.ts new file mode 100644 index 0000000000..64198790d9 --- /dev/null +++ b/plugins/scorecards/src/components/ScorecardsOverview/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { ScorecardsOverview } from './ScorecardsOverview'; diff --git a/plugins/scorecards/src/index.ts b/plugins/scorecards/src/index.ts new file mode 100644 index 0000000000..cba54febcf --- /dev/null +++ b/plugins/scorecards/src/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { scorecardsPlugin, EntityScorecardContent } from './plugin'; diff --git a/plugins/scorecards/src/plugin.test.ts b/plugins/scorecards/src/plugin.test.ts new file mode 100644 index 0000000000..537a6399bf --- /dev/null +++ b/plugins/scorecards/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { scorecardsPlugin } from './plugin'; + +describe('scorecards', () => { + it('should export plugin', () => { + expect(scorecardsPlugin).toBeDefined(); + }); +}); diff --git a/plugins/scorecards/src/plugin.ts b/plugins/scorecards/src/plugin.ts new file mode 100644 index 0000000000..c9f0d47571 --- /dev/null +++ b/plugins/scorecards/src/plugin.ts @@ -0,0 +1,47 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + createPlugin, + createRoutableExtension, + createApiFactory, + discoveryApiRef, +} from '@backstage/core-plugin-api'; +import { rootRouteRef } from './routes'; +import { scorecardsApiRef } from './api/ScorecardsApi'; +import { ScorecardsClient } from './api'; + +export const scorecardsPlugin = createPlugin({ + id: 'scorecards', + apis: [ + createApiFactory({ + api: scorecardsApiRef, + deps: { discoveryApi: discoveryApiRef }, + factory: ({ discoveryApi }) => new ScorecardsClient({ discoveryApi }), + }), + ], + routes: { + root: rootRouteRef, + }, +}); + +export const EntityScorecardContent = scorecardsPlugin.provide( + createRoutableExtension({ + name: 'EntityScorecardContent', + component: () => + import('./components/ScorecardsOverview').then(m => m.ScorecardsOverview), + mountPoint: rootRouteRef, + }), +); diff --git a/plugins/scorecards/src/routes.ts b/plugins/scorecards/src/routes.ts new file mode 100644 index 0000000000..c81a4b8eef --- /dev/null +++ b/plugins/scorecards/src/routes.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createRouteRef } from '@backstage/core-plugin-api'; + +export const rootRouteRef = createRouteRef({ + title: 'scorecards', +}); diff --git a/plugins/scorecards/src/setupTests.ts b/plugins/scorecards/src/setupTests.ts new file mode 100644 index 0000000000..fc6dbd98f8 --- /dev/null +++ b/plugins/scorecards/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import '@testing-library/jest-dom'; +import 'cross-fetch/polyfill'; diff --git a/plugins/tech-insights-backend/src/service/router.ts b/plugins/tech-insights-backend/src/service/router.ts index a8951318ea..80902c307c 100644 --- a/plugins/tech-insights-backend/src/service/router.ts +++ b/plugins/tech-insights-backend/src/service/router.ts @@ -92,11 +92,6 @@ export async function createRouter< router.post('/checks/run/:namespace/:kind/:name', async (req, res) => { const { namespace, kind, name } = req.params; try { - if (!('checks' in req.body)) { - return res.status(422).send({ - message: 'Failed to get checks from request.', - }); - } const { checks }: { checks: string[] } = req.body; const entityTriplet = stringifyEntityRef({ namespace, kind, name }); const checkResult = await factChecker.runChecks(entityTriplet, checks); diff --git a/plugins/tech-insights-common/api-report.md b/plugins/tech-insights-common/api-report.md index ddb38cfa85..3c806daa57 100644 --- a/plugins/tech-insights-common/api-report.md +++ b/plugins/tech-insights-common/api-report.md @@ -25,6 +25,7 @@ export interface CheckResponse { export type CheckResult = { facts: FactResponse; check: CheckResponse; + result: any; }; // @public diff --git a/plugins/tech-insights-common/src/index.ts b/plugins/tech-insights-common/src/index.ts index 4bfc660748..5b6e814474 100644 --- a/plugins/tech-insights-common/src/index.ts +++ b/plugins/tech-insights-common/src/index.ts @@ -112,6 +112,7 @@ export type FactResponse = { export type CheckResult = { facts: FactResponse; check: CheckResponse; + result: any; }; /**