diff --git a/app-config.yaml b/app-config.yaml index 5b704f9b8e..9fdf7a28ee 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -57,6 +57,10 @@ catalog: rules: - allow: [Component, API, Group, Template, Location] processors: + github: + privateToken: + $secret: + env: GITHUB_PRIVATE_TOKEN githubApi: privateToken: $secret: diff --git a/docs/getting-started/running-backstage-locally.md b/docs/getting-started/running-backstage-locally.md index 08d2ab385b..249727e9d4 100644 --- a/docs/getting-started/running-backstage-locally.md +++ b/docs/getting-started/running-backstage-locally.md @@ -3,21 +3,39 @@ id: running-backstage-locally title: Running Backstage Locally --- +## Prerequisites + +- Node.js + First make sure you are using NodeJS with an Active LTS Release, currently v12. This is made easy with a version manager such as [nvm](https://github.com/nvm-sh/nvm) which allows for version switching. ```bash -# Checking your version -node --version -> v14.7.0 - -# Adding a second node version +# Installing a new version nvm install 12 > Downloading and installing node v12.18.3... > Now using node v12.18.3 (npm v6.14.6) + +# Checking your version +node --version +> v12.18.3 ``` +- yarn + +Please refer to the +[installation instructions for yarn](https://classic.yarnpkg.com/en/docs/install/). + +- Docker + +We use Docker for few of our core features. So, you will need Docker installed +locally to use features like Software Templates and TechDocs. Please refer to +the +[installation instructions for Docker](https://docs.docker.com/engine/install/). + +## Clone and Build + To get up and running with a local Backstage to evaluate it, let's clone it off of GitHub and run an initial build. diff --git a/packages/core/src/components/ProgressBars/ProgressCard.stories.tsx b/packages/core/src/components/ProgressBars/GaugeCard.stories.tsx similarity index 69% rename from packages/core/src/components/ProgressBars/ProgressCard.stories.tsx rename to packages/core/src/components/ProgressBars/GaugeCard.stories.tsx index 62c9f3be6e..922bb63b2f 100644 --- a/packages/core/src/components/ProgressBars/ProgressCard.stories.tsx +++ b/packages/core/src/components/ProgressBars/GaugeCard.stories.tsx @@ -15,26 +15,26 @@ */ import React from 'react'; -import { ProgressCard } from './ProgressCard'; +import { GaugeCard } from './GaugeCard'; import { Grid } from '@material-ui/core'; const linkInfo = { title: 'Go to XYZ Location', link: '#' }; export default { title: 'Progress Card', - component: ProgressCard, + component: GaugeCard, }; export const Default = () => ( - + - + - + ); @@ -42,21 +42,17 @@ export const Default = () => ( export const Subhead = () => ( - + - - ( export const LinkInFooter = () => ( - + - + - + ); diff --git a/packages/core/src/components/ProgressBars/ProgressCard.test.jsx b/packages/core/src/components/ProgressBars/GaugeCard.test.jsx similarity index 75% rename from packages/core/src/components/ProgressBars/ProgressCard.test.jsx rename to packages/core/src/components/ProgressBars/GaugeCard.test.jsx index 8568077a92..27ef0bb188 100644 --- a/packages/core/src/components/ProgressBars/ProgressCard.test.jsx +++ b/packages/core/src/components/ProgressBars/GaugeCard.test.jsx @@ -18,32 +18,30 @@ import React from 'react'; import { render } from '@testing-library/react'; import { wrapInTestApp } from '@backstage/test-utils'; -import { ProgressCard } from './ProgressCard'; +import { GaugeCard } from './GaugeCard'; const minProps = { title: 'Tingle upgrade', progress: 0.12 }; -describe('', () => { +describe('', () => { it('renders without exploding', () => { - const { getByText } = render(wrapInTestApp()); + const { getByText } = render(wrapInTestApp()); expect(getByText(/Tingle.*/)).toBeInTheDocument(); }); it('renders progress and title', () => { - const { getByText } = render(wrapInTestApp()); + const { getByText } = render(wrapInTestApp()); expect(getByText(/Tingle.*/)).toBeInTheDocument(); expect(getByText(/12%.*/)).toBeInTheDocument(); }); it('does not render deepLink', () => { - const { queryByText } = render( - wrapInTestApp(), - ); + const { queryByText } = render(wrapInTestApp()); expect(queryByText('View more')).not.toBeInTheDocument(); }); it('handles invalid numbers', () => { const badProps = { title: 'Tingle upgrade', progress: 'hejjo' }; - const { getByText } = render(wrapInTestApp()); + const { getByText } = render(wrapInTestApp()); expect(getByText(/N\/A.*/)).toBeInTheDocument(); }); }); diff --git a/packages/core/src/components/ProgressBars/ProgressCard.tsx b/packages/core/src/components/ProgressBars/GaugeCard.tsx similarity index 90% rename from packages/core/src/components/ProgressBars/ProgressCard.tsx rename to packages/core/src/components/ProgressBars/GaugeCard.tsx index eef6312600..fc7055f705 100644 --- a/packages/core/src/components/ProgressBars/ProgressCard.tsx +++ b/packages/core/src/components/ProgressBars/GaugeCard.tsx @@ -18,7 +18,7 @@ import React, { FC } from 'react'; import { makeStyles } from '@material-ui/core'; import { InfoCard } from '../../layout/InfoCard'; import { BottomLinkProps } from '../../layout/BottomLink'; -import { CircleProgress } from './CircleProgress'; +import { GaugeProgress } from './GaugeProgress'; type Props = { title: string; @@ -36,7 +36,7 @@ const useStyles = makeStyles({ }, }); -export const ProgressCard: FC = props => { +export const GaugeCard: FC = props => { const classes = useStyles(props); const { title, subheader, progress, deepLink, variant } = props; @@ -48,7 +48,7 @@ export const ProgressCard: FC = props => { deepLink={deepLink} variant={variant} > - + ); diff --git a/packages/core/src/components/ProgressBars/CircleProgress.test.jsx b/packages/core/src/components/ProgressBars/GaugeProgress.test.jsx similarity index 82% rename from packages/core/src/components/ProgressBars/CircleProgress.test.jsx rename to packages/core/src/components/ProgressBars/GaugeProgress.test.jsx index 9b9eae1bb8..778abdf12c 100644 --- a/packages/core/src/components/ProgressBars/CircleProgress.test.jsx +++ b/packages/core/src/components/ProgressBars/GaugeProgress.test.jsx @@ -17,32 +17,32 @@ import React from 'react'; import { render } from '@testing-library/react'; import { wrapInTestApp } from '@backstage/test-utils'; -import { CircleProgress, getProgressColor } from './CircleProgress'; +import { GaugeProgress, getProgressColor } from './GaugeProgress'; -describe('', () => { +describe('', () => { it('renders without exploding', () => { const { getByText } = render( - wrapInTestApp(), + wrapInTestApp(), ); getByText('10%'); }); it('handles fractional prop', () => { const { getByText } = render( - wrapInTestApp(), + wrapInTestApp(), ); getByText('10%'); }); it('handles max prop', () => { const { getByText } = render( - wrapInTestApp(), + wrapInTestApp(), ); getByText('1%'); }); it('handles unit prop', () => { const { getByText } = render( - wrapInTestApp(), + wrapInTestApp(), ); getByText('10m'); }); diff --git a/packages/core/src/components/ProgressBars/CircleProgress.tsx b/packages/core/src/components/ProgressBars/GaugeProgress.tsx similarity index 98% rename from packages/core/src/components/ProgressBars/CircleProgress.tsx rename to packages/core/src/components/ProgressBars/GaugeProgress.tsx index 79a451b14e..14776ed431 100644 --- a/packages/core/src/components/ProgressBars/CircleProgress.tsx +++ b/packages/core/src/components/ProgressBars/GaugeProgress.tsx @@ -77,7 +77,7 @@ export function getProgressColor( return palette.status.ok; } -export const CircleProgress: FC = props => { +export const GaugeProgress: FC = props => { const classes = useStyles(props); const theme = useTheme(); const { value, fractional, inverse, unit, max } = { diff --git a/packages/core/src/components/ProgressBars/HorizontalProgress.stories.tsx b/packages/core/src/components/ProgressBars/LinearGauge.stories.tsx similarity index 79% rename from packages/core/src/components/ProgressBars/HorizontalProgress.stories.tsx rename to packages/core/src/components/ProgressBars/LinearGauge.stories.tsx index 6e8f4ed7fd..c4492986b6 100644 --- a/packages/core/src/components/ProgressBars/HorizontalProgress.stories.tsx +++ b/packages/core/src/components/ProgressBars/LinearGauge.stories.tsx @@ -15,29 +15,29 @@ */ import React from 'react'; -import { HorizontalProgress } from './HorizontalProgress'; +import { LinearGauge } from './LinearGauge'; const containerStyle = { width: 300 }; export default { - title: 'HorizontalProgress', - component: HorizontalProgress, + title: 'LinearGauge', + component: LinearGauge, }; export const Default = () => (
- +
); export const MediumProgress = () => (
- +
); export const LowProgress = () => (
- +
); diff --git a/packages/core/src/components/ProgressBars/HorizontalProgress.tsx b/packages/core/src/components/ProgressBars/LinearGauge.tsx similarity index 92% rename from packages/core/src/components/ProgressBars/HorizontalProgress.tsx rename to packages/core/src/components/ProgressBars/LinearGauge.tsx index 72bf1f34c3..73163b345f 100644 --- a/packages/core/src/components/ProgressBars/HorizontalProgress.tsx +++ b/packages/core/src/components/ProgressBars/LinearGauge.tsx @@ -19,7 +19,7 @@ import { Tooltip, useTheme } from '@material-ui/core'; // @ts-ignore import { Line } from 'rc-progress'; import { BackstageTheme } from '@backstage/theme'; -import { getProgressColor } from './CircleProgress'; +import { getProgressColor } from './GaugeProgress'; type Props = { /** @@ -28,7 +28,7 @@ type Props = { value: number; }; -export const HorizontalProgress: FC = ({ value }) => { +export const LinearGauge: FC = ({ value }) => { const theme = useTheme(); if (isNaN(value)) { return null; diff --git a/packages/core/src/components/ProgressBars/index.ts b/packages/core/src/components/ProgressBars/index.ts index c74e283ae6..c7131c8831 100644 --- a/packages/core/src/components/ProgressBars/index.ts +++ b/packages/core/src/components/ProgressBars/index.ts @@ -14,6 +14,6 @@ * limitations under the License. */ -export { ProgressCard } from './ProgressCard'; -export { CircleProgress } from './CircleProgress'; -export { HorizontalProgress } from './HorizontalProgress'; +export { GaugeCard } from './GaugeCard'; +export { GaugeProgress } from './GaugeProgress'; +export { LinearGauge } from './LinearGauge'; diff --git a/packages/core/src/layout/Page/Page.stories.tsx b/packages/core/src/layout/Page/Page.stories.tsx index 0b91875546..8fd779196d 100644 --- a/packages/core/src/layout/Page/Page.stories.tsx +++ b/packages/core/src/layout/Page/Page.stories.tsx @@ -30,7 +30,7 @@ import { Table, StatusOK, TableColumn, - ProgressCard, + GaugeCard, TrendLine, } from '../../components'; import { Box, Typography, Link, Chip, Grid } from '@material-ui/core'; @@ -120,14 +120,14 @@ const DataGrid = () => ( direction="row" > - - = () => { + const classes = useStyles(); + + return ( + + + + ); +}; + +export default LogoFull; diff --git a/packages/create-app/templates/default-app/packages/app/src/LogoIcon.tsx b/packages/create-app/templates/default-app/packages/app/src/LogoIcon.tsx new file mode 100644 index 0000000000..d70be3dd32 --- /dev/null +++ b/packages/create-app/templates/default-app/packages/app/src/LogoIcon.tsx @@ -0,0 +1,47 @@ +/* + * Copyright 2020 Spotify AB + * + * 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, { FC } from 'react'; +import { makeStyles } from '@material-ui/core'; + +const useStyles = makeStyles({ + svg: { + width: 'auto', + height: 28, + }, + path: { + fill: '#7df3e1', + }, +}); + +const LogoIcon: FC<{}> = () => { + const classes = useStyles(); + + return ( + + + + ); +}; + +export default LogoIcon; diff --git a/packages/create-app/templates/default-app/packages/app/src/sidebar.tsx b/packages/create-app/templates/default-app/packages/app/src/sidebar.tsx index 9e343b86ac..96d18965ec 100644 --- a/packages/create-app/templates/default-app/packages/app/src/sidebar.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/sidebar.tsx @@ -1,15 +1,21 @@ -import React from 'react'; +import React, { FC, useContext } from 'react'; import HomeIcon from '@material-ui/icons/Home'; import LibraryBooks from '@material-ui/icons/LibraryBooks'; import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; import BuildIcon from '@material-ui/icons/BuildRounded'; import RuleIcon from '@material-ui/icons/AssignmentTurnedIn'; import MapIcon from '@material-ui/icons/MyLocation'; +import { Link, makeStyles } from '@material-ui/core'; +import { NavLink } from 'react-router-dom'; +import LogoFull from './LogoFull'; +import LogoIcon from './LogoIcon'; import { Sidebar, SidebarItem, SidebarDivider, + sidebarConfig, + SidebarContext, SidebarSpace, SidebarUserSettings, SidebarThemeToggle, @@ -19,6 +25,7 @@ import { export const AppSidebar = () => ( + {/* Global nav, not org-specific */} @@ -37,3 +44,36 @@ export const AppSidebar = () => ( ); + +const useSidebarLogoStyles = makeStyles({ + root: { + width: sidebarConfig.drawerWidthClosed, + height: 3 * sidebarConfig.logoHeight, + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + marginBottom: -14, + }, + link: { + width: sidebarConfig.drawerWidthClosed, + marginLeft: 24, + }, +}); + +const SidebarLogo: FC<{}> = () => { + const classes = useSidebarLogoStyles(); + const { isOpen } = useContext(SidebarContext); + + return ( +
+ + {isOpen ? : } + +
+ ); +}; diff --git a/packages/e2e-test/src/e2e-test.ts b/packages/e2e-test/src/e2e-test.ts index 5dfac68d6a..bdb7c25c5c 100644 --- a/packages/e2e-test/src/e2e-test.ts +++ b/packages/e2e-test/src/e2e-test.ts @@ -277,19 +277,28 @@ async function testAppServe(pluginName: string, appDir: string) { let successful = false; try { - const browser = new Browser(); + for (let attempts = 1; ; attempts++) { + try { + const browser = new Browser(); - await waitForPageWithText(browser, '/', 'Backstage Service Catalog'); - await waitForPageWithText( - browser, - `/${pluginName}`, - `Welcome to ${pluginName}!`, - ); + await waitForPageWithText(browser, '/', 'Backstage Service Catalog'); + await waitForPageWithText( + browser, + `/${pluginName}`, + `Welcome to ${pluginName}!`, + ); - print('Both App and Plugin loaded correctly'); - successful = true; - } catch (error) { - throw new Error(`App serve test failed, ${error}`); + print('Both App and Plugin loaded correctly'); + successful = true; + break; + } catch (error) { + if (attempts >= 5) { + throw new Error(`App serve test failed, ${error}`); + } + console.log(`App serve failed, trying again, ${error}`); + await new Promise(resolve => setTimeout(resolve, 1000)); + } + } } finally { // Kill entire process group, otherwise we'll end up with hanging serve processes killTree(startApp.pid); diff --git a/packages/storybook/.storybook/main.js b/packages/storybook/.storybook/main.js index 2ee58a8c4f..c83bb221be 100644 --- a/packages/storybook/.storybook/main.js +++ b/packages/storybook/.storybook/main.js @@ -22,7 +22,7 @@ module.exports = { const [jsLoader] = config.module.rules.splice(0, 1); if (jsLoader.use[0].loader !== 'babel-loader') { throw new Error( - `Unexpected loader removed from storybook config, ${jsonLoader.use[0].loader}`, + `Unexpected loader removed from storybook config, ${jsLoader.use[0].loader}`, ); } diff --git a/packages/techdocs-container/Dockerfile b/packages/techdocs-container/Dockerfile index 2002d93d70..e910935baf 100644 --- a/packages/techdocs-container/Dockerfile +++ b/packages/techdocs-container/Dockerfile @@ -18,7 +18,7 @@ FROM python:3.8-alpine RUN apk update && apk --no-cache add gcc musl-dev openjdk11-jdk curl graphviz ttf-dejavu fontconfig RUN curl -L http://sourceforge.net/projects/plantuml/files/plantuml.1.2020.16.jar/download > /opt/plantuml.jar -RUN pip install --upgrade pip && pip install mkdocs-techdocs-core==0.0.4 +RUN pip install --upgrade pip && pip install mkdocs-techdocs-core==0.0.7 # Create script to call plantuml.jar from a location in path diff --git a/packages/techdocs-container/mock-docs/docs/index.md b/packages/techdocs-container/mock-docs/docs/index.md index 77c64582de..2586b86cfb 100644 --- a/packages/techdocs-container/mock-docs/docs/index.md +++ b/packages/techdocs-container/mock-docs/docs/index.md @@ -59,3 +59,5 @@ digraph G { Goofy <-- MickeyMouse: responds @enduml ``` + +:bulb: diff --git a/packages/techdocs-container/techdocs-core/README.md b/packages/techdocs-container/techdocs-core/README.md index a4afed0158..36f1437a54 100644 --- a/packages/techdocs-container/techdocs-core/README.md +++ b/packages/techdocs-container/techdocs-core/README.md @@ -50,6 +50,18 @@ python -m black src/ ## Changelog +### 0.0.7 + +- Fix an issue with configuration of emoji support + +### 0.0.6 + +- Further adjustments to versions to find ones that are compatible + +### 0.0.5 + +- Downgrade some versions of markdown extensions to versions that are more stable + ### 0.0.4 - Added support for more mkdocs extensions diff --git a/packages/techdocs-container/techdocs-core/requirements.txt b/packages/techdocs-container/techdocs-core/requirements.txt index 4037a174ea..36daaab4d7 100644 --- a/packages/techdocs-container/techdocs-core/requirements.txt +++ b/packages/techdocs-container/techdocs-core/requirements.txt @@ -4,10 +4,10 @@ mkdocs==1.1.2 mkdocs-material==5.3.2 mkdocs-monorepo-plugin==0.4.5 -plantuml-markdown==3.4.0 +plantuml-markdown==3.1.2 markdown_inline_graphviz_extension==1.1 pygments==2.6.1 -pymdown-extensions==7.1 +pymdown-extensions==8.0.0 # The linter using for Python # Note: This requires Python 3.6+ to run, but can format Python 2 code too. diff --git a/packages/techdocs-container/techdocs-core/setup.py b/packages/techdocs-container/techdocs-core/setup.py index 72593dc433..3e3fa47caa 100644 --- a/packages/techdocs-container/techdocs-core/setup.py +++ b/packages/techdocs-container/techdocs-core/setup.py @@ -18,7 +18,7 @@ from setuptools import setup, find_packages setup( name='mkdocs-techdocs-core', - version='0.0.4', + version='0.0.7', description='A Mkdocs package that contains TechDocs defaults', long_description='', keywords='mkdocs', @@ -31,10 +31,10 @@ setup( 'mkdocs>=1.1.2', 'mkdocs-material==5.3.2', 'mkdocs-monorepo-plugin==0.4.5', - 'plantuml-markdown==3.4.0', + 'plantuml-markdown==3.1.2', 'markdown_inline_graphviz_extension==1.1', 'pygments==2.6.1', - 'pymdown-extensions==7.1' + 'pymdown-extensions==8.0.0' ], classifiers=[ 'Development Status :: 1 - Planning', diff --git a/packages/techdocs-container/techdocs-core/src/core.py b/packages/techdocs-container/techdocs-core/src/core.py index d021a69486..69e39d401b 100644 --- a/packages/techdocs-container/techdocs-core/src/core.py +++ b/packages/techdocs-container/techdocs-core/src/core.py @@ -18,6 +18,7 @@ from mkdocs.plugins import BasePlugin, PluginCollection from mkdocs.theme import Theme from mkdocs.contrib.search import SearchPlugin from mkdocs_monorepo_plugin.plugin import MonorepoPlugin +from pymdownx.emoji import to_svg import tempfile import os @@ -76,9 +77,7 @@ class TechDocsCore(BasePlugin): config["markdown_extensions"].append("pymdownx.critic") config["markdown_extensions"].append("pymdownx.details") config["markdown_extensions"].append("pymdownx.emoji") - config["mdx_configs"]["pymdownx.emoji"] = { - "emoji_generator": "!!python/name:pymdownx.emoji.to_svg", - } + config["mdx_configs"]["pymdownx.emoji"] = {"emoji_generator": to_svg} config["markdown_extensions"].append("pymdownx.inlinehilite") config["markdown_extensions"].append("pymdownx.magiclink") config["markdown_extensions"].append("pymdownx.mark") diff --git a/plugins/scaffolder/src/components/JobStatusModal/JobStatusModal.tsx b/plugins/scaffolder/src/components/JobStatusModal/JobStatusModal.tsx index 102e93f91d..87b70a9553 100644 --- a/plugins/scaffolder/src/components/JobStatusModal/JobStatusModal.tsx +++ b/plugins/scaffolder/src/components/JobStatusModal/JobStatusModal.tsx @@ -72,7 +72,7 @@ export const JobStatusModal = ({ {entity && (