From 445d222a487d62629d3226addc3fcbcca90df055 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 5 Oct 2021 13:28:33 +0200 Subject: [PATCH 01/10] added scaffolder-common package with beta3 entity definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: blam Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- plugins/scaffolder-common/.eslintrc.js | 3 + plugins/scaffolder-common/README.md | 3 + plugins/scaffolder-common/package.json | 44 +++++ .../src/Template.v1beta3.schema.json | 186 ++++++++++++++++++ .../src/TemplateEntityV1beta3.test.ts | 157 +++++++++++++++ .../src/TemplateEntityV1beta3.ts | 37 ++++ plugins/scaffolder-common/src/index.ts | 27 +++ 7 files changed, 457 insertions(+) create mode 100644 plugins/scaffolder-common/.eslintrc.js create mode 100644 plugins/scaffolder-common/README.md create mode 100644 plugins/scaffolder-common/package.json create mode 100644 plugins/scaffolder-common/src/Template.v1beta3.schema.json create mode 100644 plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts create mode 100644 plugins/scaffolder-common/src/TemplateEntityV1beta3.ts create mode 100644 plugins/scaffolder-common/src/index.ts diff --git a/plugins/scaffolder-common/.eslintrc.js b/plugins/scaffolder-common/.eslintrc.js new file mode 100644 index 0000000000..16a033dbc6 --- /dev/null +++ b/plugins/scaffolder-common/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint.backend')], +}; diff --git a/plugins/scaffolder-common/README.md b/plugins/scaffolder-common/README.md new file mode 100644 index 0000000000..9217ceab86 --- /dev/null +++ b/plugins/scaffolder-common/README.md @@ -0,0 +1,3 @@ +# @backstage/plugin-scaffolder-common + +Common types and functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend. diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json new file mode 100644 index 0000000000..ad422fb149 --- /dev/null +++ b/plugins/scaffolder-common/package.json @@ -0,0 +1,44 @@ +{ + "name": "@backstage/plugin-scaffolder-common", + "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugin/scaffolder-common" + }, + "keywords": [ + "techdocs", + "scaffolder" + ], + "files": [ + "dist" + ], + "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" + }, + "bugs": { + "url": "https://github.com/backstage/backstage/issues" + }, + "dependencies": { + "@backstage/catalog-model": "^0.9.3", + "@backstage/config": "^0.1.10" + }, + "devDependencies": { + "@backstage/cli": "^0.7.13" + } +} diff --git a/plugins/scaffolder-common/src/Template.v1beta3.schema.json b/plugins/scaffolder-common/src/Template.v1beta3.schema.json new file mode 100644 index 0000000000..afcc6dd011 --- /dev/null +++ b/plugins/scaffolder-common/src/Template.v1beta3.schema.json @@ -0,0 +1,186 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "TemplateV1beta3", + "description": "A Template describes a scaffolding task for use with the Scaffolder. It describes the required parameters as well as a series of steps that will be taken to execute the scaffolding task.", + "examples": [ + { + "apiVersion": "templates.backstage.io/v1beta3", + "kind": "Template", + "metadata": { + "name": "react-ssr-template", + "title": "React SSR Template", + "description": "Next.js application skeleton for creating isomorphic web applications.", + "tags": ["recommended", "react"] + }, + "spec": { + "owner": "artist-relations-team", + "parameters": { + "required": ["name", "description", "repoUrl"], + "properties": { + "name": { + "title": "Name", + "type": "string", + "description": "Unique name of the component" + }, + "description": { + "title": "Description", + "type": "string", + "description": "Description of the component" + }, + "repoUrl": { + "title": "Pick a repository", + "type": "string", + "ui:field": "RepoUrlPicker" + } + } + }, + "steps": [ + { + "id": "fetch", + "name": "Fetch", + "action": "fetch:plain", + "parameters": { + "url": "./template" + } + }, + { + "id": "publish", + "name": "Publish to GitHub", + "action": "publish:github", + "parameters": { + "repoUrl": "${{ parameters.repoUrl }}" + }, + "if": "${{ parameters.repoUrl }}" + } + ], + "output": { + "catalogInfoUrl": "${{ steps.publish.output.catalogInfoUrl }}" + } + } + } + ], + "allOf": [ + { + "$ref": "Entity" + }, + { + "type": "object", + "required": ["spec"], + "properties": { + "apiVersion": { + "enum": ["templates.backstage.io/v1beta3"] + }, + "kind": { + "enum": ["Template"] + }, + "spec": { + "type": "object", + "required": ["type", "steps"], + "properties": { + "type": { + "type": "string", + "description": "The type of component created by the template. The software catalog accepts any type value, but an organization should take great care to establish a proper taxonomy for these. Tools including Backstage itself may read this field and behave differently depending on its value. For example, a website type component may present tooling in the Backstage interface that is specific to just websites.", + "examples": ["service", "website", "library"], + "minLength": 1 + }, + "parameters": { + "oneOf": [ + { + "type": "object", + "description": "The JSONSchema describing the inputs for the template." + }, + { + "type": "array", + "description": "A list of separate forms to collect parameters.", + "items": { + "type": "object", + "description": "The JSONSchema describing the inputs for the template." + } + } + ] + }, + "steps": { + "type": "array", + "description": "A list of steps to execute.", + "items": { + "type": "object", + "description": "A description of the step to execute.", + "required": ["action"], + "properties": { + "id": { + "type": "string", + "description": "The ID of the step, which can be used to refer to its outputs." + }, + "name": { + "type": "string", + "description": "The name of the step, which will be displayed in the UI during the scaffolding process." + }, + "action": { + "type": "string", + "description": "The name of the action to execute." + }, + "input": { + "type": "object", + "description": "A templated object describing the inputs to the action." + }, + "if": { + "type": ["string", "boolean"], + "description": "A templated condition that skips the step when evaluated to false. If the condition is true or not defined, the step is executed. The condition is true, if the input is not `false`, `undefined`, `null`, `\"\"`, `0`, or `[]`." + } + } + } + }, + "output": { + "type": "object", + "description": "A templated object describing the outputs of the scaffolding task.", + "properties": { + "links": { + "type": "array", + "description": "A list of external hyperlinks, typically pointing to resources created or updated by the template", + "items": { + "type": "object", + "required": [], + "properties": { + "url": { + "type": "string", + "description": "A url in a standard uri format.", + "examples": ["https://github.com/my-org/my-new-repo"], + "minLength": 1 + }, + "entityRef": { + "type": "string", + "description": "An entity reference to an entity in the catalog.", + "examples": ["Component:default/my-app"], + "minLength": 1 + }, + "title": { + "type": "string", + "description": "A user friendly display name for the link.", + "examples": ["View new repo"], + "minLength": 1 + }, + "icon": { + "type": "string", + "description": "A key representing a visual icon to be displayed in the UI.", + "examples": ["dashboard"], + "minLength": 1 + } + } + } + } + }, + "additionalProperties": { + "type": "string" + } + }, + "owner": { + "type": "string", + "description": "The user (or group) owner of the template", + "minLength": 1 + } + } + } + } + } + ] +} diff --git a/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts b/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts new file mode 100644 index 0000000000..dd3080333f --- /dev/null +++ b/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts @@ -0,0 +1,157 @@ +/* + * 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 { entityKindSchemaValidator } from '@backstage/catalog-model'; +import type { TemplateEntityV1beta3 } from './TemplateEntityV1beta3'; +import schema from './Template.v1beta3.schema.json'; + +const validator = entityKindSchemaValidator(schema); + +describe('templateEntityV1beta3Validator', () => { + let entity: TemplateEntityV1beta3; + + beforeEach(() => { + entity = { + apiVersion: 'templates.backstage.io/v1beta3', + kind: 'Template', + metadata: { + name: 'test', + }, + spec: { + type: 'website', + parameters: { + required: ['storePath', 'owner'], + properties: { + owner: { + type: 'string', + title: 'Owner', + description: 'Who is going to own this component', + }, + }, + }, + steps: [ + { + id: 'fetch', + name: 'Fetch', + action: 'fetch:plan', + input: { + url: './template', + }, + if: '${{ parameters.owner }}', + }, + ], + output: { + fetchUrl: '${{ steps.fetch.output.targetUrl }}', + }, + owner: 'team-b@example.com', + }, + }; + }); + + it('happy path: accepts valid data', async () => { + expect(validator(entity)).toBe(entity); + }); + + it('ignores unknown apiVersion', async () => { + (entity as any).apiVersion = 'backstage.io/v1beta0'; + expect(validator(entity)).toBe(false); + }); + + it('ignores unknown kind', async () => { + (entity as any).kind = 'Wizard'; + expect(validator(entity)).toBe(false); + }); + + it('rejects missing type', async () => { + delete (entity as any).spec.type; + expect(() => validator(entity)).toThrow(/type/); + }); + + it('accepts any other type', async () => { + (entity as any).spec.type = 'hallo'; + expect(validator(entity)).toBe(entity); + }); + + it('accepts missing parameters', async () => { + delete (entity as any).spec.parameters; + expect(validator(entity)).toBe(entity); + }); + + it('accepts missing outputs', async () => { + delete (entity as any).spec.outputs; + expect(validator(entity)).toBe(entity); + }); + + it('rejects empty type', async () => { + (entity as any).spec.type = ''; + expect(() => validator(entity)).toThrow(/type/); + }); + + it('rejects missing steps', async () => { + delete (entity as any).spec.steps; + expect(() => validator(entity)).toThrow(/steps/); + }); + + it('accepts step with missing id', async () => { + delete (entity as any).spec.steps[0].id; + expect(validator(entity)).toBe(entity); + }); + + it('accepts step with missing name', async () => { + delete (entity as any).spec.steps[0].name; + expect(validator(entity)).toBe(entity); + }); + + it('rejects step with missing action', async () => { + delete (entity as any).spec.steps[0].action; + expect(() => validator(entity)).toThrow(/action/); + }); + + it('accepts missing owner', async () => { + delete (entity as any).spec.owner; + expect(validator(entity)).toBe(entity); + }); + + it('rejects empty owner', async () => { + (entity as any).spec.owner = ''; + expect(() => validator(entity)).toThrow(/owner/); + }); + + it('rejects wrong type owner', async () => { + (entity as any).spec.owner = 5; + expect(() => validator(entity)).toThrow(/owner/); + }); + + it('accepts missing if', async () => { + delete (entity as any).spec.steps[0].if; + expect(validator(entity)).toBe(entity); + }); + + it('accepts boolean in if', async () => { + (entity as any).spec.steps[0].if = true; + expect(validator(entity)).toBe(entity); + }); + + it('accepts empty if', async () => { + (entity as any).spec.steps[0].if = ''; + expect(validator(entity)).toBe(entity); + }); + + it('rejects wrong type if', async () => { + (entity as any).spec.steps[0].if = 5; + expect(() => validator(entity)).toThrow(/if/); + }); +}); diff --git a/plugins/scaffolder-common/src/TemplateEntityV1beta3.ts b/plugins/scaffolder-common/src/TemplateEntityV1beta3.ts new file mode 100644 index 0000000000..ebad23f94a --- /dev/null +++ b/plugins/scaffolder-common/src/TemplateEntityV1beta3.ts @@ -0,0 +1,37 @@ +/* + * 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 { JsonObject } from '@backstage/config'; +import { Entity } from '@backstage/catalog-model'; + +/** @public */ +export interface TemplateEntityV1beta3 extends Entity { + apiVersion: 'templates.backstage.io/v1beta3'; + kind: 'Template'; + spec: { + type: string; + parameters?: JsonObject | JsonObject[]; + steps: Array<{ + id?: string; + name?: string; + action: string; + input?: JsonObject; + if?: string | boolean; + }>; + output?: { [name: string]: string }; + owner?: string; + }; +} diff --git a/plugins/scaffolder-common/src/index.ts b/plugins/scaffolder-common/src/index.ts new file mode 100644 index 0000000000..5cce1ceded --- /dev/null +++ b/plugins/scaffolder-common/src/index.ts @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/** + * Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin + * + * @packageDocumentation + */ + +// The `{ default as ...}` re-export does not seem to work for json in tests +import templateEntityV1beta3Schema from './Template.v1beta3.schema.json'; + +export type { TemplateEntityV1beta3 } from './TemplateEntityV1beta3'; +export { templateEntityV1beta3Schema }; From 65742aa801f0dc62b1668c0eb05aaf2f8a2fca12 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 5 Oct 2021 17:37:10 +0200 Subject: [PATCH 02/10] scaffolder-backend: exported new TemplateEntityProcessor Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- plugins/scaffolder-backend/package.json | 2 + plugins/scaffolder-backend/src/index.ts | 1 + .../processor/TemplateEntityProcessor.test.ts | 80 +++++++++++++++ .../src/processor/TemplateEntityProcessor.ts | 97 +++++++++++++++++++ .../scaffolder-backend/src/processor/index.ts | 17 ++++ 5 files changed, 197 insertions(+) create mode 100644 plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts create mode 100644 plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts create mode 100644 plugins/scaffolder-backend/src/processor/index.ts diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index ffe8a1e1b8..4de879d41b 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -36,6 +36,8 @@ "@backstage/config": "^0.1.10", "@backstage/errors": "^0.1.2", "@backstage/integration": "^0.6.7", + "@backstage/plugin-catalog-backend": "^0.15.0", + "@backstage/plugin-scaffolder-common": "^0.1.0", "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.2", "@gitbeaker/core": "^30.2.0", "@gitbeaker/node": "^30.2.0", diff --git a/plugins/scaffolder-backend/src/index.ts b/plugins/scaffolder-backend/src/index.ts index a7ae821463..76cda63eef 100644 --- a/plugins/scaffolder-backend/src/index.ts +++ b/plugins/scaffolder-backend/src/index.ts @@ -23,3 +23,4 @@ export * from './scaffolder'; export * from './service/router'; export * from './lib/catalog'; +export * from './processor'; diff --git a/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts b/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts new file mode 100644 index 0000000000..6b9576695a --- /dev/null +++ b/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts @@ -0,0 +1,80 @@ +/* + * 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 { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; +import { TemplateEntityProcessor } from './TemplateEntityProcessor'; + +const mockLocation = { type: 'a', target: 'b' }; +const mockEntity: TemplateEntityV1beta3 = { + apiVersion: 'templates.backstage.io/v1beta3', + kind: 'Template', + metadata: { name: 'n' }, + spec: { + parameters: {}, + steps: [], + type: 'service', + owner: 'o', + }, +}; + +describe('TemplateEntityProcessor', () => { + describe('validateEntityKind', () => { + it('validates the entity kind', async () => { + const processor = new TemplateEntityProcessor(); + + await expect(processor.validateEntityKind(mockEntity)).resolves.toBe( + true, + ); + await expect( + processor.validateEntityKind({ + ...mockEntity, + apiVersion: 'backstage.io/v1beta3', + }), + ).resolves.toBe(false); + await expect( + processor.validateEntityKind({ ...mockEntity, kind: 'Component' }), + ).resolves.toBe(false); + }); + }); + + describe('postProcessEntity', () => { + it('generates relations for component entities', async () => { + const processor = new TemplateEntityProcessor(); + + const emit = jest.fn(); + + await processor.postProcessEntity(mockEntity, mockLocation, emit); + + expect(emit).toBeCalledTimes(2); + expect(emit).toBeCalledWith({ + type: 'relation', + relation: { + source: { kind: 'Group', namespace: 'default', name: 'o' }, + type: 'ownerOf', + target: { kind: 'Template', namespace: 'default', name: 'n' }, + }, + }); + expect(emit).toBeCalledWith({ + type: 'relation', + relation: { + source: { kind: 'Template', namespace: 'default', name: 'n' }, + type: 'ownedBy', + target: { kind: 'Group', namespace: 'default', name: 'o' }, + }, + }); + }); + }); +}); diff --git a/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts b/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts new file mode 100644 index 0000000000..dc11b6d86d --- /dev/null +++ b/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts @@ -0,0 +1,97 @@ +/* + * 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 { + Entity, + getEntityName, + LocationSpec, + parseEntityRef, + RELATION_OWNED_BY, + RELATION_OWNER_OF, + entityKindSchemaValidator, +} from '@backstage/catalog-model'; +import { + CatalogProcessor, + CatalogProcessorEmit, + results, +} from '@backstage/plugin-catalog-backend'; +import { + TemplateEntityV1beta3, + templateEntityV1beta3Schema, +} from '@backstage/plugin-scaffolder-common'; + +export class TemplateEntityProcessor implements CatalogProcessor { + private readonly validators = [ + entityKindSchemaValidator(templateEntityV1beta3Schema), + ]; + + async validateEntityKind(entity: Entity): Promise { + for (const validator of this.validators) { + if (validator(entity)) { + return true; + } + } + + return false; + } + + async postProcessEntity( + entity: Entity, + _location: LocationSpec, + emit: CatalogProcessorEmit, + ): Promise { + const selfRef = getEntityName(entity); + + if ( + entity.apiVersion === 'templates.backstage.io/v1beta3' && + entity.kind === 'Template' + ) { + const template = entity as TemplateEntityV1beta3; + + const target = template.spec.owner; + if (target) { + const targetRef = parseEntityRef(target, { + defaultKind: 'Group', + defaultNamespace: selfRef.namespace, + }); + emit( + results.relation({ + source: selfRef, + type: RELATION_OWNED_BY, + target: { + kind: targetRef.kind, + namespace: targetRef.namespace, + name: targetRef.name, + }, + }), + ); + emit( + results.relation({ + source: { + kind: targetRef.kind, + namespace: targetRef.namespace, + name: targetRef.name, + }, + type: RELATION_OWNER_OF, + target: selfRef, + }), + ); + } + } + + return entity; + } +} diff --git a/plugins/scaffolder-backend/src/processor/index.ts b/plugins/scaffolder-backend/src/processor/index.ts new file mode 100644 index 0000000000..621ac186a4 --- /dev/null +++ b/plugins/scaffolder-backend/src/processor/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 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. + */ + +export { TemplateEntityProcessor } from './TemplateEntityProcessor'; From 987eb79f63f7b41389aacf79a4b0353578adc69a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 6 Oct 2021 11:23:08 +0200 Subject: [PATCH 03/10] scaffolder-common: use apiVersion group scaffolder.backstage.io Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- .../src/processor/TemplateEntityProcessor.test.ts | 2 +- .../src/processor/TemplateEntityProcessor.ts | 2 +- plugins/scaffolder-common/src/Template.v1beta3.schema.json | 4 ++-- plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts | 2 +- plugins/scaffolder-common/src/TemplateEntityV1beta3.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts b/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts index 6b9576695a..568231f673 100644 --- a/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts +++ b/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts @@ -19,7 +19,7 @@ import { TemplateEntityProcessor } from './TemplateEntityProcessor'; const mockLocation = { type: 'a', target: 'b' }; const mockEntity: TemplateEntityV1beta3 = { - apiVersion: 'templates.backstage.io/v1beta3', + apiVersion: 'scaffolder.backstage.io/v1beta3', kind: 'Template', metadata: { name: 'n' }, spec: { diff --git a/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts b/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts index dc11b6d86d..8bd741a4ce 100644 --- a/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts +++ b/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts @@ -56,7 +56,7 @@ export class TemplateEntityProcessor implements CatalogProcessor { const selfRef = getEntityName(entity); if ( - entity.apiVersion === 'templates.backstage.io/v1beta3' && + entity.apiVersion === 'scaffolder.backstage.io/v1beta3' && entity.kind === 'Template' ) { const template = entity as TemplateEntityV1beta3; diff --git a/plugins/scaffolder-common/src/Template.v1beta3.schema.json b/plugins/scaffolder-common/src/Template.v1beta3.schema.json index afcc6dd011..6992e82f02 100644 --- a/plugins/scaffolder-common/src/Template.v1beta3.schema.json +++ b/plugins/scaffolder-common/src/Template.v1beta3.schema.json @@ -4,7 +4,7 @@ "description": "A Template describes a scaffolding task for use with the Scaffolder. It describes the required parameters as well as a series of steps that will be taken to execute the scaffolding task.", "examples": [ { - "apiVersion": "templates.backstage.io/v1beta3", + "apiVersion": "scaffolder.backstage.io/v1beta3", "kind": "Template", "metadata": { "name": "react-ssr-template", @@ -68,7 +68,7 @@ "required": ["spec"], "properties": { "apiVersion": { - "enum": ["templates.backstage.io/v1beta3"] + "enum": ["scaffolder.backstage.io/v1beta3"] }, "kind": { "enum": ["Template"] diff --git a/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts b/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts index dd3080333f..7863b7b476 100644 --- a/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts +++ b/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts @@ -25,7 +25,7 @@ describe('templateEntityV1beta3Validator', () => { beforeEach(() => { entity = { - apiVersion: 'templates.backstage.io/v1beta3', + apiVersion: 'scaffolder.backstage.io/v1beta3', kind: 'Template', metadata: { name: 'test', diff --git a/plugins/scaffolder-common/src/TemplateEntityV1beta3.ts b/plugins/scaffolder-common/src/TemplateEntityV1beta3.ts index ebad23f94a..6471fe0ca6 100644 --- a/plugins/scaffolder-common/src/TemplateEntityV1beta3.ts +++ b/plugins/scaffolder-common/src/TemplateEntityV1beta3.ts @@ -19,7 +19,7 @@ import { Entity } from '@backstage/catalog-model'; /** @public */ export interface TemplateEntityV1beta3 extends Entity { - apiVersion: 'templates.backstage.io/v1beta3'; + apiVersion: 'scaffolder.backstage.io/v1beta3'; kind: 'Template'; spec: { type: string; From 17bca651a696cee0f57dd45abaecd87d690d2080 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 6 Oct 2021 11:32:07 +0200 Subject: [PATCH 04/10] scaffolder-backend: rename to ScaffolderEntitiesProcessor Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- ...cessor.test.ts => ScaffolderEntitiesProcessor.test.ts} | 8 ++++---- ...eEntityProcessor.ts => ScaffolderEntitiesProcessor.ts} | 2 +- plugins/scaffolder-backend/src/processor/index.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) rename plugins/scaffolder-backend/src/processor/{TemplateEntityProcessor.test.ts => ScaffolderEntitiesProcessor.test.ts} (90%) rename plugins/scaffolder-backend/src/processor/{TemplateEntityProcessor.ts => ScaffolderEntitiesProcessor.ts} (97%) diff --git a/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts b/plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.test.ts similarity index 90% rename from plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts rename to plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.test.ts index 568231f673..c5278edce3 100644 --- a/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.test.ts +++ b/plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.test.ts @@ -15,7 +15,7 @@ */ import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { TemplateEntityProcessor } from './TemplateEntityProcessor'; +import { ScaffolderEntitiesProcessor } from './ScaffolderEntitiesProcessor'; const mockLocation = { type: 'a', target: 'b' }; const mockEntity: TemplateEntityV1beta3 = { @@ -30,10 +30,10 @@ const mockEntity: TemplateEntityV1beta3 = { }, }; -describe('TemplateEntityProcessor', () => { +describe('ScaffolderEntitiesProcessor', () => { describe('validateEntityKind', () => { it('validates the entity kind', async () => { - const processor = new TemplateEntityProcessor(); + const processor = new ScaffolderEntitiesProcessor(); await expect(processor.validateEntityKind(mockEntity)).resolves.toBe( true, @@ -52,7 +52,7 @@ describe('TemplateEntityProcessor', () => { describe('postProcessEntity', () => { it('generates relations for component entities', async () => { - const processor = new TemplateEntityProcessor(); + const processor = new ScaffolderEntitiesProcessor(); const emit = jest.fn(); diff --git a/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts b/plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.ts similarity index 97% rename from plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts rename to plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.ts index 8bd741a4ce..c69ba154f6 100644 --- a/plugins/scaffolder-backend/src/processor/TemplateEntityProcessor.ts +++ b/plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.ts @@ -33,7 +33,7 @@ import { templateEntityV1beta3Schema, } from '@backstage/plugin-scaffolder-common'; -export class TemplateEntityProcessor implements CatalogProcessor { +export class ScaffolderEntitiesProcessor implements CatalogProcessor { private readonly validators = [ entityKindSchemaValidator(templateEntityV1beta3Schema), ]; diff --git a/plugins/scaffolder-backend/src/processor/index.ts b/plugins/scaffolder-backend/src/processor/index.ts index 621ac186a4..518827668d 100644 --- a/plugins/scaffolder-backend/src/processor/index.ts +++ b/plugins/scaffolder-backend/src/processor/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export { TemplateEntityProcessor } from './TemplateEntityProcessor'; +export { ScaffolderEntitiesProcessor } from './ScaffolderEntitiesProcessor'; From eaca0f53fb4fffb2b10b2eee4532a90f3fe2efee Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 6 Oct 2021 11:50:45 +0200 Subject: [PATCH 05/10] backend,create-app: install ScaffolderEntitiesProcessor Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- .changeset/funny-dolls-draw.md | 19 +++++++++++++++++++ packages/backend/src/plugins/catalog.ts | 2 ++ .../packages/backend/src/plugins/catalog.ts | 2 ++ 3 files changed, 23 insertions(+) create mode 100644 .changeset/funny-dolls-draw.md diff --git a/.changeset/funny-dolls-draw.md b/.changeset/funny-dolls-draw.md new file mode 100644 index 0000000000..f194b30750 --- /dev/null +++ b/.changeset/funny-dolls-draw.md @@ -0,0 +1,19 @@ +--- +'@backstage/create-app': patch +--- + +The scaffolder plugin has just released the beta 3 version of software templates, which replaces the handlebars templating syntax. As part of this change, the template entity schema is no longer included in the core catalog-model as with previous versions. The decoupling of the template entities version will allow us to more easily make updates in the future. + +In order to use the new beta 3 templates, the following changes are **required** for any existing installation, inside `packages/backend/src/plugins/catalog.ts`: + +```diff ++import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend'; + +... + + const builder = await CatalogBuilder.create(env); ++ builder.addProcessor(new ScaffolderEntitiesProcessor()); + const { processingEngine, router } = await builder.build(); +``` + +If you're interested in learning more about creating custom kinds, please check out the [extending the model](https://backstage.io/docs/features/software-catalog/extending-the-model) documentation. diff --git a/packages/backend/src/plugins/catalog.ts b/packages/backend/src/plugins/catalog.ts index 6a903d0df8..7beeb4f35e 100644 --- a/packages/backend/src/plugins/catalog.ts +++ b/packages/backend/src/plugins/catalog.ts @@ -15,6 +15,7 @@ */ import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; +import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; @@ -22,6 +23,7 @@ export default async function createPlugin( env: PluginEnvironment, ): Promise { const builder = await CatalogBuilder.create(env); + builder.addProcessor(new ScaffolderEntitiesProcessor()); const { processingEngine, router } = await builder.build(); await processingEngine.start(); return router; diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/catalog.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/catalog.ts index d1ded511da..876cb6bccc 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/plugins/catalog.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/catalog.ts @@ -1,4 +1,5 @@ import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; +import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; @@ -6,6 +7,7 @@ export default async function createPlugin( env: PluginEnvironment, ): Promise { const builder = await CatalogBuilder.create(env); + builder.addProcessor(new ScaffolderEntitiesProcessor()); const { processingEngine, router } = await builder.build(); await processingEngine.start(); return router; From 1a6de93e200aba002d4fcbb019dcd73e4f1f8d44 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 6 Oct 2021 13:32:16 +0200 Subject: [PATCH 06/10] scaffolder-common,scaffolder-backend: udpate API reports Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- plugins/scaffolder-backend/api-report.md | 16 +++++++++++ plugins/scaffolder-common/api-report.md | 36 ++++++++++++++++++++++++ plugins/scaffolder-common/src/index.ts | 11 ++++++-- 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 plugins/scaffolder-common/api-report.md diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 4a8c103906..ef4defcc50 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -6,13 +6,17 @@ /// import { CatalogApi } from '@backstage/catalog-client'; +import { CatalogProcessor } from '@backstage/plugin-catalog-backend'; +import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend'; import { Config } from '@backstage/config'; import { ContainerRunner } from '@backstage/backend-common'; import { createFetchCookiecutterAction } from '@backstage/plugin-scaffolder-backend-module-cookiecutter'; import { createPullRequest } from 'octokit-plugin-create-pull-request'; +import { Entity } from '@backstage/catalog-model'; import express from 'express'; import { JsonObject } from '@backstage/config'; import { JsonValue } from '@backstage/config'; +import { LocationSpec } from '@backstage/catalog-model'; import { Logger as Logger_2 } from 'winston'; import { Octokit } from '@octokit/rest'; import { PluginDatabaseManager } from '@backstage/backend-common'; @@ -244,6 +248,18 @@ export const runCommand: ({ logStream, }: RunCommandOptions) => Promise; +// @public (undocumented) +export class ScaffolderEntitiesProcessor implements CatalogProcessor { + // (undocumented) + postProcessEntity( + entity: Entity, + _location: LocationSpec, + emit: CatalogProcessorEmit, + ): Promise; + // (undocumented) + validateEntityKind(entity: Entity): Promise; +} + // Warning: (ae-missing-release-tag) "TemplateAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) diff --git a/plugins/scaffolder-common/api-report.md b/plugins/scaffolder-common/api-report.md new file mode 100644 index 0000000000..722e746967 --- /dev/null +++ b/plugins/scaffolder-common/api-report.md @@ -0,0 +1,36 @@ +## API Report File for "@backstage/plugin-scaffolder-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Entity } from '@backstage/catalog-model'; +import { JsonObject } from '@backstage/config'; +import { JSONSchema } from '@backstage/catalog-model'; + +// @public (undocumented) +export interface TemplateEntityV1beta3 extends Entity { + // (undocumented) + apiVersion: 'scaffolder.backstage.io/v1beta3'; + // (undocumented) + kind: 'Template'; + // (undocumented) + spec: { + type: string; + parameters?: JsonObject | JsonObject[]; + steps: Array<{ + id?: string; + name?: string; + action: string; + input?: JsonObject; + if?: string | boolean; + }>; + output?: { + [name: string]: string; + }; + owner?: string; + }; +} + +// @public (undocumented) +export const templateEntityV1beta3Schema: JSONSchema; +``` diff --git a/plugins/scaffolder-common/src/index.ts b/plugins/scaffolder-common/src/index.ts index 5cce1ceded..3b6fa71d7a 100644 --- a/plugins/scaffolder-common/src/index.ts +++ b/plugins/scaffolder-common/src/index.ts @@ -20,8 +20,13 @@ * @packageDocumentation */ -// The `{ default as ...}` re-export does not seem to work for json in tests -import templateEntityV1beta3Schema from './Template.v1beta3.schema.json'; +import { JSONSchema } from '@backstage/catalog-model'; +import v1beta3Schema from './Template.v1beta3.schema.json'; export type { TemplateEntityV1beta3 } from './TemplateEntityV1beta3'; -export { templateEntityV1beta3Schema }; + +/** @public */ +export const templateEntityV1beta3Schema: JSONSchema = v1beta3Schema as Omit< + JSONSchema, + 'examples' +>; From 7f2d184eb448e0780012af46e85a14adec060b4c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 6 Oct 2021 15:14:12 +0200 Subject: [PATCH 07/10] docs: add implementation section to extending the catalog model Co-authored-by: Johan Haals Signed-off-by: Patrik Oldsberg --- .../software-catalog/extending-the-model.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/docs/features/software-catalog/extending-the-model.md b/docs/features/software-catalog/extending-the-model.md index ed106bb5dd..340daae7d3 100644 --- a/docs/features/software-catalog/extending-the-model.md +++ b/docs/features/software-catalog/extending-the-model.md @@ -429,3 +429,101 @@ from one environment to the other, do rollbacks, see their relative performance metrics, and similar. This coherency and collection of tooling in one place is where something like Backstage can offer the most value and effectiveness of use. Splitting your entities apart into small islands makes this harder. + +## Implementing custom model extensions + +This section walks you through the steps involved extending the catalog model +with a new Entity type. + +### Creating a custom entity definition + +The first step of introducing a custom entity is to define what shape and schema +it has. We do this both using a TypeScript type, along with a JSONSchema schema. + +Most of the time you will want to have at least the TypeScript type of your +extension available in both frontend and backend code, which means you likely +want to have an isomorphic package that houses these types. Within the Backstage +main repo the package naming pattern of `-common` is used for isomorphic +packages, and you may choose to adopt this pattern as well. + +There's at this point no existing templates for generating isomorphic plugins +using the `@backstage/cli`. Perhaps the simplest wat to get started right now is +to copy the contents of one of the existing packages in the main repository, +such as `plugins/scaffolder-common`, and rename the folder and file contents to +the desired name. This example uses _foobar_ as the plugin name so the plugin +will be named _foobar-common_. + +Once you have a common package in place you can start adding your own entity +definitions. For the exact details on how to do that we defer to getting +inspired by the existing +[scaffolder-common](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-common/src/index.ts) +package. But in short you will need to declare a TypeScript type and a +JSONSchema for the new entity kind. + +### Building a custom processor for the entity + +The next step is to create a custom processor for your new entity kind. This +will be used within the catalog to make sure that it's able to ingest and +validate entities of our new kind. Just like with the definition package, you +can find inspiration in for example the existing +[ScaffolderEntitiesProcessor](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.ts). +We also provide a high-level example of what a catalog process for a custom +entity might look like: + +```ts +import { entityKindSchemaValidator } from '@backstage/catalog-model'; + +export class FoobarEntitiesProcessor implements CatalogProcessor { + // You often end up wanting to support multiple versions of your kind as you + // iterate on the definition, so we keep each version inside this array. + private readonly validators = [ + // This is where we use the JSONSchema that we export from our isomorphic package + entityKindSchemaValidator(foobarEntityV1alpha1Schema), + ]; + + // validateEntityKind is responsible for signaling to the catalog processing engine + // that this entity is valid and should therefore be submitted for further processing. + async validateEntityKind(entity: Entity): Promise { + for (const validator of this.validators) { + if (validator(entity)) { + return true; + } + } + + return false; + } + + async postProcessEntity( + entity: Entity, + _location: LocationSpec, + emit: CatalogProcessorEmit, + ): Promise { + if ( + entity.apiVersion === 'example.com/v1alpha1' && + entity.kind === 'Foobar' + ) { + const foobarEntity = entity as FoobarEntityV1alpha1; + + // Here we can modify the entity or emit results related to the entity + // Typically you will want to emit any relations associated with the entity here + emit(results.relation({ ... })) + } + + return entity; + } +} +``` + +Once the processor is created it can be wired up to the catalog via the +`CatalogBuilder` in `packages/backend/src/plugins/catalog.ts`: + +```diff ++ import { FoobarEntitiesProcessor implements CatalogProcessor { + } from '@internal/plugin-foobar-backend'; + + // ... + + const builder = await CatalogBuilder.create(env); ++ builder.addProcessor(new FoobarEntitiesProcessor()); + const { processingEngine, router } = await builder.build(); +``` From 0f74ce87fb6bb70ba12ba5b4e75115c3dd7a3a5c Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 6 Oct 2021 15:24:44 +0200 Subject: [PATCH 08/10] scaffolder: apply review fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Johan Haals Co-authored-by: Fredrik Adelöw Signed-off-by: Patrik Oldsberg --- .../src/processor/ScaffolderEntitiesProcessor.ts | 1 + plugins/scaffolder-common/.eslintrc.js | 2 +- plugins/scaffolder-common/package.json | 4 ++-- .../scaffolder-common/src/Template.v1beta3.schema.json | 10 +++++----- .../src/TemplateEntityV1beta3.test.ts | 4 ++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.ts b/plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.ts index c69ba154f6..4f3c13f342 100644 --- a/plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.ts +++ b/plugins/scaffolder-backend/src/processor/ScaffolderEntitiesProcessor.ts @@ -33,6 +33,7 @@ import { templateEntityV1beta3Schema, } from '@backstage/plugin-scaffolder-common'; +/** @public */ export class ScaffolderEntitiesProcessor implements CatalogProcessor { private readonly validators = [ entityKindSchemaValidator(templateEntityV1beta3Schema), diff --git a/plugins/scaffolder-common/.eslintrc.js b/plugins/scaffolder-common/.eslintrc.js index 16a033dbc6..13573efa9c 100644 --- a/plugins/scaffolder-common/.eslintrc.js +++ b/plugins/scaffolder-common/.eslintrc.js @@ -1,3 +1,3 @@ module.exports = { - extends: [require.resolve('@backstage/cli/config/eslint.backend')], + extends: [require.resolve('@backstage/cli/config/eslint')], }; diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index ad422fb149..27aa2594b2 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -5,6 +5,7 @@ "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", + "private": false, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -14,10 +15,9 @@ "repository": { "type": "git", "url": "https://github.com/backstage/backstage", - "directory": "plugin/scaffolder-common" + "directory": "plugins/scaffolder-common" }, "keywords": [ - "techdocs", "scaffolder" ], "files": [ diff --git a/plugins/scaffolder-common/src/Template.v1beta3.schema.json b/plugins/scaffolder-common/src/Template.v1beta3.schema.json index 6992e82f02..e45bfb788d 100644 --- a/plugins/scaffolder-common/src/Template.v1beta3.schema.json +++ b/plugins/scaffolder-common/src/Template.v1beta3.schema.json @@ -83,6 +83,11 @@ "examples": ["service", "website", "library"], "minLength": 1 }, + "owner": { + "type": "string", + "description": "The user (or group) owner of the template", + "minLength": 1 + }, "parameters": { "oneOf": [ { @@ -172,11 +177,6 @@ "additionalProperties": { "type": "string" } - }, - "owner": { - "type": "string", - "description": "The user (or group) owner of the template", - "minLength": 1 } } } diff --git a/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts b/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts index 7863b7b476..ab5900ab32 100644 --- a/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts +++ b/plugins/scaffolder-common/src/TemplateEntityV1beta3.test.ts @@ -32,8 +32,9 @@ describe('templateEntityV1beta3Validator', () => { }, spec: { type: 'website', + owner: 'team-b', parameters: { - required: ['storePath', 'owner'], + required: ['owner'], properties: { owner: { type: 'string', @@ -56,7 +57,6 @@ describe('templateEntityV1beta3Validator', () => { output: { fetchUrl: '${{ steps.fetch.output.targetUrl }}', }, - owner: 'team-b@example.com', }, }; }); From f20547d7454654fa45c7adfbecc259a14344545b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Wed, 6 Oct 2021 20:08:28 +0200 Subject: [PATCH 09/10] scaffolder-common: fix module entrypoints Signed-off-by: Patrik Oldsberg --- plugins/scaffolder-common/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index 27aa2594b2..d00918322b 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -8,7 +8,8 @@ "private": false, "publishConfig": { "access": "public", - "main": "dist/index.esm.js", + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, "homepage": "https://backstage.io", From e23831dffb626a5bb07e8b4807b9979deead7c50 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 11 Oct 2021 11:12:51 +0200 Subject: [PATCH 10/10] scaffolder-{backend,common}: fix outdated dependency versions Signed-off-by: Patrik Oldsberg --- plugins/scaffolder-backend/package.json | 2 +- plugins/scaffolder-common/package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 4de879d41b..98fd053771 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -36,7 +36,7 @@ "@backstage/config": "^0.1.10", "@backstage/errors": "^0.1.2", "@backstage/integration": "^0.6.7", - "@backstage/plugin-catalog-backend": "^0.15.0", + "@backstage/plugin-catalog-backend": "^0.16.0", "@backstage/plugin-scaffolder-common": "^0.1.0", "@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.2", "@gitbeaker/core": "^30.2.0", diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index d00918322b..7f79dab541 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -36,10 +36,10 @@ "url": "https://github.com/backstage/backstage/issues" }, "dependencies": { - "@backstage/catalog-model": "^0.9.3", + "@backstage/catalog-model": "^0.9.4", "@backstage/config": "^0.1.10" }, "devDependencies": { - "@backstage/cli": "^0.7.13" + "@backstage/cli": "^0.7.15" } }