Merge branch 'master' into anderoo/github-deployments-ghe

This commit is contained in:
Andrew Johnson
2021-04-16 17:29:02 +01:00
committed by GitHub
286 changed files with 7846 additions and 2058 deletions
+2 -2
View File
@@ -21,7 +21,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.7.6",
"@backstage/core": "^0.7.4",
"@backstage/core": "^0.7.5",
"@backstage/errors": "^0.1.1",
"@backstage/integration": "^0.5.1",
"@backstage/integration-react": "^0.1.1",
@@ -37,7 +37,7 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.6.7",
"@backstage/cli": "^0.6.8",
"@backstage/dev-utils": "^0.1.13",
"@backstage/test-utils": "^0.1.10",
"@testing-library/jest-dom": "^5.10.1",
@@ -58,6 +58,10 @@ export type GithubDeployment = {
abbreviatedOid: string;
commitUrl: string;
};
creator: {
login: string;
};
payload: string;
};
type QueryParams = {
@@ -99,6 +103,10 @@ query deployments($owner: String!, $repo: String!, $last: Int) {
abbreviatedOid
commitUrl
}
creator {
login
}
payload
}
}
}
@@ -26,7 +26,11 @@ import {
import { fireEvent } from '@testing-library/react';
import { msw, renderInTestApp } from '@backstage/test-utils';
import { GithubDeploymentsApiClient, githubDeploymentsApiRef } from '../api';
import {
GithubDeployment,
GithubDeploymentsApiClient,
githubDeploymentsApiRef,
} from '../api';
import { githubDeploymentsPlugin } from '../plugin';
import { GithubDeploymentsCard } from './GithubDeploymentsCard';
@@ -41,6 +45,8 @@ import { setupServer } from 'msw/node';
import { graphql } from 'msw';
import { ScmIntegrations } from '@backstage/integration';
import { Entity } from '@backstage/catalog-model';
import { GithubDeploymentsTable } from './GithubDeploymentsTable';
import { Box } from '@material-ui/core';
let entity: { entity: Entity };
@@ -204,6 +210,40 @@ describe('github-deployments', () => {
).toBeInTheDocument();
expect(await rendered.findByText('failure')).toBeInTheDocument();
});
it('should display extra columns', async () => {
worker.use(
graphql.query('deployments', (_, res, ctx) =>
res(ctx.data(responseStub)),
),
);
const renderTargetFromPayload = (payload: string) => {
const parsedPayload = JSON.parse(payload);
return parsedPayload?.target || 'unknown';
};
const extraColumn = {
title: 'Target',
render: (row: GithubDeployment): JSX.Element => (
<Box>{renderTargetFromPayload(row.payload)}</Box>
),
};
const columns = [
...GithubDeploymentsTable.defaultDeploymentColumns,
extraColumn,
];
const rendered = await renderInTestApp(
<ApiProvider apis={apis}>
<GithubDeploymentsCard columns={columns} />
</ApiProvider>,
);
expect(await rendered.findByText('moon')).toBeInTheDocument();
expect(await rendered.findByText('sun')).toBeInTheDocument();
});
describe('entity with source location', () => {
beforeEach(() => {
@@ -17,16 +17,17 @@ import React from 'react';
import {
MissingAnnotationEmptyState,
ResponseErrorPanel,
TableColumn,
useApi,
} from '@backstage/core';
import { useAsyncRetry } from 'react-use';
import { githubDeploymentsApiRef } from '../api';
import { GithubDeployment, githubDeploymentsApiRef } from '../api';
import { useEntity } from '@backstage/plugin-catalog-react';
import {
GITHUB_PROJECT_SLUG_ANNOTATION,
isGithubDeploymentsAvailable,
} from '../Router';
import GithubDeploymentsTable from './GithubDeploymentsTable/GithubDeploymentsTable';
import { GithubDeploymentsTable } from './GithubDeploymentsTable/GithubDeploymentsTable';
import {
LOCATION_ANNOTATION,
SOURCE_LOCATION_ANNOTATION,
@@ -35,11 +36,13 @@ import {
const GithubDeploymentsComponent = ({
projectSlug,
last,
columns,
locations,
}: {
projectSlug: string;
last: number;
locations: string[];
columns: TableColumn<GithubDeployment>[];
}) => {
const api = useApi(githubDeploymentsApiRef);
const [owner, repo] = projectSlug.split('/');
@@ -57,11 +60,18 @@ const GithubDeploymentsComponent = ({
deployments={value || []}
isLoading={loading}
reload={reload}
columns={columns}
/>
);
};
export const GithubDeploymentsCard = ({ last }: { last?: number }) => {
export const GithubDeploymentsCard = ({
last,
columns,
}: {
last?: number;
columns?: TableColumn<GithubDeployment>[];
}) => {
const { entity } = useEntity();
const locations = [
entity?.metadata.annotations?.[SOURCE_LOCATION_ANNOTATION],
@@ -77,6 +87,7 @@ export const GithubDeploymentsCard = ({ last }: { last?: number }) => {
}
last={last || 10}
locations={locations}
columns={columns || GithubDeploymentsTable.defaultDeploymentColumns}
/>
);
};
@@ -14,19 +14,12 @@
* limitations under the License.
*/
import React from 'react';
import {
StatusPending,
StatusRunning,
StatusOK,
Table,
TableColumn,
StatusAborted,
StatusError,
} from '@backstage/core';
import { Table, TableColumn } from '@backstage/core';
import { GithubDeployment } from '../../api';
import { DateTime } from 'luxon';
import { Box, Typography, Link, makeStyles } from '@material-ui/core';
import { Typography, makeStyles } from '@material-ui/core';
import SyncIcon from '@material-ui/icons/Sync';
import * as columnFactories from './columns';
import { defaultDeploymentColumns } from './presets';
const useStyles = makeStyles(theme => ({
empty: {
@@ -36,63 +29,19 @@ const useStyles = makeStyles(theme => ({
},
}));
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>[] = [
{
title: 'Environment',
field: 'environment',
highlight: true,
},
{
title: 'Status',
render: (row: GithubDeployment): React.ReactNode => (
<Box display="flex" alignItems="center">
{statusIndicator(row.state)}
<Typography variant="caption">{row.state}</Typography>
</Box>
),
},
{
title: 'Commit',
render: (row: GithubDeployment): React.ReactNode => (
<Link href={row.commit.commitUrl} target="_blank" rel="noopener">
{row.commit.abbreviatedOid}
</Link>
),
},
{
title: 'Last Updated',
render: (row: GithubDeployment): React.ReactNode =>
DateTime.fromISO(row.updatedAt).toRelative({ locale: 'en' }),
},
];
type GithubDeploymentsTableProps = {
deployments: GithubDeployment[];
isLoading: boolean;
reload: () => void;
columns: TableColumn<GithubDeployment>[];
};
const GithubDeploymentsTable = ({
export function GithubDeploymentsTable({
deployments,
isLoading,
reload,
}: GithubDeploymentsTableProps) => {
columns,
}: GithubDeploymentsTableProps) {
const classes = useStyles();
return (
@@ -119,6 +68,8 @@ const GithubDeploymentsTable = ({
}
/>
);
};
}
export default GithubDeploymentsTable;
GithubDeploymentsTable.columns = columnFactories;
GithubDeploymentsTable.defaultDeploymentColumns = defaultDeploymentColumns;
@@ -0,0 +1,91 @@
/*
* Copyright 2021 Spotify AB
*
* 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 {
StatusPending,
StatusRunning,
StatusOK,
TableColumn,
StatusAborted,
StatusError,
Link,
} from '@backstage/core';
import { GithubDeployment } from '../../api';
import { DateTime } from 'luxon';
import { Box, Typography } from '@material-ui/core';
export const GithubStateIndicator = ({ state }: { state: string }) => {
switch (state) {
case 'PENDING':
return <StatusPending />;
case 'IN_PROGRESS':
return <StatusRunning />;
case 'ACTIVE':
return <StatusOK />;
case 'ERROR':
case 'FAILURE':
return <StatusError />;
default:
return <StatusAborted />;
}
};
export function createEnvironmentColumn(): TableColumn<GithubDeployment> {
return {
title: 'Environment',
field: 'environment',
highlight: true,
};
}
export function createStatusColumn(): TableColumn<GithubDeployment> {
return {
title: 'Status',
render: (row: GithubDeployment): JSX.Element => (
<Box display="flex" alignItems="center">
<GithubStateIndicator state={row.state} />
<Typography variant="caption">{row.state}</Typography>
</Box>
),
};
}
export function createCommitColumn(): TableColumn<GithubDeployment> {
return {
title: 'Commit',
render: (row: GithubDeployment): JSX.Element => (
<Link to={row.commit.commitUrl} target="_blank" rel="noopener">
{row.commit.abbreviatedOid}
</Link>
),
};
}
export function createCreatorColumn(): TableColumn<GithubDeployment> {
return {
title: 'Creator',
field: 'creator.login',
};
}
export function createLastUpdatedColumn(): TableColumn<GithubDeployment> {
return {
title: 'Last Updated',
render: (row: GithubDeployment): JSX.Element => (
<Box>{DateTime.fromISO(row.updatedAt).toRelative({ locale: 'en' })}</Box>
),
};
}
@@ -0,0 +1,16 @@
/*
* Copyright 2021 Spotify AB
*
* 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 { GithubDeploymentsTable } from './GithubDeploymentsTable';
@@ -0,0 +1,32 @@
/*
* Copyright 2021 Spotify AB
*
* 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 { TableColumn } from '@backstage/core';
import { GithubDeployment } from '../../api';
import {
createEnvironmentColumn,
createStatusColumn,
createCommitColumn,
createLastUpdatedColumn,
createCreatorColumn,
} from './columns';
export const defaultDeploymentColumns: TableColumn<GithubDeployment>[] = [
createEnvironmentColumn(),
createStatusColumn(),
createCommitColumn(),
createCreatorColumn(),
createLastUpdatedColumn(),
];
+1
View File
@@ -14,4 +14,5 @@
* limitations under the License.
*/
export { githubDeploymentsPlugin, EntityGithubDeploymentsCard } from './plugin';
export { GithubDeploymentsTable } from './components/GithubDeploymentsTable';
export { isGithubDeploymentsAvailable } from './Router';
@@ -48,6 +48,10 @@ export const responseStub: QueryResponse = {
commitUrl: 'https://exampleapi.com/123456789',
abbreviatedOid: '12345',
},
creator: {
login: 'robot-user-001',
},
payload: '{"target":"moon"}',
},
{
state: 'pending',
@@ -57,6 +61,10 @@ export const responseStub: QueryResponse = {
commitUrl: 'https://exampleapi.com/543212345',
abbreviatedOid: '54321',
},
creator: {
login: 'robot-user-002',
},
payload: '{"target":"sun"}',
},
],
},
@@ -75,6 +83,10 @@ export const refreshedResponseStub: QueryResponse = {
commitUrl: 'https://exampleapi.com/123456789',
abbreviatedOid: '12345',
},
creator: {
login: 'robot-user-001',
},
payload: '',
},
{
state: 'failure',
@@ -84,6 +96,10 @@ export const refreshedResponseStub: QueryResponse = {
commitUrl: 'https://exampleapi.com/543212345',
abbreviatedOid: '54321',
},
creator: {
login: 'robot-user-002',
},
payload: '',
},
],
},