From f8633307c40b0af9bf813e9d90986bc954a51bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Fri, 4 Feb 2022 20:17:10 +0100 Subject: [PATCH 01/51] add an entity inspection dialog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/big-days-divide.md | 10 + .changeset/smooth-wasps-knock.md | 7 + packages/catalog-client/api-report.md | 4 +- packages/catalog-client/src/types/api.ts | 4 +- plugins/catalog-react/api-report.md | 7 + plugins/catalog-react/package.json | 2 + .../InspectEntityDialog.tsx | 162 +++++++++++++ .../components/AncestryPage.tsx | 223 ++++++++++++++++++ .../components/ColocatedPage.tsx | 171 ++++++++++++++ .../components/EntityKindIcon.tsx | 36 +++ .../components/JsonPage.tsx | 41 ++++ .../components/OverviewPage.tsx | 180 ++++++++++++++ .../components/YamlPage.tsx | 42 ++++ .../InspectEntityDialog/components/common.tsx | 124 ++++++++++ .../InspectEntityDialog/components/util.ts | 25 ++ .../components/InspectEntityDialog/index.ts | 17 ++ plugins/catalog-react/src/components/index.ts | 1 + plugins/catalog/api-report.md | 4 +- .../EntityContextMenu.test.tsx | 29 ++- .../EntityContextMenu/EntityContextMenu.tsx | 18 +- .../components/EntityLayout/EntityLayout.tsx | 24 +- .../EntityPageLayout/EntityPageLayout.tsx | 17 +- .../EntityProcessingErrorsPanel.test.tsx | 15 +- 23 files changed, 1139 insertions(+), 24 deletions(-) create mode 100644 .changeset/big-days-divide.md create mode 100644 .changeset/smooth-wasps-knock.md create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/components/ColocatedPage.tsx create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/components/EntityKindIcon.tsx create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/components/common.tsx create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/components/util.ts create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/index.ts diff --git a/.changeset/big-days-divide.md b/.changeset/big-days-divide.md new file mode 100644 index 0000000000..0285a5aacd --- /dev/null +++ b/.changeset/big-days-divide.md @@ -0,0 +1,10 @@ +--- +'@backstage/catalog-client': minor +--- + +Fixed the return type of the catalog API `getEntityAncestors`, to match the +actual server response shape. + +While this technically is a breaking change, the old shape has never worked at +all if you tried to use it - so treating this as an immediately-shipped breaking +bug fix. diff --git a/.changeset/smooth-wasps-knock.md b/.changeset/smooth-wasps-knock.md new file mode 100644 index 0000000000..de4c58e04b --- /dev/null +++ b/.changeset/smooth-wasps-knock.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog': patch +'@backstage/plugin-catalog-react': patch +--- + +Added an "inspect" entry in the entity three-dots menu, for lower level catalog +insights and debugging. diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index f3921993d3..13b2e6b5f0 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -133,10 +133,10 @@ export type CatalogEntityAncestorsRequest = { // @public export type CatalogEntityAncestorsResponse = { - root: EntityName; + rootEntityRef: string; items: { entity: Entity; - parents: EntityName[]; + parentEntityRefs: string[]; }[]; }; diff --git a/packages/catalog-client/src/types/api.ts b/packages/catalog-client/src/types/api.ts index 3a09e14d71..0622d654fa 100644 --- a/packages/catalog-client/src/types/api.ts +++ b/packages/catalog-client/src/types/api.ts @@ -121,8 +121,8 @@ export type CatalogEntityAncestorsRequest = { * @public */ export type CatalogEntityAncestorsResponse = { - root: EntityName; - items: { entity: Entity; parents: EntityName[] }[]; + rootEntityRef: string; + items: { entity: Entity; parentEntityRefs: string[] }[]; }; /** diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index 2c064a504f..83c5d4aaa2 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -766,6 +766,13 @@ export function getEntitySourceLocation( scmIntegrationsApi: ScmIntegrationRegistry, ): EntitySourceLocation | undefined; +// @public +export function InspectEntityDialog(props: { + open: boolean; + entity: Entity; + onClose: () => void; +}): JSX.Element | null; + // Warning: (ae-missing-release-tag) "isOwnerOf" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 9018ea75d7..98c671feec 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -42,11 +42,13 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", + "classnames": "^2.2.6", "jwt-decode": "^3.1.0", "lodash": "^4.17.21", "qs": "^6.9.4", "react-router": "6.0.0-beta.0", "react-use": "^17.2.4", + "yaml": "^1.10.0", "zen-observable": "^0.8.15" }, "peerDependencies": { diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx new file mode 100644 index 0000000000..2e904e4eb9 --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx @@ -0,0 +1,162 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { + Box, + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + makeStyles, + Tab, + Tabs, +} from '@material-ui/core'; +import React, { useEffect } from 'react'; +import { AncestryPage } from './components/AncestryPage'; +import { ColocatedPage } from './components/ColocatedPage'; +import { JsonPage } from './components/JsonPage'; +import { OverviewPage } from './components/OverviewPage'; +import { YamlPage } from './components/YamlPage'; + +const useStyles = makeStyles(theme => ({ + fullHeightDialog: { + height: 'calc(100% - 64px)', + }, + root: { + display: 'flex', + flexGrow: 1, + width: '100%', + backgroundColor: theme.palette.background.paper, + }, + tabs: { + borderRight: `1px solid ${theme.palette.divider}`, + flexShrink: 0, + }, + tabContents: { + flexGrow: 1, + overflowX: 'auto', + }, +})); + +function TabPanel(props: { + children?: React.ReactNode; + index: any; + value: any; +}) { + const { children, value, index, ...other } = props; + const classes = useStyles(); + return ( + + ); +} + +function a11yProps(index: number) { + return { + id: `vertical-tab-${index}`, + 'aria-controls': `vertical-tabpanel-${index}`, + }; +} + +/** + * A dialog that lets users inspect the low level details of their entities. + * + * @public + */ +export function InspectEntityDialog(props: { + open: boolean; + entity: Entity; + onClose: () => void; +}) { + const classes = useStyles(); + const [activeTab, setActiveTab] = React.useState(0); + + useEffect(() => { + setActiveTab(0); + }, [props.open]); + + if (!props.entity) { + return null; + } + + return ( + + + Entity Inspector + + +
+ setActiveTab(newValue)} + aria-label="Inspector options" + className={classes.tabs} + > + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ ); +} diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx new file mode 100644 index 0000000000..cab6faff0e --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx @@ -0,0 +1,223 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Entity, + ENTITY_DEFAULT_NAMESPACE, + stringifyEntityRef, +} from '@backstage/catalog-model'; +import { + DependencyGraph, + DependencyGraphTypes, + Link, + Progress, + ResponseErrorPanel, +} from '@backstage/core-components'; +import { useApi, useRouteRef } from '@backstage/core-plugin-api'; +import { DialogContentText, makeStyles } from '@material-ui/core'; +import classNames from 'classnames'; +import React, { useLayoutEffect, useRef, useState } from 'react'; +import { useNavigate } from 'react-router'; +import useAsync from 'react-use/lib/useAsync'; +import { catalogApiRef } from '../../../api'; +import { formatEntityRefTitle } from '../../../components/EntityRefLink/format'; +import { entityRouteRef } from '../../../routes'; +import { EntityKindIcon } from './EntityKindIcon'; + +const useStyles = makeStyles(theme => ({ + node: { + fill: theme.palette.grey[300], + stroke: theme.palette.grey[300], + '&.primary': { + fill: theme.palette.primary.light, + stroke: theme.palette.primary.light, + }, + '&.secondary': { + fill: theme.palette.secondary.light, + stroke: theme.palette.secondary.light, + }, + }, + text: { + fill: theme.palette.getContrastText(theme.palette.grey[300]), + '&.primary': { + fill: theme.palette.primary.contrastText, + }, + '&.secondary': { + fill: theme.palette.secondary.contrastText, + }, + '&.focused': { + fontWeight: 'bold', + }, + }, + clickable: { + cursor: 'pointer', + }, +})); + +type NodeType = Entity & { root: boolean }; + +function useAncestry(root: Entity): { + loading: boolean; + error?: Error; + nodes: DependencyGraphTypes.DependencyNode[]; + edges: DependencyGraphTypes.DependencyEdge[]; +} { + const catalogClient = useApi(catalogApiRef); + const entityRef = stringifyEntityRef(root); + + const { loading, error, value } = useAsync(async () => { + const response = await catalogClient.getEntityAncestors({ entityRef }); + const nodes = new Array>(); + const edges = new Array(); + for (const current of response.items) { + const currentRef = stringifyEntityRef(current.entity); + const isRootNode = currentRef === response.rootEntityRef; + nodes.push({ id: currentRef, root: isRootNode, ...current.entity }); + for (const parentRef of current.parentEntityRefs) { + edges.push({ from: currentRef, to: parentRef }); + } + } + return { nodes, edges }; + }, [entityRef]); + + return { + loading, + error, + nodes: value?.nodes || [], + edges: value?.edges || [], + }; +} + +function CustomNode({ node }: DependencyGraphTypes.RenderNodeProps) { + const classes = useStyles(); + const navigate = useNavigate(); + const entityRoute = useRouteRef(entityRouteRef); + const [width, setWidth] = useState(0); + const [height, setHeight] = useState(0); + const idRef = useRef(null); + + useLayoutEffect(() => { + // set the width to the length of the ID + if (idRef.current) { + let { height: renderedHeight, width: renderedWidth } = + idRef.current.getBBox(); + renderedHeight = Math.round(renderedHeight); + renderedWidth = Math.round(renderedWidth); + if (renderedHeight !== height || renderedWidth !== width) { + setWidth(renderedWidth); + setHeight(renderedHeight); + } + } + }, [width, height]); + + const padding = 10; + const iconSize = height; + const paddedIconWidth = iconSize + padding; + const paddedWidth = paddedIconWidth + width + padding * 2; + const paddedHeight = height + padding * 2; + + const displayTitle = + node.metadata.title || + (node.kind && node.metadata.name && node.metadata.namespace + ? formatEntityRefTitle({ + kind: node.kind, + name: node.metadata.name, + namespace: node.metadata.namespace || '', + }) + : node.id); + + const onClick = () => { + navigate( + entityRoute({ + kind: node.kind, + namespace: node.metadata.namespace || ENTITY_DEFAULT_NAMESPACE, + name: node.metadata.name, + }), + ); + }; + const focused = false; + + return ( + + + + + {displayTitle} + + + ); +} + +export function AncestryPage(props: { entity: Entity }) { + const { loading, error, nodes, edges } = useAncestry(props.entity); + if (loading) { + return ; + } else if (error) { + return ; + } + + return ( + <> + Ancestry + + This is the ancestry of entities above the current one - as in, the + chain(s) of entities down to the current one, where{' '} + + processors emitted + {' '} + child entities that ultimately led to the current one existing. Note + that this is a completely different mechanism from relations. + + + + ); +} diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/ColocatedPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/ColocatedPage.tsx new file mode 100644 index 0000000000..96d3900a59 --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/ColocatedPage.tsx @@ -0,0 +1,171 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Entity, + LOCATION_ANNOTATION, + ORIGIN_LOCATION_ANNOTATION, + stringifyEntityRef, +} from '@backstage/catalog-model'; +import { Progress, ResponseErrorPanel } from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; +import { + DialogContentText, + List, + ListItem, + ListItemIcon, + makeStyles, +} from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; +import React from 'react'; +import useAsync from 'react-use/lib/useAsync'; +import { catalogApiRef } from '../../../api'; +import { EntityRefLink } from '../../EntityRefLink'; +import { KeyValueListItem, ListItemText } from './common'; +import { EntityKindIcon } from './EntityKindIcon'; + +const useStyles = makeStyles({ + root: { + display: 'flex', + flexDirection: 'column', + }, +}); + +function useColocated(entity: Entity): { + loading: boolean; + error?: Error; + location?: string; + originLocation?: string; + colocatedEntities?: Entity[]; +} { + const catalogApi = useApi(catalogApiRef); + const currentEntityRef = stringifyEntityRef(entity); + const location = entity.metadata.annotations?.[LOCATION_ANNOTATION]; + const origin = entity.metadata.annotations?.[ORIGIN_LOCATION_ANNOTATION]; + + const { loading, error, value } = useAsync(async () => { + if (!location && !origin) { + return []; + } + const response = await catalogApi.getEntities({ + filter: [ + ...(location + ? [{ [`metadata.annotations.${LOCATION_ANNOTATION}`]: location }] + : []), + ...(origin + ? [{ [`metadata.annotations.${ORIGIN_LOCATION_ANNOTATION}`]: origin }] + : []), + ], + }); + return response.items; + }, [location, origin]); + + return { + loading, + error, + location, + originLocation: origin, + colocatedEntities: value?.filter( + colocated => stringifyEntityRef(colocated) !== currentEntityRef, + ), + }; +} + +function EntityList(props: { entities: Entity[]; header?: [string, string] }) { + return ( + + {props.header && } + {props.entities.map(entity => ( + + + + + } /> + + ))} + + ); +} + +function Contents(props: { entity: Entity }) { + const { entity } = props; + + const { loading, error, location, originLocation, colocatedEntities } = + useColocated(entity); + if (loading) { + return ; + } else if (error) { + return ; + } + + if (!location && !originLocation) { + return ( + Entity had no location information. + ); + } else if (!colocatedEntities?.length) { + return ( + + There were no other entities on this location. + + ); + } + + if (location === originLocation) { + return ; + } + + const atLocation = colocatedEntities.filter( + e => e.metadata.annotations?.[LOCATION_ANNOTATION] === location, + ); + const atOrigin = colocatedEntities.filter( + e => + e.metadata.annotations?.[ORIGIN_LOCATION_ANNOTATION] === originLocation, + ); + + return ( + <> + {atLocation.length > 0 && ( + + )} + {atOrigin.length > 0 && ( + + )} + + ); +} + +export function ColocatedPage(props: { entity: Entity }) { + const classes = useStyles(); + return ( + <> + Colocated + + These are the entities that are colocated with this entity - as in, they + originated from the same data source (e.g. came from the same YAML + file), or from the same origin (e.g. the originally registered URL). + +
+ +
+ + ); +} diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/EntityKindIcon.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/EntityKindIcon.tsx new file mode 100644 index 0000000000..c2fc49aa0c --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/EntityKindIcon.tsx @@ -0,0 +1,36 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useApp } from '@backstage/core-plugin-api'; +import WorkIcon from '@material-ui/icons/Work'; +import React from 'react'; + +export function EntityKindIcon(props: { + kind: string; + x?: number; + y?: number; + width?: number; + height?: number; + className?: string; +}) { + const app = useApp(); + + const { kind, ...otherProps } = props; + const Icon = + app.getSystemIcon(`kind:${kind.toLocaleLowerCase('en-US')}`) ?? WorkIcon; + + return ; +} diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx new file mode 100644 index 0000000000..cee350f62a --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx @@ -0,0 +1,41 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { CodeSnippet } from '@backstage/core-components'; +import { DialogContentText } from '@material-ui/core'; +import React from 'react'; +import { sortKeys } from './util'; + +export function JsonPage(props: { entity: Entity }) { + return ( + <> + Entity as JSON + + This is the raw entity data as received from the catalog, on JSON form. + + +
+ +
+
+ + ); +} diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx new file mode 100644 index 0000000000..dbb7399481 --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx @@ -0,0 +1,180 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AlphaEntity, stringifyEntityRef } from '@backstage/catalog-model'; +import { + Box, + DialogContentText, + List, + ListItem, + ListItemIcon, + makeStyles, + Typography, +} from '@material-ui/core'; +import groupBy from 'lodash/groupBy'; +import sortBy from 'lodash/sortBy'; +import React from 'react'; +import { EntityRefLink } from '../../EntityRefLink'; +import { + Container, + HelpIcon, + KeyValueListItem, + ListItemText, + ListSubheader, +} from './common'; +import { EntityKindIcon } from './EntityKindIcon'; + +const useStyles = makeStyles({ + root: { + display: 'flex', + flexDirection: 'column', + }, +}); + +export function OverviewPage(props: { entity: AlphaEntity }) { + const classes = useStyles(); + const { + apiVersion, + kind, + metadata, + spec, + relations = [], + status = {}, + } = props.entity; + + const groupedRelations = groupBy( + sortBy(relations, r => stringifyEntityRef(r.target)), + 'type', + ); + + return ( + <> + Overview +
+ + + + + + + + + {spec?.type && ( + + + + )} + {metadata.uid && ( + + + + )} + {metadata.etag && ( + + + + )} + + + + + {!!Object.keys(metadata.annotations || {}).length && ( + + Annotations + + + } + > + {Object.entries(metadata.annotations!).map(entry => ( + + ))} + + )} + {!!Object.keys(metadata.labels || {}).length && ( + + Labels + + + } + > + {Object.entries(metadata.labels!).map(entry => ( + + ))} + + )} + {!!metadata.tags?.length && ( + Tags}> + {metadata.tags.map((tag, index) => ( + + + + + ))} + + )} + + + {!!relations.length && ( + + {Object.entries(groupedRelations).map( + ([type, groupRelations], index) => ( +
+ {type}}> + {groupRelations.map(group => ( + + + + + } + /> + + ))} + +
+ ), + )} +
+ )} + + {!!status.items?.length && ( + + {status.items.map((item, index) => ( +
+ + {item.level}: {item.type} + + {item.message} +
+ ))} +
+ )} +
+ + ); +} diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx new file mode 100644 index 0000000000..c876fe9edd --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx @@ -0,0 +1,42 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { CodeSnippet } from '@backstage/core-components'; +import DialogContentText from '@material-ui/core/DialogContentText'; +import React from 'react'; +import YAML from 'yaml'; +import { sortKeys } from './util'; + +export function YamlPage(props: { entity: Entity }) { + return ( + <> + Entity as YAML + + This is the raw entity data as received from the catalog, on YAML form. + + +
+ +
+
+ + ); +} diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/common.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/common.tsx new file mode 100644 index 0000000000..79a3c69955 --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/common.tsx @@ -0,0 +1,124 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Link } from '@backstage/core-components'; +import { + Box, + Card, + CardContent, + ListItem, + ListItemIcon, + ListItemText as MuiListItemText, + ListSubheader as MuiListSubheader, + makeStyles, + Typography, +} from '@material-ui/core'; +import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; +import React from 'react'; + +const useStyles = makeStyles(theme => ({ + root: { + display: 'flex', + flexDirection: 'column', + }, + marginTop: { + marginTop: theme.spacing(2), + }, + helpIcon: { + marginLeft: theme.spacing(1), + color: theme.palette.text.disabled, + }, + monospace: { + fontFamily: 'monospace', + }, +})); + +export function ListItemText(props: { + primary: React.ReactNode; + secondary?: React.ReactNode; +}) { + const classes = useStyles(); + return ( + + ); +} + +export function ListSubheader(props: { children?: React.ReactNode }) { + const classes = useStyles(); + return ( + + {props.children} + + ); +} + +export function Container(props: { + title: React.ReactNode; + helpLink?: string; + children: React.ReactNode; +}) { + return ( + + + + + {props.title} + {props.helpLink && } + + {props.children} + + + + ); +} + +export function KeyValueListItem(props: { + indent?: boolean; + entry: [string, string]; +}) { + const [key, value] = props.entry; + return ( + + {props.indent && } + + {value.substring(0, 4)} + {value.substring(4)} + + ) + } + /> + + ); +} + +export function HelpIcon(props: { to: string }) { + const classes = useStyles(); + return ( + + + + ); +} diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/util.ts b/plugins/catalog-react/src/components/InspectEntityDialog/components/util.ts new file mode 100644 index 0000000000..9dd25ba538 --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/util.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { JsonObject } from '@backstage/types'; + +export function sortKeys(data: JsonObject): JsonObject { + // we could do something custom, but lexicographical sorting is actually a + // good choice at least for the default set of keys + return Object.fromEntries( + [...Object.entries(data)].sort((a, b) => (a[0] < b[0] ? -1 : 1)), + ); +} diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/index.ts b/plugins/catalog-react/src/components/InspectEntityDialog/index.ts new file mode 100644 index 0000000000..1360ade125 --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { InspectEntityDialog } from './InspectEntityDialog'; diff --git a/plugins/catalog-react/src/components/index.ts b/plugins/catalog-react/src/components/index.ts index b80472a81d..807d6bb702 100644 --- a/plugins/catalog-react/src/components/index.ts +++ b/plugins/catalog-react/src/components/index.ts @@ -23,5 +23,6 @@ export * from './EntityTable'; export * from './EntityTagPicker'; export * from './EntityTypePicker'; export * from './FavoriteEntity'; +export * from './InspectEntityDialog'; export * from './UnregisterEntityDialog'; export * from './UserListPicker'; diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md index ad391b594f..e7825127a6 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/api-report.md @@ -351,7 +351,7 @@ export const EntityOrphanWarning: () => JSX.Element; // Warning: (ae-missing-release-tag) "EntityPageLayout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated export const EntityPageLayout: { ({ children, @@ -481,6 +481,6 @@ export type SystemDiagramCardClassKey = // src/components/CatalogTable/CatalogTable.d.ts:11:5 - (ae-forgotten-export) The symbol "columnFactories" needs to be exported by the entry point index.d.ts // src/components/EntityLayout/EntityLayout.d.ts:43:5 - (ae-forgotten-export) The symbol "EntityLayoutProps" needs to be exported by the entry point index.d.ts // src/components/EntityLayout/EntityLayout.d.ts:44:5 - (ae-forgotten-export) The symbol "SubRoute" needs to be exported by the entry point index.d.ts -// src/components/EntityPageLayout/EntityPageLayout.d.ts:17:5 - (ae-forgotten-export) The symbol "EntityPageLayoutProps" needs to be exported by the entry point index.d.ts +// src/components/EntityPageLayout/EntityPageLayout.d.ts:22:5 - (ae-forgotten-export) The symbol "EntityPageLayoutProps" needs to be exported by the entry point index.d.ts // src/plugin.d.ts:22:5 - (ae-forgotten-export) The symbol "ColumnBreakpoints" needs to be exported by the entry point index.d.ts ``` diff --git a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.test.tsx b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.test.tsx index f16a17bc1d..eb920aaa20 100644 --- a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.test.tsx +++ b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.test.tsx @@ -43,7 +43,12 @@ describe('ComponentContextMenu', () => { it('should call onUnregisterEntity on button click', async () => { const mockCallback = jest.fn(); - await render(); + await render( + {}} + />, + ); const button = await screen.findByTestId('menu-button'); expect(button).toBeInTheDocument(); @@ -56,6 +61,27 @@ describe('ComponentContextMenu', () => { expect(mockCallback).toBeCalled(); }); + it('should call onInspectEntity on button click', async () => { + const mockCallback = jest.fn(); + + await render( + {}} + onInspectEntity={mockCallback} + />, + ); + + const button = await screen.findByTestId('menu-button'); + expect(button).toBeInTheDocument(); + fireEvent.click(button); + + const unregister = await screen.findByText('Inspect entity'); + expect(unregister).toBeInTheDocument(); + fireEvent.click(unregister); + + expect(mockCallback).toBeCalled(); + }); + it('supports extra items', async () => { const extra = { title: 'HELLO', @@ -66,6 +92,7 @@ describe('ComponentContextMenu', () => { await render( , ); diff --git a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx index 6648514382..7bda1f4629 100644 --- a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx +++ b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx @@ -24,7 +24,8 @@ import { Popover, } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; -import Cancel from '@material-ui/icons/Cancel'; +import CancelIcon from '@material-ui/icons/Cancel'; +import BugReportIcon from '@material-ui/icons/BugReport'; import MoreVert from '@material-ui/icons/MoreVert'; import React, { useState } from 'react'; import { IconComponent } from '@backstage/core-plugin-api'; @@ -55,12 +56,14 @@ type Props = { UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[]; UNSTABLE_contextMenuOptions?: contextMenuOptions; onUnregisterEntity: () => void; + onInspectEntity: () => void; }; export const EntityContextMenu = ({ UNSTABLE_extraContextMenuItems, UNSTABLE_contextMenuOptions, onUnregisterEntity, + onInspectEntity, }: Props) => { const [anchorEl, setAnchorEl] = useState(); const classes = useStyles(); @@ -128,10 +131,21 @@ export const EntityContextMenu = ({ disabled={disableUnregister} > - + + { + onClose(); + onInspectEntity(); + }} + > + + + + + diff --git a/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx b/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx index c5679355e5..144e5d01a8 100644 --- a/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx +++ b/plugins/catalog/src/components/EntityLayout/EntityLayout.tsx @@ -39,13 +39,14 @@ import { EntityRefLinks, FavoriteEntity, getEntityRelations, + InspectEntityDialog, UnregisterEntityDialog, useEntityCompoundName, } from '@backstage/plugin-catalog-react'; import { Box, TabProps } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; -import React, { useContext, useState } from 'react'; -import { useNavigate } from 'react-router'; +import React, { useContext, useEffect, useState } from 'react'; +import { useLocation, useNavigate } from 'react-router'; import { EntityContextMenu } from '../EntityContextMenu/EntityContextMenu'; type SubRoute = { @@ -177,6 +178,7 @@ export const EntityLayout = ({ }: EntityLayoutProps) => { const { kind, namespace, name } = useEntityCompoundName(); const { entity, loading, error } = useContext(EntityContext); + const location = useLocation(); const routes = useElementFilter( children, elements => @@ -212,13 +214,21 @@ export const EntityLayout = ({ ); const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); + const [inspectionDialogOpen, setInspectionDialogOpen] = useState(false); const navigate = useNavigate(); const cleanUpAfterRemoval = async () => { setConfirmationDialogOpen(false); + setInspectionDialogOpen(false); navigate('/'); }; - const showRemovalDialog = () => setConfirmationDialogOpen(true); + // Make sure to close the dialog if the user clicks links in it that navigate + // to another entity. + useEffect(() => { + setConfirmationDialogOpen(false); + setInspectionDialogOpen(false); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [location.pathname]); return ( @@ -233,7 +243,8 @@ export const EntityLayout = ({ setConfirmationDialogOpen(true)} + onInspectEntity={() => setInspectionDialogOpen(true)} /> )} @@ -267,6 +278,11 @@ export const EntityLayout = ({ onConfirm={cleanUpAfterRemoval} onClose={() => setConfirmationDialogOpen(false)} /> + setInspectionDialogOpen(false)} + /> ); }; diff --git a/plugins/catalog/src/components/EntityPageLayout/EntityPageLayout.tsx b/plugins/catalog/src/components/EntityPageLayout/EntityPageLayout.tsx index c371d6245e..82a980afcb 100644 --- a/plugins/catalog/src/components/EntityPageLayout/EntityPageLayout.tsx +++ b/plugins/catalog/src/components/EntityPageLayout/EntityPageLayout.tsx @@ -23,6 +23,7 @@ import { EntityRefLinks, FavoriteEntity, getEntityRelations, + InspectEntityDialog, UnregisterEntityDialog, useEntityCompoundName, } from '@backstage/plugin-catalog-react'; @@ -123,6 +124,11 @@ type EntityPageLayoutProps = { children?: React.ReactNode; }; +/** + * Old entity page, only used by the old router based hierarchies. + * + * @deprecated Please use CatalogEntityPage instead + */ export const EntityPageLayout = ({ children, UNSTABLE_extraContextMenuItems, @@ -138,14 +144,13 @@ export const EntityPageLayout = ({ ); const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); + const [inspectionDialogOpen, setInspectionDialogOpen] = useState(false); const navigate = useNavigate(); const cleanUpAfterRemoval = async () => { setConfirmationDialogOpen(false); navigate('/'); }; - const showRemovalDialog = () => setConfirmationDialogOpen(true); - return (
setConfirmationDialogOpen(true)} + onInspectEntity={() => setInspectionDialogOpen(true)} /> )} @@ -198,6 +204,11 @@ export const EntityPageLayout = ({ onConfirm={cleanUpAfterRemoval} onClose={() => setConfirmationDialogOpen(false)} /> + setInspectionDialogOpen(false)} + /> ); }; diff --git a/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx b/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx index ae5a4684b1..2297493a7a 100644 --- a/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx +++ b/plugins/catalog/src/components/EntityProcessingErrorsPanel/EntityProcessingErrorsPanel.test.tsx @@ -14,18 +14,17 @@ * limitations under the License. */ +import { AlphaEntity, stringifyEntityRef } from '@backstage/catalog-model'; +import { ApiProvider } from '@backstage/core-app-api'; import { CatalogApi, catalogApiRef, EntityProvider, entityRouteRef, } from '@backstage/plugin-catalog-react'; - import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; import React from 'react'; import { EntityProcessingErrorsPanel } from './EntityProcessingErrorsPanel'; -import { AlphaEntity, getEntityName } from '@backstage/catalog-model'; -import { ApiProvider } from '@backstage/core-app-api'; describe('', () => { const getEntityAncestors: jest.MockedFunction< @@ -98,8 +97,8 @@ describe('', () => { }; getEntityAncestors.mockResolvedValue({ - root: getEntityName(entity), - items: [{ entity, parents: [] }], + rootEntityRef: stringifyEntityRef(entity), + items: [{ entity, parentEntityRefs: [] }], }); const { getByText, queryByText } = await renderInTestApp( @@ -199,10 +198,10 @@ describe('', () => { }, }; getEntityAncestors.mockResolvedValue({ - root: getEntityName(entity), + rootEntityRef: stringifyEntityRef(entity), items: [ - { entity, parents: [getEntityName(parent)] }, - { entity: parent, parents: [] }, + { entity, parentEntityRefs: [stringifyEntityRef(parent)] }, + { entity: parent, parentEntityRefs: [] }, ], }); const { getByText, queryByText } = await renderInTestApp( From b04ef1e4255fb96b62519c9cdc8ff06ff364969a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 7 Feb 2022 10:38:57 +0100 Subject: [PATCH 02/51] add some tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../components/AncestryPage.tsx | 21 +++++---- .../components/JsonPage.test.tsx | 45 +++++++++++++++++++ .../components/JsonPage.tsx | 2 +- .../components/YamlPage.test.tsx | 45 +++++++++++++++++++ .../components/YamlPage.tsx | 2 +- 5 files changed, 102 insertions(+), 13 deletions(-) create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.test.tsx create mode 100644 plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.test.tsx diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx index cab6faff0e..b27bbe3948 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx @@ -27,7 +27,7 @@ import { ResponseErrorPanel, } from '@backstage/core-components'; import { useApi, useRouteRef } from '@backstage/core-plugin-api'; -import { DialogContentText, makeStyles } from '@material-ui/core'; +import { Box, DialogContentText, makeStyles } from '@material-ui/core'; import classNames from 'classnames'; import React, { useLayoutEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router'; @@ -148,7 +148,6 @@ function CustomNode({ node }: DependencyGraphTypes.RenderNodeProps) { }), ); }; - const focused = false; return ( @@ -169,7 +168,6 @@ function CustomNode({ node }: DependencyGraphTypes.RenderNodeProps) { height={iconSize} className={classNames( classes.text, - focused && 'focused', node.root ? 'secondary' : 'primary', )} /> @@ -177,7 +175,6 @@ function CustomNode({ node }: DependencyGraphTypes.RenderNodeProps) { ref={idRef} className={classNames( classes.text, - focused && 'focused', node.root ? 'secondary' : 'primary', )} y={paddedHeight / 2} @@ -211,13 +208,15 @@ export function AncestryPage(props: { entity: Entity }) { child entities that ultimately led to the current one existing. Note that this is a completely different mechanism from relations. - + + + ); } diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.test.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.test.tsx new file mode 100644 index 0000000000..83888a867f --- /dev/null +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.test.tsx @@ -0,0 +1,45 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ComponentEntity } from '@backstage/catalog-model'; +import { renderInTestApp } from '@backstage/test-utils'; +import { screen } from '@testing-library/react'; +import React from 'react'; +import { JsonPage } from './JsonPage'; + +describe('JsonPage', () => { + it('renders', async () => { + const entity: ComponentEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'c1', + }, + spec: { + type: 'service', + lifecycle: 'production', + owner: 'ops', + }, + }; + + await renderInTestApp(); + + expect(screen.getByTestId('code-snippet')).toHaveTextContent( + '"lifecycle": "production"', + ); + }); +}); diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx index cee350f62a..44dd626963 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx @@ -28,7 +28,7 @@ export function JsonPage(props: { entity: Entity }) { This is the raw entity data as received from the catalog, on JSON form. -
+
{ + it('renders', async () => { + const entity: ComponentEntity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + namespace: 'default', + name: 'c1', + }, + spec: { + type: 'service', + lifecycle: 'production', + owner: 'ops', + }, + }; + + await renderInTestApp(); + + expect(screen.getByTestId('code-snippet')).toHaveTextContent( + 'lifecycle: production', + ); + }); +}); diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx index c876fe9edd..ad74611ec5 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx @@ -29,7 +29,7 @@ export function YamlPage(props: { entity: Entity }) { This is the raw entity data as received from the catalog, on YAML form. -
+
Date: Mon, 7 Feb 2022 13:36:30 +0100 Subject: [PATCH 03/51] review comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/ten-geese-hide.md | 5 +++++ .../components/InspectEntityDialog/InspectEntityDialog.tsx | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/ten-geese-hide.md diff --git a/.changeset/ten-geese-hide.md b/.changeset/ten-geese-hide.md new file mode 100644 index 0000000000..c2386fc44f --- /dev/null +++ b/.changeset/ten-geese-hide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Deprecated the `EntityPageLayout`; please use the new extension based `CatalogEntityPage` instead diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx index 2e904e4eb9..bfb5fd4179 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx @@ -55,8 +55,8 @@ const useStyles = makeStyles(theme => ({ function TabPanel(props: { children?: React.ReactNode; - index: any; - value: any; + index: number; + value: number; }) { const { children, value, index, ...other } = props; const classes = useStyles(); From 0d181683e841d817a18475a056c0707bd12d9318 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Feb 2022 00:53:49 +0000 Subject: [PATCH 04/51] chore(deps-dev): bump @types/react from 16.14.18 to 17.0.39 Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 16.14.18 to 17.0.39. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: "@types/react" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 354559cc6a..b6aa763360 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6062,9 +6062,9 @@ "@types/react" "*" "@types/react@*", "@types/react@>=16.9.0", "@types/react@^16.13.1 || ^17.0.0": - version "16.14.18" - resolved "https://registry.npmjs.org/@types/react/-/react-16.14.18.tgz#b2bcea05ee244fde92d409f91bd888ca8e54b20f" - integrity sha512-eeyqd1mqoG43mI0TvNKy9QNf1Tjz3DEOsRP3rlPo35OeMIt05I+v9RR8ZvL2GuYZeF2WAcLXJZMzu6zdz3VbtQ== + version "17.0.39" + resolved "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz#d0f4cde092502a6db00a1cded6e6bf2abb7633ce" + integrity sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" From 6bc86fcf2dabc9b2f329e1bd3dc22dc1366a5b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 8 Feb 2022 11:25:13 +0100 Subject: [PATCH 05/51] make IdentityClient.listPublicKeys private MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/giant-nails-grow.md | 5 +++++ plugins/auth-backend/api-report.md | 4 ---- plugins/auth-backend/src/identity/IdentityClient.test.ts | 4 ++-- plugins/auth-backend/src/identity/IdentityClient.ts | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 .changeset/giant-nails-grow.md diff --git a/.changeset/giant-nails-grow.md b/.changeset/giant-nails-grow.md new file mode 100644 index 0000000000..c715f78d5c --- /dev/null +++ b/.changeset/giant-nails-grow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': minor +--- + +Made `IdentityClient.listPublicKeys` private. It was only used in tests, and should not be part of the API surface of that class. The interface is marked as experimental, and therefore this is a breaking change without a deprecation period. diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index aaacd05815..09f1c5185e 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -10,7 +10,6 @@ import { Config } from '@backstage/config'; import { Entity } from '@backstage/catalog-model'; import express from 'express'; import { JsonValue } from '@backstage/types'; -import { JSONWebKey } from 'jose'; import { Logger as Logger_2 } from 'winston'; import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; @@ -432,9 +431,6 @@ export class IdentityClient { static getBearerToken( authorizationHeader: string | undefined, ): string | undefined; - listPublicKeys(): Promise<{ - keys: JSONWebKey[]; - }>; } // Warning: (ae-missing-release-tag) "microsoftEmailSignInResolver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/auth-backend/src/identity/IdentityClient.test.ts b/plugins/auth-backend/src/identity/IdentityClient.test.ts index 9f5e1ce489..da7a8e7dce 100644 --- a/plugins/auth-backend/src/identity/IdentityClient.test.ts +++ b/plugins/auth-backend/src/identity/IdentityClient.test.ts @@ -83,7 +83,7 @@ describe('IdentityClient', () => { it('should use the correct endpoint', async () => { await factory.issueToken({ claims: { sub: 'foo' } }); const keys = await factory.listPublicKeys(); - const response = await client.listPublicKeys(); + const response = await (client as any).listPublicKeys(); expect(response).toEqual(keys); }); @@ -257,7 +257,7 @@ describe('IdentityClient', () => { }); it('should use the correct endpoint', async () => { - const response = await client.listPublicKeys(); + const response = await (client as any).listPublicKeys(); expect(response).toEqual(defaultServiceResponse); }); }); diff --git a/plugins/auth-backend/src/identity/IdentityClient.ts b/plugins/auth-backend/src/identity/IdentityClient.ts index 552d231e1f..810ae56722 100644 --- a/plugins/auth-backend/src/identity/IdentityClient.ts +++ b/plugins/auth-backend/src/identity/IdentityClient.ts @@ -125,7 +125,7 @@ export class IdentityClient { /** * Lists public part of keys used to sign Backstage Identity tokens */ - async listPublicKeys(): Promise<{ + private async listPublicKeys(): Promise<{ keys: JSONWebKey[]; }> { const url = `${await this.discovery.getBaseUrl( From 9058bb1b5e4683f25098482c27e531f038ee40eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 8 Feb 2022 11:26:33 +0100 Subject: [PATCH 06/51] add empty @backstage/plugin-auth-node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/famous-hats-decide.md | 6 ++++++ plugins/auth-node/.eslintrc.js | 3 +++ plugins/auth-node/README.md | 3 +++ plugins/auth-node/api-report.md | 8 ++++++++ plugins/auth-node/package.json | 32 +++++++++++++++++++++++++++++ plugins/auth-node/src/index.ts | 28 +++++++++++++++++++++++++ plugins/auth-node/src/setupTests.ts | 17 +++++++++++++++ scripts/api-extractor.ts | 1 + 8 files changed, 98 insertions(+) create mode 100644 .changeset/famous-hats-decide.md create mode 100644 plugins/auth-node/.eslintrc.js create mode 100644 plugins/auth-node/README.md create mode 100644 plugins/auth-node/api-report.md create mode 100644 plugins/auth-node/package.json create mode 100644 plugins/auth-node/src/index.ts create mode 100644 plugins/auth-node/src/setupTests.ts diff --git a/.changeset/famous-hats-decide.md b/.changeset/famous-hats-decide.md new file mode 100644 index 0000000000..e6f3a4bd5a --- /dev/null +++ b/.changeset/famous-hats-decide.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-auth-node': minor +--- + +Added this package, to hold shared types and functionality that other backend +packages need to import. diff --git a/plugins/auth-node/.eslintrc.js b/plugins/auth-node/.eslintrc.js new file mode 100644 index 0000000000..16a033dbc6 --- /dev/null +++ b/plugins/auth-node/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint.backend')], +}; diff --git a/plugins/auth-node/README.md b/plugins/auth-node/README.md new file mode 100644 index 0000000000..3558e031b2 --- /dev/null +++ b/plugins/auth-node/README.md @@ -0,0 +1,3 @@ +# Auth Node + +Common functionality and types for the Backstage `auth` plugin. diff --git a/plugins/auth-node/api-report.md b/plugins/auth-node/api-report.md new file mode 100644 index 0000000000..bbbf455b18 --- /dev/null +++ b/plugins/auth-node/api-report.md @@ -0,0 +1,8 @@ +## API Report File for "@backstage/plugin-auth-node" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +// @public +export const COMMON_CONSTANT = 1; +``` diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json new file mode 100644 index 0000000000..3231c6993e --- /dev/null +++ b/plugins/auth-node/package.json @@ -0,0 +1,32 @@ +{ + "name": "@backstage/plugin-auth-node", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": false, + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "scripts": { + "build": "backstage-cli backend:build", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/backend-common": "^0.10.6", + "@backstage/config": "^0.1.13", + "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/cli": "^0.13.1" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/auth-node/src/index.ts b/plugins/auth-node/src/index.ts new file mode 100644 index 0000000000..04d073a748 --- /dev/null +++ b/plugins/auth-node/src/index.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Common functionality and types for the Backstage auth plugin. + * + * @packageDocumentation + */ + +/** + * Dummy. + * + * @public + */ +export const COMMON_CONSTANT = 1; diff --git a/plugins/auth-node/src/setupTests.ts b/plugins/auth-node/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/auth-node/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export {}; diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 808af8754d..f026adbc9b 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -218,6 +218,7 @@ const NO_WARNING_PACKAGES = [ 'packages/types', 'packages/release-manifests', 'packages/version-bridge', + 'plugins/auth-node', 'plugins/catalog-backend-module-ldap', 'plugins/catalog-backend-module-msgraph', 'plugins/catalog-common', From b3f3e420363c6e795af5846ae91bf2236f43eaf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 8 Feb 2022 12:25:27 +0100 Subject: [PATCH 07/51] move `IdentityClient.getBearerToken` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/giant-nails-grow.md | 8 ++- .changeset/little-onions-fly.md | 6 +++ plugins/auth-backend/api-report.md | 3 -- plugins/auth-backend/package.json | 1 + .../src/identity/IdentityClient.test.ts | 32 ------------ .../src/identity/IdentityClient.ts | 14 ------ .../src/providers/oauth2-proxy/provider.ts | 4 +- plugins/auth-node/api-report.md | 4 +- plugins/auth-node/package.json | 4 +- ...BearerTokenFromAuthorizationHeader.test.ts | 50 +++++++++++++++++++ .../getBearerTokenFromAuthorizationHeader.ts | 37 ++++++++++++++ plugins/auth-node/src/index.ts | 7 +-- plugins/permission-backend/package.json | 1 + .../permission-backend/src/service/router.ts | 5 +- plugins/search-backend/package.json | 2 +- plugins/search-backend/src/service/router.ts | 6 ++- 16 files changed, 119 insertions(+), 65 deletions(-) create mode 100644 .changeset/little-onions-fly.md create mode 100644 plugins/auth-node/src/getBearerTokenFromAuthorizationHeader.test.ts create mode 100644 plugins/auth-node/src/getBearerTokenFromAuthorizationHeader.ts diff --git a/.changeset/giant-nails-grow.md b/.changeset/giant-nails-grow.md index c715f78d5c..bed8c422aa 100644 --- a/.changeset/giant-nails-grow.md +++ b/.changeset/giant-nails-grow.md @@ -2,4 +2,10 @@ '@backstage/plugin-auth-backend': minor --- -Made `IdentityClient.listPublicKeys` private. It was only used in tests, and should not be part of the API surface of that class. The interface is marked as experimental, and therefore this is a breaking change without a deprecation period. +- Made `IdentityClient.listPublicKeys` private. It was only used in tests, and + should not be part of the API surface of that class. +- Removed the static `IdentityClient.getBearerToken`. It is now replaced by + `getBearerTokenFromAuthorizationHeader` from `@backstage/plugin-auth-node`. + +Since the `IdentityClient` interface is marked as experimental, this is a +breaking change without a deprecation period. diff --git a/.changeset/little-onions-fly.md b/.changeset/little-onions-fly.md new file mode 100644 index 0000000000..8bff96d866 --- /dev/null +++ b/.changeset/little-onions-fly.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-permission-backend': patch +'@backstage/plugin-search-backend': patch +--- + +Use `getBearerTokenFromAuthorizationHeader` from `@backstage/plugin-auth-node` instead of the deprecated `IdentityClient` method. diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index 09f1c5185e..6a77f1a7cf 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -428,9 +428,6 @@ export type GoogleProviderOptions = { export class IdentityClient { constructor(options: { discovery: PluginEndpointDiscovery; issuer: string }); authenticate(token: string | undefined): Promise; - static getBearerToken( - authorizationHeader: string | undefined, - ): string | undefined; } // Warning: (ae-missing-release-tag) "microsoftEmailSignInResolver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 3dab33d8da..4f2ef4e76c 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -30,6 +30,7 @@ "clean": "backstage-cli clean" }, "dependencies": { + "@backstage/plugin-auth-node": "^0.0.0", "@backstage/backend-common": "^0.10.7-next.0", "@backstage/catalog-client": "^0.5.5", "@backstage/catalog-model": "^0.9.10", diff --git a/plugins/auth-backend/src/identity/IdentityClient.test.ts b/plugins/auth-backend/src/identity/IdentityClient.test.ts index da7a8e7dce..cf60fd0852 100644 --- a/plugins/auth-backend/src/identity/IdentityClient.test.ts +++ b/plugins/auth-backend/src/identity/IdentityClient.test.ts @@ -199,38 +199,6 @@ describe('IdentityClient', () => { }); }); - describe('getBearerToken', () => { - it('should return undefined on undefined input', async () => { - const token = IdentityClient.getBearerToken(undefined); - expect(token).toBeUndefined(); - }); - - it('should return undefined on malformed input', async () => { - const token = IdentityClient.getBearerToken('malformed'); - expect(token).toBeUndefined(); - }); - - it('should return undefined on unexpected scheme', async () => { - const token = IdentityClient.getBearerToken('Basic token'); - expect(token).toBeUndefined(); - }); - - it('should return Bearer token', async () => { - const token = IdentityClient.getBearerToken('Bearer token'); - expect(token).toEqual('token'); - }); - - it('should return Bearer token despite extra space', async () => { - const token = IdentityClient.getBearerToken('Bearer \n token '); - expect(token).toEqual('token'); - }); - - it('should return Bearer token despite unconventionial case', async () => { - const token = IdentityClient.getBearerToken('bEARER token'); - expect(token).toEqual('token'); - }); - }); - describe('listPublicKeys', () => { const defaultServiceResponse: { keys: JSONWebKey[]; diff --git a/plugins/auth-backend/src/identity/IdentityClient.ts b/plugins/auth-backend/src/identity/IdentityClient.ts index 810ae56722..5fbd126cdf 100644 --- a/plugins/auth-backend/src/identity/IdentityClient.ts +++ b/plugins/auth-backend/src/identity/IdentityClient.ts @@ -84,20 +84,6 @@ export class IdentityClient { return user; } - /** - * Parses the given authorization header and returns - * the bearer token, or null if no bearer token is given - */ - static getBearerToken( - authorizationHeader: string | undefined, - ): string | undefined { - if (typeof authorizationHeader !== 'string') { - return undefined; - } - const matches = authorizationHeader.match(/Bearer\s+(\S+)/i); - return matches?.[1]; - } - /** * Returns the public signing key matching the given jwt token, * or null if no matching key was found diff --git a/plugins/auth-backend/src/providers/oauth2-proxy/provider.ts b/plugins/auth-backend/src/providers/oauth2-proxy/provider.ts index 24bb4d0362..8c4dcc3249 100644 --- a/plugins/auth-backend/src/providers/oauth2-proxy/provider.ts +++ b/plugins/auth-backend/src/providers/oauth2-proxy/provider.ts @@ -17,6 +17,7 @@ import express from 'express'; import { Logger } from 'winston'; import { AuthenticationError } from '@backstage/errors'; +import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { AuthHandler, SignInResolver, @@ -26,7 +27,6 @@ import { } from '../types'; import { CatalogIdentityClient } from '../../lib/catalog'; import { JWT } from 'jose'; -import { IdentityClient } from '../../identity'; import { TokenIssuer } from '../../identity/types'; import { prepareBackstageIdentityResponse } from '../prepareBackstageIdentityResponse'; @@ -156,7 +156,7 @@ export class Oauth2ProxyAuthProvider private getResult(req: express.Request): OAuth2ProxyResult { const authHeader = req.header(OAUTH2_PROXY_JWT_HEADER); - const jwt = IdentityClient.getBearerToken(authHeader); + const jwt = getBearerTokenFromAuthorizationHeader(authHeader); if (!jwt) { throw new AuthenticationError( diff --git a/plugins/auth-node/api-report.md b/plugins/auth-node/api-report.md index bbbf455b18..e32a35880b 100644 --- a/plugins/auth-node/api-report.md +++ b/plugins/auth-node/api-report.md @@ -4,5 +4,7 @@ ```ts // @public -export const COMMON_CONSTANT = 1; +export function getBearerTokenFromAuthorizationHeader( + authorizationHeader: unknown, +): string | undefined; ``` diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 3231c6993e..7e4b4bfe77 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -19,12 +19,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.6", + "@backstage/backend-common": "^0.10.7-next.0", "@backstage/config": "^0.1.13", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.13.1" + "@backstage/cli": "^0.13.2-next.0" }, "files": [ "dist" diff --git a/plugins/auth-node/src/getBearerTokenFromAuthorizationHeader.test.ts b/plugins/auth-node/src/getBearerTokenFromAuthorizationHeader.test.ts new file mode 100644 index 0000000000..0bd7b5ea93 --- /dev/null +++ b/plugins/auth-node/src/getBearerTokenFromAuthorizationHeader.test.ts @@ -0,0 +1,50 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getBearerTokenFromAuthorizationHeader } from './getBearerTokenFromAuthorizationHeader'; + +describe('getBearerToken', () => { + it('should return undefined on bad input', async () => { + expect(getBearerTokenFromAuthorizationHeader(undefined)).toBeUndefined(); + expect(getBearerTokenFromAuthorizationHeader(7)).toBeUndefined(); + expect( + getBearerTokenFromAuthorizationHeader('Bearer \n token'), + ).toBeUndefined(); + expect( + getBearerTokenFromAuthorizationHeader('Bearer token '), + ).toBeUndefined(); + }); + + it('should return undefined on malformed input', async () => { + const token = getBearerTokenFromAuthorizationHeader('malformed'); + expect(token).toBeUndefined(); + }); + + it('should return undefined on unexpected scheme', async () => { + const token = getBearerTokenFromAuthorizationHeader('Basic token'); + expect(token).toBeUndefined(); + }); + + it('should return Bearer token', async () => { + const token = getBearerTokenFromAuthorizationHeader('Bearer token'); + expect(token).toEqual('token'); + }); + + it('should return Bearer token despite unconventional case', async () => { + const token = getBearerTokenFromAuthorizationHeader('bEARER token'); + expect(token).toEqual('token'); + }); +}); diff --git a/plugins/auth-node/src/getBearerTokenFromAuthorizationHeader.ts b/plugins/auth-node/src/getBearerTokenFromAuthorizationHeader.ts new file mode 100644 index 0000000000..8451cd6ab1 --- /dev/null +++ b/plugins/auth-node/src/getBearerTokenFromAuthorizationHeader.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Parses the given authorization header and returns the bearer token, or + * undefined if no bearer token is given. + * + * @remarks + * + * This function is explicitly built to tolerate bad inputs safely, so you may + * call it directly with e.g. the output of `req.header('authorization')` + * without first checking that it exists. + * + * @public + */ +export function getBearerTokenFromAuthorizationHeader( + authorizationHeader: unknown, +): string | undefined { + if (typeof authorizationHeader !== 'string') { + return undefined; + } + const matches = authorizationHeader.match(/^Bearer[ ]+(\S+)$/i); + return matches?.[1]; +} diff --git a/plugins/auth-node/src/index.ts b/plugins/auth-node/src/index.ts index 04d073a748..83037f75be 100644 --- a/plugins/auth-node/src/index.ts +++ b/plugins/auth-node/src/index.ts @@ -20,9 +20,4 @@ * @packageDocumentation */ -/** - * Dummy. - * - * @public - */ -export const COMMON_CONSTANT = 1; +export { getBearerTokenFromAuthorizationHeader } from './getBearerTokenFromAuthorizationHeader'; diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index bc6faae17b..9ee959243d 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -23,6 +23,7 @@ "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", "@backstage/plugin-auth-backend": "^0.10.0-next.0", + "@backstage/plugin-auth-node": "^0.0.0", "@backstage/plugin-permission-common": "^0.4.0", "@backstage/plugin-permission-node": "^0.4.3-next.0", "@types/express": "*", diff --git a/plugins/permission-backend/src/service/router.ts b/plugins/permission-backend/src/service/router.ts index e22aec8129..10a70b01db 100644 --- a/plugins/permission-backend/src/service/router.ts +++ b/plugins/permission-backend/src/service/router.ts @@ -27,6 +27,7 @@ import { BackstageIdentityResponse, IdentityClient, } from '@backstage/plugin-auth-backend'; +import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { AuthorizeResult, AuthorizeDecision, @@ -157,7 +158,9 @@ export async function createRouter( req: Request, res: Response, ) => { - const token = IdentityClient.getBearerToken(req.header('authorization')); + const token = getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ); const user = token ? await identity.authenticate(token) : undefined; const parseResult = requestSchema.safeParse(req.body); diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index ee064851fa..3770dbd875 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -24,7 +24,7 @@ "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", "@backstage/search-common": "^0.2.2", - "@backstage/plugin-auth-backend": "^0.10.0-next.0", + "@backstage/plugin-auth-node": "^0.0.0", "@backstage/plugin-permission-common": "^0.4.0-next.0", "@backstage/plugin-permission-node": "^0.4.3-next.0", "@backstage/plugin-search-backend-node": "^0.4.5", diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index 28a3247919..3f25c4f24a 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -22,7 +22,7 @@ import { errorHandler } from '@backstage/backend-common'; import { InputError } from '@backstage/errors'; import { Config } from '@backstage/config'; import { JsonObject, JsonValue } from '@backstage/types'; -import { IdentityClient } from '@backstage/plugin-auth-backend'; +import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; import { DocumentTypeInfo, SearchResultSet } from '@backstage/search-common'; import { SearchEngine } from '@backstage/plugin-search-backend-node'; @@ -106,7 +106,9 @@ export async function createRouter( }, pageCursor=${query.pageCursor ?? ''}`, ); - const token = IdentityClient.getBearerToken(req.header('authorization')); + const token = getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ); try { const resultSet = await engine?.query(query, { token }); From 9643f75a1197e02efaa24d755dc058c46f6bd007 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 9 Feb 2022 14:29:47 +0100 Subject: [PATCH 08/51] chore: added guards as these could be string types which don't have props... Signed-off-by: blam --- .../core-components/src/layout/TabbedCard/TabbedCard.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx b/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx index 06e9f53224..b3b977f04b 100644 --- a/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx +++ b/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx @@ -89,12 +89,15 @@ export function TabbedCard(props: PropsWithChildren) { let selectedTabContent: ReactNode; if (!value) { React.Children.map(children, (child, index) => { - if (index === selectedIndex) selectedTabContent = child?.props.children; + if (React.isValidElement(child) && index === selectedIndex) { + selectedTabContent = child?.props.children; + } }); } else { React.Children.map(children, child => { - if (child?.props.value === value) + if (React.isValidElement(child) && child?.props.value === value) { selectedTabContent = child?.props.children; + } }); } From 89c84b9108e0e46ee8426271f800ad9e26d050d2 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 9 Feb 2022 14:31:24 +0100 Subject: [PATCH 09/51] chore: added changeset for r17 issues Signed-off-by: blam --- .changeset/tall-elephants-smash.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tall-elephants-smash.md diff --git a/.changeset/tall-elephants-smash.md b/.changeset/tall-elephants-smash.md new file mode 100644 index 0000000000..a26dbd65a6 --- /dev/null +++ b/.changeset/tall-elephants-smash.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +chore: fixing typescript errors for `TabbedCard.tsx` for React 17.x From 8928dea8f663ae3a024782995cf9f6a10fe39dc9 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 9 Feb 2022 15:36:05 +0100 Subject: [PATCH 10/51] core-components: update Button and Link doc workarounds Signed-off-by: Patrik Oldsberg --- .../src/components/Button/Button.tsx | 28 ++++++------------- .../src/components/Link/Link.tsx | 13 ++------- 2 files changed, 11 insertions(+), 30 deletions(-) diff --git a/packages/core-components/src/components/Button/Button.tsx b/packages/core-components/src/components/Button/Button.tsx index 81c8ee28a5..d7d3c192a4 100644 --- a/packages/core-components/src/components/Button/Button.tsx +++ b/packages/core-components/src/components/Button/Button.tsx @@ -31,6 +31,13 @@ import { Link, LinkProps } from '../Link'; export type ButtonProps = MaterialButtonProps & Omit; +/** + * This wrapper is here to reset the color of the Link and make typescript happy. + */ +const LinkWrapper = React.forwardRef((props, ref) => ( + +)); + /** * Thin wrapper on top of material-ui's {@link https://v4.mui.com/components/buttons/ | Button} component * @@ -39,23 +46,6 @@ export type ButtonProps = MaterialButtonProps & * * Makes the Button to utilise react-router */ -declare function ButtonType(props: ButtonProps): JSX.Element; - -/** - * This wrapper is here to reset the color of the Link and make typescript happy. - */ -const LinkWrapper = React.forwardRef((props, ref) => ( - -)); - -/** @public */ -const ActualButton = React.forwardRef((props, ref) => ( +export const Button = React.forwardRef((props, ref) => ( -)) as { (props: ButtonProps): JSX.Element }; - -// TODO(Rugvip): We use this as a workaround to make the exported type be a -// function, which makes our API reference docs much nicer. -// The first type to be exported gets priority, but it will -// be thrown away when compiling to JS. -// @ts-ignore -export { ButtonType as Button, ActualButton as Button }; +)) as (props: ButtonProps) => JSX.Element; diff --git a/packages/core-components/src/components/Link/Link.tsx b/packages/core-components/src/components/Link/Link.tsx index 30796c4e05..a1af06ae3b 100644 --- a/packages/core-components/src/components/Link/Link.tsx +++ b/packages/core-components/src/components/Link/Link.tsx @@ -32,8 +32,6 @@ export type LinkProps = MaterialLinkProps & noTrack?: boolean; }; -declare function LinkType(props: LinkProps): JSX.Element; - /** * Given a react node, try to retrieve its text content. */ @@ -62,7 +60,7 @@ const getNodeText = (node: React.ReactNode): string => { * - Makes the Link use react-router * - Captures Link clicks as analytics events. */ -const ActualLink = React.forwardRef( +export const Link = React.forwardRef( ({ onClick, noTrack, ...props }, ref) => { const analytics = useAnalytics(); const to = String(props.to); @@ -96,11 +94,4 @@ const ActualLink = React.forwardRef( /> ); }, -); - -// TODO(Rugvip): We use this as a workaround to make the exported type be a -// function, which makes our API reference docs much nicer. -// The first type to be exported gets priority, but it will -// be thrown away when compiling to JS. -// @ts-ignore -export { LinkType as Link, ActualLink as Link }; +) as (props: LinkProps) => JSX.Element; From e58af60d262c7b670f6b5f3f2db86094be68c85c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 9 Feb 2022 16:57:45 +0100 Subject: [PATCH 11/51] core-components: explicit types for styled components Signed-off-by: Patrik Oldsberg --- .../core-components/src/layout/Sidebar/Items.tsx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/core-components/src/layout/Sidebar/Items.tsx b/packages/core-components/src/layout/Sidebar/Items.tsx index fc97fdc0ce..239963ab2b 100644 --- a/packages/core-components/src/layout/Sidebar/Items.tsx +++ b/packages/core-components/src/layout/Sidebar/Items.tsx @@ -21,13 +21,18 @@ import useMediaQuery from '@material-ui/core/useMediaQuery'; import Badge from '@material-ui/core/Badge'; import TextField from '@material-ui/core/TextField'; import Typography from '@material-ui/core/Typography'; -import { CreateCSSProperties } from '@material-ui/core/styles/withStyles'; +import { + CreateCSSProperties, + StyledComponentProps, +} from '@material-ui/core/styles/withStyles'; import ArrowRightIcon from '@material-ui/icons/ArrowRight'; import SearchIcon from '@material-ui/icons/Search'; import ArrowDropUp from '@material-ui/icons/ArrowDropUp'; import ArrowDropDown from '@material-ui/icons/ArrowDropDown'; import classnames from 'classnames'; import React, { + ComponentProps, + ComponentType, forwardRef, KeyboardEventHandler, ReactNode, @@ -580,7 +585,7 @@ export const SidebarSpace = styled('div')( flex: 1, }, { name: 'BackstageSidebarSpace' }, -); +) as ComponentType & StyledComponentProps<'root'>>; export type SidebarSpacerClassKey = 'root'; @@ -589,7 +594,7 @@ export const SidebarSpacer = styled('div')( height: 8, }, { name: 'BackstageSidebarSpacer' }, -); +) as ComponentType & StyledComponentProps<'root'>>; export type SidebarDividerClassKey = 'root'; @@ -602,7 +607,7 @@ export const SidebarDivider = styled('hr')( margin: '12px 0px', }, { name: 'BackstageSidebarDivider' }, -); +) as ComponentType & StyledComponentProps<'root'>>; const styledScrollbar = (theme: Theme): CreateCSSProperties => ({ overflowY: 'auto', @@ -631,7 +636,7 @@ export const SidebarScrollWrapper = styled('div')(({ theme }) => { '@media (hover: none)': scrollbarStyles, '&:hover': scrollbarStyles, }; -}); +}) as ComponentType & StyledComponentProps<'root'>>; /** * A button which allows you to expand the sidebar when clicked. From 86b40d464fc71c0fdb3becca964f78cf5c421f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 9 Feb 2022 17:10:18 +0100 Subject: [PATCH 12/51] move over BackstageSignInResult, BackstageIdentityResponse, BackstageUserIdentity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/giant-nails-grow.md | 3 + plugins/auth-backend/api-report.md | 24 +---- .../src/identity/IdentityClient.ts | 2 +- .../src/lib/oauth/OAuthAdapter.ts | 6 +- plugins/auth-backend/src/lib/oauth/types.ts | 7 +- plugins/auth-backend/src/providers/index.ts | 9 +- .../src/providers/oidc/provider.ts | 2 +- .../prepareBackstageIdentityResponse.ts | 7 +- plugins/auth-backend/src/providers/types.ts | 82 ++--------------- plugins/auth-node/api-report.md | 23 +++++ plugins/auth-node/package.json | 1 + plugins/auth-node/src/index.ts | 5 ++ plugins/auth-node/src/types.ts | 88 +++++++++++++++++++ .../permission-backend/src/service/router.ts | 6 +- plugins/permission-node/api-report.md | 2 +- plugins/permission-node/package.json | 2 +- plugins/permission-node/src/policy/types.ts | 2 +- 17 files changed, 149 insertions(+), 122 deletions(-) create mode 100644 plugins/auth-node/src/types.ts diff --git a/.changeset/giant-nails-grow.md b/.changeset/giant-nails-grow.md index bed8c422aa..be4d5793e7 100644 --- a/.changeset/giant-nails-grow.md +++ b/.changeset/giant-nails-grow.md @@ -9,3 +9,6 @@ Since the `IdentityClient` interface is marked as experimental, this is a breaking change without a deprecation period. + +- Moved `BackstageSignInResult`, `BackstageIdentityResponse`, and + `BackstageUserIdentity` to `@backstage/plugin-auth-node`. diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index 6a77f1a7cf..e555eb4a36 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -5,9 +5,10 @@ ```ts /// +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; +import { BackstageSignInResult } from '@backstage/plugin-auth-node'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; -import { Entity } from '@backstage/catalog-model'; import express from 'express'; import { JsonValue } from '@backstage/types'; import { Logger as Logger_2 } from 'winston'; @@ -130,27 +131,6 @@ export type AwsAlbProviderOptions = { // @public @deprecated export type BackstageIdentity = BackstageSignInResult; -// @public -export interface BackstageIdentityResponse extends BackstageSignInResult { - identity: BackstageUserIdentity; -} - -// @public -export interface BackstageSignInResult { - // @deprecated - entity?: Entity; - // @deprecated - id: string; - token: string; -} - -// @public -export type BackstageUserIdentity = { - type: 'user'; - userEntityRef: string; - ownershipEntityRefs: string[]; -}; - // Warning: (ae-missing-release-tag) "BitbucketOAuthResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) diff --git a/plugins/auth-backend/src/identity/IdentityClient.ts b/plugins/auth-backend/src/identity/IdentityClient.ts index 5fbd126cdf..6c6c2ca4b1 100644 --- a/plugins/auth-backend/src/identity/IdentityClient.ts +++ b/plugins/auth-backend/src/identity/IdentityClient.ts @@ -18,7 +18,7 @@ import fetch from 'node-fetch'; import { JWK, JWT, JWKS, JSONWebKey } from 'jose'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { AuthenticationError } from '@backstage/errors'; -import { BackstageIdentityResponse } from '../providers/types'; +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; const CLOCK_MARGIN_S = 10; diff --git a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts index 82a43c7c64..75a3605483 100644 --- a/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts +++ b/plugins/auth-backend/src/lib/oauth/OAuthAdapter.ts @@ -23,10 +23,12 @@ import { stringifyEntityRef, } from '@backstage/catalog-model'; import { - AuthProviderRouteHandlers, - AuthProviderConfig, BackstageIdentityResponse, BackstageSignInResult, +} from '@backstage/plugin-auth-node'; +import { + AuthProviderRouteHandlers, + AuthProviderConfig, } from '../../providers/types'; import { AuthenticationError, diff --git a/plugins/auth-backend/src/lib/oauth/types.ts b/plugins/auth-backend/src/lib/oauth/types.ts index 6973e99569..6e5fe19859 100644 --- a/plugins/auth-backend/src/lib/oauth/types.ts +++ b/plugins/auth-backend/src/lib/oauth/types.ts @@ -16,11 +16,8 @@ import express from 'express'; import { Profile as PassportProfile } from 'passport'; -import { - RedirectInfo, - BackstageSignInResult, - ProfileInfo, -} from '../../providers/types'; +import { BackstageSignInResult } from '@backstage/plugin-auth-node'; +import { RedirectInfo, ProfileInfo } from '../../providers/types'; /** * Common options for passport.js-based OAuth providers diff --git a/plugins/auth-backend/src/providers/index.ts b/plugins/auth-backend/src/providers/index.ts index 1207254e11..37ce09978c 100644 --- a/plugins/auth-backend/src/providers/index.ts +++ b/plugins/auth-backend/src/providers/index.ts @@ -48,13 +48,6 @@ export type { // These types are needed for a postMessage from the login pop-up // to the frontend -export type { - AuthResponse, - BackstageIdentity, - BackstageUserIdentity, - BackstageIdentityResponse, - BackstageSignInResult, - ProfileInfo, -} from './types'; +export type { AuthResponse, BackstageIdentity, ProfileInfo } from './types'; export { prepareBackstageIdentityResponse } from './prepareBackstageIdentityResponse'; diff --git a/plugins/auth-backend/src/providers/oidc/provider.ts b/plugins/auth-backend/src/providers/oidc/provider.ts index e77812e750..9ccdf25f74 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.ts @@ -234,7 +234,7 @@ export const oAuth2DefaultSignInResolver: SignInResolver< * can be passed while creating a OIDC provider. * * authHandler : called after sign in was successful, a new object must be returned which includes a profile - * signInResolver: called after sign in was successful, expects to return a new {@link BackstageSignInResult} + * signInResolver: called after sign in was successful, expects to return a new {@link @backstage/plugin-auth-node#BackstageSignInResult} * * Both options are optional. There is fallback for authHandler where the default handler expect an e-mail explicitly * otherwise it throws an error diff --git a/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.ts b/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.ts index bb99cb3487..f3b234c08e 100644 --- a/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.ts +++ b/plugins/auth-backend/src/providers/prepareBackstageIdentityResponse.ts @@ -19,7 +19,10 @@ import { parseEntityRef, stringifyEntityRef, } from '@backstage/catalog-model'; -import { BackstageIdentityResponse, BackstageSignInResult } from './types'; +import { + BackstageIdentityResponse, + BackstageSignInResult, +} from '@backstage/plugin-auth-node'; function parseJwtPayload(token: string) { const [_header, payload, _signature] = token.split('.'); @@ -28,7 +31,7 @@ function parseJwtPayload(token: string) { /** * Parses a Backstage-issued token and decorates the - * {@link BackstageIdentityResponse} with identity information sourced from the + * {@link @backstage/plugin-auth-node#BackstageIdentityResponse} with identity information sourced from the * token. * * @public diff --git a/plugins/auth-backend/src/providers/types.ts b/plugins/auth-backend/src/providers/types.ts index f3a1a95919..6bef80fd4c 100644 --- a/plugins/auth-backend/src/providers/types.ts +++ b/plugins/auth-backend/src/providers/types.ts @@ -19,8 +19,11 @@ import { TokenManager, } from '@backstage/backend-common'; import { CatalogApi } from '@backstage/catalog-client'; -import { Entity } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; +import { + BackstageIdentityResponse, + BackstageSignInResult, +} from '@backstage/plugin-auth-node'; import express from 'express'; import { Logger } from 'winston'; import { TokenIssuer } from '../identity/types'; @@ -162,84 +165,13 @@ export type AuthResponse = { }; /** - * User identity information within Backstage. + * The old exported symbol for {@link @backstage/plugin-auth-node#BackstageSignInResult}. * * @public - */ -export type BackstageUserIdentity = { - /** - * The type of identity that this structure represents. In the frontend app - * this will currently always be 'user'. - */ - type: 'user'; - - /** - * The entityRef of the user in the catalog. - * For example User:default/sandra - */ - userEntityRef: string; - - /** - * The user and group entities that the user claims ownership through - */ - ownershipEntityRefs: string[]; -}; - -/** - * A representation of a successful Backstage sign-in. - * - * Compared to the {@link BackstageIdentityResponse} this type omits - * the decoded identity information embedded in the token. - * - * @public - */ -export interface BackstageSignInResult { - /** - * An opaque ID that uniquely identifies the user within Backstage. - * - * This is typically the same as the user entity `metadata.name`. - * - * @deprecated Use the `identity` field instead - */ - id: string; - - /** - * The entity that the user is represented by within Backstage. - * - * This entity may or may not exist within the Catalog, and it can be used - * to read and store additional metadata about the user. - * - * @deprecated Use the `identity` field instead. - */ - entity?: Entity; - - /** - * The token used to authenticate the user within Backstage. - */ - token: string; -} - -/** - * The old exported symbol for {@link BackstageSignInResult}. - * - * @public - * @deprecated Use the {@link BackstageSignInResult} instead. + * @deprecated Use the {@link @backstage/plugin-auth-node#BackstageSignInResult} instead. */ export type BackstageIdentity = BackstageSignInResult; -/** - * Response object containing the {@link BackstageUserIdentity} and the token - * from the authentication provider. - * - * @public - */ -export interface BackstageIdentityResponse extends BackstageSignInResult { - /** - * A plaintext description of the identity that is encapsulated within the token. - */ - identity: BackstageUserIdentity; -} - /** * Used to display login information to user, i.e. sidebar popup. * @@ -286,7 +218,7 @@ export type SignInInfo = { /** * Describes the function which handles the result of a successful - * authentication. Must return a valid {@link BackstageSignInResult}. + * authentication. Must return a valid {@link @backstage/plugin-auth-node#BackstageSignInResult}. * * @public */ diff --git a/plugins/auth-node/api-report.md b/plugins/auth-node/api-report.md index e32a35880b..7795cae2ca 100644 --- a/plugins/auth-node/api-report.md +++ b/plugins/auth-node/api-report.md @@ -3,6 +3,29 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { Entity } from '@backstage/catalog-model'; + +// @public +export interface BackstageIdentityResponse extends BackstageSignInResult { + identity: BackstageUserIdentity; +} + +// @public +export interface BackstageSignInResult { + // @deprecated + entity?: Entity; + // @deprecated + id: string; + token: string; +} + +// @public +export type BackstageUserIdentity = { + type: 'user'; + userEntityRef: string; + ownershipEntityRefs: string[]; +}; + // @public export function getBearerTokenFromAuthorizationHeader( authorizationHeader: unknown, diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 7e4b4bfe77..6b66f37c6a 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -20,6 +20,7 @@ }, "dependencies": { "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "winston": "^3.2.1" }, diff --git a/plugins/auth-node/src/index.ts b/plugins/auth-node/src/index.ts index 83037f75be..0ecee97e40 100644 --- a/plugins/auth-node/src/index.ts +++ b/plugins/auth-node/src/index.ts @@ -21,3 +21,8 @@ */ export { getBearerTokenFromAuthorizationHeader } from './getBearerTokenFromAuthorizationHeader'; +export type { + BackstageIdentityResponse, + BackstageSignInResult, + BackstageUserIdentity, +} from './types'; diff --git a/plugins/auth-node/src/types.ts b/plugins/auth-node/src/types.ts new file mode 100644 index 0000000000..b574c2204d --- /dev/null +++ b/plugins/auth-node/src/types.ts @@ -0,0 +1,88 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; + +/** + * A representation of a successful Backstage sign-in. + * + * Compared to the {@link BackstageIdentityResponse} this type omits + * the decoded identity information embedded in the token. + * + * @public + */ +export interface BackstageSignInResult { + /** + * An opaque ID that uniquely identifies the user within Backstage. + * + * This is typically the same as the user entity `metadata.name`. + * + * @deprecated Use the `identity` field instead + */ + id: string; + + /** + * The entity that the user is represented by within Backstage. + * + * This entity may or may not exist within the Catalog, and it can be used + * to read and store additional metadata about the user. + * + * @deprecated Use the `identity` field instead. + */ + entity?: Entity; + + /** + * The token used to authenticate the user within Backstage. + */ + token: string; +} + +/** + * Response object containing the {@link BackstageUserIdentity} and the token + * from the authentication provider. + * + * @public + */ +export interface BackstageIdentityResponse extends BackstageSignInResult { + /** + * A plaintext description of the identity that is encapsulated within the token. + */ + identity: BackstageUserIdentity; +} + +/** + * User identity information within Backstage. + * + * @public + */ +export type BackstageUserIdentity = { + /** + * The type of identity that this structure represents. In the frontend app + * this will currently always be 'user'. + */ + type: 'user'; + + /** + * The entityRef of the user in the catalog. + * For example User:default/sandra + */ + userEntityRef: string; + + /** + * The user and group entities that the user claims ownership through + */ + ownershipEntityRefs: string[]; +}; diff --git a/plugins/permission-backend/src/service/router.ts b/plugins/permission-backend/src/service/router.ts index 10a70b01db..e68f2497e4 100644 --- a/plugins/permission-backend/src/service/router.ts +++ b/plugins/permission-backend/src/service/router.ts @@ -23,11 +23,11 @@ import { PluginEndpointDiscovery, } from '@backstage/backend-common'; import { InputError } from '@backstage/errors'; +import { IdentityClient } from '@backstage/plugin-auth-backend'; import { + getBearerTokenFromAuthorizationHeader, BackstageIdentityResponse, - IdentityClient, -} from '@backstage/plugin-auth-backend'; -import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; +} from '@backstage/plugin-auth-node'; import { AuthorizeResult, AuthorizeDecision, diff --git a/plugins/permission-node/api-report.md b/plugins/permission-node/api-report.md index 43bb548a06..534ad45110 100644 --- a/plugins/permission-node/api-report.md +++ b/plugins/permission-node/api-report.md @@ -7,7 +7,7 @@ import { AuthorizeDecision } from '@backstage/plugin-permission-common'; import { AuthorizeQuery } from '@backstage/plugin-permission-common'; import { AuthorizeRequestOptions } from '@backstage/plugin-permission-common'; import { AuthorizeResult } from '@backstage/plugin-permission-common'; -import { BackstageIdentityResponse } from '@backstage/plugin-auth-backend'; +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { Config } from '@backstage/config'; import express from 'express'; import { Identified } from '@backstage/plugin-permission-common'; diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index 6fb58251e3..7977e9057f 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -32,7 +32,7 @@ "@backstage/backend-common": "^0.10.7-next.0", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", - "@backstage/plugin-auth-backend": "^0.10.0-next.0", + "@backstage/plugin-auth-node": "^0.0.0", "@backstage/plugin-permission-common": "^0.4.0", "@types/express": "^4.17.6", "express": "^4.17.1", diff --git a/plugins/permission-node/src/policy/types.ts b/plugins/permission-node/src/policy/types.ts index 2e344d6d96..19b12b8f28 100644 --- a/plugins/permission-node/src/policy/types.ts +++ b/plugins/permission-node/src/policy/types.ts @@ -20,7 +20,7 @@ import { PermissionCondition, PermissionCriteria, } from '@backstage/plugin-permission-common'; -import { BackstageIdentityResponse } from '@backstage/plugin-auth-backend'; +import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; /** * An authorization request to be evaluated by the {@link PermissionPolicy}. From 56f20465b7b5dd68f5508a45449335614543288e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 9 Feb 2022 17:09:50 +0100 Subject: [PATCH 13/51] core-components,catalog-react: override type for forwardRef components Signed-off-by: Patrik Oldsberg --- packages/core-components/src/layout/Sidebar/Items.tsx | 2 +- .../src/components/EntityRefLink/EntityRefLink.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core-components/src/layout/Sidebar/Items.tsx b/packages/core-components/src/layout/Sidebar/Items.tsx index 239963ab2b..7eb86772f9 100644 --- a/packages/core-components/src/layout/Sidebar/Items.tsx +++ b/packages/core-components/src/layout/Sidebar/Items.tsx @@ -509,7 +509,7 @@ export const SidebarItem = forwardRef((props, ref) => { } return ; -}); +}) as (props: SidebarItemProps) => JSX.Element; type SidebarSearchFieldProps = { onSearch: (input: string) => void; diff --git a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx index aa92fd0818..8120ececd2 100644 --- a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx +++ b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx @@ -87,4 +87,4 @@ export const EntityRefLink = forwardRef( link ); }, -); +) as (props: EntityRefLinkProps) => JSX.Element; From 1cabe4264aa7a3fab8a4c634037887799baa2900 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 9 Feb 2022 17:39:48 +0100 Subject: [PATCH 14/51] core-components,catalog-react: update API reports Signed-off-by: Patrik Oldsberg --- packages/core-components/api-report.md | 1078 +----------------------- plugins/catalog-react/api-report.md | 288 +------ 2 files changed, 19 insertions(+), 1347 deletions(-) diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 6365b4f9d7..a8c51b6913 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -42,7 +42,7 @@ import { SessionApi } from '@backstage/core-plugin-api'; import { SignInPageProps } from '@backstage/core-plugin-api'; import { SparklinesLineProps } from 'react-sparklines'; import { SparklinesProps } from 'react-sparklines'; -import { StyledComponentProps } from '@material-ui/core/styles'; +import { StyledComponentProps } from '@material-ui/core/styles/withStyles'; import { StyleRules } from '@material-ui/styles'; import { StyleRules as StyleRules_2 } from '@material-ui/core/styles/withStyles'; import { TabProps } from '@material-ui/core/Tab'; @@ -120,7 +120,7 @@ export type BreadcrumbsStyledBoxClassKey = 'root'; export function BrokenImageIcon(props: IconComponentProps): JSX.Element; // @public -export function Button(props: ButtonProps): JSX.Element; +export const Button: (props: ButtonProps) => JSX.Element; // @public export type ButtonProps = ButtonProps_2 & Omit; @@ -594,10 +594,10 @@ export type LifecycleClassKey = 'alpha' | 'beta'; // @public (undocumented) export function LinearGauge(props: Props_11): JSX.Element | null; -// Warning: (ae-missing-release-tag) "LinkType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "Link" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) -export function Link(props: LinkProps): JSX.Element; +// @public +export const Link: (props: LinkProps) => JSX.Element; // Warning: (ae-missing-release-tag) "LinkProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -909,269 +909,9 @@ export type SidebarContextType = { // // @public (undocumented) export const SidebarDivider: React_2.ComponentType< - Pick< - React_2.DetailedHTMLProps< - React_2.HTMLAttributes, - HTMLHRElement - >, - | 'id' - | 'color' - | 'translate' - | 'hidden' - | 'dir' - | 'slot' - | 'style' - | 'title' - | 'accessKey' - | 'draggable' - | 'lang' - | 'prefix' - | 'children' - | 'contentEditable' - | 'inputMode' - | 'tabIndex' - | 'defaultChecked' - | 'defaultValue' - | 'suppressContentEditableWarning' - | 'suppressHydrationWarning' - | 'contextMenu' - | 'placeholder' - | 'spellCheck' - | 'radioGroup' - | 'role' - | 'about' - | 'datatype' - | 'inlist' - | 'property' - | 'resource' - | 'typeof' - | 'vocab' - | 'autoCapitalize' - | 'autoCorrect' - | 'autoSave' - | 'itemProp' - | 'itemScope' - | 'itemType' - | 'itemID' - | 'itemRef' - | 'results' - | 'security' - | 'unselectable' - | 'is' - | 'aria-activedescendant' - | 'aria-atomic' - | 'aria-autocomplete' - | 'aria-busy' - | 'aria-checked' - | 'aria-colcount' - | 'aria-colindex' - | 'aria-colspan' - | 'aria-controls' - | 'aria-current' - | 'aria-describedby' - | 'aria-details' - | 'aria-disabled' - | 'aria-dropeffect' - | 'aria-errormessage' - | 'aria-expanded' - | 'aria-flowto' - | 'aria-grabbed' - | 'aria-haspopup' - | 'aria-hidden' - | 'aria-invalid' - | 'aria-keyshortcuts' - | 'aria-label' - | 'aria-labelledby' - | 'aria-level' - | 'aria-live' - | 'aria-modal' - | 'aria-multiline' - | 'aria-multiselectable' - | 'aria-orientation' - | 'aria-owns' - | 'aria-placeholder' - | 'aria-posinset' - | 'aria-pressed' - | 'aria-readonly' - | 'aria-relevant' - | 'aria-required' - | 'aria-roledescription' - | 'aria-rowcount' - | 'aria-rowindex' - | 'aria-rowspan' - | 'aria-selected' - | 'aria-setsize' - | 'aria-sort' - | 'aria-valuemax' - | 'aria-valuemin' - | 'aria-valuenow' - | 'aria-valuetext' - | 'dangerouslySetInnerHTML' - | 'onCopy' - | 'onCopyCapture' - | 'onCut' - | 'onCutCapture' - | 'onPaste' - | 'onPasteCapture' - | 'onCompositionEnd' - | 'onCompositionEndCapture' - | 'onCompositionStart' - | 'onCompositionStartCapture' - | 'onCompositionUpdate' - | 'onCompositionUpdateCapture' - | 'onFocus' - | 'onFocusCapture' - | 'onBlur' - | 'onBlurCapture' - | 'onChange' - | 'onChangeCapture' - | 'onBeforeInput' - | 'onBeforeInputCapture' - | 'onInput' - | 'onInputCapture' - | 'onReset' - | 'onResetCapture' - | 'onSubmit' - | 'onSubmitCapture' - | 'onInvalid' - | 'onInvalidCapture' - | 'onLoad' - | 'onLoadCapture' - | 'onError' - | 'onErrorCapture' - | 'onKeyDown' - | 'onKeyDownCapture' - | 'onKeyPress' - | 'onKeyPressCapture' - | 'onKeyUp' - | 'onKeyUpCapture' - | 'onAbort' - | 'onAbortCapture' - | 'onCanPlay' - | 'onCanPlayCapture' - | 'onCanPlayThrough' - | 'onCanPlayThroughCapture' - | 'onDurationChange' - | 'onDurationChangeCapture' - | 'onEmptied' - | 'onEmptiedCapture' - | 'onEncrypted' - | 'onEncryptedCapture' - | 'onEnded' - | 'onEndedCapture' - | 'onLoadedData' - | 'onLoadedDataCapture' - | 'onLoadedMetadata' - | 'onLoadedMetadataCapture' - | 'onLoadStart' - | 'onLoadStartCapture' - | 'onPause' - | 'onPauseCapture' - | 'onPlay' - | 'onPlayCapture' - | 'onPlaying' - | 'onPlayingCapture' - | 'onProgress' - | 'onProgressCapture' - | 'onRateChange' - | 'onRateChangeCapture' - | 'onSeeked' - | 'onSeekedCapture' - | 'onSeeking' - | 'onSeekingCapture' - | 'onStalled' - | 'onStalledCapture' - | 'onSuspend' - | 'onSuspendCapture' - | 'onTimeUpdate' - | 'onTimeUpdateCapture' - | 'onVolumeChange' - | 'onVolumeChangeCapture' - | 'onWaiting' - | 'onWaitingCapture' - | 'onAuxClick' - | 'onAuxClickCapture' - | 'onClick' - | 'onClickCapture' - | 'onContextMenu' - | 'onContextMenuCapture' - | 'onDoubleClick' - | 'onDoubleClickCapture' - | 'onDrag' - | 'onDragCapture' - | 'onDragEnd' - | 'onDragEndCapture' - | 'onDragEnter' - | 'onDragEnterCapture' - | 'onDragExit' - | 'onDragExitCapture' - | 'onDragLeave' - | 'onDragLeaveCapture' - | 'onDragOver' - | 'onDragOverCapture' - | 'onDragStart' - | 'onDragStartCapture' - | 'onDrop' - | 'onDropCapture' - | 'onMouseDown' - | 'onMouseDownCapture' - | 'onMouseEnter' - | 'onMouseLeave' - | 'onMouseMove' - | 'onMouseMoveCapture' - | 'onMouseOut' - | 'onMouseOutCapture' - | 'onMouseOver' - | 'onMouseOverCapture' - | 'onMouseUp' - | 'onMouseUpCapture' - | 'onSelect' - | 'onSelectCapture' - | 'onTouchCancel' - | 'onTouchCancelCapture' - | 'onTouchEnd' - | 'onTouchEndCapture' - | 'onTouchMove' - | 'onTouchMoveCapture' - | 'onTouchStart' - | 'onTouchStartCapture' - | 'onPointerDown' - | 'onPointerDownCapture' - | 'onPointerMove' - | 'onPointerMoveCapture' - | 'onPointerUp' - | 'onPointerUpCapture' - | 'onPointerCancel' - | 'onPointerCancelCapture' - | 'onPointerEnter' - | 'onPointerEnterCapture' - | 'onPointerLeave' - | 'onPointerLeaveCapture' - | 'onPointerOver' - | 'onPointerOverCapture' - | 'onPointerOut' - | 'onPointerOutCapture' - | 'onGotPointerCapture' - | 'onGotPointerCaptureCapture' - | 'onLostPointerCapture' - | 'onLostPointerCaptureCapture' - | 'onScroll' - | 'onScrollCapture' - | 'onWheel' - | 'onWheelCapture' - | 'onAnimationStart' - | 'onAnimationStartCapture' - | 'onAnimationEnd' - | 'onAnimationEndCapture' - | 'onAnimationIteration' - | 'onAnimationIterationCapture' - | 'onTransitionEnd' - | 'onTransitionEndCapture' - | keyof React_2.ClassAttributes - > & - StyledComponentProps<'root'> & { - className?: string | undefined; - } + React_2.ClassAttributes & + React_2.HTMLAttributes & + StyledComponentProps<'root'> >; // Warning: (ae-missing-release-tag) "SidebarDividerClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1209,9 +949,7 @@ export type SidebarIntroClassKey = // Warning: (ae-missing-release-tag) "SidebarItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export const SidebarItem: React_2.ForwardRefExoticComponent< - SidebarItemProps & React_2.RefAttributes ->; +export const SidebarItem: (props: SidebarItemProps) => JSX.Element; // @public (undocumented) export type SidebarItemClassKey = @@ -1271,269 +1009,9 @@ export type SidebarProps = { // // @public (undocumented) export const SidebarScrollWrapper: React_2.ComponentType< - Pick< - React_2.DetailedHTMLProps< - React_2.HTMLAttributes, - HTMLDivElement - >, - | 'id' - | 'color' - | 'translate' - | 'hidden' - | 'dir' - | 'slot' - | 'style' - | 'title' - | 'accessKey' - | 'draggable' - | 'lang' - | 'prefix' - | 'children' - | 'contentEditable' - | 'inputMode' - | 'tabIndex' - | 'defaultChecked' - | 'defaultValue' - | 'suppressContentEditableWarning' - | 'suppressHydrationWarning' - | 'contextMenu' - | 'placeholder' - | 'spellCheck' - | 'radioGroup' - | 'role' - | 'about' - | 'datatype' - | 'inlist' - | 'property' - | 'resource' - | 'typeof' - | 'vocab' - | 'autoCapitalize' - | 'autoCorrect' - | 'autoSave' - | 'itemProp' - | 'itemScope' - | 'itemType' - | 'itemID' - | 'itemRef' - | 'results' - | 'security' - | 'unselectable' - | 'is' - | 'aria-activedescendant' - | 'aria-atomic' - | 'aria-autocomplete' - | 'aria-busy' - | 'aria-checked' - | 'aria-colcount' - | 'aria-colindex' - | 'aria-colspan' - | 'aria-controls' - | 'aria-current' - | 'aria-describedby' - | 'aria-details' - | 'aria-disabled' - | 'aria-dropeffect' - | 'aria-errormessage' - | 'aria-expanded' - | 'aria-flowto' - | 'aria-grabbed' - | 'aria-haspopup' - | 'aria-hidden' - | 'aria-invalid' - | 'aria-keyshortcuts' - | 'aria-label' - | 'aria-labelledby' - | 'aria-level' - | 'aria-live' - | 'aria-modal' - | 'aria-multiline' - | 'aria-multiselectable' - | 'aria-orientation' - | 'aria-owns' - | 'aria-placeholder' - | 'aria-posinset' - | 'aria-pressed' - | 'aria-readonly' - | 'aria-relevant' - | 'aria-required' - | 'aria-roledescription' - | 'aria-rowcount' - | 'aria-rowindex' - | 'aria-rowspan' - | 'aria-selected' - | 'aria-setsize' - | 'aria-sort' - | 'aria-valuemax' - | 'aria-valuemin' - | 'aria-valuenow' - | 'aria-valuetext' - | 'dangerouslySetInnerHTML' - | 'onCopy' - | 'onCopyCapture' - | 'onCut' - | 'onCutCapture' - | 'onPaste' - | 'onPasteCapture' - | 'onCompositionEnd' - | 'onCompositionEndCapture' - | 'onCompositionStart' - | 'onCompositionStartCapture' - | 'onCompositionUpdate' - | 'onCompositionUpdateCapture' - | 'onFocus' - | 'onFocusCapture' - | 'onBlur' - | 'onBlurCapture' - | 'onChange' - | 'onChangeCapture' - | 'onBeforeInput' - | 'onBeforeInputCapture' - | 'onInput' - | 'onInputCapture' - | 'onReset' - | 'onResetCapture' - | 'onSubmit' - | 'onSubmitCapture' - | 'onInvalid' - | 'onInvalidCapture' - | 'onLoad' - | 'onLoadCapture' - | 'onError' - | 'onErrorCapture' - | 'onKeyDown' - | 'onKeyDownCapture' - | 'onKeyPress' - | 'onKeyPressCapture' - | 'onKeyUp' - | 'onKeyUpCapture' - | 'onAbort' - | 'onAbortCapture' - | 'onCanPlay' - | 'onCanPlayCapture' - | 'onCanPlayThrough' - | 'onCanPlayThroughCapture' - | 'onDurationChange' - | 'onDurationChangeCapture' - | 'onEmptied' - | 'onEmptiedCapture' - | 'onEncrypted' - | 'onEncryptedCapture' - | 'onEnded' - | 'onEndedCapture' - | 'onLoadedData' - | 'onLoadedDataCapture' - | 'onLoadedMetadata' - | 'onLoadedMetadataCapture' - | 'onLoadStart' - | 'onLoadStartCapture' - | 'onPause' - | 'onPauseCapture' - | 'onPlay' - | 'onPlayCapture' - | 'onPlaying' - | 'onPlayingCapture' - | 'onProgress' - | 'onProgressCapture' - | 'onRateChange' - | 'onRateChangeCapture' - | 'onSeeked' - | 'onSeekedCapture' - | 'onSeeking' - | 'onSeekingCapture' - | 'onStalled' - | 'onStalledCapture' - | 'onSuspend' - | 'onSuspendCapture' - | 'onTimeUpdate' - | 'onTimeUpdateCapture' - | 'onVolumeChange' - | 'onVolumeChangeCapture' - | 'onWaiting' - | 'onWaitingCapture' - | 'onAuxClick' - | 'onAuxClickCapture' - | 'onClick' - | 'onClickCapture' - | 'onContextMenu' - | 'onContextMenuCapture' - | 'onDoubleClick' - | 'onDoubleClickCapture' - | 'onDrag' - | 'onDragCapture' - | 'onDragEnd' - | 'onDragEndCapture' - | 'onDragEnter' - | 'onDragEnterCapture' - | 'onDragExit' - | 'onDragExitCapture' - | 'onDragLeave' - | 'onDragLeaveCapture' - | 'onDragOver' - | 'onDragOverCapture' - | 'onDragStart' - | 'onDragStartCapture' - | 'onDrop' - | 'onDropCapture' - | 'onMouseDown' - | 'onMouseDownCapture' - | 'onMouseEnter' - | 'onMouseLeave' - | 'onMouseMove' - | 'onMouseMoveCapture' - | 'onMouseOut' - | 'onMouseOutCapture' - | 'onMouseOver' - | 'onMouseOverCapture' - | 'onMouseUp' - | 'onMouseUpCapture' - | 'onSelect' - | 'onSelectCapture' - | 'onTouchCancel' - | 'onTouchCancelCapture' - | 'onTouchEnd' - | 'onTouchEndCapture' - | 'onTouchMove' - | 'onTouchMoveCapture' - | 'onTouchStart' - | 'onTouchStartCapture' - | 'onPointerDown' - | 'onPointerDownCapture' - | 'onPointerMove' - | 'onPointerMoveCapture' - | 'onPointerUp' - | 'onPointerUpCapture' - | 'onPointerCancel' - | 'onPointerCancelCapture' - | 'onPointerEnter' - | 'onPointerEnterCapture' - | 'onPointerLeave' - | 'onPointerLeaveCapture' - | 'onPointerOver' - | 'onPointerOverCapture' - | 'onPointerOut' - | 'onPointerOutCapture' - | 'onGotPointerCapture' - | 'onGotPointerCaptureCapture' - | 'onLostPointerCapture' - | 'onLostPointerCaptureCapture' - | 'onScroll' - | 'onScrollCapture' - | 'onWheel' - | 'onWheelCapture' - | 'onAnimationStart' - | 'onAnimationStartCapture' - | 'onAnimationEnd' - | 'onAnimationEndCapture' - | 'onAnimationIteration' - | 'onAnimationIterationCapture' - | 'onTransitionEnd' - | 'onTransitionEndCapture' - | keyof React_2.ClassAttributes - > & - StyledComponentProps<'root'> & { - className?: string | undefined; - } + React_2.ClassAttributes & + React_2.HTMLAttributes & + StyledComponentProps<'root'> >; // Warning: (ae-forgotten-export) The symbol "SidebarSearchFieldProps" needs to be exported by the entry point index.d.ts @@ -1546,269 +1024,9 @@ export function SidebarSearchField(props: SidebarSearchFieldProps): JSX.Element; // // @public (undocumented) export const SidebarSpace: React_2.ComponentType< - Pick< - React_2.DetailedHTMLProps< - React_2.HTMLAttributes, - HTMLDivElement - >, - | 'id' - | 'color' - | 'translate' - | 'hidden' - | 'dir' - | 'slot' - | 'style' - | 'title' - | 'accessKey' - | 'draggable' - | 'lang' - | 'prefix' - | 'children' - | 'contentEditable' - | 'inputMode' - | 'tabIndex' - | 'defaultChecked' - | 'defaultValue' - | 'suppressContentEditableWarning' - | 'suppressHydrationWarning' - | 'contextMenu' - | 'placeholder' - | 'spellCheck' - | 'radioGroup' - | 'role' - | 'about' - | 'datatype' - | 'inlist' - | 'property' - | 'resource' - | 'typeof' - | 'vocab' - | 'autoCapitalize' - | 'autoCorrect' - | 'autoSave' - | 'itemProp' - | 'itemScope' - | 'itemType' - | 'itemID' - | 'itemRef' - | 'results' - | 'security' - | 'unselectable' - | 'is' - | 'aria-activedescendant' - | 'aria-atomic' - | 'aria-autocomplete' - | 'aria-busy' - | 'aria-checked' - | 'aria-colcount' - | 'aria-colindex' - | 'aria-colspan' - | 'aria-controls' - | 'aria-current' - | 'aria-describedby' - | 'aria-details' - | 'aria-disabled' - | 'aria-dropeffect' - | 'aria-errormessage' - | 'aria-expanded' - | 'aria-flowto' - | 'aria-grabbed' - | 'aria-haspopup' - | 'aria-hidden' - | 'aria-invalid' - | 'aria-keyshortcuts' - | 'aria-label' - | 'aria-labelledby' - | 'aria-level' - | 'aria-live' - | 'aria-modal' - | 'aria-multiline' - | 'aria-multiselectable' - | 'aria-orientation' - | 'aria-owns' - | 'aria-placeholder' - | 'aria-posinset' - | 'aria-pressed' - | 'aria-readonly' - | 'aria-relevant' - | 'aria-required' - | 'aria-roledescription' - | 'aria-rowcount' - | 'aria-rowindex' - | 'aria-rowspan' - | 'aria-selected' - | 'aria-setsize' - | 'aria-sort' - | 'aria-valuemax' - | 'aria-valuemin' - | 'aria-valuenow' - | 'aria-valuetext' - | 'dangerouslySetInnerHTML' - | 'onCopy' - | 'onCopyCapture' - | 'onCut' - | 'onCutCapture' - | 'onPaste' - | 'onPasteCapture' - | 'onCompositionEnd' - | 'onCompositionEndCapture' - | 'onCompositionStart' - | 'onCompositionStartCapture' - | 'onCompositionUpdate' - | 'onCompositionUpdateCapture' - | 'onFocus' - | 'onFocusCapture' - | 'onBlur' - | 'onBlurCapture' - | 'onChange' - | 'onChangeCapture' - | 'onBeforeInput' - | 'onBeforeInputCapture' - | 'onInput' - | 'onInputCapture' - | 'onReset' - | 'onResetCapture' - | 'onSubmit' - | 'onSubmitCapture' - | 'onInvalid' - | 'onInvalidCapture' - | 'onLoad' - | 'onLoadCapture' - | 'onError' - | 'onErrorCapture' - | 'onKeyDown' - | 'onKeyDownCapture' - | 'onKeyPress' - | 'onKeyPressCapture' - | 'onKeyUp' - | 'onKeyUpCapture' - | 'onAbort' - | 'onAbortCapture' - | 'onCanPlay' - | 'onCanPlayCapture' - | 'onCanPlayThrough' - | 'onCanPlayThroughCapture' - | 'onDurationChange' - | 'onDurationChangeCapture' - | 'onEmptied' - | 'onEmptiedCapture' - | 'onEncrypted' - | 'onEncryptedCapture' - | 'onEnded' - | 'onEndedCapture' - | 'onLoadedData' - | 'onLoadedDataCapture' - | 'onLoadedMetadata' - | 'onLoadedMetadataCapture' - | 'onLoadStart' - | 'onLoadStartCapture' - | 'onPause' - | 'onPauseCapture' - | 'onPlay' - | 'onPlayCapture' - | 'onPlaying' - | 'onPlayingCapture' - | 'onProgress' - | 'onProgressCapture' - | 'onRateChange' - | 'onRateChangeCapture' - | 'onSeeked' - | 'onSeekedCapture' - | 'onSeeking' - | 'onSeekingCapture' - | 'onStalled' - | 'onStalledCapture' - | 'onSuspend' - | 'onSuspendCapture' - | 'onTimeUpdate' - | 'onTimeUpdateCapture' - | 'onVolumeChange' - | 'onVolumeChangeCapture' - | 'onWaiting' - | 'onWaitingCapture' - | 'onAuxClick' - | 'onAuxClickCapture' - | 'onClick' - | 'onClickCapture' - | 'onContextMenu' - | 'onContextMenuCapture' - | 'onDoubleClick' - | 'onDoubleClickCapture' - | 'onDrag' - | 'onDragCapture' - | 'onDragEnd' - | 'onDragEndCapture' - | 'onDragEnter' - | 'onDragEnterCapture' - | 'onDragExit' - | 'onDragExitCapture' - | 'onDragLeave' - | 'onDragLeaveCapture' - | 'onDragOver' - | 'onDragOverCapture' - | 'onDragStart' - | 'onDragStartCapture' - | 'onDrop' - | 'onDropCapture' - | 'onMouseDown' - | 'onMouseDownCapture' - | 'onMouseEnter' - | 'onMouseLeave' - | 'onMouseMove' - | 'onMouseMoveCapture' - | 'onMouseOut' - | 'onMouseOutCapture' - | 'onMouseOver' - | 'onMouseOverCapture' - | 'onMouseUp' - | 'onMouseUpCapture' - | 'onSelect' - | 'onSelectCapture' - | 'onTouchCancel' - | 'onTouchCancelCapture' - | 'onTouchEnd' - | 'onTouchEndCapture' - | 'onTouchMove' - | 'onTouchMoveCapture' - | 'onTouchStart' - | 'onTouchStartCapture' - | 'onPointerDown' - | 'onPointerDownCapture' - | 'onPointerMove' - | 'onPointerMoveCapture' - | 'onPointerUp' - | 'onPointerUpCapture' - | 'onPointerCancel' - | 'onPointerCancelCapture' - | 'onPointerEnter' - | 'onPointerEnterCapture' - | 'onPointerLeave' - | 'onPointerLeaveCapture' - | 'onPointerOver' - | 'onPointerOverCapture' - | 'onPointerOut' - | 'onPointerOutCapture' - | 'onGotPointerCapture' - | 'onGotPointerCaptureCapture' - | 'onLostPointerCapture' - | 'onLostPointerCaptureCapture' - | 'onScroll' - | 'onScrollCapture' - | 'onWheel' - | 'onWheelCapture' - | 'onAnimationStart' - | 'onAnimationStartCapture' - | 'onAnimationEnd' - | 'onAnimationEndCapture' - | 'onAnimationIteration' - | 'onAnimationIterationCapture' - | 'onTransitionEnd' - | 'onTransitionEndCapture' - | keyof React_2.ClassAttributes - > & - StyledComponentProps<'root'> & { - className?: string | undefined; - } + React_2.ClassAttributes & + React_2.HTMLAttributes & + StyledComponentProps<'root'> >; // Warning: (ae-missing-release-tag) "SidebarSpaceClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1820,269 +1038,9 @@ export type SidebarSpaceClassKey = 'root'; // // @public (undocumented) export const SidebarSpacer: React_2.ComponentType< - Pick< - React_2.DetailedHTMLProps< - React_2.HTMLAttributes, - HTMLDivElement - >, - | 'id' - | 'color' - | 'translate' - | 'hidden' - | 'dir' - | 'slot' - | 'style' - | 'title' - | 'accessKey' - | 'draggable' - | 'lang' - | 'prefix' - | 'children' - | 'contentEditable' - | 'inputMode' - | 'tabIndex' - | 'defaultChecked' - | 'defaultValue' - | 'suppressContentEditableWarning' - | 'suppressHydrationWarning' - | 'contextMenu' - | 'placeholder' - | 'spellCheck' - | 'radioGroup' - | 'role' - | 'about' - | 'datatype' - | 'inlist' - | 'property' - | 'resource' - | 'typeof' - | 'vocab' - | 'autoCapitalize' - | 'autoCorrect' - | 'autoSave' - | 'itemProp' - | 'itemScope' - | 'itemType' - | 'itemID' - | 'itemRef' - | 'results' - | 'security' - | 'unselectable' - | 'is' - | 'aria-activedescendant' - | 'aria-atomic' - | 'aria-autocomplete' - | 'aria-busy' - | 'aria-checked' - | 'aria-colcount' - | 'aria-colindex' - | 'aria-colspan' - | 'aria-controls' - | 'aria-current' - | 'aria-describedby' - | 'aria-details' - | 'aria-disabled' - | 'aria-dropeffect' - | 'aria-errormessage' - | 'aria-expanded' - | 'aria-flowto' - | 'aria-grabbed' - | 'aria-haspopup' - | 'aria-hidden' - | 'aria-invalid' - | 'aria-keyshortcuts' - | 'aria-label' - | 'aria-labelledby' - | 'aria-level' - | 'aria-live' - | 'aria-modal' - | 'aria-multiline' - | 'aria-multiselectable' - | 'aria-orientation' - | 'aria-owns' - | 'aria-placeholder' - | 'aria-posinset' - | 'aria-pressed' - | 'aria-readonly' - | 'aria-relevant' - | 'aria-required' - | 'aria-roledescription' - | 'aria-rowcount' - | 'aria-rowindex' - | 'aria-rowspan' - | 'aria-selected' - | 'aria-setsize' - | 'aria-sort' - | 'aria-valuemax' - | 'aria-valuemin' - | 'aria-valuenow' - | 'aria-valuetext' - | 'dangerouslySetInnerHTML' - | 'onCopy' - | 'onCopyCapture' - | 'onCut' - | 'onCutCapture' - | 'onPaste' - | 'onPasteCapture' - | 'onCompositionEnd' - | 'onCompositionEndCapture' - | 'onCompositionStart' - | 'onCompositionStartCapture' - | 'onCompositionUpdate' - | 'onCompositionUpdateCapture' - | 'onFocus' - | 'onFocusCapture' - | 'onBlur' - | 'onBlurCapture' - | 'onChange' - | 'onChangeCapture' - | 'onBeforeInput' - | 'onBeforeInputCapture' - | 'onInput' - | 'onInputCapture' - | 'onReset' - | 'onResetCapture' - | 'onSubmit' - | 'onSubmitCapture' - | 'onInvalid' - | 'onInvalidCapture' - | 'onLoad' - | 'onLoadCapture' - | 'onError' - | 'onErrorCapture' - | 'onKeyDown' - | 'onKeyDownCapture' - | 'onKeyPress' - | 'onKeyPressCapture' - | 'onKeyUp' - | 'onKeyUpCapture' - | 'onAbort' - | 'onAbortCapture' - | 'onCanPlay' - | 'onCanPlayCapture' - | 'onCanPlayThrough' - | 'onCanPlayThroughCapture' - | 'onDurationChange' - | 'onDurationChangeCapture' - | 'onEmptied' - | 'onEmptiedCapture' - | 'onEncrypted' - | 'onEncryptedCapture' - | 'onEnded' - | 'onEndedCapture' - | 'onLoadedData' - | 'onLoadedDataCapture' - | 'onLoadedMetadata' - | 'onLoadedMetadataCapture' - | 'onLoadStart' - | 'onLoadStartCapture' - | 'onPause' - | 'onPauseCapture' - | 'onPlay' - | 'onPlayCapture' - | 'onPlaying' - | 'onPlayingCapture' - | 'onProgress' - | 'onProgressCapture' - | 'onRateChange' - | 'onRateChangeCapture' - | 'onSeeked' - | 'onSeekedCapture' - | 'onSeeking' - | 'onSeekingCapture' - | 'onStalled' - | 'onStalledCapture' - | 'onSuspend' - | 'onSuspendCapture' - | 'onTimeUpdate' - | 'onTimeUpdateCapture' - | 'onVolumeChange' - | 'onVolumeChangeCapture' - | 'onWaiting' - | 'onWaitingCapture' - | 'onAuxClick' - | 'onAuxClickCapture' - | 'onClick' - | 'onClickCapture' - | 'onContextMenu' - | 'onContextMenuCapture' - | 'onDoubleClick' - | 'onDoubleClickCapture' - | 'onDrag' - | 'onDragCapture' - | 'onDragEnd' - | 'onDragEndCapture' - | 'onDragEnter' - | 'onDragEnterCapture' - | 'onDragExit' - | 'onDragExitCapture' - | 'onDragLeave' - | 'onDragLeaveCapture' - | 'onDragOver' - | 'onDragOverCapture' - | 'onDragStart' - | 'onDragStartCapture' - | 'onDrop' - | 'onDropCapture' - | 'onMouseDown' - | 'onMouseDownCapture' - | 'onMouseEnter' - | 'onMouseLeave' - | 'onMouseMove' - | 'onMouseMoveCapture' - | 'onMouseOut' - | 'onMouseOutCapture' - | 'onMouseOver' - | 'onMouseOverCapture' - | 'onMouseUp' - | 'onMouseUpCapture' - | 'onSelect' - | 'onSelectCapture' - | 'onTouchCancel' - | 'onTouchCancelCapture' - | 'onTouchEnd' - | 'onTouchEndCapture' - | 'onTouchMove' - | 'onTouchMoveCapture' - | 'onTouchStart' - | 'onTouchStartCapture' - | 'onPointerDown' - | 'onPointerDownCapture' - | 'onPointerMove' - | 'onPointerMoveCapture' - | 'onPointerUp' - | 'onPointerUpCapture' - | 'onPointerCancel' - | 'onPointerCancelCapture' - | 'onPointerEnter' - | 'onPointerEnterCapture' - | 'onPointerLeave' - | 'onPointerLeaveCapture' - | 'onPointerOver' - | 'onPointerOverCapture' - | 'onPointerOut' - | 'onPointerOutCapture' - | 'onGotPointerCapture' - | 'onGotPointerCaptureCapture' - | 'onLostPointerCapture' - | 'onLostPointerCaptureCapture' - | 'onScroll' - | 'onScrollCapture' - | 'onWheel' - | 'onWheelCapture' - | 'onAnimationStart' - | 'onAnimationStartCapture' - | 'onAnimationEnd' - | 'onAnimationEndCapture' - | 'onAnimationIteration' - | 'onAnimationIterationCapture' - | 'onTransitionEnd' - | 'onTransitionEndCapture' - | keyof React_2.ClassAttributes - > & - StyledComponentProps<'root'> & { - className?: string | undefined; - } + React_2.ClassAttributes & + React_2.HTMLAttributes & + StyledComponentProps<'root'> >; // Warning: (ae-missing-release-tag) "SidebarSpacerClassKey" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index 2c064a504f..a0274b3b5a 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -272,293 +272,7 @@ export interface EntityProviderProps { } // @public -export const EntityRefLink: React_2.ForwardRefExoticComponent< - Pick< - EntityRefLinkProps, - | 'replace' - | 'type' - | 'key' - | 'id' - | 'media' - | 'state' - | 'color' - | 'display' - | 'translate' - | 'hidden' - | 'dir' - | 'slot' - | 'style' - | 'title' - | 'target' - | 'accessKey' - | 'draggable' - | 'lang' - | 'className' - | 'prefix' - | 'children' - | 'contentEditable' - | 'inputMode' - | 'tabIndex' - | 'underline' - | 'download' - | 'href' - | 'hrefLang' - | 'defaultChecked' - | 'defaultValue' - | 'suppressContentEditableWarning' - | 'suppressHydrationWarning' - | 'contextMenu' - | 'placeholder' - | 'spellCheck' - | 'radioGroup' - | 'role' - | 'about' - | 'datatype' - | 'inlist' - | 'property' - | 'resource' - | 'typeof' - | 'vocab' - | 'autoCapitalize' - | 'autoCorrect' - | 'autoSave' - | 'itemProp' - | 'itemScope' - | 'itemType' - | 'itemID' - | 'itemRef' - | 'results' - | 'security' - | 'unselectable' - | 'is' - | 'aria-activedescendant' - | 'aria-atomic' - | 'aria-autocomplete' - | 'aria-busy' - | 'aria-checked' - | 'aria-colcount' - | 'aria-colindex' - | 'aria-colspan' - | 'aria-controls' - | 'aria-current' - | 'aria-describedby' - | 'aria-details' - | 'aria-disabled' - | 'aria-dropeffect' - | 'aria-errormessage' - | 'aria-expanded' - | 'aria-flowto' - | 'aria-grabbed' - | 'aria-haspopup' - | 'aria-hidden' - | 'aria-invalid' - | 'aria-keyshortcuts' - | 'aria-label' - | 'aria-labelledby' - | 'aria-level' - | 'aria-live' - | 'aria-modal' - | 'aria-multiline' - | 'aria-multiselectable' - | 'aria-orientation' - | 'aria-owns' - | 'aria-placeholder' - | 'aria-posinset' - | 'aria-pressed' - | 'aria-readonly' - | 'aria-relevant' - | 'aria-required' - | 'aria-roledescription' - | 'aria-rowcount' - | 'aria-rowindex' - | 'aria-rowspan' - | 'aria-selected' - | 'aria-setsize' - | 'aria-sort' - | 'aria-valuemax' - | 'aria-valuemin' - | 'aria-valuenow' - | 'aria-valuetext' - | 'rel' - | 'dangerouslySetInnerHTML' - | 'onCopy' - | 'onCopyCapture' - | 'onCut' - | 'onCutCapture' - | 'onPaste' - | 'onPasteCapture' - | 'onCompositionEnd' - | 'onCompositionEndCapture' - | 'onCompositionStart' - | 'onCompositionStartCapture' - | 'onCompositionUpdate' - | 'onCompositionUpdateCapture' - | 'onFocus' - | 'onFocusCapture' - | 'onBlur' - | 'onBlurCapture' - | 'onChange' - | 'onChangeCapture' - | 'onBeforeInput' - | 'onBeforeInputCapture' - | 'onInput' - | 'onInputCapture' - | 'onReset' - | 'onResetCapture' - | 'onSubmit' - | 'onSubmitCapture' - | 'onInvalid' - | 'onInvalidCapture' - | 'onLoad' - | 'onLoadCapture' - | 'onError' - | 'onErrorCapture' - | 'onKeyDown' - | 'onKeyDownCapture' - | 'onKeyPress' - | 'onKeyPressCapture' - | 'onKeyUp' - | 'onKeyUpCapture' - | 'onAbort' - | 'onAbortCapture' - | 'onCanPlay' - | 'onCanPlayCapture' - | 'onCanPlayThrough' - | 'onCanPlayThroughCapture' - | 'onDurationChange' - | 'onDurationChangeCapture' - | 'onEmptied' - | 'onEmptiedCapture' - | 'onEncrypted' - | 'onEncryptedCapture' - | 'onEnded' - | 'onEndedCapture' - | 'onLoadedData' - | 'onLoadedDataCapture' - | 'onLoadedMetadata' - | 'onLoadedMetadataCapture' - | 'onLoadStart' - | 'onLoadStartCapture' - | 'onPause' - | 'onPauseCapture' - | 'onPlay' - | 'onPlayCapture' - | 'onPlaying' - | 'onPlayingCapture' - | 'onProgress' - | 'onProgressCapture' - | 'onRateChange' - | 'onRateChangeCapture' - | 'onSeeked' - | 'onSeekedCapture' - | 'onSeeking' - | 'onSeekingCapture' - | 'onStalled' - | 'onStalledCapture' - | 'onSuspend' - | 'onSuspendCapture' - | 'onTimeUpdate' - | 'onTimeUpdateCapture' - | 'onVolumeChange' - | 'onVolumeChangeCapture' - | 'onWaiting' - | 'onWaitingCapture' - | 'onAuxClick' - | 'onAuxClickCapture' - | 'onClick' - | 'onClickCapture' - | 'onContextMenu' - | 'onContextMenuCapture' - | 'onDoubleClick' - | 'onDoubleClickCapture' - | 'onDrag' - | 'onDragCapture' - | 'onDragEnd' - | 'onDragEndCapture' - | 'onDragEnter' - | 'onDragEnterCapture' - | 'onDragExit' - | 'onDragExitCapture' - | 'onDragLeave' - | 'onDragLeaveCapture' - | 'onDragOver' - | 'onDragOverCapture' - | 'onDragStart' - | 'onDragStartCapture' - | 'onDrop' - | 'onDropCapture' - | 'onMouseDown' - | 'onMouseDownCapture' - | 'onMouseEnter' - | 'onMouseLeave' - | 'onMouseMove' - | 'onMouseMoveCapture' - | 'onMouseOut' - | 'onMouseOutCapture' - | 'onMouseOver' - | 'onMouseOverCapture' - | 'onMouseUp' - | 'onMouseUpCapture' - | 'onSelect' - | 'onSelectCapture' - | 'onTouchCancel' - | 'onTouchCancelCapture' - | 'onTouchEnd' - | 'onTouchEndCapture' - | 'onTouchMove' - | 'onTouchMoveCapture' - | 'onTouchStart' - | 'onTouchStartCapture' - | 'onPointerDown' - | 'onPointerDownCapture' - | 'onPointerMove' - | 'onPointerMoveCapture' - | 'onPointerUp' - | 'onPointerUpCapture' - | 'onPointerCancel' - | 'onPointerCancelCapture' - | 'onPointerEnter' - | 'onPointerEnterCapture' - | 'onPointerLeave' - | 'onPointerLeaveCapture' - | 'onPointerOver' - | 'onPointerOverCapture' - | 'onPointerOut' - | 'onPointerOutCapture' - | 'onGotPointerCapture' - | 'onGotPointerCaptureCapture' - | 'onLostPointerCapture' - | 'onLostPointerCaptureCapture' - | 'onScroll' - | 'onScrollCapture' - | 'onWheel' - | 'onWheelCapture' - | 'onAnimationStart' - | 'onAnimationStartCapture' - | 'onAnimationEnd' - | 'onAnimationEndCapture' - | 'onAnimationIteration' - | 'onAnimationIterationCapture' - | 'onTransitionEnd' - | 'onTransitionEndCapture' - | 'ping' - | 'referrerPolicy' - | 'align' - | 'variant' - | 'component' - | 'classes' - | 'innerRef' - | 'noWrap' - | 'gutterBottom' - | 'paragraph' - | 'variantMapping' - | 'noTrack' - | 'TypographyClasses' - | 'entityRef' - | 'defaultKind' - > & - React_2.RefAttributes ->; +export const EntityRefLink: (props: EntityRefLinkProps) => JSX.Element; // @public export type EntityRefLinkProps = { From 19155e0939b5dc509dd4d7322f453da14bf37042 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 9 Feb 2022 17:52:20 +0100 Subject: [PATCH 15/51] changesets: add changeset for cleaning up components in api reports Signed-off-by: Patrik Oldsberg --- .changeset/soft-dogs-exercise.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/soft-dogs-exercise.md diff --git a/.changeset/soft-dogs-exercise.md b/.changeset/soft-dogs-exercise.md new file mode 100644 index 0000000000..2d045ba1f6 --- /dev/null +++ b/.changeset/soft-dogs-exercise.md @@ -0,0 +1,6 @@ +--- +'@backstage/core-components': patch +'@backstage/plugin-catalog-react': patch +--- + +Updated React component type declarations to avoid exporting exotic component types. From c904cefa0ebf47d454325b4f2ac81328a51e3f70 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 9 Feb 2022 18:33:29 +0100 Subject: [PATCH 16/51] changesets: exit pre-release Signed-off-by: blam --- .changeset/pre.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 9c6e4b2c4c..6261b07f60 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,5 +1,5 @@ { - "mode": "pre", + "mode": "exit", "tag": "next", "initialVersions": { "example-app": "0.2.63", From b719d2873a68c3fc747346f437d862d5922cb531 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 9 Feb 2022 18:40:19 +0100 Subject: [PATCH 17/51] chore: uodating package name to be correct Signed-off-by: blam --- packages/create-app/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 385d3acdf9..d65cd3ae3a 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -275,7 +275,7 @@ To make this change to an existing app: - Add `@backstage/plugin-catalog-graph` as a `dependency` in `packages/app/package.json` + Add `@backstage/plugin-catalog-graph` as a `dependency` in `packages/app/package.json` or `cd packages/app && yarn add @backstage/plugin-catalog-graph`. Apply the following changes to the `packages/app/src/components/catalog/EntityPage.tsx` file: From 71162bdcb34237f61407b9eff9d458ba10af22fa Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 9 Feb 2022 18:42:54 +0100 Subject: [PATCH 18/51] chore: updating collator reference too they should be using tokenManagers Signed-off-by: blam --- packages/create-app/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index d65cd3ae3a..da2f05008b 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -271,6 +271,13 @@ } ``` +The `.fromConfig` of the `DefaultCatalogCollator` also now takes a `tokenManager` as a parameter. + +```diff +- collator: DefaultCatalogCollator.fromConfig(config, { discovery }), ++ collator: DefaultCatalogCollator.fromConfig(config, { discovery, tokenManager }), +``` + - a0d446c8ec: Replaced EntitySystemDiagramCard with EntityCatalogGraphCard To make this change to an existing app: From 945ea0d27829ca5fbc4b5af5acb5b5054f3b5051 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 9 Feb 2022 19:06:30 +0100 Subject: [PATCH 19/51] chore: roll back the date-io/luxon bump Signed-off-by: blam --- plugins/bazaar/package.json | 2 +- plugins/ilert/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index e385155c39..a82e23034f 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -28,7 +28,7 @@ "@backstage/core-plugin-api": "^0.6.0", "@backstage/plugin-catalog": "^0.7.12-next.0", "@backstage/plugin-catalog-react": "^0.6.14-next.0", - "@date-io/luxon": "2.x", + "@date-io/luxon": "1.x", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index acd621bcf3..3ea25b9414 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -27,7 +27,7 @@ "@backstage/errors": "^0.2.0", "@backstage/plugin-catalog-react": "^0.6.14-next.0", "@backstage/theme": "^0.2.14", - "@date-io/luxon": "2.x", + "@date-io/luxon": "1.x", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", From d674971d3ae2133119a3f4683a7836e9e5788e00 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 9 Feb 2022 19:08:20 +0100 Subject: [PATCH 20/51] chore: added changeset Signed-off-by: blam --- .changeset/moody-parrots-listen.md | 6 ++++++ yarn.lock | 15 +++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) create mode 100644 .changeset/moody-parrots-listen.md diff --git a/.changeset/moody-parrots-listen.md b/.changeset/moody-parrots-listen.md new file mode 100644 index 0000000000..ff19f67bfd --- /dev/null +++ b/.changeset/moody-parrots-listen.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-bazaar': patch +'@backstage/plugin-ilert': patch +--- + +Rolling back the `@date-io/luxon` bump as this broke both packages, and we need it for `@material-ui/pickers` diff --git a/yarn.lock b/yarn.lock index d40d08797f..ffc877abc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1828,11 +1828,6 @@ resolved "https://registry.npmjs.org/@date-io/core/-/core-2.10.7.tgz#0fe1fa0ef02c827919e23c2802a4b25589ac522d" integrity sha512-EG/1qDiQvd12RoNJ6H+sZcHVswC/3uMx/ySvfaJ24vB30rLjkgHggEXbgMbfgki7wMuiQ/zXI8QlmF1k3kWRGQ== -"@date-io/core@^2.13.1": - version "2.13.1" - resolved "https://registry.npmjs.org/@date-io/core/-/core-2.13.1.tgz#f041765aff5c55fbc7e37fdd75fc1792733426d6" - integrity sha512-pVI9nfkf2qClb2Cxdq0Q4zJhdawMG4ybWZUVGifT78FDwzRMX2SwXBb55s5NRJk0HcIicDuxktmCtemZqMH1Zg== - "@date-io/date-fns@^1.3.13": version "1.3.13" resolved "https://registry.npmjs.org/@date-io/date-fns/-/date-fns-1.3.13.tgz#7798844041640ab393f7e21a7769a65d672f4735" @@ -1840,12 +1835,12 @@ dependencies: "@date-io/core" "^1.3.13" -"@date-io/luxon@2.x": - version "2.13.1" - resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-2.13.1.tgz#3701b3cabfffda5102af302979aa6e58acfda91a" - integrity sha512-yG+uM7lXfwLyKKEwjvP8oZ7qblpmfl9gxQYae55ifbwiTs0CoCTkYkxEaQHGkYtTqGTzLqcb0O9Pzx6vgWg+yg== +"@date-io/luxon@1.x": + version "1.3.13" + resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-1.3.13.tgz#68f0134bb38ef486b2ed6df01981f814c633e28a" + integrity sha512-9wUrJCNSMZJeYAiH+dbb45oGpnHeFP7TOH/Lt26If47gjFCkjvyINzWx+K5AGsnlP0Qosxc7hkF1yLi6ecutxw== dependencies: - "@date-io/core" "^2.13.1" + "@date-io/core" "^1.3.13" "@elastic/elasticsearch-mock@^0.3.0": version "0.3.0" From bf5222bfa1e7a41aa8b1afbc535ca917f442cbb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 9 Feb 2022 19:32:59 +0100 Subject: [PATCH 21/51] moved over IdentityClient as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/giant-nails-grow.md | 8 +- packages/backend/package.json | 1 + packages/backend/src/plugins/permission.ts | 2 +- plugins/auth-backend/api-report.md | 8 -- plugins/auth-backend/src/identity/index.ts | 1 - plugins/auth-backend/src/index.ts | 1 - plugins/auth-node/api-report.md | 7 ++ plugins/auth-node/package.json | 7 +- .../src}/IdentityClient.test.ts | 76 ++++++++++++++----- .../src}/IdentityClient.ts | 11 +-- plugins/auth-node/src/index.ts | 1 + plugins/permission-backend/api-report.md | 2 +- plugins/permission-backend/package.json | 1 - .../src/service/router.test.ts | 2 +- .../permission-backend/src/service/router.ts | 2 +- 15 files changed, 85 insertions(+), 45 deletions(-) rename plugins/{auth-backend/src/identity => auth-node/src}/IdentityClient.test.ts (81%) rename plugins/{auth-backend/src/identity => auth-node/src}/IdentityClient.ts (95%) diff --git a/.changeset/giant-nails-grow.md b/.changeset/giant-nails-grow.md index be4d5793e7..f96efce2ba 100644 --- a/.changeset/giant-nails-grow.md +++ b/.changeset/giant-nails-grow.md @@ -2,6 +2,11 @@ '@backstage/plugin-auth-backend': minor --- +- Moved `IdentityClient`, `BackstageSignInResult`, `BackstageIdentityResponse`, + and `BackstageUserIdentity` to `@backstage/plugin-auth-node`. + +While moving over, `IdentityClient` was also changed in the following ways: + - Made `IdentityClient.listPublicKeys` private. It was only used in tests, and should not be part of the API surface of that class. - Removed the static `IdentityClient.getBearerToken`. It is now replaced by @@ -9,6 +14,3 @@ Since the `IdentityClient` interface is marked as experimental, this is a breaking change without a deprecation period. - -- Moved `BackstageSignInResult`, `BackstageIdentityResponse`, and - `BackstageUserIdentity` to `@backstage/plugin-auth-node`. diff --git a/packages/backend/package.json b/packages/backend/package.json index c2e8711757..1c709195b0 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -32,6 +32,7 @@ "@backstage/integration": "^0.7.2", "@backstage/plugin-app-backend": "^0.3.24-next.0", "@backstage/plugin-auth-backend": "^0.10.0-next.0", + "@backstage/plugin-auth-node": "^0.0.0", "@backstage/plugin-azure-devops-backend": "^0.3.3-next.0", "@backstage/plugin-badges-backend": "^0.1.18-next.0", "@backstage/plugin-catalog-backend": "^0.21.3-next.0", diff --git a/packages/backend/src/plugins/permission.ts b/packages/backend/src/plugins/permission.ts index 71a9b90311..6ba24ba1f7 100644 --- a/packages/backend/src/plugins/permission.ts +++ b/packages/backend/src/plugins/permission.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { IdentityClient } from '@backstage/plugin-auth-backend'; +import { IdentityClient } from '@backstage/plugin-auth-node'; import { createRouter } from '@backstage/plugin-permission-backend'; import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index e555eb4a36..66153fd0af 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -402,14 +402,6 @@ export type GoogleProviderOptions = { }; }; -// Warning: (ae-missing-release-tag) "IdentityClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export class IdentityClient { - constructor(options: { discovery: PluginEndpointDiscovery; issuer: string }); - authenticate(token: string | undefined): Promise; -} - // Warning: (ae-missing-release-tag) "microsoftEmailSignInResolver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) diff --git a/plugins/auth-backend/src/identity/index.ts b/plugins/auth-backend/src/identity/index.ts index 73858d7e07..cb2f369668 100644 --- a/plugins/auth-backend/src/identity/index.ts +++ b/plugins/auth-backend/src/identity/index.ts @@ -15,7 +15,6 @@ */ export { createOidcRouter } from './router'; -export { IdentityClient } from './IdentityClient'; export { TokenFactory } from './TokenFactory'; export { DatabaseKeyStore } from './DatabaseKeyStore'; export { MemoryKeyStore } from './MemoryKeyStore'; diff --git a/plugins/auth-backend/src/index.ts b/plugins/auth-backend/src/index.ts index 66c1b42dd9..d0cade087e 100644 --- a/plugins/auth-backend/src/index.ts +++ b/plugins/auth-backend/src/index.ts @@ -21,7 +21,6 @@ */ export * from './service/router'; -export { IdentityClient } from './identity'; export type { TokenIssuer } from './identity'; export * from './providers'; diff --git a/plugins/auth-node/api-report.md b/plugins/auth-node/api-report.md index 7795cae2ca..7a04ba8181 100644 --- a/plugins/auth-node/api-report.md +++ b/plugins/auth-node/api-report.md @@ -4,6 +4,7 @@ ```ts import { Entity } from '@backstage/catalog-model'; +import { PluginEndpointDiscovery } from '@backstage/backend-common'; // @public export interface BackstageIdentityResponse extends BackstageSignInResult { @@ -30,4 +31,10 @@ export type BackstageUserIdentity = { export function getBearerTokenFromAuthorizationHeader( authorizationHeader: unknown, ): string | undefined; + +// @public +export class IdentityClient { + constructor(options: { discovery: PluginEndpointDiscovery; issuer: string }); + authenticate(token: string | undefined): Promise; +} ``` diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 6b66f37c6a..cec1006ef0 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -22,10 +22,15 @@ "@backstage/backend-common": "^0.10.7-next.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", + "@backstage/errors": "^0.2.0", + "jose": "^1.27.1", + "node-fetch": "^2.6.1", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0" + "@backstage/cli": "^0.13.2-next.0", + "msw": "^0.35.0", + "uuid": "^8.0.0" }, "files": [ "dist" diff --git a/plugins/auth-backend/src/identity/IdentityClient.test.ts b/plugins/auth-node/src/IdentityClient.test.ts similarity index 81% rename from plugins/auth-backend/src/identity/IdentityClient.test.ts rename to plugins/auth-node/src/IdentityClient.test.ts index cf60fd0852..cddc5f33a2 100644 --- a/plugins/auth-backend/src/identity/IdentityClient.test.ts +++ b/plugins/auth-node/src/IdentityClient.test.ts @@ -14,19 +14,61 @@ * limitations under the License. */ -import { JWT, JSONWebKey } from 'jose'; +import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { JSONWebKey, JWK, JWS, JWT } from 'jose'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; -import { - getVoidLogger, - PluginEndpointDiscovery, -} from '@backstage/backend-common'; +import { v4 as uuid } from 'uuid'; import { IdentityClient } from './IdentityClient'; -import { MemoryKeyStore } from './MemoryKeyStore'; -import { TokenFactory } from './TokenFactory'; -import { KeyStore } from './types'; -const logger = getVoidLogger(); +interface AnyJWK extends Record { + use: 'sig'; + alg: string; + kid: string; + kty: string; +} + +// Simplified copy of TokenFactory in @backstage/plugin-auth-backend +class FakeTokenFactory { + private readonly keys = new Array(); + + constructor( + private readonly options: { + issuer: string; + keyDurationSeconds: number; + }, + ) {} + + async issueToken(params: { + claims: { + sub: string; + ent?: string[]; + }; + }): Promise { + const key = await JWK.generate('EC', 'P-256', { + use: 'sig', + kid: uuid(), + alg: 'ES256', + }); + this.keys.push(key.toJWK(false) as unknown as AnyJWK); + + const iss = this.options.issuer; + const sub = params.claims.sub; + const ent = params.claims.ent; + const aud = 'backstage'; + const iat = Math.floor(Date.now() / 1000); + const exp = iat + this.options.keyDurationSeconds; + + return JWS.sign({ iss, sub, aud, iat, exp, ent }, key, { + alg: key.alg, + kid: key.kid, + }); + } + + async listPublicKeys(): Promise<{ keys: AnyJWK[] }> { + return { keys: this.keys }; + } +} function jwtKid(jwt: string): string { const { header } = JWT.decode(jwt, { complete: true }) as { @@ -48,8 +90,7 @@ const discovery: PluginEndpointDiscovery = { describe('IdentityClient', () => { let client: IdentityClient; - let factory: TokenFactory; - let keyStore: KeyStore; + let factory: FakeTokenFactory; const keyDurationSeconds = 5; beforeAll(() => server.listen({ onUnhandledRequest: 'error' })); @@ -58,12 +99,9 @@ describe('IdentityClient', () => { beforeEach(() => { client = new IdentityClient({ discovery, issuer: mockBaseUrl }); - keyStore = new MemoryKeyStore(); - factory = new TokenFactory({ + factory = new FakeTokenFactory({ issuer: mockBaseUrl, - keyStore: keyStore, keyDurationSeconds, - logger, }); }); @@ -108,11 +146,9 @@ describe('IdentityClient', () => { }); it('should throw on incorrect issuer', async () => { - const hackerFactory = new TokenFactory({ + const hackerFactory = new FakeTokenFactory({ issuer: 'hacker', - keyStore, keyDurationSeconds, - logger, }); return expect(async () => { const token = await hackerFactory.issueToken({ @@ -137,11 +173,9 @@ describe('IdentityClient', () => { }); it('should throw on incorrect signing key', async () => { - const hackerFactory = new TokenFactory({ + const hackerFactory = new FakeTokenFactory({ issuer: mockBaseUrl, - keyStore: new MemoryKeyStore(), keyDurationSeconds, - logger, }); return expect(async () => { const token = await hackerFactory.issueToken({ diff --git a/plugins/auth-backend/src/identity/IdentityClient.ts b/plugins/auth-node/src/IdentityClient.ts similarity index 95% rename from plugins/auth-backend/src/identity/IdentityClient.ts rename to plugins/auth-node/src/IdentityClient.ts index 6c6c2ca4b1..ddbccff027 100644 --- a/plugins/auth-backend/src/identity/IdentityClient.ts +++ b/plugins/auth-node/src/IdentityClient.ts @@ -14,19 +14,20 @@ * limitations under the License. */ -import fetch from 'node-fetch'; -import { JWK, JWT, JWKS, JSONWebKey } from 'jose'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { AuthenticationError } from '@backstage/errors'; -import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; +import { JSONWebKey, JWK, JWKS, JWT } from 'jose'; +import fetch from 'node-fetch'; +import { BackstageIdentityResponse } from './types'; const CLOCK_MARGIN_S = 10; /** - * A identity client to interact with auth-backend - * and authenticate backstage identity tokens + * An identity client to interact with auth-backend and authenticate Backstage + * tokens * * @experimental This is not a stable API yet + * @public */ export class IdentityClient { private readonly discovery: PluginEndpointDiscovery; diff --git a/plugins/auth-node/src/index.ts b/plugins/auth-node/src/index.ts index 0ecee97e40..5551f2c85d 100644 --- a/plugins/auth-node/src/index.ts +++ b/plugins/auth-node/src/index.ts @@ -21,6 +21,7 @@ */ export { getBearerTokenFromAuthorizationHeader } from './getBearerTokenFromAuthorizationHeader'; +export { IdentityClient } from './IdentityClient'; export type { BackstageIdentityResponse, BackstageSignInResult, diff --git a/plugins/permission-backend/api-report.md b/plugins/permission-backend/api-report.md index 4857c8b044..843c9a315c 100644 --- a/plugins/permission-backend/api-report.md +++ b/plugins/permission-backend/api-report.md @@ -4,7 +4,7 @@ ```ts import express from 'express'; -import { IdentityClient } from '@backstage/plugin-auth-backend'; +import { IdentityClient } from '@backstage/plugin-auth-node'; import { Logger as Logger_2 } from 'winston'; import { PermissionPolicy } from '@backstage/plugin-permission-node'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 9ee959243d..01efa7af04 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -22,7 +22,6 @@ "@backstage/backend-common": "^0.10.7-next.0", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", - "@backstage/plugin-auth-backend": "^0.10.0-next.0", "@backstage/plugin-auth-node": "^0.0.0", "@backstage/plugin-permission-common": "^0.4.0", "@backstage/plugin-permission-node": "^0.4.3-next.0", diff --git a/plugins/permission-backend/src/service/router.test.ts b/plugins/permission-backend/src/service/router.test.ts index fd09cca828..498fcb748b 100644 --- a/plugins/permission-backend/src/service/router.test.ts +++ b/plugins/permission-backend/src/service/router.test.ts @@ -17,7 +17,7 @@ import express from 'express'; import request from 'supertest'; import { getVoidLogger } from '@backstage/backend-common'; -import { IdentityClient } from '@backstage/plugin-auth-backend'; +import { IdentityClient } from '@backstage/plugin-auth-node'; import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { ApplyConditionsRequestEntry, diff --git a/plugins/permission-backend/src/service/router.ts b/plugins/permission-backend/src/service/router.ts index e68f2497e4..413f3e6b45 100644 --- a/plugins/permission-backend/src/service/router.ts +++ b/plugins/permission-backend/src/service/router.ts @@ -23,10 +23,10 @@ import { PluginEndpointDiscovery, } from '@backstage/backend-common'; import { InputError } from '@backstage/errors'; -import { IdentityClient } from '@backstage/plugin-auth-backend'; import { getBearerTokenFromAuthorizationHeader, BackstageIdentityResponse, + IdentityClient, } from '@backstage/plugin-auth-node'; import { AuthorizeResult, From 770c195f34ebdc79c0bee0b6f8c6b8a52bb6b58d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Thu, 13 Jan 2022 11:15:32 +0100 Subject: [PATCH 22/51] feat(cicd-statistics): Added CI/CD statistics plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- .changeset/strong-ties-exist.md | 5 + plugins/cicd-statistics/.eslintrc.js | 3 + plugins/cicd-statistics/README.md | 7 + plugins/cicd-statistics/api-report.md | 182 +++++++++ plugins/cicd-statistics/package.json | 53 +++ .../src/apis/cicd-statistics.ts | 23 ++ plugins/cicd-statistics/src/apis/index.ts | 18 + plugins/cicd-statistics/src/apis/types.ts | 225 +++++++++++ plugins/cicd-statistics/src/charts/colors.ts | 39 ++ .../cicd-statistics/src/charts/conversions.ts | 238 +++++++++++ .../src/charts/stage-chart.tsx | 212 ++++++++++ .../src/charts/status-chart.tsx | 133 ++++++ plugins/cicd-statistics/src/charts/types.ts | 48 +++ plugins/cicd-statistics/src/charts/utils.tsx | 87 ++++ .../src/components/button-switch.tsx | 117 ++++++ .../src/components/chart-filters.tsx | 382 ++++++++++++++++++ .../src/components/progress.tsx | 147 +++++++ .../cicd-statistics/src/components/toggle.tsx | 40 ++ plugins/cicd-statistics/src/entity-page.tsx | 175 ++++++++ .../src/hooks/use-cicd-configuration.ts | 59 +++ .../src/hooks/use-cicd-statistics-api.ts | 27 ++ .../src/hooks/use-cicd-statistics.ts | 120 ++++++ plugins/cicd-statistics/src/index.ts | 18 + plugins/cicd-statistics/src/plugin.ts | 40 ++ .../cicd-statistics/src/utils/stage-names.ts | 73 ++++ 25 files changed, 2471 insertions(+) create mode 100644 .changeset/strong-ties-exist.md create mode 100644 plugins/cicd-statistics/.eslintrc.js create mode 100644 plugins/cicd-statistics/README.md create mode 100644 plugins/cicd-statistics/api-report.md create mode 100644 plugins/cicd-statistics/package.json create mode 100644 plugins/cicd-statistics/src/apis/cicd-statistics.ts create mode 100644 plugins/cicd-statistics/src/apis/index.ts create mode 100644 plugins/cicd-statistics/src/apis/types.ts create mode 100644 plugins/cicd-statistics/src/charts/colors.ts create mode 100644 plugins/cicd-statistics/src/charts/conversions.ts create mode 100644 plugins/cicd-statistics/src/charts/stage-chart.tsx create mode 100644 plugins/cicd-statistics/src/charts/status-chart.tsx create mode 100644 plugins/cicd-statistics/src/charts/types.ts create mode 100644 plugins/cicd-statistics/src/charts/utils.tsx create mode 100644 plugins/cicd-statistics/src/components/button-switch.tsx create mode 100644 plugins/cicd-statistics/src/components/chart-filters.tsx create mode 100644 plugins/cicd-statistics/src/components/progress.tsx create mode 100644 plugins/cicd-statistics/src/components/toggle.tsx create mode 100644 plugins/cicd-statistics/src/entity-page.tsx create mode 100644 plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts create mode 100644 plugins/cicd-statistics/src/hooks/use-cicd-statistics-api.ts create mode 100644 plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts create mode 100644 plugins/cicd-statistics/src/index.ts create mode 100644 plugins/cicd-statistics/src/plugin.ts create mode 100644 plugins/cicd-statistics/src/utils/stage-names.ts diff --git a/.changeset/strong-ties-exist.md b/.changeset/strong-ties-exist.md new file mode 100644 index 0000000000..dae77c2805 --- /dev/null +++ b/.changeset/strong-ties-exist.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cicd-statistics': minor +--- + +Added new plugin "CI/CD Statistics" which charts pipeline build durations over time diff --git a/plugins/cicd-statistics/.eslintrc.js b/plugins/cicd-statistics/.eslintrc.js new file mode 100644 index 0000000000..13573efa9c --- /dev/null +++ b/plugins/cicd-statistics/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint')], +}; diff --git a/plugins/cicd-statistics/README.md b/plugins/cicd-statistics/README.md new file mode 100644 index 0000000000..e4db2166a6 --- /dev/null +++ b/plugins/cicd-statistics/README.md @@ -0,0 +1,7 @@ +# CI/CD Statistics Plugin + +This plugin shows charts of CI/CD pipeline durations over time. It expects to be used on the Software Catalog entity page, as it uses `useEntity` to figure out what component to get the build information for. + +To use this plugin, you need to implement an API `CicdStatisticsApi` and bind it to the `cicdStatisticsApiRef`. This API is defined in `src/apis/types.ts` and is an interface with two functions, `getConfiguration()` and `fetchBuilds(options)`. This plugin will call `getConfiguration` to allow the implementation to specify defaults an settings for the UI. First time the UI shows, and each time the user changes filters and clicks `Update` to refresh the data, `fetchBuilds` is invoked with the filter options. The API implementation is the expected to fetch build information from somewhere, format it into a generic and rather simpe type `Build` (also defined in `types.ts`). The API can optionally signal completion for a progress bar in the UI. + +When this plugin has fetched the builds, it will transpose the list of builds (and build stages) into a tree of build stages. As build pipelines sometimes change, certain stages might end or begin within the timerange of the view. diff --git a/plugins/cicd-statistics/api-report.md b/plugins/cicd-statistics/api-report.md new file mode 100644 index 0000000000..aef376c9b8 --- /dev/null +++ b/plugins/cicd-statistics/api-report.md @@ -0,0 +1,182 @@ +## API Report File for "@backstage/plugin-cicd-statistics" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { ApiRef } from '@backstage/core-plugin-api'; +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; +import { RouteRef } from '@backstage/core-plugin-api'; + +// Warning: (ae-missing-release-tag) "AbortError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class AbortError extends Error {} + +// Warning: (ae-missing-release-tag) "branchTypes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const branchTypes: Array; + +// Warning: (ae-missing-release-tag) "Build" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface Build { + buildType: FilterBranchType; + duration: number; + id: string; + // (undocumented) + raw?: unknown; + requestedAt: Date; + stages: Array; + status: FilterStatusType; +} + +// Warning: (ae-missing-release-tag) "BuildWithRaw" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type BuildWithRaw = Build & { + raw: T; +}; + +// Warning: (ae-missing-release-tag) "CicdConfiguration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface CicdConfiguration { + availableStatuses: ReadonlyArray; + defaults: Partial; + formatStageName: (parentNames: Array, stageName: string) => string; +} + +// Warning: (ae-missing-release-tag) "CicdDefaults" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface CicdDefaults { + collapsedLimit: number; + // (undocumented) + filterStatus: Array; + // (undocumented) + filterType: FilterBranchType<'all'>; + lowercaseNames: boolean; + normalizeTimeRange: boolean; + // (undocumented) + timeFrom: Date; + // (undocumented) + timeTo: Date; +} + +// Warning: (ae-missing-release-tag) "CicdState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface CicdState { + // (undocumented) + builds: Array; +} + +// Warning: (ae-missing-release-tag) "CicdStatisticsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface CicdStatisticsApi { + // (undocumented) + fetchBuilds(options: FetchBuildsOptions): Promise; + // (undocumented) + getConfiguration(): Promise>; +} + +// Warning: (ae-missing-release-tag) "cicdStatisticsApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const cicdStatisticsApiRef: ApiRef; + +// Warning: (ae-missing-release-tag) "cicdStatisticsPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const cicdStatisticsPlugin: BackstagePlugin< + { + entityContent: RouteRef; + }, + {} +>; + +// Warning: (ae-forgotten-export) The symbol "EntityPageCicdCharts" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "EntityCicdStatisticsContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const EntityCicdStatisticsContent: EntityPageCicdCharts; + +// Warning: (ae-missing-release-tag) "FetchBuildsOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface FetchBuildsOptions { + // (undocumented) + abortSignal: AbortSignal; + // (undocumented) + entity: Entity; + // (undocumented) + filterStatus: Array>; + // (undocumented) + filterType: FilterBranchType<'all'>; + // (undocumented) + timeFrom: Date; + // (undocumented) + timeTo: Date; + // (undocumented) + updateProgress: UpdateProgress; +} + +// Warning: (ae-missing-release-tag) "FilterBranchType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type FilterBranchType = + | Extra + | 'master' + | 'branch'; + +// Warning: (ae-missing-release-tag) "FilterStatusType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type FilterStatusType = + | Extra + | 'unknown' + | 'enqueued' + | 'scheduled' + | 'running' + | 'aborted' + | 'succeeded' + | 'failed' + | 'stalled' + | 'expired'; + +// Warning: (ae-missing-release-tag) "rootCatalogCicdStatsRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const rootCatalogCicdStatsRouteRef: RouteRef; + +// Warning: (ae-missing-release-tag) "Stage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface Stage { + duration: number; + // (undocumented) + name: string; + stages?: Array; +} + +// Warning: (ae-missing-release-tag) "statusTypes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const statusTypes: Array; + +// Warning: (ae-missing-release-tag) "UpdateProgress" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type UpdateProgress = ( + completed: number, + total: number, + started?: number, +) => void; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json new file mode 100644 index 0000000000..8fad2b25f3 --- /dev/null +++ b/plugins/cicd-statistics/package.json @@ -0,0 +1,53 @@ +{ + "name": "@backstage/plugin-cicd-statistics", + "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": false, + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/cicd-statistics" + }, + "keywords": [ + "backstage" + ], + "scripts": { + "build": "backstage-cli build", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/catalog-model": "^0.9.8", + "@backstage/core-plugin-api": "^0.4.1", + "@backstage/plugin-catalog-react": "^0.6.9", + "@date-io/date-fns": "^1.3.13", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.11.2", + "@material-ui/lab": "4.0.0-alpha.57", + "@material-ui/pickers": "^3.3.10", + "already": "^3.2.0", + "date-fns": "^2.27.0", + "lodash": "^4.17.21", + "react-use": "^17.3.1", + "recharts": "^2.1.5" + }, + "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0", + "react": "^16.13.1 || ^17.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/cicd-statistics/src/apis/cicd-statistics.ts b/plugins/cicd-statistics/src/apis/cicd-statistics.ts new file mode 100644 index 0000000000..714900a1bd --- /dev/null +++ b/plugins/cicd-statistics/src/apis/cicd-statistics.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createApiRef } from '@backstage/core-plugin-api'; + +import { CicdStatisticsApi } from './types'; + +export const cicdStatisticsApiRef = createApiRef({ + id: 'cicd-statistics-api', +}); diff --git a/plugins/cicd-statistics/src/apis/index.ts b/plugins/cicd-statistics/src/apis/index.ts new file mode 100644 index 0000000000..cb2fff3700 --- /dev/null +++ b/plugins/cicd-statistics/src/apis/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './types'; +export * from './cicd-statistics'; diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts new file mode 100644 index 0000000000..1f2fa8a5b9 --- /dev/null +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -0,0 +1,225 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; + +/** + * This is a generic enum of build statuses. + * + * If all of these aren't applicable to the underlying CI/CD, these can be + * configured to be hidden, using the `availableStatuses` in `CicdConfiguration`. + */ +export type FilterStatusType = + | Extra + | 'unknown' + | 'enqueued' + | 'scheduled' + | 'running' + | 'aborted' + | 'succeeded' + | 'failed' + | 'stalled' + | 'expired'; +export const statusTypes: Array = [ + 'succeeded', + 'failed', + 'enqueued', + 'scheduled', + 'running', + 'aborted', + 'stalled', + 'expired', + 'unknown', +]; + +/** + * The branch enum of either 'master' or 'branch' (or possibly the meta 'all'). + * + * The concept of what constitues a master branch is generic. It might be called + * something like 'release' or 'main' or 'trunk' in the underlying CI/CD system, + * which is then up to the Api to map accordingly. + */ +export type FilterBranchType = + | Extra + | 'master' + | 'branch'; +export const branchTypes: Array = ['master', 'branch']; + +/** + * A Stage is a part of either a Build or a parent Stage. + * + * This may be called things like Stage or Step or Task in CI/CD systems, but is + * generic here. There's also no concept of parallelism which might exist within + * some stages. + */ +export interface Stage { + name: string; + + /** Stage duration in milliseconds */ + duration: number; + + /** Sub stages within this stage */ + stages?: Array; +} + +/** + * Generic Build type. + * + * A build has e.g. a build type (master/branch), a status and (possibly) sub stages. + */ +export interface Build { + raw?: unknown; + + /** Build id */ + id: string; + + /** The status of the build */ + status: FilterStatusType; + + /** Branch type */ + buildType: FilterBranchType; + + /** Time when the build started */ + requestedAt: Date; + + /** The overall duration of the build */ + duration: number; + + /** Top-level build stages */ + stages: Array; +} + +/** + * Helper type which is a Build with a certain typed 'raw' field. + * + * This can be useful in an Api to use while mapping internal data structures + * (raw) into generic builds. + */ +export type BuildWithRaw = Build & { + raw: T; +}; + +/** + * Default settings for the fetching options and view options. + * + * These are all optional, but can be overridden from the Api to whatever makes + * most sense for that implementation. + */ +export interface CicdDefaults { + timeFrom: Date; + timeTo: Date; + filterStatus: Array; + filterType: FilterBranchType<'all'>; + + /** Lower-case all stage names (to potentially merge stages with different cases) */ + lowercaseNames: boolean; + /** Normalize the from-to date range in all charts */ + normalizeTimeRange: boolean; + /** Default collapse the stages with a max-duration below this value */ + collapsedLimit: number; +} + +/** + * A configuration interface which the Api must implement. + * + * When the UI for the CI/CD Statistics is loaded, it begins with fetching the + * configuration before anything else. + * + * All of these fields are optional though, and will fallback to hard-coded defaults. + */ +export interface CicdConfiguration { + /** + * This field can be used to override what statuses are available + */ + availableStatuses: ReadonlyArray; + + /** + * When transposing the list of builds into a tree of stages, the stage names + * will be transformed through this function. + * + * Override this for a custom implementation. The default will try to remove + * parent names off of child names, if they are prepended by them. + * + * For example; if a stage has the name 'Install' and a child stage has the + * name 'Install - Fetch dependencies', the child name will be replaced with + * 'Fetch dependencies'. + */ + formatStageName: (parentNames: Array, stageName: string) => string; + + /** + * Default options for the UI + */ + defaults: Partial; +} + +/** + * If the Api implements support for aborting the fetching of builds, throw an + * AbortError of this type + */ +export class AbortError extends Error {} + +/** + * The result type for `fetchBuilds`. + */ +export interface CicdState { + builds: Array; +} + +/** + * When fetching, if applicable, the Api can feedback progress back to the UI. + * + * Use the `updateProgress(completed, total, started?)` to signal that + * `completed` builds out of a `total` has finished. Optionally use the + * `started` to signal how many builds have been started in total (i.e. at least + * the amount of `completed`). + * + * This can be called at any rate. Rate limiting (debouncing) is implemented in + * the UI. + */ +export type UpdateProgress = ( + completed: number, + total: number, + started?: number, +) => void; + +/** + * When fetching, the Api should fetch build information about the `entity` and + * respect the `timeFrom`, `timeTo`, `filterStatus` and `filterType`. + * + * Optionally implement support for `updateProgress` and `abortSignal` if + * preferred. + * + * When the UI re-fetches, it will abort any previous fetching, so polling + * `abortSignal.aborted`, and possibly throwing an `AbortError`, can be useful. + */ +export interface FetchBuildsOptions { + entity: Entity; + updateProgress: UpdateProgress; + abortSignal: AbortSignal; + timeFrom: Date; + timeTo: Date; + filterStatus: Array>; + filterType: FilterBranchType<'all'>; +} + +/** + * The interface which is mapped to the `cicdStatisticsApiRef` which is used by + * the UI. + */ +export interface CicdStatisticsApi { + getConfiguration(): Promise>; + fetchBuilds(options: FetchBuildsOptions): Promise; +} diff --git a/plugins/cicd-statistics/src/charts/colors.ts b/plugins/cicd-statistics/src/charts/colors.ts new file mode 100644 index 0000000000..e1ccb67fea --- /dev/null +++ b/plugins/cicd-statistics/src/charts/colors.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FilterStatusType } from '../apis/types'; + +export const statusColorMap: Record = { + unknown: '#3d01a4', + enqueued: '#7ad1b9', + scheduled: '#0391ce', + running: '#f3f318', + aborted: '#8600af', + succeeded: '#66b032', + failed: '#fe2712', + stalled: '#fb9904', + expired: '#a7194b', +}; + +export const fireColors: Array<[percent: string, color: string]> = [ + ['5%', '#e19678'], + ['30%', '#dfe178'], + ['50%', '#82ca9d'], + ['95%', '#82ca9d'], +]; + +export const colorStroke = '#c0c0c0'; +export const colorStrokeAvg = '#788ee1'; diff --git a/plugins/cicd-statistics/src/charts/conversions.ts b/plugins/cicd-statistics/src/charts/conversions.ts new file mode 100644 index 0000000000..0f2b024d1f --- /dev/null +++ b/plugins/cicd-statistics/src/charts/conversions.ts @@ -0,0 +1,238 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { map } from 'already'; + +import { Build, Stage, FilterStatusType, statusTypes } from '../apis/types'; +import { + Averagify, + ChartableStage, + ChartableStageAnalysis, + ChartableStageDatapoints, + ChartableStagesAnalysis, +} from './types'; + +function makeStage(name: string): ChartableStage { + return { + analysis: { + unknown: { avg: 0, max: 0, min: 0 }, + enqueued: { avg: 0, max: 0, min: 0 }, + scheduled: { avg: 0, max: 0, min: 0 }, + running: { avg: 0, max: 0, min: 0 }, + aborted: { avg: 0, max: 0, min: 0 }, + succeeded: { avg: 0, max: 0, min: 0 }, + failed: { avg: 0, max: 0, min: 0 }, + stalled: { avg: 0, max: 0, min: 0 }, + expired: { avg: 0, max: 0, min: 0 }, + }, + combinedAnalysis: { avg: 0, max: 0, min: 0 }, + statusSet: new Set(), + name, + values: [], + stages: new Map(), + }; +} + +export interface ChartableStagesOptions { + normalizeTimeRange: boolean; +} + +/** + * Converts a list of builds, each with a tree of stages (and durations) into a + * merged tree of stages, and calculates {avg, min, max} of each stage. + */ +export async function buildsToChartableStages( + builds: Array, + options: ChartableStagesOptions, +): Promise { + const { normalizeTimeRange } = options; + + const total: ChartableStage = makeStage('Total'); + + const recurseDown = ( + status: FilterStatusType, + stageMap: Map, + stage: Stage, + __epoch: number, + ) => { + const { name, duration } = stage; + + const subChartableStage = getOrSetStage(stageMap, name); + + subChartableStage.statusSet.add(status); + subChartableStage.values.push({ + __epoch, + [status]: duration, + [`${status} avg`]: duration, + }); + + stage.stages?.forEach(subStage => { + recurseDown(status, subChartableStage.stages, subStage, __epoch); + }); + }; + + const stages = new Map(); + + await map(builds, { chunk: 'idle' }, build => { + const { duration, requestedAt, status } = build; + const __epoch = requestedAt.getTime(); + + total.statusSet.add(status); + total.values.push({ + __epoch, + [status]: duration, + [`${status} avg`]: duration, + }); + + build.stages?.forEach(subStage => { + recurseDown(status, stages, subStage, __epoch); + }); + }); + + const allEpochs = normalizeTimeRange + ? builds.map(build => build.requestedAt.getTime()) + : []; + + // Recurse down again and calculate averages + await map([...stages.values()], { chunk: 'idle' }, stage => + finalizeStage(stage, { allEpochs, averageWidth: 10 }), + ); + finalizeStage(total, { allEpochs, averageWidth: 10 }); + + return { total, stages }; +} + +function getAnalysis( + values: Array, + status: FilterStatusType, +): ChartableStageAnalysis { + const analysis: ChartableStageAnalysis = { + max: 0, + min: 0, + avg: 0, + }; + + const definedValues = values.filter( + value => typeof value[status] !== 'undefined', + ); + + analysis.max = definedValues.reduce( + (prev, cur) => Math.max(prev, cur[status]!), + 0, + ); + analysis.min = definedValues.reduce( + (prev, cur) => Math.min(prev, cur[status]!), + analysis.max, + ); + analysis.avg = + definedValues.length === 0 + ? 0 + : definedValues.reduce((prev, cur) => prev + cur[status]!, 0) / + values.length; + + return analysis; +} + +interface FinalizeStageOptions { + averageWidth: number; + allEpochs: Array; +} + +/** + * Calculate {avg, min, max} of a stage and its sub stages, recursively. + * This is calculated per status (successful, failed, etc). + */ +function finalizeStage(stage: ChartableStage, options: FinalizeStageOptions) { + const { averageWidth, allEpochs } = options; + const { values, analysis, combinedAnalysis } = stage; + + if (allEpochs.length > 0) { + const valueEpochs = new Set(values.map(value => value.__epoch)); + + allEpochs.forEach(epoch => { + if (!valueEpochs.has(epoch)) { + values.push({ __epoch: epoch }); + } + }); + } + + values.sort((a, b) => a.__epoch - b.__epoch); + + const avgDuration: [duration: number, count: number] = [0, 0]; + + statusTypes.forEach(status => { + analysis[status] = getAnalysis(values, status); + + const durationsIndexes = values + .map(value => value[status]) + .map((duration, index) => ({ index, duration })) + .filter(({ duration }) => typeof duration !== 'undefined') + .map(({ index }) => index); + const durationsDense = values + .map(value => value[status]) + .filter( + (duration): duration is number => typeof duration !== 'undefined', + ); + + avgDuration[0] += durationsDense.reduce((prev, cur) => prev + cur, 0); + avgDuration[1] += durationsDense.length; + + const averages = durationsDense.map((_, i) => + average( + durationsDense.slice( + Math.max(i - averageWidth, 0), + Math.min(i + averageWidth, durationsDense.length), + ), + ), + ); + + averages.forEach((avg, index) => { + const key: Averagify = `${status} avg`; + values[durationsIndexes[index]][key] = avg; + }); + }); + + const analysisValues = Object.values(analysis); + combinedAnalysis.max = analysisValues.reduce( + (prev, cur) => Math.max(prev, cur.max), + 0, + ); + combinedAnalysis.min = analysisValues.reduce( + (prev, cur) => Math.min(prev, cur.min), + combinedAnalysis.max, + ); + combinedAnalysis.avg = !avgDuration[1] ? 0 : avgDuration[0] / avgDuration[1]; + + stage.stages.forEach(subStage => finalizeStage(subStage, options)); +} + +function average(values: number[]): number { + return !values.length + ? 0 + : Math.round(values.reduce((prev, cur) => prev + cur, 0) / values.length); +} + +function getOrSetStage( + stages: Map, + name: string, +): ChartableStage { + const stage = stages.get(name); + if (stage) return stage; + + const newStage: ChartableStage = makeStage(name); + stages.set(name, newStage); + return newStage; +} diff --git a/plugins/cicd-statistics/src/charts/stage-chart.tsx b/plugins/cicd-statistics/src/charts/stage-chart.tsx new file mode 100644 index 0000000000..f407a274b1 --- /dev/null +++ b/plugins/cicd-statistics/src/charts/stage-chart.tsx @@ -0,0 +1,212 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { Fragment, useMemo } from 'react'; +import { + Area, + ComposedChart, + XAxis, + YAxis, + YAxisProps, + CartesianGrid, + Legend, + LegendProps, + Line, + Tooltip, + ResponsiveContainer, +} from 'recharts'; +import Alert from '@material-ui/lab/Alert'; +import { + Accordion, + AccordionSummary, + AccordionDetails, + Grid, + Typography, +} from '@material-ui/core'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; + +import { statusTypes } from '../apis/types'; +import { ChartableStage } from './types'; +import { + pickElements, + labelFormatter, + tickFormatterX, + tickFormatterY, + tooltipValueFormatter, + formatDuration, +} from './utils'; +import { + statusColorMap, + fireColors, + colorStroke, + colorStrokeAvg, +} from './colors'; + +const fullWidth = { + width: '100%', +}; + +const transitionProps = { unmountOnExit: true }; + +export interface StageChartProps { + stage: ChartableStage; + + defaultCollapsed?: number; + zeroYAxis?: boolean; +} + +export function StageChart(props: StageChartProps) { + const { stage, ...chartOptions } = props; + const { defaultCollapsed = 0, zeroYAxis = false } = chartOptions; + + const ticks = useMemo( + () => pickElements(stage.values, 8).map(val => val.__epoch), + [stage.values], + ); + const domainY = useMemo( + () => [zeroYAxis ? 0 : 'auto', 'auto'] as YAxisProps['domain'], + [zeroYAxis], + ); + const statuses = useMemo( + () => statusTypes.filter(status => stage.statusSet.has(status)), + [stage.statusSet], + ); + const legendPayload = useMemo( + (): LegendProps['payload'] => + statuses.map(status => ({ + value: status, + type: 'line', + id: status, + color: statusColorMap[status], + })), + [statuses], + ); + + return ( + defaultCollapsed} + TransitionProps={transitionProps} + > + }> + + {stage.name} (avg {formatDuration(stage.combinedAnalysis.avg)}) + + + + {stage.values.length === 0 ? ( + No data + ) : ( + + + + + + + {fireColors.map(([percent, color]) => ( + + ))} + + + {statuses.length > 1 && } + + + + + {statuses.map(status => ( + + 1 + ? statusColorMap[status] + : colorStroke + } + fillOpacity={statuses.length > 1 ? 0.5 : 1} + fill={ + statuses.length > 1 + ? statusColorMap[status] + : 'url(#colorDur)' + } + connectNulls + /> + 1 + ? statusColorMap[status] + : colorStrokeAvg + } + opacity={0.8} + strokeWidth={2} + dot={false} + connectNulls + /> + + ))} + + + + {stage.stages.size === 0 ? null : ( + + + }> + Sub stages ({stage.stages.size}) + + +
+ {[...stage.stages.values()].map(subStage => ( + + ))} +
+
+
+
+ )} +
+ )} +
+
+ ); +} diff --git a/plugins/cicd-statistics/src/charts/status-chart.tsx b/plugins/cicd-statistics/src/charts/status-chart.tsx new file mode 100644 index 0000000000..c3153c1700 --- /dev/null +++ b/plugins/cicd-statistics/src/charts/status-chart.tsx @@ -0,0 +1,133 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { Fragment, useMemo } from 'react'; +import { + Bar, + ComposedChart, + XAxis, + YAxis, + CartesianGrid, + Legend, + LegendProps, + Tooltip, + ResponsiveContainer, +} from 'recharts'; +import Alert from '@material-ui/lab/Alert'; +import { + Accordion, + AccordionSummary, + AccordionDetails, + Typography, +} from '@material-ui/core'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import { formatISO9075, parseISO } from 'date-fns'; +import { countBy } from 'lodash'; + +import { Build, FilterStatusType, statusTypes } from '../apis/types'; +import { labelFormatterWithoutTime, tickFormatterX } from './utils'; +import { statusColorMap } from './colors'; + +export interface StatusChartProps { + builds: ReadonlyArray; +} + +export function StatusChart(props: StatusChartProps) { + const { builds } = props; + + const { statuses, values } = useMemo(() => { + const buildsByDay = new Map>(); + + const foundStatuses = new Set(); + + builds.forEach(build => { + foundStatuses.add(build.status); + + const dayString = formatISO9075(build.requestedAt, { + representation: 'date', + }); + const dayList = buildsByDay.get(dayString); + if (dayList) { + dayList.push(build); + } else { + buildsByDay.set(dayString, [build]); + } + }); + + return { + statuses: [ + ...statusTypes.filter(status => foundStatuses.has(status)), + ...[...foundStatuses].filter( + status => !(statusTypes as Array).includes(status), + ), + ], + values: [...buildsByDay.entries()].map(([dayString, buildThisDay]) => ({ + __epoch: parseISO(dayString).getTime(), + ...countBy(buildThisDay, 'status'), + })), + }; + }, [builds]); + + const legendPayload = useMemo( + (): LegendProps['payload'] => + statuses.map(status => ({ + value: status, + type: 'line', + id: status, + color: statusColorMap[status as FilterStatusType] ?? '', + })), + [statuses], + ); + + return ( + 1}> + }> + Build count per status + + + {values.length === 0 ? ( + No data + ) : ( + + + + + + + + {statuses.map(status => ( + + + + ))} + + + )} + + + ); +} diff --git a/plugins/cicd-statistics/src/charts/types.ts b/plugins/cicd-statistics/src/charts/types.ts new file mode 100644 index 0000000000..6355343ee0 --- /dev/null +++ b/plugins/cicd-statistics/src/charts/types.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FilterStatusType } from '../apis/types'; + +export type Averagify = `${T} avg`; + +export type ChartableStageDatapoints = { + __epoch: number; +} & { + [status in FilterStatusType]?: number; +} & { + [status in Averagify]?: number; +}; + +export interface ChartableStageAnalysis { + max: number; + min: number; + avg: number; +} + +export interface ChartableStage { + analysis: Record; + combinedAnalysis: ChartableStageAnalysis; + name: string; + values: Array; + statusSet: Set; + + stages: Map; +} + +export interface ChartableStagesAnalysis { + total: ChartableStage; + stages: Map; +} diff --git a/plugins/cicd-statistics/src/charts/utils.tsx b/plugins/cicd-statistics/src/charts/utils.tsx new file mode 100644 index 0000000000..8fcd5e08d6 --- /dev/null +++ b/plugins/cicd-statistics/src/charts/utils.tsx @@ -0,0 +1,87 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { CSSProperties } from 'react'; +import { formatISO9075, formatDistanceStrict } from 'date-fns'; + +const infoText: CSSProperties = { color: 'InfoText' }; + +/** + * Picks {num} elements from {arr} evenly, from the first to the last + */ +export function pickElements(arr: ReadonlyArray, num: number): Array { + if (arr.length <= num) { + return [...arr]; + } + + if (num < 2) { + return [arr[arr.length / 2]]; + } + + const step = arr.length / (num - 1); + return [ + ...Array.from(Array(num - 1)).map( + (_, index) => arr[Math.round(index * step)], + ), + arr[arr.length - 1], + ]; +} + +export function labelFormatter(epoch: number) { + return {formatISO9075(new Date(epoch))}; +} + +export function labelFormatterWithoutTime(epoch: number) { + return ( + + {formatISO9075(new Date(epoch), { representation: 'date' })} + + ); +} + +export function tickFormatterX(epoch: number) { + return formatISO9075(new Date(epoch), { representation: 'date' }); +} + +export function tickFormatterY(duration: number) { + if (duration === 0) { + return '0'; + } else if (duration < 500) { + return `${duration} ms`; + } + return formatDuration(duration) + .replace(/second.*/, 'sec') + .replace(/minute.*/, 'min') + .replace(/hour.*/, 'h') + .replace(/day.*/, 'd') + .replace(/month.*/, 'm') + .replace(/year.*/, 'y'); +} + +export function tooltipValueFormatter(duration: number, name: string) { + return [ + + {name}: {formatDuration(duration)} + , + null, + ]; +} + +const baseDate = new Date(); +const baseEpoch = baseDate.getTime(); +export function formatDuration(milliseconds: number) { + return formatDistanceStrict(baseDate, new Date(baseEpoch + milliseconds)); +} diff --git a/plugins/cicd-statistics/src/components/button-switch.tsx b/plugins/cicd-statistics/src/components/button-switch.tsx new file mode 100644 index 0000000000..03c7066171 --- /dev/null +++ b/plugins/cicd-statistics/src/components/button-switch.tsx @@ -0,0 +1,117 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useCallback, MouseEvent } from 'react'; +import { ButtonGroup, Button, Tooltip, Zoom } from '@material-ui/core'; + +export interface SwitchValueDetails { + value: T; + tooltip?: string; +} + +export type SwitchValue = T | SwitchValueDetails; + +export interface ButtonSwitchPropsBase { + values: ReadonlyArray>; + vertical?: boolean; +} +export interface ButtonSwitchPropsSingle + extends ButtonSwitchPropsBase { + multi?: false; + selection: T; + onChange: (selected: T) => void; +} +export interface ButtonSwitchPropsMulti + extends ButtonSwitchPropsBase { + multi: true; + selection: ReadonlyArray; + onChange: (selected: Array) => void; +} + +export type ButtonSwitchProps = + | ButtonSwitchPropsSingle + | ButtonSwitchPropsMulti; + +function switchValue(value: SwitchValue): T { + return typeof value === 'object' ? value.value : value; +} + +export function ButtonSwitch(props: ButtonSwitchProps) { + const { values, vertical = false } = props; + + const onClick = useCallback( + (ev: MouseEvent) => { + const value = (ev.target as HTMLSpanElement).textContent!; + if (props.multi) { + props.onChange( + props.selection.includes(value as T) + ? props.selection.filter(val => val !== value) + : [...props.selection, value as T], + ); + } else { + props.onChange(value as T); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [values, props.selection, props.multi, props.onChange], + ); + + const hasSelection = (value: T) => { + if (props.multi) { + return props.selection.includes(value); + } + return props.selection === value; + }; + + const tooltipify = (value: SwitchValue, elem: JSX.Element) => + typeof value === 'object' && value.tooltip ? ( + + {elem} + + ) : ( + elem + ); + + return ( + + {values.map(value => + tooltipify( + value, + , + ), + )} + + ); +} diff --git a/plugins/cicd-statistics/src/components/chart-filters.tsx b/plugins/cicd-statistics/src/components/chart-filters.tsx new file mode 100644 index 0000000000..a6e2b9ede3 --- /dev/null +++ b/plugins/cicd-statistics/src/components/chart-filters.tsx @@ -0,0 +1,382 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useCallback, useState, useEffect, useMemo } from 'react'; +import { + Button, + Card, + CardHeader, + CardContent, + FormControl, + FormGroup, + FormControlLabel, + Switch, + Theme, + Tooltip, + Typography, + makeStyles, +} from '@material-ui/core'; +import { + MuiPickersUtilsProvider, + KeyboardDatePicker, +} from '@material-ui/pickers'; +import { subMonths, isSameDay } from 'date-fns'; +import DateFnsUtils from '@date-io/date-fns'; + +import { + CicdConfiguration, + FilterBranchType, + FilterStatusType, +} from '../apis/types'; +import { ButtonSwitch, SwitchValue } from './button-switch'; +import { Toggle } from './toggle'; + +const useStyles = makeStyles( + theme => ({ + rootCard: { + padding: theme.spacing(0, 0, 0, 0), + margin: theme.spacing(0, 0, 2, 0), + }, + updateButton: { + margin: theme.spacing(1, 0, 0, 0), + }, + header: { + margin: theme.spacing(0, 0, 0, 0), + textTransform: 'uppercase', + fontSize: 12, + fontWeight: 'bold', + }, + title: { + margin: theme.spacing(3, 0, 1, 0), + textTransform: 'uppercase', + fontSize: 12, + fontWeight: 'bold', + '&:first-child': { + margin: theme.spacing(1, 0, 1, 0), + }, + }, + }), + { + name: 'CicdStatisticsChartFilters', + }, +); + +export type BranchSelection = FilterBranchType<'all'>; +export type StatusSelection = FilterStatusType; + +export interface ChartFilter { + fromDate: Date; + toDate: Date; + branch: BranchSelection; + status: Array; +} + +export function getDefaultChartFilter( + cicdConfiguration: CicdConfiguration, +): ChartFilter { + const toDate = cicdConfiguration.defaults?.timeTo ?? new Date(); + return { + fromDate: cicdConfiguration.defaults?.timeFrom ?? subMonths(toDate, 1), + toDate, + branch: cicdConfiguration.defaults?.filterType ?? 'branch', + status: + cicdConfiguration.defaults?.filterStatus ?? + cicdConfiguration.availableStatuses.filter( + status => status === 'succeeded', + ), + }; +} + +function isSameChartFilter(a: ChartFilter, b: ChartFilter): boolean { + return ( + a.branch === b.branch && + [...a.status].sort().join(' ') === [...b.status].sort().join(' ') && + isSameDay(a.fromDate, b.fromDate) && + isSameDay(a.toDate, b.toDate) + ); +} + +export interface ViewOptions { + lowercaseNames: boolean; + normalizeTimeRange: boolean; +} + +export function getDefaultViewOptions( + cicdConfiguration: CicdConfiguration, +): ViewOptions { + return { + lowercaseNames: cicdConfiguration.defaults?.lowercaseNames ?? false, + normalizeTimeRange: cicdConfiguration.defaults?.normalizeTimeRange ?? true, + }; +} + +export interface ChartFiltersProps { + cicdConfiguration: CicdConfiguration; + initialFetchFilter: ChartFilter; + currentFetchFilter?: ChartFilter; + onChangeFetchFilter(filter: ChartFilter): void; + updateFetchFilter(filter: ChartFilter): void; + + initialViewOptions: ViewOptions; + onChangeViewOptions(filter: ViewOptions): void; +} + +interface InternalRef { + first: boolean; +} + +export function ChartFilters(props: ChartFiltersProps) { + const { + cicdConfiguration, + initialFetchFilter, + currentFetchFilter, + onChangeFetchFilter, + updateFetchFilter, + initialViewOptions, + onChangeViewOptions, + } = props; + + const classes = useStyles(); + + const [internalRef] = useState({ first: true }); + + const [useNowAsToDate, setUseNowAsToDate] = useState(true); + const [toDate, setToDate] = useState(initialFetchFilter.toDate); + const [fromDate, setFromDate] = useState(initialFetchFilter.fromDate); + + const branchValues: Array> = [ + 'master', + 'branch', + { + value: 'all', + tooltip: + 'NOTE; If the build pipelines are very different between master and branch ' + + 'builds, viewing them combined might not result in a very useful chart', + }, + ]; + const [branch, setBranch] = useState(initialFetchFilter.branch); + + const statusValues: ReadonlyArray = + cicdConfiguration.availableStatuses; + const [selectedStatus, setSelectedStatus] = useState( + initialFetchFilter.status, + ); + + const [viewOptions, setViewOptions] = useState(initialViewOptions); + + const setLowercaseNames = useCallback( + (lowercaseNames: boolean) => { + setViewOptions(old => ({ ...old, lowercaseNames })); + }, + [setViewOptions], + ); + + const setNormalizeTimeRange = useCallback( + (normalizeTimeRange: boolean) => { + setViewOptions(old => ({ ...old, normalizeTimeRange })); + }, + [setViewOptions], + ); + + useEffect(() => { + onChangeViewOptions(viewOptions); + }, [onChangeViewOptions, viewOptions]); + + useEffect(() => { + if (internalRef.first) { + // Skip calling onChangeFetchFilter first time + internalRef.first = false; + return; + } + onChangeFetchFilter({ + toDate, + fromDate, + branch, + status: selectedStatus, + }); + }, [ + internalRef, + toDate, + fromDate, + branch, + selectedStatus, + onChangeFetchFilter, + ]); + + const toggleUseNowAsDate = useCallback(() => { + setUseNowAsToDate(!useNowAsToDate); + if (!isSameDay(toDate, new Date())) { + setToDate(new Date()); + } + }, [useNowAsToDate, toDate]); + + const hasFetchFilterChanges = useMemo( + () => + !currentFetchFilter || + !isSameChartFilter( + { + toDate, + fromDate, + branch, + status: selectedStatus, + }, + currentFetchFilter, + ), + [toDate, fromDate, branch, selectedStatus, currentFetchFilter], + ); + + const updateFilter = useCallback(() => { + updateFetchFilter({ + toDate, + fromDate, + branch, + status: selectedStatus, + }); + }, [toDate, fromDate, branch, selectedStatus, updateFetchFilter]); + + return ( + + + + Update + + } + title={ + + Fetching options + + } + /> + + + Date range + + setFromDate(date as any as Date)} + /> +
+ + + + } + label="To today" + /> + {useNowAsToDate ? null : ( + setToDate(date as any as Date)} + /> + )} + + + + Branch + + + values={branchValues} + selection={branch} + onChange={setBranch} + /> + + Status + + + values={statusValues} + multi + vertical + selection={selectedStatus} + onChange={setSelectedStatus} + /> +
+
+ + + View options + + } + /> + + + + Lowercase names + + + + + Normalize time range + + + + +
+ ); +} diff --git a/plugins/cicd-statistics/src/components/progress.tsx b/plugins/cicd-statistics/src/components/progress.tsx new file mode 100644 index 0000000000..1b707573c0 --- /dev/null +++ b/plugins/cicd-statistics/src/components/progress.tsx @@ -0,0 +1,147 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { DependencyList } from 'react'; +import { useAsync } from 'react-use'; +import { Box, LinearProgress } from '@material-ui/core'; +import Alert from '@material-ui/lab/Alert'; +import { useApp } from '@backstage/core-plugin-api'; + +// Matching react-use, only has loading/error/value +type AsyncState = + | { + loading: boolean; + error?: undefined; + value?: undefined; + } + | { + loading: true; + error?: Error | undefined; + value?: T; + } + | { + loading: false; + error: Error; + value?: undefined; + } + | { + loading: false; + error?: undefined; + value: T; + }; + +export type ProgressAsLoading = { + loading: true; + progress?: number; + progressBuffer?: number; + error?: undefined; + value?: undefined; +}; +export type ProgressAsError = { + loading?: false | undefined; + progress?: undefined; + progressBuffer?: undefined; + error: Error; + value?: undefined; +}; +export type ProgressAsValue = { + loading?: false | undefined; + progress?: undefined; + progressBuffer?: undefined; + error?: undefined; + value: T; +}; + +/** + * An AsyncState but with the addition of progress (decimal 0-1) to allow + * rendering a progress bar while waiting. + */ +export type Progress = + | ProgressAsLoading + | ProgressAsError + | ProgressAsValue; + +const sentry = Symbol(); + +/** + * Casts an AsyncState or Progress into its non-succeeded sub types + */ +type Unsuccessful | AsyncState> = + S extends Progress + ? ProgressAsLoading | ProgressAsError + : Omit, 'value'>; + +/** + * Similar to useAsync except it "waits" for a dependent (upstream) async state + * to finish first, otherwise it forwards the dependent pending state. + * + * When/if the dependent state has settled successfully, the callback will be + * invoked for a new layer of async state with the dependent (upstream) success + * result as argument. + */ +export function useAsyncChain | AsyncState, R>( + parentState: S, + fn: (value: NonNullable) => Promise, + deps: DependencyList, +): Unsuccessful | AsyncState { + const childState = useAsync( + async () => (!parentState.value ? sentry : fn(parentState.value)), + [!parentState.error, !parentState.loading, parentState.value, ...deps], + ); + + if (!parentState.value) { + return parentState as Unsuccessful; + } else if (childState.value === sentry) { + return { loading: true }; + } + return childState as AsyncState; +} + +export function renderFallbacks( + state: Progress | AsyncState, + success: (value: T) => JSX.Element, +): JSX.Element { + if (state.loading) { + return ; + } else if (state.error) { + return {state.error.stack}; + } + + return success(state.value!); +} + +export function ViewProgress({ + state, +}: { + state: ProgressAsLoading | { loading: boolean }; +}) { + const { Progress } = useApp().getComponents(); + + const stateAsProgress = state as ProgressAsLoading; + + if (!stateAsProgress.progress && !stateAsProgress.progressBuffer) { + return ; + } + return ( + + + + ); +} diff --git a/plugins/cicd-statistics/src/components/toggle.tsx b/plugins/cicd-statistics/src/components/toggle.tsx new file mode 100644 index 0000000000..02f1941d85 --- /dev/null +++ b/plugins/cicd-statistics/src/components/toggle.tsx @@ -0,0 +1,40 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useCallback, PropsWithChildren } from 'react'; +import { FormControlLabel, Switch } from '@material-ui/core'; + +export interface ToggleProps { + checked: boolean; + setChecked: (checked: boolean) => void; +} + +export function Toggle({ + checked, + setChecked, + children, +}: PropsWithChildren) { + const toggler = useCallback(() => { + setChecked(!checked); + }, [checked, setChecked]); + + return ( + } + label={children} + /> + ); +} diff --git a/plugins/cicd-statistics/src/entity-page.tsx b/plugins/cicd-statistics/src/entity-page.tsx new file mode 100644 index 0000000000..d339f52fde --- /dev/null +++ b/plugins/cicd-statistics/src/entity-page.tsx @@ -0,0 +1,175 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useCallback, useState, useMemo, useEffect } from 'react'; +import { Grid, makeStyles, Theme } from '@material-ui/core'; +import { startOfDay, endOfDay } from 'date-fns'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { useApi, errorApiRef } from '@backstage/core-plugin-api'; + +import { + useCicdStatistics, + UseCicdStatisticsOptions, +} from './hooks/use-cicd-statistics'; +import { useCicdConfiguration } from './hooks/use-cicd-configuration'; +import { buildsToChartableStages } from './charts/conversions'; +import { StageChart } from './charts/stage-chart'; +import { StatusChart } from './charts/status-chart'; +import { + ChartFilter, + ChartFilters, + getDefaultChartFilter, + getDefaultViewOptions, + ViewOptions, +} from './components/chart-filters'; +import { AbortError, CicdConfiguration } from './apis'; +import { cleanupBuildTree } from './utils/stage-names'; +import { renderFallbacks, useAsyncChain } from './components/progress'; + +export function EntityPageCicdCharts() { + const state = useCicdConfiguration(); + + return renderFallbacks(state, value => ( + + )); +} + +const useStyles = makeStyles( + theme => ({ + pane: { + padding: theme.spacing(1, 1, 1, 1), + }, + }), + { + name: 'CicdStatisticsView', + }, +); + +interface CicdChartsProps { + cicdConfiguration: CicdConfiguration; +} + +function CicdCharts(props: CicdChartsProps) { + const { cicdConfiguration } = props; + + const errorApi = useApi(errorApiRef); + const { entity } = useEntity(); + + const classes = useStyles(); + + const [chartFilter, setChartFilter] = useState( + getDefaultChartFilter(cicdConfiguration), + ); + const [fetchedChartData, setFetchedChartData] = useState({ + abortController: null as null | AbortController, + chartFilter, + }); + + const [viewOptions, setViewOptions] = useState( + getDefaultViewOptions(cicdConfiguration), + ); + + const fetchStatisticsOptions = useMemo((): UseCicdStatisticsOptions => { + const abortController = new AbortController(); + fetchedChartData.abortController = abortController; + return { + abortController, + entity, + timeFrom: startOfDay(fetchedChartData.chartFilter.fromDate), + timeTo: endOfDay(fetchedChartData.chartFilter.toDate), + filterStatus: fetchedChartData.chartFilter.status, + filterType: fetchedChartData.chartFilter.branch, + }; + }, [entity, fetchedChartData]); + + const statisticsState = useCicdStatistics(fetchStatisticsOptions); + + const updateFilter = useCallback(() => { + // Abort previous fetch + fetchedChartData.abortController?.abort(); + + setFetchedChartData({ abortController: null, chartFilter }); + }, [fetchedChartData, setFetchedChartData, chartFilter]); + + const chartableStagesState = useAsyncChain( + statisticsState, + async value => + buildsToChartableStages( + await cleanupBuildTree(value.builds, { + formatStageName: cicdConfiguration.formatStageName, + lowerCase: viewOptions.lowercaseNames, + }), + { normalizeTimeRange: viewOptions.normalizeTimeRange }, + ), + [statisticsState, cicdConfiguration, viewOptions], + ); + + const onFilterChange = useCallback((filter: ChartFilter) => { + setChartFilter(filter); + }, []); + + const onViewOptionsChange = useCallback( + (options: ViewOptions) => { + setViewOptions(options); + }, + [setViewOptions], + ); + + useEffect(() => { + if ( + !chartableStagesState.error || + chartableStagesState.error instanceof AbortError + ) { + return; + } + errorApi.post(chartableStagesState.error); + }, [errorApi, chartableStagesState.error]); + + const collapsedLimit = cicdConfiguration.defaults.collapsedLimit ?? 60 * 1000; // 1m + + return ( + + + + + + {renderFallbacks(chartableStagesState, chartableStages => ( + <> + {!statisticsState.value?.builds.length ? null : ( + + )} + + {[...chartableStages.stages.entries()].map(([name, stage]) => ( + + ))} + + ))} + + + ); +} diff --git a/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts b/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts new file mode 100644 index 0000000000..89f2c9f666 --- /dev/null +++ b/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts @@ -0,0 +1,59 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useState, useEffect } from 'react'; + +import { CicdConfiguration, statusTypes } from '../apis'; +import { Progress } from '../components/progress'; +import { defaultFormatStageName } from '../utils/stage-names'; +import { useCicdStatisticsApi } from './use-cicd-statistics-api'; + +export function useCicdConfiguration(): Progress { + const cicdStatisticsApi = useCicdStatisticsApi(); + + const [state, setState] = useState>({ + loading: true, + }); + + useEffect(() => { + if (!cicdStatisticsApi) { + setState({ error: new Error('No CI/CD Statistics API installed') }); + return; + } + + cicdStatisticsApi + .getConfiguration() + .then(configuration => { + const { + availableStatuses = statusTypes, + formatStageName = defaultFormatStageName, + defaults = {}, + } = configuration; + setState({ + value: { + availableStatuses, + formatStageName, + defaults, + }, + }); + }) + .catch(error => { + setState({ error }); + }); + }, [cicdStatisticsApi]); + + return state; +} diff --git a/plugins/cicd-statistics/src/hooks/use-cicd-statistics-api.ts b/plugins/cicd-statistics/src/hooks/use-cicd-statistics-api.ts new file mode 100644 index 0000000000..02773b20ef --- /dev/null +++ b/plugins/cicd-statistics/src/hooks/use-cicd-statistics-api.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useApi } from '@backstage/core-plugin-api'; + +import { cicdStatisticsApiRef } from '../apis'; + +export function useCicdStatisticsApi() { + try { + return useApi(cicdStatisticsApiRef); + } catch (err) { + return undefined; + } +} diff --git a/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts b/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts new file mode 100644 index 0000000000..645af9900b --- /dev/null +++ b/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts @@ -0,0 +1,120 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useState, useEffect } from 'react'; +import { debounce } from 'lodash'; +import { Entity } from '@backstage/catalog-model'; + +import { + CicdState, + FetchBuildsOptions, + AbortError, + FilterStatusType, + FilterBranchType, +} from '../apis'; +import { Progress } from '../components/progress'; +import { useCicdStatisticsApi } from './use-cicd-statistics-api'; + +export interface UseCicdStatisticsOptions { + entity: Entity; + abortController: AbortController; + timeFrom: Date; + timeTo: Date; + filterStatus: Array>; + filterType: FilterBranchType<'all'>; +} + +export function useCicdStatistics( + options: UseCicdStatisticsOptions, +): Progress { + const { + entity, + abortController, + timeFrom, + timeTo, + filterStatus, + filterType, + } = options; + + const [state, setState] = useState>({ loading: true }); + + const cicdStatisticsApi = useCicdStatisticsApi(); + + useEffect(() => { + if (!cicdStatisticsApi) { + setState({ error: new Error('No CI/CD Statistics API installed') }); + return () => {}; + } + + let mounted = true; + let completed = false; // successfully or failed + + const updateProgress = debounce((count, total, started = 0) => { + if (mounted && !completed) { + setState({ + loading: true, + progress: !total ? 0 : count / total, + progressBuffer: !total ? 0 : started / total, + }); + } + }, 200); + + const fetchOptions: FetchBuildsOptions = { + entity, + updateProgress, + abortSignal: abortController.signal, + timeFrom, + timeTo, + filterStatus, + filterType, + }; + + (async () => { + return cicdStatisticsApi.fetchBuilds(fetchOptions); + })() + .then(builds => { + completed = true; + if (mounted) { + setState({ + value: builds, + }); + } + }) + .catch(err => { + completed = true; + if (mounted) { + setState({ + error: abortController.signal.aborted ? new AbortError() : err, + }); + } + }); + + return () => { + mounted = false; + abortController.abort(); + }; + }, [ + abortController, + entity, + timeFrom, + timeTo, + filterStatus, + filterType, + cicdStatisticsApi, + ]); + + return state; +} diff --git a/plugins/cicd-statistics/src/index.ts b/plugins/cicd-statistics/src/index.ts new file mode 100644 index 0000000000..0190f37f20 --- /dev/null +++ b/plugins/cicd-statistics/src/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './plugin'; +export * from './apis'; diff --git a/plugins/cicd-statistics/src/plugin.ts b/plugins/cicd-statistics/src/plugin.ts new file mode 100644 index 0000000000..76f6ce674f --- /dev/null +++ b/plugins/cicd-statistics/src/plugin.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createPlugin, + createRoutableExtension, + createRouteRef, +} from '@backstage/core-plugin-api'; + +export const rootCatalogCicdStatsRouteRef = createRouteRef({ + id: 'cicd-statistics', +}); + +export const cicdStatisticsPlugin = createPlugin({ + id: 'cicd-statistics', + routes: { + entityContent: rootCatalogCicdStatsRouteRef, + }, +}); + +export const EntityCicdStatisticsContent = cicdStatisticsPlugin.provide( + createRoutableExtension({ + component: () => import('./entity-page').then(m => m.EntityPageCicdCharts), + mountPoint: rootCatalogCicdStatsRouteRef, + name: 'cicd-statistics-page', + }), +); diff --git a/plugins/cicd-statistics/src/utils/stage-names.ts b/plugins/cicd-statistics/src/utils/stage-names.ts new file mode 100644 index 0000000000..69c8cdcf25 --- /dev/null +++ b/plugins/cicd-statistics/src/utils/stage-names.ts @@ -0,0 +1,73 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { map } from 'already'; + +import { Build, Stage } from '../apis/types'; + +export function defaultFormatStageName( + parentNames: Array, + stageName: string, +): string { + let name = stageName; + + // Cut off parent names (if they are prefixed to the stage name) + parentNames.forEach(parentName => { + if (name.startsWith(parentName)) { + const newName = name + .slice(parentName.length) + // Remove things like ' - ' + .replace(/^[^\w\d]+/g, ''); + if (newName) { + name = newName; + } + } + }); + + // Cut off anything after colon in what looks like pulling docker images + return name.replace(/((pulling|(running)) [^:/]*\/.*?):.*/g, '$1'); +} + +export interface CleanupBuildTreeOptions { + formatStageName: typeof defaultFormatStageName; + lowerCase: boolean; +} + +export async function cleanupBuildTree( + builds: Build[], + opts: CleanupBuildTreeOptions, +): Promise { + const { formatStageName, lowerCase } = opts; + + const recurseStage = (stage: Stage, parentNames: Array): Stage => { + const name = formatStageName( + parentNames, + lowerCase ? stage.name.toLocaleLowerCase('en-US') : stage.name, + ); + const ancestry = [...parentNames, name]; + + return { + ...stage, + name, + stages: stage.stages?.map(subStage => recurseStage(subStage, ancestry)), + }; + }; + + return map(builds, { chunk: 'idle' }, build => ({ + ...build, + stages: build.stages.map(stage => recurseStage(stage, [])), + })); +} From d82fe02ecfb16273ee322d4fd045283d54390265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Thu, 13 Jan 2022 14:22:16 +0100 Subject: [PATCH 23/51] docs(cicd-statistics): Fixed spellings in README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/cicd-statistics/README.md b/plugins/cicd-statistics/README.md index e4db2166a6..78733735d7 100644 --- a/plugins/cicd-statistics/README.md +++ b/plugins/cicd-statistics/README.md @@ -2,6 +2,6 @@ This plugin shows charts of CI/CD pipeline durations over time. It expects to be used on the Software Catalog entity page, as it uses `useEntity` to figure out what component to get the build information for. -To use this plugin, you need to implement an API `CicdStatisticsApi` and bind it to the `cicdStatisticsApiRef`. This API is defined in `src/apis/types.ts` and is an interface with two functions, `getConfiguration()` and `fetchBuilds(options)`. This plugin will call `getConfiguration` to allow the implementation to specify defaults an settings for the UI. First time the UI shows, and each time the user changes filters and clicks `Update` to refresh the data, `fetchBuilds` is invoked with the filter options. The API implementation is the expected to fetch build information from somewhere, format it into a generic and rather simpe type `Build` (also defined in `types.ts`). The API can optionally signal completion for a progress bar in the UI. +To use this plugin, you need to implement an API `CicdStatisticsApi` and bind it to the `cicdStatisticsApiRef`. This API is defined in `src/apis/types.ts` and is an interface with two functions, `getConfiguration()` and `fetchBuilds(options)`. This plugin will call `getConfiguration` to allow the implementation to specify defaults and settings for the UI. First time the UI shows, and each time the user changes filters and clicks `Update` to refresh the data, `fetchBuilds` is invoked with the filter options. The API implementation is the expected to fetch build information from somewhere, format it into a generic and rather simple type `Build` (also defined in `types.ts`). The API can optionally signal completion for a progress bar in the UI. -When this plugin has fetched the builds, it will transpose the list of builds (and build stages) into a tree of build stages. As build pipelines sometimes change, certain stages might end or begin within the timerange of the view. +When this plugin has fetched the builds, it will transpose the list of builds (and build stages) into a tree of build stages. As build pipelines sometimes change, certain stages might end or begin within the date range of the view. From cf0e970bc2788bd567682faa94caa366ac4fa2e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 14 Jan 2022 14:14:37 +0100 Subject: [PATCH 24/51] fix(cicd-statistics): Added entity option to getConfiguration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/api-report.md | 10 +++++++++- plugins/cicd-statistics/src/apis/types.ts | 12 +++++++++++- .../src/hooks/use-cicd-configuration.ts | 6 ++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/plugins/cicd-statistics/api-report.md b/plugins/cicd-statistics/api-report.md index aef376c9b8..1af39b6f0f 100644 --- a/plugins/cicd-statistics/api-report.md +++ b/plugins/cicd-statistics/api-report.md @@ -82,7 +82,9 @@ export interface CicdStatisticsApi { // (undocumented) fetchBuilds(options: FetchBuildsOptions): Promise; // (undocumented) - getConfiguration(): Promise>; + getConfiguration( + options: GetConfigurationOptions, + ): Promise>; } // Warning: (ae-missing-release-tag) "cicdStatisticsApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -150,9 +152,15 @@ export type FilterStatusType = | 'expired'; // Warning: (ae-missing-release-tag) "rootCatalogCicdStatsRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "GetConfigurationOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const rootCatalogCicdStatsRouteRef: RouteRef; +// @public +export interface GetConfigurationOptions { + // (undocumented) + entity: Entity; +} // Warning: (ae-missing-release-tag) "Stage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index 1f2fa8a5b9..6bfc21008d 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -195,6 +195,14 @@ export type UpdateProgress = ( started?: number, ) => void; +/** + * When reading configuration, the Api can return a custom settings depending on + * the entity being viewed. + */ +export interface GetConfigurationOptions { + entity: Entity; +} + /** * When fetching, the Api should fetch build information about the `entity` and * respect the `timeFrom`, `timeTo`, `filterStatus` and `filterType`. @@ -220,6 +228,8 @@ export interface FetchBuildsOptions { * the UI. */ export interface CicdStatisticsApi { - getConfiguration(): Promise>; + getConfiguration( + options: GetConfigurationOptions, + ): Promise>; fetchBuilds(options: FetchBuildsOptions): Promise; } diff --git a/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts b/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts index 89f2c9f666..d435cb21aa 100644 --- a/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts +++ b/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts @@ -15,6 +15,7 @@ */ import { useState, useEffect } from 'react'; +import { useEntity } from '@backstage/plugin-catalog-react'; import { CicdConfiguration, statusTypes } from '../apis'; import { Progress } from '../components/progress'; @@ -23,6 +24,7 @@ import { useCicdStatisticsApi } from './use-cicd-statistics-api'; export function useCicdConfiguration(): Progress { const cicdStatisticsApi = useCicdStatisticsApi(); + const { entity } = useEntity(); const [state, setState] = useState>({ loading: true, @@ -35,7 +37,7 @@ export function useCicdConfiguration(): Progress { } cicdStatisticsApi - .getConfiguration() + .getConfiguration({ entity }) .then(configuration => { const { availableStatuses = statusTypes, @@ -53,7 +55,7 @@ export function useCicdConfiguration(): Progress { .catch(error => { setState({ error }); }); - }, [cicdStatisticsApi]); + }, [cicdStatisticsApi, entity]); return state; } From 706817149ba88e0742f03e668d0ed7d9cc4f837c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 14 Jan 2022 14:18:15 +0100 Subject: [PATCH 25/51] fix(cicd-statistics): Made FilterBranchType and FilterStatusType not be parameterized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/api-report.md | 14 +++++--------- plugins/cicd-statistics/src/apis/types.ts | 14 +++++--------- .../src/components/chart-filters.tsx | 2 +- .../src/hooks/use-cicd-statistics.ts | 4 ++-- 4 files changed, 13 insertions(+), 21 deletions(-) diff --git a/plugins/cicd-statistics/api-report.md b/plugins/cicd-statistics/api-report.md index 1af39b6f0f..c3976084e5 100644 --- a/plugins/cicd-statistics/api-report.md +++ b/plugins/cicd-statistics/api-report.md @@ -58,7 +58,7 @@ export interface CicdDefaults { // (undocumented) filterStatus: Array; // (undocumented) - filterType: FilterBranchType<'all'>; + filterType: FilterBranchType | 'all'; lowercaseNames: boolean; normalizeTimeRange: boolean; // (undocumented) @@ -117,9 +117,9 @@ export interface FetchBuildsOptions { // (undocumented) entity: Entity; // (undocumented) - filterStatus: Array>; + filterStatus: Array; // (undocumented) - filterType: FilterBranchType<'all'>; + filterType: FilterBranchType | 'all'; // (undocumented) timeFrom: Date; // (undocumented) @@ -131,16 +131,12 @@ export interface FetchBuildsOptions { // Warning: (ae-missing-release-tag) "FilterBranchType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export type FilterBranchType = - | Extra - | 'master' - | 'branch'; +export type FilterBranchType = 'master' | 'branch'; // Warning: (ae-missing-release-tag) "FilterStatusType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export type FilterStatusType = - | Extra +export type FilterStatusType = | 'unknown' | 'enqueued' | 'scheduled' diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index 6bfc21008d..5392657a64 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -22,8 +22,7 @@ import { Entity } from '@backstage/catalog-model'; * If all of these aren't applicable to the underlying CI/CD, these can be * configured to be hidden, using the `availableStatuses` in `CicdConfiguration`. */ -export type FilterStatusType = - | Extra +export type FilterStatusType = | 'unknown' | 'enqueued' | 'scheduled' @@ -52,10 +51,7 @@ export const statusTypes: Array = [ * something like 'release' or 'main' or 'trunk' in the underlying CI/CD system, * which is then up to the Api to map accordingly. */ -export type FilterBranchType = - | Extra - | 'master' - | 'branch'; +export type FilterBranchType = 'master' | 'branch'; export const branchTypes: Array = ['master', 'branch']; /** @@ -122,7 +118,7 @@ export interface CicdDefaults { timeFrom: Date; timeTo: Date; filterStatus: Array; - filterType: FilterBranchType<'all'>; + filterType: FilterBranchType | 'all'; /** Lower-case all stage names (to potentially merge stages with different cases) */ lowercaseNames: boolean; @@ -219,8 +215,8 @@ export interface FetchBuildsOptions { abortSignal: AbortSignal; timeFrom: Date; timeTo: Date; - filterStatus: Array>; - filterType: FilterBranchType<'all'>; + filterStatus: Array; + filterType: FilterBranchType | 'all'; } /** diff --git a/plugins/cicd-statistics/src/components/chart-filters.tsx b/plugins/cicd-statistics/src/components/chart-filters.tsx index a6e2b9ede3..a27fb58cf8 100644 --- a/plugins/cicd-statistics/src/components/chart-filters.tsx +++ b/plugins/cicd-statistics/src/components/chart-filters.tsx @@ -74,7 +74,7 @@ const useStyles = makeStyles( }, ); -export type BranchSelection = FilterBranchType<'all'>; +export type BranchSelection = FilterBranchType | 'all'; export type StatusSelection = FilterStatusType; export interface ChartFilter { diff --git a/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts b/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts index 645af9900b..bf3558b7dc 100644 --- a/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts +++ b/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts @@ -33,8 +33,8 @@ export interface UseCicdStatisticsOptions { abortController: AbortController; timeFrom: Date; timeTo: Date; - filterStatus: Array>; - filterType: FilterBranchType<'all'>; + filterStatus: Array; + filterType: FilterBranchType | 'all'; } export function useCicdStatistics( From 37218e495ea8a30caf8df161ceb4bb5ebe11ed56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 14 Jan 2022 14:21:19 +0100 Subject: [PATCH 26/51] fix(cicd-statistics): Renamed the exported component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/src/plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/cicd-statistics/src/plugin.ts b/plugins/cicd-statistics/src/plugin.ts index 76f6ce674f..b83764a1a3 100644 --- a/plugins/cicd-statistics/src/plugin.ts +++ b/plugins/cicd-statistics/src/plugin.ts @@ -35,6 +35,6 @@ export const EntityCicdStatisticsContent = cicdStatisticsPlugin.provide( createRoutableExtension({ component: () => import('./entity-page').then(m => m.EntityPageCicdCharts), mountPoint: rootCatalogCicdStatsRouteRef, - name: 'cicd-statistics-page', + name: 'EntityCicdStatisticsContent', }), ); From 721dca4a1446ec7bbd1c947bd8ffc0c0490af485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 14 Jan 2022 14:25:32 +0100 Subject: [PATCH 27/51] fix(cicd-statistics): Don't export the routeRef MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/api-report.md | 3 --- plugins/cicd-statistics/src/plugin.ts | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/cicd-statistics/api-report.md b/plugins/cicd-statistics/api-report.md index c3976084e5..400d8de1a6 100644 --- a/plugins/cicd-statistics/api-report.md +++ b/plugins/cicd-statistics/api-report.md @@ -147,11 +147,8 @@ export type FilterStatusType = | 'stalled' | 'expired'; -// Warning: (ae-missing-release-tag) "rootCatalogCicdStatsRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "GetConfigurationOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) -export const rootCatalogCicdStatsRouteRef: RouteRef; // @public export interface GetConfigurationOptions { // (undocumented) diff --git a/plugins/cicd-statistics/src/plugin.ts b/plugins/cicd-statistics/src/plugin.ts index b83764a1a3..cd53ce53e5 100644 --- a/plugins/cicd-statistics/src/plugin.ts +++ b/plugins/cicd-statistics/src/plugin.ts @@ -20,7 +20,7 @@ import { createRouteRef, } from '@backstage/core-plugin-api'; -export const rootCatalogCicdStatsRouteRef = createRouteRef({ +const rootCatalogCicdStatsRouteRef = createRouteRef({ id: 'cicd-statistics', }); From 6c4744725623fb2007ad8d3a5bb859950b8aaf8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 14 Jan 2022 14:43:19 +0100 Subject: [PATCH 28/51] fix(cicd-statistics): Export missing component type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/api-report.md | 6 +++++- plugins/cicd-statistics/src/plugin.ts | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/cicd-statistics/api-report.md b/plugins/cicd-statistics/api-report.md index 400d8de1a6..f12ab166ab 100644 --- a/plugins/cicd-statistics/api-report.md +++ b/plugins/cicd-statistics/api-report.md @@ -102,12 +102,16 @@ export const cicdStatisticsPlugin: BackstagePlugin< {} >; -// Warning: (ae-forgotten-export) The symbol "EntityPageCicdCharts" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "EntityCicdStatisticsContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const EntityCicdStatisticsContent: EntityPageCicdCharts; +// Warning: (ae-missing-release-tag) "EntityPageCicdCharts" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function EntityPageCicdCharts(): JSX.Element; + // Warning: (ae-missing-release-tag) "FetchBuildsOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public diff --git a/plugins/cicd-statistics/src/plugin.ts b/plugins/cicd-statistics/src/plugin.ts index cd53ce53e5..ca9506475a 100644 --- a/plugins/cicd-statistics/src/plugin.ts +++ b/plugins/cicd-statistics/src/plugin.ts @@ -20,6 +20,8 @@ import { createRouteRef, } from '@backstage/core-plugin-api'; +export type { EntityPageCicdCharts } from './entity-page'; + const rootCatalogCicdStatsRouteRef = createRouteRef({ id: 'cicd-statistics', }); From d3d16a2442d536443eb8185b6f82078e05ba3369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 14 Jan 2022 16:28:28 +0100 Subject: [PATCH 29/51] fix(cicd-statistics): Don't instanceof, do fuzzy matching for better compat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/src/apis/types.ts | 2 +- plugins/cicd-statistics/src/entity-page.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index 5392657a64..48cb58e350 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -163,7 +163,7 @@ export interface CicdConfiguration { /** * If the Api implements support for aborting the fetching of builds, throw an - * AbortError of this type + * AbortError of this type (or any other error with name === 'AbortError'). */ export class AbortError extends Error {} diff --git a/plugins/cicd-statistics/src/entity-page.tsx b/plugins/cicd-statistics/src/entity-page.tsx index d339f52fde..28c08f2371 100644 --- a/plugins/cicd-statistics/src/entity-page.tsx +++ b/plugins/cicd-statistics/src/entity-page.tsx @@ -35,7 +35,7 @@ import { getDefaultViewOptions, ViewOptions, } from './components/chart-filters'; -import { AbortError, CicdConfiguration } from './apis'; +import { CicdConfiguration } from './apis'; import { cleanupBuildTree } from './utils/stage-names'; import { renderFallbacks, useAsyncChain } from './components/progress'; @@ -131,7 +131,7 @@ function CicdCharts(props: CicdChartsProps) { useEffect(() => { if ( !chartableStagesState.error || - chartableStagesState.error instanceof AbortError + chartableStagesState.error?.name === 'AbortError' ) { return; } From b8492f3b14829051f0913e7c490ed5cd1f075d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 14 Jan 2022 16:32:49 +0100 Subject: [PATCH 30/51] fix(cicd-statistics): buildType -> branchType MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/api-report.md | 2 +- plugins/cicd-statistics/src/apis/types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/cicd-statistics/api-report.md b/plugins/cicd-statistics/api-report.md index f12ab166ab..09e0948753 100644 --- a/plugins/cicd-statistics/api-report.md +++ b/plugins/cicd-statistics/api-report.md @@ -24,7 +24,7 @@ export const branchTypes: Array; // // @public export interface Build { - buildType: FilterBranchType; + branchType: FilterBranchType; duration: number; id: string; // (undocumented) diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index 48cb58e350..6ff0b67741 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -86,7 +86,7 @@ export interface Build { status: FilterStatusType; /** Branch type */ - buildType: FilterBranchType; + branchType: FilterBranchType; /** Time when the build started */ requestedAt: Date; From 0a7179538a73e71a0e497ec2c8578a50c3abfdf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 14 Jan 2022 16:35:33 +0100 Subject: [PATCH 31/51] fix(cicd-statistics): Don't export branchTypes, it's not very useful MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/api-report.md | 5 ----- plugins/cicd-statistics/src/apis/types.ts | 1 - 2 files changed, 6 deletions(-) diff --git a/plugins/cicd-statistics/api-report.md b/plugins/cicd-statistics/api-report.md index 09e0948753..c2e7e0934d 100644 --- a/plugins/cicd-statistics/api-report.md +++ b/plugins/cicd-statistics/api-report.md @@ -15,11 +15,6 @@ import { RouteRef } from '@backstage/core-plugin-api'; // @public export class AbortError extends Error {} -// Warning: (ae-missing-release-tag) "branchTypes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const branchTypes: Array; - // Warning: (ae-missing-release-tag) "Build" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index 6ff0b67741..d89b0e1f0c 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -52,7 +52,6 @@ export const statusTypes: Array = [ * which is then up to the Api to map accordingly. */ export type FilterBranchType = 'master' | 'branch'; -export const branchTypes: Array = ['master', 'branch']; /** * A Stage is a part of either a Build or a parent Stage. From ecaa8e7a151bb142c122ced25d2a445566dd2cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Thu, 20 Jan 2022 15:25:52 +0100 Subject: [PATCH 32/51] fix(cicd-statistics): date-fns -> luxon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/package.json | 7 +- .../src/charts/status-chart.tsx | 8 +- plugins/cicd-statistics/src/charts/utils.tsx | 57 +++-- .../src/components/chart-filters.tsx | 23 +- plugins/cicd-statistics/src/entity-page.tsx | 9 +- yarn.lock | 221 +++++++++++++++++- 6 files changed, 286 insertions(+), 39 deletions(-) diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 8fad2b25f3..3e93d2adf6 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -28,18 +28,21 @@ "postpack": "backstage-cli postpack", "clean": "backstage-cli clean" }, + "devDependencies": { + "@types/luxon": "^2.0.9" + }, "dependencies": { "@backstage/catalog-model": "^0.9.8", "@backstage/core-plugin-api": "^0.4.1", "@backstage/plugin-catalog-react": "^0.6.9", - "@date-io/date-fns": "^1.3.13", + "@date-io/luxon": "^1.3.13", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "4.0.0-alpha.57", "@material-ui/pickers": "^3.3.10", "already": "^3.2.0", - "date-fns": "^2.27.0", "lodash": "^4.17.21", + "luxon": "^2.3.0", "react-use": "^17.3.1", "recharts": "^2.1.5" }, diff --git a/plugins/cicd-statistics/src/charts/status-chart.tsx b/plugins/cicd-statistics/src/charts/status-chart.tsx index c3153c1700..5b541961fa 100644 --- a/plugins/cicd-statistics/src/charts/status-chart.tsx +++ b/plugins/cicd-statistics/src/charts/status-chart.tsx @@ -34,8 +34,8 @@ import { Typography, } from '@material-ui/core'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import { formatISO9075, parseISO } from 'date-fns'; import { countBy } from 'lodash'; +import { DateTime } from 'luxon'; import { Build, FilterStatusType, statusTypes } from '../apis/types'; import { labelFormatterWithoutTime, tickFormatterX } from './utils'; @@ -56,9 +56,7 @@ export function StatusChart(props: StatusChartProps) { builds.forEach(build => { foundStatuses.add(build.status); - const dayString = formatISO9075(build.requestedAt, { - representation: 'date', - }); + const dayString = DateTime.fromJSDate(build.requestedAt).toISODate(); const dayList = buildsByDay.get(dayString); if (dayList) { dayList.push(build); @@ -75,7 +73,7 @@ export function StatusChart(props: StatusChartProps) { ), ], values: [...buildsByDay.entries()].map(([dayString, buildThisDay]) => ({ - __epoch: parseISO(dayString).getTime(), + __epoch: DateTime.fromISO(dayString).toMillis(), ...countBy(buildThisDay, 'status'), })), }; diff --git a/plugins/cicd-statistics/src/charts/utils.tsx b/plugins/cicd-statistics/src/charts/utils.tsx index 8fcd5e08d6..4a7131b7c9 100644 --- a/plugins/cicd-statistics/src/charts/utils.tsx +++ b/plugins/cicd-statistics/src/charts/utils.tsx @@ -15,7 +15,7 @@ */ import React, { CSSProperties } from 'react'; -import { formatISO9075, formatDistanceStrict } from 'date-fns'; +import { DateTime, Duration } from 'luxon'; const infoText: CSSProperties = { color: 'InfoText' }; @@ -40,20 +40,25 @@ export function pickElements(arr: ReadonlyArray, num: number): Array { ]; } -export function labelFormatter(epoch: number) { - return {formatISO9075(new Date(epoch))}; +function formatDateShort(milliseconds: number) { + return DateTime.fromMillis(milliseconds).toLocaleString(DateTime.DATE_SHORT); } - -export function labelFormatterWithoutTime(epoch: number) { - return ( - - {formatISO9075(new Date(epoch), { representation: 'date' })} - +function formatDateTimeShort(milliseconds: number) { + return DateTime.fromMillis(milliseconds).toLocaleString( + DateTime.DATETIME_SHORT, ); } +export function labelFormatter(epoch: number) { + return {formatDateTimeShort(epoch)}; +} + +export function labelFormatterWithoutTime(epoch: number) { + return {formatDateShort(epoch)}; +} + export function tickFormatterX(epoch: number) { - return formatISO9075(new Date(epoch), { representation: 'date' }); + return formatDateShort(epoch); } export function tickFormatterY(duration: number) { @@ -80,8 +85,32 @@ export function tooltipValueFormatter(duration: number, name: string) { ]; } -const baseDate = new Date(); -const baseEpoch = baseDate.getTime(); -export function formatDuration(milliseconds: number) { - return formatDistanceStrict(baseDate, new Date(baseEpoch + milliseconds)); +export function formatDuration(millis: number) { + let rest = Math.round(millis); + const days = Math.floor(rest / (1000 * 60 * 60 * 24)); + rest -= days * (1000 * 60 * 60 * 24); + const hours = Math.floor(rest / (1000 * 60 * 60)); + rest -= hours * (1000 * 60 * 60); + const minutes = Math.floor(rest / (1000 * 60)); + rest -= minutes * (1000 * 60); + const seconds = Math.floor(rest / 1000); + rest -= seconds * 1000; + const milliseconds = rest; + + if (!days && !hours && !minutes) { + if (seconds < 1) { + return `${milliseconds}ms`; + } else if (seconds < 2) { + return `${((milliseconds + seconds * 1000) / 1000).toFixed(1)}s`; + } + } + + const dur = Duration.fromObject({ + ...(days && { days }), + ...(hours && { hours }), + ...(minutes && !days && { minutes }), + ...(seconds && !days && !hours && { seconds }), + }); + + return dur.toHuman({ unitDisplay: 'narrow' }).replace(/, /g, ''); } diff --git a/plugins/cicd-statistics/src/components/chart-filters.tsx b/plugins/cicd-statistics/src/components/chart-filters.tsx index a27fb58cf8..e14ff366d5 100644 --- a/plugins/cicd-statistics/src/components/chart-filters.tsx +++ b/plugins/cicd-statistics/src/components/chart-filters.tsx @@ -33,8 +33,8 @@ import { MuiPickersUtilsProvider, KeyboardDatePicker, } from '@material-ui/pickers'; -import { subMonths, isSameDay } from 'date-fns'; -import DateFnsUtils from '@date-io/date-fns'; +import { DateTime } from 'luxon'; +import LuxonUtils from '@date-io/luxon'; import { CicdConfiguration, @@ -89,7 +89,9 @@ export function getDefaultChartFilter( ): ChartFilter { const toDate = cicdConfiguration.defaults?.timeTo ?? new Date(); return { - fromDate: cicdConfiguration.defaults?.timeFrom ?? subMonths(toDate, 1), + fromDate: + cicdConfiguration.defaults?.timeFrom ?? + DateTime.fromJSDate(toDate).minus({ months: 1 }).toJSDate(), toDate, branch: cicdConfiguration.defaults?.filterType ?? 'branch', status: @@ -104,8 +106,11 @@ function isSameChartFilter(a: ChartFilter, b: ChartFilter): boolean { return ( a.branch === b.branch && [...a.status].sort().join(' ') === [...b.status].sort().join(' ') && - isSameDay(a.fromDate, b.fromDate) && - isSameDay(a.toDate, b.toDate) + DateTime.fromJSDate(a.fromDate).hasSame( + DateTime.fromJSDate(b.fromDate), + 'day', + ) && + DateTime.fromJSDate(a.toDate).hasSame(DateTime.fromJSDate(b.toDate), 'day') ); } @@ -218,7 +223,7 @@ export function ChartFilters(props: ChartFiltersProps) { const toggleUseNowAsDate = useCallback(() => { setUseNowAsToDate(!useNowAsToDate); - if (!isSameDay(toDate, new Date())) { + if (!DateTime.fromJSDate(toDate).hasSame(DateTime.now(), 'day')) { setToDate(new Date()); } }, [useNowAsToDate, toDate]); @@ -248,7 +253,7 @@ export function ChartFilters(props: ChartFiltersProps) { }, [toDate, fromDate, branch, selectedStatus, updateFetchFilter]); return ( - + setFromDate(date as any as Date)} + onChange={date => setFromDate(date?.toJSDate() ?? new Date())} />
@@ -306,7 +311,7 @@ export function ChartFilters(props: ChartFiltersProps) { format="yyyy-MM-dd" value={toDate} InputAdornmentProps={{ position: 'start' }} - onChange={date => setToDate(date as any as Date)} + onChange={date => setToDate(date?.toJSDate() ?? new Date())} /> )} diff --git a/plugins/cicd-statistics/src/entity-page.tsx b/plugins/cicd-statistics/src/entity-page.tsx index 28c08f2371..e12b75fe65 100644 --- a/plugins/cicd-statistics/src/entity-page.tsx +++ b/plugins/cicd-statistics/src/entity-page.tsx @@ -16,9 +16,9 @@ import React, { useCallback, useState, useMemo, useEffect } from 'react'; import { Grid, makeStyles, Theme } from '@material-ui/core'; -import { startOfDay, endOfDay } from 'date-fns'; import { useEntity } from '@backstage/plugin-catalog-react'; import { useApi, errorApiRef } from '@backstage/core-plugin-api'; +import { DateTime } from 'luxon'; import { useCicdStatistics, @@ -58,6 +58,13 @@ const useStyles = makeStyles( }, ); +function startOfDay(date: Date) { + return DateTime.fromJSDate(date).startOf('day').toJSDate(); +} +function endOfDay(date: Date) { + return DateTime.fromJSDate(date).endOf('day').toJSDate(); +} + interface CicdChartsProps { cicdConfiguration: CicdConfiguration; } diff --git a/yarn.lock b/yarn.lock index ffc877abc6..2245504748 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1409,7 +1409,7 @@ zen-observable "^0.8.15" zod "^3.11.6" -"@backstage/core-plugin-api@^0.4.0": +"@backstage/core-plugin-api@^0.4.0", "@backstage/core-plugin-api@^0.4.1": version "0.4.1" resolved "https://registry.npmjs.org/@backstage/core-plugin-api/-/core-plugin-api-0.4.1.tgz#c0a13504bdfa61ae3d0db96934cd6c32a7574446" integrity sha512-IIb7XTcquTPaSIlamMKUgeTs5uLqkKN0Nw32QdTZhKgFkFFVzWC0AwN+henkaMNBZFdGb0ttPzrvNXGj5E6dGg== @@ -1440,7 +1440,7 @@ "@material-ui/lab" "4.0.0-alpha.57" react-use "^17.2.4" -"@backstage/plugin-catalog-react@^0.6.13", "@backstage/plugin-catalog-react@^0.6.5": +"@backstage/plugin-catalog-react@^0.6.13", "@backstage/plugin-catalog-react@^0.6.5", "@backstage/plugin-catalog-react@^0.6.9": version "0.6.13" resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.6.13.tgz#b325eae501d3edeb8b7caef5d9615f2e632f5430" integrity sha512-XBwop7PwAZqfongx3KP6jAJar+MEscLSp8nLuHYX5XxA+suQNiBgi96uO3SEQmvtae+hvsRM7c0WHSxbYiXsDA== @@ -1835,7 +1835,7 @@ dependencies: "@date-io/core" "^1.3.13" -"@date-io/luxon@1.x": +"@date-io/luxon@1.x", "@date-io/luxon@^1.3.13": version "1.3.13" resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-1.3.13.tgz#68f0134bb38ef486b2ed6df01981f814c633e28a" integrity sha512-9wUrJCNSMZJeYAiH+dbb45oGpnHeFP7TOH/Lt26If47gjFCkjvyINzWx+K5AGsnlP0Qosxc7hkF1yLi6ecutxw== @@ -3622,7 +3622,7 @@ react-beautiful-dnd "^13.0.0" react-double-scrollbar "0.0.15" -"@material-ui/core@^4.11.0", "@material-ui/core@^4.11.3", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2": +"@material-ui/core@^4.11.0", "@material-ui/core@^4.11.3", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2", "@material-ui/core@^4.9.13": version "4.12.3" resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.12.3.tgz#80d665caf0f1f034e52355c5450c0e38b099d3ca" integrity sha512-sdpgI/PL56QVsEJldwEe4FFaFTLUqN+rd7sSZiRCdx2E/C7z5yK0y/khAWVBH24tXwto7I1hCzNWfJGZIYJKnw== @@ -5309,6 +5309,11 @@ resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.0.2.tgz#53f2d6325f66ee79afd707c05ac849e8ae0edbb0" integrity sha512-WVx6zBiz4sWlboCy7TCgjeyHpNjMsoF36yaagny1uXfbadc9f+5BeBf7U+lRmQqY3EHbGQpP8UdW8AC+cywSwQ== +"@types/d3-color@^2": + version "2.0.3" + resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.3.tgz#8bc4589073c80e33d126345542f588056511fe82" + integrity sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w== + "@types/d3-force@^2.1.1": version "2.1.1" resolved "https://registry.npmjs.org/@types/d3-force/-/d3-force-2.1.1.tgz#a18b6f029d056eb0f8f84a09471e6228e4469b14" @@ -5321,6 +5326,13 @@ dependencies: "@types/d3-color" "*" +"@types/d3-interpolate@^2.0.0": + version "2.0.2" + resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-2.0.2.tgz#78eddf7278b19e48e8652603045528d46897aba0" + integrity sha512-lElyqlUfIPyWG/cD475vl6msPL4aMU7eJvx1//Q177L8mdXoVPFl1djIESF2FKnc0NyaHvQlJpWwKJYwAhUoCw== + dependencies: + "@types/d3-color" "^2" + "@types/d3-path@*": version "3.0.0" resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz#939e3a784ae4f80b1fde8098b91af1776ff1312b" @@ -5331,6 +5343,18 @@ resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c" integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ== +"@types/d3-path@^2": + version "2.0.1" + resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.1.tgz#ca03dfa8b94d8add97ad0cd97e96e2006b4763cb" + integrity sha512-6K8LaFlztlhZO7mwsZg7ClRsdLg3FJRzIIi6SZXDWmmSJc2x8dd2VkESbLXdk3p8cuvz71f36S0y8Zv2AxqvQw== + +"@types/d3-scale@^3.0.0": + version "3.3.2" + resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz#18c94e90f4f1c6b1ee14a70f14bfca2bd1c61d06" + integrity sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ== + dependencies: + "@types/d3-time" "^2" + "@types/d3-selection@*", "@types/d3-selection@^3.0.1": version "3.0.2" resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.2.tgz#23e48a285b24063630bbe312cc0cfe2276de4a59" @@ -5343,6 +5367,13 @@ dependencies: "@types/d3-path" "^1" +"@types/d3-shape@^2.0.0": + version "2.1.3" + resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz#35d397b9e687abaa0de82343b250b9897b8cacf3" + integrity sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ== + dependencies: + "@types/d3-path" "^2" + "@types/d3-shape@^3.0.1": version "3.0.2" resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.0.2.tgz#4b1ca4ddaac294e76b712429726d40365cd1e8ca" @@ -5350,6 +5381,11 @@ dependencies: "@types/d3-path" "*" +"@types/d3-time@^2": + version "2.1.1" + resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz#743fdc821c81f86537cbfece07093ac39b4bc342" + integrity sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg== + "@types/d3-zoom@^3.0.1": version "3.0.1" resolved "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.1.tgz#4bfc7e29625c4f79df38e2c36de52ec3e9faf826" @@ -5756,6 +5792,11 @@ resolved "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.5.tgz#29d3b095d55ee50df8f4cf109b16009334d9828e" integrity sha512-GKrG5v16BOs9XGpouu33hOkAFaiSDi3ZaDXG9F2yAoyzHRBtksZnI60VWY5aM/yAENCccBejrxw8jDY+9OVlxw== +"@types/luxon@^2.0.9": + version "2.0.9" + resolved "https://artifactory.spotify.net/artifactory/api/npm/virtual-npm/@types/luxon/-/luxon-2.0.9.tgz#782a0edfa6d699191292c13168bd496cd66b87c6" + integrity sha1-eCoO36bWmRkSksExaL1JbNZrh8Y= + "@types/mdast@^3.0.0", "@types/mdast@^3.0.3": version "3.0.3" resolved "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb" @@ -6095,6 +6136,11 @@ "@types/tough-cookie" "*" form-data "^2.5.0" +"@types/resize-observer-browser@^0.1.6": + version "0.1.7" + resolved "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz#294aaadf24ac6580b8fbd1fe3ab7b59fe85f9ef3" + integrity sha512-G9eN0Sn0ii9PWQ3Vl72jDPgeJwRWhv2Qk/nQkJuWmRmOB4HX3/BhD5SE1dZs/hzPZL/WKnvF0RHdTSG54QJFyg== + "@types/resolve@1.17.1": version "1.17.1" resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" @@ -6897,6 +6943,11 @@ alphanum-sort@^1.0.2: resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= +already@^3.2.0: + version "3.3.0" + resolved "https://registry.npmjs.org/already/-/already-3.3.0.tgz#a5e5becd167cf537b45f8f1c23d331488ed77003" + integrity sha512-ADGyKddqEp8t/Wu4ITc0y9GGsgZDgyMeMk38AM5qrPK7VEjNAYD87QGTGGgNhSQahmjw76V3mi+3fJRwPJXcTw== + anafanafo@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/anafanafo/-/anafanafo-2.0.0.tgz#43f56274680bc553dd67a9625a920f88d0057b5c" @@ -9635,7 +9686,7 @@ css-tree@^1.1.3: mdn-data "2.0.14" source-map "^0.6.1" -css-unit-converter@^1.1.2: +css-unit-converter@^1.1.1, css-unit-converter@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== @@ -9850,6 +9901,13 @@ cypress@^7.3.0: url "^0.11.0" yauzl "^2.10.0" +d3-array@2, d3-array@^2.3.0: + version "2.12.1" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" + d3-array@^1.2.0: version "1.2.4" resolved "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" @@ -9865,6 +9923,11 @@ d3-color@1: resolved "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== +"d3-color@1 - 2": + version "2.0.0" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" + integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== + "d3-color@1 - 3": version "3.0.1" resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.0.1.tgz#03316e595955d1fcd39d9f3610ad41bb90194d0a" @@ -9907,6 +9970,11 @@ d3-format@1: resolved "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4" integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== +"d3-format@1 - 2": + version "2.0.0" + resolved "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" + integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== + d3-interpolate@1, d3-interpolate@^1.3.0: version "1.4.0" resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" @@ -9921,11 +9989,23 @@ d3-interpolate@1, d3-interpolate@^1.3.0: dependencies: d3-color "1 - 3" +"d3-interpolate@1.2.0 - 2", d3-interpolate@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" + integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== + dependencies: + d3-color "1 - 2" + d3-path@1: version "1.0.9" resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== +"d3-path@1 - 2": + version "2.0.0" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8" + integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA== + "d3-path@1 - 3": version "3.0.1" resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.0.1.tgz#f09dec0aaffd770b7995f1a399152bf93052321e" @@ -9948,6 +10028,17 @@ d3-scale@^2.1.0: d3-time "1" d3-time-format "2" +d3-scale@^3.0.0: + version "3.3.0" + resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" + integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== + dependencies: + d3-array "^2.3.0" + d3-format "1 - 2" + d3-interpolate "1.2.0 - 2" + d3-time "^2.1.1" + d3-time-format "2 - 3" + "d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31" @@ -9960,6 +10051,13 @@ d3-shape@^1.2.0: dependencies: d3-path "1" +d3-shape@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f" + integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA== + dependencies: + d3-path "1 - 2" + d3-shape@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.1.0.tgz#c8a495652d83ea6f524e482fca57aa3f8bc32556" @@ -9974,11 +10072,25 @@ d3-time-format@2: dependencies: d3-time "1" +"d3-time-format@2 - 3": + version "3.0.0" + resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" + integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== + dependencies: + d3-time "1 - 2" + d3-time@1: version "1.1.0" resolved "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== +"d3-time@1 - 2", d3-time@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" + integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== + dependencies: + d3-array "2" + "d3-timer@1 - 2": version "2.0.0" resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz#055edb1d170cfe31ab2da8968deee940b56623e6" @@ -11503,7 +11615,7 @@ eventemitter3@^3.1.0: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== -eventemitter3@^4.0.0, eventemitter3@^4.0.4: +eventemitter3@^4.0.0, eventemitter3@^4.0.1, eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -11885,6 +11997,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-equals@^2.0.0: + version "2.0.4" + resolved "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.4.tgz#3add9410585e2d7364c2deeb6a707beadb24b927" + integrity sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w== + fast-glob@^3.1.1: version "3.2.2" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz#ade1a9d91148965d4bf7c51f72e1ca662d32e63d" @@ -13857,6 +13974,11 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + interpret@^1.0.0: version "1.4.0" resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" @@ -16446,6 +16568,11 @@ luxon@^1.27.0: resolved "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf" integrity sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ== +luxon@^2.3.0: + version "2.3.0" + resolved "https://artifactory.spotify.net/artifactory/api/npm/virtual-npm/luxon/-/luxon-2.3.0.tgz#bf16a7e642513c2a20a6230a6a41b0ab446d0045" + integrity sha1-vxan5kJRPCogpiMKakGwq0RtAEU= + lz-string@^1.4.4: version "1.4.4" resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" @@ -19569,6 +19696,11 @@ postcss-unique-selectors@^5.0.2: alphanum-sort "^1.0.2" postcss-selector-parser "^6.0.5" +postcss-value-parser@^3.3.0: + version "3.3.1" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" @@ -20260,7 +20392,7 @@ react-inspector@^5.1.1: is-dom "^1.0.0" prop-types "^15.0.0" -react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.6, react-is@^16.9.0: +react-is@^16.10.2, react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.6, react-is@^16.9.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -20317,6 +20449,15 @@ react-resize-detector@^2.3.0: prop-types "^15.6.0" resize-observer-polyfill "^1.5.0" +react-resize-detector@^6.6.3: + version "6.7.8" + resolved "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.8.tgz#318c85d1335e50f99d4fb8eb9ec34e066db597d0" + integrity sha512-0FaEcUBAbn+pq3PT5a9hHRebUfuS1SRLGLpIw8LydU7zX429I6XJgKerKAMPsJH0qWAl6o5bVKNqFJqr6tGPYw== + dependencies: + "@types/resize-observer-browser" "^0.1.6" + lodash "^4.17.21" + resize-observer-polyfill "^1.5.1" + react-router-dom@6.0.0-beta.0: version "6.0.0-beta.0" resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.0.0-beta.0.tgz#9dcc8555365f22f7fbd09f26b6b82543f3eb97d6" @@ -20354,6 +20495,15 @@ react-smooth@^1.0.5: raf "^3.4.0" react-transition-group "^2.5.0" +react-smooth@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz#561647b33e498b2e25f449b3c6689b2e9111bf91" + integrity sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw== + dependencies: + fast-equals "^2.0.0" + raf "^3.4.0" + react-transition-group "2.9.0" + react-sparklines@^1.7.0: version "1.7.0" resolved "https://registry.npmjs.org/react-sparklines/-/react-sparklines-1.7.0.tgz#9b1d97e8c8610095eeb2ad658d2e1fcf91f91a60" @@ -20389,7 +20539,7 @@ react-text-truncate@^0.17.0: dependencies: prop-types "^15.5.7" -react-transition-group@^2.5.0: +react-transition-group@2.9.0, react-transition-group@^2.5.0: version "2.9.0" resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== @@ -20434,6 +20584,26 @@ react-use@^17.2.4: ts-easing "^0.2.0" tslib "^2.1.0" +react-use@^17.3.1: + version "17.3.2" + resolved "https://registry.npmjs.org/react-use/-/react-use-17.3.2.tgz#448abf515f47c41c32455024db28167cb6e53be8" + integrity sha512-bj7OD0/1wL03KyWmzFXAFe425zziuTf7q8olwCYBfOeFHY1qfO1FAMjROQLsLZYwG4Rx63xAfb7XAbBrJsZmEw== + dependencies: + "@types/js-cookie" "^2.2.6" + "@xobotyi/scrollbar-width" "^1.9.5" + copy-to-clipboard "^3.3.1" + fast-deep-equal "^3.1.3" + fast-shallow-equal "^1.0.0" + js-cookie "^2.2.1" + nano-css "^5.3.1" + react-universal-interface "^0.6.2" + resize-observer-polyfill "^1.5.1" + screenfull "^5.1.0" + set-harmonic-interval "^1.0.1" + throttle-debounce "^3.0.1" + ts-easing "^0.2.0" + tslib "^2.1.0" + react-virtualized-auto-sizer@^1.0.6: version "1.0.6" resolved "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.6.tgz#66c5b1c9278064c5ef1699ed40a29c11518f97ca" @@ -20647,6 +20817,13 @@ recharts-scale@^0.4.2: dependencies: decimal.js-light "^2.4.1" +recharts-scale@^0.4.4: + version "0.4.5" + resolved "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" + integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== + dependencies: + decimal.js-light "^2.4.1" + recharts@^1.8.5: version "1.8.5" resolved "https://registry.npmjs.org/recharts/-/recharts-1.8.5.tgz#ca94a3395550946334a802e35004ceb2583fdb12" @@ -20664,6 +20841,26 @@ recharts@^1.8.5: recharts-scale "^0.4.2" reduce-css-calc "^1.3.0" +recharts@^2.1.5: + version "2.1.8" + resolved "https://registry.npmjs.org/recharts/-/recharts-2.1.8.tgz#ca8774fcec5f5d7ec15dedd638db9ee12faf1c09" + integrity sha512-Wi7ufdDGyvy/BPf1za1Ok7VeWB2KtEejaewO9ulmlUhvn5l5RPS4AOkrUfhtMRTTjgJ4K6AbWMDpwtDjczUHJA== + dependencies: + "@types/d3-interpolate" "^2.0.0" + "@types/d3-scale" "^3.0.0" + "@types/d3-shape" "^2.0.0" + classnames "^2.2.5" + d3-interpolate "^2.0.0" + d3-scale "^3.0.0" + d3-shape "^2.0.0" + eventemitter3 "^4.0.1" + lodash "^4.17.19" + react-is "^16.10.2" + react-resize-detector "^6.6.3" + react-smooth "^2.0.0" + recharts-scale "^0.4.4" + reduce-css-calc "^2.1.8" + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -20710,6 +20907,14 @@ reduce-css-calc@^1.3.0: math-expression-evaluator "^1.2.14" reduce-function-call "^1.0.1" +reduce-css-calc@^2.1.8: + version "2.1.8" + resolved "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" + integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== + dependencies: + css-unit-converter "^1.1.1" + postcss-value-parser "^3.3.0" + reduce-function-call@^1.0.1: version "1.0.3" resolved "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f" From cbbab88d9f58ee76d4381088086c2354955bbd11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 21 Jan 2022 16:07:37 +0100 Subject: [PATCH 33/51] feat(cicd-statistics): Allow stages to individual status, and added bar charts counts, and some refactoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/src/apis/types.ts | 20 +- .../cicd-statistics/src/charts/conversions.ts | 238 ------------------ .../src/charts/logic/conversions.ts | 90 +++++++ .../src/charts/logic/count-builds-per-day.ts | 51 ++++ .../src/charts/logic/finalize-stage.ts | 103 ++++++++ .../src/charts/logic/get-analysis.ts | 49 ++++ .../cicd-statistics/src/charts/logic/utils.ts | 57 +++++ .../src/charts/stage-chart.tsx | 97 ++++--- plugins/cicd-statistics/src/charts/types.ts | 3 + plugins/cicd-statistics/src/charts/utils.tsx | 7 +- .../src/components/button-switch.tsx | 27 +- .../src/components/chart-filters.tsx | 102 ++++++-- plugins/cicd-statistics/src/entity-page.tsx | 18 +- plugins/cicd-statistics/src/utils/api.ts | 33 +++ 14 files changed, 598 insertions(+), 297 deletions(-) delete mode 100644 plugins/cicd-statistics/src/charts/conversions.ts create mode 100644 plugins/cicd-statistics/src/charts/logic/conversions.ts create mode 100644 plugins/cicd-statistics/src/charts/logic/count-builds-per-day.ts create mode 100644 plugins/cicd-statistics/src/charts/logic/finalize-stage.ts create mode 100644 plugins/cicd-statistics/src/charts/logic/get-analysis.ts create mode 100644 plugins/cicd-statistics/src/charts/logic/utils.ts create mode 100644 plugins/cicd-statistics/src/utils/api.ts diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index d89b0e1f0c..b185a4a50e 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -63,6 +63,9 @@ export type FilterBranchType = 'master' | 'branch'; export interface Stage { name: string; + /** The status of the stage */ + status: FilterStatusType; + /** Stage duration in milliseconds */ duration: number; @@ -107,6 +110,16 @@ export type BuildWithRaw = Build & { raw: T; }; +/** + * Chart type. + * + * Values are: + * * `duration`: shows an area chart of the duration over time + * * `count`: shows a bar chart of the number of build per day + */ +export type ChartType = 'duration' | 'count'; +export type ChartTypes = Array; + /** * Default settings for the fetching options and view options. * @@ -119,12 +132,15 @@ export interface CicdDefaults { filterStatus: Array; filterType: FilterBranchType | 'all'; + /** Default collapse the stages with a max-duration below this value */ + collapsedLimit: number; + /** Lower-case all stage names (to potentially merge stages with different cases) */ lowercaseNames: boolean; /** Normalize the from-to date range in all charts */ normalizeTimeRange: boolean; - /** Default collapse the stages with a max-duration below this value */ - collapsedLimit: number; + /** Chart types per status */ + chartTypes: Record; } /** diff --git a/plugins/cicd-statistics/src/charts/conversions.ts b/plugins/cicd-statistics/src/charts/conversions.ts deleted file mode 100644 index 0f2b024d1f..0000000000 --- a/plugins/cicd-statistics/src/charts/conversions.ts +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { map } from 'already'; - -import { Build, Stage, FilterStatusType, statusTypes } from '../apis/types'; -import { - Averagify, - ChartableStage, - ChartableStageAnalysis, - ChartableStageDatapoints, - ChartableStagesAnalysis, -} from './types'; - -function makeStage(name: string): ChartableStage { - return { - analysis: { - unknown: { avg: 0, max: 0, min: 0 }, - enqueued: { avg: 0, max: 0, min: 0 }, - scheduled: { avg: 0, max: 0, min: 0 }, - running: { avg: 0, max: 0, min: 0 }, - aborted: { avg: 0, max: 0, min: 0 }, - succeeded: { avg: 0, max: 0, min: 0 }, - failed: { avg: 0, max: 0, min: 0 }, - stalled: { avg: 0, max: 0, min: 0 }, - expired: { avg: 0, max: 0, min: 0 }, - }, - combinedAnalysis: { avg: 0, max: 0, min: 0 }, - statusSet: new Set(), - name, - values: [], - stages: new Map(), - }; -} - -export interface ChartableStagesOptions { - normalizeTimeRange: boolean; -} - -/** - * Converts a list of builds, each with a tree of stages (and durations) into a - * merged tree of stages, and calculates {avg, min, max} of each stage. - */ -export async function buildsToChartableStages( - builds: Array, - options: ChartableStagesOptions, -): Promise { - const { normalizeTimeRange } = options; - - const total: ChartableStage = makeStage('Total'); - - const recurseDown = ( - status: FilterStatusType, - stageMap: Map, - stage: Stage, - __epoch: number, - ) => { - const { name, duration } = stage; - - const subChartableStage = getOrSetStage(stageMap, name); - - subChartableStage.statusSet.add(status); - subChartableStage.values.push({ - __epoch, - [status]: duration, - [`${status} avg`]: duration, - }); - - stage.stages?.forEach(subStage => { - recurseDown(status, subChartableStage.stages, subStage, __epoch); - }); - }; - - const stages = new Map(); - - await map(builds, { chunk: 'idle' }, build => { - const { duration, requestedAt, status } = build; - const __epoch = requestedAt.getTime(); - - total.statusSet.add(status); - total.values.push({ - __epoch, - [status]: duration, - [`${status} avg`]: duration, - }); - - build.stages?.forEach(subStage => { - recurseDown(status, stages, subStage, __epoch); - }); - }); - - const allEpochs = normalizeTimeRange - ? builds.map(build => build.requestedAt.getTime()) - : []; - - // Recurse down again and calculate averages - await map([...stages.values()], { chunk: 'idle' }, stage => - finalizeStage(stage, { allEpochs, averageWidth: 10 }), - ); - finalizeStage(total, { allEpochs, averageWidth: 10 }); - - return { total, stages }; -} - -function getAnalysis( - values: Array, - status: FilterStatusType, -): ChartableStageAnalysis { - const analysis: ChartableStageAnalysis = { - max: 0, - min: 0, - avg: 0, - }; - - const definedValues = values.filter( - value => typeof value[status] !== 'undefined', - ); - - analysis.max = definedValues.reduce( - (prev, cur) => Math.max(prev, cur[status]!), - 0, - ); - analysis.min = definedValues.reduce( - (prev, cur) => Math.min(prev, cur[status]!), - analysis.max, - ); - analysis.avg = - definedValues.length === 0 - ? 0 - : definedValues.reduce((prev, cur) => prev + cur[status]!, 0) / - values.length; - - return analysis; -} - -interface FinalizeStageOptions { - averageWidth: number; - allEpochs: Array; -} - -/** - * Calculate {avg, min, max} of a stage and its sub stages, recursively. - * This is calculated per status (successful, failed, etc). - */ -function finalizeStage(stage: ChartableStage, options: FinalizeStageOptions) { - const { averageWidth, allEpochs } = options; - const { values, analysis, combinedAnalysis } = stage; - - if (allEpochs.length > 0) { - const valueEpochs = new Set(values.map(value => value.__epoch)); - - allEpochs.forEach(epoch => { - if (!valueEpochs.has(epoch)) { - values.push({ __epoch: epoch }); - } - }); - } - - values.sort((a, b) => a.__epoch - b.__epoch); - - const avgDuration: [duration: number, count: number] = [0, 0]; - - statusTypes.forEach(status => { - analysis[status] = getAnalysis(values, status); - - const durationsIndexes = values - .map(value => value[status]) - .map((duration, index) => ({ index, duration })) - .filter(({ duration }) => typeof duration !== 'undefined') - .map(({ index }) => index); - const durationsDense = values - .map(value => value[status]) - .filter( - (duration): duration is number => typeof duration !== 'undefined', - ); - - avgDuration[0] += durationsDense.reduce((prev, cur) => prev + cur, 0); - avgDuration[1] += durationsDense.length; - - const averages = durationsDense.map((_, i) => - average( - durationsDense.slice( - Math.max(i - averageWidth, 0), - Math.min(i + averageWidth, durationsDense.length), - ), - ), - ); - - averages.forEach((avg, index) => { - const key: Averagify = `${status} avg`; - values[durationsIndexes[index]][key] = avg; - }); - }); - - const analysisValues = Object.values(analysis); - combinedAnalysis.max = analysisValues.reduce( - (prev, cur) => Math.max(prev, cur.max), - 0, - ); - combinedAnalysis.min = analysisValues.reduce( - (prev, cur) => Math.min(prev, cur.min), - combinedAnalysis.max, - ); - combinedAnalysis.avg = !avgDuration[1] ? 0 : avgDuration[0] / avgDuration[1]; - - stage.stages.forEach(subStage => finalizeStage(subStage, options)); -} - -function average(values: number[]): number { - return !values.length - ? 0 - : Math.round(values.reduce((prev, cur) => prev + cur, 0) / values.length); -} - -function getOrSetStage( - stages: Map, - name: string, -): ChartableStage { - const stage = stages.get(name); - if (stage) return stage; - - const newStage: ChartableStage = makeStage(name); - stages.set(name, newStage); - return newStage; -} diff --git a/plugins/cicd-statistics/src/charts/logic/conversions.ts b/plugins/cicd-statistics/src/charts/logic/conversions.ts new file mode 100644 index 0000000000..b2e990d9e4 --- /dev/null +++ b/plugins/cicd-statistics/src/charts/logic/conversions.ts @@ -0,0 +1,90 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { map } from 'already'; + +import { Build, Stage } from '../../apis/types'; +import { ChartableStage, ChartableStagesAnalysis } from '../types'; +import { getOrSetStage, makeStage } from './utils'; +import { finalizeStage } from './finalize-stage'; + +export interface ChartableStagesOptions { + normalizeTimeRange: boolean; +} + +/** + * Converts a list of builds, each with a tree of stages (and durations) into a + * merged tree of stages, and calculates {avg, min, max} of each stage. + */ +export async function buildsToChartableStages( + builds: Array, + options: ChartableStagesOptions, +): Promise { + const { normalizeTimeRange } = options; + + const total: ChartableStage = makeStage('Total'); + + const recurseDown = ( + stageMap: Map, + stage: Stage, + __epoch: number, + ) => { + const { name, status, duration } = stage; + + const subChartableStage = getOrSetStage(stageMap, name); + + subChartableStage.statusSet.add(status); + subChartableStage.values.push({ + __epoch, + [status]: duration, + [`${status} avg`]: duration, + }); + + stage.stages?.forEach(subStage => { + recurseDown(subChartableStage.stages, subStage, __epoch); + }); + }; + + const stages = new Map(); + + await map(builds, { chunk: 'idle' }, build => { + const { duration, requestedAt, status } = build; + const __epoch = requestedAt.getTime(); + + total.statusSet.add(status); + total.values.push({ + __epoch, + [status]: duration, + [`${status} avg`]: duration, + }); + + build.stages?.forEach(subStage => { + recurseDown(stages, subStage, __epoch); + }); + }); + + const allEpochs = normalizeTimeRange + ? builds.map(build => build.requestedAt.getTime()) + : []; + + // Recurse down again and calculate averages + await map([...stages.values()], { chunk: 'idle' }, stage => + finalizeStage(stage, { allEpochs, averageWidth: 10 }), + ); + finalizeStage(total, { allEpochs, averageWidth: 10 }); + + return { total, stages }; +} diff --git a/plugins/cicd-statistics/src/charts/logic/count-builds-per-day.ts b/plugins/cicd-statistics/src/charts/logic/count-builds-per-day.ts new file mode 100644 index 0000000000..c7c7ce1c21 --- /dev/null +++ b/plugins/cicd-statistics/src/charts/logic/count-builds-per-day.ts @@ -0,0 +1,51 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DateTime } from 'luxon'; +import { groupBy } from 'lodash'; + +import { FilterStatusType, statusTypes } from '../../apis/types'; +import { Countify, ChartableStageDatapoints } from '../types'; + +function startOfDayEpoch(epoch: number) { + return DateTime.fromMillis(epoch).startOf('day').toMillis(); +} + +export function countBuildsPerDay( + values: ReadonlyArray, +) { + const days = groupBy(values, value => startOfDayEpoch(value.__epoch)); + Object.entries(days).forEach(([_startOfDay, valuesThisDay]) => { + const counts = Object.fromEntries( + statusTypes + .map( + type => + [ + type, + valuesThisDay.map(value => value[type] !== undefined).length, + ] as const, + ) + .filter(([_type, count]) => count > 0) + .map(([type, count]): [Countify, number] => [ + `${type} count`, + count, + ]), + ); + + // Assign the count for this day to the first value this day + Object.assign(valuesThisDay[0], counts); + }); +} diff --git a/plugins/cicd-statistics/src/charts/logic/finalize-stage.ts b/plugins/cicd-statistics/src/charts/logic/finalize-stage.ts new file mode 100644 index 0000000000..e56c5649ff --- /dev/null +++ b/plugins/cicd-statistics/src/charts/logic/finalize-stage.ts @@ -0,0 +1,103 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FilterStatusType, statusTypes } from '../../apis/types'; +import { Averagify, ChartableStage } from '../types'; +import { countBuildsPerDay } from './count-builds-per-day'; +import { getAnalysis } from './get-analysis'; +import { average } from './utils'; + +interface FinalizeStageOptions { + averageWidth: number; + allEpochs: Array; +} + +/** + * Calculate: + * * {avg, min, max} + * * count per day + * of a stage and its sub stages, recursively. + * + * This is calculated per status (successful, failed, etc). + */ +export function finalizeStage( + stage: ChartableStage, + options: FinalizeStageOptions, +) { + const { averageWidth, allEpochs } = options; + const { values, analysis, combinedAnalysis } = stage; + + if (allEpochs.length > 0) { + const valueEpochs = new Set(values.map(value => value.__epoch)); + + allEpochs.forEach(epoch => { + if (!valueEpochs.has(epoch)) { + values.push({ __epoch: epoch }); + } + }); + } + + values.sort((a, b) => a.__epoch - b.__epoch); + + countBuildsPerDay(values); + + const avgDuration: [duration: number, count: number] = [0, 0]; + + statusTypes.forEach(status => { + analysis[status] = getAnalysis(values, status); + + const durationsIndexes = values + .map(value => value[status]) + .map((duration, index) => ({ index, duration })) + .filter(({ duration }) => typeof duration !== 'undefined') + .map(({ index }) => index); + const durationsDense = values + .map(value => value[status]) + .filter( + (duration): duration is number => typeof duration !== 'undefined', + ); + + avgDuration[0] += durationsDense.reduce((prev, cur) => prev + cur, 0); + avgDuration[1] += durationsDense.length; + + const averages = durationsDense.map((_, i) => + average( + durationsDense.slice( + Math.max(i - averageWidth, 0), + Math.min(i + averageWidth, durationsDense.length), + ), + ), + ); + + averages.forEach((avg, index) => { + const key: Averagify = `${status} avg`; + values[durationsIndexes[index]][key] = avg; + }); + }); + + const analysisValues = Object.values(analysis); + combinedAnalysis.max = analysisValues.reduce( + (prev, cur) => Math.max(prev, cur.max), + 0, + ); + combinedAnalysis.min = analysisValues.reduce( + (prev, cur) => Math.min(prev, cur.min), + combinedAnalysis.max, + ); + combinedAnalysis.avg = !avgDuration[1] ? 0 : avgDuration[0] / avgDuration[1]; + + stage.stages.forEach(subStage => finalizeStage(subStage, options)); +} diff --git a/plugins/cicd-statistics/src/charts/logic/get-analysis.ts b/plugins/cicd-statistics/src/charts/logic/get-analysis.ts new file mode 100644 index 0000000000..493355991d --- /dev/null +++ b/plugins/cicd-statistics/src/charts/logic/get-analysis.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FilterStatusType } from '../../apis/types'; +import { ChartableStageAnalysis, ChartableStageDatapoints } from '../types'; + +export function getAnalysis( + values: Array, + status: FilterStatusType, +): ChartableStageAnalysis { + const analysis: ChartableStageAnalysis = { + max: 0, + min: 0, + avg: 0, + }; + + const definedValues = values.filter( + value => typeof value[status] !== 'undefined', + ); + + analysis.max = definedValues.reduce( + (prev, cur) => Math.max(prev, cur[status]!), + 0, + ); + analysis.min = definedValues.reduce( + (prev, cur) => Math.min(prev, cur[status]!), + analysis.max, + ); + analysis.avg = + definedValues.length === 0 + ? 0 + : definedValues.reduce((prev, cur) => prev + cur[status]!, 0) / + values.length; + + return analysis; +} diff --git a/plugins/cicd-statistics/src/charts/logic/utils.ts b/plugins/cicd-statistics/src/charts/logic/utils.ts new file mode 100644 index 0000000000..eaed81ac89 --- /dev/null +++ b/plugins/cicd-statistics/src/charts/logic/utils.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FilterStatusType } from '../../apis/types'; +import { ChartableStage } from '../types'; + +export function average(values: number[]): number { + return !values.length + ? 0 + : Math.round(values.reduce((prev, cur) => prev + cur, 0) / values.length); +} + +export function getOrSetStage( + stages: Map, + name: string, +): ChartableStage { + const stage = stages.get(name); + if (stage) return stage; + + const newStage: ChartableStage = makeStage(name); + stages.set(name, newStage); + return newStage; +} + +export function makeStage(name: string): ChartableStage { + return { + analysis: { + unknown: { avg: 0, max: 0, min: 0 }, + enqueued: { avg: 0, max: 0, min: 0 }, + scheduled: { avg: 0, max: 0, min: 0 }, + running: { avg: 0, max: 0, min: 0 }, + aborted: { avg: 0, max: 0, min: 0 }, + succeeded: { avg: 0, max: 0, min: 0 }, + failed: { avg: 0, max: 0, min: 0 }, + stalled: { avg: 0, max: 0, min: 0 }, + expired: { avg: 0, max: 0, min: 0 }, + }, + combinedAnalysis: { avg: 0, max: 0, min: 0 }, + statusSet: new Set(), + name, + values: [], + stages: new Map(), + }; +} diff --git a/plugins/cicd-statistics/src/charts/stage-chart.tsx b/plugins/cicd-statistics/src/charts/stage-chart.tsx index f407a274b1..eceb37a35c 100644 --- a/plugins/cicd-statistics/src/charts/stage-chart.tsx +++ b/plugins/cicd-statistics/src/charts/stage-chart.tsx @@ -17,6 +17,7 @@ import React, { Fragment, useMemo } from 'react'; import { Area, + Bar, ComposedChart, XAxis, YAxis, @@ -38,7 +39,7 @@ import { } from '@material-ui/core'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import { statusTypes } from '../apis/types'; +import { CicdDefaults, statusTypes } from '../apis/types'; import { ChartableStage } from './types'; import { pickElements, @@ -64,13 +65,14 @@ const transitionProps = { unmountOnExit: true }; export interface StageChartProps { stage: ChartableStage; + chartTypes: CicdDefaults['chartTypes']; defaultCollapsed?: number; zeroYAxis?: boolean; } export function StageChart(props: StageChartProps) { const { stage, ...chartOptions } = props; - const { defaultCollapsed = 0, zeroYAxis = false } = chartOptions; + const { chartTypes, defaultCollapsed = 0, zeroYAxis = false } = chartOptions; const ticks = useMemo( () => pickElements(stage.values, 8).map(val => val.__epoch), @@ -134,49 +136,74 @@ export function StageChart(props: StageChartProps) { tickFormatter={tickFormatterX} /> + - {statuses.map(status => ( - - 1 - ? statusColorMap[status] - : colorStroke - } - fillOpacity={statuses.length > 1 ? 0.5 : 1} - fill={ - statuses.length > 1 - ? statusColorMap[status] - : 'url(#colorDur)' - } - connectNulls - /> - 1 - ? statusColorMap[status] - : colorStrokeAvg - } - opacity={0.8} - strokeWidth={2} - dot={false} - connectNulls - /> - + {statuses.reverse().map(status => ( + <> + {!chartTypes[status].includes('duration') ? null : ( + + 1 + ? statusColorMap[status] + : colorStroke + } + fillOpacity={statuses.length > 1 ? 0.5 : 1} + fill={ + statuses.length > 1 + ? statusColorMap[status] + : 'url(#colorDur)' + } + connectNulls + /> + 1 + ? statusColorMap[status] + : colorStrokeAvg + } + opacity={0.8} + strokeWidth={2} + dot={false} + connectNulls + /> + + )} + {!chartTypes[status].includes('count') ? null : ( + + )} + ))} diff --git a/plugins/cicd-statistics/src/charts/types.ts b/plugins/cicd-statistics/src/charts/types.ts index 6355343ee0..42b3cf4f04 100644 --- a/plugins/cicd-statistics/src/charts/types.ts +++ b/plugins/cicd-statistics/src/charts/types.ts @@ -17,6 +17,7 @@ import { FilterStatusType } from '../apis/types'; export type Averagify = `${T} avg`; +export type Countify = `${T} count`; export type ChartableStageDatapoints = { __epoch: number; @@ -24,6 +25,8 @@ export type ChartableStageDatapoints = { [status in FilterStatusType]?: number; } & { [status in Averagify]?: number; +} & { + [status in Countify]?: number; }; export interface ChartableStageAnalysis { diff --git a/plugins/cicd-statistics/src/charts/utils.tsx b/plugins/cicd-statistics/src/charts/utils.tsx index 4a7131b7c9..6086e84ade 100644 --- a/plugins/cicd-statistics/src/charts/utils.tsx +++ b/plugins/cicd-statistics/src/charts/utils.tsx @@ -76,10 +76,13 @@ export function tickFormatterY(duration: number) { .replace(/year.*/, 'y'); } -export function tooltipValueFormatter(duration: number, name: string) { +export function tooltipValueFormatter(durationOrCount: number, name: string) { return [ - {name}: {formatDuration(duration)} + {name}:{' '} + {name.endsWith(' count') + ? durationOrCount + : formatDuration(durationOrCount)} , null, ]; diff --git a/plugins/cicd-statistics/src/components/button-switch.tsx b/plugins/cicd-statistics/src/components/button-switch.tsx index 03c7066171..65f55eee41 100644 --- a/plugins/cicd-statistics/src/components/button-switch.tsx +++ b/plugins/cicd-statistics/src/components/button-switch.tsx @@ -20,6 +20,7 @@ import { ButtonGroup, Button, Tooltip, Zoom } from '@material-ui/core'; export interface SwitchValueDetails { value: T; tooltip?: string; + text?: string | JSX.Element; } export type SwitchValue = T | SwitchValueDetails; @@ -49,12 +50,34 @@ function switchValue(value: SwitchValue): T { return typeof value === 'object' ? value.value : value; } +function switchText( + value: SwitchValue, +): string | JSX.Element { + return typeof value === 'object' ? value.text ?? value.value : value; +} + +function findParent(tagName: string, elem: HTMLElement): HTMLElement { + let node: HTMLElement | null = elem; + while (node.tagName !== tagName) { + node = node.parentElement; + if (!node) { + throw new Error(`Couldn't find ${tagName} parent`); + } + } + return node; +} + export function ButtonSwitch(props: ButtonSwitchProps) { const { values, vertical = false } = props; const onClick = useCallback( (ev: MouseEvent) => { - const value = (ev.target as HTMLSpanElement).textContent!; + const btn = findParent('BUTTON', ev.target as HTMLElement); + const index = [...btn.parentElement!.children].findIndex( + child => child === btn, + ); + const value = switchValue(values[index]); + if (props.multi) { props.onChange( props.selection.includes(value as T) @@ -108,7 +131,7 @@ export function ButtonSwitch(props: ButtonSwitchProps) { } onClick={onClick} > - {switchValue(value)} + {switchText(value)} , ), )} diff --git a/plugins/cicd-statistics/src/components/chart-filters.tsx b/plugins/cicd-statistics/src/components/chart-filters.tsx index e14ff366d5..3c5f10d7e9 100644 --- a/plugins/cicd-statistics/src/components/chart-filters.tsx +++ b/plugins/cicd-statistics/src/components/chart-filters.tsx @@ -23,12 +23,15 @@ import { FormControl, FormGroup, FormControlLabel, + Grid, Switch, Theme, Tooltip, Typography, makeStyles, } from '@material-ui/core'; +import ShowChartIcon from '@material-ui/icons/ShowChart'; +import BarChartIcon from '@material-ui/icons/BarChart'; import { MuiPickersUtilsProvider, KeyboardDatePicker, @@ -37,9 +40,13 @@ import { DateTime } from 'luxon'; import LuxonUtils from '@date-io/luxon'; import { + ChartType, + ChartTypes, CicdConfiguration, + CicdDefaults, FilterBranchType, FilterStatusType, + statusTypes, } from '../apis/types'; import { ButtonSwitch, SwitchValue } from './button-switch'; import { Toggle } from './toggle'; @@ -68,6 +75,10 @@ const useStyles = makeStyles( margin: theme.spacing(1, 0, 1, 0), }, }, + buttonDescription: { + textTransform: 'uppercase', + margin: theme.spacing(1, 0, 0, 1), + }, }), { name: 'CicdStatisticsChartFilters', @@ -97,7 +108,7 @@ export function getDefaultChartFilter( status: cicdConfiguration.defaults?.filterStatus ?? cicdConfiguration.availableStatuses.filter( - status => status === 'succeeded', + status => status === 'succeeded' || status === 'failed', ), }; } @@ -114,10 +125,10 @@ function isSameChartFilter(a: ChartFilter, b: ChartFilter): boolean { ); } -export interface ViewOptions { - lowercaseNames: boolean; - normalizeTimeRange: boolean; -} +export type ViewOptions = Pick< + CicdDefaults, + 'lowercaseNames' | 'normalizeTimeRange' | 'chartTypes' +>; export function getDefaultViewOptions( cicdConfiguration: CicdConfiguration, @@ -125,9 +136,36 @@ export function getDefaultViewOptions( return { lowercaseNames: cicdConfiguration.defaults?.lowercaseNames ?? false, normalizeTimeRange: cicdConfiguration.defaults?.normalizeTimeRange ?? true, + chartTypes: { + succeeded: ['duration'], + failed: ['count'], + enqueued: ['count'], + scheduled: ['count'], + running: ['count'], + aborted: ['count'], + stalled: ['count'], + expired: ['count'], + unknown: ['count'], + }, }; } +const branchValues: Array> = [ + 'master', + 'branch', + { + value: 'all', + tooltip: + 'NOTE; If the build pipelines are very different between master and branch ' + + 'builds, viewing them combined might not result in a very useful chart', + }, +]; + +const chartTypeValues: Array> = [ + { value: 'duration', text: , tooltip: 'Duration' }, + { value: 'count', text: , tooltip: 'Count per day' }, +]; + export interface ChartFiltersProps { cicdConfiguration: CicdConfiguration; initialFetchFilter: ChartFilter; @@ -162,16 +200,6 @@ export function ChartFilters(props: ChartFiltersProps) { const [toDate, setToDate] = useState(initialFetchFilter.toDate); const [fromDate, setFromDate] = useState(initialFetchFilter.fromDate); - const branchValues: Array> = [ - 'master', - 'branch', - { - value: 'all', - tooltip: - 'NOTE; If the build pipelines are very different between master and branch ' + - 'builds, viewing them combined might not result in a very useful chart', - }, - ]; const [branch, setBranch] = useState(initialFetchFilter.branch); const statusValues: ReadonlyArray = @@ -196,6 +224,29 @@ export function ChartFilters(props: ChartFiltersProps) { [setViewOptions], ); + const setChartType = useCallback( + (statusType: FilterStatusType, chartTypes: ChartTypes) => { + setViewOptions(old => ({ + ...old, + chartTypes: { ...old.chartTypes, [statusType]: chartTypes }, + })); + }, + [setViewOptions], + ); + const setChartTypeSpecific = useMemo( + () => + Object.fromEntries( + statusTypes.map( + status => + [ + status, + (chartTypes: ChartTypes) => setChartType(status, chartTypes), + ] as const, + ), + ), + [setChartType], + ); + useEffect(() => { onChangeViewOptions(viewOptions); }, [onChangeViewOptions, viewOptions]); @@ -380,6 +431,27 @@ export function ChartFilters(props: ChartFiltersProps) { Normalize time range + + Chart styles + + {currentFetchFilter?.status.map(status => ( + + + + values={chartTypeValues} + selection={viewOptions.chartTypes[status]} + onChange={setChartTypeSpecific[status]} + multi + /> + + +
{status}
+
+
+ ))}
diff --git a/plugins/cicd-statistics/src/entity-page.tsx b/plugins/cicd-statistics/src/entity-page.tsx index e12b75fe65..c007e355a9 100644 --- a/plugins/cicd-statistics/src/entity-page.tsx +++ b/plugins/cicd-statistics/src/entity-page.tsx @@ -25,7 +25,7 @@ import { UseCicdStatisticsOptions, } from './hooks/use-cicd-statistics'; import { useCicdConfiguration } from './hooks/use-cicd-configuration'; -import { buildsToChartableStages } from './charts/conversions'; +import { buildsToChartableStages } from './charts/logic/conversions'; import { StageChart } from './charts/stage-chart'; import { StatusChart } from './charts/status-chart'; import { @@ -38,6 +38,7 @@ import { import { CicdConfiguration } from './apis'; import { cleanupBuildTree } from './utils/stage-names'; import { renderFallbacks, useAsyncChain } from './components/progress'; +import { sortFilterStatusType } from './utils/api'; export function EntityPageCicdCharts() { const state = useCicdConfiguration(); @@ -64,6 +65,12 @@ function startOfDay(date: Date) { function endOfDay(date: Date) { return DateTime.fromJSDate(date).endOf('day').toJSDate(); } +function cleanChartFilter(filter: ChartFilter): ChartFilter { + return { + ...filter, + status: sortFilterStatusType(filter.status), + }; +} interface CicdChartsProps { cicdConfiguration: CicdConfiguration; @@ -125,7 +132,7 @@ function CicdCharts(props: CicdChartsProps) { ); const onFilterChange = useCallback((filter: ChartFilter) => { - setChartFilter(filter); + setChartFilter(cleanChartFilter(filter)); }, []); const onViewOptionsChange = useCallback( @@ -166,12 +173,17 @@ function CicdCharts(props: CicdChartsProps) { {!statisticsState.value?.builds.length ? null : ( )} - + {[...chartableStages.stages.entries()].map(([name, stage]) => ( ))} diff --git a/plugins/cicd-statistics/src/utils/api.ts b/plugins/cicd-statistics/src/utils/api.ts new file mode 100644 index 0000000000..8af21b3507 --- /dev/null +++ b/plugins/cicd-statistics/src/utils/api.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FilterStatusType, statusTypes } from '../apis/types'; + +export function sortFilterStatusType( + statuses: ReadonlyArray, +): Array { + const statusSet = new Set(statuses); + + const sorted = (['all', ...statusTypes] as Array).filter((status: T) => { + if (statusSet.has(status)) { + statusSet.delete(status); + return true; + } + return false; + }); + + return [...sorted, ...statusSet]; +} From 2d7f173e0721f759012cbc4667628f13587cb811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 21 Jan 2022 16:31:00 +0100 Subject: [PATCH 34/51] feat(cicd-statistics): Added median analysis (alongside average) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- .../src/charts/logic/analysis.ts | 79 +++++++++++++++++++ .../src/charts/logic/finalize-stage.ts | 18 +---- .../src/charts/logic/get-analysis.ts | 49 ------------ .../cicd-statistics/src/charts/logic/utils.ts | 20 ++--- .../src/charts/stage-chart.tsx | 3 +- plugins/cicd-statistics/src/charts/types.ts | 5 ++ 6 files changed, 100 insertions(+), 74 deletions(-) create mode 100644 plugins/cicd-statistics/src/charts/logic/analysis.ts delete mode 100644 plugins/cicd-statistics/src/charts/logic/get-analysis.ts diff --git a/plugins/cicd-statistics/src/charts/logic/analysis.ts b/plugins/cicd-statistics/src/charts/logic/analysis.ts new file mode 100644 index 0000000000..4333ae3a6f --- /dev/null +++ b/plugins/cicd-statistics/src/charts/logic/analysis.ts @@ -0,0 +1,79 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FilterStatusType } from '../../apis/types'; +import { ChartableStageAnalysis, ChartableStageDatapoints } from '../types'; + +export function getAnalysis( + values: Array, + status: FilterStatusType, +): ChartableStageAnalysis { + const analysis: ChartableStageAnalysis = { + max: 0, + min: 0, + avg: 0, + med: 0, + }; + + const definedValues = values + .filter(value => typeof value[status] !== 'undefined') + .map(value => value[status]!) + .sort((a, b) => a - b); + + analysis.max = definedValues[definedValues.length - 1] ?? 0; + + analysis.min = definedValues[0] ?? 0; + + analysis.avg = + definedValues.length === 0 + ? 0 + : definedValues.reduce((prev, cur) => prev + cur, 0) / values.length; + + analysis.med = definedValues[Math.ceil(definedValues.length / 2)] ?? 0; + + return analysis; +} + +export function makeCombinedAnalysis( + analysis: Record, + allDurations: Array, +): ChartableStageAnalysis { + if (analysis.succeeded) { + // If succeeded is a viewed status, it's probably what's expected to see + // overall. Otherwise combine all other. + return analysis.succeeded; + } + + const analysisValues = Object.values(analysis); + + const max = analysisValues.reduce((prev, cur) => Math.max(prev, cur.max), 0); + const min = analysisValues.reduce( + (prev, cur) => Math.min(prev, cur.min), + max, + ); + const avg = !allDurations.length + ? 0 + : allDurations.reduce((prev, cur) => prev + cur, 0) / allDurations.length; + allDurations.sort((a, b) => a - b); + const med = allDurations[Math.ceil(allDurations.length / 2)] ?? 0; + + return { + max, + min, + avg, + med, + }; +} diff --git a/plugins/cicd-statistics/src/charts/logic/finalize-stage.ts b/plugins/cicd-statistics/src/charts/logic/finalize-stage.ts index e56c5649ff..bb54fbf41e 100644 --- a/plugins/cicd-statistics/src/charts/logic/finalize-stage.ts +++ b/plugins/cicd-statistics/src/charts/logic/finalize-stage.ts @@ -17,7 +17,7 @@ import { FilterStatusType, statusTypes } from '../../apis/types'; import { Averagify, ChartableStage } from '../types'; import { countBuildsPerDay } from './count-builds-per-day'; -import { getAnalysis } from './get-analysis'; +import { getAnalysis, makeCombinedAnalysis } from './analysis'; import { average } from './utils'; interface FinalizeStageOptions { @@ -54,7 +54,7 @@ export function finalizeStage( countBuildsPerDay(values); - const avgDuration: [duration: number, count: number] = [0, 0]; + const allDurations: Array = []; statusTypes.forEach(status => { analysis[status] = getAnalysis(values, status); @@ -70,8 +70,7 @@ export function finalizeStage( (duration): duration is number => typeof duration !== 'undefined', ); - avgDuration[0] += durationsDense.reduce((prev, cur) => prev + cur, 0); - avgDuration[1] += durationsDense.length; + durationsDense.forEach(dur => allDurations.push(dur)); const averages = durationsDense.map((_, i) => average( @@ -88,16 +87,7 @@ export function finalizeStage( }); }); - const analysisValues = Object.values(analysis); - combinedAnalysis.max = analysisValues.reduce( - (prev, cur) => Math.max(prev, cur.max), - 0, - ); - combinedAnalysis.min = analysisValues.reduce( - (prev, cur) => Math.min(prev, cur.min), - combinedAnalysis.max, - ); - combinedAnalysis.avg = !avgDuration[1] ? 0 : avgDuration[0] / avgDuration[1]; + Object.assign(combinedAnalysis, makeCombinedAnalysis(analysis, allDurations)); stage.stages.forEach(subStage => finalizeStage(subStage, options)); } diff --git a/plugins/cicd-statistics/src/charts/logic/get-analysis.ts b/plugins/cicd-statistics/src/charts/logic/get-analysis.ts deleted file mode 100644 index 493355991d..0000000000 --- a/plugins/cicd-statistics/src/charts/logic/get-analysis.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { FilterStatusType } from '../../apis/types'; -import { ChartableStageAnalysis, ChartableStageDatapoints } from '../types'; - -export function getAnalysis( - values: Array, - status: FilterStatusType, -): ChartableStageAnalysis { - const analysis: ChartableStageAnalysis = { - max: 0, - min: 0, - avg: 0, - }; - - const definedValues = values.filter( - value => typeof value[status] !== 'undefined', - ); - - analysis.max = definedValues.reduce( - (prev, cur) => Math.max(prev, cur[status]!), - 0, - ); - analysis.min = definedValues.reduce( - (prev, cur) => Math.min(prev, cur[status]!), - analysis.max, - ); - analysis.avg = - definedValues.length === 0 - ? 0 - : definedValues.reduce((prev, cur) => prev + cur[status]!, 0) / - values.length; - - return analysis; -} diff --git a/plugins/cicd-statistics/src/charts/logic/utils.ts b/plugins/cicd-statistics/src/charts/logic/utils.ts index eaed81ac89..0c3900d025 100644 --- a/plugins/cicd-statistics/src/charts/logic/utils.ts +++ b/plugins/cicd-statistics/src/charts/logic/utils.ts @@ -38,17 +38,17 @@ export function getOrSetStage( export function makeStage(name: string): ChartableStage { return { analysis: { - unknown: { avg: 0, max: 0, min: 0 }, - enqueued: { avg: 0, max: 0, min: 0 }, - scheduled: { avg: 0, max: 0, min: 0 }, - running: { avg: 0, max: 0, min: 0 }, - aborted: { avg: 0, max: 0, min: 0 }, - succeeded: { avg: 0, max: 0, min: 0 }, - failed: { avg: 0, max: 0, min: 0 }, - stalled: { avg: 0, max: 0, min: 0 }, - expired: { avg: 0, max: 0, min: 0 }, + unknown: { avg: 0, med: 0, max: 0, min: 0 }, + enqueued: { avg: 0, med: 0, max: 0, min: 0 }, + scheduled: { avg: 0, med: 0, max: 0, min: 0 }, + running: { avg: 0, med: 0, max: 0, min: 0 }, + aborted: { avg: 0, med: 0, max: 0, min: 0 }, + succeeded: { avg: 0, med: 0, max: 0, min: 0 }, + failed: { avg: 0, med: 0, max: 0, min: 0 }, + stalled: { avg: 0, med: 0, max: 0, min: 0 }, + expired: { avg: 0, med: 0, max: 0, min: 0 }, }, - combinedAnalysis: { avg: 0, max: 0, min: 0 }, + combinedAnalysis: { avg: 0, med: 0, max: 0, min: 0 }, statusSet: new Set(), name, values: [], diff --git a/plugins/cicd-statistics/src/charts/stage-chart.tsx b/plugins/cicd-statistics/src/charts/stage-chart.tsx index eceb37a35c..3e18bd17cd 100644 --- a/plugins/cicd-statistics/src/charts/stage-chart.tsx +++ b/plugins/cicd-statistics/src/charts/stage-chart.tsx @@ -104,7 +104,8 @@ export function StageChart(props: StageChartProps) { > }> - {stage.name} (avg {formatDuration(stage.combinedAnalysis.avg)}) + {stage.name} (med {formatDuration(stage.combinedAnalysis.med)}, avg{' '} + {formatDuration(stage.combinedAnalysis.avg)}) diff --git a/plugins/cicd-statistics/src/charts/types.ts b/plugins/cicd-statistics/src/charts/types.ts index 42b3cf4f04..75a72a8a4f 100644 --- a/plugins/cicd-statistics/src/charts/types.ts +++ b/plugins/cicd-statistics/src/charts/types.ts @@ -30,9 +30,14 @@ export type ChartableStageDatapoints = { }; export interface ChartableStageAnalysis { + /** Maximum duration */ max: number; + /** Minimum duration */ min: number; + /** Average duration */ avg: number; + /** Median duration */ + med: number; } export interface ChartableStage { From 52756327cfc9b02f57db1f40c6db74bd78fd8c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Fri, 21 Jan 2022 18:00:30 +0100 Subject: [PATCH 35/51] feat(cicd-statistics): Allow custom hiding/collapsing under certain thresholds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/src/apis/types.ts | 7 +- .../src/charts/stage-chart.tsx | 28 ++++- .../src/charts/status-chart.tsx | 2 +- .../src/components/chart-filters.tsx | 46 +++++-- .../src/components/duration-slider.tsx | 117 ++++++++++++++++++ .../cicd-statistics/src/components/label.tsx | 40 ++++++ .../src/{charts => components}/utils.tsx | 4 + plugins/cicd-statistics/src/entity-page.tsx | 6 +- 8 files changed, 230 insertions(+), 20 deletions(-) create mode 100644 plugins/cicd-statistics/src/components/duration-slider.tsx create mode 100644 plugins/cicd-statistics/src/components/label.tsx rename plugins/cicd-statistics/src/{charts => components}/utils.tsx (96%) diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index b185a4a50e..19b4ac84b2 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -132,13 +132,14 @@ export interface CicdDefaults { filterStatus: Array; filterType: FilterBranchType | 'all'; - /** Default collapse the stages with a max-duration below this value */ - collapsedLimit: number; - /** Lower-case all stage names (to potentially merge stages with different cases) */ lowercaseNames: boolean; /** Normalize the from-to date range in all charts */ normalizeTimeRange: boolean; + /** Default collapse the stages with a max-duration below this value */ + collapsedLimit: number; + /** Default hide stages with a max-duration below this value */ + hideLimit: number; /** Chart types per status */ chartTypes: Record; } diff --git a/plugins/cicd-statistics/src/charts/stage-chart.tsx b/plugins/cicd-statistics/src/charts/stage-chart.tsx index 3e18bd17cd..f9b0312595 100644 --- a/plugins/cicd-statistics/src/charts/stage-chart.tsx +++ b/plugins/cicd-statistics/src/charts/stage-chart.tsx @@ -48,7 +48,7 @@ import { tickFormatterY, tooltipValueFormatter, formatDuration, -} from './utils'; +} from '../components/utils'; import { statusColorMap, fireColors, @@ -67,12 +67,18 @@ export interface StageChartProps { chartTypes: CicdDefaults['chartTypes']; defaultCollapsed?: number; + defaultHidden?: number; zeroYAxis?: boolean; } export function StageChart(props: StageChartProps) { const { stage, ...chartOptions } = props; - const { chartTypes, defaultCollapsed = 0, zeroYAxis = false } = chartOptions; + const { + chartTypes, + defaultCollapsed = 0, + defaultHidden = 0, + zeroYAxis = false, + } = chartOptions; const ticks = useMemo( () => pickElements(stage.values, 8).map(val => val.__epoch), @@ -97,7 +103,17 @@ export function StageChart(props: StageChartProps) { [statuses], ); - return ( + const subStages = useMemo( + () => + new Map( + [...stage.stages.entries()].filter( + ([_name, subStage]) => subStage.combinedAnalysis.max > defaultHidden, + ), + ), + [stage.stages, defaultHidden], + ); + + return stage.combinedAnalysis.max < defaultHidden ? null : ( defaultCollapsed} TransitionProps={transitionProps} @@ -209,18 +225,18 @@ export function StageChart(props: StageChartProps) { - {stage.stages.size === 0 ? null : ( + {subStages.size === 0 ? null : ( }> - Sub stages ({stage.stages.size}) + Sub stages ({subStages.size})
- {[...stage.stages.values()].map(subStage => ( + {[...subStages.values()].map(subStage => ( ( +export const useStyles = makeStyles( theme => ({ rootCard: { padding: theme.spacing(0, 0, 0, 0), @@ -81,7 +83,7 @@ const useStyles = makeStyles( }, }), { - name: 'CicdStatisticsChartFilters', + name: 'CicdStatistics', }, ); @@ -127,7 +129,11 @@ function isSameChartFilter(a: ChartFilter, b: ChartFilter): boolean { export type ViewOptions = Pick< CicdDefaults, - 'lowercaseNames' | 'normalizeTimeRange' | 'chartTypes' + | 'lowercaseNames' + | 'normalizeTimeRange' + | 'collapsedLimit' + | 'hideLimit' + | 'chartTypes' >; export function getDefaultViewOptions( @@ -136,6 +142,8 @@ export function getDefaultViewOptions( return { lowercaseNames: cicdConfiguration.defaults?.lowercaseNames ?? false, normalizeTimeRange: cicdConfiguration.defaults?.normalizeTimeRange ?? true, + collapsedLimit: 60 * 1000, // 1m + hideLimit: 20 * 1000, // 20s chartTypes: { succeeded: ['duration'], failed: ['count'], @@ -224,6 +232,20 @@ export function ChartFilters(props: ChartFiltersProps) { [setViewOptions], ); + const setHideLimit = useCallback( + (value: number) => { + setViewOptions(old => ({ ...old, hideLimit: value })); + }, + [setViewOptions], + ); + + const setCollapseLimit = useCallback( + (value: number) => { + setViewOptions(old => ({ ...old, collapsedLimit: value })); + }, + [setViewOptions], + ); + const setChartType = useCallback( (statusType: FilterStatusType, chartTypes: ChartTypes) => { setViewOptions(old => ({ @@ -351,7 +373,7 @@ export function ChartFilters(props: ChartFiltersProps) { onChange={toggleUseNowAsDate} /> } - label="To today" + label={} /> {useNowAsToDate ? null : ( - Lowercase names + - Normalize time range + + + ({ + value: index, + label: formatDurationFromSeconds(value), + seconds: value, +})); + +function findMarkIndex(seconds: number): number { + if (marks[0].seconds > seconds) { + return 0; + } else if (marks[marks.length - 1].seconds < seconds) { + return marks.length - 1; + } + for (let i = 0; i < marks.length - 1; ++i) { + const a = marks[i]; + const b = marks[i + 1]; + if (seconds === a.seconds) { + return i; + } else if (seconds === b.seconds) { + return i + 1; + } else if (a.seconds < seconds && b.seconds > seconds) { + return seconds - a.seconds < b.seconds - seconds ? i : i - 1; + } + } + return 0; // Won't happen +} + +function formatDurationFromIndex(index: number) { + return formatDurationFromSeconds(marks[index].seconds); +} + +export interface DurationSliderProps { + header: string; + value: number; + setValue: (value: number) => void; +} + +export function DurationSlider(props: DurationSliderProps) { + const { header, value, setValue } = props; + + const [curValue, setCurValue] = useState(value); + + const debouncedSetValue = useMemo(() => debounce(setValue, 1000), [setValue]); + + const onChange = useCallback( + (_: any, index: number | number[]) => { + const millis = marks[index as number].seconds * 1000; + setCurValue(millis); + debouncedSetValue(millis); + }, + [debouncedSetValue], + ); + + const indexValue = useMemo(() => findMarkIndex(curValue / 1000), [curValue]); + + return ( + <> + + + + ); +} diff --git a/plugins/cicd-statistics/src/components/label.tsx b/plugins/cicd-statistics/src/components/label.tsx new file mode 100644 index 0000000000..fe064d30a6 --- /dev/null +++ b/plugins/cicd-statistics/src/components/label.tsx @@ -0,0 +1,40 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { PropsWithChildren } from 'react'; +import { Typography, Theme, makeStyles } from '@material-ui/core'; + +export const useStyles = makeStyles( + theme => ({ + label: { + fontWeight: 'normal', + margin: theme.spacing(0), + }, + }), + { + name: 'CicdStatisticsLabel', + }, +); + +export function Label({ children }: PropsWithChildren<{}>) { + const classes = useStyles(); + + return ( + + {children} + + ); +} diff --git a/plugins/cicd-statistics/src/charts/utils.tsx b/plugins/cicd-statistics/src/components/utils.tsx similarity index 96% rename from plugins/cicd-statistics/src/charts/utils.tsx rename to plugins/cicd-statistics/src/components/utils.tsx index 6086e84ade..6eeb81df23 100644 --- a/plugins/cicd-statistics/src/charts/utils.tsx +++ b/plugins/cicd-statistics/src/components/utils.tsx @@ -117,3 +117,7 @@ export function formatDuration(millis: number) { return dur.toHuman({ unitDisplay: 'narrow' }).replace(/, /g, ''); } + +export function formatDurationFromSeconds(seconds: number) { + return formatDuration(seconds * 1000); +} diff --git a/plugins/cicd-statistics/src/entity-page.tsx b/plugins/cicd-statistics/src/entity-page.tsx index c007e355a9..87f5a9e8d4 100644 --- a/plugins/cicd-statistics/src/entity-page.tsx +++ b/plugins/cicd-statistics/src/entity-page.tsx @@ -152,8 +152,6 @@ function CicdCharts(props: CicdChartsProps) { errorApi.post(chartableStagesState.error); }, [errorApi, chartableStagesState.error]); - const collapsedLimit = cicdConfiguration.defaults.collapsedLimit ?? 60 * 1000; // 1m - return ( @@ -176,13 +174,15 @@ function CicdCharts(props: CicdChartsProps) { {[...chartableStages.stages.entries()].map(([name, stage]) => ( ))} From ec1ddbd8121dc1aa1559a330d65167a72f189680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Mon, 24 Jan 2022 10:16:43 +0100 Subject: [PATCH 36/51] docs(cicd-statistics): Made it a bit more clear this plugin requires a custom API implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/plugins/cicd-statistics/README.md b/plugins/cicd-statistics/README.md index 78733735d7..8d91d74794 100644 --- a/plugins/cicd-statistics/README.md +++ b/plugins/cicd-statistics/README.md @@ -2,6 +2,12 @@ This plugin shows charts of CI/CD pipeline durations over time. It expects to be used on the Software Catalog entity page, as it uses `useEntity` to figure out what component to get the build information for. -To use this plugin, you need to implement an API `CicdStatisticsApi` and bind it to the `cicdStatisticsApiRef`. This API is defined in `src/apis/types.ts` and is an interface with two functions, `getConfiguration()` and `fetchBuilds(options)`. This plugin will call `getConfiguration` to allow the implementation to specify defaults and settings for the UI. First time the UI shows, and each time the user changes filters and clicks `Update` to refresh the data, `fetchBuilds` is invoked with the filter options. The API implementation is the expected to fetch build information from somewhere, format it into a generic and rather simple type `Build` (also defined in `types.ts`). The API can optionally signal completion for a progress bar in the UI. +## Usage -When this plugin has fetched the builds, it will transpose the list of builds (and build stages) into a tree of build stages. As build pipelines sometimes change, certain stages might end or begin within the date range of the view. +> This plugin cannot be used as-is; it requires a custom implementation to fetch build information + +To use this plugin, you need to implement an API `CicdStatisticsApi` and bind it to the `cicdStatisticsApiRef`. This API is defined in `src/apis/types.ts` and is an interface with two functions, `getConfiguration(options)` and `fetchBuilds(options)`. This plugin will call `getConfiguration` to allow the implementation to specify defaults and settings for the UI. + +First time the UI shows, and each time the user changes filters and clicks `Update` to refresh the data, `fetchBuilds` is invoked with the filter options. The API implementation is the expected to fetch build information from somewhere, format it into a generic and rather simple type `Build` (also defined in `types.ts`). The API can optionally signal completion for a progress bar in the UI. + +When this plugin has fetched the builds, it will transpose the list of builds (and build stages) into a tree of build stages. As build pipelines sometimes change, certain stages might end or begin within the date range of the view (when _Normalize time range_ is enabled, which is the default). From fdabd241d2b42916014ab9cc2d155a67c7fb3458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Wed, 2 Feb 2022 13:18:19 +0100 Subject: [PATCH 37/51] feat(cicd-statistics): Added trigger reason MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some refactoring and tweaks. The trigger reason is an overlay to the build counts, and is a percentage of manually triggered builds vs all builds. When this is high, it indicates likelyhood of flaky tests. Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/src/apis/types.ts | 20 +++ plugins/cicd-statistics/src/charts/colors.ts | 9 +- .../src/charts/logic/conversions.ts | 36 +++- .../src/charts/logic/count-builds-per-day.ts | 10 +- .../src/charts/logic/daily-summary.ts | 115 ++++++++++++ .../src/charts/logic/utils.test.ts | 27 +++ .../cicd-statistics/src/charts/logic/utils.ts | 32 +++- .../src/charts/stage-chart.tsx | 7 +- .../src/charts/status-chart.tsx | 163 +++++++++++++----- plugins/cicd-statistics/src/charts/types.ts | 55 +++++- .../src/components/chart-filters.tsx | 20 ++- .../cicd-statistics/src/components/utils.tsx | 3 +- plugins/cicd-statistics/src/entity-page.tsx | 18 +- 13 files changed, 436 insertions(+), 79 deletions(-) create mode 100644 plugins/cicd-statistics/src/charts/logic/daily-summary.ts create mode 100644 plugins/cicd-statistics/src/charts/logic/utils.test.ts diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index 19b4ac84b2..0726c566c7 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -53,6 +53,23 @@ export const statusTypes: Array = [ */ export type FilterBranchType = 'master' | 'branch'; +export type TriggerReason = + /** Triggered by source code management, e.g. a Github hook */ + | 'scm' + /** Triggered manually */ + | 'manual' + /** Triggered internally (non-scm, or perhaps after being delayed/enqueued) */ + | 'internal' + /** Triggered for some other reason */ + | 'other'; + +export const triggerReasons: Array = [ + 'scm', + 'manual', + 'internal', + 'other', +]; + /** * A Stage is a part of either a Build or a parent Stage. * @@ -84,6 +101,9 @@ export interface Build { /** Build id */ id: string; + /** The reason this build was started */ + triggeredBy?: TriggerReason; + /** The status of the build */ status: FilterStatusType; diff --git a/plugins/cicd-statistics/src/charts/colors.ts b/plugins/cicd-statistics/src/charts/colors.ts index e1ccb67fea..670b214665 100644 --- a/plugins/cicd-statistics/src/charts/colors.ts +++ b/plugins/cicd-statistics/src/charts/colors.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { FilterStatusType } from '../apis/types'; +import { FilterStatusType, TriggerReason } from '../apis/types'; export const statusColorMap: Record = { unknown: '#3d01a4', @@ -28,6 +28,13 @@ export const statusColorMap: Record = { expired: '#a7194b', }; +export const triggerColorMap: Record = { + scm: '#0391ce', + manual: '#a7194b', + internal: '#82ca9d', + other: '#f3f318', +}; + export const fireColors: Array<[percent: string, color: string]> = [ ['5%', '#e19678'], ['30%', '#dfe178'], diff --git a/plugins/cicd-statistics/src/charts/logic/conversions.ts b/plugins/cicd-statistics/src/charts/logic/conversions.ts index b2e990d9e4..c548b0e2f5 100644 --- a/plugins/cicd-statistics/src/charts/logic/conversions.ts +++ b/plugins/cicd-statistics/src/charts/logic/conversions.ts @@ -16,10 +16,11 @@ import { map } from 'already'; -import { Build, Stage } from '../../apis/types'; +import { Build, Stage, FilterStatusType } from '../../apis/types'; import { ChartableStage, ChartableStagesAnalysis } from '../types'; -import { getOrSetStage, makeStage } from './utils'; +import { getOrSetStage, makeStage, sortStatuses } from './utils'; import { finalizeStage } from './finalize-stage'; +import { dailySummary } from './daily-summary'; export interface ChartableStagesOptions { normalizeTimeRange: boolean; @@ -86,5 +87,34 @@ export async function buildsToChartableStages( ); finalizeStage(total, { allEpochs, averageWidth: 10 }); - return { total, stages }; + const daily = dailySummary(builds); + + const statuses = findStatuses(total, [...stages.values()]); + + return { daily, total, stages, statuses }; +} + +function findStatuses( + total: ChartableStage, + stages: Array, +): Array { + const statuses = new Set(); + + const addStatuses = (set: Set) => { + set.forEach(status => { + statuses.add(status); + }); + }; + + addStatuses(total.statusSet); + + const recurse = (subStages: Array) => { + subStages.forEach(stage => { + addStatuses(stage.statusSet); + recurse([...stage.stages.values()]); + }); + }; + recurse(stages); + + return sortStatuses([...statuses]); } diff --git a/plugins/cicd-statistics/src/charts/logic/count-builds-per-day.ts b/plugins/cicd-statistics/src/charts/logic/count-builds-per-day.ts index c7c7ce1c21..54e47c3f5b 100644 --- a/plugins/cicd-statistics/src/charts/logic/count-builds-per-day.ts +++ b/plugins/cicd-statistics/src/charts/logic/count-builds-per-day.ts @@ -14,20 +14,16 @@ * limitations under the License. */ -import { DateTime } from 'luxon'; import { groupBy } from 'lodash'; import { FilterStatusType, statusTypes } from '../../apis/types'; import { Countify, ChartableStageDatapoints } from '../types'; - -function startOfDayEpoch(epoch: number) { - return DateTime.fromMillis(epoch).startOf('day').toMillis(); -} +import { startOfDay } from './utils'; export function countBuildsPerDay( values: ReadonlyArray, ) { - const days = groupBy(values, value => startOfDayEpoch(value.__epoch)); + const days = groupBy(values, value => startOfDay(value.__epoch)); Object.entries(days).forEach(([_startOfDay, valuesThisDay]) => { const counts = Object.fromEntries( statusTypes @@ -35,7 +31,7 @@ export function countBuildsPerDay( type => [ type, - valuesThisDay.map(value => value[type] !== undefined).length, + valuesThisDay.filter(value => value[type] !== undefined).length, ] as const, ) .filter(([_type, count]) => count > 0) diff --git a/plugins/cicd-statistics/src/charts/logic/daily-summary.ts b/plugins/cicd-statistics/src/charts/logic/daily-summary.ts new file mode 100644 index 0000000000..93c7b07c34 --- /dev/null +++ b/plugins/cicd-statistics/src/charts/logic/daily-summary.ts @@ -0,0 +1,115 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { groupBy, countBy } from 'lodash'; + +import { Build } from '../../apis/types'; +import { + Epoch, + TriggerReasonsDatapoint, + StatusesDatapoint, + ChartableDaily, +} from '../types'; +import { sortStatuses, sortTriggerReasons, startOfDay } from './utils'; + +export function dailySummary(builds: ReadonlyArray): ChartableDaily { + const triggersDaily = countTriggersPerDay(builds); + const statusesDaily = countStatusesPerDay(builds); + + const { triggerReasons } = triggersDaily; + const { statuses } = statusesDaily; + + const reasonMap = new Map( + triggersDaily.values.map(value => [value.__epoch, value]), + ); + const statusMap = new Map( + statusesDaily.values.map(value => [value.__epoch, value]), + ); + + const days = Object.keys( + groupBy(builds, value => startOfDay(value.requestedAt)), + ) + .map(epoch => parseInt(epoch, 10)) + .sort(); + + return { + values: days.map(epoch => ({ + __epoch: epoch, + ...reasonMap.get(epoch), + ...statusMap.get(epoch), + })), + triggerReasons, + statuses, + }; +} + +function countTriggersPerDay(builds: ReadonlyArray) { + const days = groupBy(builds, value => startOfDay(value.requestedAt)); + + const triggerReasons = sortTriggerReasons([ + ...new Set( + builds + .map(({ triggeredBy }) => triggeredBy) + .filter((v): v is NonNullable => !!v), + ), + ]); + + const values = Object.entries(days).map(([epoch, buildsThisDay]) => { + const datapoint = Object.fromEntries( + triggerReasons + .map(reason => [ + reason, + buildsThisDay.filter(build => build.triggeredBy === reason).length, + ]) + .filter(([_type, count]) => count > 0), + ) as Omit; + + // Assign the count for this day to the first value this day + const value: Epoch & TriggerReasonsDatapoint = Object.assign(datapoint, { + __epoch: parseInt(epoch, 10), + }); + + return value; + }); + + return { triggerReasons, values }; +} + +function countStatusesPerDay(builds: ReadonlyArray) { + const days = groupBy(builds, value => startOfDay(value.requestedAt)); + + const foundStatuses = new Set(); + + const values = Object.entries(days).map(([epoch, buildsThisDay]) => { + const byStatus = countBy(buildsThisDay, 'status'); + + const value: Epoch & StatusesDatapoint = { + __epoch: parseInt(epoch, 10), + ...byStatus, + }; + + Object.keys(byStatus).forEach(status => { + foundStatuses.add(status); + }); + + return value; + }); + + return { + statuses: sortStatuses([...foundStatuses]), + values, + }; +} diff --git a/plugins/cicd-statistics/src/charts/logic/utils.test.ts b/plugins/cicd-statistics/src/charts/logic/utils.test.ts new file mode 100644 index 0000000000..420a6bf90c --- /dev/null +++ b/plugins/cicd-statistics/src/charts/logic/utils.test.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { sortTriggerReasons } from './daily-summary'; + +describe('daily-summary', () => { + it('sortTriggerReasons', () => { + const values = ['a', 'manual', 'b', 'other', 'c', 'scm', 'd']; + const expected = ['manual', 'scm', 'other', 'a', 'b', 'c', 'd']; + + expect(sortTriggerReasons(values)).toStrictEqual(expected); + expect(sortTriggerReasons(values.reverse())).toStrictEqual(expected); + }); +}); diff --git a/plugins/cicd-statistics/src/charts/logic/utils.ts b/plugins/cicd-statistics/src/charts/logic/utils.ts index 0c3900d025..f3a0087a3d 100644 --- a/plugins/cicd-statistics/src/charts/logic/utils.ts +++ b/plugins/cicd-statistics/src/charts/logic/utils.ts @@ -14,7 +14,9 @@ * limitations under the License. */ -import { FilterStatusType } from '../../apis/types'; +import { DateTime } from 'luxon'; + +import { FilterStatusType, statusTypes } from '../../apis/types'; import { ChartableStage } from '../types'; export function average(values: number[]): number { @@ -55,3 +57,31 @@ export function makeStage(name: string): ChartableStage { stages: new Map(), }; } + +export function startOfDay(date: number | Date) { + if (typeof date === 'number') { + return DateTime.fromMillis(date).startOf('day').toMillis(); + } + return DateTime.fromJSDate(date).startOf('day').toMillis(); +} + +export function sortTriggerReasons(reasons: Array): Array { + return reasons.sort((a, b) => { + if (a === 'manual') return -1; + else if (b === 'manual') return 1; + else if (a === 'scm') return -1; + else if (b === 'scm') return 1; + else if (a === 'other') return -1; + else if (b === 'other') return 1; + return a.localeCompare(b); + }); +} + +export function sortStatuses(statuses: Array): Array { + return [ + ...statusTypes.filter(status => statuses.includes(status)), + ...statuses + .filter(status => !(statusTypes as Array).includes(status)) + .sort((a, b) => a.localeCompare(b)), + ]; +} diff --git a/plugins/cicd-statistics/src/charts/stage-chart.tsx b/plugins/cicd-statistics/src/charts/stage-chart.tsx index f9b0312595..4141a6755a 100644 --- a/plugins/cicd-statistics/src/charts/stage-chart.tsx +++ b/plugins/cicd-statistics/src/charts/stage-chart.tsx @@ -38,6 +38,7 @@ import { Typography, } from '@material-ui/core'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import { capitalize } from 'lodash'; import { CicdDefaults, statusTypes } from '../apis/types'; import { ChartableStage } from './types'; @@ -95,7 +96,7 @@ export function StageChart(props: StageChartProps) { const legendPayload = useMemo( (): LegendProps['payload'] => statuses.map(status => ({ - value: status, + value: capitalize(status), type: 'line', id: status, color: statusColorMap[status], @@ -172,7 +173,7 @@ export function StageChart(props: StageChartProps) { labelFormatter={labelFormatter} /> {statuses.reverse().map(status => ( - <> + {!chartTypes[status].includes('duration') ? null : ( )} - + ))} diff --git a/plugins/cicd-statistics/src/charts/status-chart.tsx b/plugins/cicd-statistics/src/charts/status-chart.tsx index ff4d3fea3a..5a4cc953ca 100644 --- a/plugins/cicd-statistics/src/charts/status-chart.tsx +++ b/plugins/cicd-statistics/src/charts/status-chart.tsx @@ -16,6 +16,7 @@ import React, { Fragment, useMemo } from 'react'; import { + Area, Bar, ComposedChart, XAxis, @@ -34,66 +35,101 @@ import { Typography, } from '@material-ui/core'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import { countBy } from 'lodash'; -import { DateTime } from 'luxon'; +import { capitalize } from 'lodash'; -import { Build, FilterStatusType, statusTypes } from '../apis/types'; +import { FilterStatusType, TriggerReason } from '../apis/types'; import { labelFormatterWithoutTime, tickFormatterX } from '../components/utils'; -import { statusColorMap } from './colors'; +import { statusColorMap, triggerColorMap } from './colors'; +import { ChartableStagesAnalysis } from './types'; export interface StatusChartProps { - builds: ReadonlyArray; + analysis: ChartableStagesAnalysis; } export function StatusChart(props: StatusChartProps) { - const { builds } = props; + const { analysis } = props; - const { statuses, values } = useMemo(() => { - const buildsByDay = new Map>(); + const values = useMemo(() => { + return analysis.daily.values.map(value => { + const totTriggers = analysis.daily.triggerReasons.reduce( + (prev, cur) => prev + (value[cur as TriggerReason] ?? 0), + 0, + ); - const foundStatuses = new Set(); - - builds.forEach(build => { - foundStatuses.add(build.status); - - const dayString = DateTime.fromJSDate(build.requestedAt).toISODate(); - const dayList = buildsByDay.get(dayString); - if (dayList) { - dayList.push(build); - } else { - buildsByDay.set(dayString, [build]); + if (!totTriggers) { + return value; } - }); - return { - statuses: [ - ...statusTypes.filter(status => foundStatuses.has(status)), - ...[...foundStatuses].filter( - status => !(statusTypes as Array).includes(status), + return { + ...value, + ...Object.fromEntries( + analysis.daily.triggerReasons.map(reason => [ + reason, + (value[reason as TriggerReason] ?? 0) / totTriggers, + ]), ), - ], - values: [...buildsByDay.entries()].map(([dayString, buildThisDay]) => ({ - __epoch: DateTime.fromISO(dayString).toMillis(), - ...countBy(buildThisDay, 'status'), - })), - }; - }, [builds]); + }; + }); + }, [analysis.daily]); - const legendPayload = useMemo( - (): LegendProps['payload'] => - statuses.map(status => ({ - value: status, + const triggerReasonLegendPayload = useMemo( + (): NonNullable => + analysis.daily.triggerReasons.map(reason => ({ + value: humanTriggerReason(reason), + type: 'line', + id: reason, + color: triggerColorMap[reason as TriggerReason] ?? '', + })), + [analysis.daily.triggerReasons], + ); + + const statusesLegendPayload = useMemo( + (): NonNullable => + analysis.daily.statuses.map(status => ({ + value: capitalize(status), type: 'line', id: status, color: statusColorMap[status as FilterStatusType] ?? '', })), - [statuses], + [analysis.daily.statuses], ); + const legendPayload = useMemo( + (): NonNullable => [ + ...triggerReasonLegendPayload, + ...statusesLegendPayload, + ], + [statusesLegendPayload, triggerReasonLegendPayload], + ); + + const tooltipFormatter = useMemo(() => { + const reasonSet = new Set(analysis.daily.triggerReasons); + + return (percentOrCount: number, name: string) => { + const label = reasonSet.has(name) + ? humanTriggerReason(name) + : capitalize(name); + const valueText = reasonSet.has(name) + ? `${(percentOrCount * 100).toFixed(0)}%` + : percentOrCount; + + return [ + + {label}: {valueText} + , + null, + ]; + }; + }, [analysis.daily.triggerReasons]); + + const barSize = getBarSize(analysis.daily.values.length); + return ( - 1}> + 1}> }> - Build count per status + + Build count per status over build trigger reason + {values.length === 0 ? ( @@ -108,14 +144,33 @@ export function StatusChart(props: StatusChartProps) { type="category" tickFormatter={tickFormatterX} /> - - - {statuses.map(status => ( + + + + {triggerReasonLegendPayload.map(reason => ( + + + + ))} + {[...analysis.daily.statuses].reverse().map(status => ( ); } + +function humanTriggerReason(reason: string): string { + if ((reason as TriggerReason) === 'manual') { + return 'Triggered manually'; + } else if ((reason as TriggerReason) === 'scm') { + return 'Triggered by SCM'; + } else if ((reason as TriggerReason) === 'internal') { + return 'Triggered internally'; + } else if ((reason as TriggerReason) === 'other') { + return 'Triggered by another reason'; + } + return `Triggered by ${reason}`; +} + +function getBarSize(count: number): number { + if (count < 20) { + return 10; + } else if (count < 40) { + return 8; + } + return 5; +} diff --git a/plugins/cicd-statistics/src/charts/types.ts b/plugins/cicd-statistics/src/charts/types.ts index 75a72a8a4f..88c0085f77 100644 --- a/plugins/cicd-statistics/src/charts/types.ts +++ b/plugins/cicd-statistics/src/charts/types.ts @@ -14,14 +14,14 @@ * limitations under the License. */ -import { FilterStatusType } from '../apis/types'; +import { FilterStatusType, TriggerReason } from '../apis/types'; export type Averagify = `${T} avg`; export type Countify = `${T} count`; -export type ChartableStageDatapoints = { - __epoch: number; -} & { +export type Epoch = { __epoch: number }; + +export type ChartableStageDatapoints = Epoch & { [status in FilterStatusType]?: number; } & { [status in Averagify]?: number; @@ -50,7 +50,48 @@ export interface ChartableStage { stages: Map; } -export interface ChartableStagesAnalysis { - total: ChartableStage; - stages: Map; +export type TriggerReasonsDatapoint = { + [K in TriggerReason]?: number; +}; +export type StatusesDatapoint = { [status in FilterStatusType]?: number }; + +export type ChartableDailyDatapoint = Epoch & + TriggerReasonsDatapoint & + StatusesDatapoint; + +export interface ChartableDaily { + values: Array; + + /** + * The build trigger reasons + */ + triggerReasons: Array; + + /** + * The top-level (build) statuses + */ + statuses: Array; +} + +export interface ChartableStagesAnalysis { + /** + * Summary of statuses and trigger reasons per day + */ + daily: ChartableDaily; + + /** + * Total aggregates of sub stages + */ + total: ChartableStage; + + /** + * Top-level stages {name -> stage} + */ + stages: Map; + + /** + * All statuses found deeper in the stage tree. A stage might have been + * _aborted_ although the build actually _failed_, e.g. + */ + statuses: Array; } diff --git a/plugins/cicd-statistics/src/components/chart-filters.tsx b/plugins/cicd-statistics/src/components/chart-filters.tsx index 6ff44bc40a..03cbea5dd0 100644 --- a/plugins/cicd-statistics/src/components/chart-filters.tsx +++ b/plugins/cicd-statistics/src/components/chart-filters.tsx @@ -48,6 +48,7 @@ import { FilterStatusType, statusTypes, } from '../apis/types'; +import { ChartableStagesAnalysis } from '../charts/types'; import { ButtonSwitch, SwitchValue } from './button-switch'; import { Toggle } from './toggle'; import { DurationSlider } from './duration-slider'; @@ -93,8 +94,8 @@ export type StatusSelection = FilterStatusType; export interface ChartFilter { fromDate: Date; toDate: Date; - branch: BranchSelection; - status: Array; + branch: string; + status: Array; } export function getDefaultChartFilter( @@ -175,6 +176,8 @@ const chartTypeValues: Array> = [ ]; export interface ChartFiltersProps { + analysis?: ChartableStagesAnalysis; + cicdConfiguration: CicdConfiguration; initialFetchFilter: ChartFilter; currentFetchFilter?: ChartFilter; @@ -191,6 +194,7 @@ interface InternalRef { export function ChartFilters(props: ChartFiltersProps) { const { + analysis, cicdConfiguration, initialFetchFilter, currentFetchFilter, @@ -325,6 +329,8 @@ export function ChartFilters(props: ChartFiltersProps) { }); }, [toDate, fromDate, branch, selectedStatus, updateFetchFilter]); + const inrefferedStatuses = analysis?.statuses ?? selectedStatus; + return ( @@ -395,7 +401,7 @@ export function ChartFilters(props: ChartFiltersProps) { > Branch - + values={branchValues} selection={branch} onChange={setBranch} @@ -406,7 +412,7 @@ export function ChartFilters(props: ChartFiltersProps) { > Status - + values={statusValues} multi vertical @@ -469,12 +475,12 @@ export function ChartFilters(props: ChartFiltersProps) { > Chart styles - {currentFetchFilter?.status.map(status => ( - + {inrefferedStatuses.map(status => ( + values={chartTypeValues} - selection={viewOptions.chartTypes[status]} + selection={viewOptions.chartTypes[status as FilterStatusType]} onChange={setChartTypeSpecific[status]} multi /> diff --git a/plugins/cicd-statistics/src/components/utils.tsx b/plugins/cicd-statistics/src/components/utils.tsx index 6eeb81df23..2b6d1ad029 100644 --- a/plugins/cicd-statistics/src/components/utils.tsx +++ b/plugins/cicd-statistics/src/components/utils.tsx @@ -16,6 +16,7 @@ import React, { CSSProperties } from 'react'; import { DateTime, Duration } from 'luxon'; +import { capitalize } from 'lodash'; const infoText: CSSProperties = { color: 'InfoText' }; @@ -79,7 +80,7 @@ export function tickFormatterY(duration: number) { export function tooltipValueFormatter(durationOrCount: number, name: string) { return [ - {name}:{' '} + {capitalize(name)}:{' '} {name.endsWith(' count') ? durationOrCount : formatDuration(durationOrCount)} diff --git a/plugins/cicd-statistics/src/entity-page.tsx b/plugins/cicd-statistics/src/entity-page.tsx index 87f5a9e8d4..532900c1da 100644 --- a/plugins/cicd-statistics/src/entity-page.tsx +++ b/plugins/cicd-statistics/src/entity-page.tsx @@ -35,7 +35,11 @@ import { getDefaultViewOptions, ViewOptions, } from './components/chart-filters'; -import { CicdConfiguration } from './apis'; +import { + CicdConfiguration, + FilterStatusType, + FilterBranchType, +} from './apis/types'; import { cleanupBuildTree } from './utils/stage-names'; import { renderFallbacks, useAsyncChain } from './components/progress'; import { sortFilterStatusType } from './utils/api'; @@ -68,7 +72,7 @@ function endOfDay(date: Date) { function cleanChartFilter(filter: ChartFilter): ChartFilter { return { ...filter, - status: sortFilterStatusType(filter.status), + status: sortFilterStatusType(filter.status as FilterStatusType[]), }; } @@ -104,8 +108,8 @@ function CicdCharts(props: CicdChartsProps) { entity, timeFrom: startOfDay(fetchedChartData.chartFilter.fromDate), timeTo: endOfDay(fetchedChartData.chartFilter.toDate), - filterStatus: fetchedChartData.chartFilter.status, - filterType: fetchedChartData.chartFilter.branch, + filterStatus: fetchedChartData.chartFilter.status as FilterStatusType[], + filterType: fetchedChartData.chartFilter.branch as FilterBranchType, }; }, [entity, fetchedChartData]); @@ -156,6 +160,7 @@ function CicdCharts(props: CicdChartsProps) { {renderFallbacks(chartableStagesState, chartableStages => ( <> - {!statisticsState.value?.builds.length ? null : ( - + {!statisticsState.value?.builds?.length || + !chartableStagesState.value?.daily?.values?.length ? null : ( + )} Date: Wed, 2 Feb 2022 16:23:34 +0100 Subject: [PATCH 38/51] fix(cicd-statistics): Fixed progress bar animation, should be throttle, not debounce MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts b/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts index bf3558b7dc..5c1fe1bfe2 100644 --- a/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts +++ b/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts @@ -15,7 +15,7 @@ */ import { useState, useEffect } from 'react'; -import { debounce } from 'lodash'; +import { throttle } from 'lodash'; import { Entity } from '@backstage/catalog-model'; import { @@ -62,7 +62,7 @@ export function useCicdStatistics( let mounted = true; let completed = false; // successfully or failed - const updateProgress = debounce((count, total, started = 0) => { + const updateProgress = throttle((count, total, started = 0) => { if (mounted && !completed) { setState({ loading: true, From d5acd9f03554d19c5d15a84e233c976fabe481b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Wed, 2 Feb 2022 16:27:02 +0100 Subject: [PATCH 39/51] feat(cicd-statistics): Added zoom capability to the charts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since loading of build information can take a long time, being able to zoom "client-side", using the fetched data, is very useful. This is built using a provider (ZoomProvider) which keeps zoom state, simplifies rendering a gray area while zooming and has a filter-function which can filter only values within the zoomed time range. Signed-off-by: Gustaf Räntilä --- .../src/charts/stage-chart.tsx | 28 ++- .../src/charts/status-chart.tsx | 14 +- plugins/cicd-statistics/src/charts/zoom.tsx | 221 ++++++++++++++++++ .../cicd-statistics/src/components/utils.tsx | 8 + plugins/cicd-statistics/src/entity-page.tsx | 11 +- 5 files changed, 272 insertions(+), 10 deletions(-) create mode 100644 plugins/cicd-statistics/src/charts/zoom.tsx diff --git a/plugins/cicd-statistics/src/charts/stage-chart.tsx b/plugins/cicd-statistics/src/charts/stage-chart.tsx index 4141a6755a..ba3474153c 100644 --- a/plugins/cicd-statistics/src/charts/stage-chart.tsx +++ b/plugins/cicd-statistics/src/charts/stage-chart.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { Fragment, useMemo } from 'react'; +import React, { CSSProperties, Fragment, useMemo } from 'react'; import { Area, Bar, @@ -40,6 +40,7 @@ import { import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import { capitalize } from 'lodash'; +import { useZoom, useZoomArea } from './zoom'; import { CicdDefaults, statusTypes } from '../apis/types'; import { ChartableStage } from './types'; import { @@ -57,9 +58,8 @@ import { colorStrokeAvg, } from './colors'; -const fullWidth = { - width: '100%', -}; +const fullWidth: CSSProperties = { width: '100%' }; +const noUserSelect: CSSProperties = { userSelect: 'none' }; const transitionProps = { unmountOnExit: true }; @@ -81,6 +81,9 @@ export function StageChart(props: StageChartProps) { zeroYAxis = false, } = chartOptions; + const { zoomFilterValues } = useZoom(); + const { zoomProps, getZoomArea } = useZoomArea(); + const ticks = useMemo( () => pickElements(stage.values, 8).map(val => val.__epoch), [stage.values], @@ -114,6 +117,11 @@ export function StageChart(props: StageChartProps) { [stage.stages, defaultHidden], ); + const zoomFilteredValues = useMemo( + () => zoomFilterValues(stage.values), + [stage.values, zoomFilterValues], + ); + return stage.combinedAnalysis.max < defaultHidden ? null : ( defaultCollapsed} @@ -130,9 +138,9 @@ export function StageChart(props: StageChartProps) { No data ) : ( - + - + {fireColors.map(([percent, color]) => ( @@ -175,8 +183,9 @@ export function StageChart(props: StageChartProps) { {statuses.reverse().map(status => ( {!chartTypes[status].includes('duration') ? null : ( - + <> - + )} {!chartTypes[status].includes('count') ? null : ( ))} + {getZoomArea({ yAxisId: 1 })} diff --git a/plugins/cicd-statistics/src/charts/status-chart.tsx b/plugins/cicd-statistics/src/charts/status-chart.tsx index 5a4cc953ca..7b07885ca5 100644 --- a/plugins/cicd-statistics/src/charts/status-chart.tsx +++ b/plugins/cicd-statistics/src/charts/status-chart.tsx @@ -37,6 +37,7 @@ import { import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import { capitalize } from 'lodash'; +import { useZoom, useZoomArea } from './zoom'; import { FilterStatusType, TriggerReason } from '../apis/types'; import { labelFormatterWithoutTime, tickFormatterX } from '../components/utils'; import { statusColorMap, triggerColorMap } from './colors'; @@ -49,6 +50,9 @@ export interface StatusChartProps { export function StatusChart(props: StatusChartProps) { const { analysis } = props; + const { zoomFilterValues } = useZoom(); + const { zoomProps, getZoomArea } = useZoomArea(); + const values = useMemo(() => { return analysis.daily.values.map(value => { const totTriggers = analysis.daily.triggerReasons.reduce( @@ -122,6 +126,11 @@ export function StatusChart(props: StatusChartProps) { }; }, [analysis.daily.triggerReasons]); + const zoomFilteredValues = useMemo( + () => zoomFilterValues(values), + [values, zoomFilterValues], + ); + const barSize = getBarSize(analysis.daily.values.length); return ( @@ -136,7 +145,7 @@ export function StatusChart(props: StatusChartProps) { No data ) : ( - + ( ( ))} + {getZoomArea({ yAxisId: 1 })} )} diff --git a/plugins/cicd-statistics/src/charts/zoom.tsx b/plugins/cicd-statistics/src/charts/zoom.tsx new file mode 100644 index 0000000000..57e2b8678f --- /dev/null +++ b/plugins/cicd-statistics/src/charts/zoom.tsx @@ -0,0 +1,221 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { throttle } from 'lodash'; +import React, { + PropsWithChildren, + Dispatch, + SetStateAction, + Fragment, + useContext, + useState, + useCallback, + useMemo, + useEffect, +} from 'react'; +import { ReferenceArea } from 'recharts'; + +import type { Epoch } from './types'; + +interface ZoomState { + left?: number; + right?: number; +} + +interface ZoomContext { + registerSelection(setter: Dispatch): void; + setSelectState: Dispatch>; + + zoomState: ZoomState; + setZoomState: Dispatch>; + + resetZoom: () => void; +} + +const context = React.createContext(undefined as any); + +export function ZoomProvider({ children }: PropsWithChildren<{}>) { + const [registeredSelectors, setRegisteredSelectors] = useState< + Array> + >([]); + const [selectState, setSelectState] = useState({}); + const [zoomState, setZoomState] = useState({}); + + const registerSelection = useCallback( + (selector: Dispatch) => { + setRegisteredSelectors(old => [...old, selector]); + + return () => { + setRegisteredSelectors(old => old.filter(sel => sel === selector)); + }; + }, + [setRegisteredSelectors], + ); + + const callSelectors = useCallback( + (state: ZoomState) => { + registeredSelectors.forEach(selector => { + selector(state); + }); + }, + [registeredSelectors], + ); + + const throttledCallSelectors = useMemo( + () => throttle(callSelectors, 200), + [callSelectors], + ); + + useEffect(() => { + throttledCallSelectors({ + left: selectState.left, + right: selectState.right, + }); + }, [selectState.left, selectState.right, throttledCallSelectors]); + + const resetZoom = useCallback(() => { + setSelectState({}); + setZoomState({}); + }, [setSelectState, setZoomState]); + + const value = useMemo( + (): ZoomContext => ({ + registerSelection, + setSelectState, + + zoomState, + setZoomState, + + resetZoom, + }), + [registerSelection, setSelectState, zoomState, setZoomState, resetZoom], + ); + + return ; +} + +export function useZoom() { + const { zoomState, resetZoom } = useContext(context); + + const zoomFilterValues = useCallback( + (values: Array): Array => { + const { left, right } = zoomState; + return left === undefined || right === undefined + ? values + : values.filter(({ __epoch }) => __epoch > left && __epoch < right); + }, + [zoomState], + ); + + return useMemo( + () => ({ + resetZoom, + zoomState, + zoomFilterValues, + }), + [resetZoom, zoomState, zoomFilterValues], + ); +} + +export interface ZoomAreaProps { + yAxisId?: number | string | undefined; +} + +export function useZoomArea() { + const [showSelection, setShowSelection] = useState(false); + const [state, setState] = useState({}); + const { setSelectState, setZoomState, registerSelection } = + useContext(context); + + const onMouseDown = useCallback( + (e: any) => { + if (!e?.activeLabel) return; + + setSelectState({ left: e.activeLabel }); + setShowSelection(true); + }, + [setSelectState, setShowSelection], + ); + + const onMouseMove = useCallback( + (e: any) => { + if (!e?.activeLabel) return; + + setSelectState(area => { + if (!area.left) { + return area; + } + return { ...area, right: e.activeLabel }; + }); + }, + [setSelectState], + ); + + const doZoom = useCallback(() => { + setSelectState(old => { + const { left, right } = old; + + if (left === undefined || right === undefined || left === right) { + // Either is undefined or both are same - zoom out + setZoomState({}); + } else if (left < right) { + setZoomState({ left, right }); + } else if (left > right) { + setZoomState({ left: right, right: left }); + } + + return {}; + }); + setShowSelection(false); + }, [setSelectState, setZoomState, setShowSelection]); + + const zoomProps = useMemo( + () => ({ + onMouseDown, + onMouseMove, + onMouseUp: doZoom, + }), + [onMouseDown, onMouseMove, doZoom], + ); + + useEffect(() => { + if (!showSelection) { + return undefined; + } + return registerSelection(setState); + }, [registerSelection, setState, showSelection]); + + const getZoomArea = useCallback( + (props?: ZoomAreaProps) => ( + + {showSelection && state.left && state.right ? ( + + ) : null} + + ), + [showSelection, state.left, state.right], + ); + + return { + zoomProps, + getZoomArea, + }; +} diff --git a/plugins/cicd-statistics/src/components/utils.tsx b/plugins/cicd-statistics/src/components/utils.tsx index 2b6d1ad029..e4663c8cde 100644 --- a/plugins/cicd-statistics/src/components/utils.tsx +++ b/plugins/cicd-statistics/src/components/utils.tsx @@ -42,9 +42,17 @@ export function pickElements(arr: ReadonlyArray, num: number): Array { } function formatDateShort(milliseconds: number) { + if ((milliseconds as any) === 'auto') { + // When recharts gets confused (empty data) + return ''; + } return DateTime.fromMillis(milliseconds).toLocaleString(DateTime.DATE_SHORT); } function formatDateTimeShort(milliseconds: number) { + if ((milliseconds as any) === 'auto') { + // When recharts gets confused (empty data) + return ''; + } return DateTime.fromMillis(milliseconds).toLocaleString( DateTime.DATETIME_SHORT, ); diff --git a/plugins/cicd-statistics/src/entity-page.tsx b/plugins/cicd-statistics/src/entity-page.tsx index 532900c1da..74a0add0b3 100644 --- a/plugins/cicd-statistics/src/entity-page.tsx +++ b/plugins/cicd-statistics/src/entity-page.tsx @@ -26,6 +26,7 @@ import { } from './hooks/use-cicd-statistics'; import { useCicdConfiguration } from './hooks/use-cicd-configuration'; import { buildsToChartableStages } from './charts/logic/conversions'; +import { ZoomProvider, useZoom } from './charts/zoom'; import { StageChart } from './charts/stage-chart'; import { StatusChart } from './charts/status-chart'; import { @@ -48,7 +49,9 @@ export function EntityPageCicdCharts() { const state = useCicdConfiguration(); return renderFallbacks(state, value => ( - + + + )); } @@ -88,6 +91,8 @@ function CicdCharts(props: CicdChartsProps) { const classes = useStyles(); + const { resetZoom } = useZoom(); + const [chartFilter, setChartFilter] = useState( getDefaultChartFilter(cicdConfiguration), ); @@ -135,6 +140,10 @@ function CicdCharts(props: CicdChartsProps) { [statisticsState, cicdConfiguration, viewOptions], ); + useEffect(() => { + resetZoom(); + }, [resetZoom, statisticsState.value]); + const onFilterChange = useCallback((filter: ChartFilter) => { setChartFilter(cleanChartFilter(filter)); }, []); From 365e3f87ad0d593205d56bcdeb839f396f8bfc2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Mon, 7 Feb 2022 12:56:21 +0100 Subject: [PATCH 40/51] feat(cicd-statistics): Allow multi-step progress when loading statistics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Loading can take a pretty long time, and often in several steps, such as "loading builds" followed by "loading pipelines per build". Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/src/apis/types.ts | 18 ++- .../src/components/progress.tsx | 113 ++++++++++++++---- plugins/cicd-statistics/src/entity-page.tsx | 4 + .../src/hooks/use-cicd-configuration.ts | 6 +- .../src/hooks/use-cicd-statistics.ts | 39 +++++- 5 files changed, 144 insertions(+), 36 deletions(-) diff --git a/plugins/cicd-statistics/src/apis/types.ts b/plugins/cicd-statistics/src/apis/types.ts index 0726c566c7..0a87b40fc2 100644 --- a/plugins/cicd-statistics/src/apis/types.ts +++ b/plugins/cicd-statistics/src/apis/types.ts @@ -220,12 +220,20 @@ export interface CicdState { * * This can be called at any rate. Rate limiting (debouncing) is implemented in * the UI. + * + * Optionally this can signal multiple progresses in several steps */ -export type UpdateProgress = ( - completed: number, - total: number, - started?: number, -) => void; +export interface UpdateProgress { + (completed: number, total: number, started?: number): void; + ( + steps: Array<{ + title: string; + completed: number; + total: number; + started?: number; + }>, + ): void; +} /** * When reading configuration, the Api can return a custom settings depending on diff --git a/plugins/cicd-statistics/src/components/progress.tsx b/plugins/cicd-statistics/src/components/progress.tsx index 1b707573c0..9973ba170d 100644 --- a/plugins/cicd-statistics/src/components/progress.tsx +++ b/plugins/cicd-statistics/src/components/progress.tsx @@ -14,12 +14,23 @@ * limitations under the License. */ -import React, { DependencyList } from 'react'; +import React, { CSSProperties, DependencyList } from 'react'; import { useAsync } from 'react-use'; import { Box, LinearProgress } from '@material-ui/core'; +import Timeline from '@material-ui/lab/Timeline'; +import TimelineItem from '@material-ui/lab/TimelineItem'; +import TimelineSeparator from '@material-ui/lab/TimelineSeparator'; +import TimelineConnector from '@material-ui/lab/TimelineConnector'; +import TimelineContent from '@material-ui/lab/TimelineContent'; +import TimelineOppositeContent from '@material-ui/lab/TimelineOppositeContent'; +import TimelineDot, { TimelineDotProps } from '@material-ui/lab/TimelineDot'; import Alert from '@material-ui/lab/Alert'; import { useApp } from '@backstage/core-plugin-api'; +const stepProgressStyle: CSSProperties = { + marginTop: 6, +}; + // Matching react-use, only has loading/error/value type AsyncState = | { @@ -43,24 +54,33 @@ type AsyncState = value: T; }; -export type ProgressAsLoading = { +export interface ProgressStep extends ProgessAsSingle { + title: string; +} +export interface ProgessAsSteps { + steps: Array; +} +export interface ProgessAsSingle { + progress?: T; + progressBuffer?: T; +} + +export type ProgessState = + | ProgessAsSingle + | (T extends number ? ProgessAsSteps : { steps?: undefined }); + +export type ProgressAsLoading = ProgessState & { loading: true; - progress?: number; - progressBuffer?: number; error?: undefined; value?: undefined; }; -export type ProgressAsError = { +export type ProgressAsError = ProgessState & { loading?: false | undefined; - progress?: undefined; - progressBuffer?: undefined; error: Error; value?: undefined; }; -export type ProgressAsValue = { +export type ProgressAsValue = ProgessState & { loading?: false | undefined; - progress?: undefined; - progressBuffer?: undefined; error?: undefined; value: T; }; @@ -69,7 +89,7 @@ export type ProgressAsValue = { * An AsyncState but with the addition of progress (decimal 0-1) to allow * rendering a progress bar while waiting. */ -export type Progress = +export type ProgressType = | ProgressAsLoading | ProgressAsError | ProgressAsValue; @@ -79,8 +99,8 @@ const sentry = Symbol(); /** * Casts an AsyncState or Progress into its non-succeeded sub types */ -type Unsuccessful | AsyncState> = - S extends Progress +type Unsuccessful | AsyncState> = + S extends ProgressType ? ProgressAsLoading | ProgressAsError : Omit, 'value'>; @@ -92,7 +112,7 @@ type Unsuccessful | AsyncState> = * invoked for a new layer of async state with the dependent (upstream) success * result as argument. */ -export function useAsyncChain | AsyncState, R>( +export function useAsyncChain | AsyncState, R>( parentState: S, fn: (value: NonNullable) => Promise, deps: DependencyList, @@ -111,7 +131,7 @@ export function useAsyncChain | AsyncState, R>( } export function renderFallbacks( - state: Progress | AsyncState, + state: ProgressType | AsyncState, success: (value: T) => JSX.Element, ): JSX.Element { if (state.loading) { @@ -130,18 +150,67 @@ export function ViewProgress({ }) { const { Progress } = useApp().getComponents(); - const stateAsProgress = state as ProgressAsLoading; + const stateAsSingleProgress = state as ProgessAsSingle; + const stateAsStepProgress = state as ProgessAsSteps; - if (!stateAsProgress.progress && !stateAsProgress.progressBuffer) { + if ( + !stateAsSingleProgress.progress && + !stateAsSingleProgress.progressBuffer && + !stateAsStepProgress.steps + ) { + // Simple spinner return ; + } else if (stateAsSingleProgress.progress !== undefined) { + // Simple _single_ progress + return ( + + + + ); } + + // Multi-step progresses + return ( - + + {stateAsStepProgress.steps.map((step, index) => ( + + {step.title} + + + {index < stateAsStepProgress.steps.length - 1 ? ( + + ) : null} + + + {!step.progress && !step.progressBuffer ? null : ( + + )} + + + ))} + ); } + +function getDotColor(step: ProgressStep): TimelineDotProps['color'] { + const progress = step.progress ?? 0; + + if (progress >= 1) { + return 'primary'; + } else if (progress > 0) { + return 'secondary'; + } + return 'grey'; +} diff --git a/plugins/cicd-statistics/src/entity-page.tsx b/plugins/cicd-statistics/src/entity-page.tsx index 74a0add0b3..3c51dabf2a 100644 --- a/plugins/cicd-statistics/src/entity-page.tsx +++ b/plugins/cicd-statistics/src/entity-page.tsx @@ -16,6 +16,7 @@ import React, { useCallback, useState, useMemo, useEffect } from 'react'; import { Grid, makeStyles, Theme } from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; import { useEntity } from '@backstage/plugin-catalog-react'; import { useApi, errorApiRef } from '@backstage/core-plugin-api'; import { DateTime } from 'luxon'; @@ -182,6 +183,9 @@ function CicdCharts(props: CicdChartsProps) { {renderFallbacks(chartableStagesState, chartableStages => ( <> + {chartableStages.stages.size > 0 ? null : ( + No data + )} {!statisticsState.value?.builds?.length || !chartableStagesState.value?.daily?.values?.length ? null : ( diff --git a/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts b/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts index d435cb21aa..d21b978a92 100644 --- a/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts +++ b/plugins/cicd-statistics/src/hooks/use-cicd-configuration.ts @@ -18,15 +18,15 @@ import { useState, useEffect } from 'react'; import { useEntity } from '@backstage/plugin-catalog-react'; import { CicdConfiguration, statusTypes } from '../apis'; -import { Progress } from '../components/progress'; +import { ProgressType } from '../components/progress'; import { defaultFormatStageName } from '../utils/stage-names'; import { useCicdStatisticsApi } from './use-cicd-statistics-api'; -export function useCicdConfiguration(): Progress { +export function useCicdConfiguration(): ProgressType { const cicdStatisticsApi = useCicdStatisticsApi(); const { entity } = useEntity(); - const [state, setState] = useState>({ + const [state, setState] = useState>({ loading: true, }); diff --git a/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts b/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts index 5c1fe1bfe2..e52673a576 100644 --- a/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts +++ b/plugins/cicd-statistics/src/hooks/use-cicd-statistics.ts @@ -24,8 +24,9 @@ import { AbortError, FilterStatusType, FilterBranchType, + UpdateProgress, } from '../apis'; -import { Progress } from '../components/progress'; +import { ProgressType } from '../components/progress'; import { useCicdStatisticsApi } from './use-cicd-statistics-api'; export interface UseCicdStatisticsOptions { @@ -39,7 +40,7 @@ export interface UseCicdStatisticsOptions { export function useCicdStatistics( options: UseCicdStatisticsOptions, -): Progress { +): ProgressType { const { entity, abortController, @@ -49,7 +50,9 @@ export function useCicdStatistics( filterType, } = options; - const [state, setState] = useState>({ loading: true }); + const [state, setState] = useState>({ + loading: true, + }); const cicdStatisticsApi = useCicdStatisticsApi(); @@ -62,15 +65,39 @@ export function useCicdStatistics( let mounted = true; let completed = false; // successfully or failed - const updateProgress = throttle((count, total, started = 0) => { - if (mounted && !completed) { + const updateProgressImpl: UpdateProgress = (_count, _total?, _started?) => { + if (!mounted || completed) { + return; + } + + if (Array.isArray(_count)) { + // Multi-progress + setState({ + loading: true, + steps: _count.map(step => ({ + title: step.title, + progress: !step.total ? 0 : step.completed / step.total, + progressBuffer: !step.total ? 0 : (step.started ?? 0) / step.total, + })), + }); + } else { + // Single-progress + const count = _count; + const total = _total as number; + const started = (_started as number) ?? 0; setState({ loading: true, progress: !total ? 0 : count / total, progressBuffer: !total ? 0 : started / total, }); } - }, 200); + }; + + const updateProgress = throttle( + updateProgressImpl, + 200, + // throttle doesn't handle types of multi-signature functions + ) as any as UpdateProgress; const fetchOptions: FetchBuildsOptions = { entity, From 07faca1f278b3eaf424d4b96d6768836d7cd95c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Mon, 7 Feb 2022 17:21:17 +0100 Subject: [PATCH 41/51] fix(cicd-statistics): Fixed test issue after refactoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/src/charts/logic/utils.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/cicd-statistics/src/charts/logic/utils.test.ts b/plugins/cicd-statistics/src/charts/logic/utils.test.ts index 420a6bf90c..72e0a22101 100644 --- a/plugins/cicd-statistics/src/charts/logic/utils.test.ts +++ b/plugins/cicd-statistics/src/charts/logic/utils.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { sortTriggerReasons } from './daily-summary'; +import { sortTriggerReasons } from './utils'; describe('daily-summary', () => { it('sortTriggerReasons', () => { From b947238d1dd0b4fde53e85ad452fb26a2d1e847e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Tue, 8 Feb 2022 11:47:11 +0100 Subject: [PATCH 42/51] fix(yarn.lock): Fixed urls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- yarn.lock | 221 ++---------------------------------------------------- 1 file changed, 8 insertions(+), 213 deletions(-) diff --git a/yarn.lock b/yarn.lock index 2245504748..ffc877abc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1409,7 +1409,7 @@ zen-observable "^0.8.15" zod "^3.11.6" -"@backstage/core-plugin-api@^0.4.0", "@backstage/core-plugin-api@^0.4.1": +"@backstage/core-plugin-api@^0.4.0": version "0.4.1" resolved "https://registry.npmjs.org/@backstage/core-plugin-api/-/core-plugin-api-0.4.1.tgz#c0a13504bdfa61ae3d0db96934cd6c32a7574446" integrity sha512-IIb7XTcquTPaSIlamMKUgeTs5uLqkKN0Nw32QdTZhKgFkFFVzWC0AwN+henkaMNBZFdGb0ttPzrvNXGj5E6dGg== @@ -1440,7 +1440,7 @@ "@material-ui/lab" "4.0.0-alpha.57" react-use "^17.2.4" -"@backstage/plugin-catalog-react@^0.6.13", "@backstage/plugin-catalog-react@^0.6.5", "@backstage/plugin-catalog-react@^0.6.9": +"@backstage/plugin-catalog-react@^0.6.13", "@backstage/plugin-catalog-react@^0.6.5": version "0.6.13" resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.6.13.tgz#b325eae501d3edeb8b7caef5d9615f2e632f5430" integrity sha512-XBwop7PwAZqfongx3KP6jAJar+MEscLSp8nLuHYX5XxA+suQNiBgi96uO3SEQmvtae+hvsRM7c0WHSxbYiXsDA== @@ -1835,7 +1835,7 @@ dependencies: "@date-io/core" "^1.3.13" -"@date-io/luxon@1.x", "@date-io/luxon@^1.3.13": +"@date-io/luxon@1.x": version "1.3.13" resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-1.3.13.tgz#68f0134bb38ef486b2ed6df01981f814c633e28a" integrity sha512-9wUrJCNSMZJeYAiH+dbb45oGpnHeFP7TOH/Lt26If47gjFCkjvyINzWx+K5AGsnlP0Qosxc7hkF1yLi6ecutxw== @@ -3622,7 +3622,7 @@ react-beautiful-dnd "^13.0.0" react-double-scrollbar "0.0.15" -"@material-ui/core@^4.11.0", "@material-ui/core@^4.11.3", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2", "@material-ui/core@^4.9.13": +"@material-ui/core@^4.11.0", "@material-ui/core@^4.11.3", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2": version "4.12.3" resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.12.3.tgz#80d665caf0f1f034e52355c5450c0e38b099d3ca" integrity sha512-sdpgI/PL56QVsEJldwEe4FFaFTLUqN+rd7sSZiRCdx2E/C7z5yK0y/khAWVBH24tXwto7I1hCzNWfJGZIYJKnw== @@ -5309,11 +5309,6 @@ resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.0.2.tgz#53f2d6325f66ee79afd707c05ac849e8ae0edbb0" integrity sha512-WVx6zBiz4sWlboCy7TCgjeyHpNjMsoF36yaagny1uXfbadc9f+5BeBf7U+lRmQqY3EHbGQpP8UdW8AC+cywSwQ== -"@types/d3-color@^2": - version "2.0.3" - resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.3.tgz#8bc4589073c80e33d126345542f588056511fe82" - integrity sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w== - "@types/d3-force@^2.1.1": version "2.1.1" resolved "https://registry.npmjs.org/@types/d3-force/-/d3-force-2.1.1.tgz#a18b6f029d056eb0f8f84a09471e6228e4469b14" @@ -5326,13 +5321,6 @@ dependencies: "@types/d3-color" "*" -"@types/d3-interpolate@^2.0.0": - version "2.0.2" - resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-2.0.2.tgz#78eddf7278b19e48e8652603045528d46897aba0" - integrity sha512-lElyqlUfIPyWG/cD475vl6msPL4aMU7eJvx1//Q177L8mdXoVPFl1djIESF2FKnc0NyaHvQlJpWwKJYwAhUoCw== - dependencies: - "@types/d3-color" "^2" - "@types/d3-path@*": version "3.0.0" resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz#939e3a784ae4f80b1fde8098b91af1776ff1312b" @@ -5343,18 +5331,6 @@ resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c" integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ== -"@types/d3-path@^2": - version "2.0.1" - resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.1.tgz#ca03dfa8b94d8add97ad0cd97e96e2006b4763cb" - integrity sha512-6K8LaFlztlhZO7mwsZg7ClRsdLg3FJRzIIi6SZXDWmmSJc2x8dd2VkESbLXdk3p8cuvz71f36S0y8Zv2AxqvQw== - -"@types/d3-scale@^3.0.0": - version "3.3.2" - resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz#18c94e90f4f1c6b1ee14a70f14bfca2bd1c61d06" - integrity sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ== - dependencies: - "@types/d3-time" "^2" - "@types/d3-selection@*", "@types/d3-selection@^3.0.1": version "3.0.2" resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.2.tgz#23e48a285b24063630bbe312cc0cfe2276de4a59" @@ -5367,13 +5343,6 @@ dependencies: "@types/d3-path" "^1" -"@types/d3-shape@^2.0.0": - version "2.1.3" - resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz#35d397b9e687abaa0de82343b250b9897b8cacf3" - integrity sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ== - dependencies: - "@types/d3-path" "^2" - "@types/d3-shape@^3.0.1": version "3.0.2" resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.0.2.tgz#4b1ca4ddaac294e76b712429726d40365cd1e8ca" @@ -5381,11 +5350,6 @@ dependencies: "@types/d3-path" "*" -"@types/d3-time@^2": - version "2.1.1" - resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz#743fdc821c81f86537cbfece07093ac39b4bc342" - integrity sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg== - "@types/d3-zoom@^3.0.1": version "3.0.1" resolved "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.1.tgz#4bfc7e29625c4f79df38e2c36de52ec3e9faf826" @@ -5792,11 +5756,6 @@ resolved "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.5.tgz#29d3b095d55ee50df8f4cf109b16009334d9828e" integrity sha512-GKrG5v16BOs9XGpouu33hOkAFaiSDi3ZaDXG9F2yAoyzHRBtksZnI60VWY5aM/yAENCccBejrxw8jDY+9OVlxw== -"@types/luxon@^2.0.9": - version "2.0.9" - resolved "https://artifactory.spotify.net/artifactory/api/npm/virtual-npm/@types/luxon/-/luxon-2.0.9.tgz#782a0edfa6d699191292c13168bd496cd66b87c6" - integrity sha1-eCoO36bWmRkSksExaL1JbNZrh8Y= - "@types/mdast@^3.0.0", "@types/mdast@^3.0.3": version "3.0.3" resolved "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb" @@ -6136,11 +6095,6 @@ "@types/tough-cookie" "*" form-data "^2.5.0" -"@types/resize-observer-browser@^0.1.6": - version "0.1.7" - resolved "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz#294aaadf24ac6580b8fbd1fe3ab7b59fe85f9ef3" - integrity sha512-G9eN0Sn0ii9PWQ3Vl72jDPgeJwRWhv2Qk/nQkJuWmRmOB4HX3/BhD5SE1dZs/hzPZL/WKnvF0RHdTSG54QJFyg== - "@types/resolve@1.17.1": version "1.17.1" resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" @@ -6943,11 +6897,6 @@ alphanum-sort@^1.0.2: resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= -already@^3.2.0: - version "3.3.0" - resolved "https://registry.npmjs.org/already/-/already-3.3.0.tgz#a5e5becd167cf537b45f8f1c23d331488ed77003" - integrity sha512-ADGyKddqEp8t/Wu4ITc0y9GGsgZDgyMeMk38AM5qrPK7VEjNAYD87QGTGGgNhSQahmjw76V3mi+3fJRwPJXcTw== - anafanafo@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/anafanafo/-/anafanafo-2.0.0.tgz#43f56274680bc553dd67a9625a920f88d0057b5c" @@ -9686,7 +9635,7 @@ css-tree@^1.1.3: mdn-data "2.0.14" source-map "^0.6.1" -css-unit-converter@^1.1.1, css-unit-converter@^1.1.2: +css-unit-converter@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== @@ -9901,13 +9850,6 @@ cypress@^7.3.0: url "^0.11.0" yauzl "^2.10.0" -d3-array@2, d3-array@^2.3.0: - version "2.12.1" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" - integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== - dependencies: - internmap "^1.0.0" - d3-array@^1.2.0: version "1.2.4" resolved "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" @@ -9923,11 +9865,6 @@ d3-color@1: resolved "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== -"d3-color@1 - 2": - version "2.0.0" - resolved "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" - integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== - "d3-color@1 - 3": version "3.0.1" resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.0.1.tgz#03316e595955d1fcd39d9f3610ad41bb90194d0a" @@ -9970,11 +9907,6 @@ d3-format@1: resolved "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4" integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== -"d3-format@1 - 2": - version "2.0.0" - resolved "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" - integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== - d3-interpolate@1, d3-interpolate@^1.3.0: version "1.4.0" resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" @@ -9989,23 +9921,11 @@ d3-interpolate@1, d3-interpolate@^1.3.0: dependencies: d3-color "1 - 3" -"d3-interpolate@1.2.0 - 2", d3-interpolate@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" - integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== - dependencies: - d3-color "1 - 2" - d3-path@1: version "1.0.9" resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== -"d3-path@1 - 2": - version "2.0.0" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8" - integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA== - "d3-path@1 - 3": version "3.0.1" resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.0.1.tgz#f09dec0aaffd770b7995f1a399152bf93052321e" @@ -10028,17 +9948,6 @@ d3-scale@^2.1.0: d3-time "1" d3-time-format "2" -d3-scale@^3.0.0: - version "3.3.0" - resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" - integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== - dependencies: - d3-array "^2.3.0" - d3-format "1 - 2" - d3-interpolate "1.2.0 - 2" - d3-time "^2.1.1" - d3-time-format "2 - 3" - "d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31" @@ -10051,13 +9960,6 @@ d3-shape@^1.2.0: dependencies: d3-path "1" -d3-shape@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f" - integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA== - dependencies: - d3-path "1 - 2" - d3-shape@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.1.0.tgz#c8a495652d83ea6f524e482fca57aa3f8bc32556" @@ -10072,25 +9974,11 @@ d3-time-format@2: dependencies: d3-time "1" -"d3-time-format@2 - 3": - version "3.0.0" - resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" - integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== - dependencies: - d3-time "1 - 2" - d3-time@1: version "1.1.0" resolved "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== -"d3-time@1 - 2", d3-time@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" - integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== - dependencies: - d3-array "2" - "d3-timer@1 - 2": version "2.0.0" resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz#055edb1d170cfe31ab2da8968deee940b56623e6" @@ -11615,7 +11503,7 @@ eventemitter3@^3.1.0: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== -eventemitter3@^4.0.0, eventemitter3@^4.0.1, eventemitter3@^4.0.4: +eventemitter3@^4.0.0, eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -11997,11 +11885,6 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-equals@^2.0.0: - version "2.0.4" - resolved "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.4.tgz#3add9410585e2d7364c2deeb6a707beadb24b927" - integrity sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w== - fast-glob@^3.1.1: version "3.2.2" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz#ade1a9d91148965d4bf7c51f72e1ca662d32e63d" @@ -13974,11 +13857,6 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -internmap@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" - integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== - interpret@^1.0.0: version "1.4.0" resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" @@ -16568,11 +16446,6 @@ luxon@^1.27.0: resolved "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf" integrity sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ== -luxon@^2.3.0: - version "2.3.0" - resolved "https://artifactory.spotify.net/artifactory/api/npm/virtual-npm/luxon/-/luxon-2.3.0.tgz#bf16a7e642513c2a20a6230a6a41b0ab446d0045" - integrity sha1-vxan5kJRPCogpiMKakGwq0RtAEU= - lz-string@^1.4.4: version "1.4.4" resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" @@ -19696,11 +19569,6 @@ postcss-unique-selectors@^5.0.2: alphanum-sort "^1.0.2" postcss-selector-parser "^6.0.5" -postcss-value-parser@^3.3.0: - version "3.3.1" - resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== - postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" @@ -20392,7 +20260,7 @@ react-inspector@^5.1.1: is-dom "^1.0.0" prop-types "^15.0.0" -react-is@^16.10.2, react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.6, react-is@^16.9.0: +react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.6, react-is@^16.9.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -20449,15 +20317,6 @@ react-resize-detector@^2.3.0: prop-types "^15.6.0" resize-observer-polyfill "^1.5.0" -react-resize-detector@^6.6.3: - version "6.7.8" - resolved "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.8.tgz#318c85d1335e50f99d4fb8eb9ec34e066db597d0" - integrity sha512-0FaEcUBAbn+pq3PT5a9hHRebUfuS1SRLGLpIw8LydU7zX429I6XJgKerKAMPsJH0qWAl6o5bVKNqFJqr6tGPYw== - dependencies: - "@types/resize-observer-browser" "^0.1.6" - lodash "^4.17.21" - resize-observer-polyfill "^1.5.1" - react-router-dom@6.0.0-beta.0: version "6.0.0-beta.0" resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.0.0-beta.0.tgz#9dcc8555365f22f7fbd09f26b6b82543f3eb97d6" @@ -20495,15 +20354,6 @@ react-smooth@^1.0.5: raf "^3.4.0" react-transition-group "^2.5.0" -react-smooth@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz#561647b33e498b2e25f449b3c6689b2e9111bf91" - integrity sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw== - dependencies: - fast-equals "^2.0.0" - raf "^3.4.0" - react-transition-group "2.9.0" - react-sparklines@^1.7.0: version "1.7.0" resolved "https://registry.npmjs.org/react-sparklines/-/react-sparklines-1.7.0.tgz#9b1d97e8c8610095eeb2ad658d2e1fcf91f91a60" @@ -20539,7 +20389,7 @@ react-text-truncate@^0.17.0: dependencies: prop-types "^15.5.7" -react-transition-group@2.9.0, react-transition-group@^2.5.0: +react-transition-group@^2.5.0: version "2.9.0" resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== @@ -20584,26 +20434,6 @@ react-use@^17.2.4: ts-easing "^0.2.0" tslib "^2.1.0" -react-use@^17.3.1: - version "17.3.2" - resolved "https://registry.npmjs.org/react-use/-/react-use-17.3.2.tgz#448abf515f47c41c32455024db28167cb6e53be8" - integrity sha512-bj7OD0/1wL03KyWmzFXAFe425zziuTf7q8olwCYBfOeFHY1qfO1FAMjROQLsLZYwG4Rx63xAfb7XAbBrJsZmEw== - dependencies: - "@types/js-cookie" "^2.2.6" - "@xobotyi/scrollbar-width" "^1.9.5" - copy-to-clipboard "^3.3.1" - fast-deep-equal "^3.1.3" - fast-shallow-equal "^1.0.0" - js-cookie "^2.2.1" - nano-css "^5.3.1" - react-universal-interface "^0.6.2" - resize-observer-polyfill "^1.5.1" - screenfull "^5.1.0" - set-harmonic-interval "^1.0.1" - throttle-debounce "^3.0.1" - ts-easing "^0.2.0" - tslib "^2.1.0" - react-virtualized-auto-sizer@^1.0.6: version "1.0.6" resolved "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.6.tgz#66c5b1c9278064c5ef1699ed40a29c11518f97ca" @@ -20817,13 +20647,6 @@ recharts-scale@^0.4.2: dependencies: decimal.js-light "^2.4.1" -recharts-scale@^0.4.4: - version "0.4.5" - resolved "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" - integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== - dependencies: - decimal.js-light "^2.4.1" - recharts@^1.8.5: version "1.8.5" resolved "https://registry.npmjs.org/recharts/-/recharts-1.8.5.tgz#ca94a3395550946334a802e35004ceb2583fdb12" @@ -20841,26 +20664,6 @@ recharts@^1.8.5: recharts-scale "^0.4.2" reduce-css-calc "^1.3.0" -recharts@^2.1.5: - version "2.1.8" - resolved "https://registry.npmjs.org/recharts/-/recharts-2.1.8.tgz#ca8774fcec5f5d7ec15dedd638db9ee12faf1c09" - integrity sha512-Wi7ufdDGyvy/BPf1za1Ok7VeWB2KtEejaewO9ulmlUhvn5l5RPS4AOkrUfhtMRTTjgJ4K6AbWMDpwtDjczUHJA== - dependencies: - "@types/d3-interpolate" "^2.0.0" - "@types/d3-scale" "^3.0.0" - "@types/d3-shape" "^2.0.0" - classnames "^2.2.5" - d3-interpolate "^2.0.0" - d3-scale "^3.0.0" - d3-shape "^2.0.0" - eventemitter3 "^4.0.1" - lodash "^4.17.19" - react-is "^16.10.2" - react-resize-detector "^6.6.3" - react-smooth "^2.0.0" - recharts-scale "^0.4.4" - reduce-css-calc "^2.1.8" - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -20907,14 +20710,6 @@ reduce-css-calc@^1.3.0: math-expression-evaluator "^1.2.14" reduce-function-call "^1.0.1" -reduce-css-calc@^2.1.8: - version "2.1.8" - resolved "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" - integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== - dependencies: - css-unit-converter "^1.1.1" - postcss-value-parser "^3.3.0" - reduce-function-call@^1.0.1: version "1.0.3" resolved "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f" From c2cbcaf234566c33ad440b784589c89cf4922630 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 9 Feb 2022 11:50:56 +0100 Subject: [PATCH 43/51] =?UTF-8?q?chore:=20de-dedupe=20dependencies=20and?= =?UTF-8?q?=20make=20the=20build=20green=20=F0=9F=A4=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: blam --- plugins/cicd-statistics/package.json | 7 +- .../src/components/progress.tsx | 2 +- .../cicd-statistics/src/components/utils.tsx | 3 +- yarn.lock | 209 +++++++++++++++++- 4 files changed, 209 insertions(+), 12 deletions(-) diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 3e93d2adf6..c7c3900c22 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -29,20 +29,21 @@ "clean": "backstage-cli clean" }, "devDependencies": { - "@types/luxon": "^2.0.9" + "@types/luxon": "^2.0.5" }, "dependencies": { "@backstage/catalog-model": "^0.9.8", "@backstage/core-plugin-api": "^0.4.1", "@backstage/plugin-catalog-react": "^0.6.9", - "@date-io/luxon": "^1.3.13", + "@date-io/luxon": "2.x", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "4.0.0-alpha.57", "@material-ui/pickers": "^3.3.10", + "humanize-duration": "^3.27.0", "already": "^3.2.0", "lodash": "^4.17.21", - "luxon": "^2.3.0", + "luxon": "^2.0.2", "react-use": "^17.3.1", "recharts": "^2.1.5" }, diff --git a/plugins/cicd-statistics/src/components/progress.tsx b/plugins/cicd-statistics/src/components/progress.tsx index 9973ba170d..6ea8e6497d 100644 --- a/plugins/cicd-statistics/src/components/progress.tsx +++ b/plugins/cicd-statistics/src/components/progress.tsx @@ -15,7 +15,7 @@ */ import React, { CSSProperties, DependencyList } from 'react'; -import { useAsync } from 'react-use'; +import useAsync from 'react-use/lib/useAsync'; import { Box, LinearProgress } from '@material-ui/core'; import Timeline from '@material-ui/lab/Timeline'; import TimelineItem from '@material-ui/lab/TimelineItem'; diff --git a/plugins/cicd-statistics/src/components/utils.tsx b/plugins/cicd-statistics/src/components/utils.tsx index e4663c8cde..0133cf7ba8 100644 --- a/plugins/cicd-statistics/src/components/utils.tsx +++ b/plugins/cicd-statistics/src/components/utils.tsx @@ -16,6 +16,7 @@ import React, { CSSProperties } from 'react'; import { DateTime, Duration } from 'luxon'; +import humanizeDuration from 'humanize-duration'; import { capitalize } from 'lodash'; const infoText: CSSProperties = { color: 'InfoText' }; @@ -124,7 +125,7 @@ export function formatDuration(millis: number) { ...(seconds && !days && !hours && { seconds }), }); - return dur.toHuman({ unitDisplay: 'narrow' }).replace(/, /g, ''); + return humanizeDuration(dur.toMillis(), { round: true }); } export function formatDurationFromSeconds(seconds: number) { diff --git a/yarn.lock b/yarn.lock index ffc877abc6..a0ba55df6d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1409,7 +1409,7 @@ zen-observable "^0.8.15" zod "^3.11.6" -"@backstage/core-plugin-api@^0.4.0": +"@backstage/core-plugin-api@^0.4.0", "@backstage/core-plugin-api@^0.4.1": version "0.4.1" resolved "https://registry.npmjs.org/@backstage/core-plugin-api/-/core-plugin-api-0.4.1.tgz#c0a13504bdfa61ae3d0db96934cd6c32a7574446" integrity sha512-IIb7XTcquTPaSIlamMKUgeTs5uLqkKN0Nw32QdTZhKgFkFFVzWC0AwN+henkaMNBZFdGb0ttPzrvNXGj5E6dGg== @@ -1440,7 +1440,7 @@ "@material-ui/lab" "4.0.0-alpha.57" react-use "^17.2.4" -"@backstage/plugin-catalog-react@^0.6.13", "@backstage/plugin-catalog-react@^0.6.5": +"@backstage/plugin-catalog-react@^0.6.13", "@backstage/plugin-catalog-react@^0.6.5", "@backstage/plugin-catalog-react@^0.6.9": version "0.6.13" resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.6.13.tgz#b325eae501d3edeb8b7caef5d9615f2e632f5430" integrity sha512-XBwop7PwAZqfongx3KP6jAJar+MEscLSp8nLuHYX5XxA+suQNiBgi96uO3SEQmvtae+hvsRM7c0WHSxbYiXsDA== @@ -3622,7 +3622,7 @@ react-beautiful-dnd "^13.0.0" react-double-scrollbar "0.0.15" -"@material-ui/core@^4.11.0", "@material-ui/core@^4.11.3", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2": +"@material-ui/core@^4.11.0", "@material-ui/core@^4.11.3", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2", "@material-ui/core@^4.9.13": version "4.12.3" resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.12.3.tgz#80d665caf0f1f034e52355c5450c0e38b099d3ca" integrity sha512-sdpgI/PL56QVsEJldwEe4FFaFTLUqN+rd7sSZiRCdx2E/C7z5yK0y/khAWVBH24tXwto7I1hCzNWfJGZIYJKnw== @@ -5309,6 +5309,11 @@ resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.0.2.tgz#53f2d6325f66ee79afd707c05ac849e8ae0edbb0" integrity sha512-WVx6zBiz4sWlboCy7TCgjeyHpNjMsoF36yaagny1uXfbadc9f+5BeBf7U+lRmQqY3EHbGQpP8UdW8AC+cywSwQ== +"@types/d3-color@^2": + version "2.0.3" + resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.3.tgz#8bc4589073c80e33d126345542f588056511fe82" + integrity sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w== + "@types/d3-force@^2.1.1": version "2.1.1" resolved "https://registry.npmjs.org/@types/d3-force/-/d3-force-2.1.1.tgz#a18b6f029d056eb0f8f84a09471e6228e4469b14" @@ -5321,6 +5326,13 @@ dependencies: "@types/d3-color" "*" +"@types/d3-interpolate@^2.0.0": + version "2.0.2" + resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-2.0.2.tgz#78eddf7278b19e48e8652603045528d46897aba0" + integrity sha512-lElyqlUfIPyWG/cD475vl6msPL4aMU7eJvx1//Q177L8mdXoVPFl1djIESF2FKnc0NyaHvQlJpWwKJYwAhUoCw== + dependencies: + "@types/d3-color" "^2" + "@types/d3-path@*": version "3.0.0" resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz#939e3a784ae4f80b1fde8098b91af1776ff1312b" @@ -5331,6 +5343,18 @@ resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c" integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ== +"@types/d3-path@^2": + version "2.0.1" + resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.1.tgz#ca03dfa8b94d8add97ad0cd97e96e2006b4763cb" + integrity sha512-6K8LaFlztlhZO7mwsZg7ClRsdLg3FJRzIIi6SZXDWmmSJc2x8dd2VkESbLXdk3p8cuvz71f36S0y8Zv2AxqvQw== + +"@types/d3-scale@^3.0.0": + version "3.3.2" + resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz#18c94e90f4f1c6b1ee14a70f14bfca2bd1c61d06" + integrity sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ== + dependencies: + "@types/d3-time" "^2" + "@types/d3-selection@*", "@types/d3-selection@^3.0.1": version "3.0.2" resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.2.tgz#23e48a285b24063630bbe312cc0cfe2276de4a59" @@ -5343,6 +5367,13 @@ dependencies: "@types/d3-path" "^1" +"@types/d3-shape@^2.0.0": + version "2.1.3" + resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz#35d397b9e687abaa0de82343b250b9897b8cacf3" + integrity sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ== + dependencies: + "@types/d3-path" "^2" + "@types/d3-shape@^3.0.1": version "3.0.2" resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.0.2.tgz#4b1ca4ddaac294e76b712429726d40365cd1e8ca" @@ -5350,6 +5381,11 @@ dependencies: "@types/d3-path" "*" +"@types/d3-time@^2": + version "2.1.1" + resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz#743fdc821c81f86537cbfece07093ac39b4bc342" + integrity sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg== + "@types/d3-zoom@^3.0.1": version "3.0.1" resolved "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.1.tgz#4bfc7e29625c4f79df38e2c36de52ec3e9faf826" @@ -6095,6 +6131,11 @@ "@types/tough-cookie" "*" form-data "^2.5.0" +"@types/resize-observer-browser@^0.1.6": + version "0.1.7" + resolved "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz#294aaadf24ac6580b8fbd1fe3ab7b59fe85f9ef3" + integrity sha512-G9eN0Sn0ii9PWQ3Vl72jDPgeJwRWhv2Qk/nQkJuWmRmOB4HX3/BhD5SE1dZs/hzPZL/WKnvF0RHdTSG54QJFyg== + "@types/resolve@1.17.1": version "1.17.1" resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" @@ -6897,6 +6938,11 @@ alphanum-sort@^1.0.2: resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= +already@^3.2.0: + version "3.3.0" + resolved "https://registry.npmjs.org/already/-/already-3.3.0.tgz#a5e5becd167cf537b45f8f1c23d331488ed77003" + integrity sha512-ADGyKddqEp8t/Wu4ITc0y9GGsgZDgyMeMk38AM5qrPK7VEjNAYD87QGTGGgNhSQahmjw76V3mi+3fJRwPJXcTw== + anafanafo@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/anafanafo/-/anafanafo-2.0.0.tgz#43f56274680bc553dd67a9625a920f88d0057b5c" @@ -9635,7 +9681,7 @@ css-tree@^1.1.3: mdn-data "2.0.14" source-map "^0.6.1" -css-unit-converter@^1.1.2: +css-unit-converter@^1.1.1, css-unit-converter@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== @@ -9850,6 +9896,13 @@ cypress@^7.3.0: url "^0.11.0" yauzl "^2.10.0" +d3-array@2, d3-array@^2.3.0: + version "2.12.1" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" + d3-array@^1.2.0: version "1.2.4" resolved "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" @@ -9865,6 +9918,11 @@ d3-color@1: resolved "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== +"d3-color@1 - 2": + version "2.0.0" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" + integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== + "d3-color@1 - 3": version "3.0.1" resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.0.1.tgz#03316e595955d1fcd39d9f3610ad41bb90194d0a" @@ -9907,6 +9965,11 @@ d3-format@1: resolved "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4" integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== +"d3-format@1 - 2": + version "2.0.0" + resolved "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" + integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== + d3-interpolate@1, d3-interpolate@^1.3.0: version "1.4.0" resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" @@ -9921,11 +9984,23 @@ d3-interpolate@1, d3-interpolate@^1.3.0: dependencies: d3-color "1 - 3" +"d3-interpolate@1.2.0 - 2", d3-interpolate@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" + integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== + dependencies: + d3-color "1 - 2" + d3-path@1: version "1.0.9" resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== +"d3-path@1 - 2": + version "2.0.0" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8" + integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA== + "d3-path@1 - 3": version "3.0.1" resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.0.1.tgz#f09dec0aaffd770b7995f1a399152bf93052321e" @@ -9948,6 +10023,17 @@ d3-scale@^2.1.0: d3-time "1" d3-time-format "2" +d3-scale@^3.0.0: + version "3.3.0" + resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" + integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== + dependencies: + d3-array "^2.3.0" + d3-format "1 - 2" + d3-interpolate "1.2.0 - 2" + d3-time "^2.1.1" + d3-time-format "2 - 3" + "d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31" @@ -9960,6 +10046,13 @@ d3-shape@^1.2.0: dependencies: d3-path "1" +d3-shape@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f" + integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA== + dependencies: + d3-path "1 - 2" + d3-shape@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.1.0.tgz#c8a495652d83ea6f524e482fca57aa3f8bc32556" @@ -9974,11 +10067,25 @@ d3-time-format@2: dependencies: d3-time "1" +"d3-time-format@2 - 3": + version "3.0.0" + resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" + integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== + dependencies: + d3-time "1 - 2" + d3-time@1: version "1.1.0" resolved "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== +"d3-time@1 - 2", d3-time@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" + integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== + dependencies: + d3-array "2" + "d3-timer@1 - 2": version "2.0.0" resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz#055edb1d170cfe31ab2da8968deee940b56623e6" @@ -11503,7 +11610,7 @@ eventemitter3@^3.1.0: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== -eventemitter3@^4.0.0, eventemitter3@^4.0.4: +eventemitter3@^4.0.0, eventemitter3@^4.0.1, eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -11885,6 +11992,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-equals@^2.0.0: + version "2.0.4" + resolved "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.4.tgz#3add9410585e2d7364c2deeb6a707beadb24b927" + integrity sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w== + fast-glob@^3.1.1: version "3.2.2" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz#ade1a9d91148965d4bf7c51f72e1ca662d32e63d" @@ -13857,6 +13969,11 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + interpret@^1.0.0: version "1.4.0" resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" @@ -19569,6 +19686,11 @@ postcss-unique-selectors@^5.0.2: alphanum-sort "^1.0.2" postcss-selector-parser "^6.0.5" +postcss-value-parser@^3.3.0: + version "3.3.1" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" @@ -20260,7 +20382,7 @@ react-inspector@^5.1.1: is-dom "^1.0.0" prop-types "^15.0.0" -react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.6, react-is@^16.9.0: +react-is@^16.10.2, react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.6, react-is@^16.9.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -20317,6 +20439,15 @@ react-resize-detector@^2.3.0: prop-types "^15.6.0" resize-observer-polyfill "^1.5.0" +react-resize-detector@^6.6.3: + version "6.7.8" + resolved "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-6.7.8.tgz#318c85d1335e50f99d4fb8eb9ec34e066db597d0" + integrity sha512-0FaEcUBAbn+pq3PT5a9hHRebUfuS1SRLGLpIw8LydU7zX429I6XJgKerKAMPsJH0qWAl6o5bVKNqFJqr6tGPYw== + dependencies: + "@types/resize-observer-browser" "^0.1.6" + lodash "^4.17.21" + resize-observer-polyfill "^1.5.1" + react-router-dom@6.0.0-beta.0: version "6.0.0-beta.0" resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.0.0-beta.0.tgz#9dcc8555365f22f7fbd09f26b6b82543f3eb97d6" @@ -20354,6 +20485,15 @@ react-smooth@^1.0.5: raf "^3.4.0" react-transition-group "^2.5.0" +react-smooth@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz#561647b33e498b2e25f449b3c6689b2e9111bf91" + integrity sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw== + dependencies: + fast-equals "^2.0.0" + raf "^3.4.0" + react-transition-group "2.9.0" + react-sparklines@^1.7.0: version "1.7.0" resolved "https://registry.npmjs.org/react-sparklines/-/react-sparklines-1.7.0.tgz#9b1d97e8c8610095eeb2ad658d2e1fcf91f91a60" @@ -20389,7 +20529,7 @@ react-text-truncate@^0.17.0: dependencies: prop-types "^15.5.7" -react-transition-group@^2.5.0: +react-transition-group@2.9.0, react-transition-group@^2.5.0: version "2.9.0" resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== @@ -20434,6 +20574,26 @@ react-use@^17.2.4: ts-easing "^0.2.0" tslib "^2.1.0" +react-use@^17.3.1: + version "17.3.2" + resolved "https://registry.npmjs.org/react-use/-/react-use-17.3.2.tgz#448abf515f47c41c32455024db28167cb6e53be8" + integrity sha512-bj7OD0/1wL03KyWmzFXAFe425zziuTf7q8olwCYBfOeFHY1qfO1FAMjROQLsLZYwG4Rx63xAfb7XAbBrJsZmEw== + dependencies: + "@types/js-cookie" "^2.2.6" + "@xobotyi/scrollbar-width" "^1.9.5" + copy-to-clipboard "^3.3.1" + fast-deep-equal "^3.1.3" + fast-shallow-equal "^1.0.0" + js-cookie "^2.2.1" + nano-css "^5.3.1" + react-universal-interface "^0.6.2" + resize-observer-polyfill "^1.5.1" + screenfull "^5.1.0" + set-harmonic-interval "^1.0.1" + throttle-debounce "^3.0.1" + ts-easing "^0.2.0" + tslib "^2.1.0" + react-virtualized-auto-sizer@^1.0.6: version "1.0.6" resolved "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.6.tgz#66c5b1c9278064c5ef1699ed40a29c11518f97ca" @@ -20647,6 +20807,13 @@ recharts-scale@^0.4.2: dependencies: decimal.js-light "^2.4.1" +recharts-scale@^0.4.4: + version "0.4.5" + resolved "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" + integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== + dependencies: + decimal.js-light "^2.4.1" + recharts@^1.8.5: version "1.8.5" resolved "https://registry.npmjs.org/recharts/-/recharts-1.8.5.tgz#ca94a3395550946334a802e35004ceb2583fdb12" @@ -20664,6 +20831,26 @@ recharts@^1.8.5: recharts-scale "^0.4.2" reduce-css-calc "^1.3.0" +recharts@^2.1.5: + version "2.1.8" + resolved "https://registry.npmjs.org/recharts/-/recharts-2.1.8.tgz#ca8774fcec5f5d7ec15dedd638db9ee12faf1c09" + integrity sha512-Wi7ufdDGyvy/BPf1za1Ok7VeWB2KtEejaewO9ulmlUhvn5l5RPS4AOkrUfhtMRTTjgJ4K6AbWMDpwtDjczUHJA== + dependencies: + "@types/d3-interpolate" "^2.0.0" + "@types/d3-scale" "^3.0.0" + "@types/d3-shape" "^2.0.0" + classnames "^2.2.5" + d3-interpolate "^2.0.0" + d3-scale "^3.0.0" + d3-shape "^2.0.0" + eventemitter3 "^4.0.1" + lodash "^4.17.19" + react-is "^16.10.2" + react-resize-detector "^6.6.3" + react-smooth "^2.0.0" + recharts-scale "^0.4.4" + reduce-css-calc "^2.1.8" + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -20710,6 +20897,14 @@ reduce-css-calc@^1.3.0: math-expression-evaluator "^1.2.14" reduce-function-call "^1.0.1" +reduce-css-calc@^2.1.8: + version "2.1.8" + resolved "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" + integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== + dependencies: + css-unit-converter "^1.1.1" + postcss-value-parser "^3.3.0" + reduce-function-call@^1.0.1: version "1.0.3" resolved "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f" From 476c4c52fc9a3d9f71f3e747f496ffed70368f63 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 9 Feb 2022 13:50:20 +0100 Subject: [PATCH 44/51] =?UTF-8?q?chore:=20api-reports=20=F0=9F=98=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: blam --- plugins/cicd-statistics/api-report.md | 50 ++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/plugins/cicd-statistics/api-report.md b/plugins/cicd-statistics/api-report.md index c2e7e0934d..3c7a52cdad 100644 --- a/plugins/cicd-statistics/api-report.md +++ b/plugins/cicd-statistics/api-report.md @@ -27,6 +27,7 @@ export interface Build { requestedAt: Date; stages: Array; status: FilterStatusType; + triggeredBy?: TriggerReason; } // Warning: (ae-missing-release-tag) "BuildWithRaw" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -36,6 +37,16 @@ export type BuildWithRaw = Build & { raw: T; }; +// Warning: (ae-missing-release-tag) "ChartType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ChartType = 'duration' | 'count'; + +// Warning: (ae-missing-release-tag) "ChartTypes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ChartTypes = Array; + // Warning: (ae-missing-release-tag) "CicdConfiguration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @@ -49,11 +60,13 @@ export interface CicdConfiguration { // // @public export interface CicdDefaults { + chartTypes: Record; collapsedLimit: number; // (undocumented) filterStatus: Array; // (undocumented) filterType: FilterBranchType | 'all'; + hideLimit: number; lowercaseNames: boolean; normalizeTimeRange: boolean; // (undocumented) @@ -162,6 +175,7 @@ export interface Stage { // (undocumented) name: string; stages?: Array; + status: FilterStatusType; } // Warning: (ae-missing-release-tag) "statusTypes" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -169,14 +183,40 @@ export interface Stage { // @public (undocumented) export const statusTypes: Array; +// Warning: (ae-missing-release-tag) "TriggerReason" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type TriggerReason = + /** Triggered by source code management, e.g. a Github hook */ + | 'scm' + /** Triggered manually */ + | 'manual' + /** Triggered internally (non-scm, or perhaps after being delayed/enqueued) */ + | 'internal' + /** Triggered for some other reason */ + | 'other'; + +// Warning: (ae-missing-release-tag) "triggerReasons" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const triggerReasons: Array; + // Warning: (ae-missing-release-tag) "UpdateProgress" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export type UpdateProgress = ( - completed: number, - total: number, - started?: number, -) => void; +export interface UpdateProgress { + // (undocumented) + (completed: number, total: number, started?: number): void; + // (undocumented) + ( + steps: Array<{ + title: string; + completed: number; + total: number; + started?: number; + }>, + ): void; +} // (No @packageDocumentation comment for this package) ``` From 29302d39db8d1a27e8df1970a1976e95e22b76ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Wed, 9 Feb 2022 16:54:32 +0100 Subject: [PATCH 45/51] fix(cicd-statistics): @types/react -> devDependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index c7c3900c22..696231c529 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -29,6 +29,7 @@ "clean": "backstage-cli clean" }, "devDependencies": { + "@types/react": "^16.13.1 || ^17.0.0", "@types/luxon": "^2.0.5" }, "dependencies": { @@ -48,7 +49,6 @@ "recharts": "^2.1.5" }, "peerDependencies": { - "@types/react": "^16.13.1 || ^17.0.0", "react": "^16.13.1 || ^17.0.0" }, "files": [ From ad136d1c8732afbada469a134b17b0c0b77cd261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20R=C3=A4ntil=C3=A4?= Date: Wed, 9 Feb 2022 17:48:43 +0100 Subject: [PATCH 46/51] chore: go back to @date-io/luxon 1 for mui pickers... MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Gustaf Räntilä --- plugins/cicd-statistics/package.json | 2 +- yarn.lock | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 696231c529..1c4d8a455e 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -36,7 +36,7 @@ "@backstage/catalog-model": "^0.9.8", "@backstage/core-plugin-api": "^0.4.1", "@backstage/plugin-catalog-react": "^0.6.9", - "@date-io/luxon": "2.x", + "@date-io/luxon": "^1.3.13", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "4.0.0-alpha.57", diff --git a/yarn.lock b/yarn.lock index a0ba55df6d..6988edda3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1842,6 +1842,13 @@ dependencies: "@date-io/core" "^1.3.13" +"@date-io/luxon@^1.3.13": + version "1.3.13" + resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-1.3.13.tgz#68f0134bb38ef486b2ed6df01981f814c633e28a" + integrity sha512-9wUrJCNSMZJeYAiH+dbb45oGpnHeFP7TOH/Lt26If47gjFCkjvyINzWx+K5AGsnlP0Qosxc7hkF1yLi6ecutxw== + dependencies: + "@date-io/core" "^1.3.13" + "@elastic/elasticsearch-mock@^0.3.0": version "0.3.0" resolved "https://registry.npmjs.org/@elastic/elasticsearch-mock/-/elasticsearch-mock-0.3.0.tgz#6b1d8448aad3ca20f760fa01c0206b733c9c1e54" From 3c9aed1b16c5e89a05087999625eb4d9ccee0136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 10 Feb 2022 10:36:45 +0100 Subject: [PATCH 47/51] review comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/giant-nails-grow.md | 47 ++++++++++++++++--- .../tutorials/authenticate-api-requests.md | 11 +++-- packages/backend/src/plugins/permission.ts | 2 +- plugins/auth-backend/api-report.md | 3 -- plugins/auth-backend/src/providers/index.ts | 2 +- plugins/auth-backend/src/providers/types.ts | 8 ---- plugins/auth-node/api-report.md | 5 +- plugins/auth-node/src/IdentityClient.test.ts | 2 +- plugins/auth-node/src/IdentityClient.ts | 15 +++++- 9 files changed, 69 insertions(+), 26 deletions(-) diff --git a/.changeset/giant-nails-grow.md b/.changeset/giant-nails-grow.md index f96efce2ba..7ea36968b9 100644 --- a/.changeset/giant-nails-grow.md +++ b/.changeset/giant-nails-grow.md @@ -2,15 +2,50 @@ '@backstage/plugin-auth-backend': minor --- -- Moved `IdentityClient`, `BackstageSignInResult`, `BackstageIdentityResponse`, - and `BackstageUserIdentity` to `@backstage/plugin-auth-node`. +The following breaking changes were made, which may imply specifically needing +to make small adjustments in your custom auth providers. + +- **BREAKING**: Moved `IdentityClient`, `BackstageSignInResult`, + `BackstageIdentityResponse`, and `BackstageUserIdentity` to + `@backstage/plugin-auth-node`. +- **BREAKING**: Removed deprecated type `BackstageIdentity`, please use + `BackstageSignInResult` from `@backstage/plugin-auth-node` instead. While moving over, `IdentityClient` was also changed in the following ways: -- Made `IdentityClient.listPublicKeys` private. It was only used in tests, and - should not be part of the API surface of that class. -- Removed the static `IdentityClient.getBearerToken`. It is now replaced by - `getBearerTokenFromAuthorizationHeader` from `@backstage/plugin-auth-node`. +- **BREAKING**: Made `IdentityClient.listPublicKeys` private. It was only used + in tests, and should not be part of the API surface of that class. +- **BREAKING**: Removed the static `IdentityClient.getBearerToken`. It is now + replaced by `getBearerTokenFromAuthorizationHeader` from + `@backstage/plugin-auth-node`. +- **BREAKING**: Removed the constructor. Please use the `IdentityClient.create` + static method instead. Since the `IdentityClient` interface is marked as experimental, this is a breaking change without a deprecation period. + +In your auth providers, you may need to update your imports and usages as +follows (example code; yours may be slightly different): + +````diff +-import { IdentityClient } from '@backstage/plugin-auth-backend'; ++import { ++ IdentityClient, ++ getBearerTokenFromAuthorizationHeader ++} from '@backstage/plugin-auth-node'; + + // ... + +- const identity = new IdentityClient({ ++ const identity = IdentityClient.create({ + discovery, + issuer: await discovery.getExternalBaseUrl('auth'), + });``` + + // ... + + const token = +- IdentityClient.getBearerToken(req.headers.authorization) || ++ getBearerTokenFromAuthorizationHeader(req.headers.authorization) || + req.cookies['token']; +```` diff --git a/contrib/docs/tutorials/authenticate-api-requests.md b/contrib/docs/tutorials/authenticate-api-requests.md index 25dd08e054..45ae38b8b7 100644 --- a/contrib/docs/tutorials/authenticate-api-requests.md +++ b/contrib/docs/tutorials/authenticate-api-requests.md @@ -15,7 +15,10 @@ import cookieParser from 'cookie-parser'; import { Request, Response, NextFunction } from 'express'; import { JWT } from 'jose'; import { URL } from 'url'; -import { IdentityClient } from '@backstage/plugin-auth-backend'; +import { + IdentityClient, + getBearerTokenFromAuthorizationHeader, +} from '@backstage/plugin-auth-node'; // ... @@ -44,7 +47,7 @@ async function main() { // ... const discovery = SingleHostDiscovery.fromConfig(config); - const identity = new IdentityClient({ + const identity = IdentityClient.create({ discovery, issuer: await discovery.getExternalBaseUrl('auth'), }); @@ -58,7 +61,7 @@ async function main() { ) => { try { const token = - IdentityClient.getBearerToken(req.headers.authorization) || + getBearerTokenFromAuthorizationHeader(req.headers.authorization) || req.cookies['token']; req.user = await identity.authenticate(token); if (!req.headers.authorization) { @@ -80,7 +83,7 @@ async function main() { const apiRouter = Router(); apiRouter.use(cookieParser()); - // The auth route must be publically available as it is used during login + // The auth route must be publicly available as it is used during login apiRouter.use('/auth', await auth(authEnv)); // Add a simple endpoint to be used when setting a token cookie apiRouter.use('/cookie', authMiddleware, (_req, res) => { diff --git a/packages/backend/src/plugins/permission.ts b/packages/backend/src/plugins/permission.ts index 6ba24ba1f7..276d16ff97 100644 --- a/packages/backend/src/plugins/permission.ts +++ b/packages/backend/src/plugins/permission.ts @@ -40,7 +40,7 @@ export default async function createPlugin( logger, discovery, policy: new AllowAllPermissionPolicy(), - identity: new IdentityClient({ + identity: IdentityClient.create({ discovery, issuer: await discovery.getExternalBaseUrl('auth'), }), diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index 66153fd0af..416da59b46 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -128,9 +128,6 @@ export type AwsAlbProviderOptions = { }; }; -// @public @deprecated -export type BackstageIdentity = BackstageSignInResult; - // Warning: (ae-missing-release-tag) "BitbucketOAuthResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) diff --git a/plugins/auth-backend/src/providers/index.ts b/plugins/auth-backend/src/providers/index.ts index 37ce09978c..78814ae7e6 100644 --- a/plugins/auth-backend/src/providers/index.ts +++ b/plugins/auth-backend/src/providers/index.ts @@ -48,6 +48,6 @@ export type { // These types are needed for a postMessage from the login pop-up // to the frontend -export type { AuthResponse, BackstageIdentity, ProfileInfo } from './types'; +export type { AuthResponse, ProfileInfo } from './types'; export { prepareBackstageIdentityResponse } from './prepareBackstageIdentityResponse'; diff --git a/plugins/auth-backend/src/providers/types.ts b/plugins/auth-backend/src/providers/types.ts index 6bef80fd4c..5bd52f0c94 100644 --- a/plugins/auth-backend/src/providers/types.ts +++ b/plugins/auth-backend/src/providers/types.ts @@ -164,14 +164,6 @@ export type AuthResponse = { backstageIdentity?: BackstageIdentityResponse; }; -/** - * The old exported symbol for {@link @backstage/plugin-auth-node#BackstageSignInResult}. - * - * @public - * @deprecated Use the {@link @backstage/plugin-auth-node#BackstageSignInResult} instead. - */ -export type BackstageIdentity = BackstageSignInResult; - /** * Used to display login information to user, i.e. sidebar popup. * diff --git a/plugins/auth-node/api-report.md b/plugins/auth-node/api-report.md index 7a04ba8181..7840fc7d74 100644 --- a/plugins/auth-node/api-report.md +++ b/plugins/auth-node/api-report.md @@ -34,7 +34,10 @@ export function getBearerTokenFromAuthorizationHeader( // @public export class IdentityClient { - constructor(options: { discovery: PluginEndpointDiscovery; issuer: string }); authenticate(token: string | undefined): Promise; + static create(options: { + discovery: PluginEndpointDiscovery; + issuer: string; + }): IdentityClient; } ``` diff --git a/plugins/auth-node/src/IdentityClient.test.ts b/plugins/auth-node/src/IdentityClient.test.ts index cddc5f33a2..72ef7f2a57 100644 --- a/plugins/auth-node/src/IdentityClient.test.ts +++ b/plugins/auth-node/src/IdentityClient.test.ts @@ -98,7 +98,7 @@ describe('IdentityClient', () => { afterEach(() => server.resetHandlers()); beforeEach(() => { - client = new IdentityClient({ discovery, issuer: mockBaseUrl }); + client = IdentityClient.create({ discovery, issuer: mockBaseUrl }); factory = new FakeTokenFactory({ issuer: mockBaseUrl, keyDurationSeconds, diff --git a/plugins/auth-node/src/IdentityClient.ts b/plugins/auth-node/src/IdentityClient.ts index ddbccff027..d8e841bf75 100644 --- a/plugins/auth-node/src/IdentityClient.ts +++ b/plugins/auth-node/src/IdentityClient.ts @@ -35,7 +35,20 @@ export class IdentityClient { private keyStore: JWKS.KeyStore; private keyStoreUpdated: number; - constructor(options: { discovery: PluginEndpointDiscovery; issuer: string }) { + /** + * Create a new {@link IdentityClient} instance. + */ + static create(options: { + discovery: PluginEndpointDiscovery; + issuer: string; + }): IdentityClient { + return new IdentityClient(options); + } + + private constructor(options: { + discovery: PluginEndpointDiscovery; + issuer: string; + }) { this.discovery = options.discovery; this.issuer = options.issuer; this.keyStore = new JWKS.KeyStore(); From 898a56578cc65ba2e00b9a4ddc038ffd93aad1a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 10 Feb 2022 09:45:19 +0100 Subject: [PATCH 48/51] scaffolder: bump vm2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/sour-hairs-beam.md | 5 +++++ plugins/scaffolder-backend/package.json | 2 +- .../actions/builtin/fetch/template.test.ts | 1 - .../tasks/NunjucksWorkflowRunner.test.ts | 1 - yarn.lock | 22 ++++++++----------- 5 files changed, 15 insertions(+), 16 deletions(-) create mode 100644 .changeset/sour-hairs-beam.md diff --git a/.changeset/sour-hairs-beam.md b/.changeset/sour-hairs-beam.md new file mode 100644 index 0000000000..9611fa912b --- /dev/null +++ b/.changeset/sour-hairs-beam.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Bump `vm2` to version 3.9.6 diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index cac4185920..240ec98753 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -70,7 +70,7 @@ "uuid": "^8.2.0", "winston": "^3.2.1", "yaml": "^1.10.0", - "vm2": "^3.9.5" + "vm2": "^3.9.6" }, "devDependencies": { "@backstage/cli": "^0.13.2-next.0", diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.test.ts index cf1662307c..6ee8f8ce01 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.test.ts @@ -35,7 +35,6 @@ jest.mock('./helpers', () => ({ const realFiles = Object.fromEntries( [ - require.resolve('vm2/lib/fixasync'), resolvePackagePath( '@backstage/plugin-scaffolder-backend', 'assets', diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts index 2fc6b99406..1597c575ac 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts @@ -26,7 +26,6 @@ import { TaskContext, TaskSpec, TaskSecrets } from './types'; const realFiles = Object.fromEntries( [ - require.resolve('vm2/lib/fixasync'), resolvePackagePath( '@backstage/plugin-scaffolder-backend', 'assets', diff --git a/yarn.lock b/yarn.lock index 6988edda3f..6b4da73202 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1835,14 +1835,7 @@ dependencies: "@date-io/core" "^1.3.13" -"@date-io/luxon@1.x": - version "1.3.13" - resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-1.3.13.tgz#68f0134bb38ef486b2ed6df01981f814c633e28a" - integrity sha512-9wUrJCNSMZJeYAiH+dbb45oGpnHeFP7TOH/Lt26If47gjFCkjvyINzWx+K5AGsnlP0Qosxc7hkF1yLi6ecutxw== - dependencies: - "@date-io/core" "^1.3.13" - -"@date-io/luxon@^1.3.13": +"@date-io/luxon@1.x", "@date-io/luxon@^1.3.13": version "1.3.13" resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-1.3.13.tgz#68f0134bb38ef486b2ed6df01981f814c633e28a" integrity sha512-9wUrJCNSMZJeYAiH+dbb45oGpnHeFP7TOH/Lt26If47gjFCkjvyINzWx+K5AGsnlP0Qosxc7hkF1yLi6ecutxw== @@ -6835,7 +6828,7 @@ acorn-walk@^7.1.1: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e" integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ== -acorn-walk@^8.1.1: +acorn-walk@^8.1.1, acorn-walk@^8.2.0: version "8.2.0" resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== @@ -24502,10 +24495,13 @@ vm-browserify@^1.0.1: resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -vm2@^3.9.5: - version "3.9.5" - resolved "https://registry.npmjs.org/vm2/-/vm2-3.9.5.tgz#5288044860b4bbace443101fcd3bddb2a0aa2496" - integrity sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng== +vm2@^3.9.6: + version "3.9.6" + resolved "https://registry.npmjs.org/vm2/-/vm2-3.9.6.tgz#2f9b2fd0d82802dcd872e1011869ba8ae6b74778" + integrity sha512-BF7euUjgO+ezsz2UKex9kO9M/PtDNOf+KEpiqNepZsgf1MT7JYfJEIvG8BoYhZMLAVjqevFJ0UmXNuETe8m5dQ== + dependencies: + acorn "^8.7.0" + acorn-walk "^8.2.0" vscode-languageserver-types@^3.15.1: version "3.15.1" From 1043789dc69ced1bb21cfea684d3a4d28577fef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 10 Feb 2022 10:53:25 +0100 Subject: [PATCH 49/51] bump follow-redirects and istanbul-reports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See #9441, #8702 Signed-off-by: Fredrik Adelöw --- yarn.lock | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6988edda3f..78a34c94b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1835,14 +1835,7 @@ dependencies: "@date-io/core" "^1.3.13" -"@date-io/luxon@1.x": - version "1.3.13" - resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-1.3.13.tgz#68f0134bb38ef486b2ed6df01981f814c633e28a" - integrity sha512-9wUrJCNSMZJeYAiH+dbb45oGpnHeFP7TOH/Lt26If47gjFCkjvyINzWx+K5AGsnlP0Qosxc7hkF1yLi6ecutxw== - dependencies: - "@date-io/core" "^1.3.13" - -"@date-io/luxon@^1.3.13": +"@date-io/luxon@1.x", "@date-io/luxon@^1.3.13": version "1.3.13" resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-1.3.13.tgz#68f0134bb38ef486b2ed6df01981f814c633e28a" integrity sha512-9wUrJCNSMZJeYAiH+dbb45oGpnHeFP7TOH/Lt26If47gjFCkjvyINzWx+K5AGsnlP0Qosxc7hkF1yLi6ecutxw== @@ -12330,9 +12323,9 @@ fn.name@1.x.x: integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== follow-redirects@^1.0.0, follow-redirects@^1.14.0: - version "1.14.7" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" - integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== + version "1.14.8" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc" + integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA== for-in@^1.0.2: version "1.0.2" @@ -14773,9 +14766,9 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" - integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== + version "3.1.4" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" From 04398e946e78198cd0c97d2e21ae4be2209c7425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 10 Feb 2022 11:06:25 +0100 Subject: [PATCH 50/51] bump selfsigned, google-p12-pem, xml-encryption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/spotty-turkeys-fail.md | 5 +++ packages/backend-common/package.json | 2 +- yarn.lock | 48 ++++++++-------------------- 3 files changed, 20 insertions(+), 35 deletions(-) create mode 100644 .changeset/spotty-turkeys-fail.md diff --git a/.changeset/spotty-turkeys-fail.md b/.changeset/spotty-turkeys-fail.md new file mode 100644 index 0000000000..34dab90cd6 --- /dev/null +++ b/.changeset/spotty-turkeys-fail.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Bump `selfsigned` to 2.0.0 diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 2a2aee69bd..e22fef3778 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -68,7 +68,7 @@ "node-abort-controller": "^3.0.1", "node-fetch": "^2.6.1", "raw-body": "^2.4.1", - "selfsigned": "^1.10.7", + "selfsigned": "^2.0.0", "stoppable": "^1.1.0", "tar": "^6.1.2", "unzipper": "^0.10.11", diff --git a/yarn.lock b/yarn.lock index 6988edda3f..96e1425e60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1835,14 +1835,7 @@ dependencies: "@date-io/core" "^1.3.13" -"@date-io/luxon@1.x": - version "1.3.13" - resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-1.3.13.tgz#68f0134bb38ef486b2ed6df01981f814c633e28a" - integrity sha512-9wUrJCNSMZJeYAiH+dbb45oGpnHeFP7TOH/Lt26If47gjFCkjvyINzWx+K5AGsnlP0Qosxc7hkF1yLi6ecutxw== - dependencies: - "@date-io/core" "^1.3.13" - -"@date-io/luxon@^1.3.13": +"@date-io/luxon@1.x", "@date-io/luxon@^1.3.13": version "1.3.13" resolved "https://registry.npmjs.org/@date-io/luxon/-/luxon-1.3.13.tgz#68f0134bb38ef486b2ed6df01981f814c633e28a" integrity sha512-9wUrJCNSMZJeYAiH+dbb45oGpnHeFP7TOH/Lt26If47gjFCkjvyINzWx+K5AGsnlP0Qosxc7hkF1yLi6ecutxw== @@ -12970,11 +12963,11 @@ google-gax@^2.12.0, google-gax@^2.24.1: retry-request "^4.0.0" google-p12-pem@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz#673ac3a75d3903a87f05878f3c75e06fc151669e" - integrity sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA== + version "3.1.3" + resolved "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.3.tgz#5497998798ee86c2fc1f4bb1f92b7729baf37537" + integrity sha512-MC0jISvzymxePDVembypNefkAQp+DRP7dBE+zNUPaIjEspIlYg0++OrsNr248V9tPbz6iqtZ7rX1hxWA5B8qBQ== dependencies: - node-forge "^0.10.0" + node-forge "^1.0.0" got@^11.8.0, got@^11.8.2: version "11.8.2" @@ -17907,12 +17900,7 @@ node-fetch@2.6.7, node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node- dependencies: whatwg-url "^5.0.0" -node-forge@^0.10.0: - version "0.10.0" - resolved "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" - integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== - -node-forge@^1.2.0: +node-forge@^1.0.0, node-forge@^1.2.0: version "1.2.1" resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz#82794919071ef2eb5c509293325cec8afd0fd53c" integrity sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w== @@ -19049,15 +19037,15 @@ passport-onelogin-oauth@^0.0.1: uid2 "0.0.3" passport-saml@^3.1.2: - version "3.2.0" - resolved "https://registry.npmjs.org/passport-saml/-/passport-saml-3.2.0.tgz#72ec8203df6dd872a205b8d5f578859a4e723e42" - integrity sha512-EUzL+Wk8ZVdvOYhCBTkUrR1fwuMwF9za1FinFabP5Tl9qeJktsJWfoiBz7Fk6jQvpLwfnfryGdvwcOlGVct41A== + version "3.2.1" + resolved "https://registry.npmjs.org/passport-saml/-/passport-saml-3.2.1.tgz#c489a61a4c2dd93ddec1d53952a595b9f33e15e8" + integrity sha512-Y8aD94B6MTLht57BlBrDauEgvtWjuSeINKk7NadXlpT/OBmsoGGYPpb0FJeBtdyGX4GEbZARAkxvBEqsL8E7XQ== dependencies: "@xmldom/xmldom" "^0.7.5" debug "^4.3.2" passport-strategy "^1.0.0" xml-crypto "^2.1.3" - xml-encryption "^1.3.0" + xml-encryption "^2.0.0" xml2js "^0.4.23" xmlbuilder "^15.1.1" @@ -21724,13 +21712,6 @@ select-hose@^2.0.0: resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= -selfsigned@^1.10.7: - version "1.10.11" - resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" - integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== - dependencies: - node-forge "^0.10.0" - selfsigned@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.0.tgz#e927cd5377cbb0a1075302cff8df1042cc2bce5b" @@ -25014,14 +24995,13 @@ xml-crypto@^2.1.3: "@xmldom/xmldom" "^0.7.0" xpath "0.0.32" -xml-encryption@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/xml-encryption/-/xml-encryption-1.3.0.tgz#4cad44a59bf8bdec76d7865ce0b89e13c09962f4" - integrity sha512-3P8C4egMMxSR1BmsRM+fG16a3WzOuUEQKS2U4c3AZ5v7OseIfdUeVkD8dwxIhuLryFZSRWUL5OP6oqkgU7hguA== +xml-encryption@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/xml-encryption/-/xml-encryption-2.0.0.tgz#d4e1eb3ec1f2c5d2a2a0a6e23d199237e8b4bf83" + integrity sha512-4Av83DdvAgUQQMfi/w8G01aJshbEZP9ewjmZMpS9t3H+OCZBDvyK4GJPnHGfWiXlArnPbYvR58JB9qF2x9Ds+Q== dependencies: "@xmldom/xmldom" "^0.7.0" escape-html "^1.0.3" - node-forge "^0.10.0" xpath "0.0.32" xml-name-validator@^3.0.0: From e4791789d1cb8485c1698c8d699c95445f7795ff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 10 Feb 2022 11:06:33 +0000 Subject: [PATCH 51/51] Version Packages --- .changeset/big-days-divide.md | 10 - .changeset/big-jeans-love.md | 5 - .changeset/brave-tools-drop.md | 5 - .changeset/breezy-windows-jump.md | 5 - .changeset/chilly-pans-jog.md | 5 - .changeset/cold-houses-type.md | 7 - .changeset/cool-birds-ring.md | 5 - .changeset/curly-fireants-crash.md | 5 - .changeset/dependabot-e379ac7.md | 18 -- .changeset/dependabot-f436b5b.md | 5 - .changeset/early-beds-smoke.md | 5 - .changeset/famous-hats-decide.md | 6 - .changeset/giant-nails-grow.md | 51 ----- .changeset/green-peaches-explode.md | 6 - .changeset/healthy-flies-fold.md | 5 - .changeset/honest-foxes-scream.md | 5 - .changeset/khaki-jokes-grab.md | 5 - .changeset/little-onions-fly.md | 6 - .changeset/loud-monkeys-explode.md | 5 - .changeset/many-terms-type.md | 5 - .changeset/metal-clouds-fail.md | 5 - .changeset/metal-lions-fix.md | 5 - .changeset/moody-parrots-listen.md | 6 - .changeset/nasty-socks-exist.md | 14 -- .changeset/neat-icons-fry.md | 5 - .changeset/ninety-dancers-bow.md | 5 - .changeset/old-phones-draw.md | 5 - .changeset/popular-planes-lay.md | 58 ----- .changeset/pre.json | 161 -------------- .changeset/pretty-glasses-admire.md | 9 - .changeset/seven-apes-shave.md | 5 - .changeset/seven-teachers-arrive.md | 6 - .changeset/shaggy-buckets-confess.md | 5 - .changeset/shiny-radios-deliver.md | 5 - .changeset/smart-boxes-double.md | 5 - .changeset/smooth-wasps-knock.md | 7 - .changeset/soft-dogs-exercise.md | 6 - .changeset/sour-hairs-beam.md | 5 - .changeset/spotty-turkeys-fail.md | 5 - .changeset/strong-ties-exist.md | 5 - .changeset/tall-elephants-smash.md | 5 - .changeset/tasty-spoons-beg.md | 5 - .changeset/ten-geese-hide.md | 5 - .changeset/three-dolls-fly.md | 5 - .changeset/three-pigs-sniff.md | 5 - .changeset/twenty-colts-applaud.md | 5 - .changeset/warm-beds-flow.md | 5 - .changeset/wise-peaches-flow.md | 8 - .changeset/wise-plants-tease.md | 5 - package.json | 2 +- packages/app-defaults/CHANGELOG.md | 7 + packages/app-defaults/package.json | 6 +- packages/app/CHANGELOG.md | 46 ++++ packages/app/package.json | 82 +++---- packages/backend-common/CHANGELOG.md | 12 ++ packages/backend-common/package.json | 4 +- packages/backend-tasks/CHANGELOG.md | 11 + packages/backend-tasks/package.json | 8 +- packages/backend-test-utils/CHANGELOG.md | 12 ++ packages/backend-test-utils/package.json | 8 +- packages/backend/CHANGELOG.md | 34 +++ packages/backend/package.json | 58 ++--- packages/catalog-client/CHANGELOG.md | 11 + packages/catalog-client/package.json | 4 +- packages/cli/CHANGELOG.md | 24 +++ packages/cli/package.json | 10 +- packages/codemods/CHANGELOG.md | 7 + packages/codemods/package.json | 2 +- packages/core-components/CHANGELOG.md | 10 + packages/core-components/package.json | 4 +- packages/create-app/CHANGELOG.md | 70 ++++++ packages/create-app/package.json | 2 +- packages/dev-utils/CHANGELOG.md | 10 + packages/dev-utils/package.json | 12 +- packages/integration-react/CHANGELOG.md | 7 + packages/integration-react/package.json | 8 +- packages/release-manifests/CHANGELOG.md | 7 + packages/release-manifests/package.json | 2 +- .../techdocs-cli-embedded-app/CHANGELOG.md | 12 ++ .../techdocs-cli-embedded-app/package.json | 16 +- packages/techdocs-cli/CHANGELOG.md | 9 + packages/techdocs-cli/package.json | 8 +- packages/techdocs-common/CHANGELOG.md | 7 + packages/techdocs-common/package.json | 6 +- plugins/airbrake/CHANGELOG.md | 7 + plugins/airbrake/package.json | 10 +- plugins/allure/CHANGELOG.md | 8 + plugins/allure/package.json | 10 +- plugins/analytics-module-ga/CHANGELOG.md | 7 + plugins/analytics-module-ga/package.json | 8 +- plugins/apache-airflow/CHANGELOG.md | 7 + plugins/apache-airflow/package.json | 8 +- plugins/api-docs/CHANGELOG.md | 9 + plugins/api-docs/package.json | 12 +- plugins/app-backend/CHANGELOG.md | 11 + plugins/app-backend/package.json | 8 +- plugins/auth-backend/CHANGELOG.md | 66 ++++++ plugins/auth-backend/package.json | 10 +- plugins/auth-node/CHANGELOG.md | 13 ++ plugins/auth-node/package.json | 6 +- plugins/azure-devops-backend/CHANGELOG.md | 7 + plugins/azure-devops-backend/package.json | 6 +- plugins/azure-devops/CHANGELOG.md | 8 + plugins/azure-devops/package.json | 10 +- plugins/badges-backend/CHANGELOG.md | 8 + plugins/badges-backend/package.json | 8 +- plugins/badges/CHANGELOG.md | 8 + plugins/badges/package.json | 10 +- plugins/bazaar-backend/CHANGELOG.md | 12 ++ plugins/bazaar-backend/package.json | 8 +- plugins/bazaar/CHANGELOG.md | 12 ++ plugins/bazaar/package.json | 16 +- plugins/bitrise/CHANGELOG.md | 8 + plugins/bitrise/package.json | 10 +- .../catalog-backend-module-ldap/CHANGELOG.md | 7 + .../catalog-backend-module-ldap/package.json | 6 +- .../CHANGELOG.md | 9 + .../package.json | 8 +- plugins/catalog-backend/CHANGELOG.md | 13 ++ plugins/catalog-backend/package.json | 12 +- plugins/catalog-graph/CHANGELOG.md | 10 + plugins/catalog-graph/package.json | 12 +- plugins/catalog-import/CHANGELOG.md | 11 + plugins/catalog-import/package.json | 14 +- plugins/catalog-react/CHANGELOG.md | 13 ++ plugins/catalog-react/package.json | 8 +- plugins/catalog/CHANGELOG.md | 13 ++ plugins/catalog/package.json | 14 +- plugins/cicd-statistics/CHANGELOG.md | 12 ++ plugins/cicd-statistics/package.json | 4 +- plugins/circleci/CHANGELOG.md | 8 + plugins/circleci/package.json | 10 +- plugins/cloudbuild/CHANGELOG.md | 8 + plugins/cloudbuild/package.json | 10 +- plugins/code-coverage-backend/CHANGELOG.md | 12 ++ plugins/code-coverage-backend/package.json | 8 +- plugins/code-coverage/CHANGELOG.md | 8 + plugins/code-coverage/package.json | 10 +- plugins/config-schema/CHANGELOG.md | 7 + plugins/config-schema/package.json | 8 +- plugins/cost-insights/CHANGELOG.md | 7 + plugins/cost-insights/package.json | 8 +- plugins/explore/CHANGELOG.md | 8 + plugins/explore/package.json | 10 +- plugins/firehydrant/CHANGELOG.md | 8 + plugins/firehydrant/package.json | 10 +- plugins/fossa/CHANGELOG.md | 8 + plugins/fossa/package.json | 10 +- plugins/gcp-projects/CHANGELOG.md | 7 + plugins/gcp-projects/package.json | 8 +- plugins/git-release-manager/CHANGELOG.md | 7 + plugins/git-release-manager/package.json | 8 +- plugins/github-actions/CHANGELOG.md | 8 + plugins/github-actions/package.json | 10 +- plugins/github-deployments/CHANGELOG.md | 9 + plugins/github-deployments/package.json | 12 +- plugins/gitops-profiles/CHANGELOG.md | 7 + plugins/gitops-profiles/package.json | 8 +- plugins/gocd/CHANGELOG.md | 8 + plugins/gocd/package.json | 10 +- plugins/graphiql/CHANGELOG.md | 7 + plugins/graphiql/package.json | 8 +- plugins/graphql-backend/CHANGELOG.md | 7 + plugins/graphql-backend/package.json | 6 +- plugins/home/CHANGELOG.md | 10 + plugins/home/package.json | 12 +- plugins/ilert/CHANGELOG.md | 9 + plugins/ilert/package.json | 10 +- plugins/jenkins-backend/CHANGELOG.md | 8 + plugins/jenkins-backend/package.json | 8 +- plugins/jenkins/CHANGELOG.md | 8 + plugins/jenkins/package.json | 10 +- plugins/kafka-backend/CHANGELOG.md | 7 + plugins/kafka-backend/package.json | 6 +- plugins/kafka/CHANGELOG.md | 8 + plugins/kafka/package.json | 10 +- plugins/kubernetes-backend/CHANGELOG.md | 7 + plugins/kubernetes-backend/package.json | 6 +- plugins/kubernetes/CHANGELOG.md | 8 + plugins/kubernetes/package.json | 10 +- plugins/lighthouse/CHANGELOG.md | 8 + plugins/lighthouse/package.json | 10 +- plugins/newrelic-dashboard/CHANGELOG.md | 9 + plugins/newrelic-dashboard/package.json | 10 +- plugins/newrelic/CHANGELOG.md | 7 + plugins/newrelic/package.json | 8 +- plugins/org/package.json | 10 +- plugins/pagerduty/CHANGELOG.md | 8 + plugins/pagerduty/package.json | 10 +- plugins/permission-backend/CHANGELOG.md | 10 + plugins/permission-backend/package.json | 10 +- plugins/permission-node/CHANGELOG.md | 8 + plugins/permission-node/package.json | 8 +- plugins/proxy-backend/CHANGELOG.md | 7 + plugins/proxy-backend/package.json | 6 +- plugins/rollbar-backend/CHANGELOG.md | 7 + plugins/rollbar-backend/package.json | 6 +- plugins/rollbar/CHANGELOG.md | 8 + plugins/rollbar/package.json | 10 +- .../CHANGELOG.md | 8 + .../package.json | 8 +- .../CHANGELOG.md | 8 + .../package.json | 8 +- .../CHANGELOG.md | 7 + .../package.json | 6 +- plugins/scaffolder-backend/CHANGELOG.md | 17 ++ plugins/scaffolder-backend/package.json | 12 +- plugins/scaffolder/CHANGELOG.md | 13 ++ plugins/scaffolder/package.json | 16 +- plugins/search-backend-module-pg/CHANGELOG.md | 11 + plugins/search-backend-module-pg/package.json | 8 +- plugins/search-backend/CHANGELOG.md | 10 + plugins/search-backend/package.json | 10 +- plugins/search/CHANGELOG.md | 9 + plugins/search/package.json | 10 +- plugins/sentry/CHANGELOG.md | 8 + plugins/sentry/package.json | 10 +- plugins/shortcuts/CHANGELOG.md | 7 + plugins/shortcuts/package.json | 8 +- plugins/sonarqube/CHANGELOG.md | 8 + plugins/sonarqube/package.json | 10 +- plugins/splunk-on-call/CHANGELOG.md | 10 + plugins/splunk-on-call/package.json | 10 +- .../CHANGELOG.md | 8 + .../package.json | 8 +- plugins/tech-insights-backend/CHANGELOG.md | 13 ++ plugins/tech-insights-backend/package.json | 12 +- plugins/tech-insights-node/CHANGELOG.md | 7 + plugins/tech-insights-node/package.json | 6 +- plugins/tech-insights/CHANGELOG.md | 8 + plugins/tech-insights/package.json | 10 +- plugins/tech-radar/CHANGELOG.md | 7 + plugins/tech-radar/package.json | 8 +- plugins/techdocs-backend/CHANGELOG.md | 13 ++ plugins/techdocs-backend/package.json | 10 +- plugins/techdocs/CHANGELOG.md | 11 + plugins/techdocs/package.json | 16 +- plugins/todo-backend/CHANGELOG.md | 8 + plugins/todo-backend/package.json | 8 +- plugins/todo/CHANGELOG.md | 12 ++ plugins/todo/package.json | 10 +- plugins/user-settings/CHANGELOG.md | 7 + plugins/user-settings/package.json | 8 +- plugins/xcmetrics/CHANGELOG.md | 7 + plugins/xcmetrics/package.json | 8 +- yarn.lock | 202 +++++------------- 246 files changed, 1608 insertions(+), 1195 deletions(-) delete mode 100644 .changeset/big-days-divide.md delete mode 100644 .changeset/big-jeans-love.md delete mode 100644 .changeset/brave-tools-drop.md delete mode 100644 .changeset/breezy-windows-jump.md delete mode 100644 .changeset/chilly-pans-jog.md delete mode 100644 .changeset/cold-houses-type.md delete mode 100644 .changeset/cool-birds-ring.md delete mode 100644 .changeset/curly-fireants-crash.md delete mode 100644 .changeset/dependabot-e379ac7.md delete mode 100644 .changeset/dependabot-f436b5b.md delete mode 100644 .changeset/early-beds-smoke.md delete mode 100644 .changeset/famous-hats-decide.md delete mode 100644 .changeset/giant-nails-grow.md delete mode 100644 .changeset/green-peaches-explode.md delete mode 100644 .changeset/healthy-flies-fold.md delete mode 100644 .changeset/honest-foxes-scream.md delete mode 100644 .changeset/khaki-jokes-grab.md delete mode 100644 .changeset/little-onions-fly.md delete mode 100644 .changeset/loud-monkeys-explode.md delete mode 100644 .changeset/many-terms-type.md delete mode 100644 .changeset/metal-clouds-fail.md delete mode 100644 .changeset/metal-lions-fix.md delete mode 100644 .changeset/moody-parrots-listen.md delete mode 100644 .changeset/nasty-socks-exist.md delete mode 100644 .changeset/neat-icons-fry.md delete mode 100644 .changeset/ninety-dancers-bow.md delete mode 100644 .changeset/old-phones-draw.md delete mode 100644 .changeset/popular-planes-lay.md delete mode 100644 .changeset/pre.json delete mode 100644 .changeset/pretty-glasses-admire.md delete mode 100644 .changeset/seven-apes-shave.md delete mode 100644 .changeset/seven-teachers-arrive.md delete mode 100644 .changeset/shaggy-buckets-confess.md delete mode 100644 .changeset/shiny-radios-deliver.md delete mode 100644 .changeset/smart-boxes-double.md delete mode 100644 .changeset/smooth-wasps-knock.md delete mode 100644 .changeset/soft-dogs-exercise.md delete mode 100644 .changeset/sour-hairs-beam.md delete mode 100644 .changeset/spotty-turkeys-fail.md delete mode 100644 .changeset/strong-ties-exist.md delete mode 100644 .changeset/tall-elephants-smash.md delete mode 100644 .changeset/tasty-spoons-beg.md delete mode 100644 .changeset/ten-geese-hide.md delete mode 100644 .changeset/three-dolls-fly.md delete mode 100644 .changeset/three-pigs-sniff.md delete mode 100644 .changeset/twenty-colts-applaud.md delete mode 100644 .changeset/warm-beds-flow.md delete mode 100644 .changeset/wise-peaches-flow.md delete mode 100644 .changeset/wise-plants-tease.md create mode 100644 plugins/auth-node/CHANGELOG.md create mode 100644 plugins/cicd-statistics/CHANGELOG.md diff --git a/.changeset/big-days-divide.md b/.changeset/big-days-divide.md deleted file mode 100644 index 0285a5aacd..0000000000 --- a/.changeset/big-days-divide.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/catalog-client': minor ---- - -Fixed the return type of the catalog API `getEntityAncestors`, to match the -actual server response shape. - -While this technically is a breaking change, the old shape has never worked at -all if you tried to use it - so treating this as an immediately-shipped breaking -bug fix. diff --git a/.changeset/big-jeans-love.md b/.changeset/big-jeans-love.md deleted file mode 100644 index e97ae15ff4..0000000000 --- a/.changeset/big-jeans-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -The `plugin:diff` command no longer validates the existence of any of the files within `dev/` or `src/`. diff --git a/.changeset/brave-tools-drop.md b/.changeset/brave-tools-drop.md deleted file mode 100644 index 02b6b7ebb1..0000000000 --- a/.changeset/brave-tools-drop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Introduced initial support for an experimental `backstage.role` field in package.json, as well as experimental and hidden `migrate` and `script` sub-commands. We do not recommend usage of any of these additions yet. diff --git a/.changeset/breezy-windows-jump.md b/.changeset/breezy-windows-jump.md deleted file mode 100644 index 0d839614ff..0000000000 --- a/.changeset/breezy-windows-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': minor ---- - -The `callbackUrl` option of `OAuthAdapter` is now required. diff --git a/.changeset/chilly-pans-jog.md b/.changeset/chilly-pans-jog.md deleted file mode 100644 index b63d5fde50..0000000000 --- a/.changeset/chilly-pans-jog.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-todo': minor ---- - -**BREAKING**: The `EntityTodoContent` is now a routable extension. This means it must be rendered within a route, but that's most likely already the case for most apps. The mount point `RouteRef` is available via `todoPlugin.routes.entityContent`. diff --git a/.changeset/cold-houses-type.md b/.changeset/cold-houses-type.md deleted file mode 100644 index 05155c96c0..0000000000 --- a/.changeset/cold-houses-type.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Introduces a new `--release` parameter to the `backstage-cli versions:bump` command. -The release can be either a specific version, for example `0.99.1`, or the latest `main` or `next` release. -The default behavior is to bump to the latest `main` release. diff --git a/.changeset/cool-birds-ring.md b/.changeset/cool-birds-ring.md deleted file mode 100644 index 0ecd4a47e9..0000000000 --- a/.changeset/cool-birds-ring.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-newrelic-dashboard': patch ---- - -Export DashboardSnapshotComponent from new-relic-dashboard-plugin diff --git a/.changeset/curly-fireants-crash.md b/.changeset/curly-fireants-crash.md deleted file mode 100644 index db426a0fde..0000000000 --- a/.changeset/curly-fireants-crash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -chore: bump `ansi-regex` from `5.0.1` to `6.0.1` diff --git a/.changeset/dependabot-e379ac7.md b/.changeset/dependabot-e379ac7.md deleted file mode 100644 index a00f5c5582..0000000000 --- a/.changeset/dependabot-e379ac7.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/backend-tasks': patch -'@backstage/backend-test-utils': patch -'@backstage/plugin-app-backend': patch -'@backstage/plugin-auth-backend': patch -'@backstage/plugin-bazaar-backend': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-code-coverage-backend': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-search-backend-module-pg': patch -'@backstage/plugin-tech-insights-backend': patch -'@backstage/plugin-techdocs-backend': patch ---- - -chore(deps): bump `knex` from 0.95.6 to 1.0.2 - -This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 diff --git a/.changeset/dependabot-f436b5b.md b/.changeset/dependabot-f436b5b.md deleted file mode 100644 index 9dc9fbccc8..0000000000 --- a/.changeset/dependabot-f436b5b.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -chore(deps-dev): bump `@types/concat-stream` from 1.6.1 to 2.0.0 diff --git a/.changeset/early-beds-smoke.md b/.changeset/early-beds-smoke.md deleted file mode 100644 index de9a412e7f..0000000000 --- a/.changeset/early-beds-smoke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Enabled refresh for the Atlassian provider. diff --git a/.changeset/famous-hats-decide.md b/.changeset/famous-hats-decide.md deleted file mode 100644 index e6f3a4bd5a..0000000000 --- a/.changeset/famous-hats-decide.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-auth-node': minor ---- - -Added this package, to hold shared types and functionality that other backend -packages need to import. diff --git a/.changeset/giant-nails-grow.md b/.changeset/giant-nails-grow.md deleted file mode 100644 index 7ea36968b9..0000000000 --- a/.changeset/giant-nails-grow.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -'@backstage/plugin-auth-backend': minor ---- - -The following breaking changes were made, which may imply specifically needing -to make small adjustments in your custom auth providers. - -- **BREAKING**: Moved `IdentityClient`, `BackstageSignInResult`, - `BackstageIdentityResponse`, and `BackstageUserIdentity` to - `@backstage/plugin-auth-node`. -- **BREAKING**: Removed deprecated type `BackstageIdentity`, please use - `BackstageSignInResult` from `@backstage/plugin-auth-node` instead. - -While moving over, `IdentityClient` was also changed in the following ways: - -- **BREAKING**: Made `IdentityClient.listPublicKeys` private. It was only used - in tests, and should not be part of the API surface of that class. -- **BREAKING**: Removed the static `IdentityClient.getBearerToken`. It is now - replaced by `getBearerTokenFromAuthorizationHeader` from - `@backstage/plugin-auth-node`. -- **BREAKING**: Removed the constructor. Please use the `IdentityClient.create` - static method instead. - -Since the `IdentityClient` interface is marked as experimental, this is a -breaking change without a deprecation period. - -In your auth providers, you may need to update your imports and usages as -follows (example code; yours may be slightly different): - -````diff --import { IdentityClient } from '@backstage/plugin-auth-backend'; -+import { -+ IdentityClient, -+ getBearerTokenFromAuthorizationHeader -+} from '@backstage/plugin-auth-node'; - - // ... - -- const identity = new IdentityClient({ -+ const identity = IdentityClient.create({ - discovery, - issuer: await discovery.getExternalBaseUrl('auth'), - });``` - - // ... - - const token = -- IdentityClient.getBearerToken(req.headers.authorization) || -+ getBearerTokenFromAuthorizationHeader(req.headers.authorization) || - req.cookies['token']; -```` diff --git a/.changeset/green-peaches-explode.md b/.changeset/green-peaches-explode.md deleted file mode 100644 index cfebebffc3..0000000000 --- a/.changeset/green-peaches-explode.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/release-manifests': patch ---- - -Introduces a new package with utilities for fetching release manifests. -This package will primarily be used by the `@backstage/cli` package. diff --git a/.changeset/healthy-flies-fold.md b/.changeset/healthy-flies-fold.md deleted file mode 100644 index ae42533f8a..0000000000 --- a/.changeset/healthy-flies-fold.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Removed unnecessary `get-port` dependency diff --git a/.changeset/honest-foxes-scream.md b/.changeset/honest-foxes-scream.md deleted file mode 100644 index f2d80b63a9..0000000000 --- a/.changeset/honest-foxes-scream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-splunk-on-call': patch ---- - -Add Splunk On-Call plugin support for a `splunk.com/on-call-routing-key` annotation. If the `splunk.com/on-call-routing-key` is provided, the plugin displays a Splunk On-Call card for each of the teams associated with the routing key. diff --git a/.changeset/khaki-jokes-grab.md b/.changeset/khaki-jokes-grab.md deleted file mode 100644 index 31201c1078..0000000000 --- a/.changeset/khaki-jokes-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Adjust ErrorPage to accept optional supportUrl property to override app support config. Update type of additionalInfo property to be ReactNode to accept both string and component. diff --git a/.changeset/little-onions-fly.md b/.changeset/little-onions-fly.md deleted file mode 100644 index 8bff96d866..0000000000 --- a/.changeset/little-onions-fly.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-permission-backend': patch -'@backstage/plugin-search-backend': patch ---- - -Use `getBearerTokenFromAuthorizationHeader` from `@backstage/plugin-auth-node` instead of the deprecated `IdentityClient` method. diff --git a/.changeset/loud-monkeys-explode.md b/.changeset/loud-monkeys-explode.md deleted file mode 100644 index b17b1e1641..0000000000 --- a/.changeset/loud-monkeys-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Adds a loading bar to the scaffolder task page if the task is still loading. This can happen if it takes a while for a task worker to pick up a task. diff --git a/.changeset/many-terms-type.md b/.changeset/many-terms-type.md deleted file mode 100644 index fd11d14106..0000000000 --- a/.changeset/many-terms-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -The experimental types build enabled by `--experimental-type-build` now runs in a separate worker thread. diff --git a/.changeset/metal-clouds-fail.md b/.changeset/metal-clouds-fail.md deleted file mode 100644 index 083984c015..0000000000 --- a/.changeset/metal-clouds-fail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -The file path printed by the default lint formatter is now relative to the repository root, rather than the individual package. diff --git a/.changeset/metal-lions-fix.md b/.changeset/metal-lions-fix.md deleted file mode 100644 index 913098bbf7..0000000000 --- a/.changeset/metal-lions-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Added a new `cookieConfigurer` option to `AuthProviderConfig` that makes it possible to override the default logic for configuring OAuth provider cookies. diff --git a/.changeset/moody-parrots-listen.md b/.changeset/moody-parrots-listen.md deleted file mode 100644 index ff19f67bfd..0000000000 --- a/.changeset/moody-parrots-listen.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-bazaar': patch -'@backstage/plugin-ilert': patch ---- - -Rolling back the `@date-io/luxon` bump as this broke both packages, and we need it for `@material-ui/pickers` diff --git a/.changeset/nasty-socks-exist.md b/.changeset/nasty-socks-exist.md deleted file mode 100644 index 6aa3e56a1d..0000000000 --- a/.changeset/nasty-socks-exist.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Switched the `file:` dependency for a `link:` dependency in the `backend` package. This makes sure that the `app` package is linked in rather than copied. - -To apply this update to an existing app, make the following change to `packages/backend/package.json`: - -```diff - "dependencies": { -- "app": "file:../app", -+ "app": "link:../app", - "@backstage/backend-common": "^{{version '@backstage/backend-common'}}", -``` diff --git a/.changeset/neat-icons-fry.md b/.changeset/neat-icons-fry.md deleted file mode 100644 index 33c4a4512c..0000000000 --- a/.changeset/neat-icons-fry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Tweaked frontend bundling configuration to avoid leaking declarations into global scope. diff --git a/.changeset/ninety-dancers-bow.md b/.changeset/ninety-dancers-bow.md deleted file mode 100644 index dc8bd7b702..0000000000 --- a/.changeset/ninety-dancers-bow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-msgraph': patch ---- - -Add userExpand option to allow users to expand fields retrieved from the Graph API - for use in custom transformers diff --git a/.changeset/old-phones-draw.md b/.changeset/old-phones-draw.md deleted file mode 100644 index fd987844f3..0000000000 --- a/.changeset/old-phones-draw.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search': patch ---- - -Modify modal search to clamp result length to 5 rows. diff --git a/.changeset/popular-planes-lay.md b/.changeset/popular-planes-lay.md deleted file mode 100644 index 2771039ede..0000000000 --- a/.changeset/popular-planes-lay.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -**BREAKING:** Updated `knex` to major version 1, which also implies changing out -the underlying `sqlite` implementation. - -The old `sqlite3` NPM library has been abandoned by its maintainers, which has -led to unhandled security reports and other issues. Therefore, in the `knex` 1.x -release line they have instead switched over to the [`@vscode/sqlite3` -library](https://github.com/microsoft/vscode-node-sqlite3) by default, which is -actively maintained by Microsoft. - -This means that as you update to this version of Backstage, there are two -breaking changes that you will have to address in your own repository: - -## Bumping `knex` itself - -All `package.json` files of your repo that used to depend on a 0.x version of -`knex`, should now be updated to depend on the 1.x release line. This applies in -particular to `packages/backend`, but may also occur in backend plugins or -libraries. - -```diff -- "knex": "^0.95.1", -+ "knex": "^1.0.2", -``` - -Almost all existing database code will continue to function without modification -after this bump. The only significant difference that we discovered in the main -repo, is that the `alter()` function had a slightly different signature in -migration files. It now accepts an object with `alterType` and `alterNullable` -fields that clarify a previous grey area such that the intent of the alteration -is made explicit. This is caught by `tsc` and your editor if you are using the -`@ts-check` and `@param` syntax in your migration files -([example](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend/migrations/20220116144621_remove_legacy.js#L17)), -which we strongly recommend. - -See the [`knex` documentation](https://knexjs.org/#Schema-alter) for more -information about the `alter` syntax. - -Also see the [`knex` changelog](https://knexjs.org/#changelog) for information -about breaking changes in the 1.x line; if you are using `RETURNING` you may -want to make some additional modifications in your code. - -## Switching out `sqlite3` - -All `package.json` files of your repo that used to depend on `sqlite3`, should -now be updated to depend on `@vscode/sqlite3`. This applies in particular to -`packages/backend`, but may also occur in backend plugins or libraries. - -```diff -- "sqlite3": "^5.0.1", -+ "@vscode/sqlite3": "^5.0.7", -``` - -These should be functionally equivalent, except that the new library will have -addressed some long standing problems with old transitive dependencies etc. diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 6261b07f60..0000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,161 +0,0 @@ -{ - "mode": "exit", - "tag": "next", - "initialVersions": { - "example-app": "0.2.63", - "@backstage/app-defaults": "0.1.6", - "example-backend": "0.2.63", - "@backstage/backend-common": "0.10.6", - "@backstage/backend-tasks": "0.1.5", - "@backstage/backend-test-utils": "0.1.16", - "@backstage/catalog-client": "0.5.5", - "@backstage/catalog-model": "0.9.10", - "@backstage/cli": "0.13.1", - "@backstage/cli-common": "0.1.6", - "@backstage/codemods": "0.1.32", - "@backstage/config": "0.1.13", - "@backstage/config-loader": "0.9.3", - "@backstage/core-app-api": "0.5.2", - "@backstage/core-components": "0.8.7", - "@backstage/core-plugin-api": "0.6.0", - "@backstage/create-app": "0.4.18", - "@backstage/dev-utils": "0.2.20", - "e2e-test": "0.2.0", - "@backstage/errors": "0.2.0", - "@backstage/integration": "0.7.2", - "@backstage/integration-react": "0.1.20", - "@backstage/search-common": "0.2.2", - "@techdocs/cli": "0.8.12", - "techdocs-cli-embedded-app": "0.2.62", - "@backstage/techdocs-common": "0.11.6", - "@backstage/test-utils": "0.2.4", - "@backstage/theme": "0.2.14", - "@backstage/types": "0.1.1", - "@backstage/version-bridge": "0.1.1", - "@backstage/plugin-airbrake": "0.1.2", - "@backstage/plugin-allure": "0.1.13", - "@backstage/plugin-analytics-module-ga": "0.1.8", - "@backstage/plugin-apache-airflow": "0.1.5", - "@backstage/plugin-api-docs": "0.7.1", - "@backstage/plugin-app-backend": "0.3.23", - "@backstage/plugin-auth-backend": "0.9.0", - "@backstage/plugin-azure-devops": "0.1.13", - "@backstage/plugin-azure-devops-backend": "0.3.2", - "@backstage/plugin-azure-devops-common": "0.2.0", - "@backstage/plugin-badges": "0.2.21", - "@backstage/plugin-badges-backend": "0.1.17", - "@backstage/plugin-bazaar": "0.1.12", - "@backstage/plugin-bazaar-backend": "0.1.8", - "@backstage/plugin-bitrise": "0.1.24", - "@backstage/plugin-catalog": "0.7.11", - "@backstage/plugin-catalog-backend": "0.21.2", - "@backstage/plugin-catalog-backend-module-ldap": "0.3.11", - "@backstage/plugin-catalog-backend-module-msgraph": "0.2.14", - "@backstage/plugin-catalog-common": "0.1.2", - "@backstage/plugin-catalog-graph": "0.2.9", - "@backstage/plugin-catalog-graphql": "0.3.1", - "@backstage/plugin-catalog-import": "0.8.0", - "@backstage/plugin-catalog-react": "0.6.13", - "@backstage/plugin-circleci": "0.2.36", - "@backstage/plugin-cloudbuild": "0.2.34", - "@backstage/plugin-code-coverage": "0.1.24", - "@backstage/plugin-code-coverage-backend": "0.1.21", - "@backstage/plugin-config-schema": "0.1.20", - "@backstage/plugin-cost-insights": "0.11.19", - "@backstage/plugin-explore": "0.3.28", - "@backstage/plugin-explore-react": "0.0.11", - "@backstage/plugin-firehydrant": "0.1.14", - "@backstage/plugin-fossa": "0.2.29", - "@backstage/plugin-gcp-projects": "0.3.16", - "@backstage/plugin-git-release-manager": "0.3.10", - "@backstage/plugin-github-actions": "0.4.34", - "@backstage/plugin-github-deployments": "0.1.28", - "@backstage/plugin-gitops-profiles": "0.3.15", - "@backstage/plugin-gocd": "0.1.3", - "@backstage/plugin-graphiql": "0.2.29", - "@backstage/plugin-graphql-backend": "0.1.13", - "@backstage/plugin-home": "0.4.13", - "@backstage/plugin-ilert": "0.1.23", - "@backstage/plugin-jenkins": "0.5.19", - "@backstage/plugin-jenkins-backend": "0.1.12", - "@backstage/plugin-kafka": "0.2.27", - "@backstage/plugin-kafka-backend": "0.2.16", - "@backstage/plugin-kubernetes": "0.5.6", - "@backstage/plugin-kubernetes-backend": "0.4.6", - "@backstage/plugin-kubernetes-common": "0.2.2", - "@backstage/plugin-lighthouse": "0.2.36", - "@backstage/plugin-newrelic": "0.3.15", - "@backstage/plugin-newrelic-dashboard": "0.1.5", - "@backstage/plugin-org": "0.4.1", - "@backstage/plugin-pagerduty": "0.3.24", - "@backstage/plugin-permission-backend": "0.4.2", - "@backstage/plugin-permission-common": "0.4.0", - "@backstage/plugin-permission-node": "0.4.2", - "@backstage/plugin-permission-react": "0.3.0", - "@backstage/plugin-proxy-backend": "0.2.17", - "@backstage/plugin-rollbar": "0.3.25", - "@backstage/plugin-rollbar-backend": "0.1.20", - "@backstage/plugin-scaffolder": "0.12.1", - "@backstage/plugin-scaffolder-backend": "0.15.23", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.1.10", - "@backstage/plugin-scaffolder-backend-module-rails": "0.2.5", - "@backstage/plugin-scaffolder-backend-module-yeoman": "0.1.4", - "@backstage/plugin-scaffolder-common": "0.1.3", - "@backstage/plugin-search": "0.6.1", - "@backstage/plugin-search-backend": "0.4.1", - "@backstage/plugin-search-backend-module-elasticsearch": "0.0.8", - "@backstage/plugin-search-backend-module-pg": "0.2.5", - "@backstage/plugin-search-backend-node": "0.4.5", - "@backstage/plugin-sentry": "0.3.35", - "@backstage/plugin-shortcuts": "0.1.21", - "@backstage/plugin-sonarqube": "0.2.15", - "@backstage/plugin-splunk-on-call": "0.3.21", - "@backstage/plugin-tech-insights": "0.1.7", - "@backstage/plugin-tech-insights-backend": "0.2.3", - "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.7", - "@backstage/plugin-tech-insights-common": "0.2.1", - "@backstage/plugin-tech-insights-node": "0.2.1", - "@backstage/plugin-tech-radar": "0.5.4", - "@backstage/plugin-techdocs": "0.13.2", - "@backstage/plugin-techdocs-backend": "0.13.2", - "@backstage/plugin-todo": "0.1.21", - "@backstage/plugin-todo-backend": "0.1.20", - "@backstage/plugin-user-settings": "0.3.18", - "@backstage/plugin-xcmetrics": "0.2.17" - }, - "changesets": [ - "big-jeans-love", - "brave-tools-drop", - "breezy-windows-jump", - "chilly-pans-jog", - "cool-birds-ring", - "curly-fireants-crash", - "dependabot-e379ac7", - "dependabot-f436b5b", - "early-beds-smoke", - "healthy-flies-fold", - "khaki-jokes-grab", - "loud-monkeys-explode", - "many-terms-type", - "metal-clouds-fail", - "metal-lions-fix", - "nasty-socks-exist", - "neat-icons-fry", - "ninety-dancers-bow", - "old-phones-draw", - "popular-planes-lay", - "pretty-glasses-admire", - "seven-apes-shave", - "seven-teachers-arrive", - "shaggy-buckets-confess", - "shiny-radios-deliver", - "smart-boxes-double", - "tasty-spoons-beg", - "three-dolls-fly", - "three-pigs-sniff", - "twenty-colts-applaud", - "warm-beds-flow", - "wise-peaches-flow", - "wise-plants-tease" - ] -} diff --git a/.changeset/pretty-glasses-admire.md b/.changeset/pretty-glasses-admire.md deleted file mode 100644 index 318271ddc9..0000000000 --- a/.changeset/pretty-glasses-admire.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Removed the `import/no-duplicates` lint rule from the frontend and backend ESLint configurations. This rule is quite expensive to execute and only provides a purely cosmetic benefit, so we opted to remove it from the set of default rules. If you would like to keep this rule you can add it back in your local ESLint configuration: - -```js - 'import/no-duplicates': 'warn' -``` diff --git a/.changeset/seven-apes-shave.md b/.changeset/seven-apes-shave.md deleted file mode 100644 index 356fd377dd..0000000000 --- a/.changeset/seven-apes-shave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': patch ---- - -Updated `useEntityListProvider` and catalog pickers to respond to external changes to query parameters in the URL, such as two sidebar links that apply different catalog filters. diff --git a/.changeset/seven-teachers-arrive.md b/.changeset/seven-teachers-arrive.md deleted file mode 100644 index bdbbc33c44..0000000000 --- a/.changeset/seven-teachers-arrive.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -fix for the `gitlab:publish` action to use the `oauthToken` key when creating a -`Gitlab` client. This only happens if `ctx.input.token` is provided else the key `token` will be used. diff --git a/.changeset/shaggy-buckets-confess.md b/.changeset/shaggy-buckets-confess.md deleted file mode 100644 index 186d911b77..0000000000 --- a/.changeset/shaggy-buckets-confess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-splunk-on-call': patch ---- - -Correct spelling of 'Acknowledge' in tooltip. diff --git a/.changeset/shiny-radios-deliver.md b/.changeset/shiny-radios-deliver.md deleted file mode 100644 index 3a00a6acc0..0000000000 --- a/.changeset/shiny-radios-deliver.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Encode the `formData` in the `queryString` using `JSON.stringify` to keep the types in the decoded value diff --git a/.changeset/smart-boxes-double.md b/.changeset/smart-boxes-double.md deleted file mode 100644 index 81d708297e..0000000000 --- a/.changeset/smart-boxes-double.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -The ScaffolderPage can be passed an optional `TaskPageComponent` with a `loadingText` string. It will replace the Loading text in the scaffolder task page. diff --git a/.changeset/smooth-wasps-knock.md b/.changeset/smooth-wasps-knock.md deleted file mode 100644 index de4c58e04b..0000000000 --- a/.changeset/smooth-wasps-knock.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-catalog': patch -'@backstage/plugin-catalog-react': patch ---- - -Added an "inspect" entry in the entity three-dots menu, for lower level catalog -insights and debugging. diff --git a/.changeset/soft-dogs-exercise.md b/.changeset/soft-dogs-exercise.md deleted file mode 100644 index 2d045ba1f6..0000000000 --- a/.changeset/soft-dogs-exercise.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core-components': patch -'@backstage/plugin-catalog-react': patch ---- - -Updated React component type declarations to avoid exporting exotic component types. diff --git a/.changeset/sour-hairs-beam.md b/.changeset/sour-hairs-beam.md deleted file mode 100644 index 9611fa912b..0000000000 --- a/.changeset/sour-hairs-beam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Bump `vm2` to version 3.9.6 diff --git a/.changeset/spotty-turkeys-fail.md b/.changeset/spotty-turkeys-fail.md deleted file mode 100644 index 34dab90cd6..0000000000 --- a/.changeset/spotty-turkeys-fail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Bump `selfsigned` to 2.0.0 diff --git a/.changeset/strong-ties-exist.md b/.changeset/strong-ties-exist.md deleted file mode 100644 index dae77c2805..0000000000 --- a/.changeset/strong-ties-exist.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-cicd-statistics': minor ---- - -Added new plugin "CI/CD Statistics" which charts pipeline build durations over time diff --git a/.changeset/tall-elephants-smash.md b/.changeset/tall-elephants-smash.md deleted file mode 100644 index a26dbd65a6..0000000000 --- a/.changeset/tall-elephants-smash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -chore: fixing typescript errors for `TabbedCard.tsx` for React 17.x diff --git a/.changeset/tasty-spoons-beg.md b/.changeset/tasty-spoons-beg.md deleted file mode 100644 index 651c70e03c..0000000000 --- a/.changeset/tasty-spoons-beg.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Rather than calling `yarn pack`, the `build-workspace` and `backend-bundle` commands now move files directly whenever possible. This cuts out several `yarn` invocations and speeds the packing process up by several orders of magnitude. diff --git a/.changeset/ten-geese-hide.md b/.changeset/ten-geese-hide.md deleted file mode 100644 index c2386fc44f..0000000000 --- a/.changeset/ten-geese-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Deprecated the `EntityPageLayout`; please use the new extension based `CatalogEntityPage` instead diff --git a/.changeset/three-dolls-fly.md b/.changeset/three-dolls-fly.md deleted file mode 100644 index df711c547d..0000000000 --- a/.changeset/three-dolls-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Switched the `lint` command to invoke ESLint directly through its Node.js API rather than spawning a new process. diff --git a/.changeset/three-pigs-sniff.md b/.changeset/three-pigs-sniff.md deleted file mode 100644 index c2020c9e80..0000000000 --- a/.changeset/three-pigs-sniff.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -The `ErrorPage` now falls back to using the default support configuration if the `ConfigApi` is not available. diff --git a/.changeset/twenty-colts-applaud.md b/.changeset/twenty-colts-applaud.md deleted file mode 100644 index 2390e21a6e..0000000000 --- a/.changeset/twenty-colts-applaud.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Introduced an experimental and hidden `repo` sub-command, that contains commands that operate on an entire monorepo rather than individual packages. diff --git a/.changeset/warm-beds-flow.md b/.changeset/warm-beds-flow.md deleted file mode 100644 index 7d34336739..0000000000 --- a/.changeset/warm-beds-flow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@techdocs/cli': patch ---- - -Updated the HTTP server to allow for simplification of the development of the CLI itself. diff --git a/.changeset/wise-peaches-flow.md b/.changeset/wise-peaches-flow.md deleted file mode 100644 index 68e89cf841..0000000000 --- a/.changeset/wise-peaches-flow.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-msgraph': patch -'@backstage/plugin-catalog-graph': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-catalog-react': patch ---- - -Minor API cleanups diff --git a/.changeset/wise-plants-tease.md b/.changeset/wise-plants-tease.md deleted file mode 100644 index 206704435d..0000000000 --- a/.changeset/wise-plants-tease.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Adds new StarredEntities component responsible for rendering a list of starred entities on the home page diff --git a/package.json b/package.json index 918e465b82..242c64c8bb 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "**/@roadiehq/**/@backstage/plugin-catalog": "*", "**/@roadiehq/**/@backstage/catalog-model": "*" }, - "version": "0.67.0-next.0", + "version": "0.67.0", "dependencies": { "@manypkg/get-packages": "^1.1.3", "@microsoft/api-documenter": "^7.15.0", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index f9d829c844..74313008cd 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/app-defaults +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.1.7-next.0 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index a7b118db11..c7cb87faa4 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/app-defaults", "description": "Provides the default wiring of a Backstage App", - "version": "0.1.7-next.0", + "version": "0.1.7", "private": false, "publishConfig": { "access": "public", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-app-api": "^0.5.2", "@backstage/core-plugin-api": "^0.6.0", "@backstage/plugin-permission-react": "^0.3.0", @@ -42,7 +42,7 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index a2a444b62f..1139bf2cbb 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,51 @@ # example-app +## 0.2.64 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.13.2 + - @backstage/plugin-todo@0.2.0 + - @backstage/plugin-newrelic-dashboard@0.1.6 + - @backstage/core-components@0.8.8 + - @backstage/plugin-scaffolder@0.12.2 + - @backstage/plugin-search@0.6.2 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/plugin-catalog@0.7.12 + - @backstage/plugin-catalog-graph@0.2.10 + - @backstage/plugin-catalog-import@0.8.1 + - @backstage/plugin-home@0.4.14 + - @backstage/app-defaults@0.1.7 + - @backstage/integration-react@0.1.21 + - @backstage/plugin-airbrake@0.1.3 + - @backstage/plugin-apache-airflow@0.1.6 + - @backstage/plugin-api-docs@0.7.2 + - @backstage/plugin-azure-devops@0.1.14 + - @backstage/plugin-badges@0.2.22 + - @backstage/plugin-circleci@0.2.37 + - @backstage/plugin-cloudbuild@0.2.35 + - @backstage/plugin-code-coverage@0.1.25 + - @backstage/plugin-cost-insights@0.11.20 + - @backstage/plugin-explore@0.3.29 + - @backstage/plugin-gcp-projects@0.3.17 + - @backstage/plugin-github-actions@0.4.35 + - @backstage/plugin-gocd@0.1.4 + - @backstage/plugin-graphiql@0.2.30 + - @backstage/plugin-jenkins@0.5.20 + - @backstage/plugin-kafka@0.2.28 + - @backstage/plugin-kubernetes@0.5.7 + - @backstage/plugin-lighthouse@0.2.37 + - @backstage/plugin-newrelic@0.3.16 + - @backstage/plugin-pagerduty@0.3.25 + - @backstage/plugin-rollbar@0.3.26 + - @backstage/plugin-sentry@0.3.36 + - @backstage/plugin-shortcuts@0.1.22 + - @backstage/plugin-tech-insights@0.1.8 + - @backstage/plugin-tech-radar@0.5.5 + - @backstage/plugin-techdocs@0.13.3 + - @backstage/plugin-user-settings@0.3.19 + ## 0.2.64-next.0 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index f566c7e583..bdade7974a 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,56 +1,56 @@ { "name": "example-app", - "version": "0.2.64-next.0", + "version": "0.2.64", "private": true, "bundled": true, "dependencies": { - "@backstage/app-defaults": "^0.1.7-next.0", + "@backstage/app-defaults": "^0.1.7", "@backstage/catalog-model": "^0.9.10", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/integration-react": "^0.1.21-next.0", - "@backstage/plugin-airbrake": "^0.1.3-next.0", - "@backstage/plugin-api-docs": "^0.7.2-next.0", - "@backstage/plugin-azure-devops": "^0.1.14-next.0", - "@backstage/plugin-apache-airflow": "^0.1.6-next.0", - "@backstage/plugin-badges": "^0.2.22-next.0", - "@backstage/plugin-catalog": "^0.7.12-next.0", + "@backstage/integration-react": "^0.1.21", + "@backstage/plugin-airbrake": "^0.1.3", + "@backstage/plugin-api-docs": "^0.7.2", + "@backstage/plugin-azure-devops": "^0.1.14", + "@backstage/plugin-apache-airflow": "^0.1.6", + "@backstage/plugin-badges": "^0.2.22", + "@backstage/plugin-catalog": "^0.7.12", "@backstage/plugin-catalog-common": "^0.1.2", - "@backstage/plugin-catalog-graph": "^0.2.10-next.0", - "@backstage/plugin-catalog-import": "^0.8.1-next.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", - "@backstage/plugin-circleci": "^0.2.37-next.0", - "@backstage/plugin-cloudbuild": "^0.2.35-next.0", - "@backstage/plugin-code-coverage": "^0.1.25-next.0", - "@backstage/plugin-cost-insights": "^0.11.20-next.0", - "@backstage/plugin-explore": "^0.3.29-next.0", - "@backstage/plugin-gcp-projects": "^0.3.17-next.0", - "@backstage/plugin-github-actions": "^0.4.35-next.0", - "@backstage/plugin-gocd": "^0.1.4-next.0", - "@backstage/plugin-graphiql": "^0.2.30-next.0", - "@backstage/plugin-home": "^0.4.14-next.0", - "@backstage/plugin-jenkins": "^0.5.20-next.0", - "@backstage/plugin-kafka": "^0.2.28-next.0", - "@backstage/plugin-kubernetes": "^0.5.7-next.0", - "@backstage/plugin-lighthouse": "^0.2.37-next.0", - "@backstage/plugin-newrelic": "^0.3.16-next.0", - "@backstage/plugin-newrelic-dashboard": "^0.1.6-next.0", + "@backstage/plugin-catalog-graph": "^0.2.10", + "@backstage/plugin-catalog-import": "^0.8.1", + "@backstage/plugin-catalog-react": "^0.6.14", + "@backstage/plugin-circleci": "^0.2.37", + "@backstage/plugin-cloudbuild": "^0.2.35", + "@backstage/plugin-code-coverage": "^0.1.25", + "@backstage/plugin-cost-insights": "^0.11.20", + "@backstage/plugin-explore": "^0.3.29", + "@backstage/plugin-gcp-projects": "^0.3.17", + "@backstage/plugin-github-actions": "^0.4.35", + "@backstage/plugin-gocd": "^0.1.4", + "@backstage/plugin-graphiql": "^0.2.30", + "@backstage/plugin-home": "^0.4.14", + "@backstage/plugin-jenkins": "^0.5.20", + "@backstage/plugin-kafka": "^0.2.28", + "@backstage/plugin-kubernetes": "^0.5.7", + "@backstage/plugin-lighthouse": "^0.2.37", + "@backstage/plugin-newrelic": "^0.3.16", + "@backstage/plugin-newrelic-dashboard": "^0.1.6", "@backstage/plugin-org": "^0.4.2-next.0", - "@backstage/plugin-pagerduty": "0.3.25-next.0", + "@backstage/plugin-pagerduty": "0.3.25", "@backstage/plugin-permission-react": "^0.3.0", - "@backstage/plugin-rollbar": "^0.3.26-next.0", - "@backstage/plugin-scaffolder": "^0.12.2-next.0", - "@backstage/plugin-search": "^0.6.2-next.0", - "@backstage/plugin-sentry": "^0.3.36-next.0", - "@backstage/plugin-shortcuts": "^0.1.22-next.0", - "@backstage/plugin-tech-radar": "^0.5.5-next.0", - "@backstage/plugin-techdocs": "^0.13.3-next.0", - "@backstage/plugin-todo": "^0.2.0-next.0", - "@backstage/plugin-user-settings": "^0.3.19-next.0", + "@backstage/plugin-rollbar": "^0.3.26", + "@backstage/plugin-scaffolder": "^0.12.2", + "@backstage/plugin-search": "^0.6.2", + "@backstage/plugin-sentry": "^0.3.36", + "@backstage/plugin-shortcuts": "^0.1.22", + "@backstage/plugin-tech-radar": "^0.5.5", + "@backstage/plugin-techdocs": "^0.13.3", + "@backstage/plugin-todo": "^0.2.0", + "@backstage/plugin-user-settings": "^0.3.19", "@backstage/search-common": "^0.2.2", - "@backstage/plugin-tech-insights": "^0.1.8-next.0", + "@backstage/plugin-tech-insights": "^0.1.8", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 9331c737ad..2e80c62c92 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-common +## 0.10.7 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- 599f3dfa83: chore(deps-dev): bump `@types/concat-stream` from 1.6.1 to 2.0.0 +- c3868458d8: Removed unnecessary `get-port` dependency +- 04398e946e: Bump `selfsigned` to 2.0.0 + ## 0.10.7-next.0 ### Patch Changes diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index e22fef3778..738f8da464 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.10.7-next.0", + "version": "0.10.7", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -84,7 +84,7 @@ } }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/test-utils": "^0.2.4", "@types/archiver": "^5.1.0", "@types/compression": "^1.7.0", diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index ab6003a284..d611ee8ac1 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/backend-tasks +## 0.1.6 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.1.6-next.0 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index ad5a892a3d..364f1d1380 100644 --- a/packages/backend-tasks/package.json +++ b/packages/backend-tasks/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-tasks", "description": "Common distributed task management library for Backstage backends", - "version": "0.1.6-next.0", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", "@backstage/types": "^0.1.1", @@ -43,8 +43,8 @@ "zod": "^3.9.5" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.17-next.0", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/backend-test-utils": "^0.1.17", + "@backstage/cli": "^0.13.2", "jest": "^26.0.1", "wait-for-expect": "^3.0.2" }, diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 69d80b7088..55fb3c94cd 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/backend-test-utils +## 0.1.17 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- Updated dependencies + - @backstage/cli@0.13.2 + - @backstage/backend-common@0.10.7 + ## 0.1.17-next.0 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 59fbbc3879..8a9767b292 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-test-utils", "description": "Test helpers library for Backstage backends", - "version": "0.1.17-next.0", + "version": "0.1.17", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -30,8 +30,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/backend-common": "^0.10.7", + "@backstage/cli": "^0.13.2", "@backstage/config": "^0.1.13", "@vscode/sqlite3": "^5.0.7", "knex": "^1.0.2", @@ -41,7 +41,7 @@ "uuid": "^8.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "jest": "^26.0.1" }, "files": [ diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 17e7c4c668..d68ec80469 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,39 @@ # example-backend +## 0.2.64 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/plugin-auth-backend@0.10.0 + - @backstage/backend-common@0.10.7 + - @backstage/backend-tasks@0.1.6 + - @backstage/plugin-app-backend@0.3.24 + - @backstage/plugin-catalog-backend@0.21.3 + - @backstage/plugin-code-coverage-backend@0.1.22 + - @backstage/plugin-scaffolder-backend@0.15.24 + - @backstage/plugin-search-backend-module-pg@0.2.6 + - @backstage/plugin-tech-insights-backend@0.2.4 + - @backstage/plugin-techdocs-backend@0.13.3 + - @backstage/plugin-auth-node@0.1.0 + - @backstage/plugin-permission-backend@0.4.3 + - @backstage/plugin-search-backend@0.4.2 + - @backstage/plugin-badges-backend@0.1.18 + - @backstage/plugin-jenkins-backend@0.1.13 + - @backstage/plugin-todo-backend@0.1.21 + - @backstage/plugin-permission-node@0.4.3 + - example-app@0.2.64 + - @backstage/plugin-azure-devops-backend@0.3.3 + - @backstage/plugin-graphql-backend@0.1.14 + - @backstage/plugin-kafka-backend@0.2.17 + - @backstage/plugin-kubernetes-backend@0.4.7 + - @backstage/plugin-proxy-backend@0.2.18 + - @backstage/plugin-rollbar-backend@0.1.21 + - @backstage/plugin-scaffolder-backend-module-rails@0.2.6 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.8 + - @backstage/plugin-tech-insights-node@0.2.2 + ## 0.2.64-next.0 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 1c709195b0..35b234aeda 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.64-next.0", + "version": "0.2.64", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,39 +24,39 @@ "migrate:create": "knex migrate:make -x ts" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/backend-tasks": "^0.1.6-next.0", - "@backstage/catalog-client": "^0.5.5", + "@backstage/backend-common": "^0.10.7", + "@backstage/backend-tasks": "^0.1.6", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/integration": "^0.7.2", - "@backstage/plugin-app-backend": "^0.3.24-next.0", - "@backstage/plugin-auth-backend": "^0.10.0-next.0", - "@backstage/plugin-auth-node": "^0.0.0", - "@backstage/plugin-azure-devops-backend": "^0.3.3-next.0", - "@backstage/plugin-badges-backend": "^0.1.18-next.0", - "@backstage/plugin-catalog-backend": "^0.21.3-next.0", - "@backstage/plugin-code-coverage-backend": "^0.1.22-next.0", - "@backstage/plugin-graphql-backend": "^0.1.14-next.0", - "@backstage/plugin-jenkins-backend": "^0.1.13-next.0", - "@backstage/plugin-kubernetes-backend": "^0.4.7-next.0", - "@backstage/plugin-kafka-backend": "^0.2.17-next.0", - "@backstage/plugin-permission-backend": "^0.4.3-next.0", + "@backstage/plugin-app-backend": "^0.3.24", + "@backstage/plugin-auth-backend": "^0.10.0", + "@backstage/plugin-auth-node": "^0.1.0", + "@backstage/plugin-azure-devops-backend": "^0.3.3", + "@backstage/plugin-badges-backend": "^0.1.18", + "@backstage/plugin-catalog-backend": "^0.21.3", + "@backstage/plugin-code-coverage-backend": "^0.1.22", + "@backstage/plugin-graphql-backend": "^0.1.14", + "@backstage/plugin-jenkins-backend": "^0.1.13", + "@backstage/plugin-kubernetes-backend": "^0.4.7", + "@backstage/plugin-kafka-backend": "^0.2.17", + "@backstage/plugin-permission-backend": "^0.4.3", "@backstage/plugin-permission-common": "^0.4.0", - "@backstage/plugin-permission-node": "^0.4.3-next.0", - "@backstage/plugin-proxy-backend": "^0.2.18-next.0", - "@backstage/plugin-rollbar-backend": "^0.1.21-next.0", - "@backstage/plugin-scaffolder-backend": "^0.15.24-next.0", - "@backstage/plugin-scaffolder-backend-module-rails": "^0.2.6-next.0", - "@backstage/plugin-search-backend": "^0.4.2-next.0", + "@backstage/plugin-permission-node": "^0.4.3", + "@backstage/plugin-proxy-backend": "^0.2.18", + "@backstage/plugin-rollbar-backend": "^0.1.21", + "@backstage/plugin-scaffolder-backend": "^0.15.24", + "@backstage/plugin-scaffolder-backend-module-rails": "^0.2.6", + "@backstage/plugin-search-backend": "^0.4.2", "@backstage/plugin-search-backend-node": "^0.4.5", "@backstage/plugin-search-backend-module-elasticsearch": "^0.0.8", - "@backstage/plugin-search-backend-module-pg": "^0.2.6-next.0", - "@backstage/plugin-techdocs-backend": "^0.13.3-next.0", - "@backstage/plugin-tech-insights-backend": "^0.2.4-next.0", - "@backstage/plugin-tech-insights-node": "^0.2.2-next.0", - "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.8-next.0", - "@backstage/plugin-todo-backend": "^0.1.21-next.0", + "@backstage/plugin-search-backend-module-pg": "^0.2.6", + "@backstage/plugin-techdocs-backend": "^0.13.3", + "@backstage/plugin-tech-insights-backend": "^0.2.4", + "@backstage/plugin-tech-insights-node": "^0.2.2", + "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.8", + "@backstage/plugin-todo-backend": "^0.1.21", "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^18.5.3", "@vscode/sqlite3": "^5.0.7", @@ -73,7 +73,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/dockerode": "^3.3.0", "@types/express": "^4.17.6", "@types/express-serve-static-core": "^4.17.5" diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index 81bc155bbc..664e7a49ed 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/catalog-client +## 0.6.0 + +### Minor Changes + +- f8633307c4: Fixed the return type of the catalog API `getEntityAncestors`, to match the + actual server response shape. + + While this technically is a breaking change, the old shape has never worked at + all if you tried to use it - so treating this as an immediately-shipped breaking + bug fix. + ## 0.5.5 ### Patch Changes diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index 7e7cceb64e..c5489240a5 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/catalog-client", "description": "An isomorphic client for the catalog backend", - "version": "0.5.5", + "version": "0.6.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,7 +35,7 @@ "cross-fetch": "^3.0.6" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/jest": "^26.0.7", "msw": "^0.35.0" }, diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 7477d758e7..37bea1e016 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/cli +## 0.13.2 + +### Patch Changes + +- bbbaa8ed61: The `plugin:diff` command no longer validates the existence of any of the files within `dev/` or `src/`. +- eaf67f0578: Introduced initial support for an experimental `backstage.role` field in package.json, as well as experimental and hidden `migrate` and `script` sub-commands. We do not recommend usage of any of these additions yet. +- aeb5c69abb: Introduces a new `--release` parameter to the `backstage-cli versions:bump` command. + The release can be either a specific version, for example `0.99.1`, or the latest `main` or `next` release. + The default behavior is to bump to the latest `main` release. +- d59b90852a: The experimental types build enabled by `--experimental-type-build` now runs in a separate worker thread. +- 50a19ff8dd: The file path printed by the default lint formatter is now relative to the repository root, rather than the individual package. +- 63181dee79: Tweaked frontend bundling configuration to avoid leaking declarations into global scope. +- fae2aee878: Removed the `import/no-duplicates` lint rule from the frontend and backend ESLint configurations. This rule is quite expensive to execute and only provides a purely cosmetic benefit, so we opted to remove it from the set of default rules. If you would like to keep this rule you can add it back in your local ESLint configuration: + + ```js + 'import/no-duplicates': 'warn' + ``` + +- b906f98119: Rather than calling `yarn pack`, the `build-workspace` and `backend-bundle` commands now move files directly whenever possible. This cuts out several `yarn` invocations and speeds the packing process up by several orders of magnitude. +- d0c71e2aa4: Switched the `lint` command to invoke ESLint directly through its Node.js API rather than spawning a new process. +- d59b90852a: Introduced an experimental and hidden `repo` sub-command, that contains commands that operate on an entire monorepo rather than individual packages. +- Updated dependencies + - @backstage/release-manifests@0.0.1 + ## 0.13.2-next.0 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 4f1eccc3a0..589ac58646 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.13.2-next.0", + "version": "0.13.2", "private": false, "publishConfig": { "access": "public" @@ -32,7 +32,7 @@ "@backstage/config": "^0.1.13", "@backstage/config-loader": "^0.9.3", "@backstage/errors": "^0.2.0", - "@backstage/release-manifests": "^0.0.0", + "@backstage/release-manifests": "^0.0.1", "@backstage/types": "^0.1.1", "@hot-loader/react-dom": "^16.13.0", "@manypkg/get-packages": "^1.1.3", @@ -118,12 +118,12 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@backstage/theme": "^0.2.14", "@types/diff": "^5.0.0", diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index 02a1b2ca74..c7283f5d8c 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/codemods +## 0.1.33 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.1.33-next.0 ### Patch Changes diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 0681a13287..dc1fe6a537 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/codemods", "description": "A collection of codemods for Backstage projects", - "version": "0.1.33-next.0", + "version": "0.1.33", "private": false, "publishConfig": { "access": "public", diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index c6b2f87bc8..fe51935ab0 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/core-components +## 0.8.8 + +### Patch Changes + +- 8d785a0b1b: chore: bump `ansi-regex` from `5.0.1` to `6.0.1` +- f2dfbd3fb0: Adjust ErrorPage to accept optional supportUrl property to override app support config. Update type of additionalInfo property to be ReactNode to accept both string and component. +- 19155e0939: Updated React component type declarations to avoid exporting exotic component types. +- 89c84b9108: chore: fixing typescript errors for `TabbedCard.tsx` for React 17.x +- d62bdb7a8e: The `ErrorPage` now falls back to using the default support configuration if the `ConfigApi` is not available. + ## 0.8.8-next.0 ### Patch Changes diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 6b31998d16..6e4fc33362 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-components", "description": "Core components used by Backstage plugins and apps", - "version": "0.8.8-next.0", + "version": "0.8.8", "private": false, "publishConfig": { "access": "public", @@ -74,7 +74,7 @@ }, "devDependencies": { "@backstage/core-app-api": "^0.5.2", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index da2f05008b..886d873740 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,75 @@ # @backstage/create-app +## 0.4.19 + +### Patch Changes + +- 22f4ecb0e6: Switched the `file:` dependency for a `link:` dependency in the `backend` package. This makes sure that the `app` package is linked in rather than copied. + + To apply this update to an existing app, make the following change to `packages/backend/package.json`: + + ```diff + "dependencies": { + - "app": "file:../app", + + "app": "link:../app", + "@backstage/backend-common": "^{{version '@backstage/backend-common'}}", + ``` + +- 1dd5a02e91: **BREAKING:** Updated `knex` to major version 1, which also implies changing out + the underlying `sqlite` implementation. + + The old `sqlite3` NPM library has been abandoned by its maintainers, which has + led to unhandled security reports and other issues. Therefore, in the `knex` 1.x + release line they have instead switched over to the [`@vscode/sqlite3` + library](https://github.com/microsoft/vscode-node-sqlite3) by default, which is + actively maintained by Microsoft. + + This means that as you update to this version of Backstage, there are two + breaking changes that you will have to address in your own repository: + + ## Bumping `knex` itself + + All `package.json` files of your repo that used to depend on a 0.x version of + `knex`, should now be updated to depend on the 1.x release line. This applies in + particular to `packages/backend`, but may also occur in backend plugins or + libraries. + + ```diff + - "knex": "^0.95.1", + + "knex": "^1.0.2", + ``` + + Almost all existing database code will continue to function without modification + after this bump. The only significant difference that we discovered in the main + repo, is that the `alter()` function had a slightly different signature in + migration files. It now accepts an object with `alterType` and `alterNullable` + fields that clarify a previous grey area such that the intent of the alteration + is made explicit. This is caught by `tsc` and your editor if you are using the + `@ts-check` and `@param` syntax in your migration files + ([example](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend/migrations/20220116144621_remove_legacy.js#L17)), + which we strongly recommend. + + See the [`knex` documentation](https://knexjs.org/#Schema-alter) for more + information about the `alter` syntax. + + Also see the [`knex` changelog](https://knexjs.org/#changelog) for information + about breaking changes in the 1.x line; if you are using `RETURNING` you may + want to make some additional modifications in your code. + + ## Switching out `sqlite3` + + All `package.json` files of your repo that used to depend on `sqlite3`, should + now be updated to depend on `@vscode/sqlite3`. This applies in particular to + `packages/backend`, but may also occur in backend plugins or libraries. + + ```diff + - "sqlite3": "^5.0.1", + + "@vscode/sqlite3": "^5.0.7", + ``` + + These should be functionally equivalent, except that the new library will have + addressed some long standing problems with old transitive dependencies etc. + ## 0.4.19-next.0 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index c1cbf008ae..991a241887 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "A CLI that helps you create your own Backstage app", - "version": "0.4.19-next.0", + "version": "0.4.19", "private": false, "publishConfig": { "access": "public" diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index ef8acb7ba0..8061f5fb98 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/dev-utils +## 0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/app-defaults@0.1.7 + - @backstage/integration-react@0.1.21 + ## 0.2.21-next.0 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index bc86b7736b..9d55d17592 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "0.2.21-next.0", + "version": "0.2.21", "private": false, "publishConfig": { "access": "public", @@ -29,13 +29,13 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/app-defaults": "^0.1.7-next.0", + "@backstage/app-defaults": "^0.1.7", "@backstage/core-app-api": "^0.5.2", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/catalog-model": "^0.9.10", - "@backstage/integration-react": "^0.1.21-next.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/integration-react": "^0.1.21", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/test-utils": "^0.2.4", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -55,7 +55,7 @@ "react-dom": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/jest": "^26.0.7", "@types/node": "^14.14.32" }, diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index 303625f03f..ec0457dc1e 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/integration-react +## 0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.1.21-next.0 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index 3ca522ba66..06d0645a4b 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration-react", "description": "Frontend package for managing integrations towards external systems", - "version": "0.1.21-next.0", + "version": "0.1.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,7 +22,7 @@ }, "dependencies": { "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/integration": "^0.7.2", "@backstage/theme": "^0.2.14", @@ -35,8 +35,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/cli": "^0.13.2", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/packages/release-manifests/CHANGELOG.md b/packages/release-manifests/CHANGELOG.md index 3aac6c8e6a..61e6c45992 100644 --- a/packages/release-manifests/CHANGELOG.md +++ b/packages/release-manifests/CHANGELOG.md @@ -1 +1,8 @@ # @backstage/release-manifests + +## 0.0.1 + +### Patch Changes + +- aeb5c69abb: Introduces a new package with utilities for fetching release manifests. + This package will primarily be used by the `@backstage/cli` package. diff --git a/packages/release-manifests/package.json b/packages/release-manifests/package.json index 405896f50b..7ac2a7431f 100644 --- a/packages/release-manifests/package.json +++ b/packages/release-manifests/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/release-manifests", "description": "Helper library for receiving release manifests", - "version": "0.0.0", + "version": "0.0.1", "private": false, "main": "src/index.ts", "types": "src/index.ts", diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index df0af06a30..38726ce10e 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,17 @@ # techdocs-cli-embedded-app +## 0.2.63 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.13.2 + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog@0.7.12 + - @backstage/app-defaults@0.1.7 + - @backstage/integration-react@0.1.21 + - @backstage/plugin-techdocs@0.13.3 + ## 0.2.63-next.0 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index c5e25f1bc7..975bfef43b 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,19 +1,19 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.63-next.0", + "version": "0.2.63", "private": true, "bundled": true, "dependencies": { - "@backstage/app-defaults": "^0.1.7-next.0", + "@backstage/app-defaults": "^0.1.7", "@backstage/catalog-model": "^0.9.10", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/config": "^0.1.13", "@backstage/core-app-api": "^0.5.2", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/integration-react": "^0.1.21-next.0", - "@backstage/plugin-catalog": "^0.7.12-next.0", - "@backstage/plugin-techdocs": "^0.13.3-next.0", + "@backstage/integration-react": "^0.1.21", + "@backstage/plugin-catalog": "^0.7.12", + "@backstage/plugin-techdocs": "^0.13.3", "@backstage/test-utils": "^0.2.4", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.11.0", @@ -26,7 +26,7 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^13.1.8", diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 51841ecb95..98015f766a 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,14 @@ # @techdocs/cli +## 0.8.13 + +### Patch Changes + +- b70c186194: Updated the HTTP server to allow for simplification of the development of the CLI itself. +- Updated dependencies + - @backstage/backend-common@0.10.7 + - @backstage/techdocs-common@0.11.7 + ## 0.8.13-next.0 ### Patch Changes diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index e2cba36070..19514b63d2 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,7 +1,7 @@ { "name": "@techdocs/cli", "description": "Utility CLI for managing TechDocs sites in Backstage.", - "version": "0.8.13-next.0", + "version": "0.8.13", "private": false, "publishConfig": { "access": "public" @@ -33,7 +33,7 @@ "techdocs-cli": "bin/techdocs-cli" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/commander": "^2.12.2", "@types/fs-extra": "^9.0.6", "@types/http-proxy": "^1.17.4", @@ -56,11 +56,11 @@ "ext": "ts" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/catalog-model": "^0.9.10", "@backstage/cli-common": "^0.1.6", "@backstage/config": "^0.1.13", - "@backstage/techdocs-common": "^0.11.7-next.0", + "@backstage/techdocs-common": "^0.11.7", "@types/dockerode": "^3.3.0", "commander": "^6.1.0", "dockerode": "^3.3.1", diff --git a/packages/techdocs-common/CHANGELOG.md b/packages/techdocs-common/CHANGELOG.md index fea44fdcae..44fbec4171 100644 --- a/packages/techdocs-common/CHANGELOG.md +++ b/packages/techdocs-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/techdocs-common +## 0.11.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.11.7-next.0 ### Patch Changes diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json index 805af7fd31..f45f842100 100644 --- a/packages/techdocs-common/package.json +++ b/packages/techdocs-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/techdocs-common", "description": "Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "0.11.7-next.0", + "version": "0.11.7", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -38,7 +38,7 @@ "dependencies": { "@azure/identity": "^2.0.1", "@azure/storage-blob": "^12.5.0", - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", @@ -60,7 +60,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/fs-extra": "^9.0.5", "@types/js-yaml": "^4.0.0", "@types/mime-types": "^2.1.0", diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md index d254c80018..df784d0030 100644 --- a/plugins/airbrake/CHANGELOG.md +++ b/plugins/airbrake/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-airbrake +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.1.3-next.0 ### Patch Changes diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index 778e951000..e8a1207de1 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake", - "version": "0.1.3-next.0", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,7 +20,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -34,10 +34,10 @@ }, "devDependencies": { "@types/object-hash": "^2.2.1", - "@backstage/app-defaults": "^0.1.7-next.0", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/app-defaults": "^0.1.7", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md index 99493c727f..9f5d2cc730 100644 --- a/plugins/allure/CHANGELOG.md +++ b/plugins/allure/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-allure +## 0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.1.14-next.0 ### Patch Changes diff --git a/plugins/allure/package.json b/plugins/allure/package.json index eb325d7d85..790f3e5cc6 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-allure", "description": "A Backstage plugin that integrates with Allure", - "version": "0.1.14-next.0", + "version": "0.1.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,9 +23,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -37,9 +37,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md index de25fd0b33..e24ea89a0a 100644 --- a/plugins/analytics-module-ga/CHANGELOG.md +++ b/plugins/analytics-module-ga/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-analytics-module-ga +## 0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.1.9-next.0 ### Patch Changes diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index c72155762e..bf34760f58 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga", - "version": "0.1.9-next.0", + "version": "0.1.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,7 +22,7 @@ }, "dependencies": { "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -35,9 +35,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md index 514040fb05..03bef4543a 100644 --- a/plugins/apache-airflow/CHANGELOG.md +++ b/plugins/apache-airflow/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-apache-airflow +## 0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.1.6-next.0 ### Patch Changes diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index aa179fd5e4..7feb701f32 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apache-airflow", - "version": "0.1.6-next.0", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,7 +20,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -33,9 +33,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index 88003f24d4..73de279056 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-api-docs +## 0.7.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/plugin-catalog@0.7.12 + ## 0.7.2-next.0 ### Patch Changes diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 3752b16d9a..da7f6f90f4 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-api-docs", "description": "A Backstage plugin that helps represent API entities in the frontend", - "version": "0.7.2-next.0", + "version": "0.7.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,10 +32,10 @@ "dependencies": { "@asyncapi/react-component": "1.0.0-next.32", "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog": "^0.7.12-next.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog": "^0.7.12", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -53,9 +53,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index de3662d4cc..882979326e 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-app-backend +## 0.3.24 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.3.24-next.0 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index 5a2ddcb57d..52da00fed3 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-backend", "description": "A Backstage backend plugin that serves the Backstage frontend app", - "version": "0.3.24-next.0", + "version": "0.3.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,7 +30,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config-loader": "^0.9.3", "@backstage/config": "^0.1.13", "@backstage/types": "^0.1.1", @@ -47,8 +47,8 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.17-next.0", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/backend-test-utils": "^0.1.17", + "@backstage/cli": "^0.13.2", "@backstage/types": "^0.1.1", "@types/supertest": "^2.0.8", "mock-fs": "^5.1.0", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 5ed7c8b268..a19153c4e9 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,71 @@ # @backstage/plugin-auth-backend +## 0.10.0 + +### Minor Changes + +- 08fcda13ef: The `callbackUrl` option of `OAuthAdapter` is now required. +- 6bc86fcf2d: The following breaking changes were made, which may imply specifically needing + to make small adjustments in your custom auth providers. + + - **BREAKING**: Moved `IdentityClient`, `BackstageSignInResult`, + `BackstageIdentityResponse`, and `BackstageUserIdentity` to + `@backstage/plugin-auth-node`. + - **BREAKING**: Removed deprecated type `BackstageIdentity`, please use + `BackstageSignInResult` from `@backstage/plugin-auth-node` instead. + + While moving over, `IdentityClient` was also changed in the following ways: + + - **BREAKING**: Made `IdentityClient.listPublicKeys` private. It was only used + in tests, and should not be part of the API surface of that class. + - **BREAKING**: Removed the static `IdentityClient.getBearerToken`. It is now + replaced by `getBearerTokenFromAuthorizationHeader` from + `@backstage/plugin-auth-node`. + - **BREAKING**: Removed the constructor. Please use the `IdentityClient.create` + static method instead. + + Since the `IdentityClient` interface is marked as experimental, this is a + breaking change without a deprecation period. + + In your auth providers, you may need to update your imports and usages as + follows (example code; yours may be slightly different): + + ````diff + -import { IdentityClient } from '@backstage/plugin-auth-backend'; + +import { + + IdentityClient, + + getBearerTokenFromAuthorizationHeader + +} from '@backstage/plugin-auth-node'; + + // ... + + - const identity = new IdentityClient({ + + const identity = IdentityClient.create({ + discovery, + issuer: await discovery.getExternalBaseUrl('auth'), + });``` + + // ... + + const token = + - IdentityClient.getBearerToken(req.headers.authorization) || + + getBearerTokenFromAuthorizationHeader(req.headers.authorization) || + req.cookies['token']; + ```` + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- 3396bc5973: Enabled refresh for the Atlassian provider. +- 08fcda13ef: Added a new `cookieConfigurer` option to `AuthProviderConfig` that makes it possible to override the default logic for configuring OAuth provider cookies. +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/backend-common@0.10.7 + - @backstage/plugin-auth-node@0.1.0 + ## 0.10.0-next.0 ### Minor Changes diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 4f2ef4e76c..171fb25dea 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend", "description": "A Backstage backend plugin that handles authentication", - "version": "0.10.0-next.0", + "version": "0.10.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,9 +30,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/plugin-auth-node": "^0.0.0", - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/catalog-client": "^0.5.5", + "@backstage/plugin-auth-node": "^0.1.0", + "@backstage/backend-common": "^0.10.7", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", @@ -74,7 +74,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/test-utils": "^0.2.4", "@types/body-parser": "^1.19.0", "@types/cookie-parser": "^1.4.2", diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md new file mode 100644 index 0000000000..a5103ea034 --- /dev/null +++ b/plugins/auth-node/CHANGELOG.md @@ -0,0 +1,13 @@ +# @backstage/plugin-auth-node + +## 0.1.0 + +### Minor Changes + +- 9058bb1b5e: Added this package, to hold shared types and functionality that other backend + packages need to import. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index cec1006ef0..f997cb0b48 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.0.0", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -19,7 +19,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", @@ -28,7 +28,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "msw": "^0.35.0", "uuid": "^8.0.0" }, diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md index 4503707449..0b44be4e13 100644 --- a/plugins/azure-devops-backend/CHANGELOG.md +++ b/plugins/azure-devops-backend/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-azure-devops-backend +## 0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.3.3-next.0 ### Patch Changes diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index ea1a566ef6..a87a48046e 100644 --- a/plugins/azure-devops-backend/package.json +++ b/plugins/azure-devops-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops-backend", - "version": "0.3.3-next.0", + "version": "0.3.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,7 +20,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", "@backstage/plugin-azure-devops-common": "^0.2.0", "@types/express": "^4.17.6", @@ -32,7 +32,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/supertest": "^2.0.8", "supertest": "^6.1.6", "msw": "^0.35.0" diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md index da4a88e9df..8b0331e75d 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-azure-devops +## 0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.1.14-next.0 ### Patch Changes diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index d1520e5a95..f3734f0518 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.1.14-next.0", + "version": "0.1.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,11 +28,11 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", "@backstage/plugin-azure-devops-common": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -46,9 +46,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md index 8ceec5c2b3..f025515703 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-badges-backend +## 0.1.18 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/backend-common@0.10.7 + ## 0.1.18-next.0 ### Patch Changes diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index c3622ddbbd..b5fc38f289 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges-backend", "description": "A Backstage backend plugin that generates README badges for your entities", - "version": "0.1.18-next.0", + "version": "0.1.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,8 +31,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/catalog-client": "^0.5.5", + "@backstage/backend-common": "^0.10.7", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", @@ -45,7 +45,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md index 8f98786de0..8f2a3b2e84 100644 --- a/plugins/badges/CHANGELOG.md +++ b/plugins/badges/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-badges +## 0.2.22 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.2.22-next.0 ### Patch Changes diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 8ff59c2e4a..ba60c6d1fb 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges", "description": "A Backstage plugin that generates README badges for your entities", - "version": "0.2.22-next.0", + "version": "0.2.22", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,10 +28,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -43,9 +43,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md index f04c64aac0..fdd63ff59b 100644 --- a/plugins/bazaar-backend/CHANGELOG.md +++ b/plugins/bazaar-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-bazaar-backend +## 0.1.9 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- Updated dependencies + - @backstage/backend-common@0.10.7 + - @backstage/backend-test-utils@0.1.17 + ## 0.1.9-next.0 ### Patch Changes diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 17bc7687a9..71980acea4 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar-backend", - "version": "0.1.9-next.0", + "version": "0.1.9", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,8 +20,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/backend-test-utils": "^0.1.17-next.0", + "@backstage/backend-common": "^0.10.7", + "@backstage/backend-test-utils": "^0.1.17", "@backstage/config": "^0.1.13", "@types/express": "^4.17.6", "express": "^4.17.1", @@ -31,7 +31,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0" + "@backstage/cli": "^0.13.2" }, "files": [ "dist", diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md index 6b7389abd1..00f7605888 100644 --- a/plugins/bazaar/CHANGELOG.md +++ b/plugins/bazaar/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-bazaar +## 0.1.13 + +### Patch Changes + +- d674971d3a: Rolling back the `@date-io/luxon` bump as this broke both packages, and we need it for `@material-ui/pickers` +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/cli@0.13.2 + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/plugin-catalog@0.7.12 + ## 0.1.13-next.0 ### Patch Changes diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index a82e23034f..5bf6a2f580 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar", - "version": "0.1.13-next.0", + "version": "0.1.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,13 +21,13 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-client": "^0.5.5", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", - "@backstage/cli": "^0.13.2-next.0", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/cli": "^0.13.2", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog": "^0.7.12-next.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog": "^0.7.12", + "@backstage/plugin-catalog-react": "^0.6.14", "@date-io/luxon": "1.x", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -44,8 +44,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/cli": "^0.13.2", + "@backstage/dev-utils": "^0.2.21", "@testing-library/jest-dom": "^5.10.1", "cross-fetch": "^3.0.6" }, diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md index 12fa3af075..3fc26f7da7 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-bitrise +## 0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.1.25-next.0 ### Patch Changes diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 423324aff1..422ddad743 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitrise", "description": "A Backstage plugin that integrates towards Bitrise", - "version": "0.1.25-next.0", + "version": "0.1.25", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,9 +22,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -40,9 +40,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 3249009447..55162c6003 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@0.21.3 + ## 0.3.12-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index 89f1a33cb2..a499049265 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", "description": "A Backstage catalog backend modules that helps integrate towards LDAP", - "version": "0.3.12-next.0", + "version": "0.3.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-backend": "^0.21.3-next.0", + "@backstage/plugin-catalog-backend": "^0.21.3", "@backstage/types": "^0.1.1", "@types/ldapjs": "^2.2.0", "ldapjs": "^2.2.0", @@ -40,7 +40,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/lodash": "^4.14.151" }, "files": [ diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index 521626bdfe..847fbae9d4 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.2.15 + +### Patch Changes + +- 9b122a780c: Add userExpand option to allow users to expand fields retrieved from the Graph API - for use in custom transformers +- 7bb1bde7f6: Minor API cleanups +- Updated dependencies + - @backstage/plugin-catalog-backend@0.21.3 + ## 0.2.15-next.0 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 87e47402bf..928e16be85 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", "description": "A Backstage catalog backend modules that helps integrate towards Microsoft Graph", - "version": "0.2.15-next.0", + "version": "0.2.15", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ "@azure/msal-node": "^1.1.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", - "@backstage/plugin-catalog-backend": "^0.21.3-next.0", + "@backstage/plugin-catalog-backend": "^0.21.3", "@microsoft/microsoft-graph-types": "^2.6.0", "@types/node-fetch": "^2.5.12", "lodash": "^4.17.21", @@ -42,8 +42,8 @@ "qs": "^6.9.4" }, "devDependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/backend-common": "^0.10.7", + "@backstage/cli": "^0.13.2", "@backstage/test-utils": "^0.2.4", "@types/lodash": "^4.14.151", "msw": "^0.35.0" diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 64390b43c7..a371712c80 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-backend +## 0.21.3 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/backend-common@0.10.7 + - @backstage/plugin-permission-node@0.4.3 + ## 0.21.3-next.0 ### Patch Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 22751c9214..7443be73af 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend", "description": "The Backstage backend plugin that provides the Backstage catalog", - "version": "0.21.3-next.0", + "version": "0.21.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,15 +30,15 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/catalog-client": "^0.5.5", + "@backstage/backend-common": "^0.10.7", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", "@backstage/integration": "^0.7.2", "@backstage/plugin-catalog-common": "^0.1.2", "@backstage/plugin-permission-common": "^0.4.0", - "@backstage/plugin-permission-node": "^0.4.3-next.0", + "@backstage/plugin-permission-node": "^0.4.3", "@backstage/search-common": "^0.2.2", "@backstage/types": "^0.1.1", "@octokit/graphql": "^4.5.8", @@ -65,8 +65,8 @@ "yup": "^0.32.9" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.17-next.0", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/backend-test-utils": "^0.1.17", + "@backstage/cli": "^0.13.2", "@backstage/plugin-permission-common": "^0.4.0", "@backstage/test-utils": "^0.2.4", "@types/core-js": "^2.5.4", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index 67d950ba87..0bb6e7224a 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-catalog-graph +## 0.2.10 + +### Patch Changes + +- 7bb1bde7f6: Minor API cleanups +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.2.10-next.0 ### Patch Changes diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index b8b155af13..541d21f319 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.2.10-next.0", + "version": "0.2.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,11 +21,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-client": "^0.5.5", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -42,9 +42,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index a5ee312bbb..8c86fd4ca2 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-catalog-import +## 0.8.1 + +### Patch Changes + +- 7bb1bde7f6: Minor API cleanups +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/integration-react@0.1.21 + ## 0.8.1-next.0 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index b86893350c..4a407607d1 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-import", "description": "A Backstage plugin the helps you import entities into your catalog", - "version": "0.8.1-next.0", + "version": "0.8.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,15 +31,15 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-client": "^0.5.5", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/config": "^0.1.13", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", "@backstage/integration": "^0.7.2", - "@backstage/integration-react": "^0.1.21-next.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/integration-react": "^0.1.21", + "@backstage/plugin-catalog-react": "^0.6.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -57,9 +57,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 27a43bdb94..65fd275389 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog-react +## 0.6.14 + +### Patch Changes + +- 680e7c7452: Updated `useEntityListProvider` and catalog pickers to respond to external changes to query parameters in the URL, such as two sidebar links that apply different catalog filters. +- f8633307c4: Added an "inspect" entry in the entity three-dots menu, for lower level catalog + insights and debugging. +- 19155e0939: Updated React component type declarations to avoid exporting exotic component types. +- 7bb1bde7f6: Minor API cleanups +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/core-components@0.8.8 + ## 0.6.14-next.0 ### Patch Changes diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 2084745f1e..14c90bbc97 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-react", "description": "A frontend library that helps other Backstage plugins interact with the catalog", - "version": "0.6.14-next.0", + "version": "0.6.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,9 +29,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-client": "^0.5.5", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", "@backstage/integration": "^0.7.2", @@ -56,7 +56,7 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", "@backstage/plugin-catalog-common": "^0.1.2", "@backstage/test-utils": "^0.2.4", diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index a6a5f6112f..cb13e27bd0 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-catalog +## 0.7.12 + +### Patch Changes + +- f8633307c4: Added an "inspect" entry in the entity three-dots menu, for lower level catalog + insights and debugging. +- 9033775d39: Deprecated the `EntityPageLayout`; please use the new extension based `CatalogEntityPage` instead +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/integration-react@0.1.21 + ## 0.7.12-next.0 ### Patch Changes diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index f42a949550..38a86134d0 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog", "description": "The Backstage plugin for browsing the Backstage catalog", - "version": "0.7.12-next.0", + "version": "0.7.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,14 +31,14 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-client": "^0.5.5", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/integration-react": "^0.1.21-next.0", + "@backstage/integration-react": "^0.1.21", "@backstage/plugin-catalog-common": "^0.1.2", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -54,9 +54,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/plugin-permission-react": "^0.3.0", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", diff --git a/plugins/cicd-statistics/CHANGELOG.md b/plugins/cicd-statistics/CHANGELOG.md new file mode 100644 index 0000000000..7258ea0570 --- /dev/null +++ b/plugins/cicd-statistics/CHANGELOG.md @@ -0,0 +1,12 @@ +# @backstage/plugin-cicd-statistics + +## 0.1.0 + +### Minor Changes + +- 770c195f34: Added new plugin "CI/CD Statistics" which charts pipeline build durations over time + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@0.6.14 diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 1c4d8a455e..de221887c8 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics", "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", - "version": "0.0.0", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,7 +35,7 @@ "dependencies": { "@backstage/catalog-model": "^0.9.8", "@backstage/core-plugin-api": "^0.4.1", - "@backstage/plugin-catalog-react": "^0.6.9", + "@backstage/plugin-catalog-react": "^0.6.14", "@date-io/luxon": "^1.3.13", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.11.2", diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md index 5e7eb264f3..fcd6237d70 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-circleci +## 0.2.37 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.2.37-next.0 ### Patch Changes diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index cd9821e92d..cc6987a232 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-circleci", "description": "A Backstage plugin that integrates towards Circle CI", - "version": "0.2.37-next.0", + "version": "0.2.37", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,9 +33,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -52,9 +52,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md index 05bccd2e59..8a434df33d 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-cloudbuild +## 0.2.35 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.2.35-next.0 ### Patch Changes diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index c5278cb0f0..ea9c233b56 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cloudbuild", "description": "A Backstage plugin that integrates towards Google Cloud Build", - "version": "0.2.35-next.0", + "version": "0.2.35", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -49,9 +49,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index 80335d8a71..5e0bbb0c0f 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-code-coverage-backend +## 0.1.22 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/backend-common@0.10.7 + ## 0.1.22-next.0 ### Patch Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 977c1559cf..c5c77f9873 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage-backend", "description": "A Backstage backend plugin that helps you keep track of your code coverage", - "version": "0.1.22-next.0", + "version": "0.1.22", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,8 +20,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/catalog-client": "^0.5.5", + "@backstage/backend-common": "^0.10.7", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", @@ -36,7 +36,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/express-xml-bodyparser": "^0.3.2", "@types/supertest": "^2.0.8", "msw": "^0.35.0", diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md index 00c93b22a3..2fc3acda84 100644 --- a/plugins/code-coverage/CHANGELOG.md +++ b/plugins/code-coverage/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-code-coverage +## 0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.1.25-next.0 ### Patch Changes diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index 366c35406f..99bde5764e 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage", "description": "A Backstage plugin that helps you keep track of your code coverage", - "version": "0.1.25-next.0", + "version": "0.1.25", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,10 +23,10 @@ "dependencies": { "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -43,9 +43,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index ecbe9f569a..a8b6f14292 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-config-schema +## 0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.1.21-next.0 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index fc0db012d7..374d1ca3e8 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-config-schema", "description": "A Backstage plugin that lets you browse the configuration schema of your app", - "version": "0.1.21-next.0", + "version": "0.1.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,7 +22,7 @@ }, "dependencies": { "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", "@backstage/theme": "^0.2.14", @@ -38,9 +38,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index 3f29655334..e1f3caf8ec 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-cost-insights +## 0.11.20 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.11.20-next.0 ### Patch Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 1a4b171f00..34c74569d2 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cost-insights", "description": "A Backstage plugin that helps you keep track of your cloud spend", - "version": "0.11.20-next.0", + "version": "0.11.20", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,7 +33,7 @@ "dependencies": { "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -57,9 +57,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index 106f4cae80..d417976d1c 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-explore +## 0.3.29 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.3.29-next.0 ### Patch Changes diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 6664ccf469..41857f7707 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore", "description": "A Backstage plugin for building an exploration page of your software ecosystem", - "version": "0.3.29-next.0", + "version": "0.3.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/plugin-explore-react": "^0.0.11", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -50,9 +50,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/firehydrant/CHANGELOG.md b/plugins/firehydrant/CHANGELOG.md index 9d58796e0d..e446663842 100644 --- a/plugins/firehydrant/CHANGELOG.md +++ b/plugins/firehydrant/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-firehydrant +## 0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.1.15-next.0 ### Patch Changes diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index ef03bf3d23..54d3df3887 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-firehydrant", "description": "A Backstage plugin that integrates towards FireHydrant", - "version": "0.1.15-next.0", + "version": "0.1.15", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,9 +22,9 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -36,9 +36,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index f4ca3b1f1d..6e42e95021 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-fossa +## 0.2.30 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.2.30-next.0 ### Patch Changes diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index 9cc704c328..02364da0fe 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-fossa", "description": "A Backstage plugin that integrates towards FOSSA", - "version": "0.2.30-next.0", + "version": "0.2.30", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,10 +33,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -50,9 +50,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/gcp-projects/CHANGELOG.md b/plugins/gcp-projects/CHANGELOG.md index 1e7d0986fa..80761a4736 100644 --- a/plugins/gcp-projects/CHANGELOG.md +++ b/plugins/gcp-projects/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-gcp-projects +## 0.3.17 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.3.17-next.0 ### Patch Changes diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 75d0b84610..122326072a 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gcp-projects", "description": "A Backstage plugin that helps you manage projects in GCP", - "version": "0.3.17-next.0", + "version": "0.3.17", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -44,9 +44,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/git-release-manager/CHANGELOG.md b/plugins/git-release-manager/CHANGELOG.md index 8b757816c2..db988dbc9b 100644 --- a/plugins/git-release-manager/CHANGELOG.md +++ b/plugins/git-release-manager/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-git-release-manager +## 0.3.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.3.11-next.0 ### Patch Changes diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index fd82254f26..cea9a210a0 100644 --- a/plugins/git-release-manager/package.json +++ b/plugins/git-release-manager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-git-release-manager", "description": "A Backstage plugin that helps you manage releases in git", - "version": "0.3.11-next.0", + "version": "0.3.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,7 +21,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/integration": "^0.7.2", "@backstage/theme": "^0.2.14", @@ -40,9 +40,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 9e987f4d4a..2399292e8d 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-github-actions +## 0.4.35 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.4.35-next.0 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index fc0817fbc2..a984b03b1d 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-actions", "description": "A Backstage plugin that integrates towards GitHub Actions", - "version": "0.4.35-next.0", + "version": "0.4.35", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,10 +34,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/integration": "^0.7.2", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -52,9 +52,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index 5fbb45e7d7..8bcaa8287f 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-github-deployments +## 0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/integration-react@0.1.21 + ## 0.1.29-next.0 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 8f7e9acef3..e6379cbaff 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-deployments", "description": "A Backstage plugin that integrates towards GitHub Deployments", - "version": "0.1.29-next.0", + "version": "0.1.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,12 +22,12 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", "@backstage/integration": "^0.7.2", - "@backstage/integration-react": "^0.1.21-next.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/integration-react": "^0.1.21", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -40,9 +40,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/gitops-profiles/CHANGELOG.md b/plugins/gitops-profiles/CHANGELOG.md index 35666459eb..edf8bec0ae 100644 --- a/plugins/gitops-profiles/CHANGELOG.md +++ b/plugins/gitops-profiles/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-gitops-profiles +## 0.3.16 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.3.16-next.0 ### Patch Changes diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index 212c68c8e4..16f2843928 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gitops-profiles", "description": "A Backstage plugin that helps you manage GitOps profiles", - "version": "0.3.16-next.0", + "version": "0.3.16", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -45,9 +45,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/gocd/CHANGELOG.md b/plugins/gocd/CHANGELOG.md index 589da1c7a6..b2e5024fea 100644 --- a/plugins/gocd/CHANGELOG.md +++ b/plugins/gocd/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-gocd +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.1.4-next.0 ### Patch Changes diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index 3f3f8674e7..e7b348d64d 100644 --- a/plugins/gocd/package.json +++ b/plugins/gocd/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gocd", "description": "A Backstage plugin that integrates towards GoCD", - "version": "0.1.4-next.0", + "version": "0.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,10 +29,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -46,9 +46,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/graphiql/CHANGELOG.md b/plugins/graphiql/CHANGELOG.md index c3f5a1512f..da7919fb5e 100644 --- a/plugins/graphiql/CHANGELOG.md +++ b/plugins/graphiql/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-graphiql +## 0.2.30 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.2.30-next.0 ### Patch Changes diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index cf90a45c29..1f071013e0 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphiql", "description": "Backstage plugin for browsing GraphQL APIs", - "version": "0.2.30-next.0", + "version": "0.2.30", "private": false, "publishConfig": { "access": "public", @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -45,9 +45,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/graphql-backend/CHANGELOG.md b/plugins/graphql-backend/CHANGELOG.md index 514837ef65..749ced2527 100644 --- a/plugins/graphql-backend/CHANGELOG.md +++ b/plugins/graphql-backend/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-graphql-backend +## 0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.1.14-next.0 ### Patch Changes diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json index 61d8069ff3..a13a901646 100644 --- a/plugins/graphql-backend/package.json +++ b/plugins/graphql-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphql-backend", "description": "An experimental Backstage backend plugin for GraphQL", - "version": "0.1.14-next.0", + "version": "0.1.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", "@backstage/plugin-catalog-graphql": "^0.3.1", "@graphql-tools/schema": "^8.3.1", @@ -48,7 +48,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/supertest": "^2.0.8", "eslint-plugin-graphql": "^4.0.0", "msw": "^0.35.0", diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index 16a5d9fece..d0c0a5bb44 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-home +## 0.4.14 + +### Patch Changes + +- a4a777441d: Adds new StarredEntities component responsible for rendering a list of starred entities on the home page +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-search@0.6.2 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.4.14-next.0 ### Patch Changes diff --git a/plugins/home/package.json b/plugins/home/package.json index 09df9ff510..c641611eed 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-home", "description": "A Backstage plugin that helps you build a home page", - "version": "0.4.14-next.0", + "version": "0.4.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,10 +22,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", - "@backstage/plugin-search": "^0.6.2-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", + "@backstage/plugin-search": "^0.6.2", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -39,9 +39,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/ilert/CHANGELOG.md b/plugins/ilert/CHANGELOG.md index 8c17078dbe..099110e39f 100644 --- a/plugins/ilert/CHANGELOG.md +++ b/plugins/ilert/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-ilert +## 0.1.24 + +### Patch Changes + +- d674971d3a: Rolling back the `@date-io/luxon` bump as this broke both packages, and we need it for `@material-ui/pickers` +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.1.24-next.0 ### Patch Changes diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index 3ea25b9414..e8fb2540c4 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-ilert", "description": "A Backstage plugin that integrates towards iLert", - "version": "0.1.24-next.0", + "version": "0.1.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,10 +22,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@date-io/luxon": "1.x", "@material-ui/core": "^4.12.2", @@ -40,9 +40,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/jenkins-backend/CHANGELOG.md b/plugins/jenkins-backend/CHANGELOG.md index c02c0fc0ea..17fd3da85a 100644 --- a/plugins/jenkins-backend/CHANGELOG.md +++ b/plugins/jenkins-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-jenkins-backend +## 0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/backend-common@0.10.7 + ## 0.1.13-next.0 ### Patch Changes diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index a4a8d1f192..52e8862fae 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins-backend", "description": "A Backstage backend plugin that integrates towards Jenkins", - "version": "0.1.13-next.0", + "version": "0.1.13", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,8 +22,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/catalog-client": "^0.5.5", + "@backstage/backend-common": "^0.10.7", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@types/express": "^4.17.6", @@ -34,7 +34,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/jenkins": "^0.23.1", "@types/supertest": "^2.0.8", "msw": "^0.35.0", diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index 9bebccacb2..8611c9d2b7 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-jenkins +## 0.5.20 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.5.20-next.0 ### Patch Changes diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index ee4106b465..7e5f0a78fb 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins", "description": "A Backstage plugin that integrates towards Jenkins", - "version": "0.5.20-next.0", + "version": "0.5.20", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,10 +33,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -50,9 +50,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md index 34b93cc78a..cd80463672 100644 --- a/plugins/kafka-backend/CHANGELOG.md +++ b/plugins/kafka-backend/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-kafka-backend +## 0.2.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.2.17-next.0 ### Patch Changes diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index 4e46200e63..01b23ba696 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka-backend", "description": "A Backstage backend plugin that integrates towards Kafka", - "version": "0.2.17-next.0", + "version": "0.2.17", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", @@ -44,7 +44,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/jest-when": "^2.7.2", "@types/lodash": "^4.14.151", "jest-when": "^3.1.0", diff --git a/plugins/kafka/CHANGELOG.md b/plugins/kafka/CHANGELOG.md index 4ccbcdd080..e73c3a6efb 100644 --- a/plugins/kafka/CHANGELOG.md +++ b/plugins/kafka/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-kafka +## 0.2.28 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.2.28-next.0 ### Patch Changes diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index 8ec2caf171..a93fc658db 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka", "description": "A Backstage plugin that integrates towards Kafka", - "version": "0.2.28-next.0", + "version": "0.2.28", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,9 +22,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -36,9 +36,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index 5ab8b2eaee..457e17e989 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-kubernetes-backend +## 0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.4.7-next.0 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index e9b5639e72..feb6a4defd 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-backend", "description": "A Backstage backend plugin that integrates towards Kubernetes", - "version": "0.4.7-next.0", + "version": "0.4.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", @@ -55,7 +55,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/aws4": "^1.5.1", "supertest": "^6.1.3", "aws-sdk-mock": "^5.2.1", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index dabebfce4e..33abbb9255 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-kubernetes +## 0.5.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.5.7-next.0 ### Patch Changes diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index 23087d7d61..01a68bb322 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes", "description": "A Backstage plugin that integrates towards Kubernetes", - "version": "0.5.7-next.0", + "version": "0.5.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,9 +33,9 @@ "dependencies": { "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/plugin-kubernetes-common": "^0.2.2", "@kubernetes/client-node": "^0.16.0", "@backstage/theme": "^0.2.14", @@ -53,9 +53,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md index d2a0325f0e..541861b519 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-lighthouse +## 0.2.37 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.2.37-next.0 ### Patch Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index 6e3a0902f2..99ca2b1ec1 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse", "description": "A Backstage plugin that integrates towards Lighthouse", - "version": "0.2.37-next.0", + "version": "0.2.37", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,9 +34,9 @@ "dependencies": { "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -48,9 +48,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/newrelic-dashboard/CHANGELOG.md b/plugins/newrelic-dashboard/CHANGELOG.md index 918fcb266b..e1101d2369 100644 --- a/plugins/newrelic-dashboard/CHANGELOG.md +++ b/plugins/newrelic-dashboard/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-newrelic-dashboard +## 0.1.6 + +### Patch Changes + +- 5ca42462b7: Export DashboardSnapshotComponent from new-relic-dashboard-plugin +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.1.6-next.0 ### Patch Changes diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json index 2c22afde40..1ab1841b90 100644 --- a/plugins/newrelic-dashboard/package.json +++ b/plugins/newrelic-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-newrelic-dashboard", - "version": "0.1.6-next.0", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,18 +21,18 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/cli": "^0.13.2", + "@backstage/dev-utils": "^0.2.21", "@testing-library/jest-dom": "^5.10.1", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.0.6" diff --git a/plugins/newrelic/CHANGELOG.md b/plugins/newrelic/CHANGELOG.md index 306aa16bbe..821de4582a 100644 --- a/plugins/newrelic/CHANGELOG.md +++ b/plugins/newrelic/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-newrelic +## 0.3.16 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.3.16-next.0 ### Patch Changes diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index a249c08949..5580d597cc 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-newrelic", "description": "A Backstage plugin that integrates towards New Relic", - "version": "0.3.16-next.0", + "version": "0.3.16", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -44,9 +44,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/org/package.json b/plugins/org/package.json index d05bd15bb3..b5f06e5856 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -22,9 +22,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -39,10 +39,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/catalog-client": "^0.5.5", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/catalog-client": "^0.6.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md index 78feb5bf08..6fbcfc54b1 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-pagerduty +## 0.3.25 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.3.25-next.0 ### Patch Changes diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index af627e4152..c68876d20e 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-pagerduty", "description": "A Backstage plugin that integrates towards PagerDuty", - "version": "0.3.25-next.0", + "version": "0.3.25", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -49,9 +49,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index ec68631956..58ace0ff17 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-permission-backend +## 0.4.3 + +### Patch Changes + +- b3f3e42036: Use `getBearerTokenFromAuthorizationHeader` from `@backstage/plugin-auth-node` instead of the deprecated `IdentityClient` method. +- Updated dependencies + - @backstage/backend-common@0.10.7 + - @backstage/plugin-auth-node@0.1.0 + - @backstage/plugin-permission-node@0.4.3 + ## 0.4.3-next.0 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 01efa7af04..26622cf8e2 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend", - "version": "0.4.3-next.0", + "version": "0.4.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -19,12 +19,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", - "@backstage/plugin-auth-node": "^0.0.0", + "@backstage/plugin-auth-node": "^0.1.0", "@backstage/plugin-permission-common": "^0.4.0", - "@backstage/plugin-permission-node": "^0.4.3-next.0", + "@backstage/plugin-permission-node": "^0.4.3", "@types/express": "*", "dataloader": "^2.0.0", "express": "^4.17.1", @@ -36,7 +36,7 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/lodash": "^4.14.151", "@types/supertest": "^2.0.8", "supertest": "^6.1.6", diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index eb70f997ed..d79c79159f 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-permission-node +## 0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + - @backstage/plugin-auth-node@0.1.0 + ## 0.4.3-next.0 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index 7977e9057f..04a567f16b 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-node", "description": "Common permission and authorization utilities for backend plugins", - "version": "0.4.3-next.0", + "version": "0.4.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,10 +29,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", - "@backstage/plugin-auth-node": "^0.0.0", + "@backstage/plugin-auth-node": "^0.1.0", "@backstage/plugin-permission-common": "^0.4.0", "@types/express": "^4.17.6", "express": "^4.17.1", @@ -40,7 +40,7 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/supertest": "^2.0.8", "msw": "^0.35.0", "supertest": "^6.1.3" diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index 7d15c7fbad..7460eddd5a 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-proxy-backend +## 0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.2.18-next.0 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 406e82c100..5336bbb098 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-proxy-backend", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", - "version": "0.2.18-next.0", + "version": "0.2.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,7 +29,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", "@types/express": "^4.17.6", "express": "^4.17.1", @@ -43,7 +43,7 @@ "yup": "^0.32.9" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/http-proxy-middleware": "^0.19.3", "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md index 473dbe97a2..14e566219a 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-rollbar-backend +## 0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.1.21-next.0 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 4039aab295..06b7f93b4e 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar-backend", "description": "A Backstage backend plugin that integrates towards Rollbar", - "version": "0.1.21-next.0", + "version": "0.1.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", "@types/express": "^4.17.6", "camelcase-keys": "^7.0.1", @@ -48,7 +48,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/test-utils": "^0.2.4", "@types/supertest": "^2.0.8", "msw": "^0.36.3", diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md index 7cd8b4c8f2..df1cb19f83 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-rollbar +## 0.3.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.3.26-next.0 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index ab0e453448..29ea636d1e 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar", "description": "A Backstage plugin that integrates towards Rollbar", - "version": "0.3.26-next.0", + "version": "0.3.26", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,9 +33,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -50,9 +50,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 70f9e24222..29ff4e9edb 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + - @backstage/plugin-scaffolder-backend@0.15.24 + ## 0.1.11-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index fb22c8a308..cee138b576 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", - "version": "0.1.11-next.0", + "version": "0.1.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,10 +20,10 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/errors": "^0.2.0", "@backstage/integration": "^0.7.2", - "@backstage/plugin-scaffolder-backend": "^0.15.24-next.0", + "@backstage/plugin-scaffolder-backend": "^0.15.24", "@backstage/config": "^0.1.13", "@backstage/types": "^0.1.1", "command-exists": "^1.2.9", @@ -32,7 +32,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/fs-extra": "^9.0.1", "@types/mock-fs": "^4.13.0", "@types/jest": "^26.0.7", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index cf406064de..2b369835f8 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + - @backstage/plugin-scaffolder-backend@0.15.24 + ## 0.2.6-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index ef7d17193f..5f32dbadd8 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", "description": "A module for the scaffolder backend that lets you template projects using Rails", - "version": "0.2.6-next.0", + "version": "0.2.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,8 +21,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/plugin-scaffolder-backend": "^0.15.24-next.0", + "@backstage/backend-common": "^0.10.7", + "@backstage/plugin-scaffolder-backend": "^0.15.24", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", "@backstage/integration": "^0.7.2", @@ -31,7 +31,7 @@ "fs-extra": "^9.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/jest": "^26.0.7", "@types/node": "^14.14.32", "@types/command-exists": "^1.2.0", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index c41384fbda..8c5a6ade44 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@0.15.24 + ## 0.1.5-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index bb949075b3..a49898be1c 100644 --- a/plugins/scaffolder-backend-module-yeoman/package.json +++ b/plugins/scaffolder-backend-module-yeoman/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-yeoman", - "version": "0.1.5-next.0", + "version": "0.1.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,13 +21,13 @@ }, "dependencies": { "@backstage/config": "^0.1.13", - "@backstage/plugin-scaffolder-backend": "^0.15.24-next.0", + "@backstage/plugin-scaffolder-backend": "^0.15.24", "@backstage/types": "^0.1.1", "winston": "^3.2.1", "yeoman-environment": "^3.6.0" }, "devDependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@types/jest": "^26.0.7" }, "files": [ diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index 6650e75757..7c80464d71 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-scaffolder-backend +## 0.15.24 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- 2bd5f24043: fix for the `gitlab:publish` action to use the `oauthToken` key when creating a + `Gitlab` client. This only happens if `ctx.input.token` is provided else the key `token` will be used. +- 898a56578c: Bump `vm2` to version 3.9.6 +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/backend-common@0.10.7 + - @backstage/plugin-catalog-backend@0.21.3 + - @backstage/plugin-scaffolder-backend-module-cookiecutter@0.1.11 + ## 0.15.24-next.0 ### Patch Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 240ec98753..983c27b07a 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend", "description": "The Backstage backend plugin that helps you create new things", - "version": "0.15.24-next.0", + "version": "0.15.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,15 +31,15 @@ "build:assets": "node scripts/build-nunjucks.js" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/catalog-client": "^0.5.5", + "@backstage/backend-common": "^0.10.7", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", "@backstage/integration": "^0.7.2", - "@backstage/plugin-catalog-backend": "^0.21.3-next.0", + "@backstage/plugin-catalog-backend": "^0.21.3", "@backstage/plugin-scaffolder-common": "^0.1.3", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.11-next.0", + "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.11", "@backstage/types": "^0.1.1", "@gitbeaker/core": "^34.6.0", "@gitbeaker/node": "^35.1.0", @@ -73,7 +73,7 @@ "vm2": "^3.9.6" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/test-utils": "^0.2.4", "@types/command-exists": "^1.2.0", "@types/fs-extra": "^9.0.1", diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index ae767c34b5..dd7674a21b 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-scaffolder +## 0.12.2 + +### Patch Changes + +- 33e139e652: Adds a loading bar to the scaffolder task page if the task is still loading. This can happen if it takes a while for a task worker to pick up a task. +- 6458be3307: Encode the `formData` in the `queryString` using `JSON.stringify` to keep the types in the decoded value +- 319f4b79a2: The ScaffolderPage can be passed an optional `TaskPageComponent` with a `loadingText` string. It will replace the Loading text in the scaffolder task page. +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/integration-react@0.1.21 + ## 0.12.2-next.0 ### Patch Changes diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index a7cd81affb..568a5b29c3 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder", "description": "The Backstage plugin that helps you create new things", - "version": "0.12.2-next.0", + "version": "0.12.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,16 +31,16 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/catalog-client": "^0.5.5", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", "@backstage/integration": "^0.7.2", - "@backstage/integration-react": "^0.1.21-next.0", + "@backstage/integration-react": "^0.1.21", "@backstage/plugin-catalog-common": "^0.1.2", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/plugin-permission-react": "^0.3.0", "@backstage/plugin-scaffolder-common": "^0.1.3", "@backstage/theme": "^0.2.14", @@ -69,10 +69,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", - "@backstage/plugin-catalog": "^0.7.12-next.0", + "@backstage/dev-utils": "^0.2.21", + "@backstage/plugin-catalog": "^0.7.12", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index 1934eec38f..c0b1f6778d 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-search-backend-module-pg +## 0.2.6 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.2.6-next.0 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 4681213644..392b9af73a 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-pg", "description": "A module for the search backend that implements search using PostgreSQL", - "version": "0.2.6-next.0", + "version": "0.2.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,15 +20,15 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/search-common": "^0.2.2", "@backstage/plugin-search-backend-node": "^0.4.5", "lodash": "^4.17.21", "knex": "^1.0.2" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.17-next.0", - "@backstage/cli": "^0.13.2-next.0" + "@backstage/backend-test-utils": "^0.1.17", + "@backstage/cli": "^0.13.2" }, "files": [ "dist", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index 8c69c711e3..218615c66b 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-search-backend +## 0.4.2 + +### Patch Changes + +- b3f3e42036: Use `getBearerTokenFromAuthorizationHeader` from `@backstage/plugin-auth-node` instead of the deprecated `IdentityClient` method. +- Updated dependencies + - @backstage/backend-common@0.10.7 + - @backstage/plugin-auth-node@0.1.0 + - @backstage/plugin-permission-node@0.4.3 + ## 0.4.2-next.0 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 3770dbd875..117e484c62 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend", "description": "The Backstage backend plugin that provides your backstage app with search", - "version": "0.4.2-next.0", + "version": "0.4.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -20,13 +20,13 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", "@backstage/search-common": "^0.2.2", - "@backstage/plugin-auth-node": "^0.0.0", + "@backstage/plugin-auth-node": "^0.1.0", "@backstage/plugin-permission-common": "^0.4.0-next.0", - "@backstage/plugin-permission-node": "^0.4.3-next.0", + "@backstage/plugin-permission-node": "^0.4.3", "@backstage/plugin-search-backend-node": "^0.4.5", "@backstage/types": "^0.1.1", "@types/express": "^4.17.6", @@ -40,7 +40,7 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 2b42421811..bb4877b6da 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-search +## 0.6.2 + +### Patch Changes + +- faf49ba82f: Modify modal search to clamp result length to 5 rows. +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.6.2-next.0 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index e39f95183d..d2b5b58139 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search", "description": "The Backstage plugin that provides your backstage app with search", - "version": "0.6.2-next.0", + "version": "0.6.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,10 +32,10 @@ "dependencies": { "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/search-common": "^0.2.2", "@backstage/theme": "^0.2.14", "@backstage/types": "^0.1.1", @@ -53,9 +53,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index e281d651b8..5f87df9a3a 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-sentry +## 0.3.36 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.3.36-next.0 ### Patch Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index fbc6e1784e..0b24f05b6c 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sentry", "description": "A Backstage plugin that integrates towards Sentry", - "version": "0.3.36-next.0", + "version": "0.3.36", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,9 +33,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -49,9 +49,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md index e691540b1b..11bc03104a 100644 --- a/plugins/shortcuts/CHANGELOG.md +++ b/plugins/shortcuts/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-shortcuts +## 0.1.22 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.1.22-next.0 ### Patch Changes diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index bfcc14a439..5e97167c8f 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-shortcuts", "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", - "version": "0.1.22-next.0", + "version": "0.1.22", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,7 +21,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/theme": "^0.2.14", "@backstage/types": "^0.1.1", @@ -39,9 +39,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index b3939436e8..c0de393aab 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-sonarqube +## 0.2.16 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.2.16-next.0 ### Patch Changes diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index d71749b3ef..cb9bd40166 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sonarqube", "description": "", - "version": "0.2.16-next.0", + "version": "0.2.16", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,9 +34,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -50,9 +50,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md index 8393807dc9..badc0f06fc 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-splunk-on-call +## 0.3.22 + +### Patch Changes + +- c17be55ffb: Add Splunk On-Call plugin support for a `splunk.com/on-call-routing-key` annotation. If the `splunk.com/on-call-routing-key` is provided, the plugin displays a Splunk On-Call card for each of the teams associated with the routing key. +- 6c6d1c6439: Correct spelling of 'Acknowledge' in tooltip. +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.3.22-next.0 ### Patch Changes diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index 14d6a26b93..da7eaeb4e7 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-splunk-on-call", "description": "A Backstage plugin that integrates towards Splunk On-Call", - "version": "0.3.22-next.0", + "version": "0.3.22", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,9 +32,9 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -48,9 +48,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md index b5755c7fcf..3128854594 100644 --- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md +++ b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-tech-insights-backend-module-jsonfc +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + - @backstage/plugin-tech-insights-node@0.2.2 + ## 0.1.8-next.0 ### Patch Changes diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index 4e56ee53a1..fc2c6b7add 100644 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ b/plugins/tech-insights-backend-module-jsonfc/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", - "version": "0.1.8-next.0", + "version": "0.1.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,11 +31,11 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", "@backstage/plugin-tech-insights-common": "^0.2.1", - "@backstage/plugin-tech-insights-node": "^0.2.2-next.0", + "@backstage/plugin-tech-insights-node": "^0.2.2", "ajv": "^7.0.3", "json-rules-engine": "^6.1.2", "lodash": "^4.17.21", @@ -43,7 +43,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/node-cron": "^3.0.1" }, "files": [ diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md index 236716ee65..36e7aa97a1 100644 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ b/plugins/tech-insights-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-tech-insights-backend +## 0.2.4 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/backend-common@0.10.7 + - @backstage/plugin-tech-insights-node@0.2.2 + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index 7d350e2cbc..5a60e478d8 100644 --- a/plugins/tech-insights-backend/package.json +++ b/plugins/tech-insights-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend", - "version": "0.2.4-next.0", + "version": "0.2.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,13 +31,13 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/catalog-client": "^0.5.5", + "@backstage/backend-common": "^0.10.7", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", "@backstage/plugin-tech-insights-common": "^0.2.1", - "@backstage/plugin-tech-insights-node": "^0.2.2-next.0", + "@backstage/plugin-tech-insights-node": "^0.2.2", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -51,8 +51,8 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.17-next.0", - "@backstage/cli": "^0.13.2-next.0", + "@backstage/backend-test-utils": "^0.1.17", + "@backstage/cli": "^0.13.2", "@types/supertest": "^2.0.8", "@types/node-cron": "^3.0.0", "@types/semver": "^7.3.8", diff --git a/plugins/tech-insights-node/CHANGELOG.md b/plugins/tech-insights-node/CHANGELOG.md index fe02fd2b36..c38c36ecd9 100644 --- a/plugins/tech-insights-node/CHANGELOG.md +++ b/plugins/tech-insights-node/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-tech-insights-node +## 0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.7 + ## 0.2.2-next.0 ### Patch Changes diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index 5b880741d2..05c6f10071 100644 --- a/plugins/tech-insights-node/package.json +++ b/plugins/tech-insights-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-node", - "version": "0.2.2-next.0", + "version": "0.2.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,7 +30,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", + "@backstage/backend-common": "^0.10.7", "@backstage/config": "^0.1.13", "@backstage/plugin-tech-insights-common": "^0.2.1", "@types/luxon": "^2.0.5", @@ -38,7 +38,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0" + "@backstage/cli": "^0.13.2" }, "files": [ "dist" diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md index 82ca3653c6..af16d5f347 100644 --- a/plugins/tech-insights/CHANGELOG.md +++ b/plugins/tech-insights/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-tech-insights +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.1.8-next.0 ### Patch Changes diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index 54d6740584..ba57231eed 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights", - "version": "0.1.8-next.0", + "version": "0.1.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,10 +21,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/plugin-tech-insights-common": "^0.2.1", "@backstage/theme": "^0.2.14", "@backstage/types": "^0.1.1", @@ -39,9 +39,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index 1f035b700d..bafe2212cf 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-tech-radar +## 0.5.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.5.5-next.0 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 8fd20fc069..3c1e5a1fbc 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-tech-radar", "description": "A Backstage plugin that lets you display a Tech Radar for your organization", - "version": "0.5.5-next.0", + "version": "0.5.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ "start": "backstage-cli plugin:serve" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -46,9 +46,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 4439bf25a1..b05e8a6dad 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,18 @@ # @backstage/plugin-techdocs-backend +## 0.13.3 + +### Patch Changes + +- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 + + This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 + +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/backend-common@0.10.7 + - @backstage/techdocs-common@0.11.7 + ## 0.13.3-next.0 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 044880866e..0d494109fa 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-backend", "description": "The Backstage backend plugin that renders technical documentation for your components", - "version": "0.13.3-next.0", + "version": "0.13.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,15 +31,15 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/catalog-client": "^0.5.5", + "@backstage/backend-common": "^0.10.7", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", "@backstage/integration": "^0.7.2", "@backstage/plugin-catalog-common": "^0.1.2", "@backstage/search-common": "^0.2.2", - "@backstage/techdocs-common": "^0.11.7-next.0", + "@backstage/techdocs-common": "^0.11.7", "@types/express": "^4.17.6", "cross-fetch": "^3.0.6", "dockerode": "^3.3.1", @@ -53,7 +53,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/test-utils": "^0.2.4", "@types/dockerode": "^3.3.0", "msw": "^0.35.0", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index bdff088bf9..3ff8c0e175 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-techdocs +## 0.13.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-search@0.6.2 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/plugin-catalog@0.7.12 + - @backstage/integration-react@0.1.21 + ## 0.13.3-next.0 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 0f2338d19a..4721721a14 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs", "description": "The Backstage plugin that renders technical documentation for your components", - "version": "0.13.3-next.0", + "version": "0.13.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,14 +34,14 @@ "dependencies": { "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", "@backstage/integration": "^0.7.2", - "@backstage/integration-react": "^0.1.21-next.0", - "@backstage/plugin-catalog": "^0.7.12-next.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", - "@backstage/plugin-search": "^0.6.2-next.0", + "@backstage/integration-react": "^0.1.21", + "@backstage/plugin-catalog": "^0.7.12", + "@backstage/plugin-catalog-react": "^0.6.14", + "@backstage/plugin-search": "^0.6.2", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -62,9 +62,9 @@ "react-dom": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index ec73cb1a58..a5cb799a70 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-todo-backend +## 0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@0.6.0 + - @backstage/backend-common@0.10.7 + ## 0.1.21-next.0 ### Patch Changes diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index 309b70bd8d..3371dbbecc 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo-backend", "description": "A Backstage backend plugin that lets you browse TODO comments in your source code", - "version": "0.1.21-next.0", + "version": "0.1.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -25,8 +25,8 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/backend-common": "^0.10.7-next.0", - "@backstage/catalog-client": "^0.5.5", + "@backstage/backend-common": "^0.10.7", + "@backstage/catalog-client": "^0.6.0", "@backstage/catalog-model": "^0.9.10", "@backstage/config": "^0.1.13", "@backstage/errors": "^0.2.0", @@ -39,7 +39,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@types/supertest": "^2.0.8", "msw": "^0.35.0", "supertest": "^6.1.3" diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index 6080311b90..bec930df20 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-todo +## 0.2.0 + +### Minor Changes + +- 323f48704d: **BREAKING**: The `EntityTodoContent` is now a routable extension. This means it must be rendered within a route, but that's most likely already the case for most apps. The mount point `RouteRef` is available via `todoPlugin.routes.entityContent`. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-catalog-react@0.6.14 + ## 0.2.0-next.0 ### Minor Changes diff --git a/plugins/todo/package.json b/plugins/todo/package.json index 9623df973d..ea4ef83461 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo", "description": "A Backstage plugin that lets you browse TODO comments in your source code", - "version": "0.2.0-next.0", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,10 +28,10 @@ }, "dependencies": { "@backstage/catalog-model": "^0.9.10", - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", - "@backstage/plugin-catalog-react": "^0.6.14-next.0", + "@backstage/plugin-catalog-react": "^0.6.14", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -42,9 +42,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index d7205f70d7..423e978352 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-user-settings +## 0.3.19 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.3.19-next.0 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index a3da6821c9..61597c0cfe 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings", "description": "A Backstage plugin that provides a settings page", - "version": "0.3.19-next.0", + "version": "0.3.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -31,7 +31,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/theme": "^0.2.14", "@material-ui/core": "^4.12.2", @@ -44,9 +44,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md index 8b54ae9111..bcfbf2b88b 100644 --- a/plugins/xcmetrics/CHANGELOG.md +++ b/plugins/xcmetrics/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-xcmetrics +## 0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + ## 0.2.18-next.0 ### Patch Changes diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index e0e850e1e5..aa18880625 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-xcmetrics", "description": "A Backstage plugin that shows XCode build metrics for your components", - "version": "0.2.18-next.0", + "version": "0.2.18", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -21,7 +21,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "@backstage/core-components": "^0.8.8-next.0", + "@backstage/core-components": "^0.8.8", "@backstage/core-plugin-api": "^0.6.0", "@backstage/errors": "^0.2.0", "@backstage/theme": "^0.2.14", @@ -37,9 +37,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.13.2-next.0", + "@backstage/cli": "^0.13.2", "@backstage/core-app-api": "^0.5.2", - "@backstage/dev-utils": "^0.2.21-next.0", + "@backstage/dev-utils": "^0.2.21", "@backstage/test-utils": "^0.2.4", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^11.2.5", diff --git a/yarn.lock b/yarn.lock index 61b6e3f47c..fa52c146c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1366,49 +1366,6 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@backstage/core-components@*", "@backstage/core-components@^0.8.0", "@backstage/core-components@^0.8.7": - version "0.8.7" - resolved "https://registry.npmjs.org/@backstage/core-components/-/core-components-0.8.7.tgz#c4bb9760d57971882065415e6e715eb750db2392" - integrity sha512-77oIrnT5zV7vaE1MK+TTBzIt0GfqUifnNeieyBPm2uHctPt5Um0qG3+zR5UYGGcm1VWAZtNMzZIOBJUDgKPQjQ== - dependencies: - "@backstage/config" "^0.1.13" - "@backstage/core-plugin-api" "^0.6.0" - "@backstage/errors" "^0.2.0" - "@backstage/theme" "^0.2.14" - "@material-table/core" "^3.1.0" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.9.1" - "@material-ui/lab" "4.0.0-alpha.57" - "@types/react-sparklines" "^1.7.0" - "@types/react-text-truncate" "^0.14.0" - ansi-regex "^5.0.1" - classnames "^2.2.6" - d3-selection "^3.0.0" - d3-shape "^3.0.0" - d3-zoom "^3.0.0" - dagre "^0.8.5" - history "^5.0.0" - immer "^9.0.1" - lodash "^4.17.21" - pluralize "^8.0.0" - prop-types "^15.7.2" - qs "^6.9.4" - rc-progress "3.2.4" - react-helmet "6.1.0" - react-hook-form "^7.12.2" - react-markdown "^8.0.0" - react-router "6.0.0-beta.0" - react-router-dom "6.0.0-beta.0" - react-sparklines "^1.7.0" - react-syntax-highlighter "^15.4.5" - react-text-truncate "^0.17.0" - react-use "^17.2.4" - react-virtualized-auto-sizer "^1.0.6" - react-window "^1.8.6" - remark-gfm "^3.0.1" - zen-observable "^0.8.15" - zod "^3.11.6" - "@backstage/core-plugin-api@^0.4.0", "@backstage/core-plugin-api@^0.4.1": version "0.4.1" resolved "https://registry.npmjs.org/@backstage/core-plugin-api/-/core-plugin-api-0.4.1.tgz#c0a13504bdfa61ae3d0db96934cd6c32a7574446" @@ -1425,69 +1382,6 @@ react-use "^17.2.4" zen-observable "^0.8.15" -"@backstage/integration-react@^0.1.10", "@backstage/integration-react@^0.1.20": - version "0.1.20" - resolved "https://registry.npmjs.org/@backstage/integration-react/-/integration-react-0.1.20.tgz#53610c718f963018d16496aa345926740b4eb131" - integrity sha512-vX65MB+Xd51wFcG5PbRbDlxN9Ti7pIlklbWWXZrxpeyR9h9FsXjKIioeP8kKqOYRTUgfvLutnU2FrTL2tulGGw== - dependencies: - "@backstage/config" "^0.1.13" - "@backstage/core-components" "^0.8.7" - "@backstage/core-plugin-api" "^0.6.0" - "@backstage/integration" "^0.7.2" - "@backstage/theme" "^0.2.14" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.9.1" - "@material-ui/lab" "4.0.0-alpha.57" - react-use "^17.2.4" - -"@backstage/plugin-catalog-react@^0.6.13", "@backstage/plugin-catalog-react@^0.6.5", "@backstage/plugin-catalog-react@^0.6.9": - version "0.6.13" - resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-0.6.13.tgz#b325eae501d3edeb8b7caef5d9615f2e632f5430" - integrity sha512-XBwop7PwAZqfongx3KP6jAJar+MEscLSp8nLuHYX5XxA+suQNiBgi96uO3SEQmvtae+hvsRM7c0WHSxbYiXsDA== - dependencies: - "@backstage/catalog-client" "^0.5.5" - "@backstage/catalog-model" "^0.9.10" - "@backstage/core-components" "^0.8.7" - "@backstage/core-plugin-api" "^0.6.0" - "@backstage/errors" "^0.2.0" - "@backstage/integration" "^0.7.2" - "@backstage/plugin-permission-common" "^0.4.0" - "@backstage/plugin-permission-react" "^0.3.0" - "@backstage/types" "^0.1.1" - "@backstage/version-bridge" "^0.1.1" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.9.1" - "@material-ui/lab" "4.0.0-alpha.57" - jwt-decode "^3.1.0" - lodash "^4.17.21" - qs "^6.9.4" - react-router "6.0.0-beta.0" - react-use "^17.2.4" - zen-observable "^0.8.15" - -"@backstage/plugin-catalog@*": - version "0.7.11" - resolved "https://registry.npmjs.org/@backstage/plugin-catalog/-/plugin-catalog-0.7.11.tgz#9cd1d5c272300e4678a3e3ad7675b5b36aa51002" - integrity sha512-D9QohgQJZfRSrQ7aTuI6fH4tXBloEpyAC+WnXKoCjPaLm9gVbFEdBoC2+M6MiCybahJxdRK+LsNAG+jZj3ZdIg== - dependencies: - "@backstage/catalog-client" "^0.5.5" - "@backstage/catalog-model" "^0.9.10" - "@backstage/core-components" "^0.8.7" - "@backstage/core-plugin-api" "^0.6.0" - "@backstage/errors" "^0.2.0" - "@backstage/integration-react" "^0.1.20" - "@backstage/plugin-catalog-common" "^0.1.2" - "@backstage/plugin-catalog-react" "^0.6.13" - "@backstage/theme" "^0.2.14" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.9.1" - "@material-ui/lab" "4.0.0-alpha.57" - history "^5.0.0" - lodash "^4.17.21" - react-helmet "6.1.0" - react-router "6.0.0-beta.0" - react-use "^17.2.4" - "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -11634,54 +11528,54 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: safe-buffer "^5.1.1" "example-app@link:packages/app": - version "0.2.64-next.0" + version "0.2.64" dependencies: - "@backstage/app-defaults" "^0.1.7-next.0" + "@backstage/app-defaults" "^0.1.7" "@backstage/catalog-model" "^0.9.10" - "@backstage/cli" "^0.13.2-next.0" + "@backstage/cli" "^0.13.2" "@backstage/core-app-api" "^0.5.2" - "@backstage/core-components" "^0.8.8-next.0" + "@backstage/core-components" "^0.8.8" "@backstage/core-plugin-api" "^0.6.0" - "@backstage/integration-react" "^0.1.21-next.0" - "@backstage/plugin-airbrake" "^0.1.3-next.0" - "@backstage/plugin-apache-airflow" "^0.1.6-next.0" - "@backstage/plugin-api-docs" "^0.7.2-next.0" - "@backstage/plugin-azure-devops" "^0.1.14-next.0" - "@backstage/plugin-badges" "^0.2.22-next.0" - "@backstage/plugin-catalog" "^0.7.12-next.0" + "@backstage/integration-react" "^0.1.21" + "@backstage/plugin-airbrake" "^0.1.3" + "@backstage/plugin-apache-airflow" "^0.1.6" + "@backstage/plugin-api-docs" "^0.7.2" + "@backstage/plugin-azure-devops" "^0.1.14" + "@backstage/plugin-badges" "^0.2.22" + "@backstage/plugin-catalog" "^0.7.12" "@backstage/plugin-catalog-common" "^0.1.2" - "@backstage/plugin-catalog-graph" "^0.2.10-next.0" - "@backstage/plugin-catalog-import" "^0.8.1-next.0" - "@backstage/plugin-catalog-react" "^0.6.14-next.0" - "@backstage/plugin-circleci" "^0.2.37-next.0" - "@backstage/plugin-cloudbuild" "^0.2.35-next.0" - "@backstage/plugin-code-coverage" "^0.1.25-next.0" - "@backstage/plugin-cost-insights" "^0.11.20-next.0" - "@backstage/plugin-explore" "^0.3.29-next.0" - "@backstage/plugin-gcp-projects" "^0.3.17-next.0" - "@backstage/plugin-github-actions" "^0.4.35-next.0" - "@backstage/plugin-gocd" "^0.1.4-next.0" - "@backstage/plugin-graphiql" "^0.2.30-next.0" - "@backstage/plugin-home" "^0.4.14-next.0" - "@backstage/plugin-jenkins" "^0.5.20-next.0" - "@backstage/plugin-kafka" "^0.2.28-next.0" - "@backstage/plugin-kubernetes" "^0.5.7-next.0" - "@backstage/plugin-lighthouse" "^0.2.37-next.0" - "@backstage/plugin-newrelic" "^0.3.16-next.0" - "@backstage/plugin-newrelic-dashboard" "^0.1.6-next.0" + "@backstage/plugin-catalog-graph" "^0.2.10" + "@backstage/plugin-catalog-import" "^0.8.1" + "@backstage/plugin-catalog-react" "^0.6.14" + "@backstage/plugin-circleci" "^0.2.37" + "@backstage/plugin-cloudbuild" "^0.2.35" + "@backstage/plugin-code-coverage" "^0.1.25" + "@backstage/plugin-cost-insights" "^0.11.20" + "@backstage/plugin-explore" "^0.3.29" + "@backstage/plugin-gcp-projects" "^0.3.17" + "@backstage/plugin-github-actions" "^0.4.35" + "@backstage/plugin-gocd" "^0.1.4" + "@backstage/plugin-graphiql" "^0.2.30" + "@backstage/plugin-home" "^0.4.14" + "@backstage/plugin-jenkins" "^0.5.20" + "@backstage/plugin-kafka" "^0.2.28" + "@backstage/plugin-kubernetes" "^0.5.7" + "@backstage/plugin-lighthouse" "^0.2.37" + "@backstage/plugin-newrelic" "^0.3.16" + "@backstage/plugin-newrelic-dashboard" "^0.1.6" "@backstage/plugin-org" "^0.4.2-next.0" - "@backstage/plugin-pagerduty" "0.3.25-next.0" + "@backstage/plugin-pagerduty" "0.3.25" "@backstage/plugin-permission-react" "^0.3.0" - "@backstage/plugin-rollbar" "^0.3.26-next.0" - "@backstage/plugin-scaffolder" "^0.12.2-next.0" - "@backstage/plugin-search" "^0.6.2-next.0" - "@backstage/plugin-sentry" "^0.3.36-next.0" - "@backstage/plugin-shortcuts" "^0.1.22-next.0" - "@backstage/plugin-tech-insights" "^0.1.8-next.0" - "@backstage/plugin-tech-radar" "^0.5.5-next.0" - "@backstage/plugin-techdocs" "^0.13.3-next.0" - "@backstage/plugin-todo" "^0.2.0-next.0" - "@backstage/plugin-user-settings" "^0.3.19-next.0" + "@backstage/plugin-rollbar" "^0.3.26" + "@backstage/plugin-scaffolder" "^0.12.2" + "@backstage/plugin-search" "^0.6.2" + "@backstage/plugin-sentry" "^0.3.36" + "@backstage/plugin-shortcuts" "^0.1.22" + "@backstage/plugin-tech-insights" "^0.1.8" + "@backstage/plugin-tech-radar" "^0.5.5" + "@backstage/plugin-techdocs" "^0.13.3" + "@backstage/plugin-todo" "^0.2.0" + "@backstage/plugin-user-settings" "^0.3.19" "@backstage/search-common" "^0.2.2" "@backstage/theme" "^0.2.14" "@material-ui/core" "^4.12.2" @@ -23144,18 +23038,18 @@ tdigest@^0.1.1: bintrees "1.0.1" "techdocs-cli-embedded-app@link:packages/techdocs-cli-embedded-app": - version "0.2.63-next.0" + version "0.2.63" dependencies: - "@backstage/app-defaults" "^0.1.7-next.0" + "@backstage/app-defaults" "^0.1.7" "@backstage/catalog-model" "^0.9.10" - "@backstage/cli" "^0.13.2-next.0" + "@backstage/cli" "^0.13.2" "@backstage/config" "^0.1.13" "@backstage/core-app-api" "^0.5.2" - "@backstage/core-components" "^0.8.8-next.0" + "@backstage/core-components" "^0.8.8" "@backstage/core-plugin-api" "^0.6.0" - "@backstage/integration-react" "^0.1.21-next.0" - "@backstage/plugin-catalog" "^0.7.12-next.0" - "@backstage/plugin-techdocs" "^0.13.3-next.0" + "@backstage/integration-react" "^0.1.21" + "@backstage/plugin-catalog" "^0.7.12" + "@backstage/plugin-techdocs" "^0.13.3" "@backstage/test-utils" "^0.2.4" "@backstage/theme" "^0.2.14" "@material-ui/core" "^4.11.0"