diff --git a/packages/backend/package.json b/packages/backend/package.json index bf7793e33d..2e57282a07 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -27,6 +27,7 @@ "@backstage/plugin-identity-backend": "^0.1.1-alpha.13", "@backstage/plugin-scaffolder-backend": "^0.1.1-alpha.13", "@backstage/plugin-sentry-backend": "^0.1.1-alpha.13", + "@backstage/plugin-techdocs-backend": "^0.1.1-alpha.13", "dockerode": "^3.2.0", "express": "^4.17.1", "knex": "^0.21.1", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 3246c5f6f5..6841758be8 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -35,6 +35,7 @@ import catalog from './plugins/catalog'; import identity from './plugins/identity'; import scaffolder from './plugins/scaffolder'; import sentry from './plugins/sentry'; +import techdocs from './plugins/techdocs'; import { PluginEnvironment } from './types'; function makeCreateEnv(loadedConfigs: AppConfig[]) { @@ -63,6 +64,7 @@ async function main() { const scaffolderEnv = useHotMemoize(module, () => createEnv('scaffolder')); const authEnv = useHotMemoize(module, () => createEnv('auth')); const identityEnv = useHotMemoize(module, () => createEnv('identity')); + const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs')); const service = createServiceBuilder(module) .loadConfig(configReader) @@ -73,7 +75,8 @@ async function main() { await sentry(getRootLogger().child({ type: 'plugin', plugin: 'sentry' })), ) .addRouter('/auth', await auth(authEnv)) - .addRouter('/identity', await identity(identityEnv)); + .addRouter('/identity', await identity(identityEnv)) + .addRouter('/techdocs', await techdocs(techdocsEnv)); await service.start().catch(err => { console.log(err); diff --git a/packages/backend/src/plugins/techdocs.ts b/packages/backend/src/plugins/techdocs.ts new file mode 100644 index 0000000000..0d03bfabab --- /dev/null +++ b/packages/backend/src/plugins/techdocs.ts @@ -0,0 +1,22 @@ +/* + * 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 { createRouter } from '@backstage/plugin-techdocs-backend'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin({ logger }: PluginEnvironment) { + return await createRouter({ logger }); +} diff --git a/plugins/techdocs-backend/.eslintrc.js b/plugins/techdocs-backend/.eslintrc.js new file mode 100644 index 0000000000..16a033dbc6 --- /dev/null +++ b/plugins/techdocs-backend/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint.backend')], +}; diff --git a/plugins/techdocs-backend/README.md b/plugins/techdocs-backend/README.md new file mode 100644 index 0000000000..ad98d07f95 --- /dev/null +++ b/plugins/techdocs-backend/README.md @@ -0,0 +1,22 @@ +# techdocs-backend + +This is the backend part of the techdocs plugin. + +## Getting Started + +This backend plugin can be started in a standalone mode from directly in this package +with `yarn start`. However, it will have limited functionality and that process is +most convenient when developing the catalog backend plugin itself. + +To evaluate the catalog and have a greater amount of functionality available, instead do + +```bash +# in one terminal window, run this from from the very root of the Backstage project +cd packages/backend +yarn start +``` + +## Links + +- (Frontend part of the plugin)[https://github.com/spotify/backstage/tree/master/plugins/techdocs] +- (The Backstage homepage)[https://backstage.io] diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json new file mode 100644 index 0000000000..0ccae9a6f7 --- /dev/null +++ b/plugins/techdocs-backend/package.json @@ -0,0 +1,37 @@ +{ + "name": "@backstage/plugin-techdocs-backend", + "version": "0.1.1-alpha.13", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": false, + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "scripts": { + "start": "backstage-cli backend:dev", + "build": "backstage-cli backend:build", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/backend-common": "^0.1.1-alpha.12", + "@types/express": "^4.17.6", + "express": "^4.17.1", + "express-promise-router": "^3.0.3", + "knex": "^0.21.1", + "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.12", + "supertest": "^4.0.2" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/techdocs-backend/src/index.ts b/plugins/techdocs-backend/src/index.ts new file mode 100644 index 0000000000..7612c392a2 --- /dev/null +++ b/plugins/techdocs-backend/src/index.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export * from './service/router'; diff --git a/plugins/techdocs-backend/src/service/router.test.ts b/plugins/techdocs-backend/src/service/router.test.ts new file mode 100644 index 0000000000..f4dbb706fd --- /dev/null +++ b/plugins/techdocs-backend/src/service/router.test.ts @@ -0,0 +1,40 @@ +/* + * 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 express from 'express'; +import request from 'supertest'; +import { createRouter } from './router'; + +describe('createRouter', () => { + let app: express.Express; + + beforeAll(async () => { + const router = await createRouter({ + logger: getVoidLogger(), + }); + app = express().use(router); + }); + + describe('GET /', () => { + it('does not explode', async () => { + const response = await request(app).get('/'); + + expect(response.status).toEqual(200); + expect(response.text).toEqual('Hello TechDocs Backend'); + }); + }); +}); diff --git a/plugins/techdocs-backend/src/service/router.ts b/plugins/techdocs-backend/src/service/router.ts new file mode 100644 index 0000000000..7c91dd4ef7 --- /dev/null +++ b/plugins/techdocs-backend/src/service/router.ts @@ -0,0 +1,34 @@ +/* + * 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 { Logger } from 'winston'; +import Router from 'express-promise-router'; +import express from 'express'; +import Knex from 'knex'; + +type RouterOptions = { + logger: Logger; + database?: Knex; // TODO: Make database required when we're implementing database stuff. +}; + +export async function createRouter({}: RouterOptions): Promise { + const router = Router(); + + router.get('/', (_, res) => { + res.status(200).send('Hello TechDocs Backend'); + }); + + return router; +} diff --git a/plugins/techdocs-backend/src/service/standaloneServer.ts b/plugins/techdocs-backend/src/service/standaloneServer.ts new file mode 100644 index 0000000000..09acfc9e27 --- /dev/null +++ b/plugins/techdocs-backend/src/service/standaloneServer.ts @@ -0,0 +1,46 @@ +/* + * 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 { createServiceBuilder } from '@backstage/backend-common'; +import { Server } from 'http'; +import { Logger } from 'winston'; +import { createRouter } from './router'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise { + const logger = options.logger.child({ service: 'techdocs-backend' }); + + logger.debug('Creating application...'); + + logger.debug('Starting application server...'); + const router = await createRouter({ logger }); + const service = createServiceBuilder(module) + .enableCors({ origin: 'http://localhost:3000' }) + .addRouter('/techdocs', router); + return await service.start().catch(err => { + logger.error(err); + process.exit(1); + }); +} + +module.hot?.accept();