@backstage-community/plugin-github-actions 0.6.16 → 0.6.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +52 -2
  3. package/alpha/package.json +7 -0
  4. package/dist/alpha/apis.esm.js +15 -0
  5. package/dist/alpha/apis.esm.js.map +1 -0
  6. package/dist/alpha/entityCards.esm.js +51 -0
  7. package/dist/alpha/entityCards.esm.js.map +1 -0
  8. package/dist/alpha/entityContent.esm.js +15 -0
  9. package/dist/alpha/entityContent.esm.js.map +1 -0
  10. package/dist/alpha.d.ts +10 -0
  11. package/dist/alpha.esm.js +24 -0
  12. package/dist/alpha.esm.js.map +1 -0
  13. package/dist/api/GithubActionsApi.esm.js +8 -0
  14. package/dist/api/GithubActionsApi.esm.js.map +1 -0
  15. package/dist/api/GithubActionsClient.esm.js +113 -0
  16. package/dist/api/GithubActionsClient.esm.js.map +1 -0
  17. package/dist/api/types.esm.js +10 -0
  18. package/dist/api/types.esm.js.map +1 -0
  19. package/dist/components/Cards/Cards.esm.js +78 -0
  20. package/dist/components/Cards/Cards.esm.js.map +1 -0
  21. package/dist/components/Cards/RecentWorkflowRunsCard.esm.js +71 -0
  22. package/dist/components/Cards/RecentWorkflowRunsCard.esm.js.map +1 -0
  23. package/dist/components/Cards/index.esm.js +3 -0
  24. package/dist/components/Cards/index.esm.js.map +1 -0
  25. package/dist/components/Router.esm.js +28 -0
  26. package/dist/components/Router.esm.js.map +1 -0
  27. package/dist/components/WorkflowRunDetails/WorkflowRunDetails.esm.js +128 -0
  28. package/dist/components/WorkflowRunDetails/WorkflowRunDetails.esm.js.map +1 -0
  29. package/dist/components/WorkflowRunDetails/useWorkflowRunJobs.esm.js +49 -0
  30. package/dist/components/WorkflowRunDetails/useWorkflowRunJobs.esm.js.map +1 -0
  31. package/dist/components/WorkflowRunDetails/useWorkflowRunsDetails.esm.js +27 -0
  32. package/dist/components/WorkflowRunDetails/useWorkflowRunsDetails.esm.js.map +1 -0
  33. package/dist/components/WorkflowRunLogs/WorkflowRunLogs.esm.js +106 -0
  34. package/dist/components/WorkflowRunLogs/WorkflowRunLogs.esm.js.map +1 -0
  35. package/dist/components/WorkflowRunLogs/useDownloadWorkflowRunLogs.esm.js +26 -0
  36. package/dist/components/WorkflowRunLogs/useDownloadWorkflowRunLogs.esm.js.map +1 -0
  37. package/dist/components/WorkflowRunStatus/WorkflowRunStatus.esm.js +61 -0
  38. package/dist/components/WorkflowRunStatus/WorkflowRunStatus.esm.js.map +1 -0
  39. package/dist/components/WorkflowRunsCard/WorkflowRunsCard.esm.js +296 -0
  40. package/dist/components/WorkflowRunsCard/WorkflowRunsCard.esm.js.map +1 -0
  41. package/dist/components/WorkflowRunsTable/WorkflowRunsTable.esm.js +139 -0
  42. package/dist/components/WorkflowRunsTable/WorkflowRunsTable.esm.js.map +1 -0
  43. package/dist/components/getHostnameFromEntity.esm.js +10 -0
  44. package/dist/components/getHostnameFromEntity.esm.js.map +1 -0
  45. package/dist/components/getProjectNameFromEntity.esm.js +5 -0
  46. package/dist/components/getProjectNameFromEntity.esm.js.map +1 -0
  47. package/dist/components/useWorkflowRuns.esm.js +122 -0
  48. package/dist/components/useWorkflowRuns.esm.js.map +1 -0
  49. package/dist/index.d.ts +4 -4
  50. package/dist/index.esm.js +8 -1237
  51. package/dist/index.esm.js.map +1 -1
  52. package/dist/plugin.esm.js +55 -0
  53. package/dist/plugin.esm.js.map +1 -0
  54. package/dist/routes.esm.js +13 -0
  55. package/dist/routes.esm.js.map +1 -0
  56. package/package.json +37 -18
  57. package/dist/esm/index-CRpdBPJi.esm.js +0 -50
  58. package/dist/esm/index-CRpdBPJi.esm.js.map +0 -1
@@ -0,0 +1,296 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import Typography from '@material-ui/core/Typography';
3
+ import Box from '@material-ui/core/Box';
4
+ import IconButton from '@material-ui/core/IconButton';
5
+ import Tooltip from '@material-ui/core/Tooltip';
6
+ import Button from '@material-ui/core/Button';
7
+ import Chip from '@material-ui/core/Chip';
8
+ import ButtonGroup from '@material-ui/core/ButtonGroup';
9
+ import Grid from '@material-ui/core/Grid';
10
+ import TablePagination from '@material-ui/core/TablePagination';
11
+ import Select from '@material-ui/core/Select';
12
+ import MenuItem from '@material-ui/core/MenuItem';
13
+ import TextField from '@material-ui/core/TextField';
14
+ import CircularProgress from '@material-ui/core/CircularProgress';
15
+ import { makeStyles, createStyles } from '@material-ui/core/styles';
16
+ import { EmptyState, InfoCard, Link, MarkdownContent } from '@backstage/core-components';
17
+ import GitHubIcon from '@material-ui/icons/GitHub';
18
+ import RetryIcon from '@material-ui/icons/Replay';
19
+ import SyncIcon from '@material-ui/icons/Sync';
20
+ import ExternalLinkIcon from '@material-ui/icons/Launch';
21
+ import { useRouteRef } from '@backstage/core-plugin-api';
22
+ import { useWorkflowRuns } from '../useWorkflowRuns.esm.js';
23
+ import { WorkflowRunStatus } from '../WorkflowRunStatus/WorkflowRunStatus.esm.js';
24
+ import { buildRouteRef } from '../../routes.esm.js';
25
+ import { getProjectNameFromEntity } from '../getProjectNameFromEntity.esm.js';
26
+ import { getHostnameFromEntity } from '../getHostnameFromEntity.esm.js';
27
+ import Alert from '@material-ui/lab/Alert';
28
+
29
+ const useStyles = makeStyles(
30
+ (theme) => createStyles({
31
+ card: {
32
+ border: `1px solid ${theme.palette.divider}`,
33
+ boxShadow: theme.shadows[2],
34
+ borderRadius: "4px",
35
+ overflow: "visible",
36
+ position: "relative",
37
+ margin: theme.spacing(4, 1, 1),
38
+ flex: "1",
39
+ minWidth: "0px"
40
+ },
41
+ externalLinkIcon: {
42
+ fontSize: "inherit",
43
+ verticalAlign: "middle"
44
+ },
45
+ bottomline: {
46
+ display: "flex",
47
+ justifyContent: "space-between",
48
+ alignItems: "center",
49
+ marginTop: "-5px"
50
+ },
51
+ pagination: {
52
+ width: "100%"
53
+ }
54
+ })
55
+ );
56
+ const statusColors = {
57
+ skipped: "warning",
58
+ canceled: "info",
59
+ timed_out: "error",
60
+ failure: "error",
61
+ success: "success"
62
+ };
63
+ const matchesSearchTerm = (run, searchTerm) => {
64
+ const lowerCaseSearchTerm = searchTerm.toLocaleLowerCase();
65
+ return run.workflowName?.toLocaleLowerCase().includes(lowerCaseSearchTerm) || run.source.branchName?.toLocaleLowerCase().includes(lowerCaseSearchTerm) || run.status?.toLocaleLowerCase().includes(lowerCaseSearchTerm) || run.id?.toLocaleLowerCase().includes(lowerCaseSearchTerm);
66
+ };
67
+ const WorkflowRunsCardView = ({
68
+ runs,
69
+ searchTerm,
70
+ loading,
71
+ onChangePageSize,
72
+ onChangePage,
73
+ page,
74
+ total,
75
+ pageSize
76
+ }) => {
77
+ const classes = useStyles();
78
+ const routeLink = useRouteRef(buildRouteRef);
79
+ const filteredRuns = runs?.filter((run) => matchesSearchTerm(run, searchTerm));
80
+ return /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 3 }, filteredRuns && runs?.length !== 0 ? filteredRuns.map((run) => /* @__PURE__ */ React.createElement(Grid, { key: run.id, item: true, container: true, xs: 12, sm: 4, md: 4, xl: 4 }, /* @__PURE__ */ React.createElement(Box, { className: classes.card }, /* @__PURE__ */ React.createElement(
81
+ Box,
82
+ {
83
+ display: "flex",
84
+ flexDirection: "column",
85
+ m: 3,
86
+ alignItems: "center",
87
+ justifyContent: "center"
88
+ },
89
+ /* @__PURE__ */ React.createElement(Box, { pt: 2, sx: { width: "100%" }, textAlign: "center" }, /* @__PURE__ */ React.createElement(
90
+ Tooltip,
91
+ {
92
+ title: run.status ?? "No Status",
93
+ placement: "top-start"
94
+ },
95
+ /* @__PURE__ */ React.createElement(
96
+ Alert,
97
+ {
98
+ variant: "outlined",
99
+ severity: statusColors[run.conclusion],
100
+ style: { alignItems: "center" }
101
+ },
102
+ /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, /* @__PURE__ */ React.createElement(Link, { to: routeLink({ id: run.id }) }, /* @__PURE__ */ React.createElement(Typography, { color: "primary", variant: "h6" }, run.workflowName)))
103
+ )
104
+ ), /* @__PURE__ */ React.createElement(Tooltip, { title: run.message ?? "No run message" }, /* @__PURE__ */ React.createElement(
105
+ Typography,
106
+ {
107
+ variant: "body2",
108
+ component: "span",
109
+ style: { fontSize: "smaller" }
110
+ },
111
+ /* @__PURE__ */ React.createElement(
112
+ MarkdownContent,
113
+ {
114
+ content: `Commit ID : ${run.source.commit.hash}`
115
+ }
116
+ )
117
+ )), run.source.branchName && /* @__PURE__ */ React.createElement(
118
+ MarkdownContent,
119
+ {
120
+ content: `Branch : ${run.source.branchName}`
121
+ }
122
+ ), /* @__PURE__ */ React.createElement(
123
+ Chip,
124
+ {
125
+ key: run.id,
126
+ size: "small",
127
+ label: `Workflow ID : ${run.id}`
128
+ }
129
+ ), /* @__PURE__ */ React.createElement(
130
+ Chip,
131
+ {
132
+ size: "small",
133
+ label: /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(
134
+ WorkflowRunStatus,
135
+ {
136
+ status: run.status,
137
+ conclusion: run.conclusion
138
+ }
139
+ ))
140
+ }
141
+ ), /* @__PURE__ */ React.createElement("div", { className: classes.bottomline }, run.githubUrl && /* @__PURE__ */ React.createElement(Link, { to: run.githubUrl }, "Workflow runs on GitHub", " ", /* @__PURE__ */ React.createElement(
142
+ ExternalLinkIcon,
143
+ {
144
+ className: classes.externalLinkIcon
145
+ }
146
+ )), /* @__PURE__ */ React.createElement(ButtonGroup, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Rerun workflow" }, /* @__PURE__ */ React.createElement(
147
+ IconButton,
148
+ {
149
+ onClick: run.onReRunClick,
150
+ style: { fontSize: "12px" }
151
+ },
152
+ /* @__PURE__ */ React.createElement(RetryIcon, null)
153
+ )))))
154
+ )))) : /* @__PURE__ */ React.createElement(Box, { p: 2 }, loading ? /* @__PURE__ */ React.createElement(CircularProgress, null) : "No matching runs found."), /* @__PURE__ */ React.createElement("div", { className: classes.pagination }, /* @__PURE__ */ React.createElement(
155
+ TablePagination,
156
+ {
157
+ component: "div",
158
+ count: total,
159
+ page,
160
+ rowsPerPage: pageSize,
161
+ onPageChange: (_, newPage) => onChangePage(newPage),
162
+ onRowsPerPageChange: (event) => onChangePageSize(parseInt(event.target.value, 6)),
163
+ labelRowsPerPage: "Workflows per page",
164
+ rowsPerPageOptions: [6, 12, 18, { label: "All", value: -1 }]
165
+ }
166
+ )));
167
+ };
168
+ const WorkflowRunsCardSearch = ({
169
+ searchTerm,
170
+ handleSearch,
171
+ retry
172
+ }) => {
173
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { flexGrow: 1 }), /* @__PURE__ */ React.createElement(
174
+ TextField,
175
+ {
176
+ type: "search",
177
+ label: "Search",
178
+ value: searchTerm,
179
+ onChange: handleSearch,
180
+ "data-testid": "search-control",
181
+ style: { marginRight: "20px" }
182
+ }
183
+ ), /* @__PURE__ */ React.createElement(ButtonGroup, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Reload workflow runs" }, /* @__PURE__ */ React.createElement(IconButton, { onClick: retry }, /* @__PURE__ */ React.createElement(SyncIcon, null)))));
184
+ };
185
+ const WorkflowRunsCard = ({ entity }) => {
186
+ const projectName = getProjectNameFromEntity(entity);
187
+ const hostname = getHostnameFromEntity(entity);
188
+ const [owner, repo] = (projectName ?? "/").split("/");
189
+ const [branch, setBranch] = useState("default");
190
+ const [runs, setRuns] = useState([]);
191
+ const [searchTerm, setSearchTerm] = useState("");
192
+ const handleSearch = (event) => {
193
+ setSearchTerm(event.target.value);
194
+ };
195
+ const [
196
+ { runs: runsData, branches, defaultBranch, ...cardProps },
197
+ { retry, setPage, setPageSize }
198
+ ] = useWorkflowRuns({
199
+ hostname,
200
+ owner,
201
+ repo,
202
+ branch: branch === "all" ? void 0 : branch
203
+ });
204
+ const githubHost = hostname || "github.com";
205
+ const hasNoRuns = !cardProps.loading && !runsData;
206
+ const handleMenuChange = (event) => {
207
+ const selectedValue = event.target.value;
208
+ setBranch(selectedValue);
209
+ setPage(0);
210
+ retry();
211
+ };
212
+ useEffect(() => {
213
+ setRuns(runsData);
214
+ }, [runsData, branch]);
215
+ useEffect(() => {
216
+ setBranch(defaultBranch);
217
+ }, [defaultBranch]);
218
+ return /* @__PURE__ */ React.createElement(Grid, { item: true }, hasNoRuns ? /* @__PURE__ */ React.createElement(
219
+ EmptyState,
220
+ {
221
+ missing: "data",
222
+ title: "No Workflow Data",
223
+ description: "This component has GitHub Actions enabled, but no data was found. Have you created any Workflows? Click the button below to create a new Workflow.",
224
+ action: /* @__PURE__ */ React.createElement(
225
+ Button,
226
+ {
227
+ variant: "contained",
228
+ color: "primary",
229
+ href: `https://${githubHost}/${projectName}/actions/new`
230
+ },
231
+ "Create new Workflow"
232
+ )
233
+ }
234
+ ) : /* @__PURE__ */ React.createElement(
235
+ InfoCard,
236
+ {
237
+ title: /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(GitHubIcon, null), /* @__PURE__ */ React.createElement(Box, { mr: 1 }), /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, projectName), /* @__PURE__ */ React.createElement(
238
+ Select,
239
+ {
240
+ value: branch,
241
+ key: branch,
242
+ label: "Branch",
243
+ onChange: handleMenuChange,
244
+ "data-testid": "menu-control",
245
+ style: {
246
+ marginLeft: "30px",
247
+ marginRight: "20px",
248
+ width: "230px"
249
+ }
250
+ },
251
+ branches.map((branchItem) => /* @__PURE__ */ React.createElement(MenuItem, { key: branchItem.name, value: branchItem.name }, branchItem.name === defaultBranch ? /* @__PURE__ */ React.createElement(Typography, { variant: "body2", component: "span" }, branchItem.name, " ", /* @__PURE__ */ React.createElement(
252
+ Typography,
253
+ {
254
+ variant: "body2",
255
+ component: "span",
256
+ style: { color: "lightgray", fontSize: "x-small" }
257
+ },
258
+ "(default)"
259
+ )) : branchItem.name)),
260
+ /* @__PURE__ */ React.createElement(
261
+ MenuItem,
262
+ {
263
+ value: "all",
264
+ key: "all",
265
+ style: { color: "lightGrey", fontSize: "small" }
266
+ },
267
+ "select all branches"
268
+ )
269
+ ), /* @__PURE__ */ React.createElement(
270
+ WorkflowRunsCardSearch,
271
+ {
272
+ searchTerm,
273
+ handleSearch,
274
+ retry
275
+ }
276
+ ))
277
+ },
278
+ /* @__PURE__ */ React.createElement(
279
+ WorkflowRunsCardView,
280
+ {
281
+ runs,
282
+ loading: cardProps.loading,
283
+ onChangePageSize: setPageSize,
284
+ onChangePage: setPage,
285
+ page: cardProps.page,
286
+ total: cardProps.total,
287
+ pageSize: cardProps.pageSize,
288
+ searchTerm,
289
+ projectName
290
+ }
291
+ )
292
+ ));
293
+ };
294
+
295
+ export { WorkflowRunsCard, WorkflowRunsCardView, WorkflowRunsCard as default };
296
+ //# sourceMappingURL=WorkflowRunsCard.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkflowRunsCard.esm.js","sources":["../../../src/components/WorkflowRunsCard/WorkflowRunsCard.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { ChangeEvent, useEffect, useState } from 'react';\nimport Typography from '@material-ui/core/Typography';\nimport Box from '@material-ui/core/Box';\nimport IconButton from '@material-ui/core/IconButton';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Button from '@material-ui/core/Button';\nimport Chip from '@material-ui/core/Chip';\nimport ButtonGroup from '@material-ui/core/ButtonGroup';\nimport Grid from '@material-ui/core/Grid';\nimport TablePagination from '@material-ui/core/TablePagination';\nimport Select from '@material-ui/core/Select';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport TextField from '@material-ui/core/TextField';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport { makeStyles, createStyles, Theme } from '@material-ui/core/styles';\nimport {\n EmptyState,\n Link,\n MarkdownContent,\n InfoCard,\n} from '@backstage/core-components';\nimport GitHubIcon from '@material-ui/icons/GitHub';\nimport RetryIcon from '@material-ui/icons/Replay';\nimport SyncIcon from '@material-ui/icons/Sync';\nimport ExternalLinkIcon from '@material-ui/icons/Launch';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { useWorkflowRuns, WorkflowRun } from '../useWorkflowRuns';\nimport { WorkflowRunStatus } from '../WorkflowRunStatus';\nimport { buildRouteRef } from '../../routes';\nimport { getProjectNameFromEntity } from '../getProjectNameFromEntity';\nimport { getHostnameFromEntity } from '../getHostnameFromEntity';\n\nimport Alert, { Color } from '@material-ui/lab/Alert';\nimport { Entity } from '@backstage/catalog-model';\n\nconst useStyles = makeStyles((theme: Theme) =>\n createStyles({\n card: {\n border: `1px solid ${theme.palette.divider}`,\n boxShadow: theme.shadows[2],\n borderRadius: '4px',\n overflow: 'visible',\n position: 'relative',\n margin: theme.spacing(4, 1, 1),\n flex: '1',\n minWidth: '0px',\n },\n externalLinkIcon: {\n fontSize: 'inherit',\n verticalAlign: 'middle',\n },\n bottomline: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginTop: '-5px',\n },\n pagination: {\n width: '100%',\n },\n }),\n);\n\ntype WorkflowRunsCardViewProps = {\n runs?: WorkflowRun[];\n searchTerm: string;\n loading: boolean;\n onChangePageSize: (pageSize: number) => void;\n onChangePage: (page: number) => void;\n page: number;\n total: number;\n pageSize: number;\n projectName: string;\n};\n\nconst statusColors: Record<string, string> = {\n skipped: 'warning',\n canceled: 'info',\n timed_out: 'error',\n failure: 'error',\n success: 'success',\n};\n\nconst matchesSearchTerm = (run: WorkflowRun, searchTerm: string) => {\n const lowerCaseSearchTerm = searchTerm.toLocaleLowerCase();\n return (\n run.workflowName?.toLocaleLowerCase().includes(lowerCaseSearchTerm) ||\n run.source.branchName?.toLocaleLowerCase().includes(lowerCaseSearchTerm) ||\n run.status?.toLocaleLowerCase().includes(lowerCaseSearchTerm) ||\n run.id?.toLocaleLowerCase().includes(lowerCaseSearchTerm)\n );\n};\n\nexport const WorkflowRunsCardView = ({\n runs,\n searchTerm,\n loading,\n onChangePageSize,\n onChangePage,\n page,\n total,\n pageSize,\n}: WorkflowRunsCardViewProps) => {\n const classes = useStyles();\n const routeLink = useRouteRef(buildRouteRef);\n\n const filteredRuns = runs?.filter(run => matchesSearchTerm(run, searchTerm));\n\n return (\n <Grid container spacing={3}>\n {filteredRuns && runs?.length !== 0 ? (\n filteredRuns.map(run => (\n <Grid key={run.id} item container xs={12} sm={4} md={4} xl={4}>\n <Box className={classes.card}>\n <Box\n display=\"flex\"\n flexDirection=\"column\"\n m={3}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box pt={2} sx={{ width: '100%' }} textAlign=\"center\">\n <Tooltip\n title={run.status ?? 'No Status'}\n placement=\"top-start\"\n >\n <Alert\n variant=\"outlined\"\n severity={\n statusColors[\n run.conclusion as keyof typeof statusColors\n ] as Color\n }\n style={{ alignItems: 'center' }}\n >\n <Typography variant=\"h6\">\n <Link to={routeLink({ id: run.id })}>\n <Typography color=\"primary\" variant=\"h6\">\n {run.workflowName}\n </Typography>\n </Link>\n </Typography>\n </Alert>\n </Tooltip>\n <Tooltip title={run.message ?? 'No run message'}>\n <Typography\n variant=\"body2\"\n component=\"span\"\n style={{ fontSize: 'smaller' }}\n >\n <MarkdownContent\n content={`Commit ID : ${run.source.commit.hash!}`}\n />\n </Typography>\n </Tooltip>\n\n {run.source.branchName && (\n <MarkdownContent\n content={`Branch : ${run.source.branchName}`}\n />\n )}\n <Chip\n key={run.id}\n size=\"small\"\n label={`Workflow ID : ${run.id}`}\n />\n <Chip\n size=\"small\"\n label={\n <Box display=\"flex\" alignItems=\"center\">\n <WorkflowRunStatus\n status={run.status}\n conclusion={run.conclusion}\n />\n </Box>\n }\n />\n <div className={classes.bottomline}>\n {run.githubUrl && (\n <Link to={run.githubUrl}>\n Workflow runs on GitHub{' '}\n <ExternalLinkIcon\n className={classes.externalLinkIcon}\n />\n </Link>\n )}\n <ButtonGroup>\n <Tooltip title=\"Rerun workflow\">\n <IconButton\n onClick={run.onReRunClick}\n style={{ fontSize: '12px' }}\n >\n <RetryIcon />\n </IconButton>\n </Tooltip>\n </ButtonGroup>\n </div>\n </Box>\n </Box>\n </Box>\n </Grid>\n ))\n ) : (\n <Box p={2}>\n {loading ? <CircularProgress /> : 'No matching runs found.'}\n </Box>\n )}\n <div className={classes.pagination}>\n <TablePagination\n component=\"div\"\n count={total}\n page={page}\n rowsPerPage={pageSize}\n onPageChange={(_, newPage) => onChangePage(newPage)}\n onRowsPerPageChange={event =>\n onChangePageSize(parseInt(event.target.value, 6))\n }\n labelRowsPerPage=\"Workflows per page\"\n rowsPerPageOptions={[6, 12, 18, { label: 'All', value: -1 }]}\n />\n </div>\n </Grid>\n );\n};\n\ntype WorkflowRunsCardProps = {\n entity: Entity;\n};\n\nconst WorkflowRunsCardSearch = ({\n searchTerm,\n handleSearch,\n retry,\n}: {\n searchTerm: string;\n handleSearch: (event: ChangeEvent<HTMLInputElement>) => void;\n retry: () => void;\n}) => {\n return (\n <>\n <Box flexGrow={1} />\n <TextField\n type=\"search\"\n label=\"Search\"\n value={searchTerm}\n onChange={handleSearch}\n data-testid=\"search-control\"\n style={{ marginRight: '20px' }}\n />\n <ButtonGroup>\n <Tooltip title=\"Reload workflow runs\">\n <IconButton onClick={retry}>\n <SyncIcon />\n </IconButton>\n </Tooltip>\n </ButtonGroup>\n </>\n );\n};\n\nexport const WorkflowRunsCard = ({ entity }: WorkflowRunsCardProps) => {\n const projectName = getProjectNameFromEntity(entity);\n const hostname = getHostnameFromEntity(entity);\n const [owner, repo] = (projectName ?? '/').split('/');\n const [branch, setBranch] = useState<string | undefined>('default');\n const [runs, setRuns] = useState<WorkflowRun[] | undefined>([]);\n const [searchTerm, setSearchTerm] = useState('');\n\n const handleSearch = (event: ChangeEvent<HTMLInputElement>) => {\n setSearchTerm(event.target.value);\n };\n\n const [\n { runs: runsData, branches, defaultBranch, ...cardProps },\n { retry, setPage, setPageSize },\n ] = useWorkflowRuns({\n hostname,\n owner,\n repo,\n branch: branch === 'all' ? undefined : branch,\n });\n\n const githubHost = hostname || 'github.com';\n const hasNoRuns = !cardProps.loading && !runsData;\n\n const handleMenuChange = (\n event: ChangeEvent<{ name?: string; value: unknown }>,\n ) => {\n const selectedValue = event.target.value as string;\n setBranch(selectedValue);\n setPage(0);\n retry();\n };\n\n useEffect(() => {\n setRuns(runsData);\n }, [runsData, branch]);\n\n useEffect(() => {\n setBranch(defaultBranch);\n }, [defaultBranch]);\n\n return (\n <Grid item>\n {hasNoRuns ? (\n <EmptyState\n missing=\"data\"\n title=\"No Workflow Data\"\n description=\"This component has GitHub Actions enabled, but no data was found. Have you created any Workflows? Click the button below to create a new Workflow.\"\n action={\n <Button\n variant=\"contained\"\n color=\"primary\"\n href={`https://${githubHost}/${projectName}/actions/new`}\n >\n Create new Workflow\n </Button>\n }\n />\n ) : (\n <InfoCard\n title={\n <Box display=\"flex\" alignItems=\"center\">\n <GitHubIcon />\n <Box mr={1} />\n <Typography variant=\"h6\">{projectName}</Typography>\n\n <Select\n value={branch}\n key={branch}\n label=\"Branch\"\n onChange={handleMenuChange}\n data-testid=\"menu-control\"\n style={{\n marginLeft: '30px',\n marginRight: '20px',\n width: '230px',\n }}\n >\n {branches.map(branchItem => (\n <MenuItem key={branchItem.name} value={branchItem.name}>\n {branchItem.name === defaultBranch ? (\n <Typography variant=\"body2\" component=\"span\">\n {branchItem.name}{' '}\n <Typography\n variant=\"body2\"\n component=\"span\"\n style={{ color: 'lightgray', fontSize: 'x-small' }}\n >\n (default)\n </Typography>\n </Typography>\n ) : (\n branchItem.name\n )}\n </MenuItem>\n ))}\n\n <MenuItem\n value=\"all\"\n key=\"all\"\n style={{ color: 'lightGrey', fontSize: 'small' }}\n >\n select all branches\n </MenuItem>\n </Select>\n\n <WorkflowRunsCardSearch\n searchTerm={searchTerm}\n handleSearch={handleSearch}\n retry={retry}\n />\n </Box>\n }\n >\n <WorkflowRunsCardView\n runs={runs}\n loading={cardProps.loading}\n onChangePageSize={setPageSize}\n onChangePage={setPage}\n page={cardProps.page}\n total={cardProps.total}\n pageSize={cardProps.pageSize}\n searchTerm={searchTerm}\n projectName={projectName}\n />\n </InfoCard>\n )}\n </Grid>\n );\n};\n\nexport default WorkflowRunsCard;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ import React from 'react';
2
+ import Typography from '@material-ui/core/Typography';
3
+ import Box from '@material-ui/core/Box';
4
+ import IconButton from '@material-ui/core/IconButton';
5
+ import Tooltip from '@material-ui/core/Tooltip';
6
+ import Button from '@material-ui/core/Button';
7
+ import RetryIcon from '@material-ui/icons/Replay';
8
+ import GitHubIcon from '@material-ui/icons/GitHub';
9
+ import { Link as Link$1 } from 'react-router-dom';
10
+ import { useWorkflowRuns } from '../useWorkflowRuns.esm.js';
11
+ import { getStatusDescription, WorkflowRunStatus } from '../WorkflowRunStatus/WorkflowRunStatus.esm.js';
12
+ import SyncIcon from '@material-ui/icons/Sync';
13
+ import { buildRouteRef } from '../../routes.esm.js';
14
+ import { getProjectNameFromEntity } from '../getProjectNameFromEntity.esm.js';
15
+ import { EmptyState, Table, Link } from '@backstage/core-components';
16
+ import { useRouteRef } from '@backstage/core-plugin-api';
17
+ import { getHostnameFromEntity } from '../getHostnameFromEntity.esm.js';
18
+
19
+ const generatedColumns = [
20
+ {
21
+ title: "ID",
22
+ field: "id",
23
+ type: "numeric",
24
+ width: "150px"
25
+ },
26
+ {
27
+ title: "Message",
28
+ field: "message",
29
+ highlight: true,
30
+ render: (row) => {
31
+ const LinkWrapper = () => {
32
+ const routeLink = useRouteRef(buildRouteRef);
33
+ return /* @__PURE__ */ React.createElement(Link, { component: Link$1, to: routeLink({ id: row.id }) }, row.message);
34
+ };
35
+ return /* @__PURE__ */ React.createElement(LinkWrapper, null);
36
+ }
37
+ },
38
+ {
39
+ title: "Source",
40
+ render: (row) => /* @__PURE__ */ React.createElement(Typography, { variant: "body2", noWrap: true }, /* @__PURE__ */ React.createElement(Typography, { paragraph: true, variant: "body2" }, row.source?.branchName), /* @__PURE__ */ React.createElement(Typography, { paragraph: true, variant: "body2" }, row.source?.commit.hash))
41
+ },
42
+ {
43
+ title: "Workflow",
44
+ field: "workflowName"
45
+ },
46
+ {
47
+ title: "Status",
48
+ customSort: (d1, d2) => {
49
+ return getStatusDescription(d1).localeCompare(getStatusDescription(d2));
50
+ },
51
+ render: (row) => /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(WorkflowRunStatus, { status: row.status, conclusion: row.conclusion }))
52
+ },
53
+ {
54
+ title: "Actions",
55
+ render: (row) => /* @__PURE__ */ React.createElement(Tooltip, { title: "Rerun workflow" }, /* @__PURE__ */ React.createElement(IconButton, { onClick: row.onReRunClick }, /* @__PURE__ */ React.createElement(RetryIcon, null))),
56
+ width: "10%"
57
+ }
58
+ ];
59
+ const WorkflowRunsTableView = ({
60
+ projectName,
61
+ loading,
62
+ pageSize,
63
+ page,
64
+ retry,
65
+ runs,
66
+ onChangePage,
67
+ onChangePageSize,
68
+ total
69
+ }) => {
70
+ return /* @__PURE__ */ React.createElement(
71
+ Table,
72
+ {
73
+ isLoading: loading,
74
+ options: { paging: true, pageSize, padding: "dense" },
75
+ totalCount: total,
76
+ page,
77
+ actions: [
78
+ {
79
+ icon: () => /* @__PURE__ */ React.createElement(SyncIcon, null),
80
+ tooltip: "Reload workflow runs",
81
+ isFreeAction: true,
82
+ onClick: () => retry()
83
+ }
84
+ ],
85
+ data: runs ?? [],
86
+ onPageChange: onChangePage,
87
+ onRowsPerPageChange: onChangePageSize,
88
+ style: { width: "100%" },
89
+ title: /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(GitHubIcon, null), /* @__PURE__ */ React.createElement(Box, { mr: 1 }), /* @__PURE__ */ React.createElement(Typography, { variant: "h6" }, projectName)),
90
+ columns: generatedColumns
91
+ }
92
+ );
93
+ };
94
+ const WorkflowRunsTable = ({
95
+ entity,
96
+ branch
97
+ }) => {
98
+ const projectName = getProjectNameFromEntity(entity);
99
+ const hostname = getHostnameFromEntity(entity);
100
+ const [owner, repo] = (projectName ?? "/").split("/");
101
+ const [{ runs, ...tableProps }, { retry, setPage, setPageSize }] = useWorkflowRuns({
102
+ hostname,
103
+ owner,
104
+ repo,
105
+ branch
106
+ });
107
+ const githubHost = hostname || "github.com";
108
+ const hasNoRuns = !tableProps.loading && !runs;
109
+ return hasNoRuns ? /* @__PURE__ */ React.createElement(
110
+ EmptyState,
111
+ {
112
+ missing: "data",
113
+ title: "No Workflow Data",
114
+ description: "This component has GitHub Actions enabled, but no data was found. Have you created any Workflows? Click the button below to create a new Workflow.",
115
+ action: /* @__PURE__ */ React.createElement(
116
+ Button,
117
+ {
118
+ variant: "contained",
119
+ color: "primary",
120
+ href: `https://${githubHost}/${projectName}/actions/new`
121
+ },
122
+ "Create new Workflow"
123
+ )
124
+ }
125
+ ) : /* @__PURE__ */ React.createElement(
126
+ WorkflowRunsTableView,
127
+ {
128
+ ...tableProps,
129
+ runs,
130
+ loading: tableProps.loading,
131
+ retry,
132
+ onChangePageSize: setPageSize,
133
+ onChangePage: setPage
134
+ }
135
+ );
136
+ };
137
+
138
+ export { WorkflowRunsTable, WorkflowRunsTableView };
139
+ //# sourceMappingURL=WorkflowRunsTable.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkflowRunsTable.esm.js","sources":["../../../src/components/WorkflowRunsTable/WorkflowRunsTable.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport Typography from '@material-ui/core/Typography';\nimport Box from '@material-ui/core/Box';\nimport IconButton from '@material-ui/core/IconButton';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Button from '@material-ui/core/Button';\nimport RetryIcon from '@material-ui/icons/Replay';\nimport GitHubIcon from '@material-ui/icons/GitHub';\nimport { Link as RouterLink } from 'react-router-dom';\nimport { useWorkflowRuns, WorkflowRun } from '../useWorkflowRuns';\nimport { WorkflowRunStatus } from '../WorkflowRunStatus';\nimport SyncIcon from '@material-ui/icons/Sync';\nimport { buildRouteRef } from '../../routes';\nimport { getProjectNameFromEntity } from '../getProjectNameFromEntity';\nimport { Entity } from '@backstage/catalog-model';\n\nimport {\n EmptyState,\n Table,\n TableColumn,\n Link,\n} from '@backstage/core-components';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { getHostnameFromEntity } from '../getHostnameFromEntity';\nimport { getStatusDescription } from '../WorkflowRunStatus/WorkflowRunStatus';\n\nconst generatedColumns: TableColumn<Partial<WorkflowRun>>[] = [\n {\n title: 'ID',\n field: 'id',\n type: 'numeric',\n width: '150px',\n },\n {\n title: 'Message',\n field: 'message',\n highlight: true,\n render: row => {\n const LinkWrapper = () => {\n const routeLink = useRouteRef(buildRouteRef);\n return (\n <Link component={RouterLink} to={routeLink({ id: row.id! })}>\n {row.message}\n </Link>\n );\n };\n\n return <LinkWrapper />;\n },\n },\n {\n title: 'Source',\n render: row => (\n <Typography variant=\"body2\" noWrap>\n <Typography paragraph variant=\"body2\">\n {row.source?.branchName}\n </Typography>\n <Typography paragraph variant=\"body2\">\n {row.source?.commit.hash}\n </Typography>\n </Typography>\n ),\n },\n {\n title: 'Workflow',\n field: 'workflowName',\n },\n {\n title: 'Status',\n customSort: (d1, d2) => {\n return getStatusDescription(d1).localeCompare(getStatusDescription(d2));\n },\n render: row => (\n <Box display=\"flex\" alignItems=\"center\">\n <WorkflowRunStatus status={row.status} conclusion={row.conclusion} />\n </Box>\n ),\n },\n {\n title: 'Actions',\n render: (row: Partial<WorkflowRun>) => (\n <Tooltip title=\"Rerun workflow\">\n <IconButton onClick={row.onReRunClick}>\n <RetryIcon />\n </IconButton>\n </Tooltip>\n ),\n width: '10%',\n },\n];\n\ntype Props = {\n loading: boolean;\n retry: () => void;\n runs?: WorkflowRun[];\n projectName: string;\n page: number;\n onChangePage: (page: number) => void;\n total: number;\n pageSize: number;\n onChangePageSize: (pageSize: number) => void;\n};\n\nexport const WorkflowRunsTableView = ({\n projectName,\n loading,\n pageSize,\n page,\n retry,\n runs,\n onChangePage,\n onChangePageSize,\n total,\n}: Props) => {\n return (\n <Table\n isLoading={loading}\n options={{ paging: true, pageSize, padding: 'dense' }}\n totalCount={total}\n page={page}\n actions={[\n {\n icon: () => <SyncIcon />,\n tooltip: 'Reload workflow runs',\n isFreeAction: true,\n onClick: () => retry(),\n },\n ]}\n data={runs ?? []}\n onPageChange={onChangePage}\n onRowsPerPageChange={onChangePageSize}\n style={{ width: '100%' }}\n title={\n <Box display=\"flex\" alignItems=\"center\">\n <GitHubIcon />\n <Box mr={1} />\n <Typography variant=\"h6\">{projectName}</Typography>\n </Box>\n }\n columns={generatedColumns}\n />\n );\n};\n\nexport const WorkflowRunsTable = ({\n entity,\n branch,\n}: {\n entity: Entity;\n branch?: string;\n}) => {\n const projectName = getProjectNameFromEntity(entity);\n const hostname = getHostnameFromEntity(entity);\n const [owner, repo] = (projectName ?? '/').split('/');\n const [{ runs, ...tableProps }, { retry, setPage, setPageSize }] =\n useWorkflowRuns({\n hostname,\n owner,\n repo,\n branch,\n });\n\n const githubHost = hostname || 'github.com';\n const hasNoRuns = !tableProps.loading && !runs;\n\n return hasNoRuns ? (\n <EmptyState\n missing=\"data\"\n title=\"No Workflow Data\"\n description=\"This component has GitHub Actions enabled, but no data was found. Have you created any Workflows? Click the button below to create a new Workflow.\"\n action={\n <Button\n variant=\"contained\"\n color=\"primary\"\n href={`https://${githubHost}/${projectName}/actions/new`}\n >\n Create new Workflow\n </Button>\n }\n />\n ) : (\n <WorkflowRunsTableView\n {...tableProps}\n runs={runs}\n loading={tableProps.loading}\n retry={retry}\n onChangePageSize={setPageSize}\n onChangePage={setPage}\n />\n );\n};\n"],"names":["RouterLink"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { ANNOTATION_SOURCE_LOCATION, ANNOTATION_LOCATION } from '@backstage/catalog-model';
2
+ import gitUrlParse from 'git-url-parse';
3
+
4
+ const getHostnameFromEntity = (entity) => {
5
+ const location = entity?.metadata.annotations?.[ANNOTATION_SOURCE_LOCATION] ?? entity?.metadata.annotations?.[ANNOTATION_LOCATION];
6
+ return location?.startsWith("url:") ? gitUrlParse(location.slice(4)).resource : void 0;
7
+ };
8
+
9
+ export { getHostnameFromEntity };
10
+ //# sourceMappingURL=getHostnameFromEntity.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getHostnameFromEntity.esm.js","sources":["../../src/components/getHostnameFromEntity.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ANNOTATION_LOCATION,\n ANNOTATION_SOURCE_LOCATION,\n Entity,\n} from '@backstage/catalog-model';\nimport gitUrlParse from 'git-url-parse';\n\nexport const getHostnameFromEntity = (entity: Entity) => {\n const location =\n entity?.metadata.annotations?.[ANNOTATION_SOURCE_LOCATION] ??\n entity?.metadata.annotations?.[ANNOTATION_LOCATION];\n\n return location?.startsWith('url:')\n ? gitUrlParse(location.slice(4)).resource\n : undefined;\n};\n"],"names":[],"mappings":";;;AAuBa,MAAA,qBAAA,GAAwB,CAAC,MAAmB,KAAA;AACvD,EAAM,MAAA,QAAA,GACJ,QAAQ,QAAS,CAAA,WAAA,GAAc,0BAA0B,CACzD,IAAA,MAAA,EAAQ,QAAS,CAAA,WAAA,GAAc,mBAAmB,CAAA,CAAA;AAEpD,EAAO,OAAA,QAAA,EAAU,UAAW,CAAA,MAAM,CAC9B,GAAA,WAAA,CAAY,SAAS,KAAM,CAAA,CAAC,CAAC,CAAA,CAAE,QAC/B,GAAA,KAAA,CAAA,CAAA;AACN;;;;"}
@@ -0,0 +1,5 @@
1
+ const GITHUB_ACTIONS_ANNOTATION = "github.com/project-slug";
2
+ const getProjectNameFromEntity = (entity) => entity?.metadata.annotations?.[GITHUB_ACTIONS_ANNOTATION] ?? "";
3
+
4
+ export { GITHUB_ACTIONS_ANNOTATION, getProjectNameFromEntity };
5
+ //# sourceMappingURL=getProjectNameFromEntity.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getProjectNameFromEntity.esm.js","sources":["../../src/components/getProjectNameFromEntity.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\n\n/** @public */\nexport const GITHUB_ACTIONS_ANNOTATION = 'github.com/project-slug';\n\nexport const getProjectNameFromEntity = (entity: Entity) =>\n entity?.metadata.annotations?.[GITHUB_ACTIONS_ANNOTATION] ?? '';\n"],"names":[],"mappings":"AAmBO,MAAM,yBAA4B,GAAA,0BAAA;AAElC,MAAM,2BAA2B,CAAC,MAAA,KACvC,QAAQ,QAAS,CAAA,WAAA,GAAc,yBAAyB,CAAK,IAAA;;;;"}
@@ -0,0 +1,122 @@
1
+ import { useState } from 'react';
2
+ import useAsyncRetry from 'react-use/esm/useAsyncRetry';
3
+ import { githubActionsApiRef } from '../api/GithubActionsApi.esm.js';
4
+ import { useApi, errorApiRef } from '@backstage/core-plugin-api';
5
+
6
+ function useWorkflowRuns({
7
+ hostname,
8
+ owner,
9
+ repo,
10
+ branch,
11
+ initialPageSize = 6
12
+ }) {
13
+ const api = useApi(githubActionsApiRef);
14
+ const errorApi = useApi(errorApiRef);
15
+ const [total, setTotal] = useState(0);
16
+ const [page, setPage] = useState(0);
17
+ const [pageSize, setPageSize] = useState(initialPageSize);
18
+ const [branches, setBranches] = useState([]);
19
+ const [defaultBranch, setDefaultBranch] = useState("");
20
+ const {
21
+ loading,
22
+ value: runs,
23
+ retry,
24
+ error
25
+ } = useAsyncRetry(async () => {
26
+ const fetchedDefaultBranch = await api.getDefaultBranch({
27
+ hostname,
28
+ owner,
29
+ repo
30
+ });
31
+ setDefaultBranch(fetchedDefaultBranch);
32
+ let selectedBranch = branch;
33
+ if (branch === "default") {
34
+ selectedBranch = fetchedDefaultBranch;
35
+ }
36
+ const fetchBranches = async () => {
37
+ let next = true;
38
+ let iteratePage = 0;
39
+ const branchSet2 = [];
40
+ while (next) {
41
+ const branchesData = await api.listBranches({
42
+ hostname,
43
+ owner,
44
+ repo,
45
+ page: iteratePage
46
+ });
47
+ if (branchesData.length === 0) {
48
+ next = false;
49
+ }
50
+ iteratePage++;
51
+ branchSet2.push(...branchesData);
52
+ }
53
+ return branchSet2;
54
+ };
55
+ const branchSet = await fetchBranches();
56
+ setBranches(branchSet);
57
+ const workflowRunsData = await api.listWorkflowRuns({
58
+ hostname,
59
+ owner,
60
+ repo,
61
+ pageSize,
62
+ page: page + 1,
63
+ branch: selectedBranch
64
+ });
65
+ setTotal(workflowRunsData.total_count);
66
+ return workflowRunsData.workflow_runs.map((run) => ({
67
+ workflowName: run.name ?? void 0,
68
+ message: run.head_commit?.message,
69
+ id: `${run.id}`,
70
+ onReRunClick: async () => {
71
+ try {
72
+ await api.reRunWorkflow({
73
+ hostname,
74
+ owner,
75
+ repo,
76
+ runId: run.id
77
+ });
78
+ } catch (e) {
79
+ errorApi.post(
80
+ new Error(`Failed to rerun the workflow: ${e.message}`)
81
+ );
82
+ }
83
+ },
84
+ source: {
85
+ branchName: run.head_branch ?? void 0,
86
+ commit: {
87
+ hash: run.head_commit?.id,
88
+ url: run.head_repository?.branches_url?.replace(
89
+ "{/branch}",
90
+ run.head_branch ?? ""
91
+ )
92
+ }
93
+ },
94
+ status: run.status ?? void 0,
95
+ conclusion: run.conclusion ?? void 0,
96
+ url: run.url,
97
+ githubUrl: run.html_url
98
+ }));
99
+ }, [page, pageSize, repo, owner]);
100
+ return [
101
+ {
102
+ page,
103
+ pageSize,
104
+ loading,
105
+ runs,
106
+ branches,
107
+ defaultBranch,
108
+ projectName: `${owner}/${repo}`,
109
+ total,
110
+ error
111
+ },
112
+ {
113
+ runs,
114
+ setPage,
115
+ setPageSize,
116
+ retry
117
+ }
118
+ ];
119
+ }
120
+
121
+ export { useWorkflowRuns };
122
+ //# sourceMappingURL=useWorkflowRuns.esm.js.map