Merge branch 'master' into anderoo/github-deployments-ghe
This commit is contained in:
@@ -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}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+12
-61
@@ -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(),
|
||||
];
|
||||
@@ -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: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user