login({ checkExisting: true }));
+ useMountEffect(() => login({ checkExisting: true }));
return showLoginPage ? (
diff --git a/packages/core-components/src/layout/SignInPage/auth0Provider.tsx b/packages/core-components/src/layout/SignInPage/auth0Provider.tsx
deleted file mode 100644
index 739c3709a9..0000000000
--- a/packages/core-components/src/layout/SignInPage/auth0Provider.tsx
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.
- */
-
-import React from 'react';
-import Grid from '@material-ui/core/Grid';
-import Typography from '@material-ui/core/Typography';
-import Button from '@material-ui/core/Button';
-import { InfoCard } from '../InfoCard/InfoCard';
-import { ProviderComponent, ProviderLoader, SignInProvider } from './types';
-import {
- useApi,
- auth0AuthApiRef,
- errorApiRef,
-} from '@backstage/core-plugin-api';
-import { ForwardedError } from '@backstage/errors';
-import { UserIdentity } from './UserIdentity';
-
-const Component: ProviderComponent = ({ onSignInSuccess }) => {
- const auth0AuthApi = useApi(auth0AuthApiRef);
- const errorApi = useApi(errorApiRef);
-
- const handleLogin = async () => {
- try {
- const identityResponse = await auth0AuthApi.getBackstageIdentity({
- instantPopup: true,
- });
- if (!identityResponse) {
- throw new Error(
- 'The Auth0 provider is not configured to support sign-in',
- );
- }
-
- const profile = await auth0AuthApi.getProfile();
-
- onSignInSuccess(
- UserIdentity.create({
- identity: identityResponse.identity,
- authApi: auth0AuthApi,
- profile,
- }),
- );
- } catch (error) {
- errorApi.post(new ForwardedError('Auth0 login failed', error));
- }
- };
-
- return (
-
-
- Sign In
-
- }
- >
- Sign In using Auth0
-
-
- );
-};
-
-const loader: ProviderLoader = async apis => {
- const auth0AuthApi = apis.get(auth0AuthApiRef)!;
-
- const identityResponse = await auth0AuthApi.getBackstageIdentity({
- optional: true,
- });
-
- if (!identityResponse) {
- return undefined;
- }
-
- const profile = await auth0AuthApi.getProfile();
- return UserIdentity.create({
- identity: identityResponse.identity,
- authApi: auth0AuthApi,
- profile,
- });
-};
-
-export const auth0Provider: SignInProvider = { Component, loader };
diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md
index 21668577a1..bba39bf2cf 100644
--- a/packages/core-plugin-api/CHANGELOG.md
+++ b/packages/core-plugin-api/CHANGELOG.md
@@ -1,5 +1,23 @@
# @backstage/core-plugin-api
+## 0.7.0
+
+### Minor Changes
+
+- 33cd215b11: **BREAKING**: Removed deprecated `AnyAnalyticsContext` type which is replaced by `AnalyticsContextValue`
+
+## 0.6.1
+
+### Patch Changes
+
+- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5
+- c77c5c7eb6: Added `backstage.role` to `package.json`
+- 2714145cf5: Removes unused react-use dependency.
+- Updated dependencies
+ - @backstage/config@0.1.14
+ - @backstage/types@0.1.2
+ - @backstage/version-bridge@0.1.2
+
## 0.6.0
### Minor Changes
diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md
index 5ac07e195c..89361419ba 100644
--- a/packages/core-plugin-api/api-report.md
+++ b/packages/core-plugin-api/api-report.md
@@ -76,11 +76,6 @@ export type AnalyticsTracker = {
) => void;
};
-// @public @deprecated
-export type AnyAnalyticsContext = {
- [param in string]: string | boolean | number | undefined;
-};
-
// @public
export type AnyApiFactory = ApiFactory<
unknown,
@@ -189,11 +184,6 @@ export function attachComponentData(
data: unknown,
): void;
-// @public @deprecated
-export const auth0AuthApiRef: ApiRef<
- OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
->;
-
// @public
export type AuthProviderInfo = {
id: string;
@@ -536,15 +526,6 @@ export const microsoftAuthApiRef: ApiRef<
SessionApi
>;
-// @public @deprecated
-export const oauth2ApiRef: ApiRef<
- OAuthApi &
- OpenIdConnectApi &
- ProfileInfoApi &
- BackstageIdentityApi &
- SessionApi
->;
-
// @public
export type OAuthApi = {
getAccessToken(
@@ -571,24 +552,13 @@ export type OAuthRequester = (
// @public
export type OAuthRequesterOptions = {
- provider: Omit & {
- id?: string;
- };
+ provider: AuthProviderInfo;
onAuthRequest(scopes: Set): Promise;
};
// @public
export type OAuthScope = string | string[];
-// @public @deprecated
-export const oidcAuthApiRef: ApiRef<
- OAuthApi &
- OpenIdConnectApi &
- ProfileInfoApi &
- BackstageIdentityApi &
- SessionApi
->;
-
// @alpha
export const oktaAuthApiRef: ApiRef<
OAuthApi &
@@ -642,9 +612,7 @@ export type PathParams = {
// @public
export type PendingOAuthRequest = {
- provider: Omit & {
- id?: string;
- };
+ provider: AuthProviderInfo;
reject(): void;
trigger(): Promise;
};
@@ -689,11 +657,6 @@ export type RouteRef = {
params: ParamKeys;
};
-// @public @deprecated
-export const samlAuthApiRef: ApiRef<
- ProfileInfoApi & BackstageIdentityApi & SessionApi
->;
-
// @public
export type SessionApi = {
signIn(): Promise;
@@ -715,8 +678,6 @@ export type SignInPageProps = {
// @public
export interface StorageApi {
forBucket(name: string): StorageApi;
- // @deprecated
- get(key: string): T | undefined;
observe$(
key: string,
): Observable>;
@@ -728,23 +689,17 @@ export interface StorageApi {
// @public
export const storageApiRef: ApiRef;
-// @public @deprecated (undocumented)
-export type StorageValueChange =
- StorageValueSnapshot;
-
// @public
export type StorageValueSnapshot =
| {
key: string;
presence: 'unknown' | 'absent';
value?: undefined;
- newValue?: undefined;
}
| {
key: string;
presence: 'present';
value: TValue;
- newValue?: TValue;
};
// @public
diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json
index c9f110b432..4e9198557b 100644
--- a/packages/core-plugin-api/package.json
+++ b/packages/core-plugin-api/package.json
@@ -1,13 +1,16 @@
{
"name": "@backstage/core-plugin-api",
"description": "Core API used by Backstage plugins",
- "version": "0.6.0",
+ "version": "0.7.0",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
"types": "dist/index.d.ts"
},
+ "backstage": {
+ "role": "web-library"
+ },
"homepage": "https://backstage.io",
"repository": {
"type": "git",
@@ -21,21 +24,21 @@
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
- "build": "backstage-cli build --outputs types,esm",
- "lint": "backstage-cli lint",
- "test": "backstage-cli test",
- "prepack": "backstage-cli prepack",
- "postpack": "backstage-cli postpack",
- "clean": "backstage-cli clean"
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean",
+ "start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/config": "^0.1.13",
- "@backstage/types": "^0.1.1",
- "@backstage/version-bridge": "^0.1.1",
+ "@backstage/config": "^0.1.15",
+ "@backstage/types": "^0.1.3",
+ "@backstage/version-bridge": "^0.1.2",
"history": "^5.0.0",
"prop-types": "^15.7.2",
"react-router-dom": "6.0.0-beta.0",
- "react-use": "^17.2.4",
"zen-observable": "^0.8.15"
},
"peerDependencies": {
@@ -43,9 +46,9 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.13.2-next.0",
- "@backstage/core-app-api": "^0.5.2-next.0",
- "@backstage/test-utils": "^0.2.4-next.0",
+ "@backstage/cli": "^0.14.1",
+ "@backstage/core-app-api": "^0.5.4",
+ "@backstage/test-utils": "^0.2.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^7.0.2",
diff --git a/packages/core-plugin-api/src/analytics/index.ts b/packages/core-plugin-api/src/analytics/index.ts
index 942df56ef8..651e8e105e 100644
--- a/packages/core-plugin-api/src/analytics/index.ts
+++ b/packages/core-plugin-api/src/analytics/index.ts
@@ -15,9 +15,5 @@
*/
export { AnalyticsContext } from './AnalyticsContext';
-export type {
- AnalyticsContextValue,
- AnyAnalyticsContext,
- CommonAnalyticsContext,
-} from './types';
+export type { AnalyticsContextValue, CommonAnalyticsContext } from './types';
export { useAnalytics } from './useAnalytics';
diff --git a/packages/core-plugin-api/src/analytics/types.ts b/packages/core-plugin-api/src/analytics/types.ts
index 431e453a61..1a60572082 100644
--- a/packages/core-plugin-api/src/analytics/types.ts
+++ b/packages/core-plugin-api/src/analytics/types.ts
@@ -36,16 +36,6 @@ export type CommonAnalyticsContext = {
extension: string;
};
-/**
- * Allows arbitrary scalar values as context attributes too.
- *
- * @public
- * @deprecated Will be removed, use `AnalyticsContextValue` instead
- */
-export type AnyAnalyticsContext = {
- [param in string]: string | boolean | number | undefined;
-};
-
/**
* Analytics context envelope.
*
diff --git a/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts b/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts
index ccca2c50e3..75bf3a3864 100644
--- a/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts
+++ b/packages/core-plugin-api/src/apis/definitions/OAuthRequestApi.ts
@@ -27,10 +27,8 @@ import { AuthProviderInfo } from './auth';
export type OAuthRequesterOptions = {
/**
* Information about the auth provider, which will be forwarded to auth requests.
- *
- * Not passing in an `id` is deprecated, and it will be required in the future.
*/
- provider: Omit & { id?: string };
+ provider: AuthProviderInfo;
/**
* Implementation of the auth flow, which will be called synchronously when
@@ -71,10 +69,8 @@ export type OAuthRequester = (
export type PendingOAuthRequest = {
/**
* Information about the auth provider, as given in the AuthRequesterOptions
- *
- * Not passing in an `id` is deprecated, and it will be required in the future.
*/
- provider: Omit & { id?: string };
+ provider: AuthProviderInfo;
/**
* Rejects the request, causing all pending AuthRequester calls to fail with "RejectedError".
diff --git a/packages/core-plugin-api/src/apis/definitions/StorageApi.ts b/packages/core-plugin-api/src/apis/definitions/StorageApi.ts
index 4bd49f9b83..1506e5f143 100644
--- a/packages/core-plugin-api/src/apis/definitions/StorageApi.ts
+++ b/packages/core-plugin-api/src/apis/definitions/StorageApi.ts
@@ -27,24 +27,13 @@ export type StorageValueSnapshot =
key: string;
presence: 'unknown' | 'absent';
value?: undefined;
- /** @deprecated Use `value` instead */
- newValue?: undefined;
}
| {
key: string;
presence: 'present';
value: TValue;
- /** @deprecated Use `value` instead */
- newValue?: TValue;
};
-/**
- * @public
- * @deprecated Use StorageValueSnapshot instead
- */
-export type StorageValueChange =
- StorageValueSnapshot;
-
/**
* Provides a key-value persistence API.
*
@@ -59,14 +48,6 @@ export interface StorageApi {
*/
forBucket(name: string): StorageApi;
- /**
- * Get the current value for persistent data, use observe$ to be notified of updates.
- *
- * @deprecated Use `snapshot` instead.
- * @param key - Unique key associated with the data.
- */
- get(key: string): T | undefined;
-
/**
* Remove persistent data.
*
diff --git a/packages/core-plugin-api/src/apis/definitions/auth.ts b/packages/core-plugin-api/src/apis/definitions/auth.ts
index ed5a7a3264..497ce8233b 100644
--- a/packages/core-plugin-api/src/apis/definitions/auth.ts
+++ b/packages/core-plugin-api/src/apis/definitions/auth.ts
@@ -366,23 +366,6 @@ export const gitlabAuthApiRef: ApiRef<
id: 'core.auth.gitlab',
});
-/**
- * Provides authentication towards Auth0 APIs.
- *
- * @remarks
- *
- * See {@link https://auth0.com/docs/scopes/current/oidc-scopes}
- * for a full list of supported scopes.
- *
- * @public
- * @deprecated See https://backstage.io/docs/api/deprecations#generic-auth-api-refs
- */
-export const auth0AuthApiRef: ApiRef<
- OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
-> = createApiRef({
- id: 'core.auth.auth0',
-});
-
/**
* Provides authentication towards Microsoft APIs and identities.
*
@@ -404,50 +387,6 @@ export const microsoftAuthApiRef: ApiRef<
id: 'core.auth.microsoft',
});
-/**
- * Provides authentication for custom identity providers.
- *
- * @public
- * @deprecated See https://backstage.io/docs/api/deprecations#generic-auth-api-refs
- */
-export const oauth2ApiRef: ApiRef<
- OAuthApi &
- OpenIdConnectApi &
- ProfileInfoApi &
- BackstageIdentityApi &
- SessionApi
-> = createApiRef({
- id: 'core.auth.oauth2',
-});
-
-/**
- * Provides authentication for custom OpenID Connect identity providers.
- *
- * @public
- * @deprecated See https://backstage.io/docs/api/deprecations#generic-auth-api-refs
- */
-export const oidcAuthApiRef: ApiRef<
- OAuthApi &
- OpenIdConnectApi &
- ProfileInfoApi &
- BackstageIdentityApi &
- SessionApi
-> = createApiRef({
- id: 'core.auth.oidc',
-});
-
-/**
- * Provides authentication for SAML-based identity providers.
- *
- * @public
- * @deprecated See https://backstage.io/docs/api/deprecations#generic-auth-api-refs
- */
-export const samlAuthApiRef: ApiRef<
- ProfileInfoApi & BackstageIdentityApi & SessionApi
-> = createApiRef({
- id: 'core.auth.saml',
-});
-
/**
* Provides authentication towards OneLogin APIs.
*
diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md
index 886d873740..52dad1bfc9 100644
--- a/packages/create-app/CHANGELOG.md
+++ b/packages/create-app/CHANGELOG.md
@@ -1,5 +1,82 @@
# @backstage/create-app
+## 0.4.21
+
+### Patch Changes
+
+- a686702dbe: Update the template to reflect the renaming of `CatalogResultListItem` to `CatalogSearchResultListItem` from `@backstage/plugin-catalog`.
+
+ To apply this change to an existing app, make the following change to `packages/app/src/components/search/SearchPage.tsx`:
+
+ ```diff
+ -import { CatalogResultListItem } from '@backstage/plugin-catalog';
+ +import { CatalogSearchResultListItem } from '@backstage/plugin-catalog';
+ ```
+
+ ```diff
+ case 'software-catalog':
+ return (
+ -
+ ```
+
+- f39c1e6036: To reflect the updated `knex` and `@vscode/sqlite3` dependencies introduced with [v0.4.19](https://github.com/backstage/backstage/blob/master/packages/create-app/CHANGELOG.md#0419), we update our example `Dockerfile`, adding `@vscode/sqlite3` build dependencies to the image. Further on, we updated it to the `node:16-bullseye-slim` base image.
+
+ To apply this update to an existing app, make the following change to `packages/backend/Dockerfile`:
+
+ ```diff
+ -FROM node:14-buster-slim
+ +FROM node:16-bullseye-slim
+ ```
+
+ and, _only if you are using sqlite3 in your app_:
+
+ ```diff
+ RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz
+ +
+ +# install sqlite3 dependencies
+ +RUN apt-get update && \
+ + apt-get install -y libsqlite3-dev python3 cmake g++ && \
+ + rm -rf /var/lib/apt/lists/* && \
+ + yarn config set python /usr/bin/python3
+
+ RUN yarn install --frozen-lockfile --production --network-timeout 300000 && rm -rf "$(yarn cache dir)"
+ ```
+
+ If you are using a multi-stage Docker build for your app, please refer to the [updated examples](https://github.com/backstage/backstage/blob/master/docs/deployment/docker.md#multi-stage-build) in the documentation.
+
+## 0.4.20
+
+### Patch Changes
+
+- e725bb812f: Remove SearchContextProvider from ``
+
+ The `SidebarSearchModal` exported from `plugin-search` internally renders `SearchContextProvider`, so it can be removed from `Root.tsx`:
+
+ ```diff
+ -import {
+ - SidebarSearchModal,
+ - SearchContextProvider,
+ -} from '@backstage/plugin-search';
+ +import { SidebarSearchModal } from '@backstage/plugin-search';
+
+ ... omitted ...
+
+ } to="/search">
+ -
+ -
+ -
+ +
+
+ ```
+
+- c77c5c7eb6: Added `backstage.role` to `package.json`
+- Updated dependencies
+ - @backstage/cli-common@0.1.7
+
## 0.4.19
### Patch Changes
diff --git a/packages/create-app/package.json b/packages/create-app/package.json
index 991a241887..a240e95cac 100644
--- a/packages/create-app/package.json
+++ b/packages/create-app/package.json
@@ -1,11 +1,14 @@
{
"name": "@backstage/create-app",
"description": "A CLI that helps you create your own Backstage app",
- "version": "0.4.19",
+ "version": "0.4.21",
"private": false,
"publishConfig": {
"access": "public"
},
+ "backstage": {
+ "role": "cli"
+ },
"homepage": "https://backstage.io",
"repository": {
"type": "git",
@@ -21,16 +24,16 @@
"backstage-create-app": "bin/backstage-create-app"
},
"scripts": {
- "build": "backstage-cli build --outputs cjs",
- "lint": "backstage-cli lint",
- "test": "backstage-cli test",
- "clean": "backstage-cli clean",
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "clean": "backstage-cli package clean",
"prepack": "node scripts/prepack.js",
"postpack": "node scripts/postpack.js",
"start": "nodemon --"
},
"dependencies": {
- "@backstage/cli-common": "^0.1.6",
+ "@backstage/cli-common": "^0.1.8",
"chalk": "^4.0.0",
"commander": "^6.1.0",
"fs-extra": "9.1.0",
@@ -48,6 +51,7 @@
"ts-node": "^10.0.0"
},
"peerDependencies": {
+ "@backstage/app-defaults": "",
"@backstage/backend-common": "",
"@backstage/backend-tasks": "",
"@backstage/catalog-client": "",
@@ -58,30 +62,35 @@
"@backstage/core-components": "",
"@backstage/core-plugin-api": "",
"@backstage/errors": "",
+ "@backstage/integration-react": "",
"@backstage/plugin-api-docs": "",
"@backstage/plugin-app-backend": "",
"@backstage/plugin-auth-backend": "",
"@backstage/plugin-catalog": "",
"@backstage/plugin-catalog-backend": "",
+ "@backstage/plugin-catalog-common": "",
"@backstage/plugin-catalog-graph": "",
"@backstage/plugin-catalog-import": "",
+ "@backstage/plugin-catalog-react": "",
+ "@backstage/plugin-circleci": "",
"@backstage/plugin-explore": "",
"@backstage/plugin-github-actions": "",
"@backstage/plugin-lighthouse": "",
+ "@backstage/plugin-org": "",
"@backstage/plugin-permission-common": "",
"@backstage/plugin-permission-node": "",
+ "@backstage/plugin-permission-react": "",
"@backstage/plugin-proxy-backend": "",
"@backstage/plugin-rollbar-backend": "",
"@backstage/plugin-scaffolder": "",
+ "@backstage/plugin-scaffolder-backend": "",
"@backstage/plugin-search": "",
"@backstage/plugin-search-backend": "",
"@backstage/plugin-search-backend-node": "",
- "@backstage/plugin-scaffolder-backend": "",
"@backstage/plugin-tech-radar": "",
"@backstage/plugin-techdocs": "",
"@backstage/plugin-techdocs-backend": "",
"@backstage/plugin-user-settings": "",
- "@backstage/integration-react": "",
"@backstage/test-utils": "",
"@backstage/theme": ""
},
diff --git a/packages/create-app/templates/default-app/packages/app/src/App.tsx b/packages/create-app/templates/default-app/packages/app/src/App.tsx
index 9b6518620d..f4ff424926 100644
--- a/packages/create-app/templates/default-app/packages/app/src/App.tsx
+++ b/packages/create-app/templates/default-app/packages/app/src/App.tsx
@@ -15,7 +15,6 @@ import { orgPlugin } from '@backstage/plugin-org';
import { SearchPage } from '@backstage/plugin-search';
import { TechRadarPage } from '@backstage/plugin-tech-radar';
import {
- DefaultTechDocsHome,
TechDocsIndexPage,
techdocsPlugin,
TechDocsReaderPage,
@@ -31,7 +30,7 @@ import { createApp } from '@backstage/app-defaults';
import { FlatRoutes } from '@backstage/core-app-api';
import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
import { PermissionedRoute } from '@backstage/plugin-permission-react';
-import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common';
+import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';
const app = createApp({
apis,
@@ -65,9 +64,7 @@ const routes = (
>
{entityPage}
- }>
-
-
+ } />
}
diff --git a/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx b/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx
index 7e98c7d3e6..90738c44d4 100644
--- a/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx
+++ b/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx
@@ -28,10 +28,7 @@ import {
Settings as SidebarSettings,
UserSettingsSignInAvatar,
} from '@backstage/plugin-user-settings';
-import {
- SidebarSearchModal,
- SearchContextProvider,
-} from '@backstage/plugin-search';
+import { SidebarSearchModal } from '@backstage/plugin-search';
import {
Sidebar,
sidebarConfig,
@@ -84,9 +81,7 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
} to="/search">
-
-
- {' '}
+
}>
diff --git a/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx b/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx
index a88e7250e9..cd4603ecd3 100644
--- a/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx
+++ b/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx
@@ -1,12 +1,12 @@
import React from 'react';
import { makeStyles, Theme, Grid, List, Paper } from '@material-ui/core';
-import { CatalogResultListItem } from '@backstage/plugin-catalog';
+import { CatalogSearchResultListItem } from '@backstage/plugin-catalog';
import {
catalogApiRef,
CATALOG_FILTER_EXISTS,
} from '@backstage/plugin-catalog-react';
-import { DocsResultListItem } from '@backstage/plugin-techdocs';
+import { TechDocsSearchResultListItem } from '@backstage/plugin-techdocs';
import {
SearchBar,
@@ -116,14 +116,14 @@ const SearchPage = () => {
switch (type) {
case 'software-catalog':
return (
-
);
case 'techdocs':
return (
-
diff --git a/packages/create-app/templates/default-app/packages/backend/Dockerfile b/packages/create-app/templates/default-app/packages/backend/Dockerfile
index 31231a3a4a..dd35d4ddbc 100644
--- a/packages/create-app/templates/default-app/packages/backend/Dockerfile
+++ b/packages/create-app/templates/default-app/packages/backend/Dockerfile
@@ -9,7 +9,7 @@
#
# Once the commands have been run, you can build the image using `yarn build-image`
-FROM node:14-buster-slim
+FROM node:16-bullseye-slim
WORKDIR /app
@@ -19,6 +19,12 @@ WORKDIR /app
COPY yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./
RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz
+# install sqlite3 dependencies
+RUN apt-get update && \
+ apt-get install -y libsqlite3-dev python3 cmake g++ && \
+ rm -rf /var/lib/apt/lists/* && \
+ yarn config set python /usr/bin/python3
+
RUN yarn install --frozen-lockfile --production --network-timeout 300000 && rm -rf "$(yarn cache dir)"
# Then copy the rest of the backend bundle, along with any other files we might want.
diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts
index a0a1cc3701..c359cb4986 100644
--- a/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts
+++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/search.ts
@@ -5,8 +5,8 @@ import {
LunrSearchEngine,
} from '@backstage/plugin-search-backend-node';
import { PluginEnvironment } from '../types';
-import { DefaultCatalogCollator } from '@backstage/plugin-catalog-backend';
-import { DefaultTechDocsCollator } from '@backstage/plugin-techdocs-backend';
+import { DefaultCatalogCollatorFactory } from '@backstage/plugin-catalog-backend';
+import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backend';
export default async function createPlugin({
logger,
@@ -23,7 +23,7 @@ export default async function createPlugin({
// collator gathers entities from the software catalog.
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
- collator: DefaultCatalogCollator.fromConfig(config, {
+ factory: DefaultCatalogCollatorFactory.fromConfig(config, {
discovery,
tokenManager,
}),
@@ -32,7 +32,7 @@ export default async function createPlugin({
// collator gathers entities from techdocs.
indexBuilder.addCollator({
defaultRefreshIntervalSeconds: 600,
- collator: DefaultTechDocsCollator.fromConfig(config, {
+ factory: DefaultTechDocsCollatorFactory.fromConfig(config, {
discovery,
logger,
tokenManager,
diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md
index 8061f5fb98..4d2354297e 100644
--- a/packages/dev-utils/CHANGELOG.md
+++ b/packages/dev-utils/CHANGELOG.md
@@ -1,5 +1,35 @@
# @backstage/dev-utils
+## 0.2.23
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.8.10
+ - @backstage/plugin-catalog-react@0.7.0
+ - @backstage/catalog-model@0.11.0
+ - @backstage/core-plugin-api@0.7.0
+ - @backstage/app-defaults@0.1.9
+ - @backstage/core-app-api@0.5.4
+ - @backstage/integration-react@0.1.23
+ - @backstage/test-utils@0.2.6
+
+## 0.2.22
+
+### Patch Changes
+
+- c77c5c7eb6: Added `backstage.role` to `package.json`
+- Updated dependencies
+ - @backstage/core-app-api@0.5.3
+ - @backstage/core-components@0.8.9
+ - @backstage/core-plugin-api@0.6.1
+ - @backstage/integration-react@0.1.22
+ - @backstage/test-utils@0.2.5
+ - @backstage/plugin-catalog-react@0.6.15
+ - @backstage/app-defaults@0.1.8
+ - @backstage/catalog-model@0.10.0
+ - @backstage/theme@0.2.15
+
## 0.2.21
### Patch Changes
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index 9d55d17592..5c29c7dd0f 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -1,13 +1,16 @@
{
"name": "@backstage/dev-utils",
"description": "Utilities for developing Backstage plugins.",
- "version": "0.2.21",
+ "version": "0.2.23",
"private": false,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
"types": "dist/index.d.ts"
},
+ "backstage": {
+ "role": "web-library"
+ },
"homepage": "https://backstage.io",
"repository": {
"type": "git",
@@ -21,23 +24,24 @@
"main": "src/index.ts",
"types": "src/index.ts",
"scripts": {
- "build": "backstage-cli build --outputs types,esm",
- "lint": "backstage-cli lint",
- "test": "backstage-cli test",
- "prepack": "backstage-cli prepack",
- "postpack": "backstage-cli postpack",
- "clean": "backstage-cli clean"
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean",
+ "start": "backstage-cli package start"
},
"dependencies": {
- "@backstage/app-defaults": "^0.1.7",
- "@backstage/core-app-api": "^0.5.2",
- "@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",
- "@backstage/plugin-catalog-react": "^0.6.14",
- "@backstage/test-utils": "^0.2.4",
- "@backstage/theme": "^0.2.14",
+ "@backstage/app-defaults": "^0.1.9",
+ "@backstage/core-app-api": "^0.5.4",
+ "@backstage/core-components": "^0.8.10",
+ "@backstage/core-plugin-api": "^0.7.0",
+ "@backstage/catalog-model": "^0.11.0",
+ "@backstage/integration-react": "^0.1.23",
+ "@backstage/plugin-catalog-react": "^0.7.0",
+ "@backstage/test-utils": "^0.2.6",
+ "@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@testing-library/jest-dom": "^5.10.1",
@@ -55,7 +59,7 @@
"react-dom": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.13.2",
+ "@backstage/cli": "^0.14.1",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32"
},
diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json
index bbf55fac17..b17b0c14ce 100644
--- a/packages/e2e-test/package.json
+++ b/packages/e2e-test/package.json
@@ -3,6 +3,9 @@
"description": "E2E test for verifying Backstage packages",
"version": "0.2.0",
"private": true,
+ "backstage": {
+ "role": "cli"
+ },
"homepage": "https://backstage.io",
"repository": {
"type": "git",
@@ -16,16 +19,18 @@
"main": "src/index.ts",
"scripts": {
"start": "nodemon --",
- "lint": "backstage-cli lint",
- "test": "backstage-cli test",
- "test:e2e": "yarn start"
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "test:e2e": "yarn start",
+ "build": "backstage-cli package build",
+ "clean": "backstage-cli package clean"
},
"bin": {
"e2e-test": "bin/e2e-test"
},
"devDependencies": {
- "@backstage/cli-common": "^0.1.1",
- "@backstage/errors": "^0.2.0",
+ "@backstage/cli-common": "^0.1.8",
+ "@backstage/errors": "^0.2.2",
"@types/fs-extra": "^9.0.1",
"@types/node": "^14.14.32",
"@types/puppeteer": "^5.4.4",
diff --git a/packages/errors/CHANGELOG.md b/packages/errors/CHANGELOG.md
index 110863d347..0c9295532a 100644
--- a/packages/errors/CHANGELOG.md
+++ b/packages/errors/CHANGELOG.md
@@ -1,5 +1,22 @@
# @backstage/errors
+## 0.2.2
+
+### Patch Changes
+
+- Fix for the previous release with missing type declarations.
+- Updated dependencies
+ - @backstage/types@0.1.3
+
+## 0.2.1
+
+### Patch Changes
+
+- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5
+- c77c5c7eb6: Added `backstage.role` to `package.json`
+- Updated dependencies
+ - @backstage/types@0.1.2
+
## 0.2.0
### Minor Changes
diff --git a/packages/errors/package.json b/packages/errors/package.json
index f97adef8e1..b1c90f0371 100644
--- a/packages/errors/package.json
+++ b/packages/errors/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/errors",
"description": "Common utilities for error handling within Backstage",
- "version": "0.2.0",
+ "version": "0.2.2",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -12,6 +12,9 @@
"module": "dist/index.esm.js",
"types": "dist/index.d.ts"
},
+ "backstage": {
+ "role": "common-library"
+ },
"homepage": "https://backstage.io",
"repository": {
"type": "git",
@@ -22,20 +25,20 @@
"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"
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/types": "^0.1.1",
+ "@backstage/types": "^0.1.3",
"cross-fetch": "^3.1.5",
"serialize-error": "^8.0.1"
},
"devDependencies": {
- "@backstage/cli": "^0.13.2-next.0",
+ "@backstage/cli": "^0.14.0",
"@types/jest": "^26.0.7"
},
"files": [
diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md
index ec0457dc1e..1b8f22bcfc 100644
--- a/packages/integration-react/CHANGELOG.md
+++ b/packages/integration-react/CHANGELOG.md
@@ -1,5 +1,28 @@
# @backstage/integration-react
+## 0.1.23
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/core-components@0.8.10
+ - @backstage/core-plugin-api@0.7.0
+ - @backstage/integration@0.7.5
+
+## 0.1.22
+
+### Patch Changes
+
+- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5
+- c77c5c7eb6: Added `backstage.role` to `package.json`
+- f0e2f7a56a: Updated the `ScmAuth` error message for missing provider configurations to link to `ScmAuthApi` setup documentation.
+- Updated dependencies
+ - @backstage/core-components@0.8.9
+ - @backstage/core-plugin-api@0.6.1
+ - @backstage/integration@0.7.3
+ - @backstage/config@0.1.14
+ - @backstage/theme@0.2.15
+
## 0.1.21
### Patch Changes
diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json
index 8413442b3d..27e4492e65 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",
+ "version": "0.1.23",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -11,21 +11,24 @@
"main": "dist/index.esm.js",
"types": "dist/index.d.ts"
},
+ "backstage": {
+ "role": "web-library"
+ },
"scripts": {
- "build": "backstage-cli plugin:build",
- "start": "backstage-cli plugin:serve",
- "lint": "backstage-cli lint",
- "test": "backstage-cli test",
- "prepack": "backstage-cli prepack",
- "postpack": "backstage-cli postpack",
- "clean": "backstage-cli clean"
+ "build": "backstage-cli package build",
+ "start": "backstage-cli package start",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/config": "^0.1.13",
- "@backstage/core-components": "^0.8.8",
- "@backstage/core-plugin-api": "^0.6.0",
- "@backstage/integration": "^0.7.2",
- "@backstage/theme": "^0.2.14",
+ "@backstage/config": "^0.1.15",
+ "@backstage/core-components": "^0.8.10",
+ "@backstage/core-plugin-api": "^0.7.0",
+ "@backstage/integration": "^0.7.5",
+ "@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.57",
@@ -35,9 +38,9 @@
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
- "@backstage/cli": "^0.13.2",
- "@backstage/dev-utils": "^0.2.21",
- "@backstage/test-utils": "^0.2.4",
+ "@backstage/cli": "^0.14.1",
+ "@backstage/dev-utils": "^0.2.23",
+ "@backstage/test-utils": "^0.2.6",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
diff --git a/packages/integration-react/src/api/ScmAuth.test.ts b/packages/integration-react/src/api/ScmAuth.test.ts
index 4ebfef749e..1ad391d8d2 100644
--- a/packages/integration-react/src/api/ScmAuth.test.ts
+++ b/packages/integration-react/src/api/ScmAuth.test.ts
@@ -238,7 +238,7 @@ describe('ScmAuth', () => {
await expect(
emptyMux.getCredentials({ url: 'http://example.com' }),
).rejects.toThrow(
- "No authentication provider available for access to 'http://example.com'",
+ "No auth provider available for 'http://example.com', see https://backstage.io/link?scm-auth",
);
const scmAuth = ScmAuth.merge(
@@ -256,12 +256,12 @@ describe('ScmAuth', () => {
await expect(
scmAuth.getCredentials({ url: 'http://not.example.com' }),
).rejects.toThrow(
- "No authentication provider available for access to 'http://not.example.com'",
+ "No auth provider available for 'http://not.example.com', see https://backstage.io/link?scm-auth",
);
await expect(
scmAuth.getCredentials({ url: 'http://example.com:8080' }),
).rejects.toThrow(
- "No authentication provider available for access to 'http://example.com:8080'",
+ "No auth provider available for 'http://example.com:8080', see https://backstage.io/link?scm-auth",
);
});
});
diff --git a/packages/integration-react/src/api/ScmAuth.ts b/packages/integration-react/src/api/ScmAuth.ts
index 071374e6cb..b3dab4029e 100644
--- a/packages/integration-react/src/api/ScmAuth.ts
+++ b/packages/integration-react/src/api/ScmAuth.ts
@@ -53,7 +53,7 @@ class ScmAuthMux implements ScmAuthApi {
const provider = this.#providers.find(p => p.isUrlSupported(url));
if (!provider) {
throw new Error(
- `No authentication provider available for access to '${options.url}'`,
+ `No auth provider available for '${options.url}', see https://backstage.io/link?scm-auth`,
);
}
diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md
index f8f53e959b..af764c3b69 100644
--- a/packages/integration/CHANGELOG.md
+++ b/packages/integration/CHANGELOG.md
@@ -1,5 +1,28 @@
# @backstage/integration
+## 0.7.5
+
+### Patch Changes
+
+- 4e1384884f: Fixed bug in integration package where Self Hosted GitLab instances with custom ports weren't supported (because of the lack of an option to add the port in the integration configs. Now users can add the port directly in the host)
+
+## 0.7.4
+
+### Patch Changes
+
+- Fix for the previous release with missing type declarations.
+- Updated dependencies
+ - @backstage/config@0.1.15
+
+## 0.7.3
+
+### Patch Changes
+
+- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5
+- c77c5c7eb6: Added `backstage.role` to `package.json`
+- Updated dependencies
+ - @backstage/config@0.1.14
+
## 0.7.2
### Patch Changes
@@ -212,7 +235,7 @@
- 0fd4ea443: Updates the `GithubCredentialsProvider` to return the token type, it can either be `token` or `app` depending on the authentication method.
- Update the `GithubOrgReaderProcessor` NOT to query for email addresses if GitHub Apps is used for authentication, this is due to inconsistencies in the GitHub API when using server to server communications and installation tokens. https://github.community/t/api-v4-unable-to-retrieve-email-resource-not-accessible-by-integration/13831/4 for more info.
+ Update the `GithubOrgReaderProcessor` NOT to query for email addresses if GitHub Apps is used for authentication, this is due to inconsistencies in the GitHub API when using server to server communications and installation tokens. See [this community discussion](https://github.community/t/api-v4-unable-to-retrieve-email-resource-not-accessible-by-integration/13831/4) for more info.
**Removes** deprecated GithubOrgReaderProcessor provider configuration(`catalog.processors.githubOrg`). If you're using the deprecated config section make sure to migrate to [integrations](https://backstage.io/docs/integrations/github/locations) instead.
diff --git a/packages/integration/api-report.md b/packages/integration/api-report.md
index 10da05784c..9a6ba03f8e 100644
--- a/packages/integration/api-report.md
+++ b/packages/integration/api-report.md
@@ -88,7 +88,7 @@ export class BitbucketIntegration implements ScmIntegration {
// @public
export type BitbucketIntegrationConfig = {
host: string;
- apiBaseUrl?: string;
+ apiBaseUrl: string;
token?: string;
username?: string;
appPassword?: string;
diff --git a/packages/integration/package.json b/packages/integration/package.json
index d6d0edd77a..bf7c167bfa 100644
--- a/packages/integration/package.json
+++ b/packages/integration/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/integration",
"description": "Helpers for managing integrations towards external systems",
- "version": "0.7.2",
+ "version": "0.7.5",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -12,6 +12,9 @@
"module": "dist/index.esm.js",
"types": "dist/index.d.ts"
},
+ "backstage": {
+ "role": "common-library"
+ },
"homepage": "https://backstage.io",
"repository": {
"type": "git",
@@ -22,15 +25,15 @@
"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"
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean"
},
"dependencies": {
- "@backstage/config": "^0.1.13",
+ "@backstage/config": "^0.1.15",
"cross-fetch": "^3.1.5",
"git-url-parse": "^11.6.0",
"@octokit/rest": "^18.5.3",
@@ -39,9 +42,9 @@
"lodash": "^4.17.21"
},
"devDependencies": {
- "@backstage/cli": "^0.13.2-next.0",
- "@backstage/config-loader": "^0.9.3",
- "@backstage/test-utils": "^0.2.4-next.0",
+ "@backstage/cli": "^0.14.1",
+ "@backstage/config-loader": "^0.9.6",
+ "@backstage/test-utils": "^0.2.6",
"@types/jest": "^26.0.7",
"@types/luxon": "^2.0.4",
"msw": "^0.35.0"
diff --git a/packages/integration/src/bitbucket/BitbucketIntegration.test.ts b/packages/integration/src/bitbucket/BitbucketIntegration.test.ts
index 81b9be4e25..6bbe1be27b 100644
--- a/packages/integration/src/bitbucket/BitbucketIntegration.test.ts
+++ b/packages/integration/src/bitbucket/BitbucketIntegration.test.ts
@@ -45,8 +45,10 @@ describe('BitbucketIntegration', () => {
expect(integration.title).toBe('h.com');
});
- it('resolves url line number correctly', () => {
- const integration = new BitbucketIntegration({ host: 'h.com' } as any);
+ it('resolves url line number correctly for Bitbucket Cloud', () => {
+ const integration = new BitbucketIntegration({
+ host: 'bitbucket.org',
+ } as any);
expect(
integration.resolveUrl({
@@ -55,10 +57,22 @@ describe('BitbucketIntegration', () => {
lineNumber: 14,
}),
).toBe(
- 'https://bitbucket.org/my-owner/my-project/src/master/a.yaml#a.yaml-14',
+ 'https://bitbucket.org/my-owner/my-project/src/master/a.yaml#lines-14',
);
});
+ it('resolves url line number correctly for Bitbucket Server', () => {
+ const integration = new BitbucketIntegration({ host: 'h.com' } as any);
+
+ expect(
+ integration.resolveUrl({
+ url: './a.yaml',
+ base: 'https://bitbucket.org/my-owner/my-project/src/master/README.md',
+ lineNumber: 14,
+ }),
+ ).toBe('https://bitbucket.org/my-owner/my-project/src/master/a.yaml#14');
+ });
+
it('resolve edit URL', () => {
const integration = new BitbucketIntegration({ host: 'h.com' } as any);
diff --git a/packages/integration/src/bitbucket/BitbucketIntegration.ts b/packages/integration/src/bitbucket/BitbucketIntegration.ts
index 6c21d716b7..0162463e3c 100644
--- a/packages/integration/src/bitbucket/BitbucketIntegration.ts
+++ b/packages/integration/src/bitbucket/BitbucketIntegration.ts
@@ -60,17 +60,21 @@ export class BitbucketIntegration implements ScmIntegration {
lineNumber?: number;
}): string {
const resolved = defaultScmResolveUrl(options);
-
- // Bitbucket line numbers use the syntax #example.txt-42, rather than #L42
- if (options.lineNumber) {
- const url = new URL(resolved);
-
- const filename = url.pathname.split('/').slice(-1)[0];
- url.hash = `${filename}-${options.lineNumber}`;
- return url.toString();
+ if (!options.lineNumber) {
+ return resolved;
}
- return resolved;
+ const url = new URL(resolved);
+
+ if (this.integrationConfig.host === 'bitbucket.org') {
+ // Bitbucket Cloud uses the syntax #lines-{start}[:{end}][,...]
+ url.hash = `lines-${options.lineNumber}`;
+ } else {
+ // Bitbucket Server uses the syntax #{start}[-{end}][,...]
+ url.hash = `${options.lineNumber}`;
+ }
+
+ return url.toString();
}
resolveEditUrl(url: string): string {
diff --git a/packages/integration/src/bitbucket/config.ts b/packages/integration/src/bitbucket/config.ts
index 1cd911aad3..44a2f0cc1f 100644
--- a/packages/integration/src/bitbucket/config.ts
+++ b/packages/integration/src/bitbucket/config.ts
@@ -36,12 +36,10 @@ export type BitbucketIntegrationConfig = {
* The base URL of the API of this provider, e.g. "https://api.bitbucket.org/2.0",
* with no trailing slash.
*
- * May be omitted specifically for Bitbucket Cloud; then it will be deduced.
- *
- * The API will always be preferred if both its base URL and a token are
- * present.
+ * Values omitted at the optional property at the app-config will be deduced
+ * from the "host" value.
*/
- apiBaseUrl?: string;
+ apiBaseUrl: string;
/**
* The authorization token to use for requests to a Bitbucket Server provider.
@@ -90,6 +88,8 @@ export function readBitbucketIntegrationConfig(
apiBaseUrl = trimEnd(apiBaseUrl, '/');
} else if (host === BITBUCKET_HOST) {
apiBaseUrl = BITBUCKET_API_BASE_URL;
+ } else {
+ apiBaseUrl = `https://${host}/rest/api/1.0`;
}
return {
diff --git a/packages/integration/src/gitlab/config.ts b/packages/integration/src/gitlab/config.ts
index f74b849c74..71b4cd868f 100644
--- a/packages/integration/src/gitlab/config.ts
+++ b/packages/integration/src/gitlab/config.ts
@@ -82,11 +82,7 @@ export function readGitLabIntegrationConfig(
baseUrl = `https://${host}`;
}
- if (host.includes(':')) {
- throw new Error(
- `Invalid GitLab integration config, host '${host}' should just be the host name (e.g. "github.com"), not a URL`,
- );
- } else if (!isValidHost(host)) {
+ if (!isValidHost(host)) {
throw new Error(
`Invalid GitLab integration config, '${host}' is not a valid host`,
);
diff --git a/packages/integration/src/gitlab/core.ts b/packages/integration/src/gitlab/core.ts
index c5b0713340..b379d3d129 100644
--- a/packages/integration/src/gitlab/core.ts
+++ b/packages/integration/src/gitlab/core.ts
@@ -138,7 +138,7 @@ export async function getProjectId(
// Convert
// to: https://gitlab.com/api/v4/projects/groupA%2Fteams%2FsubgroupA%2FteamA%2Frepo
const repoIDLookup = new URL(
- `${url.protocol + url.hostname}/api/v4/projects/${encodeURIComponent(
+ `${url.origin}/api/v4/projects/${encodeURIComponent(
repo.replace(/^\//, ''),
)}`,
);
diff --git a/packages/integration/src/helpers.test.ts b/packages/integration/src/helpers.test.ts
index a69c7faec9..60a2789f05 100644
--- a/packages/integration/src/helpers.test.ts
+++ b/packages/integration/src/helpers.test.ts
@@ -24,7 +24,10 @@ import {
describe('basicIntegrations', () => {
describe('byUrl', () => {
it('handles hosts without a port', () => {
- const integration = new BitbucketIntegration({ host: 'host.com' });
+ const integration = new BitbucketIntegration({
+ host: 'host.com',
+ apiBaseUrl: 'a',
+ });
const integrations = basicIntegrations(
[integration],
i => i.config.host,
@@ -33,7 +36,10 @@ describe('basicIntegrations', () => {
expect(integrations.byUrl('https://host.com:8080/a')).toBeUndefined();
});
it('handles hosts with a port', () => {
- const integration = new BitbucketIntegration({ host: 'host.com:8080' });
+ const integration = new BitbucketIntegration({
+ host: 'host.com:8080',
+ apiBaseUrl: 'a',
+ });
const integrations = basicIntegrations(
[integration],
i => i.config.host,
diff --git a/packages/release-manifests/CHANGELOG.md b/packages/release-manifests/CHANGELOG.md
index 61e6c45992..61113e1c76 100644
--- a/packages/release-manifests/CHANGELOG.md
+++ b/packages/release-manifests/CHANGELOG.md
@@ -1,5 +1,12 @@
# @backstage/release-manifests
+## 0.0.2
+
+### Patch Changes
+
+- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5
+- c77c5c7eb6: Added `backstage.role` to `package.json`
+
## 0.0.1
### Patch Changes
diff --git a/packages/release-manifests/package.json b/packages/release-manifests/package.json
index 8ddbb73bca..7ec69a35e9 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.1",
+ "version": "0.0.2",
"private": false,
"main": "src/index.ts",
"types": "src/index.ts",
@@ -11,6 +11,9 @@
"module": "dist/index.esm.js",
"types": "dist/index.d.ts"
},
+ "backstage": {
+ "role": "common-library"
+ },
"homepage": "https://backstage.io",
"repository": {
"type": "git",
@@ -22,18 +25,18 @@
],
"license": "Apache-2.0",
"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"
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean"
},
"dependencies": {
"cross-fetch": "^3.1.5"
},
"devDependencies": {
- "@backstage/test-utils": "^0.2.3",
+ "@backstage/test-utils": "^0.2.5",
"msw": "^0.35.0",
"@types/jest": "^26.0.7",
"@types/node": "^14.14.32"
diff --git a/packages/search-common/CHANGELOG.md b/packages/search-common/CHANGELOG.md
index 4460374646..71f2952d90 100644
--- a/packages/search-common/CHANGELOG.md
+++ b/packages/search-common/CHANGELOG.md
@@ -1,5 +1,23 @@
# @backstage/search-common
+## 0.2.4
+
+### Patch Changes
+
+- Fix for the previous release with missing type declarations.
+- Updated dependencies
+ - @backstage/types@0.1.3
+ - @backstage/plugin-permission-common@0.5.1
+
+## 0.2.3
+
+### Patch Changes
+
+- c77c5c7eb6: Added `backstage.role` to `package.json`
+- Updated dependencies
+ - @backstage/plugin-permission-common@0.5.0
+ - @backstage/types@0.1.2
+
## 0.2.2
### Patch Changes
diff --git a/packages/search-common/api-report.md b/packages/search-common/api-report.md
index 65f9f25180..475d85e11c 100644
--- a/packages/search-common/api-report.md
+++ b/packages/search-common/api-report.md
@@ -3,38 +3,33 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
+///
+
import { JsonObject } from '@backstage/types';
import { Permission } from '@backstage/plugin-permission-common';
+import { Readable } from 'stream';
+import { Transform } from 'stream';
+import { Writable } from 'stream';
-// Warning: (ae-missing-release-tag) "DocumentCollator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public
-export interface DocumentCollator {
- // (undocumented)
- execute(): Promise;
+// @beta
+export interface DocumentCollatorFactory {
+ getCollator(): Promise;
readonly type: string;
readonly visibilityPermission?: Permission;
}
-// Warning: (ae-missing-release-tag) "DocumentDecorator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public
-export interface DocumentDecorator {
- // (undocumented)
- execute(documents: IndexableDocument[]): Promise;
+// @beta
+export interface DocumentDecoratorFactory {
+ getDecorator(): Promise;
readonly types?: string[];
}
-// Warning: (ae-missing-release-tag) "DocumentTypeInfo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public
+// @beta
export type DocumentTypeInfo = {
visibilityPermission?: Permission;
};
-// Warning: (ae-missing-release-tag) "IndexableDocument" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public
+// @beta
export interface IndexableDocument {
authorization?: {
resourceRef: string;
@@ -44,23 +39,17 @@ export interface IndexableDocument {
title: string;
}
-// Warning: (ae-missing-release-tag) "QueryRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @beta
export type QueryRequestOptions = {
token?: string;
};
-// Warning: (ae-missing-release-tag) "QueryTranslator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public
+// @beta
export type QueryTranslator = (query: SearchQuery) => unknown;
-// Warning: (ae-missing-release-tag) "SearchEngine" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public
+// @beta
export interface SearchEngine {
- index(type: string, documents: IndexableDocument[]): Promise;
+ getIndexer(type: string): Promise;
query(
query: SearchQuery,
options?: QueryRequestOptions,
@@ -68,9 +57,7 @@ export interface SearchEngine {
setTranslator(translator: QueryTranslator): void;
}
-// Warning: (ae-missing-release-tag) "SearchQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @beta (undocumented)
export interface SearchQuery {
// (undocumented)
filters?: JsonObject;
@@ -82,9 +69,7 @@ export interface SearchQuery {
types?: string[];
}
-// Warning: (ae-missing-release-tag) "SearchResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @beta (undocumented)
export interface SearchResult {
// (undocumented)
document: IndexableDocument;
@@ -92,9 +77,7 @@ export interface SearchResult {
type: string;
}
-// Warning: (ae-missing-release-tag) "SearchResultSet" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @beta (undocumented)
export interface SearchResultSet {
// (undocumented)
nextPageCursor?: string;
diff --git a/packages/search-common/package.json b/packages/search-common/package.json
index 10b03ab663..ef56017405 100644
--- a/packages/search-common/package.json
+++ b/packages/search-common/package.json
@@ -1,7 +1,7 @@
{
"name": "@backstage/search-common",
"description": "Common functionalities for Search, to be shared between various search-enabled plugins",
- "version": "0.2.2",
+ "version": "0.2.4",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -10,6 +10,9 @@
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts"
},
+ "backstage": {
+ "role": "common-library"
+ },
"homepage": "https://backstage.io",
"repository": {
"type": "git",
@@ -25,22 +28,22 @@
"dist"
],
"scripts": {
- "build": "backstage-cli build --outputs cjs,types",
- "lint": "backstage-cli lint",
- "test": "backstage-cli test",
- "prepack": "backstage-cli prepack",
- "postpack": "backstage-cli postpack",
- "clean": "backstage-cli clean"
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean"
},
"bugs": {
"url": "https://github.com/backstage/backstage/issues"
},
"dependencies": {
- "@backstage/types": "^0.1.1",
- "@backstage/plugin-permission-common": "^0.4.0-next.0"
+ "@backstage/types": "^0.1.3",
+ "@backstage/plugin-permission-common": "^0.5.1"
},
"devDependencies": {
- "@backstage/cli": "^0.13.2-next.0"
+ "@backstage/cli": "^0.14.0"
},
"jest": {
"roots": [
diff --git a/packages/search-common/src/types.ts b/packages/search-common/src/types.ts
index 4e61767ea0..51ce45617b 100644
--- a/packages/search-common/src/types.ts
+++ b/packages/search-common/src/types.ts
@@ -16,7 +16,11 @@
import { Permission } from '@backstage/plugin-permission-common';
import { JsonObject } from '@backstage/types';
+import { Readable, Transform, Writable } from 'stream';
+/**
+ * @beta
+ */
export interface SearchQuery {
term: string;
filters?: JsonObject;
@@ -24,11 +28,17 @@ export interface SearchQuery {
pageCursor?: string;
}
+/**
+ * @beta
+ */
export interface SearchResult {
type: string;
document: IndexableDocument;
}
+/**
+ * @beta
+ */
export interface SearchResultSet {
results: SearchResult[];
nextPageCursor?: string;
@@ -38,6 +48,7 @@ export interface SearchResultSet {
/**
* Base properties that all indexed documents must include, as well as some
* common properties that documents are encouraged to use where appropriate.
+ * @beta
*/
export interface IndexableDocument {
/**
@@ -72,6 +83,7 @@ export interface IndexableDocument {
* Information about a specific document type. Intended to be used in the
* {@link @backstage/search-backend-node#IndexBuilder} to collect information
* about the types stored in the index.
+ * @beta
*/
export type DocumentTypeInfo = {
/**
@@ -82,10 +94,10 @@ export type DocumentTypeInfo = {
};
/**
- * Interface that must be implemented in order to expose new documents to
- * search.
+ * Factory class for instantiating collators.
+ * @beta
*/
-export interface DocumentCollator {
+export interface DocumentCollatorFactory {
/**
* The type or name of the document set returned by this collator. Used as an
* index name by Search Engines.
@@ -98,29 +110,41 @@ export interface DocumentCollator {
*/
readonly visibilityPermission?: Permission;
- execute(): Promise;
+ /**
+ * Instantiates and resolves a document collator.
+ */
+ getCollator(): Promise;
}
/**
- * Interface that must be implemented in order to decorate existing documents with
- * additional metadata.
+ * Factory class for instantiating decorators.
+ * @beta
*/
-export interface DocumentDecorator {
+export interface DocumentDecoratorFactory {
/**
* An optional array of document/index types on which this decorator should
* be applied. If no types are provided, this decorator will be applied to
* all document/index types.
*/
readonly types?: string[];
- execute(documents: IndexableDocument[]): Promise;
+
+ /**
+ * Instantiates and resolves a document decorator.
+ */
+ getDecorator(): Promise;
}
/**
* A type of function responsible for translating an abstract search query into
* a concrete query relevant to a particular search engine.
+ * @beta
*/
export type QueryTranslator = (query: SearchQuery) => unknown;
+/**
+ * Options when querying a search engine.
+ * @beta
+ */
export type QueryRequestOptions = {
token?: string;
};
@@ -129,6 +153,7 @@ export type QueryRequestOptions = {
* Interface that must be implemented by specific search engines, responsible
* for performing indexing and querying and translating abstract queries into
* concrete, search engine-specific queries.
+ * @beta
*/
export interface SearchEngine {
/**
@@ -137,9 +162,15 @@ export interface SearchEngine {
setTranslator(translator: QueryTranslator): void;
/**
- * Add the given documents to the SearchEngine index of the given type.
+ * Factory method for getting a search engine indexer for a given document
+ * type.
+ *
+ * @param type - The type or name of the document set for which an indexer
+ * should be retrieved. This corresponds to the `type` property on the
+ * document collator/decorator factories and will most often be used to
+ * identify an index or group to which documents should be written.
*/
- index(type: string, documents: IndexableDocument[]): Promise;
+ getIndexer(type: string): Promise;
/**
* Perform a search query against the SearchEngine.
diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md
index 38726ce10e..1302d1ca9d 100644
--- a/packages/techdocs-cli-embedded-app/CHANGELOG.md
+++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md
@@ -1,5 +1,39 @@
# techdocs-cli-embedded-app
+## 0.2.65
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/plugin-catalog@0.9.0
+ - @backstage/cli@0.14.1
+ - @backstage/core-components@0.8.10
+ - @backstage/plugin-techdocs@0.14.0
+ - @backstage/catalog-model@0.11.0
+ - @backstage/core-plugin-api@0.7.0
+ - @backstage/app-defaults@0.1.9
+ - @backstage/core-app-api@0.5.4
+ - @backstage/integration-react@0.1.23
+ - @backstage/test-utils@0.2.6
+
+## 0.2.64
+
+### Patch Changes
+
+- Updated dependencies
+ - @backstage/cli@0.14.0
+ - @backstage/core-app-api@0.5.3
+ - @backstage/core-components@0.8.9
+ - @backstage/core-plugin-api@0.6.1
+ - @backstage/integration-react@0.1.22
+ - @backstage/test-utils@0.2.5
+ - @backstage/plugin-catalog@0.8.0
+ - @backstage/plugin-techdocs@0.13.4
+ - @backstage/app-defaults@0.1.8
+ - @backstage/catalog-model@0.10.0
+ - @backstage/config@0.1.14
+ - @backstage/theme@0.2.15
+
## 0.2.63
### Patch Changes
diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json
index 975bfef43b..6719701378 100644
--- a/packages/techdocs-cli-embedded-app/package.json
+++ b/packages/techdocs-cli-embedded-app/package.json
@@ -1,21 +1,24 @@
{
"name": "techdocs-cli-embedded-app",
- "version": "0.2.63",
+ "version": "0.2.65",
"private": true,
+ "backstage": {
+ "role": "frontend"
+ },
"bundled": true,
"dependencies": {
- "@backstage/app-defaults": "^0.1.7",
- "@backstage/catalog-model": "^0.9.10",
- "@backstage/cli": "^0.13.2",
- "@backstage/config": "^0.1.13",
- "@backstage/core-app-api": "^0.5.2",
- "@backstage/core-components": "^0.8.8",
- "@backstage/core-plugin-api": "^0.6.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",
+ "@backstage/app-defaults": "^0.1.9",
+ "@backstage/catalog-model": "^0.11.0",
+ "@backstage/cli": "^0.14.1",
+ "@backstage/config": "^0.1.15",
+ "@backstage/core-app-api": "^0.5.4",
+ "@backstage/core-components": "^0.8.10",
+ "@backstage/core-plugin-api": "^0.7.0",
+ "@backstage/integration-react": "^0.1.23",
+ "@backstage/plugin-catalog": "^0.9.0",
+ "@backstage/plugin-techdocs": "^0.14.0",
+ "@backstage/test-utils": "^0.2.6",
+ "@backstage/theme": "^0.2.15",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"history": "^5.0.0",
@@ -26,7 +29,7 @@
"react-use": "^17.2.4"
},
"devDependencies": {
- "@backstage/cli": "^0.13.2",
+ "@backstage/cli": "^0.14.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.1.8",
@@ -34,16 +37,16 @@
"@types/node": "^14.14.32",
"@types/react-dom": "*",
"cross-env": "^7.0.0",
- "cypress": "^7.3.0",
+ "cypress": "^9.5.0",
"eslint-plugin-cypress": "^2.10.3",
"start-server-and-test": "^1.10.11"
},
"scripts": {
- "start": "backstage-cli app:serve --config ./app-config.yaml",
- "build": "backstage-cli app:build --config ./app-config.yaml",
- "clean": "backstage-cli clean",
- "test": "backstage-cli test",
- "lint": "backstage-cli lint",
+ "start": "backstage-cli package start --config ./app-config.yaml",
+ "build": "backstage-cli package build --config ./app-config.yaml",
+ "clean": "backstage-cli package clean",
+ "test": "backstage-cli package test",
+ "lint": "backstage-cli package lint",
"test:e2e": "cross-env PORT=3001 start-server-and-test start http://localhost:3001 cy:dev",
"test:e2e:ci": "cross-env PORT=3001 start-server-and-test start http://localhost:3001 cy:run",
"cy:dev": "cypress open",
diff --git a/packages/techdocs-cli-embedded-app/src/components/Root/Root.tsx b/packages/techdocs-cli-embedded-app/src/components/Root/Root.tsx
index 65e75a488a..249394fdc4 100644
--- a/packages/techdocs-cli-embedded-app/src/components/Root/Root.tsx
+++ b/packages/techdocs-cli-embedded-app/src/components/Root/Root.tsx
@@ -14,18 +14,20 @@
* limitations under the License.
*/
-import React, { useContext, PropsWithChildren } from 'react';
+import React, { PropsWithChildren, useContext } from 'react';
+
import { Link, makeStyles } from '@material-ui/core';
import LibraryBooks from '@material-ui/icons/LibraryBooks';
import LogoFull from './LogoFull';
import LogoIcon from './LogoIcon';
+
import {
Sidebar,
+ SidebarItem,
SidebarPage,
sidebarConfig,
- SidebarContext,
- SidebarItem,
SidebarDivider,
+ SidebarContext,
} from '@backstage/core-components';
import { NavLink } from 'react-router-dom';
@@ -70,7 +72,7 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
{/* Global nav, not org-specific */}
{/* End global nav */}
diff --git a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx
index b90a49fb22..d9a518c165 100644
--- a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx
+++ b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx
@@ -14,7 +14,22 @@
* limitations under the License.
*/
-import React from 'react';
+import React, {
+ FC,
+ createContext,
+ useContext,
+ useState,
+ useCallback,
+} from 'react';
+
+import { Theme, makeStyles } from '@material-ui/core';
+
+import { ThemeProvider, Box, Tooltip, IconButton } from '@material-ui/core';
+import LightIcon from '@material-ui/icons/Brightness7';
+import DarkIcon from '@material-ui/icons/Brightness4';
+
+import { lightTheme, darkTheme } from '@backstage/theme';
+import { EntityName } from '@backstage/catalog-model';
import { Content } from '@backstage/core-components';
@@ -24,6 +39,106 @@ import {
TechDocsPageHeader,
} from '@backstage/plugin-techdocs';
+const useStyles = makeStyles((theme: Theme) => ({
+ headerIcon: {
+ color: theme.palette.common.white,
+ width: '32px',
+ height: '32px',
+ },
+ content: {
+ backgroundColor: theme.palette.background.default,
+ },
+ contentToolbar: {
+ display: 'flex',
+ justifyContent: 'flex-end',
+ padding: 0,
+ },
+}));
+
+enum Themes {
+ LIGHT = 'light',
+ DARK = 'dark',
+}
+
+type TechDocsThemeValue = {
+ theme: Themes;
+ toggleTheme: () => void;
+};
+
+const TechDocsThemeContext = createContext({
+ theme: Themes.LIGHT,
+ toggleTheme: () => {},
+});
+
+const TechdocsThemeProvider: FC = ({ children }) => {
+ const [theme, setTheme] = useState(Themes.LIGHT);
+
+ const toggleTheme = useCallback(() => {
+ setTheme(prevTheme =>
+ prevTheme === Themes.LIGHT ? Themes.DARK : Themes.LIGHT,
+ );
+ }, [setTheme]);
+
+ const value = { theme, toggleTheme };
+
+ const themes = {
+ [Themes.LIGHT]: lightTheme,
+ [Themes.DARK]: darkTheme,
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+const useTechDocsTheme = () => useContext(TechDocsThemeContext);
+
+const TechDocsThemeToggle = () => {
+ const classes = useStyles();
+ const { theme, toggleTheme } = useTechDocsTheme();
+
+ const themes = {
+ [Themes.LIGHT]: {
+ icon: DarkIcon,
+ title: 'Dark theme',
+ },
+ [Themes.DARK]: {
+ icon: LightIcon,
+ title: 'Light theme',
+ },
+ };
+
+ const { title, icon: Icon } = themes[theme];
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+const TechDocsPageContent = ({
+ onReady,
+ entityRef,
+}: {
+ entityRef: EntityName;
+ onReady: () => void;
+}) => {
+ const classes = useStyles();
+
+ return (
+
+
+
+ );
+};
+
const DefaultTechDocsPage = () => {
const techDocsMetadata = {
site_name: 'Live preview environment',
@@ -35,20 +150,20 @@ const DefaultTechDocsPage = () => {
{({ entityRef, onReady }) => (
<>
-
-
-
+ techDocsMetadata={techDocsMetadata}
+ >
+
+
+
>
)}
);
};
-export const techDocsPage = ;
+export const techDocsPage = (
+
+
+
+);
diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md
index 98015f766a..bc23499662 100644
--- a/packages/techdocs-cli/CHANGELOG.md
+++ b/packages/techdocs-cli/CHANGELOG.md
@@ -1,5 +1,31 @@
# @techdocs/cli
+## 0.8.15
+
+### Patch Changes
+
+- ed78516480: chore(deps-dev): bump `cypress` from 7.3.0 to 9.5.0
+- 209fd128e6: Updated usage of `github:` location types in docs to use `url:` instead.
+- 61ff215e08: - Adds `cypress` and `cypress-plugin-snapshots` as dependencies for integration and visual regression tests.
+ - Updates README documentation with instructions for how to run tests.
+ - Clarifies output text for prepack script.
+- Updated dependencies
+ - @backstage/backend-common@0.11.0
+ - @backstage/catalog-model@0.11.0
+ - @backstage/techdocs-common@0.11.10
+
+## 0.8.14
+
+### Patch Changes
+
+- c77c5c7eb6: Added `backstage.role` to `package.json`
+- Updated dependencies
+ - @backstage/backend-common@0.10.8
+ - @backstage/catalog-model@0.10.0
+ - @backstage/cli-common@0.1.7
+ - @backstage/config@0.1.14
+ - @backstage/techdocs-common@0.11.8
+
## 0.8.13
### Patch Changes
diff --git a/packages/techdocs-cli/README.md b/packages/techdocs-cli/README.md
index 3ac423cb38..ae296d2c26 100644
--- a/packages/techdocs-cli/README.md
+++ b/packages/techdocs-cli/README.md
@@ -17,7 +17,7 @@ bundle into the `packages/techdocs-cli/dist` which is then published with the
```sh
# From the root of this repository run
# NOTE: This will build the techdocs-cli-embedded-app and copy the output into the cli dist directory
-yarn build --scope @techdocs/cli
+yarn workspace @techdocs/cli build
# Now execute the binary
packages/techdocs-cli/bin/techdocs-cli
@@ -40,8 +40,25 @@ yarn start
yarn techdocs-cli:dev [...options]
```
+### Using an example docs project
+
+For the purpose of local development, we have created an example documentation project. You are of course also free to create your own local test site - all it takes is a `docs/index.md` and an `mkdocs.yml` in a directory.
+
+```sh
+
+cd packages/techdocs-cli/src/example-docs
+
+# To get a view of your docs in Backstage, use:
+techdocs-cli serve
+
+# To view the raw mkdocs site (without Backstage), use:
+techdocs-cli serve:mkdocs
+```
+
### Testing
+#### E2E tests
+
Running unit tests requires mkdocs to be installed locally:
```sh
@@ -51,18 +68,37 @@ pip install mkdocs-techdocs-core
Then run `yarn test`.
-### Use an example docs project
+#### Cypress (Integration and Visual regression) tests
-We have created an [example documentation project](https://github.com/backstage/techdocs-container/tree/main/mock-docs) and it's shipped with [techdocs-container](https://github.com/backstage/techdocs-container) repository, for the purpose of local development. But you are free to create your own local test site. All it takes is a `docs/index.md` and `mkdocs.yml` in a directory.
+Running cypress tests requires you to run the CLI locally against our example docs.
+
+Run the local version of techdocs-cli against the example docs:
```sh
-git clone https://github.com/backstage/techdocs-container.git
+# From the root of this repository run
+# NOTE: This will build the techdocs-cli-embedded-app and copy the output into the cli dist directory
+yarn build --scope @techdocs/cli
-cd techdocs-container/mock-docs
+# Navigate to the example project
+cd packages/techdocs-cli/src/example-docs
-# To get a view of your docs in Backstage, use:
-techdocs-cli serve
-
-# To view the raw mkdocs site (without Backstage), use:
-techdocs-cli serve:mkdocs
+# Now execute the techdocs-cli serve command
+../../bin/techdocs-cli serve
```
+
+In another shell, run the cypress tests:
+
+```sh
+# From the root of the project, navigate to the techdocs-cli package
+cd packages/techdocs-cli
+
+# Run tests
+yarn test:cypress
+```
+
+This will launch a cypress app where you can run the two different tests:
+
+- `backstage_serve` - will run against the backstage server
+- `mkdocs_serve` - will run test against the mkdocs server
+
+> If its the first time you run Cypress, it will run a "Verifying Cypress can run" step. This step can result in a "Cypress verification timed out" error. If that is the case, let the verification step run and then run the command again and it should succeed.
diff --git a/packages/techdocs-cli/cypress.json b/packages/techdocs-cli/cypress.json
new file mode 100644
index 0000000000..b6f3b96019
--- /dev/null
+++ b/packages/techdocs-cli/cypress.json
@@ -0,0 +1,17 @@
+{
+ "env": {
+ "mkDocsBaseUrl": "http://localhost:8000",
+ "backstageBaseUrl": "http://localhost:3000",
+ "cypress-plugin-snapshots": {
+ "autoCleanUp": false,
+ "imageConfig": {
+ "resizeDevicePixelRatio": true,
+ "threshold": 0.01
+ }
+ }
+ },
+ "viewportWidth": 1920,
+ "viewportHeight": 1080,
+ "includeShadowDom": true,
+ "ignoreTestFiles": ["**/__snapshots__/*", "**/__image_snapshots__/*"]
+}
diff --git a/packages/techdocs-cli/cypress/.eslintrc.json b/packages/techdocs-cli/cypress/.eslintrc.json
new file mode 100644
index 0000000000..2481ac5715
--- /dev/null
+++ b/packages/techdocs-cli/cypress/.eslintrc.json
@@ -0,0 +1,21 @@
+{
+ "plugins": ["cypress"],
+ "extends": ["plugin:cypress/recommended"],
+ "rules": {
+ "jest/expect-expect": [
+ "error",
+ {
+ "assertFunctionNames": ["expect", "cy.contains", "cy.document"]
+ }
+ ],
+ "import/no-extraneous-dependencies": [
+ "error",
+ {
+ "devDependencies": true,
+ "optionalDependencies": true,
+ "peerDependencies": true,
+ "bundledDependencies": true
+ }
+ ]
+ }
+}
diff --git a/packages/techdocs-cli/cypress/fixtures/example.json b/packages/techdocs-cli/cypress/fixtures/example.json
new file mode 100644
index 0000000000..02e4254378
--- /dev/null
+++ b/packages/techdocs-cli/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/packages/techdocs-cli/cypress/integration/__image_snapshots__/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0.png b/packages/techdocs-cli/cypress/integration/__image_snapshots__/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0.png
new file mode 100644
index 0000000000..99fc1ea483
Binary files /dev/null and b/packages/techdocs-cli/cypress/integration/__image_snapshots__/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0.png differ
diff --git a/packages/techdocs-cli/cypress/integration/__image_snapshots__/TechDocs Live Preview - MkDocs Serve toMatchImageSnapshot - MkDocs Page #0.png b/packages/techdocs-cli/cypress/integration/__image_snapshots__/TechDocs Live Preview - MkDocs Serve toMatchImageSnapshot - MkDocs Page #0.png
new file mode 100644
index 0000000000..e6c63d5d57
Binary files /dev/null and b/packages/techdocs-cli/cypress/integration/__image_snapshots__/TechDocs Live Preview - MkDocs Serve toMatchImageSnapshot - MkDocs Page #0.png differ
diff --git a/packages/techdocs-cli/cypress/integration/backstage_serve.js b/packages/techdocs-cli/cypress/integration/backstage_serve.js
new file mode 100644
index 0000000000..15fc03f8f4
--- /dev/null
+++ b/packages/techdocs-cli/cypress/integration/backstage_serve.js
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+///
+describe('TechDocs Live Preview - Backstage Serve', () => {
+ it('successfully serves documentation', () => {
+ cy.visit(`${Cypress.env('backstageBaseUrl')}/docs/default/component/local`);
+ cy.contains('hello mock docs');
+ });
+
+ it('successfully navigates to sub page of documentation', () => {
+ cy.contains('SubDocs').click();
+ cy.contains('Home 2').click();
+ cy.contains(
+ 'This is an md file in another docs folder using the MkDocs Monorepo Plugin',
+ );
+ });
+
+ it('successfully renders all Backstage main elements', () => {
+ cy.contains('header', 'Live preview environment');
+ cy.get('[data-testid="sidebar-root"]')
+ .children()
+ .should('have.length.gt', 0);
+ });
+
+ it('successfully renders all extracted MkDocs main elements', () => {
+ // as it gets replaced by Backstage header
+ cy.get('.md-header').should('have.length', 0);
+ cy.get('.md-main').should('have.length', 1);
+ cy.contains(
+ '.md-main',
+ 'This is an md file in another docs folder using the MkDocs Monorepo Plugin',
+ );
+ cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1);
+ cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1);
+ cy.get('.md-footer').should('have.length', 1);
+ });
+
+ it('toMatchImageSnapshot - Backstage TechDocs Page', () => {
+ cy.visit(
+ `${Cypress.env('backstageBaseUrl')}/docs/default/component/local`,
+ ).then(() => {
+ cy.document().toMatchImageSnapshot();
+ });
+ });
+});
diff --git a/packages/techdocs-cli/cypress/integration/mkdocs_serve.js b/packages/techdocs-cli/cypress/integration/mkdocs_serve.js
new file mode 100644
index 0000000000..1ace7298ce
--- /dev/null
+++ b/packages/techdocs-cli/cypress/integration/mkdocs_serve.js
@@ -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.
+ */
+///
+describe('TechDocs Live Preview - MkDocs Serve', () => {
+ it('successfully serves documentation', () => {
+ cy.visit(Cypress.env('mkDocsBaseUrl'));
+ cy.contains('hello mock docs');
+ });
+
+ it('successfully navigates to sub page of documentation', () => {
+ cy.contains('SubDocs').click();
+ cy.contains('Home 2').click();
+ cy.contains(
+ 'This is an md file in another docs folder using the MkDocs Monorepo Plugin',
+ );
+ });
+
+ it('successfully renders all main elements', () => {
+ cy.get('.md-header').should('have.length', 1);
+ cy.get('.md-main').should('have.length', 1);
+ cy.contains(
+ '.md-main',
+ 'This is an md file in another docs folder using the MkDocs Monorepo Plugin',
+ );
+ cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1);
+ cy.get('.md-sidebar.md-sidebar--primary').should('have.length', 1);
+ cy.get('.md-footer').should('have.length', 1);
+ });
+
+ it('toMatchImageSnapshot - MkDocs Page', () => {
+ cy.visit(Cypress.env('mkDocsBaseUrl')).then(() => {
+ cy.document().toMatchImageSnapshot();
+ });
+ });
+});
diff --git a/packages/techdocs-cli/cypress/plugins/index.js b/packages/techdocs-cli/cypress/plugins/index.js
new file mode 100644
index 0000000000..92faabb6ad
--- /dev/null
+++ b/packages/techdocs-cli/cypress/plugins/index.js
@@ -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.
+ */
+
+// ***********************************************************
+// This example plugins/index.js can be used to load plugins
+//
+// You can change the location of this file or turn off loading
+// the plugins file with the 'pluginsFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/plugins-guide
+// ***********************************************************
+
+// This function is called when a project is opened or re-opened (e.g. due to
+// the project's config changing)
+
+const { initPlugin } = require('cypress-plugin-snapshots/plugin');
+
+/**
+ * @type {Cypress.PluginConfig}
+ */
+// eslint-disable-next-line no-unused-vars
+module.exports = (on, config) => {
+ // `on` is used to hook into various events Cypress emits
+ // `config` is the resolved Cypress config
+ initPlugin(on, config);
+ return config;
+};
diff --git a/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage Header #0.png b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage Header #0.png
new file mode 100644
index 0000000000..867e8ddd81
Binary files /dev/null and b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage Header #0.png differ
diff --git a/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (1).png b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (1).png
new file mode 100644
index 0000000000..3f1078345d
Binary files /dev/null and b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (1).png differ
diff --git a/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (2).png b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (2).png
new file mode 100644
index 0000000000..c576be51c5
Binary files /dev/null and b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0 (2).png differ
diff --git a/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0.png b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0.png
new file mode 100644
index 0000000000..3f1078345d
Binary files /dev/null and b/packages/techdocs-cli/cypress/screenshots/backstage_serve.js/TechDocs Live Preview - Backstage Serve toMatchImageSnapshot - Backstage TechDocs Page #0.png differ
diff --git a/packages/techdocs-cli/cypress/support/commands.js b/packages/techdocs-cli/cypress/support/commands.js
new file mode 100644
index 0000000000..a8d6a5fdb7
--- /dev/null
+++ b/packages/techdocs-cli/cypress/support/commands.js
@@ -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.
+ */
+
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
diff --git a/packages/techdocs-cli/cypress/support/index.js b/packages/techdocs-cli/cypress/support/index.js
new file mode 100644
index 0000000000..a1a5b10ea4
--- /dev/null
+++ b/packages/techdocs-cli/cypress/support/index.js
@@ -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.
+ */
+
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands';
+import 'cypress-plugin-snapshots/commands';
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json
index 19514b63d2..929564e01c 100644
--- a/packages/techdocs-cli/package.json
+++ b/packages/techdocs-cli/package.json
@@ -1,11 +1,14 @@
{
"name": "@techdocs/cli",
"description": "Utility CLI for managing TechDocs sites in Backstage.",
- "version": "0.8.13",
+ "version": "0.8.15",
"private": false,
"publishConfig": {
"access": "public"
},
+ "backstage": {
+ "role": "cli"
+ },
"homepage": "https://backstage.io",
"repository": {
"type": "git",
@@ -21,19 +24,20 @@
"types": "",
"scripts": {
"start": "nodemon --",
- "build": "backstage-cli build --outputs cjs",
- "clean": "backstage-cli clean",
- "lint": "backstage-cli lint",
- "test": "backstage-cli test --testPathIgnorePatterns=src/e2e.test.ts",
+ "build": "backstage-cli package build",
+ "clean": "backstage-cli package clean",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test --testPathIgnorePatterns=src/e2e.test.ts",
"test:e2e": "backstage-cli test src/e2e.test.ts",
"test:e2e:ci": "backstage-cli test --watchAll=false --ci src/e2e.test.ts",
+ "test:cypress": "cypress open",
"prepack": "./scripts/prepack.sh"
},
"bin": {
"techdocs-cli": "bin/techdocs-cli"
},
"devDependencies": {
- "@backstage/cli": "^0.13.2",
+ "@backstage/cli": "^0.14.1",
"@types/commander": "^2.12.2",
"@types/fs-extra": "^9.0.6",
"@types/http-proxy": "^1.17.4",
@@ -41,9 +45,11 @@
"@types/node": "^14.14.32",
"@types/serve-handler": "^6.1.0",
"@types/webpack-env": "^1.15.3",
- "techdocs-cli-embedded-app": "link:../techdocs-cli-embedded-app",
+ "cypress": "^9.5.0",
+ "cypress-plugin-snapshots": "^1.4.4",
"find-process": "^1.4.5",
"nodemon": "^2.0.2",
+ "techdocs-cli-embedded-app": "link:../techdocs-cli-embedded-app",
"ts-node": "^10.0.0"
},
"files": [
@@ -56,11 +62,11 @@
"ext": "ts"
},
"dependencies": {
- "@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",
+ "@backstage/backend-common": "^0.11.0",
+ "@backstage/catalog-model": "^0.11.0",
+ "@backstage/cli-common": "^0.1.8",
+ "@backstage/config": "^0.1.15",
+ "@backstage/techdocs-common": "^0.11.10",
"@types/dockerode": "^3.3.0",
"commander": "^6.1.0",
"dockerode": "^3.3.1",
diff --git a/packages/techdocs-cli/scripts/prepack.sh b/packages/techdocs-cli/scripts/prepack.sh
index 6b769de37c..bfd62cfd1b 100755
--- a/packages/techdocs-cli/scripts/prepack.sh
+++ b/packages/techdocs-cli/scripts/prepack.sh
@@ -23,4 +23,4 @@ TECHDOCS_CLI_EMBEDDED_APP_DIR="$TECHDOCS_CLI_DIR"/../techdocs-cli-embedded-app
echo "🚚 Copying embedded app into dist/embedded-app"
rm -rf "$TECHDOCS_CLI_DIR"/dist/embedded-app
cp -r "$TECHDOCS_CLI_EMBEDDED_APP_DIR"/dist "$TECHDOCS_CLI_DIR"/dist/embedded-app
-echo "🏁 Ready!"
+echo "🏁 Finished copying embedded app into dist/embedded-app!"
diff --git a/packages/techdocs-cli/src/commands/generate/generate.ts b/packages/techdocs-cli/src/commands/generate/generate.ts
index a255805139..0f5213df34 100644
--- a/packages/techdocs-cli/src/commands/generate/generate.ts
+++ b/packages/techdocs-cli/src/commands/generate/generate.ts
@@ -39,6 +39,7 @@ export default async function generate(cmd: Command) {
const sourceDir = resolve(cmd.sourceDir);
const outputDir = resolve(cmd.outputDir);
+ const omitTechdocsCorePlugin = cmd.omitTechdocsCoreMkdocsPlugin;
const dockerImage = cmd.dockerImage;
const pullImage = cmd.pull;
@@ -55,6 +56,9 @@ export default async function generate(cmd: Command) {
runIn: cmd.docker ? 'docker' : 'local',
dockerImage,
pullImage,
+ mkdocs: {
+ omitTechdocsCorePlugin,
+ },
},
},
});
diff --git a/packages/techdocs-cli/src/commands/index.ts b/packages/techdocs-cli/src/commands/index.ts
index d4f41cf7a3..6f1d9847e1 100644
--- a/packages/techdocs-cli/src/commands/index.ts
+++ b/packages/techdocs-cli/src/commands/index.ts
@@ -45,7 +45,7 @@ export function registerCommands(program: CommanderStatic) {
)
.option(
'--techdocs-ref ',
- 'The repository hosting documentation source files e.g. github:https://ghe.mycompany.net.com/org/repo.' +
+ 'The repository hosting documentation source files e.g. url:https://ghe.mycompany.net.com/org/repo.' +
'\nThis value is same as the backstage.io/techdocs-ref annotation of the corresponding Backstage entity.' +
'\nIt is completely fine to skip this as it is only being used to set repo_url in mkdocs.yml if not found.\n',
)
@@ -54,6 +54,11 @@ export function registerCommands(program: CommanderStatic) {
'A unique identifier for the prepared tree e.g. commit SHA. If provided it will be stored in techdocs_metadata.json.',
)
.option('-v --verbose', 'Enable verbose output.', false)
+ .option(
+ '--omitTechdocsCoreMkdocsPlugin',
+ "Don't patch MkDocs file automatically with techdocs-core plugin.",
+ false,
+ )
.alias('build')
.action(lazy(() => import('./generate/generate').then(m => m.default)));
diff --git a/packages/techdocs-cli/src/e2e.test.ts b/packages/techdocs-cli/src/e2e.test.ts
index 088dbc44b8..7cdd867d0f 100644
--- a/packages/techdocs-cli/src/e2e.test.ts
+++ b/packages/techdocs-cli/src/e2e.test.ts
@@ -58,7 +58,7 @@ const timeout = 25000;
jest.setTimeout(timeout * 2);
describe('end-to-end', () => {
- const cwd = path.resolve(__dirname, 'fixture');
+ const cwd = path.resolve(__dirname, 'example-docs');
afterEach(async () => {
// On Windows the pid of a spawned process may be wrong
diff --git a/packages/techdocs-cli/src/example-docs/.gitignore b/packages/techdocs-cli/src/example-docs/.gitignore
new file mode 100644
index 0000000000..45ddf0ae39
--- /dev/null
+++ b/packages/techdocs-cli/src/example-docs/.gitignore
@@ -0,0 +1 @@
+site/
diff --git a/packages/techdocs-cli/src/example-docs/docs/index.md b/packages/techdocs-cli/src/example-docs/docs/index.md
new file mode 100644
index 0000000000..074d3ccb3e
--- /dev/null
+++ b/packages/techdocs-cli/src/example-docs/docs/index.md
@@ -0,0 +1,92 @@
+## hello mock docs
+
+!!! test
+Testing something
+
+Abbreviations:
+Some text about MOCDOC
+
+This is a paragraph.
+{: #test_id .test_class }
+
+Apple
+: A fruit.
+
+```javascript
+import { test } from 'something';
+
+const addThingToThing = (a, b) a + b;
+```
+
+- [abc](#abc)
+- [xyz](#xyz)
+
+## abc
+
+This is a b c.
+
+## xyz
+
+This is x y z.
+
+# Emojis
+
+:bulb: :smile:
+
+# Code blocks
+
+```javascript
+import { test } from 'something';
+
+const addThingToThing = (a, b) a + b;
+```
+
+# Grouped Code blocks
+
+=== "JavaScript"
+
+ ```javascript
+ import { test } from 'something';
+
+ const addThingToThing = (a, b) a + b;
+ ```
+
+=== "Java"
+
+ ```java
+ public void function() {
+ test();
+ }
+ ```
+
+```java tab="java"
+ public void function() {
+ test();
+ }
+```
+
+```java tab="java 2"
+ public void function() {
+ test();
+ }
+```
+
+# MDX truly sane lists
+
+- attributes
+
+- customer
+ - first_name
+ - test
+ - family_name
+ - email
+- person
+ - first_name
+ - family_name
+ - birth_date
+- subscription_id
+
+- request
+
+
+*[MOCDOC]: Mock Documentation
diff --git a/packages/techdocs-cli/src/fixture/mkdocs.yml b/packages/techdocs-cli/src/example-docs/mkdocs.yml
similarity index 50%
rename from packages/techdocs-cli/src/fixture/mkdocs.yml
rename to packages/techdocs-cli/src/example-docs/mkdocs.yml
index 5d5c2a02ae..9c9406f6e6 100644
--- a/packages/techdocs-cli/src/fixture/mkdocs.yml
+++ b/packages/techdocs-cli/src/example-docs/mkdocs.yml
@@ -2,7 +2,9 @@ site_name: docs-test-fixture
site_description: Documentation site test fixture
nav:
- - HOME: README.md
+ - Home: index.md
+ - SubDocs: '!include ./sub-docs/mkdocs.yml'
+ - Plugins: '*include ./plugins/*/mkdocs.yml'
plugins:
- techdocs-core
diff --git a/packages/techdocs-cli/src/example-docs/plugins/plugin-a/docs/index.md b/packages/techdocs-cli/src/example-docs/plugins/plugin-a/docs/index.md
new file mode 100644
index 0000000000..bd8bc3a4ea
--- /dev/null
+++ b/packages/techdocs-cli/src/example-docs/plugins/plugin-a/docs/index.md
@@ -0,0 +1,4 @@
+# Plugin A
+
+This is a description of Plugin A. This file exists to prove that glob'd
+includes using the `*include` syntax work as expected.
diff --git a/packages/techdocs-cli/src/example-docs/plugins/plugin-a/mkdocs.yml b/packages/techdocs-cli/src/example-docs/plugins/plugin-a/mkdocs.yml
new file mode 100644
index 0000000000..66407d5391
--- /dev/null
+++ b/packages/techdocs-cli/src/example-docs/plugins/plugin-a/mkdocs.yml
@@ -0,0 +1,5 @@
+site_name: Plugin A
+site_description: A description of Plugin A
+
+nav:
+ - Introduction: index.md
diff --git a/packages/techdocs-cli/src/example-docs/plugins/plugin-b/docs/index.md b/packages/techdocs-cli/src/example-docs/plugins/plugin-b/docs/index.md
new file mode 100644
index 0000000000..93e545252f
--- /dev/null
+++ b/packages/techdocs-cli/src/example-docs/plugins/plugin-b/docs/index.md
@@ -0,0 +1,4 @@
+# Plugin B
+
+This is a description of Plugin B. This file exists to prove that glob'd
+includes using the `*include` syntax work as expected.
diff --git a/packages/techdocs-cli/src/example-docs/plugins/plugin-b/mkdocs.yml b/packages/techdocs-cli/src/example-docs/plugins/plugin-b/mkdocs.yml
new file mode 100644
index 0000000000..81580c33af
--- /dev/null
+++ b/packages/techdocs-cli/src/example-docs/plugins/plugin-b/mkdocs.yml
@@ -0,0 +1,5 @@
+site_name: Plugin B
+site_description: A description of Plugin B
+
+nav:
+ - Introduction: index.md
diff --git a/packages/techdocs-cli/src/example-docs/sub-docs/docs/index.md b/packages/techdocs-cli/src/example-docs/sub-docs/docs/index.md
new file mode 100644
index 0000000000..65c6644ef8
--- /dev/null
+++ b/packages/techdocs-cli/src/example-docs/sub-docs/docs/index.md
@@ -0,0 +1 @@
+### This is an md file in another docs folder using the [MkDocs Monorepo Plugin](https://github.com/spotify/mkdocs-monorepo-plugin)
diff --git a/packages/techdocs-cli/src/example-docs/sub-docs/mkdocs.yml b/packages/techdocs-cli/src/example-docs/sub-docs/mkdocs.yml
new file mode 100644
index 0000000000..4490ddbefa
--- /dev/null
+++ b/packages/techdocs-cli/src/example-docs/sub-docs/mkdocs.yml
@@ -0,0 +1,4 @@
+site_name: subdocs
+
+nav:
+ - Home 2: 'index.md'
diff --git a/packages/techdocs-cli/src/fixture/docs/README.md b/packages/techdocs-cli/src/fixture/docs/README.md
deleted file mode 100644
index c32f73f6f4..0000000000
--- a/packages/techdocs-cli/src/fixture/docs/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Test Fixture
diff --git a/packages/techdocs-common/CHANGELOG.md b/packages/techdocs-common/CHANGELOG.md
index 44fbec4171..c99295e8db 100644
--- a/packages/techdocs-common/CHANGELOG.md
+++ b/packages/techdocs-common/CHANGELOG.md
@@ -1,5 +1,44 @@
# @backstage/techdocs-common
+## 0.11.10
+
+### Patch Changes
+
+- 209fd128e6: Updated usage of `github:` location types in docs to use `url:` instead.
+- 13ef228d03: Clean up the API interface for TechDocs common library.
+- Updated dependencies
+ - @backstage/backend-common@0.11.0
+ - @backstage/catalog-model@0.11.0
+ - @backstage/integration@0.7.5
+
+## 0.11.9
+
+### Patch Changes
+
+- Fix for the previous release with missing type declarations.
+- Updated dependencies
+ - @backstage/backend-common@0.10.9
+ - @backstage/catalog-model@0.10.1
+ - @backstage/config@0.1.15
+ - @backstage/errors@0.2.2
+ - @backstage/integration@0.7.4
+ - @backstage/search-common@0.2.4
+
+## 0.11.8
+
+### Patch Changes
+
+- c77c5c7eb6: Added `backstage.role` to `package.json`
+- 216725b434: Updated to use new names for `parseLocationRef` and `stringifyLocationRef`
+- 7aeb491394: Replace use of deprecated `ENTITY_DEFAULT_NAMESPACE` constant with `DEFAULT_NAMESPACE`.
+- Updated dependencies
+ - @backstage/backend-common@0.10.8
+ - @backstage/errors@0.2.1
+ - @backstage/integration@0.7.3
+ - @backstage/catalog-model@0.10.0
+ - @backstage/config@0.1.14
+ - @backstage/search-common@0.2.3
+
## 0.11.7
### Patch Changes
diff --git a/packages/techdocs-common/README.md b/packages/techdocs-common/README.md
index e4889d6f79..bbaac85e9b 100644
--- a/packages/techdocs-common/README.md
+++ b/packages/techdocs-common/README.md
@@ -39,7 +39,7 @@ Currently the build process is split up in these three stages.
- Generators
- Publishers
-Preparers read your entity data and creates a working directory with your documentation source code. For example if you have set your `backstage.io/techdocs-ref` to `github:https://github.com/backstage/backstage.git` it will clone that repository to a temp folder and pass that on to the generator.
+Preparers read your entity data and creates a working directory with your documentation source code. For example if you have set your `backstage.io/techdocs-ref` to `url:https://github.com/backstage/backstage.git` it will clone that repository to a temp folder and pass that on to the generator.
Generators takes the prepared source and runs the `techdocs-container` on it. It then passes on the output folder of that build to the publisher.
diff --git a/packages/techdocs-common/api-report.md b/packages/techdocs-common/api-report.md
index 281accca30..7c4fc95abb 100644
--- a/packages/techdocs-common/api-report.md
+++ b/packages/techdocs-common/api-report.md
@@ -17,38 +17,37 @@ import { ScmIntegrationRegistry } from '@backstage/integration';
import { UrlReader } from '@backstage/backend-common';
import { Writable } from 'stream';
-// Warning: (ae-missing-release-tag) "DirectoryPreparer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export class DirectoryPreparer implements PreparerBase {
- constructor(config: Config, _logger: Logger_2, reader: UrlReader);
- // Warning: (ae-forgotten-export) The symbol "PreparerResponse" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
- prepare(
- entity: Entity,
- options?: {
- logger?: Logger_2;
- etag?: string;
- },
- ): Promise;
+ // @deprecated
+ constructor(config: Config, _logger: Logger_2 | null, reader: UrlReader);
+ static fromConfig(
+ config: Config,
+ { logger, reader }: PreparerConfig,
+ ): DirectoryPreparer;
+ prepare(entity: Entity, options?: PreparerOptions): Promise;
}
-// Warning: (ae-missing-release-tag) "GeneratorBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
+export type ETag = string;
+
+// @public
export type GeneratorBase = {
run(opts: GeneratorRunOptions): Promise;
};
-// Warning: (ae-missing-release-tag) "GeneratorBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type GeneratorBuilder = {
register(protocol: SupportedGeneratorKey, generator: GeneratorBase): void;
get(entity: Entity): GeneratorBase;
};
+// @public
+export type GeneratorOptions = {
+ containerRunner: ContainerRunner;
+ logger: Logger_2;
+};
+
// @public
export type GeneratorRunOptions = {
inputDir: string;
@@ -59,11 +58,8 @@ export type GeneratorRunOptions = {
logStream?: Writable;
};
-// Warning: (ae-missing-release-tag) "Generators" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export class Generators implements GeneratorBuilder {
- // (undocumented)
static fromConfig(
config: Config,
options: {
@@ -71,15 +67,11 @@ export class Generators implements GeneratorBuilder {
containerRunner: ContainerRunner;
},
): Promise;
- // (undocumented)
get(entity: Entity): GeneratorBase;
- // (undocumented)
register(generatorKey: SupportedGeneratorKey, generator: GeneratorBase): void;
}
-// Warning: (ae-missing-release-tag) "getDocFilesFromRepository" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export const getDocFilesFromRepository: (
reader: UrlReader,
entity: Entity,
@@ -91,78 +83,74 @@ export const getDocFilesFromRepository: (
| undefined,
) => Promise;
-// Warning: (ae-missing-release-tag) "getLocationForEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export const getLocationForEntity: (
entity: Entity,
scmIntegration: ScmIntegrationRegistry,
) => ParsedLocationAnnotation;
-// Warning: (ae-missing-release-tag) "ParsedLocationAnnotation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
+export type MigrateRequest = {
+ removeOriginal?: boolean;
+ concurrency?: number;
+};
+
+// @public
export type ParsedLocationAnnotation = {
type: RemoteProtocol;
target: string;
};
-// Warning: (ae-missing-release-tag) "parseReferenceAnnotation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export const parseReferenceAnnotation: (
annotationName: string,
entity: Entity,
) => ParsedLocationAnnotation;
-// Warning: (ae-missing-release-tag) "PreparerBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export type PreparerBase = {
- prepare(
- entity: Entity,
- options?: {
- logger?: Logger_2;
- etag?: string;
- },
- ): Promise;
+ prepare(entity: Entity, options?: PreparerOptions): Promise;
};
-// Warning: (ae-missing-release-tag) "PreparerBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export type PreparerBuilder = {
register(protocol: RemoteProtocol, preparer: PreparerBase): void;
get(entity: Entity): PreparerBase;
};
-// Warning: (ae-missing-release-tag) "Preparers" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
+export type PreparerConfig = {
+ logger: Logger_2;
+ reader: UrlReader;
+};
+
+// @public
+export type PreparerOptions = {
+ logger?: Logger_2;
+ etag?: ETag;
+};
+
+// @public
+export type PreparerResponse = {
+ preparedDir: string;
+ etag: ETag;
+};
+
+// @public
export class Preparers implements PreparerBuilder {
- // Warning: (ae-forgotten-export) The symbol "factoryOptions" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
static fromConfig(
- config: Config,
- { logger, reader }: factoryOptions,
+ backstageConfig: Config,
+ { logger, reader }: PreparerConfig,
): Promise;
- // (undocumented)
get(entity: Entity): PreparerBase;
- // (undocumented)
register(protocol: RemoteProtocol, preparer: PreparerBase): void;
}
-// Warning: (ae-missing-release-tag) "Publisher" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export class Publisher {
- // Warning: (ae-forgotten-export) The symbol "factoryOptions" needs to be exported by the entry point index.d.ts
- //
- // (undocumented)
static fromConfig(
config: Config,
- { logger, discovery }: factoryOptions_2,
+ { logger, discovery }: PublisherFactory,
): Promise;
}
@@ -172,15 +160,16 @@ export interface PublisherBase {
fetchTechDocsMetadata(entityName: EntityName): Promise;
getReadiness(): Promise;
hasDocsBeenGenerated(entityName: Entity): Promise;
- // Warning: (ae-forgotten-export) The symbol "MigrateRequest" needs to be exported by the entry point index.d.ts
migrateDocsCase?(migrateRequest: MigrateRequest): Promise;
- // Warning: (ae-forgotten-export) The symbol "PublishRequest" needs to be exported by the entry point index.d.ts
- // Warning: (ae-forgotten-export) The symbol "PublishResponse" needs to be exported by the entry point index.d.ts
publish(request: PublishRequest): Promise;
}
-// Warning: (ae-missing-release-tag) "PublisherType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
+// @public
+export type PublisherFactory = {
+ logger: Logger_2;
+ discovery: PluginEndpointDiscovery;
+};
+
// @public
export type PublisherType =
| 'local'
@@ -189,37 +178,40 @@ export type PublisherType =
| 'azureBlobStorage'
| 'openStackSwift';
+// @public
+export type PublishRequest = {
+ entity: Entity;
+ directory: string;
+};
+
+// @public
+export type PublishResponse = {
+ remoteUrl?: string;
+ objects?: string[];
+} | void;
+
// @public
export type ReadinessResponse = {
isAvailable: boolean;
};
-// Warning: (ae-missing-release-tag) "RemoteProtocol" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export type RemoteProtocol = 'url' | 'dir';
-// Warning: (ae-missing-release-tag) "TechDocsDocument" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
+export type SupportedGeneratorKey = 'techdocs' | string;
+
+// @public
export interface TechDocsDocument extends IndexableDocument {
- // (undocumented)
kind: string;
- // (undocumented)
lifecycle: string;
- // (undocumented)
name: string;
- // (undocumented)
namespace: string;
- // (undocumented)
owner: string;
- // (undocumented)
path: string;
}
-// Warning: (ae-missing-release-tag) "TechdocsGenerator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export class TechdocsGenerator implements GeneratorBase {
constructor(options: {
logger: Logger_2;
@@ -227,21 +219,14 @@ export class TechdocsGenerator implements GeneratorBase {
config: Config;
scmIntegrations: ScmIntegrationRegistry;
});
- static readonly defaultDockerImage = 'spotify/techdocs:v0.3.6';
- // (undocumented)
+ static readonly defaultDockerImage = 'spotify/techdocs:v0.3.7';
static fromConfig(
config: Config,
- options: {
- containerRunner: ContainerRunner;
- logger: Logger_2;
- },
+ options: GeneratorOptions,
): TechdocsGenerator;
- // (undocumented)
run(options: GeneratorRunOptions): Promise;
}
-// Warning: (ae-missing-release-tag) "TechDocsMetadata" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export type TechDocsMetadata = {
site_name: string;
@@ -251,8 +236,6 @@ export type TechDocsMetadata = {
files?: string[];
};
-// Warning: (ae-missing-release-tag) "transformDirLocation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
// @public
export const transformDirLocation: (
entity: Entity,
@@ -263,21 +246,11 @@ export const transformDirLocation: (
target: string;
};
-// Warning: (ae-missing-release-tag) "UrlPreparer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
+// @public
export class UrlPreparer implements PreparerBase {
+ // @deprecated
constructor(reader: UrlReader, logger: Logger_2);
- // (undocumented)
- prepare(
- entity: Entity,
- options?: {
- etag?: string;
- },
- ): Promise;
+ static fromConfig({ reader, logger }: PreparerConfig): UrlPreparer;
+ prepare(entity: Entity, options?: PreparerOptions): Promise;
}
-
-// Warnings were encountered during analysis:
-//
-// src/stages/generate/types.d.ts:45:5 - (ae-forgotten-export) The symbol "SupportedGeneratorKey" needs to be exported by the entry point index.d.ts
```
diff --git a/packages/techdocs-common/package.json b/packages/techdocs-common/package.json
index f45f842100..731e967637 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",
+ "version": "0.11.10",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -10,6 +10,9 @@
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts"
},
+ "backstage": {
+ "role": "node-library"
+ },
"homepage": "https://backstage.io",
"repository": {
"type": "git",
@@ -25,12 +28,13 @@
"dist"
],
"scripts": {
- "build": "backstage-cli build --outputs cjs,types",
- "lint": "backstage-cli lint",
- "test": "backstage-cli test",
- "prepack": "backstage-cli prepack",
- "postpack": "backstage-cli postpack",
- "clean": "backstage-cli clean"
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack",
+ "clean": "backstage-cli package clean",
+ "start": "backstage-cli package start"
},
"bugs": {
"url": "https://github.com/backstage/backstage/issues"
@@ -38,12 +42,12 @@
"dependencies": {
"@azure/identity": "^2.0.1",
"@azure/storage-blob": "^12.5.0",
- "@backstage/backend-common": "^0.10.7",
- "@backstage/catalog-model": "^0.9.10",
- "@backstage/config": "^0.1.13",
- "@backstage/errors": "^0.2.0",
- "@backstage/search-common": "^0.2.2",
- "@backstage/integration": "^0.7.2",
+ "@backstage/backend-common": "^0.11.0",
+ "@backstage/catalog-model": "^0.11.0",
+ "@backstage/config": "^0.1.15",
+ "@backstage/errors": "^0.2.2",
+ "@backstage/search-common": "^0.2.4",
+ "@backstage/integration": "^0.7.5",
"@google-cloud/storage": "^5.6.0",
"@trendyol-js/openstack-swift-sdk": "^0.0.5",
"@types/express": "^4.17.6",
@@ -60,7 +64,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
- "@backstage/cli": "^0.13.2",
+ "@backstage/cli": "^0.14.1",
"@types/fs-extra": "^9.0.5",
"@types/js-yaml": "^4.0.0",
"@types/mime-types": "^2.1.0",
diff --git a/packages/techdocs-common/src/helpers.ts b/packages/techdocs-common/src/helpers.ts
index 7a9e4b18be..39a1f4c666 100644
--- a/packages/techdocs-common/src/helpers.ts
+++ b/packages/techdocs-common/src/helpers.ts
@@ -18,7 +18,7 @@ import { resolveSafeChildPath, UrlReader } from '@backstage/backend-common';
import {
Entity,
getEntitySourceLocation,
- parseLocationReference,
+ parseLocationRef,
} from '@backstage/catalog-model';
import { InputError } from '@backstage/errors';
import { ScmIntegrationRegistry } from '@backstage/integration';
@@ -26,11 +26,21 @@ import path from 'path';
import { Logger } from 'winston';
import { PreparerResponse, RemoteProtocol } from './stages/prepare/types';
+/**
+ * Parsed location annotation
+ * @public
+ */
export type ParsedLocationAnnotation = {
type: RemoteProtocol;
target: string;
};
+/**
+ * Returns a parset locations annotation
+ * @public
+ * @param annotationName - The name of the annotation in the entity metadata
+ * @param entity - A TechDocs entity instance
+ */
export const parseReferenceAnnotation = (
annotationName: string,
entity: Entity,
@@ -42,7 +52,7 @@ export const parseReferenceAnnotation = (
);
}
- const { type, target } = parseLocationReference(annotation);
+ const { type, target } = parseLocationRef(annotation);
return {
type: type as RemoteProtocol,
target,
@@ -56,7 +66,7 @@ export const parseReferenceAnnotation = (
* location, it returns a `url` location with a resolved target that points to the
* targeted subfolder. If the entity was registered by a `file` location, it returns
* an absolute `dir` location.
- *
+ * @public
* @param entity - the entity with annotations
* @param dirAnnotation - the parsed techdocs-ref annotation of type 'dir'
* @param scmIntegrations - access to the scmIntegration to do url transformations
@@ -101,6 +111,12 @@ export const transformDirLocation = (
}
};
+/**
+ * Returns a entity reference based on the TechDocs annotation type
+ * @public
+ * @param entity - A TechDocs instance
+ * @param scmIntegration - An implementation for SCM integration API
+ */
export const getLocationForEntity = (
entity: Entity,
scmIntegration: ScmIntegrationRegistry,
@@ -120,6 +136,13 @@ export const getLocationForEntity = (
}
};
+/**
+ * Returns a preparer response {@link PreparerResponse}
+ * @public
+ * @param reader - Read a tree of files from a repository
+ * @param entity - A TechDocs entity instance
+ * @param opts - Options for configuring the reader, e.g. logger, etag, etc.
+ */
export const getDocFilesFromRepository = async (
reader: UrlReader,
entity: Entity,
diff --git a/packages/techdocs-common/src/stages/generate/__fixtures__/mkdocs_with_additional_plugins.yml b/packages/techdocs-common/src/stages/generate/__fixtures__/mkdocs_with_additional_plugins.yml
new file mode 100644
index 0000000000..09e8fd7ac7
--- /dev/null
+++ b/packages/techdocs-common/src/stages/generate/__fixtures__/mkdocs_with_additional_plugins.yml
@@ -0,0 +1,6 @@
+site_name: Test site name
+site_description: Test site description
+docs_dir: docs/
+plugins:
+ - not-techdocs-core
+ - also-not-techdocs-core
diff --git a/packages/techdocs-common/src/stages/generate/__fixtures__/mkdocs_with_techdocs_plugin.yml b/packages/techdocs-common/src/stages/generate/__fixtures__/mkdocs_with_techdocs_plugin.yml
new file mode 100644
index 0000000000..eea9a8a3d9
--- /dev/null
+++ b/packages/techdocs-common/src/stages/generate/__fixtures__/mkdocs_with_techdocs_plugin.yml
@@ -0,0 +1,5 @@
+site_name: Test site name
+site_description: Test site description
+# This is a comment that is removed after editing
+plugins:
+ - techdocs-core
diff --git a/packages/techdocs-common/src/stages/generate/__fixtures__/mkdocs_without_plugins.yml b/packages/techdocs-common/src/stages/generate/__fixtures__/mkdocs_without_plugins.yml
new file mode 100644
index 0000000000..e75b06ada7
--- /dev/null
+++ b/packages/techdocs-common/src/stages/generate/__fixtures__/mkdocs_without_plugins.yml
@@ -0,0 +1,3 @@
+site_name: Test site name
+site_description: Test site description
+docs_dir: docs/
diff --git a/packages/techdocs-common/src/stages/generate/generators.ts b/packages/techdocs-common/src/stages/generate/generators.ts
index de39d4e7c3..630fccfa44 100644
--- a/packages/techdocs-common/src/stages/generate/generators.ts
+++ b/packages/techdocs-common/src/stages/generate/generators.ts
@@ -26,9 +26,18 @@ import {
SupportedGeneratorKey,
} from './types';
+/**
+ * Collection of docs generators
+ * @public
+ */
export class Generators implements GeneratorBuilder {
private generatorMap = new Map();
+ /**
+ * Returns a generators instance containing a generator for TechDocs
+ * @param config - A Backstage configuration
+ * @param options - Options to configure the TechDocs generator
+ */
static async fromConfig(
config: Config,
options: { logger: Logger; containerRunner: ContainerRunner },
@@ -41,10 +50,19 @@ export class Generators implements GeneratorBuilder {
return generators;
}
+ /**
+ * Register a generator in the generators collection
+ * @param generatorKey - Unique identifier for the generator
+ * @param generator - The generator instance to register
+ */
register(generatorKey: SupportedGeneratorKey, generator: GeneratorBase) {
this.generatorMap.set(generatorKey, generator);
}
+ /**
+ * Returns the generator for a given TechDocs entity
+ * @param entity - A TechDocs entity instance
+ */
get(entity: Entity): GeneratorBase {
const generatorKey = getGeneratorKey(entity);
const generator = this.generatorMap.get(generatorKey);
diff --git a/packages/techdocs-common/src/stages/generate/helpers.test.ts b/packages/techdocs-common/src/stages/generate/helpers.test.ts
index 9323ab4f18..7590df94fb 100644
--- a/packages/techdocs-common/src/stages/generate/helpers.test.ts
+++ b/packages/techdocs-common/src/stages/generate/helpers.test.ts
@@ -28,10 +28,14 @@ import {
getMkdocsYml,
getRepoUrlFromLocationAnnotation,
patchIndexPreBuild,
- patchMkdocsYmlPreBuild,
storeEtagMetadata,
validateMkdocsYaml,
} from './helpers';
+import {
+ patchMkdocsYmlPreBuild,
+ pathMkdocsYmlWithTechdocsPlugin,
+} from './mkDocsPatchers';
+import yaml from 'js-yaml';
const mockEntity = {
apiVersion: 'version',
@@ -65,6 +69,15 @@ const mkdocsYmlWithInvalidDocDir2 = fs.readFileSync(
const mkdocsYmlWithComments = fs.readFileSync(
resolvePath(__filename, '../__fixtures__/mkdocs_with_comments.yml'),
);
+const mkdocsYmlWithTechdocsPlugins = fs.readFileSync(
+ resolvePath(__filename, '../__fixtures__/mkdocs_with_techdocs_plugin.yml'),
+);
+const mkdocsYmlWithoutPlugins = fs.readFileSync(
+ resolvePath(__filename, '../__fixtures__/mkdocs_without_plugins.yml'),
+);
+const mkdocsYmlWithAdditionalPlugins = fs.readFileSync(
+ resolvePath(__filename, '../__fixtures__/mkdocs_with_additional_plugins.yml'),
+);
const mockLogger = getVoidLogger();
const warn = jest.spyOn(mockLogger, 'warn');
@@ -289,6 +302,60 @@ describe('helpers', () => {
});
});
+ describe('pathMkdocsYmlWithTechdocsPlugin', () => {
+ beforeEach(() => {
+ mockFs({
+ '/mkdocs_with_techdocs_plugin.yml': mkdocsYmlWithTechdocsPlugins,
+ '/mkdocs_without_plugins.yml': mkdocsYmlWithoutPlugins,
+ '/mkdocs_with_additional_plugins.yml': mkdocsYmlWithAdditionalPlugins,
+ });
+ });
+ it('should not add additional plugins if techdocs exists already in mkdocs file', async () => {
+ await pathMkdocsYmlWithTechdocsPlugin(
+ '/mkdocs_with_techdocs_plugin.yml',
+ mockLogger,
+ );
+
+ const updatedMkdocsYml = await fs.readFile(
+ '/mkdocs_with_techdocs_plugin.yml',
+ );
+ const parsedYml = yaml.load(updatedMkdocsYml.toString()) as {
+ plugins: string[];
+ };
+ expect(parsedYml.plugins).toHaveLength(1);
+ expect(parsedYml.plugins).toContain('techdocs-core');
+ });
+ it("should add the needed plugin if it doesn't exist in mkdocs file", async () => {
+ await pathMkdocsYmlWithTechdocsPlugin(
+ '/mkdocs_without_plugins.yml',
+ mockLogger,
+ );
+
+ const updatedMkdocsYml = await fs.readFile('/mkdocs_without_plugins.yml');
+ const parsedYml = yaml.load(updatedMkdocsYml.toString()) as {
+ plugins: string[];
+ };
+ expect(parsedYml.plugins).toHaveLength(1);
+ expect(parsedYml.plugins).toContain('techdocs-core');
+ });
+ it('should not override existing plugins', async () => {
+ await pathMkdocsYmlWithTechdocsPlugin(
+ '/mkdocs_with_additional_plugins.yml',
+ mockLogger,
+ );
+ const updatedMkdocsYml = await fs.readFile(
+ '/mkdocs_with_additional_plugins.yml',
+ );
+ const parsedYml = yaml.load(updatedMkdocsYml.toString()) as {
+ plugins: string[];
+ };
+ expect(parsedYml.plugins).toHaveLength(3);
+ expect(parsedYml.plugins).toContain('techdocs-core');
+ expect(parsedYml.plugins).toContain('not-techdocs-core');
+ expect(parsedYml.plugins).toContain('also-not-techdocs-core');
+ });
+ });
+
describe('patchIndexPreBuild', () => {
afterEach(() => {
warn.mockClear();
diff --git a/packages/techdocs-common/src/stages/generate/helpers.ts b/packages/techdocs-common/src/stages/generate/helpers.ts
index 2debd5822c..349783d2bd 100644
--- a/packages/techdocs-common/src/stages/generate/helpers.ts
+++ b/packages/techdocs-common/src/stages/generate/helpers.ts
@@ -125,7 +125,7 @@ class UnknownTag {
constructor(public readonly data: any, public readonly type?: string) {}
}
-const MKDOCS_SCHEMA = DEFAULT_SCHEMA.extend([
+export const MKDOCS_SCHEMA = DEFAULT_SCHEMA.extend([
new Type('', {
kind: 'scalar',
multi: true,
@@ -203,101 +203,6 @@ export const validateMkdocsYaml = async (
return parsedMkdocsYml.docs_dir;
};
-/**
- * Update the mkdocs.yml file before TechDocs generator uses it to generate docs site.
- *
- * List of tasks:
- * - Add repo_url or edit_uri if it does not exists
- * If mkdocs.yml has a repo_url, the generated docs site gets an Edit button on the pages by default.
- * If repo_url is missing in mkdocs.yml, we will use techdocs annotation of the entity to possibly get
- * the repository URL.
- *
- * This function will not throw an error since this is not critical to the whole TechDocs pipeline.
- * Instead it will log warnings if there are any errors in reading, parsing or writing YAML.
- *
- * @param mkdocsYmlPath - Absolute path to mkdocs.yml or equivalent of a docs site
- * @param logger - A logger instance
- * @param parsedLocationAnnotation - Object with location url and type
- * @param scmIntegrations - the scmIntegration to do url transformations
- */
-export const patchMkdocsYmlPreBuild = async (
- mkdocsYmlPath: string,
- logger: Logger,
- parsedLocationAnnotation: ParsedLocationAnnotation,
- scmIntegrations: ScmIntegrationRegistry,
-) => {
- // We only want to override the mkdocs.yml if it has actually changed. This is relevant if
- // used with a 'dir' location on the file system as this would permanently update the file.
- let didEdit = false;
-
- let mkdocsYmlFileString;
- try {
- mkdocsYmlFileString = await fs.readFile(mkdocsYmlPath, 'utf8');
- } catch (error) {
- assertError(error);
- logger.warn(
- `Could not read MkDocs YAML config file ${mkdocsYmlPath} before running the generator: ${error.message}`,
- );
- return;
- }
-
- let mkdocsYml: any;
- try {
- mkdocsYml = yaml.load(mkdocsYmlFileString, { schema: MKDOCS_SCHEMA });
-
- // mkdocsYml should be an object type after successful parsing.
- // But based on its type definition, it can also be a string or undefined, which we don't want.
- if (typeof mkdocsYml === 'string' || typeof mkdocsYml === 'undefined') {
- throw new Error('Bad YAML format.');
- }
- } catch (error) {
- assertError(error);
- logger.warn(
- `Error in parsing YAML at ${mkdocsYmlPath} before running the generator. ${error.message}`,
- );
- return;
- }
-
- // Add edit_uri and/or repo_url to mkdocs.yml if it is missing.
- // This will enable the Page edit button generated by MkDocs.
- // If the either has been set, keep the original value
- if (!('repo_url' in mkdocsYml) && !('edit_uri' in mkdocsYml)) {
- const result = getRepoUrlFromLocationAnnotation(
- parsedLocationAnnotation,
- scmIntegrations,
- mkdocsYml.docs_dir,
- );
-
- if (result.repo_url || result.edit_uri) {
- mkdocsYml.repo_url = result.repo_url;
- mkdocsYml.edit_uri = result.edit_uri;
- didEdit = true;
-
- logger.info(
- `Set ${JSON.stringify(
- result,
- )}. You can disable this feature by manually setting 'repo_url' or 'edit_uri' according to the MkDocs documentation at https://www.mkdocs.org/user-guide/configuration/#repo_url`,
- );
- }
- }
-
- try {
- if (didEdit) {
- await fs.writeFile(
- mkdocsYmlPath,
- yaml.dump(mkdocsYml, { schema: MKDOCS_SCHEMA }),
- 'utf8',
- );
- }
- } catch (error) {
- assertError(error);
- logger.warn(
- `Could not write to ${mkdocsYmlPath} after updating it before running the generator. ${error.message}`,
- );
- return;
- }
-};
-
/**
* Update docs/index.md file before TechDocs generator uses it to generate docs site,
* falling back to docs/README.md or README.md in case a default docs/index.md
diff --git a/packages/techdocs-common/src/stages/generate/index.ts b/packages/techdocs-common/src/stages/generate/index.ts
index eb015a5c2d..1c20c58887 100644
--- a/packages/techdocs-common/src/stages/generate/index.ts
+++ b/packages/techdocs-common/src/stages/generate/index.ts
@@ -16,7 +16,9 @@
export { TechdocsGenerator } from './techdocs';
export { Generators } from './generators';
export type {
- GeneratorBuilder,
GeneratorBase,
+ GeneratorOptions,
+ GeneratorBuilder,
GeneratorRunOptions,
+ SupportedGeneratorKey,
} from './types';
diff --git a/packages/techdocs-common/src/stages/generate/mkDocsPatchers.ts b/packages/techdocs-common/src/stages/generate/mkDocsPatchers.ts
new file mode 100644
index 0000000000..d03b5d83c2
--- /dev/null
+++ b/packages/techdocs-common/src/stages/generate/mkDocsPatchers.ts
@@ -0,0 +1,166 @@
+/*
+ * 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 { Logger } from 'winston';
+import fs from 'fs-extra';
+import yaml from 'js-yaml';
+import { ParsedLocationAnnotation } from '../../helpers';
+import { getRepoUrlFromLocationAnnotation, MKDOCS_SCHEMA } from './helpers';
+import { assertError } from '@backstage/errors';
+import { ScmIntegrationRegistry } from '@backstage/integration';
+
+type MkDocsObject = {
+ plugins?: string[];
+ docs_dir: string;
+ repo_url?: string;
+ edit_uri?: string;
+};
+
+const patchMkdocsFile = async (
+ mkdocsYmlPath: string,
+ logger: Logger,
+ updateAction: (mkdocsYml: MkDocsObject) => boolean,
+) => {
+ // We only want to override the mkdocs.yml if it has actually changed. This is relevant if
+ // used with a 'dir' location on the file system as this would permanently update the file.
+ let didEdit = false;
+
+ let mkdocsYmlFileString;
+ try {
+ mkdocsYmlFileString = await fs.readFile(mkdocsYmlPath, 'utf8');
+ } catch (error) {
+ assertError(error);
+ logger.warn(
+ `Could not read MkDocs YAML config file ${mkdocsYmlPath} before running the generator: ${error.message}`,
+ );
+ return;
+ }
+
+ let mkdocsYml: any;
+ try {
+ mkdocsYml = yaml.load(mkdocsYmlFileString, { schema: MKDOCS_SCHEMA });
+
+ // mkdocsYml should be an object type after successful parsing.
+ // But based on its type definition, it can also be a string or undefined, which we don't want.
+ if (typeof mkdocsYml === 'string' || typeof mkdocsYml === 'undefined') {
+ throw new Error('Bad YAML format.');
+ }
+ } catch (error) {
+ assertError(error);
+ logger.warn(
+ `Error in parsing YAML at ${mkdocsYmlPath} before running the generator. ${error.message}`,
+ );
+ return;
+ }
+
+ didEdit = updateAction(mkdocsYml);
+
+ try {
+ if (didEdit) {
+ await fs.writeFile(
+ mkdocsYmlPath,
+ yaml.dump(mkdocsYml, { schema: MKDOCS_SCHEMA }),
+ 'utf8',
+ );
+ }
+ } catch (error) {
+ assertError(error);
+ logger.warn(
+ `Could not write to ${mkdocsYmlPath} after updating it before running the generator. ${error.message}`,
+ );
+ return;
+ }
+};
+
+/**
+ * Update the mkdocs.yml file before TechDocs generator uses it to generate docs site.
+ *
+ * List of tasks:
+ * - Add repo_url or edit_uri if it does not exists
+ * If mkdocs.yml has a repo_url, the generated docs site gets an Edit button on the pages by default.
+ * If repo_url is missing in mkdocs.yml, we will use techdocs annotation of the entity to possibly get
+ * the repository URL.
+ *
+ * This function will not throw an error since this is not critical to the whole TechDocs pipeline.
+ * Instead it will log warnings if there are any errors in reading, parsing or writing YAML.
+ *
+ * @param mkdocsYmlPath - Absolute path to mkdocs.yml or equivalent of a docs site
+ * @param logger - A logger instance
+ * @param parsedLocationAnnotation - Object with location url and type
+ * @param scmIntegrations - the scmIntegration to do url transformations
+ */
+export const patchMkdocsYmlPreBuild = async (
+ mkdocsYmlPath: string,
+ logger: Logger,
+ parsedLocationAnnotation: ParsedLocationAnnotation,
+ scmIntegrations: ScmIntegrationRegistry,
+) => {
+ await patchMkdocsFile(mkdocsYmlPath, logger, mkdocsYml => {
+ if (!('repo_url' in mkdocsYml) && !('edit_uri' in mkdocsYml)) {
+ // Add edit_uri and/or repo_url to mkdocs.yml if it is missing.
+ // This will enable the Page edit button generated by MkDocs.
+ // If the either has been set, keep the original value
+ const result = getRepoUrlFromLocationAnnotation(
+ parsedLocationAnnotation,
+ scmIntegrations,
+ mkdocsYml.docs_dir,
+ );
+
+ if (result.repo_url || result.edit_uri) {
+ mkdocsYml.repo_url = result.repo_url;
+ mkdocsYml.edit_uri = result.edit_uri;
+
+ logger.info(
+ `Set ${JSON.stringify(
+ result,
+ )}. You can disable this feature by manually setting 'repo_url' or 'edit_uri' according to the MkDocs documentation at https://www.mkdocs.org/user-guide/configuration/#repo_url`,
+ );
+ return true;
+ }
+ }
+ return false;
+ });
+};
+
+/**
+ * Update the mkdocs.yml file before TechDocs generator uses it to generate docs site.
+ *
+ * List of tasks:
+ * - Add techdocs-core plugin to mkdocs file if it doesn't exist
+ *
+ * This function will not throw an error since this is not critical to the whole TechDocs pipeline.
+ * Instead it will log warnings if there are any errors in reading, parsing or writing YAML.
+ *
+ * @param mkdocsYmlPath - Absolute path to mkdocs.yml or equivalent of a docs site
+ * @param logger - A logger instance
+ */
+export const pathMkdocsYmlWithTechdocsPlugin = async (
+ mkdocsYmlPath: string,
+ logger: Logger,
+) => {
+ await patchMkdocsFile(mkdocsYmlPath, logger, mkdocsYml => {
+ // Modify mkdocs.yaml to contain the needed techdocs-core plugin if it is not there
+ if (!('plugins' in mkdocsYml)) {
+ mkdocsYml.plugins = ['techdocs-core'];
+ return true;
+ }
+
+ if (mkdocsYml.plugins && !mkdocsYml.plugins.includes('techdocs-core')) {
+ mkdocsYml.plugins.push('techdocs-core');
+ return true;
+ }
+ return false;
+ });
+};
diff --git a/packages/techdocs-common/src/stages/generate/techdocs.ts b/packages/techdocs-common/src/stages/generate/techdocs.ts
index 5cf992092c..b46f52f99a 100644
--- a/packages/techdocs-common/src/stages/generate/techdocs.ts
+++ b/packages/techdocs-common/src/stages/generate/techdocs.ts
@@ -26,34 +26,45 @@ import {
createOrUpdateMetadata,
getMkdocsYml,
patchIndexPreBuild,
- patchMkdocsYmlPreBuild,
runCommand,
storeEtagMetadata,
validateMkdocsYaml,
} from './helpers';
+
+import {
+ patchMkdocsYmlPreBuild,
+ pathMkdocsYmlWithTechdocsPlugin,
+} from './mkDocsPatchers';
import {
GeneratorBase,
GeneratorConfig,
+ GeneratorOptions,
GeneratorRunInType,
GeneratorRunOptions,
} from './types';
import { ForwardedError } from '@backstage/errors';
+/**
+ * Generates documentation files
+ * @public
+ */
export class TechdocsGenerator implements GeneratorBase {
/**
* The default docker image (and version) used to generate content. Public
* and static so that techdocs-common consumers can use the same version.
*/
- public static readonly defaultDockerImage = 'spotify/techdocs:v0.3.6';
+ public static readonly defaultDockerImage = 'spotify/techdocs:v0.3.7';
private readonly logger: Logger;
private readonly containerRunner: ContainerRunner;
private readonly options: GeneratorConfig;
private readonly scmIntegrations: ScmIntegrationRegistry;
- static fromConfig(
- config: Config,
- options: { containerRunner: ContainerRunner; logger: Logger },
- ) {
+ /**
+ * Returns a instance of TechDocs generator
+ * @param config - A Backstage configuration
+ * @param options - Options to configure the generator
+ */
+ static fromConfig(config: Config, options: GeneratorOptions) {
const { containerRunner, logger } = options;
const scmIntegrations = ScmIntegrations.fromConfig(config);
return new TechdocsGenerator({
@@ -76,6 +87,7 @@ export class TechdocsGenerator implements GeneratorBase {
this.scmIntegrations = options.scmIntegrations;
}
+ /** {@inheritDoc GeneratorBase.run} */
public async run(options: GeneratorRunOptions): Promise