@backstage-community/plugin-tekton 3.16.0
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 +801 -0
- package/README.md +369 -0
- package/app-config.dynamic.yaml +12 -0
- package/dist/components/Charts/PipelineBars.esm.js +49 -0
- package/dist/components/Charts/PipelineBars.esm.js.map +1 -0
- package/dist/components/Icons/CriticalRiskIcon.esm.js +22 -0
- package/dist/components/Icons/CriticalRiskIcon.esm.js.map +1 -0
- package/dist/components/Icons/EqualsIcon.esm.js +22 -0
- package/dist/components/Icons/EqualsIcon.esm.js.map +1 -0
- package/dist/components/Icons/LinkToSbomIcon.esm.js +37 -0
- package/dist/components/Icons/LinkToSbomIcon.esm.js.map +1 -0
- package/dist/components/Icons/OutputIcon.esm.js +36 -0
- package/dist/components/Icons/OutputIcon.esm.js.map +1 -0
- package/dist/components/Icons/SignedBadge.esm.js +16 -0
- package/dist/components/Icons/SignedBadge.esm.js.map +1 -0
- package/dist/components/Icons/ViewLogsIcon.esm.js +35 -0
- package/dist/components/Icons/ViewLogsIcon.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunColumnHeader.esm.js +43 -0
- package/dist/components/PipelineRunList/PipelineRunColumnHeader.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunList.esm.js +185 -0
- package/dist/components/PipelineRunList/PipelineRunList.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunListSearchBar.esm.js +42 -0
- package/dist/components/PipelineRunList/PipelineRunListSearchBar.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunOutput.esm.js +70 -0
- package/dist/components/PipelineRunList/PipelineRunOutput.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunRow.css.esm.js +7 -0
- package/dist/components/PipelineRunList/PipelineRunRow.css.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunRow.esm.js +110 -0
- package/dist/components/PipelineRunList/PipelineRunRow.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunRowActions.esm.js +137 -0
- package/dist/components/PipelineRunList/PipelineRunRowActions.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunSBOMLink.esm.js +25 -0
- package/dist/components/PipelineRunList/PipelineRunSBOMLink.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunTableBody.esm.js +32 -0
- package/dist/components/PipelineRunList/PipelineRunTableBody.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunTaskStatus.esm.js +11 -0
- package/dist/components/PipelineRunList/PipelineRunTaskStatus.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineRunVulnerabilities.esm.js +81 -0
- package/dist/components/PipelineRunList/PipelineRunVulnerabilities.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PipelineTableHeader.esm.js +53 -0
- package/dist/components/PipelineRunList/PipelineTableHeader.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PlrStatus.css.esm.js +7 -0
- package/dist/components/PipelineRunList/PlrStatus.css.esm.js.map +1 -0
- package/dist/components/PipelineRunList/PlrStatus.esm.js +11 -0
- package/dist/components/PipelineRunList/PlrStatus.esm.js.map +1 -0
- package/dist/components/PipelineRunList/ResourceBadge.css.esm.js +7 -0
- package/dist/components/PipelineRunList/ResourceBadge.css.esm.js.map +1 -0
- package/dist/components/PipelineRunList/ResourceBadge.esm.js +15 -0
- package/dist/components/PipelineRunList/ResourceBadge.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogDialog.esm.js +82 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogDialog.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogDownloader.esm.js +47 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogDownloader.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogViewer.esm.js +53 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogViewer.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogs.esm.js +69 -0
- package/dist/components/PipelineRunLogs/PipelineRunLogs.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/PodLogsDownloadLink.esm.js +69 -0
- package/dist/components/PipelineRunLogs/PodLogsDownloadLink.esm.js.map +1 -0
- package/dist/components/PipelineRunLogs/TaskStatusStepper.esm.js +128 -0
- package/dist/components/PipelineRunLogs/TaskStatusStepper.esm.js.map +1 -0
- package/dist/components/PipelineRunOutput/PipelineRunOutputDialog.esm.js +62 -0
- package/dist/components/PipelineRunOutput/PipelineRunOutputDialog.esm.js.map +1 -0
- package/dist/components/Router.esm.js +16 -0
- package/dist/components/Router.esm.js.map +1 -0
- package/dist/components/Tekton/TektonCIComponent.esm.js +53 -0
- package/dist/components/Tekton/TektonCIComponent.esm.js.map +1 -0
- package/dist/components/common/ClusterSelector.css.esm.js +7 -0
- package/dist/components/common/ClusterSelector.css.esm.js.map +1 -0
- package/dist/components/common/ClusterSelector.esm.js +46 -0
- package/dist/components/common/ClusterSelector.esm.js.map +1 -0
- package/dist/components/common/ErrorPanel.esm.js +33 -0
- package/dist/components/common/ErrorPanel.esm.js.map +1 -0
- package/dist/components/common/PermissionAlert.esm.js +9 -0
- package/dist/components/common/PermissionAlert.esm.js.map +1 -0
- package/dist/components/common/ResourceStatus.css.esm.js +7 -0
- package/dist/components/common/ResourceStatus.css.esm.js.map +1 -0
- package/dist/components/common/StatusSelector.css.esm.js +7 -0
- package/dist/components/common/StatusSelector.css.esm.js.map +1 -0
- package/dist/components/common/StatusSelector.esm.js +48 -0
- package/dist/components/common/StatusSelector.esm.js.map +1 -0
- package/dist/components/common/TableExpandCollapse.esm.js +44 -0
- package/dist/components/common/TableExpandCollapse.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineLayout.esm.js +126 -0
- package/dist/components/pipeline-topology/PipelineLayout.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineRunVisualization.esm.js +13 -0
- package/dist/components/pipeline-topology/PipelineRunVisualization.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineTaskNode.css.esm.js +7 -0
- package/dist/components/pipeline-topology/PipelineTaskNode.css.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineTaskNode.esm.js +132 -0
- package/dist/components/pipeline-topology/PipelineTaskNode.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineVisualization.css.esm.js +7 -0
- package/dist/components/pipeline-topology/PipelineVisualization.css.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineVisualization.esm.js +24 -0
- package/dist/components/pipeline-topology/PipelineVisualization.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineVisualizationStepList.css.esm.js +7 -0
- package/dist/components/pipeline-topology/PipelineVisualizationStepList.css.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineVisualizationStepList.esm.js +39 -0
- package/dist/components/pipeline-topology/PipelineVisualizationStepList.esm.js.map +1 -0
- package/dist/components/pipeline-topology/PipelineVisualizationView.esm.js +41 -0
- package/dist/components/pipeline-topology/PipelineVisualizationView.esm.js.map +1 -0
- package/dist/components/pipeline-topology/TaskGroupEdge.esm.js +16 -0
- package/dist/components/pipeline-topology/TaskGroupEdge.esm.js.map +1 -0
- package/dist/components/pipeline-topology/dag.esm.js +119 -0
- package/dist/components/pipeline-topology/dag.esm.js.map +1 -0
- package/dist/components/pipeline-topology/pipelineComponentFactory.esm.js +60 -0
- package/dist/components/pipeline-topology/pipelineComponentFactory.esm.js.map +1 -0
- package/dist/consts/pipeline-topology-const.esm.js +66 -0
- package/dist/consts/pipeline-topology-const.esm.js.map +1 -0
- package/dist/consts/tekton-const.esm.js +7 -0
- package/dist/consts/tekton-const.esm.js.map +1 -0
- package/dist/hooks/TektonResourcesContext.esm.js +16 -0
- package/dist/hooks/TektonResourcesContext.esm.js.map +1 -0
- package/dist/hooks/useAllWatchResources.esm.js +35 -0
- package/dist/hooks/useAllWatchResources.esm.js.map +1 -0
- package/dist/hooks/useDarkTheme.esm.js +21 -0
- package/dist/hooks/useDarkTheme.esm.js.map +1 -0
- package/dist/hooks/usePipelineRunScanResults.esm.js +35 -0
- package/dist/hooks/usePipelineRunScanResults.esm.js.map +1 -0
- package/dist/hooks/usePodLogsOfPipelineRun.esm.js +67 -0
- package/dist/hooks/usePodLogsOfPipelineRun.esm.js.map +1 -0
- package/dist/hooks/useResourcesClusters.esm.js +24 -0
- package/dist/hooks/useResourcesClusters.esm.js.map +1 -0
- package/dist/hooks/useTektonObjectsResponse.esm.js +78 -0
- package/dist/hooks/useTektonObjectsResponse.esm.js.map +1 -0
- package/dist/hooks/useTektonViewPermission.esm.js +12 -0
- package/dist/hooks/useTektonViewPermission.esm.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.esm.js +3 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/models.esm.js +21 -0
- package/dist/models.esm.js.map +1 -0
- package/dist/plugin.esm.js +72 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/types/types.esm.js +15 -0
- package/dist/types/types.esm.js.map +1 -0
- package/dist/utils/isTektonCIAvailable.esm.js +7 -0
- package/dist/utils/isTektonCIAvailable.esm.js.map +1 -0
- package/dist/utils/log-downloader-utils.esm.js +33 -0
- package/dist/utils/log-downloader-utils.esm.js.map +1 -0
- package/dist/utils/pipeline-step-utils.esm.js +53 -0
- package/dist/utils/pipeline-step-utils.esm.js.map +1 -0
- package/dist/utils/pipeline-topology-utils.esm.js +250 -0
- package/dist/utils/pipeline-topology-utils.esm.js.map +1 -0
- package/dist/utils/pipelineRun-utils.esm.js +128 -0
- package/dist/utils/pipelineRun-utils.esm.js.map +1 -0
- package/dist/utils/taskRun-utils.esm.js +50 -0
- package/dist/utils/taskRun-utils.esm.js.map +1 -0
- package/dist/utils/tekton-utils.esm.js +191 -0
- package/dist/utils/tekton-utils.esm.js.map +1 -0
- package/package.json +114 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { RunStatus, getSpacerNodes, getEdgesFromNodes, ModelKind, WhenStatus } from '@patternfly/react-topology';
|
|
2
|
+
import { uniq, minBy } from 'lodash';
|
|
3
|
+
import { ComputedStatus } from '@janus-idp/shared-react';
|
|
4
|
+
import { DAG } from '../components/pipeline-topology/dag.esm.js';
|
|
5
|
+
import { NodeType, NODE_HEIGHT, NODE_WIDTH, DEFAULT_BADGE_WIDTH, NODE_PADDING, DEFAULT_NODE_ICON_WIDTH, DEFAULT_FINALLLY_GROUP_PADDING, DEFAULT_NODE_HEIGHT, PipelineLayout, DAGRE_BUILDER_SPACED_PROPS, DAGRE_VIEWER_SPACED_PROPS, DAGRE_VIEWER_PROPS, DAGRE_BUILDER_PROPS, REGEX_EXTRACT_DEPS } from '../consts/pipeline-topology-const.esm.js';
|
|
6
|
+
import { getPLRTaskRuns, appendPipelineRunStatus } from './pipelineRun-utils.esm.js';
|
|
7
|
+
|
|
8
|
+
const createGenericNode = (type, width, height) => (name, data) => ({
|
|
9
|
+
id: name,
|
|
10
|
+
label: data?.label || name,
|
|
11
|
+
runAfterTasks: data?.runAfterTasks || [],
|
|
12
|
+
...data && { data },
|
|
13
|
+
height: height ?? NODE_HEIGHT,
|
|
14
|
+
width: width ?? NODE_WIDTH,
|
|
15
|
+
type
|
|
16
|
+
});
|
|
17
|
+
const getMaxFinallyNode = (finallyTaskList) => {
|
|
18
|
+
const sortedFinallyTaskList = [...finallyTaskList].sort(
|
|
19
|
+
(a, b) => b.name.length - a.name.length
|
|
20
|
+
);
|
|
21
|
+
return sortedFinallyTaskList[0]?.name || "";
|
|
22
|
+
};
|
|
23
|
+
createGenericNode(NodeType.LOADING_NODE);
|
|
24
|
+
const createPipelineTaskNode = (type, data) => createGenericNode(type, data.width, data.height)(data.id ?? "", data);
|
|
25
|
+
const getTextWidth = (text, font = "0.8rem RedHatText") => {
|
|
26
|
+
if (!text || text.length === 0) {
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
const canvas = document.createElement("canvas");
|
|
30
|
+
const context = canvas.getContext("2d");
|
|
31
|
+
if (!context) {
|
|
32
|
+
return text.length;
|
|
33
|
+
}
|
|
34
|
+
context.font = font;
|
|
35
|
+
const { width } = context.measureText(text);
|
|
36
|
+
return width;
|
|
37
|
+
};
|
|
38
|
+
const extractDepsFromContextVariables = (contextVariable) => {
|
|
39
|
+
let matches;
|
|
40
|
+
const deps = [];
|
|
41
|
+
if (!contextVariable) {
|
|
42
|
+
return deps;
|
|
43
|
+
}
|
|
44
|
+
while ((matches = REGEX_EXTRACT_DEPS.exec(contextVariable)) !== null) {
|
|
45
|
+
if (matches.index === REGEX_EXTRACT_DEPS.lastIndex) {
|
|
46
|
+
REGEX_EXTRACT_DEPS.lastIndex++;
|
|
47
|
+
}
|
|
48
|
+
if (matches) {
|
|
49
|
+
if (!deps.includes(matches[1])) {
|
|
50
|
+
deps.push(matches[1]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return deps;
|
|
55
|
+
};
|
|
56
|
+
const getSpacerNode = (node) => ({
|
|
57
|
+
...node,
|
|
58
|
+
height: 1,
|
|
59
|
+
width: 1
|
|
60
|
+
});
|
|
61
|
+
const getWhenStatus = (status) => {
|
|
62
|
+
switch (status) {
|
|
63
|
+
case ComputedStatus.Succeeded:
|
|
64
|
+
case ComputedStatus.Failed:
|
|
65
|
+
return WhenStatus.Met;
|
|
66
|
+
case ComputedStatus.Skipped:
|
|
67
|
+
case ComputedStatus["In Progress"]:
|
|
68
|
+
case ComputedStatus.Idle:
|
|
69
|
+
return WhenStatus.Unmet;
|
|
70
|
+
default:
|
|
71
|
+
return void 0;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const getTaskWhenStatus = (task) => {
|
|
75
|
+
if (!task.when) {
|
|
76
|
+
return void 0;
|
|
77
|
+
}
|
|
78
|
+
return getWhenStatus(task.status?.reason);
|
|
79
|
+
};
|
|
80
|
+
const getDepsFromContextVariables = (task) => {
|
|
81
|
+
const depsFromContextVariables = [];
|
|
82
|
+
if (task.params) {
|
|
83
|
+
task.params.forEach((p) => {
|
|
84
|
+
if (Array.isArray(p.value)) {
|
|
85
|
+
p.value.forEach((paramValue) => {
|
|
86
|
+
depsFromContextVariables.push(
|
|
87
|
+
...extractDepsFromContextVariables(paramValue)
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
depsFromContextVariables.push(
|
|
92
|
+
...extractDepsFromContextVariables(p.value)
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
if (task?.when) {
|
|
98
|
+
task.when.forEach(({ input, values }) => {
|
|
99
|
+
depsFromContextVariables.push(...extractDepsFromContextVariables(input));
|
|
100
|
+
values.forEach((whenValue) => {
|
|
101
|
+
depsFromContextVariables.push(
|
|
102
|
+
...extractDepsFromContextVariables(whenValue)
|
|
103
|
+
);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return depsFromContextVariables;
|
|
108
|
+
};
|
|
109
|
+
const getRunAfterTasks = (task, dag, vertex) => {
|
|
110
|
+
const runAfterTasks = [];
|
|
111
|
+
const depsFromContextVariables = getDepsFromContextVariables(task);
|
|
112
|
+
const dependancies = uniq([...vertex.dependancyNames]);
|
|
113
|
+
if (dependancies) {
|
|
114
|
+
dependancies.forEach((dep) => {
|
|
115
|
+
const depObj = dag.vertices.get(dep);
|
|
116
|
+
if (depObj.level - vertex.level <= 1 || vertex.data.runAfter?.includes(depObj.name)) {
|
|
117
|
+
runAfterTasks.push(dep);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (depsFromContextVariables.length > 0) {
|
|
122
|
+
const v = depsFromContextVariables.map((d) => {
|
|
123
|
+
return dag.vertices.get(d);
|
|
124
|
+
});
|
|
125
|
+
const minLevelDep = minBy(v, (d) => d.level);
|
|
126
|
+
const nearestDeps = v.filter((v1) => v1.level === minLevelDep.level);
|
|
127
|
+
nearestDeps.forEach((nd) => {
|
|
128
|
+
if (nd.level - vertex.level <= 1 || vertex.dependancyNames.length === 0) {
|
|
129
|
+
runAfterTasks.push(nd.name);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return runAfterTasks;
|
|
134
|
+
};
|
|
135
|
+
const getGraphDataModel = (pipelineRun, taskRuns) => {
|
|
136
|
+
if (!pipelineRun) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
const plrTaskRuns = getPLRTaskRuns(taskRuns, pipelineRun?.metadata?.name);
|
|
140
|
+
const taskList = appendPipelineRunStatus(pipelineRun, plrTaskRuns);
|
|
141
|
+
const dag = new DAG();
|
|
142
|
+
taskList?.forEach((task) => {
|
|
143
|
+
dag.addEdges(task.name, task, "", task.runAfter || []);
|
|
144
|
+
});
|
|
145
|
+
const nodes = [];
|
|
146
|
+
const maxWidthForLevel = {};
|
|
147
|
+
dag.topologicalSort((v) => {
|
|
148
|
+
if (!maxWidthForLevel[v.level]) {
|
|
149
|
+
maxWidthForLevel[v.level] = getTextWidth(v.name);
|
|
150
|
+
} else {
|
|
151
|
+
maxWidthForLevel[v.level] = Math.max(
|
|
152
|
+
maxWidthForLevel[v.level],
|
|
153
|
+
getTextWidth(v.name)
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
dag.topologicalSort((vertex) => {
|
|
158
|
+
const task = vertex.data;
|
|
159
|
+
const runAfterTasks = getRunAfterTasks(task, dag, vertex);
|
|
160
|
+
const badgePadding = Object.keys(pipelineRun.spec)?.length > 0 ? DEFAULT_BADGE_WIDTH : 0;
|
|
161
|
+
const isTaskSkipped = pipelineRun?.status?.skippedTasks?.some(
|
|
162
|
+
(t) => t.name === task.name
|
|
163
|
+
);
|
|
164
|
+
nodes.push(
|
|
165
|
+
createPipelineTaskNode(NodeType.TASK_NODE, {
|
|
166
|
+
id: vertex.name,
|
|
167
|
+
label: vertex.name,
|
|
168
|
+
width: maxWidthForLevel[vertex.level] + NODE_PADDING * 2 + DEFAULT_NODE_ICON_WIDTH + badgePadding,
|
|
169
|
+
runAfterTasks,
|
|
170
|
+
status: isTaskSkipped ? RunStatus.Skipped : vertex.data.status?.reason,
|
|
171
|
+
whenStatus: getTaskWhenStatus(vertex.data),
|
|
172
|
+
task: vertex.data,
|
|
173
|
+
pipelineRun
|
|
174
|
+
})
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
const finallyTaskList = appendPipelineRunStatus(
|
|
178
|
+
pipelineRun,
|
|
179
|
+
plrTaskRuns,
|
|
180
|
+
true
|
|
181
|
+
);
|
|
182
|
+
const finallyNodes = finallyTaskList.map((fTask) => {
|
|
183
|
+
const isTaskSkipped = pipelineRun?.status?.skippedTasks?.some(
|
|
184
|
+
(t) => t.name === fTask.name
|
|
185
|
+
);
|
|
186
|
+
return createPipelineTaskNode(NodeType.FINALLY_NODE, {
|
|
187
|
+
id: fTask.name,
|
|
188
|
+
label: fTask.name,
|
|
189
|
+
width: getTextWidth(getMaxFinallyNode(finallyTaskList)) + NODE_PADDING * 2 + DEFAULT_FINALLLY_GROUP_PADDING * 2,
|
|
190
|
+
height: DEFAULT_NODE_HEIGHT,
|
|
191
|
+
runAfterTasks: [],
|
|
192
|
+
status: isTaskSkipped ? RunStatus.Skipped : fTask.status?.reason,
|
|
193
|
+
whenStatus: getTaskWhenStatus(fTask),
|
|
194
|
+
task: fTask,
|
|
195
|
+
pipelineRun
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
const finallyGroup = finallyNodes.length ? [
|
|
199
|
+
{
|
|
200
|
+
id: "finally-group-id",
|
|
201
|
+
type: NodeType.FINALLY_GROUP,
|
|
202
|
+
children: finallyNodes.map((n) => n.id),
|
|
203
|
+
group: true,
|
|
204
|
+
style: { padding: DEFAULT_FINALLLY_GROUP_PADDING }
|
|
205
|
+
}
|
|
206
|
+
] : [];
|
|
207
|
+
const spacerNodes = getSpacerNodes([...nodes, ...finallyNodes], NodeType.SPACER_NODE, [
|
|
208
|
+
NodeType.FINALLY_NODE
|
|
209
|
+
]).map(getSpacerNode);
|
|
210
|
+
const edges = getEdgesFromNodes(
|
|
211
|
+
[...nodes, ...spacerNodes, ...finallyNodes],
|
|
212
|
+
NodeType.SPACER_NODE,
|
|
213
|
+
NodeType.EDGE,
|
|
214
|
+
NodeType.EDGE,
|
|
215
|
+
[NodeType.FINALLY_NODE],
|
|
216
|
+
NodeType.EDGE
|
|
217
|
+
);
|
|
218
|
+
return {
|
|
219
|
+
graph: {
|
|
220
|
+
id: `${pipelineRun?.metadata?.name}-graph`,
|
|
221
|
+
type: ModelKind.graph,
|
|
222
|
+
layout: PipelineLayout.DAGRE_VIEWER,
|
|
223
|
+
scaleExtent: [0.5, 1]
|
|
224
|
+
},
|
|
225
|
+
nodes: [
|
|
226
|
+
...nodes,
|
|
227
|
+
...spacerNodes,
|
|
228
|
+
...finallyNodes,
|
|
229
|
+
...finallyGroup
|
|
230
|
+
],
|
|
231
|
+
edges
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
const getLayoutData = (layout) => {
|
|
235
|
+
switch (layout) {
|
|
236
|
+
case PipelineLayout.DAGRE_BUILDER:
|
|
237
|
+
return DAGRE_BUILDER_PROPS;
|
|
238
|
+
case PipelineLayout.DAGRE_VIEWER:
|
|
239
|
+
return DAGRE_VIEWER_PROPS;
|
|
240
|
+
case PipelineLayout.DAGRE_VIEWER_SPACED:
|
|
241
|
+
return DAGRE_VIEWER_SPACED_PROPS;
|
|
242
|
+
case PipelineLayout.DAGRE_BUILDER_SPACED:
|
|
243
|
+
return DAGRE_BUILDER_SPACED_PROPS;
|
|
244
|
+
default:
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
export { extractDepsFromContextVariables, getGraphDataModel, getLayoutData, getSpacerNode, getTaskWhenStatus, getTextWidth, getWhenStatus };
|
|
250
|
+
//# sourceMappingURL=pipeline-topology-utils.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-topology-utils.esm.js","sources":["../../src/utils/pipeline-topology-utils.ts"],"sourcesContent":["/*\n * Copyright 2024 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 {\n EdgeModel,\n getEdgesFromNodes,\n getSpacerNodes,\n GraphModel,\n ModelKind,\n RunStatus,\n WhenStatus,\n} from '@patternfly/react-topology';\nimport * as dagre from 'dagre';\nimport { minBy, uniq } from 'lodash';\n\nimport {\n ComputedStatus,\n PipelineRunKind,\n PipelineTask,\n PipelineTaskParam,\n PipelineTaskWithStatus,\n TaskRunKind,\n} from '@janus-idp/shared-react';\n\nimport { DAG, Vertex } from '../components/pipeline-topology/dag';\nimport {\n DAGRE_BUILDER_PROPS,\n DAGRE_BUILDER_SPACED_PROPS,\n DAGRE_VIEWER_PROPS,\n DAGRE_VIEWER_SPACED_PROPS,\n DEFAULT_BADGE_WIDTH,\n DEFAULT_FINALLLY_GROUP_PADDING,\n DEFAULT_NODE_HEIGHT,\n DEFAULT_NODE_ICON_WIDTH,\n FINALLY_NODE_PADDING,\n NODE_HEIGHT,\n NODE_PADDING,\n NODE_WIDTH,\n NodeType,\n PipelineLayout,\n REGEX_EXTRACT_DEPS,\n WHEN_EXPRESSION_SPACING,\n} from '../consts/pipeline-topology-const';\nimport {\n FinallyNodeModel,\n LoadingNodeModel,\n NodeCreator,\n NodeCreatorSetup,\n PipelineEdgeModel,\n PipelineMixedNodeModel,\n PipelineRunAfterNodeModelData,\n} from '../types/pipeline-topology-types';\nimport { appendPipelineRunStatus, getPLRTaskRuns } from './pipelineRun-utils';\n\nconst createGenericNode: NodeCreatorSetup =\n (type, width?, height?) => (name, data) => ({\n id: name,\n label: data?.label || name,\n runAfterTasks: data?.runAfterTasks || [],\n ...(data && { data }),\n height: height ?? NODE_HEIGHT,\n width: width ?? NODE_WIDTH,\n type,\n });\n\nconst getMaxFinallyNode = (finallyTaskList: PipelineTaskWithStatus[]) => {\n const sortedFinallyTaskList = [...finallyTaskList].sort(\n (a, b) => b.name.length - a.name.length,\n );\n return sortedFinallyTaskList[0]?.name || '';\n};\n\nexport const createFinallyNode = (\n height: number,\n): NodeCreator<FinallyNodeModel> =>\n createGenericNode(\n NodeType.FINALLY_NODE,\n NODE_WIDTH + WHEN_EXPRESSION_SPACING + FINALLY_NODE_PADDING * 2,\n height,\n );\n\nexport const createLoadingNode: NodeCreator<LoadingNodeModel> =\n createGenericNode(NodeType.LOADING_NODE);\n\nconst createPipelineTaskNode = (\n type: NodeType,\n data: PipelineRunAfterNodeModelData,\n) => createGenericNode(type, data.width, data.height)(data.id ?? '', data);\n\nexport const getTextWidth = (\n text: string,\n font: string = '0.8rem RedHatText',\n): number => {\n if (!text || text.length === 0) {\n return 0;\n }\n const canvas = document.createElement('canvas');\n const context = canvas.getContext('2d');\n if (!context) {\n return text.length;\n }\n context.font = font;\n const { width } = context.measureText(text);\n return width;\n};\n\nexport const extractDepsFromContextVariables = (\n contextVariable: string | null | undefined,\n) => {\n let matches;\n const deps: string[] = [];\n if (!contextVariable) {\n return deps;\n }\n // eslint-disable-next-line no-cond-assign\n while ((matches = REGEX_EXTRACT_DEPS.exec(contextVariable)) !== null) {\n // This is necessary to avoid infinite loops with zero-width matches\n if (matches.index === REGEX_EXTRACT_DEPS.lastIndex) {\n REGEX_EXTRACT_DEPS.lastIndex++;\n }\n if (matches) {\n if (!deps.includes(matches[1])) {\n deps.push(matches[1]);\n }\n }\n }\n return deps;\n};\n\nexport const getSpacerNode = (\n node: PipelineMixedNodeModel,\n): PipelineMixedNodeModel => ({\n ...node,\n height: 1,\n width: 1,\n});\n\nexport const getWhenStatus = (\n status: ComputedStatus,\n): WhenStatus | undefined => {\n switch (status) {\n case ComputedStatus.Succeeded:\n case ComputedStatus.Failed:\n return WhenStatus.Met;\n case ComputedStatus.Skipped:\n case ComputedStatus['In Progress']:\n case ComputedStatus.Idle:\n return WhenStatus.Unmet;\n default:\n return undefined;\n }\n};\n\nexport const getTaskWhenStatus = (\n task: PipelineTaskWithStatus,\n): WhenStatus | undefined => {\n if (!task.when) {\n return undefined;\n }\n return getWhenStatus(task.status?.reason as ComputedStatus);\n};\n\nconst getDepsFromContextVariables = (task: PipelineTask) => {\n const depsFromContextVariables: string[] = [];\n if (task.params) {\n task.params.forEach((p: PipelineTaskParam) => {\n if (Array.isArray(p.value)) {\n p.value.forEach(paramValue => {\n depsFromContextVariables.push(\n ...extractDepsFromContextVariables(paramValue),\n );\n });\n } else {\n depsFromContextVariables.push(\n ...extractDepsFromContextVariables(p.value),\n );\n }\n });\n }\n if (task?.when) {\n task.when.forEach(({ input, values }) => {\n depsFromContextVariables.push(...extractDepsFromContextVariables(input));\n values.forEach((whenValue: string) => {\n depsFromContextVariables.push(\n ...extractDepsFromContextVariables(whenValue),\n );\n });\n });\n }\n return depsFromContextVariables;\n};\n\nconst getRunAfterTasks = (task: PipelineTask, dag: DAG, vertex: Vertex) => {\n const runAfterTasks: string[] = [];\n const depsFromContextVariables = getDepsFromContextVariables(task);\n\n const dependancies = uniq([...vertex.dependancyNames]);\n if (dependancies) {\n dependancies.forEach(dep => {\n const depObj = dag.vertices.get(dep) as Vertex;\n if (\n depObj.level - vertex.level <= 1 ||\n vertex.data.runAfter?.includes(depObj.name)\n ) {\n runAfterTasks.push(dep);\n }\n });\n }\n if (depsFromContextVariables.length > 0) {\n const v = depsFromContextVariables.map(d => {\n return dag.vertices.get(d) as Vertex;\n });\n const minLevelDep = minBy(v, (d: Vertex) => d.level) as Vertex;\n const nearestDeps = v.filter(v1 => v1.level === minLevelDep.level);\n nearestDeps.forEach(nd => {\n if (nd.level - vertex.level <= 1 || vertex.dependancyNames.length === 0) {\n runAfterTasks.push(nd.name);\n }\n });\n }\n return runAfterTasks;\n};\n\nexport const getGraphDataModel = (\n pipelineRun: PipelineRunKind | undefined,\n taskRuns: TaskRunKind[],\n): {\n graph: GraphModel;\n nodes: PipelineMixedNodeModel[];\n edges: EdgeModel[];\n} | null => {\n if (!pipelineRun) {\n return null;\n }\n\n const plrTaskRuns = getPLRTaskRuns(taskRuns, pipelineRun?.metadata?.name);\n\n const taskList = appendPipelineRunStatus(pipelineRun, plrTaskRuns);\n\n const dag = new DAG();\n taskList?.forEach((task: PipelineTask) => {\n dag.addEdges(task.name, task, '', task.runAfter || []);\n });\n\n const nodes: PipelineMixedNodeModel[] = [];\n const maxWidthForLevel: { [key: string]: number } = {};\n dag.topologicalSort((v: Vertex) => {\n if (!maxWidthForLevel[v.level]) {\n maxWidthForLevel[v.level] = getTextWidth(v.name);\n } else {\n maxWidthForLevel[v.level] = Math.max(\n maxWidthForLevel[v.level],\n getTextWidth(v.name),\n );\n }\n });\n dag.topologicalSort((vertex: Vertex) => {\n const task = vertex.data as PipelineTask;\n const runAfterTasks = getRunAfterTasks(task, dag, vertex);\n const badgePadding =\n Object.keys(pipelineRun.spec)?.length > 0 ? DEFAULT_BADGE_WIDTH : 0;\n const isTaskSkipped = pipelineRun?.status?.skippedTasks?.some(\n t => t.name === task.name,\n );\n nodes.push(\n createPipelineTaskNode(NodeType.TASK_NODE, {\n id: vertex.name,\n label: vertex.name,\n width:\n maxWidthForLevel[vertex.level] +\n NODE_PADDING * 2 +\n DEFAULT_NODE_ICON_WIDTH +\n badgePadding,\n runAfterTasks,\n status: isTaskSkipped ? RunStatus.Skipped : vertex.data.status?.reason,\n whenStatus: getTaskWhenStatus(vertex.data),\n task: vertex.data,\n pipelineRun,\n }),\n );\n });\n\n const finallyTaskList = appendPipelineRunStatus(\n pipelineRun,\n plrTaskRuns,\n true,\n );\n\n const finallyNodes = finallyTaskList.map(fTask => {\n const isTaskSkipped = pipelineRun?.status?.skippedTasks?.some(\n t => t.name === fTask.name,\n );\n\n return createPipelineTaskNode(NodeType.FINALLY_NODE, {\n id: fTask.name,\n label: fTask.name,\n width:\n getTextWidth(getMaxFinallyNode(finallyTaskList)) +\n NODE_PADDING * 2 +\n DEFAULT_FINALLLY_GROUP_PADDING * 2,\n height: DEFAULT_NODE_HEIGHT,\n runAfterTasks: [],\n status: isTaskSkipped\n ? RunStatus.Skipped\n : (fTask.status?.reason as RunStatus),\n whenStatus: getTaskWhenStatus(fTask),\n task: fTask,\n pipelineRun,\n });\n });\n\n const finallyGroup = finallyNodes.length\n ? [\n {\n id: 'finally-group-id',\n type: NodeType.FINALLY_GROUP,\n children: finallyNodes.map(n => n.id),\n group: true,\n style: { padding: DEFAULT_FINALLLY_GROUP_PADDING },\n },\n ]\n : [];\n const spacerNodes: PipelineMixedNodeModel[] = (\n getSpacerNodes([...nodes, ...finallyNodes], NodeType.SPACER_NODE, [\n NodeType.FINALLY_NODE,\n ]) as PipelineMixedNodeModel[]\n ).map(getSpacerNode);\n\n const edges: PipelineEdgeModel[] = getEdgesFromNodes(\n [...nodes, ...spacerNodes, ...finallyNodes],\n NodeType.SPACER_NODE,\n NodeType.EDGE,\n NodeType.EDGE,\n [NodeType.FINALLY_NODE],\n NodeType.EDGE,\n );\n\n return {\n graph: {\n id: `${pipelineRun?.metadata?.name}-graph`,\n type: ModelKind.graph,\n layout: PipelineLayout.DAGRE_VIEWER,\n scaleExtent: [0.5, 1],\n },\n nodes: [\n ...nodes,\n ...spacerNodes,\n ...finallyNodes,\n ...finallyGroup,\n ] as PipelineMixedNodeModel[],\n edges,\n };\n};\n\nexport const getLayoutData = (\n layout: PipelineLayout,\n): dagre.GraphLabel | null => {\n switch (layout) {\n case PipelineLayout.DAGRE_BUILDER:\n return DAGRE_BUILDER_PROPS;\n case PipelineLayout.DAGRE_VIEWER:\n return DAGRE_VIEWER_PROPS;\n case PipelineLayout.DAGRE_VIEWER_SPACED:\n return DAGRE_VIEWER_SPACED_PROPS;\n case PipelineLayout.DAGRE_BUILDER_SPACED:\n return DAGRE_BUILDER_SPACED_PROPS;\n default:\n return null;\n }\n};\n"],"names":[],"mappings":";;;;;;;AAkEA,MAAM,oBACJ,CAAC,IAAA,EAAM,OAAQ,MAAY,KAAA,CAAC,MAAM,IAAU,MAAA;AAAA,EAC1C,EAAI,EAAA,IAAA;AAAA,EACJ,KAAA,EAAO,MAAM,KAAS,IAAA,IAAA;AAAA,EACtB,aAAA,EAAe,IAAM,EAAA,aAAA,IAAiB,EAAC;AAAA,EACvC,GAAI,IAAQ,IAAA,EAAE,IAAK,EAAA;AAAA,EACnB,QAAQ,MAAU,IAAA,WAAA;AAAA,EAClB,OAAO,KAAS,IAAA,UAAA;AAAA,EAChB;AACF,CAAA,CAAA;AAEF,MAAM,iBAAA,GAAoB,CAAC,eAA8C,KAAA;AACvE,EAAA,MAAM,qBAAwB,GAAA,CAAC,GAAG,eAAe,CAAE,CAAA,IAAA;AAAA,IACjD,CAAC,CAAG,EAAA,CAAA,KAAM,EAAE,IAAK,CAAA,MAAA,GAAS,EAAE,IAAK,CAAA;AAAA,GACnC;AACA,EAAO,OAAA,qBAAA,CAAsB,CAAC,CAAA,EAAG,IAAQ,IAAA,EAAA;AAC3C,CAAA;AAYE,iBAAkB,CAAA,QAAA,CAAS,YAAY;AAEzC,MAAM,sBAAyB,GAAA,CAC7B,IACA,EAAA,IAAA,KACG,kBAAkB,IAAM,EAAA,IAAA,CAAK,KAAO,EAAA,IAAA,CAAK,MAAM,CAAA,CAAE,IAAK,CAAA,EAAA,IAAM,IAAI,IAAI,CAAA;AAElE,MAAM,YAAe,GAAA,CAC1B,IACA,EAAA,IAAA,GAAe,mBACJ,KAAA;AACX,EAAA,IAAI,CAAC,IAAA,IAAQ,IAAK,CAAA,MAAA,KAAW,CAAG,EAAA;AAC9B,IAAO,OAAA,CAAA;AAAA;AAET,EAAM,MAAA,MAAA,GAAS,QAAS,CAAA,aAAA,CAAc,QAAQ,CAAA;AAC9C,EAAM,MAAA,OAAA,GAAU,MAAO,CAAA,UAAA,CAAW,IAAI,CAAA;AACtC,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAA,OAAO,IAAK,CAAA,MAAA;AAAA;AAEd,EAAA,OAAA,CAAQ,IAAO,GAAA,IAAA;AACf,EAAA,MAAM,EAAE,KAAA,EAAU,GAAA,OAAA,CAAQ,YAAY,IAAI,CAAA;AAC1C,EAAO,OAAA,KAAA;AACT;AAEa,MAAA,+BAAA,GAAkC,CAC7C,eACG,KAAA;AACH,EAAI,IAAA,OAAA;AACJ,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,IAAI,CAAC,eAAiB,EAAA;AACpB,IAAO,OAAA,IAAA;AAAA;AAGT,EAAA,OAAA,CAAQ,OAAU,GAAA,kBAAA,CAAmB,IAAK,CAAA,eAAe,OAAO,IAAM,EAAA;AAEpE,IAAI,IAAA,OAAA,CAAQ,KAAU,KAAA,kBAAA,CAAmB,SAAW,EAAA;AAClD,MAAmB,kBAAA,CAAA,SAAA,EAAA;AAAA;AAErB,IAAA,IAAI,OAAS,EAAA;AACX,MAAA,IAAI,CAAC,IAAK,CAAA,QAAA,CAAS,OAAQ,CAAA,CAAC,CAAC,CAAG,EAAA;AAC9B,QAAK,IAAA,CAAA,IAAA,CAAK,OAAQ,CAAA,CAAC,CAAC,CAAA;AAAA;AACtB;AACF;AAEF,EAAO,OAAA,IAAA;AACT;AAEa,MAAA,aAAA,GAAgB,CAC3B,IAC4B,MAAA;AAAA,EAC5B,GAAG,IAAA;AAAA,EACH,MAAQ,EAAA,CAAA;AAAA,EACR,KAAO,EAAA;AACT,CAAA;AAEa,MAAA,aAAA,GAAgB,CAC3B,MAC2B,KAAA;AAC3B,EAAA,QAAQ,MAAQ;AAAA,IACd,KAAK,cAAe,CAAA,SAAA;AAAA,IACpB,KAAK,cAAe,CAAA,MAAA;AAClB,MAAA,OAAO,UAAW,CAAA,GAAA;AAAA,IACpB,KAAK,cAAe,CAAA,OAAA;AAAA,IACpB,KAAK,eAAe,aAAa,CAAA;AAAA,IACjC,KAAK,cAAe,CAAA,IAAA;AAClB,MAAA,OAAO,UAAW,CAAA,KAAA;AAAA,IACpB;AACE,MAAO,OAAA,KAAA,CAAA;AAAA;AAEb;AAEa,MAAA,iBAAA,GAAoB,CAC/B,IAC2B,KAAA;AAC3B,EAAI,IAAA,CAAC,KAAK,IAAM,EAAA;AACd,IAAO,OAAA,KAAA,CAAA;AAAA;AAET,EAAO,OAAA,aAAA,CAAc,IAAK,CAAA,MAAA,EAAQ,MAAwB,CAAA;AAC5D;AAEA,MAAM,2BAAA,GAA8B,CAAC,IAAuB,KAAA;AAC1D,EAAA,MAAM,2BAAqC,EAAC;AAC5C,EAAA,IAAI,KAAK,MAAQ,EAAA;AACf,IAAK,IAAA,CAAA,MAAA,CAAO,OAAQ,CAAA,CAAC,CAAyB,KAAA;AAC5C,MAAA,IAAI,KAAM,CAAA,OAAA,CAAQ,CAAE,CAAA,KAAK,CAAG,EAAA;AAC1B,QAAE,CAAA,CAAA,KAAA,CAAM,QAAQ,CAAc,UAAA,KAAA;AAC5B,UAAyB,wBAAA,CAAA,IAAA;AAAA,YACvB,GAAG,gCAAgC,UAAU;AAAA,WAC/C;AAAA,SACD,CAAA;AAAA,OACI,MAAA;AACL,QAAyB,wBAAA,CAAA,IAAA;AAAA,UACvB,GAAG,+BAAgC,CAAA,CAAA,CAAE,KAAK;AAAA,SAC5C;AAAA;AACF,KACD,CAAA;AAAA;AAEH,EAAA,IAAI,MAAM,IAAM,EAAA;AACd,IAAA,IAAA,CAAK,KAAK,OAAQ,CAAA,CAAC,EAAE,KAAA,EAAO,QAAa,KAAA;AACvC,MAAA,wBAAA,CAAyB,IAAK,CAAA,GAAG,+BAAgC,CAAA,KAAK,CAAC,CAAA;AACvE,MAAO,MAAA,CAAA,OAAA,CAAQ,CAAC,SAAsB,KAAA;AACpC,QAAyB,wBAAA,CAAA,IAAA;AAAA,UACvB,GAAG,gCAAgC,SAAS;AAAA,SAC9C;AAAA,OACD,CAAA;AAAA,KACF,CAAA;AAAA;AAEH,EAAO,OAAA,wBAAA;AACT,CAAA;AAEA,MAAM,gBAAmB,GAAA,CAAC,IAAoB,EAAA,GAAA,EAAU,MAAmB,KAAA;AACzE,EAAA,MAAM,gBAA0B,EAAC;AACjC,EAAM,MAAA,wBAAA,GAA2B,4BAA4B,IAAI,CAAA;AAEjE,EAAA,MAAM,eAAe,IAAK,CAAA,CAAC,GAAG,MAAA,CAAO,eAAe,CAAC,CAAA;AACrD,EAAA,IAAI,YAAc,EAAA;AAChB,IAAA,YAAA,CAAa,QAAQ,CAAO,GAAA,KAAA;AAC1B,MAAA,MAAM,MAAS,GAAA,GAAA,CAAI,QAAS,CAAA,GAAA,CAAI,GAAG,CAAA;AACnC,MACE,IAAA,MAAA,CAAO,KAAQ,GAAA,MAAA,CAAO,KAAS,IAAA,CAAA,IAC/B,MAAO,CAAA,IAAA,CAAK,QAAU,EAAA,QAAA,CAAS,MAAO,CAAA,IAAI,CAC1C,EAAA;AACA,QAAA,aAAA,CAAc,KAAK,GAAG,CAAA;AAAA;AACxB,KACD,CAAA;AAAA;AAEH,EAAI,IAAA,wBAAA,CAAyB,SAAS,CAAG,EAAA;AACvC,IAAM,MAAA,CAAA,GAAI,wBAAyB,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA;AAC1C,MAAO,OAAA,GAAA,CAAI,QAAS,CAAA,GAAA,CAAI,CAAC,CAAA;AAAA,KAC1B,CAAA;AACD,IAAA,MAAM,cAAc,KAAM,CAAA,CAAA,EAAG,CAAC,CAAA,KAAc,EAAE,KAAK,CAAA;AACnD,IAAA,MAAM,cAAc,CAAE,CAAA,MAAA,CAAO,QAAM,EAAG,CAAA,KAAA,KAAU,YAAY,KAAK,CAAA;AACjE,IAAA,WAAA,CAAY,QAAQ,CAAM,EAAA,KAAA;AACxB,MAAI,IAAA,EAAA,CAAG,QAAQ,MAAO,CAAA,KAAA,IAAS,KAAK,MAAO,CAAA,eAAA,CAAgB,WAAW,CAAG,EAAA;AACvE,QAAc,aAAA,CAAA,IAAA,CAAK,GAAG,IAAI,CAAA;AAAA;AAC5B,KACD,CAAA;AAAA;AAEH,EAAO,OAAA,aAAA;AACT,CAAA;AAEa,MAAA,iBAAA,GAAoB,CAC/B,WAAA,EACA,QAKU,KAAA;AACV,EAAA,IAAI,CAAC,WAAa,EAAA;AAChB,IAAO,OAAA,IAAA;AAAA;AAGT,EAAA,MAAM,WAAc,GAAA,cAAA,CAAe,QAAU,EAAA,WAAA,EAAa,UAAU,IAAI,CAAA;AAExE,EAAM,MAAA,QAAA,GAAW,uBAAwB,CAAA,WAAA,EAAa,WAAW,CAAA;AAEjE,EAAM,MAAA,GAAA,GAAM,IAAI,GAAI,EAAA;AACpB,EAAU,QAAA,EAAA,OAAA,CAAQ,CAAC,IAAuB,KAAA;AACxC,IAAI,GAAA,CAAA,QAAA,CAAS,KAAK,IAAM,EAAA,IAAA,EAAM,IAAI,IAAK,CAAA,QAAA,IAAY,EAAE,CAAA;AAAA,GACtD,CAAA;AAED,EAAA,MAAM,QAAkC,EAAC;AACzC,EAAA,MAAM,mBAA8C,EAAC;AACrD,EAAI,GAAA,CAAA,eAAA,CAAgB,CAAC,CAAc,KAAA;AACjC,IAAA,IAAI,CAAC,gBAAA,CAAiB,CAAE,CAAA,KAAK,CAAG,EAAA;AAC9B,MAAA,gBAAA,CAAiB,CAAE,CAAA,KAAK,CAAI,GAAA,YAAA,CAAa,EAAE,IAAI,CAAA;AAAA,KAC1C,MAAA;AACL,MAAiB,gBAAA,CAAA,CAAA,CAAE,KAAK,CAAA,GAAI,IAAK,CAAA,GAAA;AAAA,QAC/B,gBAAA,CAAiB,EAAE,KAAK,CAAA;AAAA,QACxB,YAAA,CAAa,EAAE,IAAI;AAAA,OACrB;AAAA;AACF,GACD,CAAA;AACD,EAAI,GAAA,CAAA,eAAA,CAAgB,CAAC,MAAmB,KAAA;AACtC,IAAA,MAAM,OAAO,MAAO,CAAA,IAAA;AACpB,IAAA,MAAM,aAAgB,GAAA,gBAAA,CAAiB,IAAM,EAAA,GAAA,EAAK,MAAM,CAAA;AACxD,IAAM,MAAA,YAAA,GACJ,OAAO,IAAK,CAAA,WAAA,CAAY,IAAI,CAAG,EAAA,MAAA,GAAS,IAAI,mBAAsB,GAAA,CAAA;AACpE,IAAM,MAAA,aAAA,GAAgB,WAAa,EAAA,MAAA,EAAQ,YAAc,EAAA,IAAA;AAAA,MACvD,CAAA,CAAA,KAAK,CAAE,CAAA,IAAA,KAAS,IAAK,CAAA;AAAA,KACvB;AACA,IAAM,KAAA,CAAA,IAAA;AAAA,MACJ,sBAAA,CAAuB,SAAS,SAAW,EAAA;AAAA,QACzC,IAAI,MAAO,CAAA,IAAA;AAAA,QACX,OAAO,MAAO,CAAA,IAAA;AAAA,QACd,OACE,gBAAiB,CAAA,MAAA,CAAO,KAAK,CAC7B,GAAA,YAAA,GAAe,IACf,uBACA,GAAA,YAAA;AAAA,QACF,aAAA;AAAA,QACA,QAAQ,aAAgB,GAAA,SAAA,CAAU,OAAU,GAAA,MAAA,CAAO,KAAK,MAAQ,EAAA,MAAA;AAAA,QAChE,UAAA,EAAY,iBAAkB,CAAA,MAAA,CAAO,IAAI,CAAA;AAAA,QACzC,MAAM,MAAO,CAAA,IAAA;AAAA,QACb;AAAA,OACD;AAAA,KACH;AAAA,GACD,CAAA;AAED,EAAA,MAAM,eAAkB,GAAA,uBAAA;AAAA,IACtB,WAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAM,MAAA,YAAA,GAAe,eAAgB,CAAA,GAAA,CAAI,CAAS,KAAA,KAAA;AAChD,IAAM,MAAA,aAAA,GAAgB,WAAa,EAAA,MAAA,EAAQ,YAAc,EAAA,IAAA;AAAA,MACvD,CAAA,CAAA,KAAK,CAAE,CAAA,IAAA,KAAS,KAAM,CAAA;AAAA,KACxB;AAEA,IAAO,OAAA,sBAAA,CAAuB,SAAS,YAAc,EAAA;AAAA,MACnD,IAAI,KAAM,CAAA,IAAA;AAAA,MACV,OAAO,KAAM,CAAA,IAAA;AAAA,MACb,KAAA,EACE,aAAa,iBAAkB,CAAA,eAAe,CAAC,CAC/C,GAAA,YAAA,GAAe,IACf,8BAAiC,GAAA,CAAA;AAAA,MACnC,MAAQ,EAAA,mBAAA;AAAA,MACR,eAAe,EAAC;AAAA,MAChB,MAAQ,EAAA,aAAA,GACJ,SAAU,CAAA,OAAA,GACT,MAAM,MAAQ,EAAA,MAAA;AAAA,MACnB,UAAA,EAAY,kBAAkB,KAAK,CAAA;AAAA,MACnC,IAAM,EAAA,KAAA;AAAA,MACN;AAAA,KACD,CAAA;AAAA,GACF,CAAA;AAED,EAAM,MAAA,YAAA,GAAe,aAAa,MAC9B,GAAA;AAAA,IACE;AAAA,MACE,EAAI,EAAA,kBAAA;AAAA,MACJ,MAAM,QAAS,CAAA,aAAA;AAAA,MACf,QAAU,EAAA,YAAA,CAAa,GAAI,CAAA,CAAA,CAAA,KAAK,EAAE,EAAE,CAAA;AAAA,MACpC,KAAO,EAAA,IAAA;AAAA,MACP,KAAA,EAAO,EAAE,OAAA,EAAS,8BAA+B;AAAA;AACnD,MAEF,EAAC;AACL,EAAM,MAAA,WAAA,GACJ,eAAe,CAAC,GAAG,OAAO,GAAG,YAAY,CAAG,EAAA,QAAA,CAAS,WAAa,EAAA;AAAA,IAChE,QAAS,CAAA;AAAA,GACV,CACD,CAAA,GAAA,CAAI,aAAa,CAAA;AAEnB,EAAA,MAAM,KAA6B,GAAA,iBAAA;AAAA,IACjC,CAAC,GAAG,KAAA,EAAO,GAAG,WAAA,EAAa,GAAG,YAAY,CAAA;AAAA,IAC1C,QAAS,CAAA,WAAA;AAAA,IACT,QAAS,CAAA,IAAA;AAAA,IACT,QAAS,CAAA,IAAA;AAAA,IACT,CAAC,SAAS,YAAY,CAAA;AAAA,IACtB,QAAS,CAAA;AAAA,GACX;AAEA,EAAO,OAAA;AAAA,IACL,KAAO,EAAA;AAAA,MACL,EAAI,EAAA,CAAA,EAAG,WAAa,EAAA,QAAA,EAAU,IAAI,CAAA,MAAA,CAAA;AAAA,MAClC,MAAM,SAAU,CAAA,KAAA;AAAA,MAChB,QAAQ,cAAe,CAAA,YAAA;AAAA,MACvB,WAAA,EAAa,CAAC,GAAA,EAAK,CAAC;AAAA,KACtB;AAAA,IACA,KAAO,EAAA;AAAA,MACL,GAAG,KAAA;AAAA,MACH,GAAG,WAAA;AAAA,MACH,GAAG,YAAA;AAAA,MACH,GAAG;AAAA,KACL;AAAA,IACA;AAAA,GACF;AACF;AAEa,MAAA,aAAA,GAAgB,CAC3B,MAC4B,KAAA;AAC5B,EAAA,QAAQ,MAAQ;AAAA,IACd,KAAK,cAAe,CAAA,aAAA;AAClB,MAAO,OAAA,mBAAA;AAAA,IACT,KAAK,cAAe,CAAA,YAAA;AAClB,MAAO,OAAA,kBAAA;AAAA,IACT,KAAK,cAAe,CAAA,mBAAA;AAClB,MAAO,OAAA,yBAAA;AAAA,IACT,KAAK,cAAe,CAAA,oBAAA;AAClB,MAAO,OAAA,0BAAA;AAAA,IACT;AACE,MAAO,OAAA,IAAA;AAAA;AAEb;;;;"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { isEmpty, get, find, cloneDeep, isFinite, each, trim } from 'lodash';
|
|
2
|
+
import { ComputedStatus, pipelineRunFilterReducer, SucceedConditionReason, pipelineRunStatus } from '@janus-idp/shared-react';
|
|
3
|
+
import { TEKTON_PIPELINE_RUN, TEKTON_PIPELINE_TASK } from '../consts/tekton-const.esm.js';
|
|
4
|
+
|
|
5
|
+
const s = 1e3;
|
|
6
|
+
const m = s * 60;
|
|
7
|
+
const h = m * 60;
|
|
8
|
+
const d = h * 24;
|
|
9
|
+
const w = d * 7;
|
|
10
|
+
const units = { w, d, h, m, s };
|
|
11
|
+
const formatPrometheusDuration = (ms) => {
|
|
12
|
+
if (!isFinite(ms) || ms < 0) {
|
|
13
|
+
return "";
|
|
14
|
+
}
|
|
15
|
+
let remaining = ms;
|
|
16
|
+
let str = "";
|
|
17
|
+
each(units, (factor, unit) => {
|
|
18
|
+
const n = Math.floor(remaining / factor);
|
|
19
|
+
if (n > 0) {
|
|
20
|
+
str += `${n}${unit} `;
|
|
21
|
+
remaining -= n * factor;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return trim(str);
|
|
25
|
+
};
|
|
26
|
+
const getPipelineRun = (runs, name) => {
|
|
27
|
+
if (runs?.length > 0 && name) {
|
|
28
|
+
return runs.find((run) => run?.metadata?.name === name) ?? null;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
};
|
|
32
|
+
const getStatusReason = (reason) => {
|
|
33
|
+
switch (reason) {
|
|
34
|
+
case SucceedConditionReason.PipelineRunCancelled:
|
|
35
|
+
return ComputedStatus.Cancelled;
|
|
36
|
+
case SucceedConditionReason.PipelineRunPending:
|
|
37
|
+
return ComputedStatus.Idle;
|
|
38
|
+
default:
|
|
39
|
+
return ComputedStatus.Failed;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const appendTaskDuration = (mTask) => {
|
|
43
|
+
const task = cloneDeep(mTask);
|
|
44
|
+
if (mTask?.status?.completionTime && mTask?.status?.startTime) {
|
|
45
|
+
const date = new Date(mTask.status.completionTime).getTime() - new Date(mTask.status.startTime).getTime();
|
|
46
|
+
task.status = {
|
|
47
|
+
...mTask.status,
|
|
48
|
+
duration: formatPrometheusDuration(date)
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return task;
|
|
52
|
+
};
|
|
53
|
+
const appendTaskStatus = (mTask) => {
|
|
54
|
+
let task = cloneDeep(mTask);
|
|
55
|
+
if (!mTask.status) {
|
|
56
|
+
task = {
|
|
57
|
+
...mTask,
|
|
58
|
+
status: { reason: ComputedStatus.Pending, conditions: [] }
|
|
59
|
+
};
|
|
60
|
+
} else if (mTask.status?.conditions) {
|
|
61
|
+
task.status.reason = pipelineRunStatus(mTask) || ComputedStatus.Pending;
|
|
62
|
+
} else if (mTask.status && !mTask.status.reason) {
|
|
63
|
+
task.status.reason = ComputedStatus.Pending;
|
|
64
|
+
}
|
|
65
|
+
return task;
|
|
66
|
+
};
|
|
67
|
+
const appendPipelineRunStatus = (pipelineRun, taskRuns, isFinallyTasks = false) => {
|
|
68
|
+
const tasks = (isFinallyTasks ? pipelineRun.status?.pipelineSpec?.finally : pipelineRun.status?.pipelineSpec?.tasks) || [];
|
|
69
|
+
return tasks?.map((task) => {
|
|
70
|
+
if (!pipelineRun.status) {
|
|
71
|
+
return task;
|
|
72
|
+
}
|
|
73
|
+
if (isEmpty(taskRuns)) {
|
|
74
|
+
return {
|
|
75
|
+
...task,
|
|
76
|
+
status: {
|
|
77
|
+
reason: getStatusReason(pipelineRun?.status?.conditions?.[0].reason)
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
let mTask = {
|
|
82
|
+
...task,
|
|
83
|
+
status: get(find(taskRuns, { pipelineTaskName: task.name }), "status")
|
|
84
|
+
};
|
|
85
|
+
mTask = appendTaskDuration(mTask);
|
|
86
|
+
mTask = appendTaskStatus(mTask);
|
|
87
|
+
return mTask;
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
const getPLRTaskRuns = (taskRuns, pipelineRun) => {
|
|
91
|
+
const filteredTaskRuns = taskRuns.filter(
|
|
92
|
+
(tr) => tr?.metadata?.labels?.[TEKTON_PIPELINE_RUN] === pipelineRun
|
|
93
|
+
);
|
|
94
|
+
return filteredTaskRuns.reduce((acc, taskRun) => {
|
|
95
|
+
const temp = {
|
|
96
|
+
[`${taskRun?.metadata?.name}`]: {
|
|
97
|
+
pipelineTaskName: taskRun?.metadata?.labels?.[TEKTON_PIPELINE_TASK],
|
|
98
|
+
status: taskRun?.status
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
acc = { ...acc, ...temp };
|
|
102
|
+
return acc;
|
|
103
|
+
}, {});
|
|
104
|
+
};
|
|
105
|
+
const getTaskStatus = (pipelineRun, task) => {
|
|
106
|
+
let taskStatus = {
|
|
107
|
+
reason: ComputedStatus.Idle
|
|
108
|
+
};
|
|
109
|
+
const computedStatus = pipelineRunFilterReducer(pipelineRun);
|
|
110
|
+
const isSkipped = !!(task && pipelineRun?.status?.skippedTasks?.some(
|
|
111
|
+
(t) => t.name === task.name
|
|
112
|
+
));
|
|
113
|
+
if (task?.status) {
|
|
114
|
+
taskStatus = task.status;
|
|
115
|
+
}
|
|
116
|
+
if (computedStatus === ComputedStatus.Failed || computedStatus === ComputedStatus.Cancelled) {
|
|
117
|
+
if (task?.status?.reason === ComputedStatus.Idle || task?.status?.reason === ComputedStatus.Pending) {
|
|
118
|
+
taskStatus.reason = ComputedStatus.Cancelled;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (isSkipped) {
|
|
122
|
+
taskStatus.reason = ComputedStatus.Skipped;
|
|
123
|
+
}
|
|
124
|
+
return taskStatus;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export { appendPipelineRunStatus, formatPrometheusDuration, getPLRTaskRuns, getPipelineRun, getTaskStatus };
|
|
128
|
+
//# sourceMappingURL=pipelineRun-utils.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipelineRun-utils.esm.js","sources":["../../src/utils/pipelineRun-utils.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { cloneDeep, each, find, get, isEmpty, isFinite, trim } from 'lodash';\n\nimport {\n ComputedStatus,\n pipelineRunFilterReducer,\n PipelineRunKind,\n pipelineRunStatus,\n PipelineTask,\n PipelineTaskWithStatus,\n PLRTaskRuns,\n SucceedConditionReason,\n TaskRunKind,\n} from '@janus-idp/shared-react';\n\nimport {\n TEKTON_PIPELINE_RUN,\n TEKTON_PIPELINE_TASK,\n} from '../consts/tekton-const';\nimport { TaskStatus } from '../types/taskRun';\n\n// Conversions between units and milliseconds\nconst s = 1000;\nconst m = s * 60;\nconst h = m * 60;\nconst d = h * 24;\nconst w = d * 7;\nconst units = { w, d, h, m, s };\n\nexport const formatPrometheusDuration = (ms: number) => {\n if (!isFinite(ms) || ms < 0) {\n return '';\n }\n let remaining = ms;\n let str = '';\n each(units, (factor, unit) => {\n const n = Math.floor(remaining / factor);\n if (n > 0) {\n str += `${n}${unit} `;\n remaining -= n * factor;\n }\n });\n return trim(str);\n};\n\nexport const taskConditions = {\n hasFromDependency: (task: PipelineTask): boolean =>\n !!task?.resources?.inputs?.[0].from,\n hasRunAfterDependency: (task: PipelineTask): boolean =>\n !!task?.runAfter && task?.runAfter?.length > 0,\n};\n\nexport const getPipelineRun = (\n runs: PipelineRunKind[],\n name: string,\n): PipelineRunKind | null => {\n if (runs?.length > 0 && name) {\n return runs.find(run => run?.metadata?.name === name) ?? null;\n }\n return null;\n};\n\nconst getStatusReason = (reason: string | undefined) => {\n switch (reason) {\n case SucceedConditionReason.PipelineRunCancelled:\n return ComputedStatus.Cancelled;\n case SucceedConditionReason.PipelineRunPending:\n return ComputedStatus.Idle;\n default:\n return ComputedStatus.Failed;\n }\n};\n\nconst appendTaskDuration = (mTask: PipelineTaskWithStatus) => {\n const task = cloneDeep(mTask);\n if (mTask?.status?.completionTime && mTask?.status?.startTime) {\n const date =\n new Date(mTask.status.completionTime).getTime() -\n new Date(mTask.status.startTime).getTime();\n task.status = {\n ...mTask.status,\n duration: formatPrometheusDuration(date),\n };\n }\n return task;\n};\n\nconst appendTaskStatus = (mTask: PipelineTaskWithStatus) => {\n let task = cloneDeep(mTask);\n if (!mTask.status) {\n task = {\n ...mTask,\n status: { reason: ComputedStatus.Pending, conditions: [] },\n };\n } else if (mTask.status?.conditions) {\n task.status.reason = pipelineRunStatus(mTask) || ComputedStatus.Pending;\n } else if (mTask.status && !mTask.status.reason) {\n task.status.reason = ComputedStatus.Pending;\n }\n return task;\n};\n\nexport const appendPipelineRunStatus = (\n pipelineRun: PipelineRunKind,\n taskRuns: PLRTaskRuns,\n isFinallyTasks = false,\n) => {\n const tasks =\n (isFinallyTasks\n ? pipelineRun.status?.pipelineSpec?.finally\n : pipelineRun.status?.pipelineSpec?.tasks) || [];\n\n return tasks?.map(task => {\n if (!pipelineRun.status) {\n return task as PipelineTaskWithStatus;\n }\n if (isEmpty(taskRuns)) {\n return {\n ...task,\n status: {\n reason: getStatusReason(pipelineRun?.status?.conditions?.[0].reason),\n },\n } as PipelineTaskWithStatus;\n }\n let mTask = {\n ...task,\n status: get(find(taskRuns, { pipelineTaskName: task.name }), 'status'),\n } as PipelineTaskWithStatus;\n // append task duration\n mTask = appendTaskDuration(mTask);\n // append task status\n mTask = appendTaskStatus(mTask);\n return mTask;\n });\n};\n\nexport const getPLRTaskRuns = (\n taskRuns: TaskRunKind[],\n pipelineRun: string | undefined,\n): PLRTaskRuns => {\n const filteredTaskRuns = taskRuns.filter(\n tr => tr?.metadata?.labels?.[TEKTON_PIPELINE_RUN] === pipelineRun,\n );\n return filteredTaskRuns.reduce((acc: any, taskRun: TaskRunKind) => {\n const temp = {\n [`${taskRun?.metadata?.name}`]: {\n pipelineTaskName: taskRun?.metadata?.labels?.[TEKTON_PIPELINE_TASK],\n status: taskRun?.status,\n },\n };\n // eslint-disable-next-line no-param-reassign\n acc = { ...acc, ...temp };\n return acc;\n }, {});\n};\n\nexport const getTaskStatus = (\n pipelineRun: PipelineRunKind,\n task: PipelineTaskWithStatus,\n) => {\n let taskStatus: TaskStatus = {\n reason: ComputedStatus.Idle,\n };\n\n const computedStatus = pipelineRunFilterReducer(pipelineRun);\n const isSkipped = !!(\n task &&\n pipelineRun?.status?.skippedTasks?.some(\n (t: { name: string }) => t.name === task.name,\n )\n );\n\n if (task?.status) {\n taskStatus = task.status as TaskStatus;\n }\n if (\n computedStatus === ComputedStatus.Failed ||\n computedStatus === ComputedStatus.Cancelled\n ) {\n if (\n task?.status?.reason === ComputedStatus.Idle ||\n task?.status?.reason === ComputedStatus.Pending\n ) {\n taskStatus.reason = ComputedStatus.Cancelled;\n }\n }\n if (isSkipped) {\n taskStatus.reason = ComputedStatus.Skipped;\n }\n return taskStatus;\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { TaskRunResultsAnnotations, TaskRunResultsKeyValue, TaskRunResultsTypeValue } from '@aonic-ui/pipelines';
|
|
2
|
+
import { pipelineRunFilterReducer } from '@janus-idp/shared-react';
|
|
3
|
+
import { TEKTON_PIPELINE_TASK, TEKTON_PIPELINE_RUN } from '../consts/tekton-const.esm.js';
|
|
4
|
+
|
|
5
|
+
const getSortedTaskRuns = (tRuns) => {
|
|
6
|
+
if (!tRuns || tRuns.length === 0) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const taskRuns = Array.from(tRuns).sort((a, b) => {
|
|
10
|
+
if (a.status?.completionTime) {
|
|
11
|
+
return b.status?.completionTime && new Date(a.status?.completionTime ?? "") > new Date(b.status.completionTime) ? 1 : -1;
|
|
12
|
+
}
|
|
13
|
+
return b.status?.completionTime || new Date(a.status?.startTime ?? "") > new Date(b.status?.startTime ?? "") ? 1 : -1;
|
|
14
|
+
});
|
|
15
|
+
return taskRuns?.map((tr) => {
|
|
16
|
+
return {
|
|
17
|
+
id: tr.metadata?.name,
|
|
18
|
+
name: tr.metadata?.labels?.[TEKTON_PIPELINE_TASK],
|
|
19
|
+
status: pipelineRunFilterReducer(tr),
|
|
20
|
+
startedAt: tr.status?.startTime,
|
|
21
|
+
endedAt: tr.status?.completionTime
|
|
22
|
+
};
|
|
23
|
+
}) || [];
|
|
24
|
+
};
|
|
25
|
+
const getActiveTaskRun = (taskRuns, activeTask) => activeTask ? taskRuns.find((taskRun) => taskRun?.id === activeTask)?.id : taskRuns[taskRuns.length - 1]?.id;
|
|
26
|
+
const checkTypeAnnotation = (tr, type) => tr?.metadata?.annotations?.[TaskRunResultsAnnotations.TYPE] === type;
|
|
27
|
+
const isSbomTaskRun = (tr) => tr?.metadata?.annotations?.[TaskRunResultsAnnotations.KEY] === TaskRunResultsKeyValue.SBOM;
|
|
28
|
+
const isECTaskRun = (tr) => checkTypeAnnotation(tr, TaskRunResultsTypeValue.EC);
|
|
29
|
+
const isACSImageScanTaskRun = (tr) => checkTypeAnnotation(tr, TaskRunResultsTypeValue.ROXCTL_IMAGE_SCAN);
|
|
30
|
+
const isACSImageCheckTaskRun = (tr) => checkTypeAnnotation(tr, TaskRunResultsTypeValue.ROXCTL_IMAGE_CHECK);
|
|
31
|
+
const isACSDeploymentCheckTaskRun = (tr) => checkTypeAnnotation(tr, TaskRunResultsTypeValue.ROXCTL_DEPLOYMENT_CHECK);
|
|
32
|
+
const getTaskrunsOutputGroup = (pipelineRunName, taskruns) => {
|
|
33
|
+
const getPLRTaskRunByType = (check) => taskruns?.find(
|
|
34
|
+
(tr) => tr?.metadata?.labels?.[TEKTON_PIPELINE_RUN] === pipelineRunName && check(tr)
|
|
35
|
+
);
|
|
36
|
+
return {
|
|
37
|
+
sbomTaskRun: getPLRTaskRunByType(isSbomTaskRun),
|
|
38
|
+
ecTaskRun: getPLRTaskRunByType(isECTaskRun),
|
|
39
|
+
acsImageScanTaskRun: getPLRTaskRunByType(isACSImageScanTaskRun),
|
|
40
|
+
acsImageCheckTaskRun: getPLRTaskRunByType(isACSImageCheckTaskRun),
|
|
41
|
+
acsDeploymentCheckTaskRun: getPLRTaskRunByType(isACSDeploymentCheckTaskRun)
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
const hasExternalLink = (sbomTaskRun) => sbomTaskRun?.metadata?.annotations?.[TaskRunResultsAnnotations.TYPE] === TaskRunResultsTypeValue.EXTERNAL_LINK;
|
|
45
|
+
const getSbomLink = (sbomTaskRun) => (sbomTaskRun?.status?.results || sbomTaskRun?.status?.taskResults)?.find(
|
|
46
|
+
(r) => r.name === TaskRunResultsKeyValue.SBOM
|
|
47
|
+
)?.value;
|
|
48
|
+
|
|
49
|
+
export { getActiveTaskRun, getSbomLink, getSortedTaskRuns, getTaskrunsOutputGroup, hasExternalLink, isACSDeploymentCheckTaskRun, isACSImageCheckTaskRun, isACSImageScanTaskRun, isECTaskRun, isSbomTaskRun };
|
|
50
|
+
//# sourceMappingURL=taskRun-utils.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskRun-utils.esm.js","sources":["../../src/utils/taskRun-utils.ts"],"sourcesContent":["/*\n * Copyright 2024 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 {\n TaskRunResultsAnnotations,\n TaskRunResultsKeyValue,\n TaskRunResultsTypeValue,\n} from '@aonic-ui/pipelines';\n\nimport {\n ComputedStatus,\n pipelineRunFilterReducer,\n TaskRunKind,\n} from '@janus-idp/shared-react';\n\nimport {\n TEKTON_PIPELINE_RUN,\n TEKTON_PIPELINE_TASK,\n} from '../consts/tekton-const';\nimport { OutputTaskRunGroup } from '../types/output';\n\nexport type TaskStep = {\n id: string;\n name: string;\n status: ComputedStatus;\n startedAt?: string;\n endedAt?: string;\n};\n\nexport const getSortedTaskRuns = (tRuns: TaskRunKind[]): TaskStep[] => {\n if (!tRuns || tRuns.length === 0) {\n return [];\n }\n const taskRuns = Array.from(tRuns).sort((a, b) => {\n if (a.status?.completionTime) {\n return b.status?.completionTime &&\n new Date(a.status?.completionTime ?? '') >\n new Date(b.status.completionTime)\n ? 1\n : -1;\n }\n return b.status?.completionTime ||\n new Date(a.status?.startTime ?? '') > new Date(b.status?.startTime ?? '')\n ? 1\n : -1;\n });\n return (taskRuns?.map(tr => {\n return {\n id: tr.metadata?.name,\n name: tr.metadata?.labels?.[TEKTON_PIPELINE_TASK],\n status: pipelineRunFilterReducer(tr),\n startedAt: tr.status?.startTime,\n endedAt: tr.status?.completionTime,\n };\n }) || []) as TaskStep[];\n};\n\nexport const getActiveTaskRun = (\n taskRuns: TaskStep[],\n activeTask: string | undefined,\n): string | undefined =>\n activeTask\n ? taskRuns.find(taskRun => taskRun?.id === activeTask)?.id\n : taskRuns[taskRuns.length - 1]?.id;\n\nconst checkTypeAnnotation = (\n tr: TaskRunKind | undefined,\n type: TaskRunResultsTypeValue,\n): boolean =>\n tr?.metadata?.annotations?.[TaskRunResultsAnnotations.TYPE] === type;\n\nexport const isSbomTaskRun = (tr: TaskRunKind | undefined): boolean =>\n tr?.metadata?.annotations?.[TaskRunResultsAnnotations.KEY] ===\n TaskRunResultsKeyValue.SBOM;\n\nexport const isECTaskRun = (tr: TaskRunKind | undefined): boolean =>\n checkTypeAnnotation(tr, TaskRunResultsTypeValue.EC);\n\nexport const isACSImageScanTaskRun = (tr: TaskRunKind | undefined): boolean =>\n checkTypeAnnotation(tr, TaskRunResultsTypeValue.ROXCTL_IMAGE_SCAN);\n\nexport const isACSImageCheckTaskRun = (tr: TaskRunKind | undefined): boolean =>\n checkTypeAnnotation(tr, TaskRunResultsTypeValue.ROXCTL_IMAGE_CHECK);\n\nexport const isACSDeploymentCheckTaskRun = (\n tr: TaskRunKind | undefined,\n): boolean =>\n checkTypeAnnotation(tr, TaskRunResultsTypeValue.ROXCTL_DEPLOYMENT_CHECK);\n\nexport const getTaskrunsOutputGroup = (\n pipelineRunName: string | undefined,\n taskruns: TaskRunKind[],\n): OutputTaskRunGroup => {\n const getPLRTaskRunByType = (\n check: (tr: TaskRunKind | undefined) => boolean,\n ): TaskRunKind | undefined =>\n taskruns?.find(\n (tr: TaskRunKind) =>\n tr?.metadata?.labels?.[TEKTON_PIPELINE_RUN] === pipelineRunName &&\n check(tr),\n );\n\n return {\n sbomTaskRun: getPLRTaskRunByType(isSbomTaskRun),\n ecTaskRun: getPLRTaskRunByType(isECTaskRun),\n acsImageScanTaskRun: getPLRTaskRunByType(isACSImageScanTaskRun),\n acsImageCheckTaskRun: getPLRTaskRunByType(isACSImageCheckTaskRun),\n acsDeploymentCheckTaskRun: getPLRTaskRunByType(isACSDeploymentCheckTaskRun),\n };\n};\n\nexport const hasExternalLink = (\n sbomTaskRun: TaskRunKind | undefined,\n): boolean =>\n sbomTaskRun?.metadata?.annotations?.[TaskRunResultsAnnotations.TYPE] ===\n TaskRunResultsTypeValue.EXTERNAL_LINK;\n\nexport const getSbomLink = (\n sbomTaskRun: TaskRunKind | undefined,\n): string | undefined =>\n (sbomTaskRun?.status?.results || sbomTaskRun?.status?.taskResults)?.find(\n r => r.name === TaskRunResultsKeyValue.SBOM,\n )?.value;\n"],"names":[],"mappings":"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"}
|