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 && (