@backstage-community/plugin-github-actions 0.6.16
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.
- package/CHANGELOG.md +2155 -0
- package/README.md +110 -0
- package/dist/esm/index-CRpdBPJi.esm.js +50 -0
- package/dist/esm/index-CRpdBPJi.esm.js.map +1 -0
- package/dist/index.d.ts +236 -0
- package/dist/index.esm.js +1238 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,1238 @@
|
|
|
1
|
+
import { createApiRef, createRouteRef, createSubRouteRef, createPlugin, createApiFactory, configApiRef, createRoutableExtension, createComponentExtension, useApi, useRouteRefParams, errorApiRef, useRouteRef } from '@backstage/core-plugin-api';
|
|
2
|
+
import { readGithubIntegrationConfigs } from '@backstage/integration';
|
|
3
|
+
import { Octokit } from '@octokit/rest';
|
|
4
|
+
import { scmAuthApiRef } from '@backstage/integration-react';
|
|
5
|
+
import React, { useState, useEffect } from 'react';
|
|
6
|
+
import { useEntity, MissingAnnotationEmptyState } from '@backstage/plugin-catalog-react';
|
|
7
|
+
import { Link as Link$1, Routes, Route } from 'react-router-dom';
|
|
8
|
+
import Accordion from '@material-ui/core/Accordion';
|
|
9
|
+
import AccordionDetails from '@material-ui/core/AccordionDetails';
|
|
10
|
+
import AccordionSummary from '@material-ui/core/AccordionSummary';
|
|
11
|
+
import Box from '@material-ui/core/Box';
|
|
12
|
+
import CircularProgress from '@material-ui/core/CircularProgress';
|
|
13
|
+
import LinearProgress from '@material-ui/core/LinearProgress';
|
|
14
|
+
import ListItemText from '@material-ui/core/ListItemText';
|
|
15
|
+
import Paper from '@material-ui/core/Paper';
|
|
16
|
+
import Table from '@material-ui/core/Table';
|
|
17
|
+
import TableBody from '@material-ui/core/TableBody';
|
|
18
|
+
import TableCell from '@material-ui/core/TableCell';
|
|
19
|
+
import TableContainer from '@material-ui/core/TableContainer';
|
|
20
|
+
import TableRow from '@material-ui/core/TableRow';
|
|
21
|
+
import Typography from '@material-ui/core/Typography';
|
|
22
|
+
import { makeStyles, createStyles } from '@material-ui/core/styles';
|
|
23
|
+
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
|
24
|
+
import ExternalLinkIcon from '@material-ui/icons/Launch';
|
|
25
|
+
import { DateTime } from 'luxon';
|
|
26
|
+
import { StatusPending, StatusOK, StatusError, StatusWarning, StatusAborted, StatusRunning, LogViewer, Breadcrumbs, Link, EmptyState, InfoCard, MarkdownContent, Table as Table$1, StructuredMetadataTable, ErrorPanel } from '@backstage/core-components';
|
|
27
|
+
import useAsync from 'react-use/esm/useAsync';
|
|
28
|
+
import Fade from '@material-ui/core/Fade';
|
|
29
|
+
import Modal from '@material-ui/core/Modal';
|
|
30
|
+
import Tooltip from '@material-ui/core/Tooltip';
|
|
31
|
+
import Zoom from '@material-ui/core/Zoom';
|
|
32
|
+
import DescriptionIcon from '@material-ui/icons/Description';
|
|
33
|
+
import { ANNOTATION_SOURCE_LOCATION, ANNOTATION_LOCATION } from '@backstage/catalog-model';
|
|
34
|
+
import gitUrlParse from 'git-url-parse';
|
|
35
|
+
import IconButton from '@material-ui/core/IconButton';
|
|
36
|
+
import Button from '@material-ui/core/Button';
|
|
37
|
+
import Chip from '@material-ui/core/Chip';
|
|
38
|
+
import ButtonGroup from '@material-ui/core/ButtonGroup';
|
|
39
|
+
import Grid from '@material-ui/core/Grid';
|
|
40
|
+
import TablePagination from '@material-ui/core/TablePagination';
|
|
41
|
+
import Select from '@material-ui/core/Select';
|
|
42
|
+
import MenuItem from '@material-ui/core/MenuItem';
|
|
43
|
+
import TextField from '@material-ui/core/TextField';
|
|
44
|
+
import GitHubIcon from '@material-ui/icons/GitHub';
|
|
45
|
+
import RetryIcon from '@material-ui/icons/Replay';
|
|
46
|
+
import SyncIcon from '@material-ui/icons/Sync';
|
|
47
|
+
import useAsyncRetry from 'react-use/esm/useAsyncRetry';
|
|
48
|
+
import Alert from '@material-ui/lab/Alert';
|
|
49
|
+
|
|
50
|
+
const githubActionsApiRef = createApiRef({
|
|
51
|
+
id: "plugin.githubactions.service"
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
var __defProp = Object.defineProperty;
|
|
55
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
56
|
+
var __publicField = (obj, key, value) => {
|
|
57
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
58
|
+
return value;
|
|
59
|
+
};
|
|
60
|
+
class GithubActionsClient {
|
|
61
|
+
constructor(options) {
|
|
62
|
+
__publicField(this, "configApi");
|
|
63
|
+
__publicField(this, "scmAuthApi");
|
|
64
|
+
this.configApi = options.configApi;
|
|
65
|
+
this.scmAuthApi = options.scmAuthApi;
|
|
66
|
+
}
|
|
67
|
+
async getOctokit(hostname = "github.com") {
|
|
68
|
+
var _a;
|
|
69
|
+
const { token } = await this.scmAuthApi.getCredentials({
|
|
70
|
+
url: `https://${hostname}/`,
|
|
71
|
+
additionalScope: {
|
|
72
|
+
customScopes: {
|
|
73
|
+
github: ["repo"]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
const configs = readGithubIntegrationConfigs(
|
|
78
|
+
(_a = this.configApi.getOptionalConfigArray("integrations.github")) != null ? _a : []
|
|
79
|
+
);
|
|
80
|
+
const githubIntegrationConfig = configs.find((v) => v.host === hostname);
|
|
81
|
+
const baseUrl = githubIntegrationConfig == null ? void 0 : githubIntegrationConfig.apiBaseUrl;
|
|
82
|
+
return new Octokit({ auth: token, baseUrl });
|
|
83
|
+
}
|
|
84
|
+
async reRunWorkflow(options) {
|
|
85
|
+
const { hostname, owner, repo, runId } = options;
|
|
86
|
+
const octokit = await this.getOctokit(hostname);
|
|
87
|
+
return octokit.actions.reRunWorkflow({
|
|
88
|
+
owner,
|
|
89
|
+
repo,
|
|
90
|
+
run_id: runId
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async listWorkflowRuns(options) {
|
|
94
|
+
const { hostname, owner, repo, pageSize = 100, page = 0, branch } = options;
|
|
95
|
+
const octokit = await this.getOctokit(hostname);
|
|
96
|
+
const workflowRuns = await octokit.actions.listWorkflowRunsForRepo({
|
|
97
|
+
owner,
|
|
98
|
+
repo,
|
|
99
|
+
per_page: pageSize,
|
|
100
|
+
page,
|
|
101
|
+
...branch ? { branch } : {}
|
|
102
|
+
});
|
|
103
|
+
return workflowRuns.data;
|
|
104
|
+
}
|
|
105
|
+
async getWorkflow(options) {
|
|
106
|
+
const { hostname, owner, repo, id } = options;
|
|
107
|
+
const octokit = await this.getOctokit(hostname);
|
|
108
|
+
const workflow = await octokit.actions.getWorkflow({
|
|
109
|
+
owner,
|
|
110
|
+
repo,
|
|
111
|
+
workflow_id: id
|
|
112
|
+
});
|
|
113
|
+
return workflow.data;
|
|
114
|
+
}
|
|
115
|
+
async getWorkflowRun(options) {
|
|
116
|
+
const { hostname, owner, repo, id } = options;
|
|
117
|
+
const octokit = await this.getOctokit(hostname);
|
|
118
|
+
const run = await octokit.actions.getWorkflowRun({
|
|
119
|
+
owner,
|
|
120
|
+
repo,
|
|
121
|
+
run_id: id
|
|
122
|
+
});
|
|
123
|
+
return run.data;
|
|
124
|
+
}
|
|
125
|
+
async listJobsForWorkflowRun(options) {
|
|
126
|
+
const { hostname, owner, repo, id, pageSize = 100, page = 0 } = options;
|
|
127
|
+
const octokit = await this.getOctokit(hostname);
|
|
128
|
+
const jobs = await octokit.actions.listJobsForWorkflowRun({
|
|
129
|
+
owner,
|
|
130
|
+
repo,
|
|
131
|
+
run_id: id,
|
|
132
|
+
per_page: pageSize,
|
|
133
|
+
page
|
|
134
|
+
});
|
|
135
|
+
return jobs.data;
|
|
136
|
+
}
|
|
137
|
+
async downloadJobLogsForWorkflowRun(options) {
|
|
138
|
+
const { hostname, owner, repo, runId } = options;
|
|
139
|
+
const octokit = await this.getOctokit(hostname);
|
|
140
|
+
const workflow = await octokit.actions.downloadJobLogsForWorkflowRun({
|
|
141
|
+
owner,
|
|
142
|
+
repo,
|
|
143
|
+
job_id: runId
|
|
144
|
+
});
|
|
145
|
+
return workflow.data;
|
|
146
|
+
}
|
|
147
|
+
async listBranches(options) {
|
|
148
|
+
const { hostname, owner, repo, page = 0 } = options;
|
|
149
|
+
const octokit = await this.getOctokit(hostname);
|
|
150
|
+
const response = await octokit.rest.repos.listBranches({
|
|
151
|
+
owner,
|
|
152
|
+
repo,
|
|
153
|
+
per_page: 100,
|
|
154
|
+
page
|
|
155
|
+
});
|
|
156
|
+
return response.data;
|
|
157
|
+
}
|
|
158
|
+
async getDefaultBranch(options) {
|
|
159
|
+
const { hostname, owner, repo } = options;
|
|
160
|
+
const octokit = await this.getOctokit(hostname);
|
|
161
|
+
const response = await octokit.rest.repos.get({
|
|
162
|
+
owner,
|
|
163
|
+
repo
|
|
164
|
+
});
|
|
165
|
+
return response.data.default_branch;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
var BuildStatus = /* @__PURE__ */ ((BuildStatus2) => {
|
|
170
|
+
BuildStatus2[BuildStatus2["success"] = 0] = "success";
|
|
171
|
+
BuildStatus2[BuildStatus2["failure"] = 1] = "failure";
|
|
172
|
+
BuildStatus2[BuildStatus2["pending"] = 2] = "pending";
|
|
173
|
+
BuildStatus2[BuildStatus2["running"] = 3] = "running";
|
|
174
|
+
return BuildStatus2;
|
|
175
|
+
})(BuildStatus || {});
|
|
176
|
+
|
|
177
|
+
const rootRouteRef = createRouteRef({
|
|
178
|
+
id: "github-actions"
|
|
179
|
+
});
|
|
180
|
+
const buildRouteRef = createSubRouteRef({
|
|
181
|
+
id: "github-actions/build",
|
|
182
|
+
path: "/:id",
|
|
183
|
+
parent: rootRouteRef
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const githubActionsPlugin = createPlugin({
|
|
187
|
+
id: "github-actions",
|
|
188
|
+
apis: [
|
|
189
|
+
createApiFactory({
|
|
190
|
+
api: githubActionsApiRef,
|
|
191
|
+
deps: { configApi: configApiRef, scmAuthApi: scmAuthApiRef },
|
|
192
|
+
factory: ({ configApi, scmAuthApi }) => new GithubActionsClient({ configApi, scmAuthApi })
|
|
193
|
+
})
|
|
194
|
+
],
|
|
195
|
+
routes: {
|
|
196
|
+
entityContent: rootRouteRef
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
const EntityGithubActionsContent = githubActionsPlugin.provide(
|
|
200
|
+
createRoutableExtension({
|
|
201
|
+
name: "EntityGithubActionsContent",
|
|
202
|
+
component: () => Promise.resolve().then(function () { return Router$1; }).then((m) => m.Router),
|
|
203
|
+
mountPoint: rootRouteRef
|
|
204
|
+
})
|
|
205
|
+
);
|
|
206
|
+
const EntityLatestGithubActionRunCard = githubActionsPlugin.provide(
|
|
207
|
+
createComponentExtension({
|
|
208
|
+
name: "EntityLatestGithubActionRunCard",
|
|
209
|
+
component: {
|
|
210
|
+
lazy: () => import('./esm/index-CRpdBPJi.esm.js').then((m) => m.LatestWorkflowRunCard)
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
);
|
|
214
|
+
const EntityLatestGithubActionsForBranchCard = githubActionsPlugin.provide(
|
|
215
|
+
createComponentExtension({
|
|
216
|
+
name: "EntityLatestGithubActionsForBranchCard",
|
|
217
|
+
component: {
|
|
218
|
+
lazy: () => import('./esm/index-CRpdBPJi.esm.js').then(
|
|
219
|
+
(m) => m.LatestWorkflowsForBranchCard
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
})
|
|
223
|
+
);
|
|
224
|
+
const EntityRecentGithubActionsRunsCard = githubActionsPlugin.provide(
|
|
225
|
+
createComponentExtension({
|
|
226
|
+
name: "EntityRecentGithubActionsRunsCard",
|
|
227
|
+
component: {
|
|
228
|
+
lazy: () => import('./esm/index-CRpdBPJi.esm.js').then((m) => m.RecentWorkflowRunsCard)
|
|
229
|
+
}
|
|
230
|
+
})
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
const GITHUB_ACTIONS_ANNOTATION = "github.com/project-slug";
|
|
234
|
+
const getProjectNameFromEntity = (entity) => {
|
|
235
|
+
var _a, _b;
|
|
236
|
+
return (_b = (_a = entity == null ? void 0 : entity.metadata.annotations) == null ? void 0 : _a[GITHUB_ACTIONS_ANNOTATION]) != null ? _b : "";
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const WorkflowRunStatus = (props) => {
|
|
240
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(WorkflowIcon, { ...props }), getStatusDescription(props));
|
|
241
|
+
};
|
|
242
|
+
function WorkflowIcon({
|
|
243
|
+
status,
|
|
244
|
+
conclusion
|
|
245
|
+
}) {
|
|
246
|
+
if (status === void 0)
|
|
247
|
+
return null;
|
|
248
|
+
switch (status.toLocaleLowerCase("en-US")) {
|
|
249
|
+
case "queued":
|
|
250
|
+
return /* @__PURE__ */ React.createElement(StatusPending, null);
|
|
251
|
+
case "in_progress":
|
|
252
|
+
return /* @__PURE__ */ React.createElement(StatusRunning, null);
|
|
253
|
+
case "completed":
|
|
254
|
+
switch (conclusion == null ? void 0 : conclusion.toLocaleLowerCase("en-US")) {
|
|
255
|
+
case "skipped":
|
|
256
|
+
case "cancelled":
|
|
257
|
+
return /* @__PURE__ */ React.createElement(StatusAborted, null);
|
|
258
|
+
case "timed_out":
|
|
259
|
+
return /* @__PURE__ */ React.createElement(StatusWarning, null);
|
|
260
|
+
case "failure":
|
|
261
|
+
return /* @__PURE__ */ React.createElement(StatusError, null);
|
|
262
|
+
default:
|
|
263
|
+
return /* @__PURE__ */ React.createElement(StatusOK, null);
|
|
264
|
+
}
|
|
265
|
+
default:
|
|
266
|
+
return /* @__PURE__ */ React.createElement(StatusPending, null);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
function getStatusDescription({
|
|
270
|
+
status,
|
|
271
|
+
conclusion
|
|
272
|
+
}) {
|
|
273
|
+
if (status === void 0)
|
|
274
|
+
return "";
|
|
275
|
+
switch (status.toLocaleLowerCase("en-US")) {
|
|
276
|
+
case "queued":
|
|
277
|
+
return "Queued";
|
|
278
|
+
case "in_progress":
|
|
279
|
+
return "In progress";
|
|
280
|
+
case "completed":
|
|
281
|
+
switch (conclusion == null ? void 0 : conclusion.toLocaleLowerCase("en-US")) {
|
|
282
|
+
case "skipped":
|
|
283
|
+
case "cancelled":
|
|
284
|
+
return "Aborted";
|
|
285
|
+
case "timed_out":
|
|
286
|
+
return "Timed out";
|
|
287
|
+
case "failure":
|
|
288
|
+
return "Error";
|
|
289
|
+
default:
|
|
290
|
+
return "Completed";
|
|
291
|
+
}
|
|
292
|
+
default:
|
|
293
|
+
return "Pending";
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const useWorkflowRunJobs = ({
|
|
298
|
+
hostname,
|
|
299
|
+
owner,
|
|
300
|
+
repo
|
|
301
|
+
}) => {
|
|
302
|
+
const api = useApi(githubActionsApiRef);
|
|
303
|
+
const { id } = useRouteRefParams(buildRouteRef);
|
|
304
|
+
return useAsync(async () => {
|
|
305
|
+
if (!repo || !owner) {
|
|
306
|
+
throw new Error("No repo/owner provided");
|
|
307
|
+
}
|
|
308
|
+
const jobs = await api.listJobsForWorkflowRun({
|
|
309
|
+
hostname,
|
|
310
|
+
owner,
|
|
311
|
+
repo,
|
|
312
|
+
id: parseInt(id, 10)
|
|
313
|
+
});
|
|
314
|
+
return {
|
|
315
|
+
total_count: jobs.total_count,
|
|
316
|
+
jobs: jobs.jobs.map((job) => {
|
|
317
|
+
var _a, _b, _c, _d;
|
|
318
|
+
return {
|
|
319
|
+
html_url: (_a = job.html_url) != null ? _a : void 0,
|
|
320
|
+
status: job.status,
|
|
321
|
+
conclusion: (_b = job.conclusion) != null ? _b : void 0,
|
|
322
|
+
started_at: job.started_at,
|
|
323
|
+
completed_at: (_c = job.completed_at) != null ? _c : void 0,
|
|
324
|
+
id: job.id,
|
|
325
|
+
name: job.name,
|
|
326
|
+
steps: (_d = job.steps) == null ? void 0 : _d.map((step) => {
|
|
327
|
+
var _a2, _b2, _c2;
|
|
328
|
+
return {
|
|
329
|
+
name: step.name,
|
|
330
|
+
status: step.status,
|
|
331
|
+
conclusion: (_a2 = step.conclusion) != null ? _a2 : void 0,
|
|
332
|
+
number: step.number,
|
|
333
|
+
started_at: (_b2 = step.started_at) != null ? _b2 : void 0,
|
|
334
|
+
completed_at: (_c2 = step.completed_at) != null ? _c2 : void 0
|
|
335
|
+
};
|
|
336
|
+
})
|
|
337
|
+
};
|
|
338
|
+
})
|
|
339
|
+
};
|
|
340
|
+
}, [repo, owner, id]);
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
const useWorkflowRunsDetails = ({
|
|
344
|
+
hostname,
|
|
345
|
+
owner,
|
|
346
|
+
repo
|
|
347
|
+
}) => {
|
|
348
|
+
const api = useApi(githubActionsApiRef);
|
|
349
|
+
const { id } = useRouteRefParams(buildRouteRef);
|
|
350
|
+
const details = useAsync(async () => {
|
|
351
|
+
return repo && owner ? api.getWorkflowRun({
|
|
352
|
+
hostname,
|
|
353
|
+
owner,
|
|
354
|
+
repo,
|
|
355
|
+
id: parseInt(id, 10)
|
|
356
|
+
}) : Promise.reject(new Error("No repo/owner provided"));
|
|
357
|
+
}, [repo, owner, id]);
|
|
358
|
+
return details;
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
const useDownloadWorkflowRunLogs = ({
|
|
362
|
+
hostname,
|
|
363
|
+
owner,
|
|
364
|
+
repo,
|
|
365
|
+
id
|
|
366
|
+
}) => {
|
|
367
|
+
const api = useApi(githubActionsApiRef);
|
|
368
|
+
const details = useAsync(async () => {
|
|
369
|
+
return repo && owner ? api.downloadJobLogsForWorkflowRun({
|
|
370
|
+
hostname,
|
|
371
|
+
owner,
|
|
372
|
+
repo,
|
|
373
|
+
runId: id
|
|
374
|
+
}) : Promise.reject("No repo/owner provided");
|
|
375
|
+
}, [repo, owner, id]);
|
|
376
|
+
return details;
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const getHostnameFromEntity = (entity) => {
|
|
380
|
+
var _a, _b, _c;
|
|
381
|
+
const location = (_c = (_a = entity == null ? void 0 : entity.metadata.annotations) == null ? void 0 : _a[ANNOTATION_SOURCE_LOCATION]) != null ? _c : (_b = entity == null ? void 0 : entity.metadata.annotations) == null ? void 0 : _b[ANNOTATION_LOCATION];
|
|
382
|
+
return (location == null ? void 0 : location.startsWith("url:")) ? gitUrlParse(location.slice(4)).resource : void 0;
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
const useStyles$3 = makeStyles((theme) => ({
|
|
386
|
+
button: {
|
|
387
|
+
order: -1,
|
|
388
|
+
marginRight: 0,
|
|
389
|
+
marginLeft: "-20px"
|
|
390
|
+
},
|
|
391
|
+
modal: {
|
|
392
|
+
display: "flex",
|
|
393
|
+
alignItems: "center",
|
|
394
|
+
width: "85%",
|
|
395
|
+
height: "85%",
|
|
396
|
+
justifyContent: "center",
|
|
397
|
+
margin: "auto"
|
|
398
|
+
},
|
|
399
|
+
normalLogContainer: {
|
|
400
|
+
height: "75vh",
|
|
401
|
+
width: "100%"
|
|
402
|
+
},
|
|
403
|
+
modalLogContainer: {
|
|
404
|
+
height: "100%",
|
|
405
|
+
width: "100%"
|
|
406
|
+
},
|
|
407
|
+
log: {
|
|
408
|
+
background: theme.palette.background.default
|
|
409
|
+
}
|
|
410
|
+
}));
|
|
411
|
+
const WorkflowRunLogs = ({
|
|
412
|
+
entity,
|
|
413
|
+
runId,
|
|
414
|
+
inProgress
|
|
415
|
+
}) => {
|
|
416
|
+
const classes = useStyles$3();
|
|
417
|
+
const projectName = getProjectNameFromEntity(entity);
|
|
418
|
+
const hostname = getHostnameFromEntity(entity);
|
|
419
|
+
const [owner, repo] = projectName && projectName.split("/") || [];
|
|
420
|
+
const jobLogs = useDownloadWorkflowRunLogs({
|
|
421
|
+
hostname,
|
|
422
|
+
owner,
|
|
423
|
+
repo,
|
|
424
|
+
id: runId
|
|
425
|
+
});
|
|
426
|
+
const logText = jobLogs.value ? String(jobLogs.value) : void 0;
|
|
427
|
+
const [open, setOpen] = React.useState(false);
|
|
428
|
+
const handleOpen = () => {
|
|
429
|
+
setOpen(true);
|
|
430
|
+
};
|
|
431
|
+
const handleClose = () => {
|
|
432
|
+
setOpen(false);
|
|
433
|
+
};
|
|
434
|
+
return /* @__PURE__ */ React.createElement(Accordion, { TransitionProps: { unmountOnExit: true }, disabled: inProgress }, /* @__PURE__ */ React.createElement(
|
|
435
|
+
AccordionSummary,
|
|
436
|
+
{
|
|
437
|
+
expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null),
|
|
438
|
+
IconButtonProps: {
|
|
439
|
+
className: classes.button
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
/* @__PURE__ */ React.createElement(Typography, { variant: "button" }, jobLogs.loading ? /* @__PURE__ */ React.createElement(CircularProgress, null) : "Job Log"),
|
|
443
|
+
/* @__PURE__ */ React.createElement(Tooltip, { title: "Open Log", TransitionComponent: Zoom, arrow: true }, /* @__PURE__ */ React.createElement(
|
|
444
|
+
DescriptionIcon,
|
|
445
|
+
{
|
|
446
|
+
onClick: (event) => {
|
|
447
|
+
event.stopPropagation();
|
|
448
|
+
handleOpen();
|
|
449
|
+
},
|
|
450
|
+
style: { marginLeft: "auto" }
|
|
451
|
+
}
|
|
452
|
+
)),
|
|
453
|
+
/* @__PURE__ */ React.createElement(
|
|
454
|
+
Modal,
|
|
455
|
+
{
|
|
456
|
+
className: classes.modal,
|
|
457
|
+
onClick: (event) => event.stopPropagation(),
|
|
458
|
+
open,
|
|
459
|
+
onClose: handleClose
|
|
460
|
+
},
|
|
461
|
+
/* @__PURE__ */ React.createElement(Fade, { in: open }, /* @__PURE__ */ React.createElement("div", { className: classes.modalLogContainer }, /* @__PURE__ */ React.createElement(
|
|
462
|
+
LogViewer,
|
|
463
|
+
{
|
|
464
|
+
text: logText != null ? logText : "No Values Found",
|
|
465
|
+
classes: { root: classes.log }
|
|
466
|
+
}
|
|
467
|
+
)))
|
|
468
|
+
)
|
|
469
|
+
), logText && /* @__PURE__ */ React.createElement("div", { className: classes.normalLogContainer }, /* @__PURE__ */ React.createElement(LogViewer, { text: logText, classes: { root: classes.log } })));
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
const useStyles$2 = makeStyles((theme) => ({
|
|
473
|
+
root: {
|
|
474
|
+
maxWidth: 720,
|
|
475
|
+
margin: theme.spacing(2)
|
|
476
|
+
},
|
|
477
|
+
title: {
|
|
478
|
+
padding: theme.spacing(1, 0, 2, 0)
|
|
479
|
+
},
|
|
480
|
+
table: {
|
|
481
|
+
padding: theme.spacing(1)
|
|
482
|
+
},
|
|
483
|
+
accordionDetails: {
|
|
484
|
+
padding: 0
|
|
485
|
+
},
|
|
486
|
+
button: {
|
|
487
|
+
order: -1,
|
|
488
|
+
marginRight: 0,
|
|
489
|
+
marginLeft: "-20px"
|
|
490
|
+
},
|
|
491
|
+
externalLinkIcon: {
|
|
492
|
+
fontSize: "inherit",
|
|
493
|
+
verticalAlign: "bottom"
|
|
494
|
+
}
|
|
495
|
+
}));
|
|
496
|
+
const getElapsedTime = (start, end) => {
|
|
497
|
+
if (!start || !end) {
|
|
498
|
+
return "";
|
|
499
|
+
}
|
|
500
|
+
const startDate = DateTime.fromISO(start);
|
|
501
|
+
const endDate = end ? DateTime.fromISO(end) : DateTime.now();
|
|
502
|
+
const diff = endDate.diff(startDate);
|
|
503
|
+
const timeElapsed = diff.toFormat(`m 'minutes' s 'seconds'`);
|
|
504
|
+
return timeElapsed;
|
|
505
|
+
};
|
|
506
|
+
const StepView = ({ step }) => {
|
|
507
|
+
var _a;
|
|
508
|
+
return /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement(
|
|
509
|
+
ListItemText,
|
|
510
|
+
{
|
|
511
|
+
primary: step.name,
|
|
512
|
+
secondary: getElapsedTime(step.started_at, step.completed_at)
|
|
513
|
+
}
|
|
514
|
+
)), /* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement(
|
|
515
|
+
WorkflowRunStatus,
|
|
516
|
+
{
|
|
517
|
+
status: step.status.toLocaleUpperCase("en-US"),
|
|
518
|
+
conclusion: (_a = step.conclusion) == null ? void 0 : _a.toLocaleUpperCase("en-US")
|
|
519
|
+
}
|
|
520
|
+
)));
|
|
521
|
+
};
|
|
522
|
+
const JobListItem = ({
|
|
523
|
+
job,
|
|
524
|
+
className,
|
|
525
|
+
entity
|
|
526
|
+
}) => {
|
|
527
|
+
var _a;
|
|
528
|
+
const classes = useStyles$2();
|
|
529
|
+
return /* @__PURE__ */ React.createElement(Accordion, { TransitionProps: { unmountOnExit: true }, className }, /* @__PURE__ */ React.createElement(
|
|
530
|
+
AccordionSummary,
|
|
531
|
+
{
|
|
532
|
+
expandIcon: /* @__PURE__ */ React.createElement(ExpandMoreIcon, null),
|
|
533
|
+
IconButtonProps: {
|
|
534
|
+
className: classes.button
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
/* @__PURE__ */ React.createElement(Typography, { variant: "button" }, job.name, " (", getElapsedTime(job.started_at, job.completed_at), ")")
|
|
538
|
+
), /* @__PURE__ */ React.createElement(AccordionDetails, { className: classes.accordionDetails }, /* @__PURE__ */ React.createElement(TableContainer, null, /* @__PURE__ */ React.createElement(Table, null, (_a = job.steps) == null ? void 0 : _a.map((step) => /* @__PURE__ */ React.createElement(StepView, { key: step.number, step }))))), job.status === "queued" || job.status === "in_progress" ? /* @__PURE__ */ React.createElement(WorkflowRunLogs, { runId: job.id, inProgress: true, entity }) : /* @__PURE__ */ React.createElement(WorkflowRunLogs, { runId: job.id, inProgress: false, entity }));
|
|
539
|
+
};
|
|
540
|
+
const JobsList = ({ jobs, entity }) => {
|
|
541
|
+
const classes = useStyles$2();
|
|
542
|
+
return /* @__PURE__ */ React.createElement(Box, null, jobs && jobs.total_count > 0 && jobs.jobs.map((job) => /* @__PURE__ */ React.createElement(
|
|
543
|
+
JobListItem,
|
|
544
|
+
{
|
|
545
|
+
key: job.id,
|
|
546
|
+
job,
|
|
547
|
+
className: job.status !== "success" ? classes.failed : classes.success,
|
|
548
|
+
entity
|
|
549
|
+
}
|
|
550
|
+
)));
|
|
551
|
+
};
|
|
552
|
+
const WorkflowRunDetails = ({ entity }) => {
|
|
553
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
554
|
+
const projectName = getProjectNameFromEntity(entity);
|
|
555
|
+
const hostname = getHostnameFromEntity(entity);
|
|
556
|
+
const [owner, repo] = projectName && projectName.split("/") || [];
|
|
557
|
+
const details = useWorkflowRunsDetails({ hostname, owner, repo });
|
|
558
|
+
const jobs = useWorkflowRunJobs({ hostname, owner, repo });
|
|
559
|
+
const classes = useStyles$2();
|
|
560
|
+
if (details.error && details.error.message) {
|
|
561
|
+
return /* @__PURE__ */ React.createElement(Typography, { variant: "h6", color: "error" }, "Failed to load build, ", details.error.message);
|
|
562
|
+
} else if (details.loading) {
|
|
563
|
+
return /* @__PURE__ */ React.createElement(LinearProgress, null);
|
|
564
|
+
}
|
|
565
|
+
return /* @__PURE__ */ React.createElement("div", { className: classes.root }, /* @__PURE__ */ React.createElement(Box, { mb: 3 }, /* @__PURE__ */ React.createElement(Breadcrumbs, { "aria-label": "breadcrumb" }, /* @__PURE__ */ React.createElement(Link, { to: ".." }, "Workflow runs"), /* @__PURE__ */ React.createElement(Typography, null, "Workflow run details"))), /* @__PURE__ */ React.createElement(TableContainer, { component: Paper, className: classes.table }, /* @__PURE__ */ React.createElement(Table, null, /* @__PURE__ */ React.createElement(TableBody, null, /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement(Typography, { noWrap: true }, "Branch")), /* @__PURE__ */ React.createElement(TableCell, null, (_a = details.value) == null ? void 0 : _a.head_branch)), /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement(Typography, { noWrap: true }, "Message")), /* @__PURE__ */ React.createElement(TableCell, null, (_c = (_b = details.value) == null ? void 0 : _b.head_commit) == null ? void 0 : _c.message)), /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement(Typography, { noWrap: true }, "Commit ID")), /* @__PURE__ */ React.createElement(TableCell, null, (_e = (_d = details.value) == null ? void 0 : _d.head_commit) == null ? void 0 : _e.id)), /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement(Typography, { noWrap: true }, "Workflow")), /* @__PURE__ */ React.createElement(TableCell, null, (_f = details.value) == null ? void 0 : _f.name)), /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement(Typography, { noWrap: true }, "Status")), /* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement(
|
|
566
|
+
WorkflowRunStatus,
|
|
567
|
+
{
|
|
568
|
+
status: ((_g = details.value) == null ? void 0 : _g.status) || void 0,
|
|
569
|
+
conclusion: ((_h = details.value) == null ? void 0 : _h.conclusion) || void 0
|
|
570
|
+
}
|
|
571
|
+
))), /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement(Typography, { noWrap: true }, "Author")), /* @__PURE__ */ React.createElement(TableCell, null, `${(_k = (_j = (_i = details.value) == null ? void 0 : _i.head_commit) == null ? void 0 : _j.author) == null ? void 0 : _k.name} (${(_n = (_m = (_l = details.value) == null ? void 0 : _l.head_commit) == null ? void 0 : _m.author) == null ? void 0 : _n.email})`)), /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement(Typography, { noWrap: true }, "Links")), /* @__PURE__ */ React.createElement(TableCell, null, ((_o = details.value) == null ? void 0 : _o.html_url) && /* @__PURE__ */ React.createElement(Link, { to: details.value.html_url }, "Workflow runs on GitHub", " ", /* @__PURE__ */ React.createElement(ExternalLinkIcon, { className: classes.externalLinkIcon })))), /* @__PURE__ */ React.createElement(TableRow, null, /* @__PURE__ */ React.createElement(TableCell, { colSpan: 2 }, /* @__PURE__ */ React.createElement(Typography, { noWrap: true }, "Jobs"), jobs.loading ? /* @__PURE__ */ React.createElement(CircularProgress, null) : /* @__PURE__ */ React.createElement(JobsList, { jobs: jobs.value, entity })))))));
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
function useWorkflowRuns({
|
|
575
|
+
hostname,
|
|
576
|
+
owner,
|
|
577
|
+
repo,
|
|
578
|
+
branch,
|
|
579
|
+
initialPageSize = 6
|
|
580
|
+
}) {
|
|
581
|
+
const api = useApi(githubActionsApiRef);
|
|
582
|
+
const errorApi = useApi(errorApiRef);
|
|
583
|
+
const [total, setTotal] = useState(0);
|
|
584
|
+
const [page, setPage] = useState(0);
|
|
585
|
+
const [pageSize, setPageSize] = useState(initialPageSize);
|
|
586
|
+
const [branches, setBranches] = useState([]);
|
|
587
|
+
const [defaultBranch, setDefaultBranch] = useState("");
|
|
588
|
+
const {
|
|
589
|
+
loading,
|
|
590
|
+
value: runs,
|
|
591
|
+
retry,
|
|
592
|
+
error
|
|
593
|
+
} = useAsyncRetry(async () => {
|
|
594
|
+
const fetchedDefaultBranch = await api.getDefaultBranch({
|
|
595
|
+
hostname,
|
|
596
|
+
owner,
|
|
597
|
+
repo
|
|
598
|
+
});
|
|
599
|
+
setDefaultBranch(fetchedDefaultBranch);
|
|
600
|
+
let selectedBranch = branch;
|
|
601
|
+
if (branch === "default") {
|
|
602
|
+
selectedBranch = fetchedDefaultBranch;
|
|
603
|
+
}
|
|
604
|
+
const fetchBranches = async () => {
|
|
605
|
+
let next = true;
|
|
606
|
+
let iteratePage = 0;
|
|
607
|
+
const branchSet2 = [];
|
|
608
|
+
while (next) {
|
|
609
|
+
const branchesData = await api.listBranches({
|
|
610
|
+
hostname,
|
|
611
|
+
owner,
|
|
612
|
+
repo,
|
|
613
|
+
page: iteratePage
|
|
614
|
+
});
|
|
615
|
+
if (branchesData.length === 0) {
|
|
616
|
+
next = false;
|
|
617
|
+
}
|
|
618
|
+
iteratePage++;
|
|
619
|
+
branchSet2.push(...branchesData);
|
|
620
|
+
}
|
|
621
|
+
return branchSet2;
|
|
622
|
+
};
|
|
623
|
+
const branchSet = await fetchBranches();
|
|
624
|
+
setBranches(branchSet);
|
|
625
|
+
const workflowRunsData = await api.listWorkflowRuns({
|
|
626
|
+
hostname,
|
|
627
|
+
owner,
|
|
628
|
+
repo,
|
|
629
|
+
pageSize,
|
|
630
|
+
page: page + 1,
|
|
631
|
+
branch: selectedBranch
|
|
632
|
+
});
|
|
633
|
+
setTotal(workflowRunsData.total_count);
|
|
634
|
+
return workflowRunsData.workflow_runs.map((run) => {
|
|
635
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
636
|
+
return {
|
|
637
|
+
workflowName: (_a = run.name) != null ? _a : void 0,
|
|
638
|
+
message: (_b = run.head_commit) == null ? void 0 : _b.message,
|
|
639
|
+
id: `${run.id}`,
|
|
640
|
+
onReRunClick: async () => {
|
|
641
|
+
try {
|
|
642
|
+
await api.reRunWorkflow({
|
|
643
|
+
hostname,
|
|
644
|
+
owner,
|
|
645
|
+
repo,
|
|
646
|
+
runId: run.id
|
|
647
|
+
});
|
|
648
|
+
} catch (e) {
|
|
649
|
+
errorApi.post(
|
|
650
|
+
new Error(`Failed to rerun the workflow: ${e.message}`)
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
source: {
|
|
655
|
+
branchName: (_c = run.head_branch) != null ? _c : void 0,
|
|
656
|
+
commit: {
|
|
657
|
+
hash: (_d = run.head_commit) == null ? void 0 : _d.id,
|
|
658
|
+
url: (_g = (_e = run.head_repository) == null ? void 0 : _e.branches_url) == null ? void 0 : _g.replace(
|
|
659
|
+
"{/branch}",
|
|
660
|
+
(_f = run.head_branch) != null ? _f : ""
|
|
661
|
+
)
|
|
662
|
+
}
|
|
663
|
+
},
|
|
664
|
+
status: (_h = run.status) != null ? _h : void 0,
|
|
665
|
+
conclusion: (_i = run.conclusion) != null ? _i : void 0,
|
|
666
|
+
url: run.url,
|
|
667
|
+
githubUrl: run.html_url
|
|
668
|
+
};
|
|
669
|
+
});
|
|
670
|
+
}, [page, pageSize, repo, owner]);
|
|
671
|
+
return [
|
|
672
|
+
{
|
|
673
|
+
page,
|
|
674
|
+
pageSize,
|
|
675
|
+
loading,
|
|
676
|
+
runs,
|
|
677
|
+
branches,
|
|
678
|
+
defaultBranch,
|
|
679
|
+
projectName: `${owner}/${repo}`,
|
|
680
|
+
total,
|
|
681
|
+
error
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
runs,
|
|
685
|
+
setPage,
|
|
686
|
+
setPageSize,
|
|
687
|
+
retry
|
|
688
|
+
}
|
|
689
|
+
];
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
const useStyles$1 = makeStyles(
|
|
693
|
+
(theme) => createStyles({
|
|
694
|
+
card: {
|
|
695
|
+
border: `1px solid ${theme.palette.divider}`,
|
|
696
|
+
boxShadow: theme.shadows[2],
|
|
697
|
+
borderRadius: "4px",
|
|
698
|
+
overflow: "visible",
|
|
699
|
+
position: "relative",
|
|
700
|
+
margin: theme.spacing(4, 1, 1),
|
|
701
|
+
flex: "1",
|
|
702
|
+
minWidth: "0px"
|
|
703
|
+
},
|
|
704
|
+
externalLinkIcon: {
|
|
705
|
+
fontSize: "inherit",
|
|
706
|
+
verticalAlign: "middle"
|
|
707
|
+
},
|
|
708
|
+
bottomline: {
|
|
709
|
+
display: "flex",
|
|
710
|
+
justifyContent: "space-between",
|
|
711
|
+
alignItems: "center",
|
|
712
|
+
marginTop: "-5px"
|
|
713
|
+
},
|
|
714
|
+
pagination: {
|
|
715
|
+
width: "100%"
|
|
716
|
+
}
|
|
717
|
+
})
|
|
718
|
+
);
|
|
719
|
+
const statusColors = {
|
|
720
|
+
skipped: "warning",
|
|
721
|
+
canceled: "info",
|
|
722
|
+
timed_out: "error",
|
|
723
|
+
failure: "error",
|
|
724
|
+
success: "success"
|
|
725
|
+
};
|
|
726
|
+
const matchesSearchTerm = (run, searchTerm) => {
|
|
727
|
+
var _a, _b, _c, _d;
|
|
728
|
+
const lowerCaseSearchTerm = searchTerm.toLocaleLowerCase();
|
|
729
|
+
return ((_a = run.workflowName) == null ? void 0 : _a.toLocaleLowerCase().includes(lowerCaseSearchTerm)) || ((_b = run.source.branchName) == null ? void 0 : _b.toLocaleLowerCase().includes(lowerCaseSearchTerm)) || ((_c = run.status) == null ? void 0 : _c.toLocaleLowerCase().includes(lowerCaseSearchTerm)) || ((_d = run.id) == null ? void 0 : _d.toLocaleLowerCase().includes(lowerCaseSearchTerm));
|
|
730
|
+
};
|
|
731
|
+
const WorkflowRunsCardView = ({
|
|
732
|
+
runs,
|
|
733
|
+
searchTerm,
|
|
734
|
+
loading,
|
|
735
|
+
onChangePageSize,
|
|
736
|
+
onChangePage,
|
|
737
|
+
page,
|
|
738
|
+
total,
|
|
739
|
+
pageSize
|
|
740
|
+
}) => {
|
|
741
|
+
const classes = useStyles$1();
|
|
742
|
+
const routeLink = useRouteRef(buildRouteRef);
|
|
743
|
+
const filteredRuns = runs == null ? void 0 : runs.filter((run) => matchesSearchTerm(run, searchTerm));
|
|
744
|
+
return /* @__PURE__ */ React.createElement(Grid, { container: true, spacing: 3 }, filteredRuns && (runs == null ? void 0 : runs.length) !== 0 ? filteredRuns.map((run) => {
|
|
745
|
+
var _a, _b;
|
|
746
|
+
return /* @__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(
|
|
747
|
+
Box,
|
|
748
|
+
{
|
|
749
|
+
display: "flex",
|
|
750
|
+
flexDirection: "column",
|
|
751
|
+
m: 3,
|
|
752
|
+
alignItems: "center",
|
|
753
|
+
justifyContent: "center"
|
|
754
|
+
},
|
|
755
|
+
/* @__PURE__ */ React.createElement(Box, { pt: 2, sx: { width: "100%" }, textAlign: "center" }, /* @__PURE__ */ React.createElement(
|
|
756
|
+
Tooltip,
|
|
757
|
+
{
|
|
758
|
+
title: (_a = run.status) != null ? _a : "No Status",
|
|
759
|
+
placement: "top-start"
|
|
760
|
+
},
|
|
761
|
+
/* @__PURE__ */ React.createElement(
|
|
762
|
+
Alert,
|
|
763
|
+
{
|
|
764
|
+
variant: "outlined",
|
|
765
|
+
severity: statusColors[run.conclusion],
|
|
766
|
+
style: { alignItems: "center" }
|
|
767
|
+
},
|
|
768
|
+
/* @__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)))
|
|
769
|
+
)
|
|
770
|
+
), /* @__PURE__ */ React.createElement(Tooltip, { title: (_b = run.message) != null ? _b : "No run message" }, /* @__PURE__ */ React.createElement(
|
|
771
|
+
Typography,
|
|
772
|
+
{
|
|
773
|
+
variant: "body2",
|
|
774
|
+
component: "span",
|
|
775
|
+
style: { fontSize: "smaller" }
|
|
776
|
+
},
|
|
777
|
+
/* @__PURE__ */ React.createElement(
|
|
778
|
+
MarkdownContent,
|
|
779
|
+
{
|
|
780
|
+
content: `Commit ID : ${run.source.commit.hash}`
|
|
781
|
+
}
|
|
782
|
+
)
|
|
783
|
+
)), run.source.branchName && /* @__PURE__ */ React.createElement(
|
|
784
|
+
MarkdownContent,
|
|
785
|
+
{
|
|
786
|
+
content: `Branch : ${run.source.branchName}`
|
|
787
|
+
}
|
|
788
|
+
), /* @__PURE__ */ React.createElement(
|
|
789
|
+
Chip,
|
|
790
|
+
{
|
|
791
|
+
key: run.id,
|
|
792
|
+
size: "small",
|
|
793
|
+
label: `Workflow ID : ${run.id}`
|
|
794
|
+
}
|
|
795
|
+
), /* @__PURE__ */ React.createElement(
|
|
796
|
+
Chip,
|
|
797
|
+
{
|
|
798
|
+
size: "small",
|
|
799
|
+
label: /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(
|
|
800
|
+
WorkflowRunStatus,
|
|
801
|
+
{
|
|
802
|
+
status: run.status,
|
|
803
|
+
conclusion: run.conclusion
|
|
804
|
+
}
|
|
805
|
+
))
|
|
806
|
+
}
|
|
807
|
+
), /* @__PURE__ */ React.createElement("div", { className: classes.bottomline }, run.githubUrl && /* @__PURE__ */ React.createElement(Link, { to: run.githubUrl }, "Workflow runs on GitHub", " ", /* @__PURE__ */ React.createElement(
|
|
808
|
+
ExternalLinkIcon,
|
|
809
|
+
{
|
|
810
|
+
className: classes.externalLinkIcon
|
|
811
|
+
}
|
|
812
|
+
)), /* @__PURE__ */ React.createElement(ButtonGroup, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Rerun workflow" }, /* @__PURE__ */ React.createElement(
|
|
813
|
+
IconButton,
|
|
814
|
+
{
|
|
815
|
+
onClick: run.onReRunClick,
|
|
816
|
+
style: { fontSize: "12px" }
|
|
817
|
+
},
|
|
818
|
+
/* @__PURE__ */ React.createElement(RetryIcon, null)
|
|
819
|
+
)))))
|
|
820
|
+
)));
|
|
821
|
+
}) : /* @__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(
|
|
822
|
+
TablePagination,
|
|
823
|
+
{
|
|
824
|
+
component: "div",
|
|
825
|
+
count: total,
|
|
826
|
+
page,
|
|
827
|
+
rowsPerPage: pageSize,
|
|
828
|
+
onPageChange: (_, newPage) => onChangePage(newPage),
|
|
829
|
+
onRowsPerPageChange: (event) => onChangePageSize(parseInt(event.target.value, 6)),
|
|
830
|
+
labelRowsPerPage: "Workflows per page",
|
|
831
|
+
rowsPerPageOptions: [6, 12, 18, { label: "All", value: -1 }]
|
|
832
|
+
}
|
|
833
|
+
)));
|
|
834
|
+
};
|
|
835
|
+
const WorkflowRunsCardSearch = ({
|
|
836
|
+
searchTerm,
|
|
837
|
+
handleSearch,
|
|
838
|
+
retry
|
|
839
|
+
}) => {
|
|
840
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Box, { flexGrow: 1 }), /* @__PURE__ */ React.createElement(
|
|
841
|
+
TextField,
|
|
842
|
+
{
|
|
843
|
+
type: "search",
|
|
844
|
+
label: "Search",
|
|
845
|
+
value: searchTerm,
|
|
846
|
+
onChange: handleSearch,
|
|
847
|
+
"data-testid": "search-control",
|
|
848
|
+
style: { marginRight: "20px" }
|
|
849
|
+
}
|
|
850
|
+
), /* @__PURE__ */ React.createElement(ButtonGroup, null, /* @__PURE__ */ React.createElement(Tooltip, { title: "Reload workflow runs" }, /* @__PURE__ */ React.createElement(IconButton, { onClick: retry }, /* @__PURE__ */ React.createElement(SyncIcon, null)))));
|
|
851
|
+
};
|
|
852
|
+
const WorkflowRunsCard = ({ entity }) => {
|
|
853
|
+
const projectName = getProjectNameFromEntity(entity);
|
|
854
|
+
const hostname = getHostnameFromEntity(entity);
|
|
855
|
+
const [owner, repo] = (projectName != null ? projectName : "/").split("/");
|
|
856
|
+
const [branch, setBranch] = useState("default");
|
|
857
|
+
const [runs, setRuns] = useState([]);
|
|
858
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
859
|
+
const handleSearch = (event) => {
|
|
860
|
+
setSearchTerm(event.target.value);
|
|
861
|
+
};
|
|
862
|
+
const [
|
|
863
|
+
{ runs: runsData, branches, defaultBranch, ...cardProps },
|
|
864
|
+
{ retry, setPage, setPageSize }
|
|
865
|
+
] = useWorkflowRuns({
|
|
866
|
+
hostname,
|
|
867
|
+
owner,
|
|
868
|
+
repo,
|
|
869
|
+
branch: branch === "all" ? void 0 : branch
|
|
870
|
+
});
|
|
871
|
+
const githubHost = hostname || "github.com";
|
|
872
|
+
const hasNoRuns = !cardProps.loading && !runsData;
|
|
873
|
+
const handleMenuChange = (event) => {
|
|
874
|
+
const selectedValue = event.target.value;
|
|
875
|
+
setBranch(selectedValue);
|
|
876
|
+
setPage(0);
|
|
877
|
+
retry();
|
|
878
|
+
};
|
|
879
|
+
useEffect(() => {
|
|
880
|
+
setRuns(runsData);
|
|
881
|
+
}, [runsData, branch]);
|
|
882
|
+
useEffect(() => {
|
|
883
|
+
setBranch(defaultBranch);
|
|
884
|
+
}, [defaultBranch]);
|
|
885
|
+
return /* @__PURE__ */ React.createElement(Grid, { item: true }, hasNoRuns ? /* @__PURE__ */ React.createElement(
|
|
886
|
+
EmptyState,
|
|
887
|
+
{
|
|
888
|
+
missing: "data",
|
|
889
|
+
title: "No Workflow Data",
|
|
890
|
+
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.",
|
|
891
|
+
action: /* @__PURE__ */ React.createElement(
|
|
892
|
+
Button,
|
|
893
|
+
{
|
|
894
|
+
variant: "contained",
|
|
895
|
+
color: "primary",
|
|
896
|
+
href: `https://${githubHost}/${projectName}/actions/new`
|
|
897
|
+
},
|
|
898
|
+
"Create new Workflow"
|
|
899
|
+
)
|
|
900
|
+
}
|
|
901
|
+
) : /* @__PURE__ */ React.createElement(
|
|
902
|
+
InfoCard,
|
|
903
|
+
{
|
|
904
|
+
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(
|
|
905
|
+
Select,
|
|
906
|
+
{
|
|
907
|
+
value: branch,
|
|
908
|
+
key: branch,
|
|
909
|
+
label: "Branch",
|
|
910
|
+
onChange: handleMenuChange,
|
|
911
|
+
"data-testid": "menu-control",
|
|
912
|
+
style: {
|
|
913
|
+
marginLeft: "30px",
|
|
914
|
+
marginRight: "20px",
|
|
915
|
+
width: "230px"
|
|
916
|
+
}
|
|
917
|
+
},
|
|
918
|
+
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(
|
|
919
|
+
Typography,
|
|
920
|
+
{
|
|
921
|
+
variant: "body2",
|
|
922
|
+
component: "span",
|
|
923
|
+
style: { color: "lightgray", fontSize: "x-small" }
|
|
924
|
+
},
|
|
925
|
+
"(default)"
|
|
926
|
+
)) : branchItem.name)),
|
|
927
|
+
/* @__PURE__ */ React.createElement(
|
|
928
|
+
MenuItem,
|
|
929
|
+
{
|
|
930
|
+
value: "all",
|
|
931
|
+
key: "all",
|
|
932
|
+
style: { color: "lightGrey", fontSize: "small" }
|
|
933
|
+
},
|
|
934
|
+
"select all branches"
|
|
935
|
+
)
|
|
936
|
+
), /* @__PURE__ */ React.createElement(
|
|
937
|
+
WorkflowRunsCardSearch,
|
|
938
|
+
{
|
|
939
|
+
searchTerm,
|
|
940
|
+
handleSearch,
|
|
941
|
+
retry
|
|
942
|
+
}
|
|
943
|
+
))
|
|
944
|
+
},
|
|
945
|
+
/* @__PURE__ */ React.createElement(
|
|
946
|
+
WorkflowRunsCardView,
|
|
947
|
+
{
|
|
948
|
+
runs,
|
|
949
|
+
loading: cardProps.loading,
|
|
950
|
+
onChangePageSize: setPageSize,
|
|
951
|
+
onChangePage: setPage,
|
|
952
|
+
page: cardProps.page,
|
|
953
|
+
total: cardProps.total,
|
|
954
|
+
pageSize: cardProps.pageSize,
|
|
955
|
+
searchTerm,
|
|
956
|
+
projectName
|
|
957
|
+
}
|
|
958
|
+
)
|
|
959
|
+
));
|
|
960
|
+
};
|
|
961
|
+
|
|
962
|
+
const generatedColumns = [
|
|
963
|
+
{
|
|
964
|
+
title: "ID",
|
|
965
|
+
field: "id",
|
|
966
|
+
type: "numeric",
|
|
967
|
+
width: "150px"
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
title: "Message",
|
|
971
|
+
field: "message",
|
|
972
|
+
highlight: true,
|
|
973
|
+
render: (row) => {
|
|
974
|
+
const LinkWrapper = () => {
|
|
975
|
+
const routeLink = useRouteRef(buildRouteRef);
|
|
976
|
+
return /* @__PURE__ */ React.createElement(Link, { component: Link$1, to: routeLink({ id: row.id }) }, row.message);
|
|
977
|
+
};
|
|
978
|
+
return /* @__PURE__ */ React.createElement(LinkWrapper, null);
|
|
979
|
+
}
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
title: "Source",
|
|
983
|
+
render: (row) => {
|
|
984
|
+
var _a, _b;
|
|
985
|
+
return /* @__PURE__ */ React.createElement(Typography, { variant: "body2", noWrap: true }, /* @__PURE__ */ React.createElement(Typography, { paragraph: true, variant: "body2" }, (_a = row.source) == null ? void 0 : _a.branchName), /* @__PURE__ */ React.createElement(Typography, { paragraph: true, variant: "body2" }, (_b = row.source) == null ? void 0 : _b.commit.hash));
|
|
986
|
+
}
|
|
987
|
+
},
|
|
988
|
+
{
|
|
989
|
+
title: "Workflow",
|
|
990
|
+
field: "workflowName"
|
|
991
|
+
},
|
|
992
|
+
{
|
|
993
|
+
title: "Status",
|
|
994
|
+
customSort: (d1, d2) => {
|
|
995
|
+
return getStatusDescription(d1).localeCompare(getStatusDescription(d2));
|
|
996
|
+
},
|
|
997
|
+
render: (row) => /* @__PURE__ */ React.createElement(Box, { display: "flex", alignItems: "center" }, /* @__PURE__ */ React.createElement(WorkflowRunStatus, { status: row.status, conclusion: row.conclusion }))
|
|
998
|
+
},
|
|
999
|
+
{
|
|
1000
|
+
title: "Actions",
|
|
1001
|
+
render: (row) => /* @__PURE__ */ React.createElement(Tooltip, { title: "Rerun workflow" }, /* @__PURE__ */ React.createElement(IconButton, { onClick: row.onReRunClick }, /* @__PURE__ */ React.createElement(RetryIcon, null))),
|
|
1002
|
+
width: "10%"
|
|
1003
|
+
}
|
|
1004
|
+
];
|
|
1005
|
+
const WorkflowRunsTableView = ({
|
|
1006
|
+
projectName,
|
|
1007
|
+
loading,
|
|
1008
|
+
pageSize,
|
|
1009
|
+
page,
|
|
1010
|
+
retry,
|
|
1011
|
+
runs,
|
|
1012
|
+
onChangePage,
|
|
1013
|
+
onChangePageSize,
|
|
1014
|
+
total
|
|
1015
|
+
}) => {
|
|
1016
|
+
return /* @__PURE__ */ React.createElement(
|
|
1017
|
+
Table$1,
|
|
1018
|
+
{
|
|
1019
|
+
isLoading: loading,
|
|
1020
|
+
options: { paging: true, pageSize, padding: "dense" },
|
|
1021
|
+
totalCount: total,
|
|
1022
|
+
page,
|
|
1023
|
+
actions: [
|
|
1024
|
+
{
|
|
1025
|
+
icon: () => /* @__PURE__ */ React.createElement(SyncIcon, null),
|
|
1026
|
+
tooltip: "Reload workflow runs",
|
|
1027
|
+
isFreeAction: true,
|
|
1028
|
+
onClick: () => retry()
|
|
1029
|
+
}
|
|
1030
|
+
],
|
|
1031
|
+
data: runs != null ? runs : [],
|
|
1032
|
+
onPageChange: onChangePage,
|
|
1033
|
+
onRowsPerPageChange: onChangePageSize,
|
|
1034
|
+
style: { width: "100%" },
|
|
1035
|
+
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)),
|
|
1036
|
+
columns: generatedColumns
|
|
1037
|
+
}
|
|
1038
|
+
);
|
|
1039
|
+
};
|
|
1040
|
+
const WorkflowRunsTable = ({
|
|
1041
|
+
entity,
|
|
1042
|
+
branch
|
|
1043
|
+
}) => {
|
|
1044
|
+
const projectName = getProjectNameFromEntity(entity);
|
|
1045
|
+
const hostname = getHostnameFromEntity(entity);
|
|
1046
|
+
const [owner, repo] = (projectName != null ? projectName : "/").split("/");
|
|
1047
|
+
const [{ runs, ...tableProps }, { retry, setPage, setPageSize }] = useWorkflowRuns({
|
|
1048
|
+
hostname,
|
|
1049
|
+
owner,
|
|
1050
|
+
repo,
|
|
1051
|
+
branch
|
|
1052
|
+
});
|
|
1053
|
+
const githubHost = hostname || "github.com";
|
|
1054
|
+
const hasNoRuns = !tableProps.loading && !runs;
|
|
1055
|
+
return hasNoRuns ? /* @__PURE__ */ React.createElement(
|
|
1056
|
+
EmptyState,
|
|
1057
|
+
{
|
|
1058
|
+
missing: "data",
|
|
1059
|
+
title: "No Workflow Data",
|
|
1060
|
+
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.",
|
|
1061
|
+
action: /* @__PURE__ */ React.createElement(
|
|
1062
|
+
Button,
|
|
1063
|
+
{
|
|
1064
|
+
variant: "contained",
|
|
1065
|
+
color: "primary",
|
|
1066
|
+
href: `https://${githubHost}/${projectName}/actions/new`
|
|
1067
|
+
},
|
|
1068
|
+
"Create new Workflow"
|
|
1069
|
+
)
|
|
1070
|
+
}
|
|
1071
|
+
) : /* @__PURE__ */ React.createElement(
|
|
1072
|
+
WorkflowRunsTableView,
|
|
1073
|
+
{
|
|
1074
|
+
...tableProps,
|
|
1075
|
+
runs,
|
|
1076
|
+
loading: tableProps.loading,
|
|
1077
|
+
retry,
|
|
1078
|
+
onChangePageSize: setPageSize,
|
|
1079
|
+
onChangePage: setPage
|
|
1080
|
+
}
|
|
1081
|
+
);
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
const isGithubActionsAvailable = (entity) => {
|
|
1085
|
+
var _a;
|
|
1086
|
+
return Boolean((_a = entity.metadata.annotations) == null ? void 0 : _a[GITHUB_ACTIONS_ANNOTATION]);
|
|
1087
|
+
};
|
|
1088
|
+
const Router = (props) => {
|
|
1089
|
+
const { view = "table" } = props;
|
|
1090
|
+
const { entity } = useEntity();
|
|
1091
|
+
if (!isGithubActionsAvailable(entity)) {
|
|
1092
|
+
return /* @__PURE__ */ React.createElement(MissingAnnotationEmptyState, { annotation: GITHUB_ACTIONS_ANNOTATION });
|
|
1093
|
+
}
|
|
1094
|
+
const workflowRunsComponent = view === "cards" ? /* @__PURE__ */ React.createElement(WorkflowRunsCard, { entity }) : /* @__PURE__ */ React.createElement(WorkflowRunsTable, { entity });
|
|
1095
|
+
return /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, { path: "/", element: workflowRunsComponent }), /* @__PURE__ */ React.createElement(
|
|
1096
|
+
Route,
|
|
1097
|
+
{
|
|
1098
|
+
path: `${buildRouteRef.path}`,
|
|
1099
|
+
element: /* @__PURE__ */ React.createElement(WorkflowRunDetails, { entity })
|
|
1100
|
+
}
|
|
1101
|
+
));
|
|
1102
|
+
};
|
|
1103
|
+
|
|
1104
|
+
var Router$1 = /*#__PURE__*/Object.freeze({
|
|
1105
|
+
__proto__: null,
|
|
1106
|
+
Router: Router,
|
|
1107
|
+
isGithubActionsAvailable: isGithubActionsAvailable
|
|
1108
|
+
});
|
|
1109
|
+
|
|
1110
|
+
const useStyles = makeStyles({
|
|
1111
|
+
externalLinkIcon: {
|
|
1112
|
+
fontSize: "inherit",
|
|
1113
|
+
verticalAlign: "bottom"
|
|
1114
|
+
}
|
|
1115
|
+
});
|
|
1116
|
+
const WidgetContent = (props) => {
|
|
1117
|
+
var _a;
|
|
1118
|
+
const { error, loading, lastRun, branch } = props;
|
|
1119
|
+
const classes = useStyles();
|
|
1120
|
+
if (error)
|
|
1121
|
+
return /* @__PURE__ */ React.createElement(Typography, null, "Couldn't fetch latest ", branch, " run");
|
|
1122
|
+
if (loading)
|
|
1123
|
+
return /* @__PURE__ */ React.createElement(LinearProgress, null);
|
|
1124
|
+
return /* @__PURE__ */ React.createElement(
|
|
1125
|
+
StructuredMetadataTable,
|
|
1126
|
+
{
|
|
1127
|
+
metadata: {
|
|
1128
|
+
status: /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1129
|
+
WorkflowRunStatus,
|
|
1130
|
+
{
|
|
1131
|
+
status: lastRun.status,
|
|
1132
|
+
conclusion: lastRun.conclusion
|
|
1133
|
+
}
|
|
1134
|
+
)),
|
|
1135
|
+
message: lastRun.message,
|
|
1136
|
+
url: /* @__PURE__ */ React.createElement(Link, { to: (_a = lastRun.githubUrl) != null ? _a : "" }, "See more on GitHub", " ", /* @__PURE__ */ React.createElement(ExternalLinkIcon, { className: classes.externalLinkIcon }))
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
);
|
|
1140
|
+
};
|
|
1141
|
+
const LatestWorkflowRunCard = (props) => {
|
|
1142
|
+
var _a, _b, _c;
|
|
1143
|
+
const { branch = "master", variant } = props;
|
|
1144
|
+
const { entity } = useEntity();
|
|
1145
|
+
const errorApi = useApi(errorApiRef);
|
|
1146
|
+
const hostname = getHostnameFromEntity(entity);
|
|
1147
|
+
const [owner, repo] = ((_b = (_a = entity == null ? void 0 : entity.metadata.annotations) == null ? void 0 : _a[GITHUB_ACTIONS_ANNOTATION]) != null ? _b : "/").split("/");
|
|
1148
|
+
const [{ runs, loading, error }] = useWorkflowRuns({
|
|
1149
|
+
hostname,
|
|
1150
|
+
owner,
|
|
1151
|
+
repo,
|
|
1152
|
+
branch
|
|
1153
|
+
});
|
|
1154
|
+
const lastRun = (_c = runs == null ? void 0 : runs[0]) != null ? _c : {};
|
|
1155
|
+
useEffect(() => {
|
|
1156
|
+
if (error) {
|
|
1157
|
+
errorApi.post(error);
|
|
1158
|
+
}
|
|
1159
|
+
}, [error, errorApi]);
|
|
1160
|
+
return /* @__PURE__ */ React.createElement(InfoCard, { title: `Last ${branch} build`, variant }, /* @__PURE__ */ React.createElement(
|
|
1161
|
+
WidgetContent,
|
|
1162
|
+
{
|
|
1163
|
+
error,
|
|
1164
|
+
loading,
|
|
1165
|
+
branch,
|
|
1166
|
+
lastRun
|
|
1167
|
+
}
|
|
1168
|
+
));
|
|
1169
|
+
};
|
|
1170
|
+
const LatestWorkflowsForBranchCard = (props) => {
|
|
1171
|
+
const { branch = "master", variant } = props;
|
|
1172
|
+
const { entity } = useEntity();
|
|
1173
|
+
return /* @__PURE__ */ React.createElement(InfoCard, { title: `Last ${branch} build`, variant }, /* @__PURE__ */ React.createElement(WorkflowRunsTable, { branch, entity }));
|
|
1174
|
+
};
|
|
1175
|
+
|
|
1176
|
+
const firstLine = (message) => message.split("\n")[0];
|
|
1177
|
+
const RecentWorkflowRunsCard = (props) => {
|
|
1178
|
+
var _a, _b;
|
|
1179
|
+
const { branch, dense = false, limit = 5, variant } = props;
|
|
1180
|
+
const { entity } = useEntity();
|
|
1181
|
+
const errorApi = useApi(errorApiRef);
|
|
1182
|
+
const hostname = getHostnameFromEntity(entity);
|
|
1183
|
+
const [owner, repo] = ((_b = (_a = entity == null ? void 0 : entity.metadata.annotations) == null ? void 0 : _a[GITHUB_ACTIONS_ANNOTATION]) != null ? _b : "/").split("/");
|
|
1184
|
+
const [{ runs = [], loading, error }] = useWorkflowRuns({
|
|
1185
|
+
hostname,
|
|
1186
|
+
owner,
|
|
1187
|
+
repo,
|
|
1188
|
+
branch,
|
|
1189
|
+
initialPageSize: limit
|
|
1190
|
+
});
|
|
1191
|
+
useEffect(() => {
|
|
1192
|
+
if (error) {
|
|
1193
|
+
errorApi.post(error);
|
|
1194
|
+
}
|
|
1195
|
+
}, [error, errorApi]);
|
|
1196
|
+
const githubHost = hostname || "github.com";
|
|
1197
|
+
const routeLink = useRouteRef(buildRouteRef);
|
|
1198
|
+
if (error) {
|
|
1199
|
+
return /* @__PURE__ */ React.createElement(ErrorPanel, { title: error.message, error });
|
|
1200
|
+
}
|
|
1201
|
+
return /* @__PURE__ */ React.createElement(
|
|
1202
|
+
InfoCard,
|
|
1203
|
+
{
|
|
1204
|
+
title: "Recent Workflow Runs",
|
|
1205
|
+
subheader: branch ? `Branch: ${branch}` : "All Branches",
|
|
1206
|
+
noPadding: true,
|
|
1207
|
+
variant
|
|
1208
|
+
},
|
|
1209
|
+
!runs.length ? /* @__PURE__ */ React.createElement("div", { style: { textAlign: "center" } }, /* @__PURE__ */ React.createElement(Typography, { variant: "body1" }, "This component has GitHub Actions enabled, but no workflows were found."), /* @__PURE__ */ React.createElement(Typography, { variant: "body2" }, /* @__PURE__ */ React.createElement(Link, { to: `https://${githubHost}/${owner}/${repo}/actions/new` }, "Create a new workflow"))) : /* @__PURE__ */ React.createElement(
|
|
1210
|
+
Table$1,
|
|
1211
|
+
{
|
|
1212
|
+
isLoading: loading,
|
|
1213
|
+
options: {
|
|
1214
|
+
search: false,
|
|
1215
|
+
paging: false,
|
|
1216
|
+
padding: dense ? "dense" : "default",
|
|
1217
|
+
toolbar: false
|
|
1218
|
+
},
|
|
1219
|
+
columns: [
|
|
1220
|
+
{
|
|
1221
|
+
title: "Commit Message",
|
|
1222
|
+
field: "message",
|
|
1223
|
+
render: (data) => {
|
|
1224
|
+
var _a2;
|
|
1225
|
+
return /* @__PURE__ */ React.createElement(Link, { component: Link$1, to: routeLink({ id: data.id }) }, firstLine((_a2 = data.message) != null ? _a2 : ""));
|
|
1226
|
+
}
|
|
1227
|
+
},
|
|
1228
|
+
{ title: "Branch", field: "source.branchName" },
|
|
1229
|
+
{ title: "Status", field: "status", render: WorkflowRunStatus }
|
|
1230
|
+
],
|
|
1231
|
+
data: runs
|
|
1232
|
+
}
|
|
1233
|
+
)
|
|
1234
|
+
);
|
|
1235
|
+
};
|
|
1236
|
+
|
|
1237
|
+
export { BuildStatus, EntityGithubActionsContent, EntityLatestGithubActionRunCard, EntityLatestGithubActionsForBranchCard, EntityRecentGithubActionsRunsCard, GITHUB_ACTIONS_ANNOTATION, GithubActionsClient, LatestWorkflowRunCard, LatestWorkflowsForBranchCard, RecentWorkflowRunsCard, Router, githubActionsApiRef, githubActionsPlugin, isGithubActionsAvailable, isGithubActionsAvailable as isPluginApplicableToEntity, githubActionsPlugin as plugin };
|
|
1238
|
+
//# sourceMappingURL=index.esm.js.map
|