update for comments

Signed-off-by: Andrew Johnson <ajohnson@gocardless.com>
This commit is contained in:
Andrew Johnson
2021-03-30 17:35:53 +01:00
parent 4b00af9b31
commit 39d7c8718a
8 changed files with 50 additions and 154 deletions
+8 -13
View File
@@ -4,18 +4,13 @@ The GitHub Deployments Plugin displays recent deployments from GitHub.
![github-deployments-card](./docs/github-deployments-card.png)
## Prerequisites
- [GitHub Authentication Provider](https://backstage.io/docs/auth/github/provider)
## Getting Started
1. Provide OAuth credentials:
- Create an [OAuth App](https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/) and set env variables for ID and Secret.
```bash
export AUTH_GITHUB_CLIENT_ID={{YOUR_CLIENT_ID}}
export AUTH_CLIENT_SECRET={{YOUR_CLIENT_SECRET}}
```
2. Install the GitHub Deployments Plugin.
1. Install the GitHub Deployments Plugin.
```bash
# packages/app
@@ -23,7 +18,7 @@ export AUTH_CLIENT_SECRET={{YOUR_CLIENT_SECRET}}
yarn add @backstage/plugin-github-deployments
```
3. Add the plugin to the app
2. Add the plugin to the app
```typescript
// packages/app/src/plugins.ts
@@ -31,7 +26,7 @@ yarn add @backstage/plugin-github-deployments
export { plugin as GithubDeployments } from '@backstage/plugin-github-deployments';
```
4. Add the `EntityGithubDeploymentsCard` to the EntityPage:
3. Add the `EntityGithubDeploymentsCard` to the EntityPage:
```typescript
// packages/app/src/components/catalog/EntityPage.tsx
@@ -49,7 +44,7 @@ const OverviewContent = () => (
);
```
5. Add the `github.com/project-slug` annotation to your `catalog-info.yaml` file:
4. Add the `github.com/project-slug` annotation to your `catalog-info.yaml` file:
```yaml
apiVersion: backstage.io/v1alpha1
+1 -1
View File
@@ -28,7 +28,7 @@
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"@octokit/graphql": "^4.6.1",
"moment": "^2.29.1",
"luxon": "^1.26.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-use": "^15.3.3"
@@ -24,14 +24,14 @@ import {
OAuthApi,
} from '@backstage/core';
import { render } from '@testing-library/react';
import { setupServer } from 'msw/node';
import { msw } from '@backstage/test-utils'
import { GithubDeploymentsApiClient, githubDeploymentsApiRef } from '../api';
import { githubDeploymentsPlugin } from '../plugin';
import { GithubDeploymentsCard } from './GithubDeploymentsCard';
import { entityStub, noDataResponseStub, responseStub } from '../mocks/mocks';
import { wrapInTestApp } from '@backstage/test-utils';
import { renderInTestApp } from '@backstage/test-utils';
import { setupServer } from 'msw/node';
import { graphql } from 'msw';
jest.mock('@backstage/plugin-catalog-react', () => ({
@@ -55,9 +55,7 @@ const apis = ApiRegistry.from([
describe('github-deployments', () => {
const worker = setupServer();
beforeAll(() => worker.listen());
afterAll(() => worker.close());
afterEach(() => worker.resetHandlers());
msw.setupDefaultHandlers(worker);
beforeEach(() => {
jest.resetAllMocks();
@@ -77,12 +75,10 @@ describe('github-deployments', () => {
),
);
const rendered = render(
wrapInTestApp(
<ApiProvider apis={apis}>
<GithubDeploymentsCard />
</ApiProvider>,
),
const rendered = await renderInTestApp(
<ApiProvider apis={apis}>
<GithubDeploymentsCard />
</ApiProvider>,
);
expect(await rendered.findByText('active')).toBeInTheDocument();
@@ -107,12 +103,10 @@ describe('github-deployments', () => {
),
);
const rendered = render(
wrapInTestApp(
<ApiProvider apis={apis}>
<GithubDeploymentsCard />
</ApiProvider>,
),
const rendered = await renderInTestApp(
<ApiProvider apis={apis}>
<GithubDeploymentsCard />
</ApiProvider>,
);
expect(
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import React from 'react';
import { LinearProgress } from '@material-ui/core';
import { InfoCard, MissingAnnotationEmptyState, useApi } from '@backstage/core';
import { InfoCard, MissingAnnotationEmptyState, Progress, ResponseErrorPanel, useApi } from '@backstage/core';
import { useAsync } from 'react-use';
import { githubDeploymentsApiRef } from '../api';
import { useEntity } from '@backstage/plugin-catalog-react';
@@ -42,15 +41,13 @@ const GithubDeploymentsComponent = ({
if (loading) {
return (
<InfoCard title="GitHub Deployments">
<LinearProgress />
<Progress />
</InfoCard>
);
}
if (error) {
return (
<InfoCard title="GitHub Deployments">
Error occured while fetching Data
</InfoCard>
<ResponseErrorPanel error={error} />
);
}
@@ -14,9 +14,9 @@
* limitations under the License.
*/
import React from 'react';
import { Table, TableColumn } from '@backstage/core';
import { StatusPending, StatusRunning, StatusOK, Table, TableColumn, StatusAborted, StatusError } from '@backstage/core';
import { GithubDeployment } from '../../api';
import moment from 'moment';
import { DateTime } from 'luxon';
import { Box, Typography, Link, makeStyles } from '@material-ui/core';
const useStyles = makeStyles(theme => ({
@@ -27,31 +27,21 @@ const useStyles = makeStyles(theme => ({
},
}));
const lastUpdated = (start: string): string => moment(start).fromNow();
const State = ({ value }: { value: string }) => {
const colorMap: Record<string, string> = {
PENDING: 'orange',
IN_PROGRESS: 'orange',
ACTIVE: 'green',
};
return (
<Box display="flex" alignItems="center">
<span
style={{
display: 'block',
width: '8px',
height: '8px',
borderRadius: '50%',
backgroundColor: colorMap[value] || 'grey',
marginRight: '5px',
}}
/>
<Typography variant="caption">{value}</Typography>
</Box>
);
};
const statusIndicator = (value: string): React.ReactNode => {
switch (value) {
case 'PENDING':
return <StatusPending />;
case 'IN_PROGRESS':
return <StatusRunning />;
case 'ACTIVE':
return <StatusOK />;
case 'ERROR':
case 'FAILURE':
return <StatusError />;
default:
return <StatusAborted />;
}
}
const columns: TableColumn<GithubDeployment>[] = [
{
@@ -62,7 +52,10 @@ const columns: TableColumn<GithubDeployment>[] = [
{
title: 'Status',
render: (row: GithubDeployment): React.ReactNode => (
<State value={row.state} />
<Box display="flex" alignItems="center">
{ statusIndicator(row.state)}
<Typography variant="caption">{row.state}</Typography>
</Box>
),
},
{
@@ -76,7 +69,7 @@ const columns: TableColumn<GithubDeployment>[] = [
{
title: 'Last Updated',
render: (row: GithubDeployment): React.ReactNode =>
lastUpdated(row.updatedAt),
DateTime.fromISO(row.updatedAt).toRelative({ locale: 'en' }),
},
];
+2 -2
View File
@@ -14,7 +14,7 @@
* limitations under the License.
*/
export {
githubDeploymentsPlugin as plugin,
githubDeploymentsPlugin,
EntityGithubDeploymentsCard,
} from './plugin';
export { isGithubDeploymentsAvailable as isPluginApplicableToEntity } from './Router';
export { isGithubDeploymentsAvailable } from './Router';
@@ -1,5 +1,3 @@
import { QueryResponse } from '../api';
/*
* Copyright 2021 Spotify AB
*
@@ -15,6 +13,8 @@ import { QueryResponse } from '../api';
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { QueryResponse } from '../api';
export const entityStub = {
entity: {
metadata: {
-83
View File
@@ -1846,23 +1846,6 @@
uuid "^8.0.0"
yup "^0.29.3"
"@backstage/core-api@^0.2.15":
version "0.2.15"
resolved "https://registry.npmjs.org/@backstage/core-api/-/core-api-0.2.15.tgz#24c3e4b1fe0bdee36de26c50b8757f41bb266109"
integrity sha512-OQTmvCGM3hkaLV0+JPF85dZk/X1SXoIFkXZi9pO/DzBPZ1Psuptia9xNXrhnEeYJaCazlCnOCTXS/kdoT1zBVg==
dependencies:
"@backstage/config" "^0.1.4"
"@backstage/theme" "^0.2.5"
"@material-ui/core" "^4.11.0"
"@material-ui/icons" "^4.9.1"
"@types/prop-types" "^15.7.3"
"@types/react" "^16.9"
prop-types "^15.7.2"
react "^16.12.0"
react-router-dom "6.0.0-beta.0"
react-use "^15.3.3"
zen-observable "^0.8.15"
"@backstage/core@^0.3.0":
version "0.7.3"
dependencies:
@@ -1989,65 +1972,6 @@
remark-gfm "^1.0.0"
zen-observable "^0.8.15"
"@backstage/core@^0.7.3":
version "0.7.3"
resolved "https://registry.npmjs.org/@backstage/core/-/core-0.7.3.tgz#a55f094f0aceab4102ea08a75832c2ec5a70e226"
integrity sha512-uKTCYYAYVtmdOiJrNKe00N0AKeEhxZ+y3qQVY+H96WN9QDql/56XTmoiyPjDU7wK4nDj+yGV4j+xM5uxSXaOCg==
dependencies:
"@backstage/config" "^0.1.4"
"@backstage/core-api" "^0.2.15"
"@backstage/errors" "^0.1.1"
"@backstage/theme" "^0.2.5"
"@material-ui/core" "^4.11.0"
"@material-ui/icons" "^4.9.1"
"@material-ui/lab" "4.0.0-alpha.45"
"@testing-library/react-hooks" "^3.4.2"
"@types/dagre" "^0.7.44"
"@types/prop-types" "^15.7.3"
"@types/react" "^16.9"
"@types/react-sparklines" "^1.7.0"
"@types/react-text-truncate" "^0.14.0"
classnames "^2.2.6"
clsx "^1.1.0"
d3-selection "^2.0.0"
d3-shape "^2.0.0"
d3-zoom "^2.0.0"
dagre "^0.8.5"
immer "^8.0.1"
lodash "^4.17.15"
material-table "^1.69.1"
prop-types "^15.7.2"
qs "^6.9.4"
rc-progress "^3.0.0"
react "^16.12.0"
react-dom "^16.12.0"
react-helmet "6.1.0"
react-hook-form "^6.6.0"
react-markdown "^5.0.2"
react-router "6.0.0-beta.0"
react-router-dom "6.0.0-beta.0"
react-sparklines "^1.7.0"
react-syntax-highlighter "^15.4.3"
react-text-truncate "^0.16.0"
react-use "^15.3.3"
remark-gfm "^1.0.0"
zen-observable "^0.8.15"
"@backstage/plugin-catalog-react@^0.1.3":
version "0.1.3"
resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.1.3.tgz#e4cc6c40616976737893cc91d7e373b9397618d1"
integrity sha512-nNIz+tc72UtwB66L++xA9drv5VV0SxMPh0BNLOFAHAllcR2RMQyvWpDq4uBupUXx/lr6bzihngkW9Jqr4rfz/Q==
dependencies:
"@backstage/catalog-client" "^0.3.8"
"@backstage/catalog-model" "^0.7.3"
"@backstage/core" "^0.7.3"
"@material-ui/core" "^4.11.0"
"@types/react" "^16.9"
react "^16.13.1"
react-router "6.0.0-beta.0"
react-router-dom "6.0.0-beta.0"
react-use "^15.3.3"
"@backstage/plugin-catalog@^0.2.1":
version "0.5.1"
dependencies:
@@ -2096,13 +2020,6 @@
react-use "^15.3.3"
swr "^0.3.0"
"@backstage/theme@^0.2.5":
version "0.2.5"
resolved "https://registry.npmjs.org/@backstage/theme/-/theme-0.2.5.tgz#657e2ceaaede1b4dbe8abeafa6e168671a27b6da"
integrity sha512-GT7Ok9QSiZWXkxka+vcpweMrOg1lgDkRRjh7aSU97Mcoiq77szdO45o0hZtQChz8qay60vCRlu57ADvUn4QxZw==
dependencies:
"@material-ui/core" "^4.11.0"
"@bcoe/v8-coverage@^0.2.3":
version "0.2.3"
resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"