feat: total upgrade
This commit is contained in:
@@ -126,6 +126,7 @@ type Props = {
|
||||
actions?: ReactNode;
|
||||
cardClassName?: string;
|
||||
actionsTopRight?: ReactNode;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const InfoCard: FC<Props> = ({
|
||||
@@ -142,6 +143,7 @@ const InfoCard: FC<Props> = ({
|
||||
actions,
|
||||
cardClassName,
|
||||
actionsTopRight,
|
||||
className,
|
||||
}) => {
|
||||
const classes = useStyles();
|
||||
|
||||
@@ -169,7 +171,7 @@ const InfoCard: FC<Props> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Card style={calculatedStyle}>
|
||||
<Card style={calculatedStyle} className={className}>
|
||||
<ErrorBoundary slackChannel={slackChannel}>
|
||||
{title && (
|
||||
<>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Route, Switch } from 'react-router';
|
||||
import React from 'react';
|
||||
import { BuildsPage } from 'pages/BuildsPage';
|
||||
// import { DetailedViewPage } from 'pages/DetailedViewPage';
|
||||
import { DetailedViewPage } from 'pages/DetailedViewPage';
|
||||
import { SettingsPage } from 'pages/SettingsPage';
|
||||
import { Provider, useDispatch } from 'react-redux';
|
||||
|
||||
@@ -23,9 +23,9 @@ export const App = () => {
|
||||
<Switch>
|
||||
<Route path="/circleci" component={BuildsPage} exact />
|
||||
<Route path="/circleci/settings" component={SettingsPage} />
|
||||
<Route path="/circleci/build/:buildId" component={DetailedViewPage} />
|
||||
</Switch>
|
||||
</>
|
||||
{/* <Route path="/build/:buildId" component={DetailedViewPage} /> */}
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
@@ -57,9 +57,10 @@ export class CircleCIApi {
|
||||
}
|
||||
|
||||
async getBuild(buildNumber: number, options: CircleCIOptions) {
|
||||
console.log({ buildNumber, options });
|
||||
return getFullBuild(options.token, buildNumber, {
|
||||
circleHost: this.apiUrl,
|
||||
...options,
|
||||
...options.vcs,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -1 +0,0 @@
|
||||
export { CircleCIFetch } from './CirleCIFetch';
|
||||
@@ -1,9 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Header, Page, pageTheme, HeaderLabel } from '@backstage/core';
|
||||
// @ts-ignore
|
||||
import logo from '../../assets/circle-logo-horizontal-white.png';
|
||||
|
||||
export const Layout: React.FC = ({ children }) => (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Header title="Welcome to circleci!" subtitle="Optional subtitle">
|
||||
<Header title={<img src={logo} style={{ height: '2em' }} />}>
|
||||
<HeaderLabel label="Owner" value="Team X" />
|
||||
<HeaderLabel label="Lifecycle" value="Alpha" />
|
||||
</Header>
|
||||
|
||||
@@ -1,18 +1,39 @@
|
||||
import React from 'react';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
import { Link as RouterLink, useLocation } from 'react-router-dom';
|
||||
import { ContentHeader, SupportButton } from '@backstage/core';
|
||||
import { Button } from '@material-ui/core';
|
||||
import { Settings as SettingsIcon } from '@material-ui/icons';
|
||||
|
||||
export const PluginHeader = () => (
|
||||
<ContentHeader title="Circle CI">
|
||||
<Button
|
||||
component={RouterLink}
|
||||
to="/circleci/settings"
|
||||
startIcon={<SettingsIcon />}
|
||||
import { Button, IconButton, Box } from '@material-ui/core';
|
||||
import { Settings as SettingsIcon, ArrowBack } from '@material-ui/icons';
|
||||
export const PluginHeader: React.FC<{ title?: string }> = ({
|
||||
title = 'Circle CI',
|
||||
}) => {
|
||||
const location = useLocation();
|
||||
const notRoot = !location.pathname.match(/\/circleci\/?$/);
|
||||
const isSettingsPage = location.pathname.match(/\/circleci\/settings\/?/);
|
||||
return (
|
||||
<ContentHeader
|
||||
title={
|
||||
(
|
||||
<Box alignItems="center" display="flex">
|
||||
{notRoot && (
|
||||
<IconButton component={RouterLink} to="/circleci">
|
||||
<ArrowBack />
|
||||
</IconButton>
|
||||
)}
|
||||
{title}
|
||||
</Box>
|
||||
) as any
|
||||
}
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
<SupportButton>A description of your plugin goes here.</SupportButton>
|
||||
</ContentHeader>
|
||||
);
|
||||
{!isSettingsPage && (
|
||||
<Button
|
||||
component={RouterLink}
|
||||
to="/circleci/settings"
|
||||
startIcon={<SettingsIcon />}
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
)}
|
||||
<SupportButton>A description of your plugin goes here.</SupportButton>
|
||||
</ContentHeader>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,34 +1,17 @@
|
||||
import React, { FC } from 'react';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
import {
|
||||
Content,
|
||||
ContentHeader,
|
||||
SupportButton,
|
||||
InfoCard,
|
||||
} from '@backstage/core';
|
||||
import { Button, Grid } from '@material-ui/core';
|
||||
import { CircleCIFetch } from 'components/CircleCIFetch';
|
||||
import { Settings as SettingsIcon } from '@material-ui/icons';
|
||||
import { Content } from '@backstage/core';
|
||||
import { Grid } from '@material-ui/core';
|
||||
import { Builds } from './lib/Builds';
|
||||
import { Layout } from 'components/Layout';
|
||||
import { PluginHeader } from 'components/PluginHeader';
|
||||
|
||||
export const BuildsPage: FC<{}> = () => (
|
||||
<Layout>
|
||||
<Content>
|
||||
<ContentHeader title="Circle CI">
|
||||
<Button
|
||||
component={RouterLink}
|
||||
to="/circleci/settings"
|
||||
startIcon={<SettingsIcon />}
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
<SupportButton>A description of your plugin goes here.</SupportButton>
|
||||
</ContentHeader>
|
||||
<PluginHeader title="All builds" />
|
||||
<Grid container spacing={3} direction="column">
|
||||
<Grid item>
|
||||
<InfoCard>
|
||||
<CircleCIFetch />
|
||||
</InfoCard>
|
||||
<Builds />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Content>
|
||||
|
||||
+5
-2
@@ -78,7 +78,7 @@ const transform = (buildsData: BuildSummary[]): CITableBuildInfo[] => {
|
||||
});
|
||||
};
|
||||
|
||||
export const CircleCIFetch: FC<{}> = () => {
|
||||
export const Builds: FC<{}> = () => {
|
||||
const dispatch: Dispatch = useDispatch();
|
||||
const api = useApi(circleCIApiRef);
|
||||
|
||||
@@ -89,7 +89,10 @@ export const CircleCIFetch: FC<{}> = () => {
|
||||
};
|
||||
}, []);
|
||||
const { builds } = useSelector((state: iRootState) => state.builds);
|
||||
const { repo, owner } = useSelector((state: iRootState) => state.settings);
|
||||
const transformedBuilds = transform(builds);
|
||||
|
||||
return <CITable builds={transformedBuilds} />;
|
||||
return (
|
||||
<CITable builds={transformedBuilds} projectName={`${owner}/${repo}`} />
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export { Builds } from './Builds';
|
||||
+18
-4
@@ -1,8 +1,14 @@
|
||||
// Idea for this component to be somehow reusable representation of CI table view
|
||||
import React, { FC } from 'react';
|
||||
// import { makeStyles } from '@material-ui/core/styles';
|
||||
import { Link, CircularProgress, Button } from '@material-ui/core';
|
||||
import { Replay as RetryIcon } from '@material-ui/icons';
|
||||
import {
|
||||
Link,
|
||||
CircularProgress,
|
||||
Button,
|
||||
Typography,
|
||||
Box,
|
||||
} from '@material-ui/core';
|
||||
import { Replay as RetryIcon, GitHub as GithubIcon } from '@material-ui/icons';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
import {
|
||||
StatusFailed,
|
||||
@@ -111,7 +117,7 @@ const generatedColumns: TableColumn[] = [
|
||||
field: 'id',
|
||||
type: 'numeric',
|
||||
// @ts-ignore
|
||||
width: '10%',
|
||||
width: '80px',
|
||||
},
|
||||
{
|
||||
title: 'Build',
|
||||
@@ -154,13 +160,21 @@ const generatedColumns: TableColumn[] = [
|
||||
];
|
||||
export const CITable: FC<{
|
||||
builds: CITableBuildInfo[];
|
||||
}> = React.memo(({ builds = [] }) => {
|
||||
projectName: string;
|
||||
}> = React.memo(({ builds = [], projectName }) => {
|
||||
// const classes = useStyles();
|
||||
// const isTestDataAvailable = builds.some(build => build.tests);
|
||||
return (
|
||||
<Table
|
||||
options={{ paging: false }}
|
||||
data={builds}
|
||||
title={
|
||||
<Box display="flex" alignItems="center">
|
||||
<GithubIcon />
|
||||
<Box mr={1} />
|
||||
<Typography variant="h6">{projectName}</Typography>
|
||||
</Box>
|
||||
}
|
||||
columns={generatedColumns}
|
||||
/>
|
||||
);
|
||||
@@ -5,46 +5,79 @@ import { PluginHeader } from 'components/PluginHeader';
|
||||
import { BuildWithSteps, BuildStepAction } from 'circleci-api';
|
||||
import { circleCIApiRef } from 'api';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { ActionOutput } from '../../components/ActionOutput/ActionOutput';
|
||||
import { ActionOutput } from './lib/ActionOutput/ActionOutput';
|
||||
import { Layout } from 'components/Layout';
|
||||
import { Dispatch, iRootState } from 'state/store';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
const BuildName: FC<{ build: BuildWithSteps | null }> = ({ build }) => (
|
||||
<>
|
||||
#{build?.build_num} - {build?.branch}
|
||||
</>
|
||||
);
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
failed: {
|
||||
position: 'relative',
|
||||
'&:after': {
|
||||
pointerEvents: 'none',
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
boxShadow: `inset 4px 0px 0px ${theme.palette.error.main}`,
|
||||
},
|
||||
},
|
||||
cardContent: {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
},
|
||||
success: {
|
||||
position: 'relative',
|
||||
'&:after': {
|
||||
pointerEvents: 'none',
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
boxShadow: `inset 4px 0px 0px ${theme.palette.success.main}`,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export const DetailedViewPage: FC<{}> = () => {
|
||||
let { buildId = '' } = useParams();
|
||||
|
||||
const [authed, setAuthed] = React.useState(false);
|
||||
const [build, setBuild] = React.useState<BuildWithSteps | null>(null);
|
||||
const classes = useStyles();
|
||||
const dispatch: Dispatch = useDispatch();
|
||||
const api = useApi(circleCIApiRef);
|
||||
|
||||
React.useEffect(() => {
|
||||
const getBuildAsync = async () => {
|
||||
if (!authed) {
|
||||
await api.restorePersistedSettings();
|
||||
await api
|
||||
.validateToken()
|
||||
.then(() => {
|
||||
setAuthed(true);
|
||||
})
|
||||
.catch(() => setAuthed(false));
|
||||
}
|
||||
api.getBuild(buildId).then(setBuild);
|
||||
dispatch.buildWithSteps.startPolling({ api, buildId: Number(buildId) });
|
||||
return () => {
|
||||
dispatch.buildWithSteps.stopPolling();
|
||||
};
|
||||
getBuildAsync();
|
||||
}, [authed, buildId]);
|
||||
}, []);
|
||||
const { build } = useSelector((state: iRootState) => state.buildWithSteps);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Content>
|
||||
<PluginHeader />
|
||||
{!api.authed ? (
|
||||
<div>Not authenticated</div>
|
||||
) : (
|
||||
<Grid container spacing={3} direction="column">
|
||||
<Grid item>
|
||||
<InfoCard title="Pipelines">
|
||||
<BuildsList build={build} />
|
||||
</InfoCard>
|
||||
</Grid>
|
||||
<PluginHeader title="Build info" />
|
||||
|
||||
<Grid container spacing={3} direction="column">
|
||||
<Grid item>
|
||||
<InfoCard
|
||||
className={build?.failed ? classes.failed : classes.success}
|
||||
title={<BuildName build={build} />}
|
||||
cardClassName={classes.cardContent}
|
||||
>
|
||||
<BuildsList build={build} />
|
||||
</InfoCard>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</Content>
|
||||
</Layout>
|
||||
);
|
||||
@@ -64,14 +97,18 @@ const BuildsList: FC<{ build: BuildWithSteps | null }> = ({ build }) => (
|
||||
|
||||
const ActionsList: FC<{ actions: BuildStepAction[]; name: string }> = ({
|
||||
actions,
|
||||
}) => (
|
||||
<>
|
||||
{actions.map((action: BuildStepAction) => (
|
||||
<ActionOutput
|
||||
action={action}
|
||||
name={action.name}
|
||||
url={action.output_url || ''}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}) => {
|
||||
const classes = useStyles();
|
||||
return (
|
||||
<>
|
||||
{actions.map((action: BuildStepAction) => (
|
||||
<ActionOutput
|
||||
className={action.failed ? classes.failed : classes.success}
|
||||
action={action}
|
||||
name={action.name}
|
||||
url={action.output_url || ''}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
+29
-7
@@ -7,20 +7,36 @@ import {
|
||||
} from '@material-ui/core';
|
||||
|
||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { BuildStepAction } from 'circleci-api';
|
||||
|
||||
const LazyLog = React.lazy(() => import('react-lazylog/build/LazyLog'));
|
||||
|
||||
const useStyles = makeStyles({
|
||||
expansionPanelDetails: {
|
||||
padding: 0,
|
||||
},
|
||||
button: {
|
||||
order: -1,
|
||||
marginRight: 0,
|
||||
// FIXME: how not to hardcode this
|
||||
marginLeft: '-20px',
|
||||
},
|
||||
});
|
||||
|
||||
export const ActionOutput: FC<{
|
||||
url: string;
|
||||
name: string;
|
||||
className?: string;
|
||||
action: BuildStepAction;
|
||||
}> = ({ url, name }) => {
|
||||
}> = ({ url, name, className }) => {
|
||||
const classes = useStyles();
|
||||
|
||||
const [messages, setMessages] = useState([]);
|
||||
useEffect(() => {
|
||||
fetch(url)
|
||||
.then(res => res.json())
|
||||
.then(actionOutput => {
|
||||
.then((res) => res.json())
|
||||
.then((actionOutput) => {
|
||||
actionOutput &&
|
||||
setMessages(
|
||||
actionOutput.map(({ message }: { message: string }) => message),
|
||||
@@ -28,20 +44,26 @@ export const ActionOutput: FC<{
|
||||
});
|
||||
}, [url]);
|
||||
return (
|
||||
<ExpansionPanel TransitionProps={{ unmountOnExit: true }}>
|
||||
<ExpansionPanel
|
||||
TransitionProps={{ unmountOnExit: true }}
|
||||
className={className}
|
||||
>
|
||||
<ExpansionPanelSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
aria-controls={`panel-${name}-content`}
|
||||
id={`panel-${name}-header`}
|
||||
IconButtonProps={{
|
||||
className: classes.button,
|
||||
}}
|
||||
>
|
||||
<Typography>{name}</Typography>
|
||||
<Typography variant="button">{name}</Typography>
|
||||
</ExpansionPanelSummary>
|
||||
<ExpansionPanelDetails>
|
||||
<ExpansionPanelDetails className={classes.expansionPanelDetails}>
|
||||
{messages.length === 0 ? (
|
||||
'Nothing here...'
|
||||
) : (
|
||||
<Suspense fallback="...">
|
||||
<div style={{ height: '200px', width: '100%' }}>
|
||||
<div style={{ height: '20vh', width: '100%' }}>
|
||||
<LazyLog text={messages.join('\n')} extraLines={1} enableSearch />
|
||||
</div>
|
||||
</Suspense>
|
||||
@@ -12,17 +12,15 @@ import {
|
||||
import {
|
||||
InfoCard,
|
||||
Content,
|
||||
ContentHeader,
|
||||
SupportButton,
|
||||
// StatusOK,
|
||||
// StatusFailed,
|
||||
} from '@backstage/core';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
import { Layout } from 'components/Layout';
|
||||
import { SettingsState } from 'state/models/settings';
|
||||
import { iRootState } from 'state/store';
|
||||
import { Dispatch } from '../../state/store';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import { PluginHeader } from 'components/PluginHeader';
|
||||
|
||||
export const SettingsPage = () => {
|
||||
const {
|
||||
@@ -60,12 +58,8 @@ export const SettingsPage = () => {
|
||||
return (
|
||||
<Layout>
|
||||
<Content>
|
||||
<ContentHeader title="Settings">
|
||||
<Button component={RouterLink} to="/circleci">
|
||||
Back
|
||||
</Button>
|
||||
<SupportButton>A description of your plugin goes here.</SupportButton>
|
||||
</ContentHeader>
|
||||
<PluginHeader title="Settings" />
|
||||
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12} md={3}>
|
||||
<InfoCard
|
||||
@@ -76,6 +70,7 @@ export const SettingsPage = () => {
|
||||
<Snackbar
|
||||
autoHideDuration={1000}
|
||||
open={saved}
|
||||
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
|
||||
onClose={() => setSaved(false)}
|
||||
>
|
||||
<Alert severity="success">Credentials saved.</Alert>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { createPlugin } from '@backstage/core';
|
||||
import { App } from './components/App';
|
||||
import { App } from './App';
|
||||
|
||||
export const plugin = createPlugin({
|
||||
id: 'circleci',
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Dispatch, iRootState } from '../store';
|
||||
import { GitType, BuildWithSteps } from 'circleci-api';
|
||||
import { CircleCIApi } from 'api';
|
||||
|
||||
export type BuildState = {
|
||||
build: BuildWithSteps | null;
|
||||
pollingIntervalId: number | null;
|
||||
pollingState: PollingState;
|
||||
};
|
||||
|
||||
const INTERVAL_AMOUNT = 1500;
|
||||
|
||||
export enum PollingState {
|
||||
Polling,
|
||||
Idle,
|
||||
}
|
||||
export const buildWithSteps = {
|
||||
state: {
|
||||
build: null,
|
||||
pollingIntervalId: null,
|
||||
pollingState: PollingState.Idle,
|
||||
} as BuildState,
|
||||
reducers: {
|
||||
setBuild(state: BuildState, payload: BuildWithSteps) {
|
||||
if (state.pollingState !== PollingState.Polling) {
|
||||
return state;
|
||||
}
|
||||
return { ...state, build: payload };
|
||||
},
|
||||
setPollingIntervalId(state: BuildState, payload: number | null) {
|
||||
return {
|
||||
...state,
|
||||
pollingIntervalId: payload,
|
||||
pollingState:
|
||||
payload === null ? PollingState.Idle : PollingState.Polling,
|
||||
};
|
||||
},
|
||||
},
|
||||
effects: (dispatch: Dispatch) => ({
|
||||
async getBuild(
|
||||
{ api, buildId }: { api: CircleCIApi; buildId: number },
|
||||
state: iRootState,
|
||||
) {
|
||||
try {
|
||||
const options = {
|
||||
token: state.settings.token,
|
||||
vcs: {
|
||||
owner: state.settings.owner,
|
||||
repo: state.settings.repo,
|
||||
type: GitType.GITHUB,
|
||||
},
|
||||
};
|
||||
const build = await api.getBuild(buildId, options);
|
||||
dispatch.buildWithSteps.setBuild(build);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
startPolling(
|
||||
{ api, buildId }: { api: CircleCIApi; buildId: number },
|
||||
state: iRootState,
|
||||
) {
|
||||
if (state.buildWithSteps.pollingIntervalId) return;
|
||||
|
||||
const intervalId = (setInterval(
|
||||
() => dispatch.buildWithSteps.getBuild({ buildId, api }),
|
||||
INTERVAL_AMOUNT,
|
||||
) as any) as number;
|
||||
dispatch.buildWithSteps.setPollingIntervalId(intervalId);
|
||||
},
|
||||
stopPolling(_: any, state: iRootState) {
|
||||
const currentIntervalId = state.buildWithSteps.pollingIntervalId;
|
||||
if (currentIntervalId) clearInterval(currentIntervalId);
|
||||
dispatch.buildWithSteps.setPollingIntervalId(null);
|
||||
},
|
||||
}),
|
||||
};
|
||||
@@ -1,13 +1,16 @@
|
||||
import { settings } from './settings';
|
||||
import { builds } from './builds';
|
||||
import { buildWithSteps } from './buildWithSteps';
|
||||
|
||||
// no need to extend from Models
|
||||
export interface RootModel {
|
||||
settings: typeof settings;
|
||||
builds: typeof builds;
|
||||
buildWithSteps: typeof buildWithSteps;
|
||||
}
|
||||
|
||||
export const models = {
|
||||
settings,
|
||||
builds,
|
||||
buildWithSteps,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { circleCIApiRef } from 'api';
|
||||
import { BuildSummary } from 'circleci-api';
|
||||
import { CITableBuildInfo } from 'components/CITable';
|
||||
import { CITableBuildInfo } from 'pages/BuildsPage/lib/CITable';
|
||||
|
||||
const makeReadableStatus = (status: string | undefined) => {
|
||||
if (typeof status === 'undefined') return '';
|
||||
@@ -22,7 +22,7 @@ const makeReadableStatus = (status: string | undefined) => {
|
||||
};
|
||||
|
||||
export const transformBuildSummary = (
|
||||
api: typeof circleCIApiRef.T,
|
||||
_: typeof circleCIApiRef.T,
|
||||
buildData: BuildSummary,
|
||||
) => {
|
||||
const tableBuildInfo: CITableBuildInfo = {
|
||||
@@ -31,7 +31,7 @@ export const transformBuildSummary = (
|
||||
? buildData.subject +
|
||||
(buildData.retry_of ? ` (retry of #${buildData.retry_of})` : '')
|
||||
: '',
|
||||
onRetryClick: () => api.retry(String(buildData.build_num)),
|
||||
onRetryClick: () => {}, //api.retry(String(buildData.build_num)),
|
||||
source: {
|
||||
branchName: String(buildData.branch),
|
||||
commit: {
|
||||
|
||||
Reference in New Issue
Block a user