Merge branch 'master' of github.com:spotify/backstage into add-microsoft-azure-auth

This commit is contained in:
Raghunandan Balachandran
2020-08-25 17:15:51 +02:00
151 changed files with 2067 additions and 832 deletions
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-api-docs",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,10 +20,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/plugin-catalog": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.19",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/plugin-catalog": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@kyma-project/asyncapi-react": "^0.11.0",
"@material-icons/font": "^1.0.2",
"@material-ui/core": "^4.9.1",
@@ -37,9 +37,9 @@
"swagger-ui-react": "^3.31.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@backstage/test-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -37,6 +37,7 @@ const columns: TableColumn<Entity>[] = [
.filter(Boolean)
.join(':'),
kind: entity.kind,
selectedTabId: 'overview',
})}
>
{entity.metadata.name}
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-auth-backend",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,8 +20,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/backend-common": "^0.1.1-alpha.19",
"@backstage/config": "^0.1.1-alpha.19",
"@types/express": "^4.17.6",
"body-parser": "^1.19.0",
"compression": "^1.7.4",
@@ -50,7 +50,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/jwt-decode": "2.2.1",
@@ -74,7 +74,7 @@ export class GithubAuthProvider implements OAuthProviderHandlers {
idToken: params.id_token,
};
// Github provides an id numeric value (123)
// GitHub provides an id numeric value (123)
// as a fallback
const id = passportProfile!.id;
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-backend",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -22,9 +22,9 @@
"mock-data:local": "./scripts/mock-data-local.sh"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/backend-common": "^0.1.1-alpha.19",
"@backstage/catalog-model": "^0.1.1-alpha.19",
"@backstage/config": "^0.1.1-alpha.19",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
@@ -41,7 +41,7 @@
"yup": "^0.29.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@types/lodash": "^4.14.151",
"@types/node-fetch": "^2.5.7",
"@types/supertest": "^2.0.8",
@@ -50,7 +50,7 @@ describe('GitlabApiReaderProcessor', () => {
'https://gitlab.com/groupA/teams/teamA/repoA/-/blob/branch/my/path/',
url: null,
err:
'Incorrect url: https://gitlab.com/groupA/teams/teamA/repoA/-/blob/branch/my/path/, Error: Gitlab url does not end in .ya?ml',
'Incorrect url: https://gitlab.com/groupA/teams/teamA/repoA/-/blob/branch/my/path/, Error: GitLab url does not end in .ya?ml',
},
];
@@ -77,7 +77,7 @@ export class GitlabApiReaderProcessor implements LocationProcessor {
const branchAndfilePath = url.pathname.split('/-/blob/')[1];
if (!branchAndfilePath.match(/\.ya?ml$/)) {
throw new Error('Gitlab url does not end in .ya?ml');
throw new Error('GitLab url does not end in .ya?ml');
}
const [branch, ...filePath] = branchAndfilePath.split('/');
@@ -127,7 +127,7 @@ export class GitlabApiReaderProcessor implements LocationProcessor {
return projectID;
} catch (e) {
throw new Error(`Could not get Gitlab ProjectID for: ${target}, ${e}`);
throw new Error(`Could not get GitLab ProjectID for: ${target}, ${e}`);
}
}
}
@@ -77,7 +77,7 @@ export class GitlabReaderProcessor implements LocationProcessor {
blobKeyword !== 'blob' ||
!restOfPath.join('/').match(/\.yaml$/)
) {
throw new Error('Wrong Gitlab URL');
throw new Error('Wrong GitLab URL');
}
// Replace 'blob' with 'raw'
+13 -13
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,15 +21,15 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/plugin-api-docs": "^0.1.1-alpha.18",
"@backstage/plugin-github-actions": "^0.1.1-alpha.18",
"@backstage/plugin-jenkins": "^0.1.1-alpha.18",
"@backstage/plugin-scaffolder": "^0.1.1-alpha.18",
"@backstage/plugin-sentry": "^0.1.1-alpha.18",
"@backstage/plugin-techdocs": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.19",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/plugin-api-docs": "^0.1.1-alpha.19",
"@backstage/plugin-github-actions": "^0.1.1-alpha.19",
"@backstage/plugin-jenkins": "^0.1.1-alpha.19",
"@backstage/plugin-scaffolder": "^0.1.1-alpha.19",
"@backstage/plugin-sentry": "^0.1.1-alpha.19",
"@backstage/plugin-techdocs": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -42,9 +42,9 @@
"swr": "^0.3.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@backstage/test-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/react-hooks": "^3.3.0",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-circleci",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"postpack": "backstage-cli postpack"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -36,8 +36,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-explore",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -32,9 +32,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@backstage/test-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-github-actions",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -22,11 +22,11 @@
"mock-data": "./scripts/mock-data.sh"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/core-api": "^0.1.1-alpha.18",
"@backstage/plugin-catalog": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.19",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/core-api": "^0.1.1-alpha.19",
"@backstage/plugin-catalog": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -39,8 +39,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -5,6 +5,7 @@ metadata:
description: backstage.io
annotations:
github.com/project-slug: 'spotify/backstage'
backstage.io/techdocs-ref: github:https://github.com/spotify/backstage.git
spec:
type: website
lifecycle: production
@@ -23,7 +23,7 @@ import {
export const githubActionsApiRef = createApiRef<GithubActionsApi>({
id: 'plugin.githubactions.service',
description: 'Used by the Github Actions plugin to make requests',
description: 'Used by the GitHub Actions plugin to make requests',
});
export type GithubActionsApi = {
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-gitops-profiles",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -32,8 +32,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-graphiql",
"description": "Backstage plugin for browsing GraphQL APIs",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"private": false,
"publishConfig": {
"access": "public",
@@ -31,8 +31,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -43,9 +43,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@backstage/test-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -33,7 +33,7 @@ export type GithubEndpointConfig = {
id: string;
title: string;
/**
* Github GraphQL API url, defaults to https://api.github.com/graphql
* GitHub GraphQL API url, defaults to https://api.github.com/graphql
*/
url?: string;
/**
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-graphql-backend",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,7 +20,7 @@
"mock-data": "./scripts/mock-data.sh"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/backend-common": "^0.1.1-alpha.19",
"@types/express": "^4.17.6",
"apollo-server": "^2.16.0",
"apollo-server-express": "^2.16.0",
@@ -32,7 +32,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@types/supertest": "^2.0.8",
"eslint-plugin-graphql": "^4.0.0",
"msw": "^0.20.5",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-identity-backend",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,7 +20,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/backend-common": "^0.1.1-alpha.19",
"@types/express": "^4.17.6",
"compression": "^1.7.4",
"cors": "^2.8.5",
@@ -33,7 +33,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"jest-fetch-mock": "^3.0.3"
},
"files": [
+1 -1
View File
@@ -4,7 +4,7 @@ Website: [https://jenkins.io/](https://jenkins.io/)
<img src="./src/assets/last-master-build.png" alt="Last master build"/>
<img src="./src/assets/folder-results.png" alt="Folder results"/>
<img src="./src/assets/build-details.png" alt="Build detials"/>
<img src="./src/assets/build-details.png" alt="Build details"/>
## Setup
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-jenkins",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.19",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -35,8 +35,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-lighthouse",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -33,9 +33,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@backstage/test-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-newrelic",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -31,8 +31,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-proxy-backend",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -19,8 +19,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/backend-common": "^0.1.1-alpha.19",
"@backstage/config": "^0.1.1-alpha.19",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
@@ -34,7 +34,7 @@
"yup": "^0.29.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@types/node-fetch": "^2.5.7",
"@types/supertest": "^2.0.8",
"@types/uuid": "^8.0.0",
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-register-component",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,10 +21,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/plugin-catalog": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.19",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/plugin-catalog": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -36,8 +36,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-rollbar-backend",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,8 +20,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/backend-common": "^0.1.1-alpha.19",
"@backstage/config": "^0.1.1-alpha.19",
"@types/express": "^4.17.6",
"axios": "^0.19.2",
"camelcase-keys": "^6.2.2",
@@ -37,7 +37,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@types/supertest": "^2.0.8",
"jest-fetch-mock": "^3.0.3",
"supertest": "^4.0.2"
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-rollbar",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -35,9 +35,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@backstage/test-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/react-hooks": "^3.3.0",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-scaffolder-backend",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"mock-data": "./scripts/mock-data.sh"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/backend-common": "^0.1.1-alpha.19",
"@backstage/catalog-model": "^0.1.1-alpha.19",
"@backstage/config": "^0.1.1-alpha.19",
"@octokit/rest": "^18.0.0",
"@types/dockerode": "^2.5.32",
"@types/express": "^4.17.6",
@@ -43,7 +43,7 @@
"yaml": "^1.10.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@octokit/types": "^5.0.1",
"@types/fs-extra": "^9.0.1",
"@types/git-url-parse": "^9.0.0",
@@ -5,9 +5,9 @@ metadata:
title: Create React App Template
description: Create a new CRA website project
tags:
- Experimental
- React
- CRA
- experimental
- react
- cra
spec:
owner: web@example.com
templater: cra
@@ -0,0 +1,29 @@
apiVersion: backstage.io/v1alpha1
kind: Template
metadata:
name: docs-template
title: Documentation Template
description: Create a new standalone documentation project
tags:
- experimental
- techdocs
- mkdocs
spec:
owner: spotify/techdocs-core
templater: cookiecutter
type: documentation
path: '.'
schema:
required:
- component_id
properties:
component_id:
title: Name
type: string
description: Unique name of the component
description:
title: Description
type: string
description: Description of the component
@@ -0,0 +1,12 @@
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: {{cookiecutter.component_id}}
description: {{cookiecutter.description}}
annotations:
github.com/project-slug: {{cookiecutter.storePath}}
backstage.io/techdocs-ref: github:https://github.com/{{cookiecutter.storePath}}
spec:
type: documentation
lifecycle: experimental
owner: {{cookiecutter.owner}}
@@ -0,0 +1,28 @@
## {{ cookiecutter.component_id }}
{{ cookiecutter.description }}
## Getting started
Start write your documentation by adding more markdown (.md) files to this folder (/docs) or replace the content in this file.
## Table of Contents
The Table of Contents on the right is generated automatically based on the hierarchy
of headings. Only use one H1 (`#` in Markdown) per file.
## Site navigation
For new pages to appear in the left hand navigation you need edit the `mkdocs.yml`
file in root of your repo. The navigation can also link out to other sites.
Alternatively, if there is no `nav` section in `mkdocs.yml`, a navigation section
will be created for you. However, you will not be able to use alternate titles for
pages, or include links to other sites.
Note that MkDocs uses `mkdocs.yml`, not `mkdocs.yaml`, although both appear to work.
See also <https://www.mkdocs.org/user-guide/configuration/>.
## Support
That's it. If you need support, reach out in [#docs-like-code](https://discord.com/channels/687207715902193673/714754240933003266) on Discord.
@@ -0,0 +1,8 @@
site_name: {{cookiecutter.component_id}}
site_description: {{cookiecutter.description}}
nav:
- Introduction: index.md
plugins:
- techdocs-core
@@ -5,8 +5,8 @@ metadata:
title: React SSR Template
description: Create a website powered with Next.js
tags:
- Recommended
- React
- recommended
- react
spec:
owner: web@example.com
templater: cookiecutter
@@ -5,8 +5,8 @@ metadata:
title: Spring Boot GRPC Service
description: Create a simple microservice using gRPC and Spring Boot Java
tags:
- Recommended
- Java
- recommended
- java
spec:
owner: service@example.com
templater: cookiecutter
@@ -4,6 +4,7 @@ for URL in \
'react-ssr-template' \
'springboot-grpc-template' \
'create-react-app' \
'docs-template' \
; do \
curl \
--location \
@@ -45,7 +45,7 @@ const {
mockRemote: jest.Mocked<NodeGit.Remote>;
};
describe('Github Publisher', () => {
describe('GitHub Publisher', () => {
const publisher = new GithubPublisher({ client: new Octokit() });
beforeEach(() => {
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-scaffolder",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,10 +21,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/plugin-catalog": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.19",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/plugin-catalog": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -41,9 +41,9 @@
"swr": "^0.3.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@backstage/test-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -26,7 +26,7 @@ import { useJobPolling } from './useJobPolling';
import { Job } from '../../types';
import { TemplateEntityV1alpha1 } from '@backstage/catalog-model';
import { Button } from '@backstage/core';
import { entityRoute } from '@backstage/plugin-catalog';
import { entityRouteDefault } from '@backstage/plugin-catalog';
import { generatePath } from 'react-router-dom';
type Props = {
@@ -72,7 +72,7 @@ export const JobStatusModal = ({
{entity && (
<DialogActions>
<Button
to={generatePath(entityRoute.path, {
to={generatePath(entityRouteDefault.path, {
kind: entity.kind,
optionalNamespaceAndName: [
entity.metadata.namespace,
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-sentry-backend",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,7 +20,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/backend-common": "^0.1.1-alpha.19",
"@types/express": "^4.17.6",
"axios": "^0.19.2",
"compression": "^1.7.4",
@@ -34,7 +34,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"jest-fetch-mock": "^3.0.3"
},
"files": [
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-sentry",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -34,8 +34,8 @@
"timeago.js": "^4.0.2"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-tech-radar",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/test-utils-core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/test-utils-core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -35,8 +35,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -4,7 +4,7 @@ metadata:
name: documented-component
description: A Service with TechDocs documentation
annotations:
backstage.io/techdocs-ref: 'dir:./'
backstage.io/techdocs-ref: 'github:https://github.com/spotify/backstage/blob/master/plugins/techdocs-backend/examples/documented-component'
spec:
type: service
lifecycle: experimental
+7 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-techdocs-backend",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,21 +21,23 @@
"mock-data": "./scripts/mock-data.sh"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/backend-common": "^0.1.1-alpha.19",
"@backstage/catalog-model": "^0.1.1-alpha.19",
"@backstage/config": "^0.1.1-alpha.19",
"@types/dockerode": "^2.5.34",
"@types/express": "^4.17.6",
"dockerode": "^3.2.1",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
"fs-extra": "^9.0.1",
"git-url-parse": "^11.1.3",
"knex": "^0.21.1",
"node-fetch": "^2.6.0",
"nodegit": "^0.27.0",
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@types/node-fetch": "^2.5.7",
"supertest": "^4.0.2"
},
@@ -24,12 +24,13 @@ import { createRouter } from './router';
describe('createRouter', () => {
let app: express.Express;
const logger = getVoidLogger();
beforeAll(async () => {
const router = await createRouter({
preparers: new Preparers(),
generators: new Generators(),
publisher: new LocalPublish(),
publisher: new LocalPublish(logger),
logger: getVoidLogger(),
dockerClient: new Docker(),
config: ConfigReader.fromConfigs([]),
+17 -1
View File
@@ -45,18 +45,34 @@ export async function createRouter({
publisher,
config,
dockerClient,
logger,
}: RouterOptions): Promise<express.Router> {
const router = Router();
const getEntityId = (entity: Entity) => {
return `${entity.kind}:${entity.metadata.namespace ?? ''}:${
entity.metadata.name
}`;
};
const buildDocsForEntity = async (entity: Entity) => {
const preparer = preparers.get(entity);
const generator = generators.get(entity);
logger.info(`[TechDocs] Running preparer on entity ${getEntityId(entity)}`);
const preparedDir = await preparer.prepare(entity);
logger.info(
`[TechDocs] Running generator on entity ${getEntityId(entity)}`,
);
const { resultDir } = await generator.run({
directory: await preparer.prepare(entity),
directory: preparedDir,
dockerClient,
});
logger.info(
`[TechDocs] Running publisher on entity ${getEntityId(entity)}`,
);
await publisher.publish({
entity,
directory: resultDir,
@@ -41,14 +41,14 @@ export async function startStandaloneServer(
logger.debug('Creating application...');
const preparers = new Preparers();
const directoryPreparer = new DirectoryPreparer();
const directoryPreparer = new DirectoryPreparer(logger);
preparers.register('dir', directoryPreparer);
const generators = new Generators();
const techdocsGenerator = new TechdocsGenerator();
const techdocsGenerator = new TechdocsGenerator(logger);
generators.register('techdocs', techdocsGenerator);
const publisher = new LocalPublish();
const publisher = new LocalPublish(logger);
const dockerClient = new Docker();
@@ -13,17 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fs from 'fs-extra';
import path from 'path';
import os from 'os';
import { Logger } from 'winston';
import {
GeneratorBase,
GeneratorRunOptions,
GeneratorRunResult,
} from './types';
import { runDockerContainer } from './helpers';
import fs from 'fs-extra';
import path from 'path';
import os from 'os';
export class TechdocsGenerator implements GeneratorBase {
private readonly logger: Logger;
constructor(logger: Logger) {
this.logger = logger;
}
public async run({
directory,
logStream,
@@ -36,18 +45,26 @@ export class TechdocsGenerator implements GeneratorBase {
path.join(tmpdirResolvedPath, 'techdocs-tmp-'),
);
await runDockerContainer({
imageName: 'spotify/techdocs',
args: ['build', '-d', '/result'],
logStream,
docsDir: directory,
resultDir,
dockerClient,
});
console.log(
`[TechDocs]: Successfully generated docs from ${directory} into ${resultDir}`,
);
try {
await runDockerContainer({
imageName: 'spotify/techdocs',
args: ['build', '-d', '/result'],
logStream,
docsDir: directory,
resultDir,
dockerClient,
});
this.logger.info(
`[TechDocs]: Successfully generated docs from ${directory} into ${resultDir}`,
);
} catch (error) {
this.logger.debug(
`[TechDocs]: Failed to generate docs from ${directory} into ${resultDir}`,
);
throw new Error(
`Failed to generate docs from ${directory} into ${resultDir} with error ${error.message}`,
);
}
return { resultDir };
}
@@ -14,6 +14,15 @@
* limitations under the License.
*/
import { DirectoryPreparer } from './dir';
import { getVoidLogger } from '@backstage/backend-common';
import { checkoutGitRepository } from './helpers';
jest.mock('./helpers', () => ({
...jest.requireActual<{}>('./helpers'),
checkoutGitRepository: jest.fn(() => '/tmp/backstage-repo/org/name/branch/'),
}));
const logger = getVoidLogger();
const createMockEntity = (annotations: {}) => {
return {
@@ -30,7 +39,7 @@ const createMockEntity = (annotations: {}) => {
describe('directory preparer', () => {
it('should merge managed-by-location and techdocs-ref when techdocs-ref is relative', async () => {
const directoryPreparer = new DirectoryPreparer();
const directoryPreparer = new DirectoryPreparer(logger);
const mockEntity = createMockEntity({
'backstage.io/managed-by-location':
@@ -44,7 +53,7 @@ describe('directory preparer', () => {
});
it('should merge managed-by-location and techdocs-ref when techdocs-ref is absolute', async () => {
const directoryPreparer = new DirectoryPreparer();
const directoryPreparer = new DirectoryPreparer(logger);
const mockEntity = createMockEntity({
'backstage.io/managed-by-location':
@@ -56,4 +65,19 @@ describe('directory preparer', () => {
'/our-documentation/techdocs',
);
});
it('should merge managed-by-location and techdocs-ref when managed-by-location is a git repository', async () => {
const directoryPreparer = new DirectoryPreparer(logger);
const mockEntity = createMockEntity({
'backstage.io/managed-by-location':
'github:https://github.com/spotify/backstage/blob/master/catalog-info.yaml',
'backstage.io/techdocs-ref': 'dir:./docs',
});
expect(await directoryPreparer.prepare(mockEntity)).toEqual(
'/tmp/backstage-repo/org/name/branch/docs',
);
expect(checkoutGitRepository).toHaveBeenCalledTimes(1);
});
});
@@ -16,23 +16,55 @@
import { PreparerBase } from './types';
import { Entity } from '@backstage/catalog-model';
import path from 'path';
import { parseReferenceAnnotation } from './helpers';
import { parseReferenceAnnotation, checkoutGitRepository } from './helpers';
import { InputError } from '@backstage/backend-common';
import parseGitUrl from 'git-url-parse';
import { Logger } from 'winston';
export class DirectoryPreparer implements PreparerBase {
prepare(entity: Entity): Promise<string> {
const { location: managedByLocation } = parseReferenceAnnotation(
private readonly logger: Logger;
constructor(logger: Logger) {
this.logger = logger;
}
private async resolveManagedByLocationToDir(entity: Entity) {
const { type, target } = parseReferenceAnnotation(
'backstage.io/managed-by-location',
entity,
);
const { location: techdocsLocation } = parseReferenceAnnotation(
this.logger.debug(
`[TechDocs] Building docs for entity with type 'dir' and managed-by-location '${type}'`,
);
switch (type) {
case 'github': {
const parsedGitLocation = parseGitUrl(target);
const repoLocation = await checkoutGitRepository(target);
return path.dirname(
path.join(repoLocation, parsedGitLocation.filepath),
);
}
case 'file':
return path.dirname(target);
default:
throw new InputError(`Unable to resolve location type ${type}`);
}
}
async prepare(entity: Entity): Promise<string> {
const { target } = parseReferenceAnnotation(
'backstage.io/techdocs-ref',
entity,
);
const managedByLocationDirectory = path.dirname(managedByLocation);
const managedByLocationDirectory = await this.resolveManagedByLocationToDir(
entity,
);
return new Promise(resolve => {
resolve(path.resolve(managedByLocationDirectory, techdocsLocation));
resolve(path.resolve(managedByLocationDirectory, target));
});
}
}
@@ -0,0 +1,56 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { GithubPreparer } from './github';
import { checkoutGitRepository } from './helpers';
jest.mock('./helpers', () => ({
...jest.requireActual<{}>('./helpers'),
checkoutGitRepository: jest.fn(() => '/tmp/backstage-repo/org/name/branch'),
}));
const createMockEntity = (annotations = {}) => {
return {
apiVersion: 'version',
kind: 'TestKind',
metadata: {
name: 'test-component-name',
annotations: {
...annotations,
},
},
};
};
const logger = getVoidLogger();
describe('github preparer', () => {
it('should prepare temp docs path from github repo', async () => {
const preparer = new GithubPreparer(logger);
const mockEntity = createMockEntity({
'backstage.io/techdocs-ref':
'github:https://github.com/spotify/backstage/blob/master/plugins/techdocs-backend/examples/documented-component',
});
const tempDocsPath = await preparer.prepare(mockEntity);
expect(checkoutGitRepository).toHaveBeenCalledTimes(1);
expect(tempDocsPath).toEqual(
'/tmp/backstage-repo/org/name/branch/plugins/techdocs-backend/examples/documented-component',
);
});
});
@@ -0,0 +1,51 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import path from 'path';
import { Entity } from '@backstage/catalog-model';
import { InputError } from '@backstage/backend-common';
import { PreparerBase } from './types';
import parseGitUrl from 'git-url-parse';
import { parseReferenceAnnotation, checkoutGitRepository } from './helpers';
import { Logger } from 'winston';
export class GithubPreparer implements PreparerBase {
private readonly logger: Logger;
constructor(logger: Logger) {
this.logger = logger;
}
async prepare(entity: Entity): Promise<string> {
const { type, target } = parseReferenceAnnotation(
'backstage.io/techdocs-ref',
entity,
);
if (type !== 'github') {
throw new InputError(`Wrong target type: ${type}, should be 'github'`);
}
try {
const repoPath = await checkoutGitRepository(target);
const parsedGitLocation = parseGitUrl(target);
return path.join(repoPath, parsedGitLocation.filepath);
} catch (error) {
this.logger.debug(`Repo checkout failed with error ${error.message}`);
throw error;
}
}
}
@@ -16,10 +16,15 @@
import { Entity } from '@backstage/catalog-model';
import { InputError } from '@backstage/backend-common';
import { RemoteProtocol } from './types';
import parseGitUrl from 'git-url-parse';
import { Clone, Repository } from 'nodegit';
import fs from 'fs-extra';
import os from 'os';
import path from 'path';
export type ParsedLocationAnnotation = {
protocol: RemoteProtocol;
location: string;
type: RemoteProtocol;
target: string;
};
export const parseReferenceAnnotation = (
@@ -36,19 +41,55 @@ export const parseReferenceAnnotation = (
// split on the first colon for the protocol and the rest after the first split
// is the location.
const [protocol, location] = annotation.split(/:(.+)/) as [
const [type, target] = annotation.split(/:(.+)/) as [
RemoteProtocol?,
string?,
];
if (!protocol || !location) {
if (!type || !target) {
throw new InputError(
`Failure to parse either protocol or location for entity: ${entity.metadata.name}`,
);
}
return {
protocol,
location,
type,
target,
};
};
export const clearGithubRepositoryCache = () => {
fs.removeSync(path.join(fs.realpathSync(os.tmpdir()), 'backstage-repo'));
};
export const checkoutGitRepository = async (
repoUrl: string,
): Promise<string> => {
const parsedGitLocation = parseGitUrl(repoUrl);
const repositoryTmpPath = path.join(
// fs.realpathSync fixes a problem with macOS returning a path that is a symlink
fs.realpathSync(os.tmpdir()),
'backstage-repo',
parsedGitLocation.source,
parsedGitLocation.owner,
parsedGitLocation.name,
parsedGitLocation.ref,
);
if (fs.existsSync(repositoryTmpPath)) {
const repository = await Repository.open(repositoryTmpPath);
await repository.mergeBranches(
parsedGitLocation.ref,
`origin/${parsedGitLocation.ref}`,
);
return repositoryTmpPath;
}
const repositoryCheckoutUrl = parsedGitLocation.toString('https');
fs.mkdirSync(repositoryTmpPath, { recursive: true });
await Clone.clone(repositoryCheckoutUrl, repositoryTmpPath, {});
return repositoryTmpPath;
};
@@ -14,5 +14,6 @@
* limitations under the License.
*/
export { DirectoryPreparer } from './dir';
export { GithubPreparer } from './github';
export { Preparers } from './preparers';
export type { PreparerBuilder } from './types';
@@ -26,13 +26,16 @@ export class Preparers implements PreparerBuilder {
}
get(entity: Entity): PreparerBase {
const { protocol } = parseReferenceAnnotation('backstage.io/techdocs-ref', entity);
const preparer = this.preparerMap.get(protocol);
const { type } = parseReferenceAnnotation(
'backstage.io/techdocs-ref',
entity,
);
const preparer = this.preparerMap.get(type);
if (!preparer) {
throw new Error(`No preparer registered for type: "${protocol}"`);
throw new Error(`No preparer registered for type: "${type}"`);
}
return preparer;
}
}
}
@@ -13,9 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { LocalPublish } from './local';
import fs from 'fs-extra';
import path from 'path';
import { getVoidLogger } from '@backstage/backend-common';
import { LocalPublish } from './local';
const createMockEntity = (annotations = {}) => {
return {
@@ -30,9 +31,11 @@ const createMockEntity = (annotations = {}) => {
};
};
const logger = getVoidLogger();
describe('local publisher', () => {
it('should publish generated documentation dir', async () => {
const publisher = new LocalPublish();
const publisher = new LocalPublish(logger);
const mockEntity = createMockEntity();
@@ -13,12 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { PublisherBase } from './types';
import { Entity } from '@backstage/catalog-model';
import path from 'path';
import fs from 'fs-extra';
import path from 'path';
import { Logger } from 'winston';
import { Entity } from '@backstage/catalog-model';
import { PublisherBase } from './types';
export class LocalPublish implements PublisherBase {
private readonly logger: Logger;
constructor(logger: Logger) {
this.logger = logger;
}
publish({
entity,
directory,
@@ -37,16 +44,22 @@ export class LocalPublish implements PublisherBase {
'../../../../static/docs/',
entity.kind,
entityNamespace,
entity.metadata.name
entity.metadata.name,
);
if (!fs.existsSync(publishDir)) {
this.logger.info(
`[TechDocs]: Could not find ${publishDir}, creates the directory.`,
);
fs.mkdirSync(publishDir, { recursive: true });
}
return new Promise((resolve, reject) => {
fs.copy(directory, publishDir, err => {
if (err) {
this.logger.debug(
`[TechDocs]: Failed to copy docs from ${directory} to ${publishDir}`,
);
reject(err);
}
+9 -9
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-techdocs",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -22,12 +22,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/core-api": "^0.1.1-alpha.18",
"@backstage/plugin-catalog": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.19",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/core-api": "^0.1.1-alpha.19",
"@backstage/plugin-catalog": "^0.1.1-alpha.19",
"@backstage/test-utils": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -40,8 +40,8 @@
"sanitize-html": "^1.27.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -15,7 +15,7 @@
*/
import React from 'react';
import { useApi } from '@backstage/core';
import { useApi, Progress } from '@backstage/core';
import { useShadowDom } from '..';
import { useAsync } from 'react-use';
import { techdocsStorageApiRef } from '../../api';
@@ -131,5 +131,10 @@ export const Reader = ({ entityId }: Props) => {
return <TechDocsNotFound />;
}
return <div ref={shadowDomRef} />;
return (
<>
{loading ? <Progress /> : null}
<div ref={shadowDomRef} />
</>
);
};
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-welcome",
"version": "0.1.1-alpha.18",
"version": "0.1.1-alpha.19",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -21,8 +21,8 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.19",
"@backstage/theme": "^0.1.1-alpha.19",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -32,8 +32,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/cli": "^0.1.1-alpha.19",
"@backstage/dev-utils": "^0.1.1-alpha.19",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",