@backstage/plugin-scaffolder 1.3.0-next.2 → 1.4.0-next.1
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 +84 -0
- package/alpha/package.json +1 -1
- package/dist/esm/{Router-09b6a7c3.esm.js → Router-a85c58bd.esm.js} +40 -23
- package/dist/esm/Router-a85c58bd.esm.js.map +1 -0
- package/dist/esm/{default-554cb9ad.esm.js → default-a3df1f11.esm.js} +2 -2
- package/dist/esm/{default-554cb9ad.esm.js.map → default-a3df1f11.esm.js.map} +1 -1
- package/dist/esm/{index-b64713a1.esm.js → index-470abc37.esm.js} +12 -7
- package/dist/esm/index-470abc37.esm.js.map +1 -0
- package/dist/esm/{index-f46ffb89.esm.js → index-eff50288.esm.js} +6 -5
- package/dist/esm/{index-f46ffb89.esm.js.map → index-eff50288.esm.js.map} +1 -1
- package/dist/index.esm.js +1 -1
- package/package.json +23 -24
- package/dist/esm/Router-09b6a7c3.esm.js.map +0 -1
- package/dist/esm/index-b64713a1.esm.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,89 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder
|
|
2
2
|
|
|
3
|
+
## 1.4.0-next.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/core-components@0.9.6-next.1
|
|
9
|
+
- @backstage/catalog-model@1.1.0-next.1
|
|
10
|
+
- @backstage/errors@1.1.0-next.0
|
|
11
|
+
- @backstage/theme@0.2.16-next.0
|
|
12
|
+
- @backstage/catalog-client@1.0.4-next.1
|
|
13
|
+
- @backstage/integration@1.2.2-next.1
|
|
14
|
+
- @backstage/integration-react@1.1.2-next.1
|
|
15
|
+
- @backstage/plugin-catalog-common@1.0.4-next.0
|
|
16
|
+
- @backstage/plugin-catalog-react@1.1.2-next.1
|
|
17
|
+
- @backstage/plugin-permission-react@0.4.3-next.0
|
|
18
|
+
|
|
19
|
+
## 1.4.0-next.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- 3500c13a33: A new template editor has been added which is accessible via the context menu on the top right hand corner of the Create page. It allows you to load a template from a local directory, edit it with a preview, execute it in dry-run mode, and view the results. Note that the [File System Access API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API) must be supported by your browser for this to be available.
|
|
24
|
+
|
|
25
|
+
To support the new template editor the `ScaffolderApi` now has an optional `dryRun` method, which is implemented by the default `ScaffolderClient`.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- 37539e29d8: The template editor now shows the cause of request errors that happen during a dry-run.
|
|
30
|
+
- 842282ecf9: Bumped `codemirror` dependencies to `v6.0.0`.
|
|
31
|
+
- 464bb0e6c8: The max content size for dry-run files has been reduced from 256k to 64k.
|
|
32
|
+
- a7c0b34d70: Swap usage of `MaterialTable` with `Table` from `core-components`
|
|
33
|
+
- Updated dependencies
|
|
34
|
+
- @backstage/catalog-model@1.1.0-next.0
|
|
35
|
+
- @backstage/core-components@0.9.6-next.0
|
|
36
|
+
- @backstage/integration@1.2.2-next.0
|
|
37
|
+
- @backstage/catalog-client@1.0.4-next.0
|
|
38
|
+
- @backstage/plugin-catalog-react@1.1.2-next.0
|
|
39
|
+
- @backstage/plugin-scaffolder-common@1.1.2-next.0
|
|
40
|
+
- @backstage/integration-react@1.1.2-next.0
|
|
41
|
+
|
|
42
|
+
## 1.3.0
|
|
43
|
+
|
|
44
|
+
### Minor Changes
|
|
45
|
+
|
|
46
|
+
- dc39366bdb: - Added a new page under `/create/tasks` to show tasks that have been run by the Scaffolder.
|
|
47
|
+
- Ability to filter these tasks by the signed in user, and all tasks.
|
|
48
|
+
- Added optional method to the `ScaffolderApi` interface called `listTasks` to get tasks with an required `filterByOwnership` parameter.
|
|
49
|
+
- 86a4a0f72d: Get data of other fields in Form from a custom field in template Scaffolder.
|
|
50
|
+
following:
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
const CustomFieldExtensionComponent = (props: FieldExtensionComponentProps<string[]>) => {
|
|
54
|
+
const { formData } = props.formContext;
|
|
55
|
+
...
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const CustomFieldExtension = scaffolderPlugin.provide(
|
|
59
|
+
createScaffolderFieldExtension({
|
|
60
|
+
name: ...,
|
|
61
|
+
component: CustomFieldExtensionComponent,
|
|
62
|
+
validation: ...
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- 72dfcbc8bf: Gerrit Integration: Implemented a `RepoUrlPicker` for Gerrit.
|
|
68
|
+
- f93af969cd: Added the ability to support running of templates that are not in the `default` namespace
|
|
69
|
+
|
|
70
|
+
### Patch Changes
|
|
71
|
+
|
|
72
|
+
- ac0c7e45ee: Fixes review mask in `MultistepJsonForm` to work as documented. `show: true` no longer needed when mask is set.
|
|
73
|
+
- 8f7b1835df: Updated dependency `msw` to `^0.41.0`.
|
|
74
|
+
- fd505f40c0: Handle binary files and files that are too large during dry-run content upload.
|
|
75
|
+
- Updated dependencies
|
|
76
|
+
- @backstage/plugin-catalog-react@1.1.1
|
|
77
|
+
- @backstage/plugin-catalog-common@1.0.3
|
|
78
|
+
- @backstage/core-components@0.9.5
|
|
79
|
+
- @backstage/integration@1.2.1
|
|
80
|
+
- @backstage/catalog-client@1.0.3
|
|
81
|
+
- @backstage/core-plugin-api@1.0.3
|
|
82
|
+
- @backstage/integration-react@1.1.1
|
|
83
|
+
- @backstage/catalog-model@1.0.3
|
|
84
|
+
- @backstage/plugin-permission-react@0.4.2
|
|
85
|
+
- @backstage/plugin-scaffolder-common@1.1.1
|
|
86
|
+
|
|
3
87
|
## 1.3.0-next.2
|
|
4
88
|
|
|
5
89
|
### Minor Changes
|
package/alpha/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React, { useState, useContext, useCallback, createContext, useEffect, useRef, useMemo, Children, Component, Fragment } from 'react';
|
|
2
|
-
import { useNavigate, Navigate, useOutlet, Routes, Route } from 'react-router';
|
|
3
|
-
import { ItemCardHeader, MarkdownContent, Button, ContentHeader, Progress, WarningPanel, Link as Link$1, Content, ItemCardGrid, Page, Header, CreateButton, SupportButton, StructuredMetadataTable, InfoCard, ErrorPage, ErrorPanel, LogViewer, StatusError, StatusOK, StatusPending, Lifecycle, EmptyState } from '@backstage/core-components';
|
|
2
|
+
import { useNavigate, Navigate, useOutlet, Routes, Route, useParams as useParams$1 } from 'react-router';
|
|
3
|
+
import { ItemCardHeader, MarkdownContent, Button, ContentHeader, Progress, WarningPanel, Link as Link$1, Content, ItemCardGrid, Page, Header, CreateButton, SupportButton, StructuredMetadataTable, InfoCard, ErrorPage, ErrorPanel, LogViewer, StatusError, StatusOK, StatusPending, Lifecycle, EmptyState, Table as Table$1 } from '@backstage/core-components';
|
|
4
4
|
import { useRouteRef, useApi, errorApiRef, featureFlagsApiRef, useApiHolder, alertApiRef, useElementFilter } from '@backstage/core-plugin-api';
|
|
5
5
|
import { getEntityRelations, getEntitySourceLocation, FavoriteEntity, EntityRefLinks, useEntityList, EntityListProvider, CatalogFilterLayout, EntitySearchBar, EntityKindPicker, UserListPicker, EntityTagPicker, catalogApiRef, humanizeEntityRef, EntityRefLink } from '@backstage/plugin-catalog-react';
|
|
6
|
-
import { s as selectedTemplateRouteRef, e as editRouteRef, a as actionsRouteRef, b as scaffolderListTaskRouteRef, r as registerComponentRouteRef, T as TemplateTypePicker, S as SecretsContext, c as scaffolderApiRef, d as scaffolderTaskRouteRef, f as rootRouteRef, g as TaskStatusStepper, h as TaskPageLinks, F as FIELD_EXTENSION_WRAPPER_KEY, i as FIELD_EXTENSION_KEY, j as SecretsContextProvider, k as TaskPage } from './index-
|
|
7
|
-
import { RELATION_OWNED_BY,
|
|
6
|
+
import { s as selectedTemplateRouteRef, e as editRouteRef, a as actionsRouteRef, b as scaffolderListTaskRouteRef, r as registerComponentRouteRef, T as TemplateTypePicker, S as SecretsContext, c as scaffolderApiRef, d as scaffolderTaskRouteRef, f as rootRouteRef, g as TaskStatusStepper, h as TaskPageLinks, F as FIELD_EXTENSION_WRAPPER_KEY, i as FIELD_EXTENSION_KEY, l as legacySelectedTemplateRouteRef, j as SecretsContextProvider, k as TaskPage } from './index-470abc37.esm.js';
|
|
7
|
+
import { RELATION_OWNED_BY, parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';
|
|
8
8
|
import { makeStyles, useTheme, Card, CardMedia, CardContent, Box, Typography, Chip, CardActions, IconButton, Tooltip, Link, Stepper, Step, StepLabel, StepContent, Button as Button$1, Paper, LinearProgress, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Divider as Divider$1, FormControl, InputLabel, Select, MenuItem as MenuItem$1, List as List$2, ListItemIcon as ListItemIcon$1, ListItemText as ListItemText$1 } from '@material-ui/core';
|
|
9
9
|
import { scmIntegrationsApiRef, ScmIntegrationIcon } from '@backstage/integration-react';
|
|
10
10
|
import WarningIcon from '@material-ui/icons/Warning';
|
|
@@ -62,12 +62,11 @@ import RefreshIcon from '@material-ui/icons/Refresh';
|
|
|
62
62
|
import SaveIcon from '@material-ui/icons/Save';
|
|
63
63
|
import useDebounce from 'react-use/lib/useDebounce';
|
|
64
64
|
import { showPanel } from '@codemirror/view';
|
|
65
|
-
import MaterialTable from '@material-table/core';
|
|
66
65
|
import SettingsIcon from '@material-ui/icons/Settings';
|
|
67
66
|
import AllIcon from '@material-ui/icons/FontDownload';
|
|
68
67
|
import { DateTime, Interval } from 'luxon';
|
|
69
68
|
import humanizeDuration from 'humanize-duration';
|
|
70
|
-
import { D as DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from './default-
|
|
69
|
+
import { D as DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from './default-a3df1f11.esm.js';
|
|
71
70
|
import '@backstage/errors';
|
|
72
71
|
import 'zen-observable';
|
|
73
72
|
import '@material-ui/core/FormControl';
|
|
@@ -169,7 +168,8 @@ const TemplateCard = ({ template, deprecated }) => {
|
|
|
169
168
|
const themeId = backstageTheme.getPageTheme({ themeId: templateProps.type }) ? templateProps.type : "other";
|
|
170
169
|
const theme = backstageTheme.getPageTheme({ themeId });
|
|
171
170
|
const classes = useStyles$e({ backgroundImage: theme.backgroundImage });
|
|
172
|
-
const
|
|
171
|
+
const { name, namespace } = parseEntityRef(stringifyEntityRef(template));
|
|
172
|
+
const href = templateRoute({ templateName: name, namespace });
|
|
173
173
|
const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
|
|
174
174
|
const sourceLocation = getEntitySourceLocation(template, scmIntegrationsApi);
|
|
175
175
|
return /* @__PURE__ */ React.createElement(Card, null, /* @__PURE__ */ React.createElement(CardMedia, {
|
|
@@ -671,11 +671,16 @@ const TemplatePage = ({
|
|
|
671
671
|
const secretsContext = useContext(SecretsContext);
|
|
672
672
|
const errorApi = useApi(errorApiRef);
|
|
673
673
|
const scaffolderApi = useApi(scaffolderApiRef);
|
|
674
|
-
const { templateName } = useParams();
|
|
674
|
+
const { templateName, namespace } = useParams();
|
|
675
|
+
const templateRef = stringifyEntityRef({
|
|
676
|
+
name: templateName,
|
|
677
|
+
kind: "template",
|
|
678
|
+
namespace
|
|
679
|
+
});
|
|
675
680
|
const navigate = useNavigate();
|
|
676
681
|
const scaffolderTaskRoute = useRouteRef(scaffolderTaskRouteRef);
|
|
677
682
|
const rootRoute = useRouteRef(rootRouteRef);
|
|
678
|
-
const { schema, loading, error } = useTemplateParameterSchema(
|
|
683
|
+
const { schema, loading, error } = useTemplateParameterSchema(templateRef);
|
|
679
684
|
const [formState, setFormState] = useState(() => {
|
|
680
685
|
var _a;
|
|
681
686
|
const query = qs.parse(window.location.search, {
|
|
@@ -692,11 +697,7 @@ const TemplatePage = ({
|
|
|
692
697
|
const handleCreate = async () => {
|
|
693
698
|
var _a;
|
|
694
699
|
const { taskId } = await scaffolderApi.scaffold({
|
|
695
|
-
templateRef
|
|
696
|
-
name: templateName,
|
|
697
|
-
kind: "template",
|
|
698
|
-
namespace: "default"
|
|
699
|
-
}),
|
|
700
|
+
templateRef,
|
|
700
701
|
values: formState,
|
|
701
702
|
secrets: secretsContext == null ? void 0 : secretsContext.secrets
|
|
702
703
|
});
|
|
@@ -1147,8 +1148,8 @@ function DirectoryEditorProvider(props) {
|
|
|
1147
1148
|
}, props.children);
|
|
1148
1149
|
}
|
|
1149
1150
|
|
|
1150
|
-
const MAX_CONTENT_SIZE =
|
|
1151
|
-
const CHUNK_SIZE =
|
|
1151
|
+
const MAX_CONTENT_SIZE = 64 * 1024;
|
|
1152
|
+
const CHUNK_SIZE = 32 * 1024;
|
|
1152
1153
|
const DryRunContext = createContext(void 0);
|
|
1153
1154
|
function base64EncodeContent(content) {
|
|
1154
1155
|
if (content.length > MAX_CONTENT_SIZE) {
|
|
@@ -1774,11 +1775,17 @@ function TemplateEditorFormDirectoryEditorDryRun(props) {
|
|
|
1774
1775
|
if (!selectedFile) {
|
|
1775
1776
|
return;
|
|
1776
1777
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1778
|
+
try {
|
|
1779
|
+
await dryRun.execute({
|
|
1780
|
+
templateContent: selectedFile.content,
|
|
1781
|
+
values: data,
|
|
1782
|
+
files: directoryEditor.files
|
|
1783
|
+
});
|
|
1784
|
+
setErrorText();
|
|
1785
|
+
} catch (e) {
|
|
1786
|
+
setErrorText(String(e.cause || e));
|
|
1787
|
+
throw e;
|
|
1788
|
+
}
|
|
1782
1789
|
};
|
|
1783
1790
|
const content = selectedFile && selectedFile.path.match(/\.ya?ml$/) ? selectedFile.content : void 0;
|
|
1784
1791
|
return /* @__PURE__ */ React.createElement(TemplateEditorForm, {
|
|
@@ -2266,7 +2273,7 @@ const ListTaskPageContent = (props) => {
|
|
|
2266
2273
|
return /* @__PURE__ */ React.createElement(CatalogFilterLayout, null, /* @__PURE__ */ React.createElement(CatalogFilterLayout.Filters, null, /* @__PURE__ */ React.createElement(OwnerListPicker, {
|
|
2267
2274
|
filter: ownerFilter,
|
|
2268
2275
|
onSelectOwner: (id) => setOwnerFilter(id)
|
|
2269
|
-
})), /* @__PURE__ */ React.createElement(CatalogFilterLayout.Content, null, /* @__PURE__ */ React.createElement(
|
|
2276
|
+
})), /* @__PURE__ */ React.createElement(CatalogFilterLayout.Content, null, /* @__PURE__ */ React.createElement(Table$1, {
|
|
2270
2277
|
data: (_a = value == null ? void 0 : value.tasks) != null ? _a : [],
|
|
2271
2278
|
title: "Tasks",
|
|
2272
2279
|
columns: [
|
|
@@ -2342,6 +2349,14 @@ const Router = (props) => {
|
|
|
2342
2349
|
...customFieldExtensions,
|
|
2343
2350
|
...DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS.filter(({ name }) => !customFieldExtensions.some((customFieldExtension) => customFieldExtension.name === name))
|
|
2344
2351
|
];
|
|
2352
|
+
const RedirectingComponent = () => {
|
|
2353
|
+
const { templateName } = useParams$1();
|
|
2354
|
+
const newLink = useRouteRef(selectedTemplateRouteRef);
|
|
2355
|
+
useEffect(() => console.warn("The route /template/:templateName is deprecated, please use the new /template/:namespace/:templateName route instead"), []);
|
|
2356
|
+
return /* @__PURE__ */ React.createElement(Navigate, {
|
|
2357
|
+
to: newLink({ namespace: "default", templateName })
|
|
2358
|
+
});
|
|
2359
|
+
};
|
|
2345
2360
|
return /* @__PURE__ */ React.createElement(Routes, null, /* @__PURE__ */ React.createElement(Route, {
|
|
2346
2361
|
element: /* @__PURE__ */ React.createElement(ScaffolderPage, {
|
|
2347
2362
|
groups,
|
|
@@ -2349,6 +2364,8 @@ const Router = (props) => {
|
|
|
2349
2364
|
contextMenu: props.contextMenu
|
|
2350
2365
|
})
|
|
2351
2366
|
}), /* @__PURE__ */ React.createElement(Route, {
|
|
2367
|
+
path: legacySelectedTemplateRouteRef.path
|
|
2368
|
+
}, /* @__PURE__ */ React.createElement(RedirectingComponent, null)), /* @__PURE__ */ React.createElement(Route, {
|
|
2352
2369
|
path: selectedTemplateRouteRef.path,
|
|
2353
2370
|
element: /* @__PURE__ */ React.createElement(SecretsContextProvider, null, /* @__PURE__ */ React.createElement(TemplatePage, {
|
|
2354
2371
|
customFieldExtensions: fieldExtensions
|
|
@@ -2377,4 +2394,4 @@ const Router = (props) => {
|
|
|
2377
2394
|
};
|
|
2378
2395
|
|
|
2379
2396
|
export { Router };
|
|
2380
|
-
//# sourceMappingURL=Router-
|
|
2397
|
+
//# sourceMappingURL=Router-a85c58bd.esm.js.map
|