diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts new file mode 100644 index 0000000000..0829a101f2 --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -0,0 +1,71 @@ +/* + * Copyright 2021 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 { UrlReader } from '@backstage/backend-common'; +import { CatalogApi } from '@backstage/catalog-client'; +import { ScmIntegrations } from '@backstage/integration'; +import { createCatalogRegisterAction } from './catalog'; +import { createFetchCookiecutterAction, createFetchPlainAction } from './fetch'; +import { + createPublishAzureAction, + createPublishBitbucketAction, + createPublishGithubAction, + createPublishGitlabAction, +} from './publish'; +import Docker from 'dockerode'; +import { TemplaterBuilder } from '../../stages'; + +export const createBuiltinActions = (options: { + reader: UrlReader; + integrations: ScmIntegrations; + dockerClient: Docker; + catalogClient: CatalogApi; + templaters: TemplaterBuilder; +}) => { + const { + reader, + integrations, + dockerClient, + templaters, + catalogClient, + } = options; + + return [ + createFetchPlainAction({ + reader, + integrations, + }), + createFetchCookiecutterAction({ + reader, + integrations, + dockerClient, + templaters, + }), + createPublishGithubAction({ + integrations, + }), + createPublishGitlabAction({ + integrations, + }), + createPublishBitbucketAction({ + integrations, + }), + createPublishAzureAction({ + integrations, + }), + createCatalogRegisterAction({ catalogClient, integrations }), + ]; +}; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts index c85c6e33ce..e4281c172b 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/index.ts @@ -17,3 +17,4 @@ export * from './catalog'; export * from './fetch'; export * from './publish'; +export { createBuiltinActions } from './createBuiltinActions'; diff --git a/plugins/scaffolder-backend/src/scaffolder/index.ts b/plugins/scaffolder-backend/src/scaffolder/index.ts index 470bc230d6..9de10ca1eb 100644 --- a/plugins/scaffolder-backend/src/scaffolder/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/index.ts @@ -15,3 +15,4 @@ */ export * from './stages'; export * from './jobs'; +export * from './actions'; diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/index.ts b/plugins/scaffolder-backend/src/scaffolder/stages/index.ts index dfe49a8aa5..ef23af1b3e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/index.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/index.ts @@ -17,3 +17,5 @@ export * from './prepare'; export * from './publish'; export * from './templater'; export * from './helpers'; + +export { createLegacyActions } from './legacy'; diff --git a/plugins/scaffolder-backend/src/scaffolder/stages/legacy.ts b/plugins/scaffolder-backend/src/scaffolder/stages/legacy.ts index deebb9b1bc..c7c52fa320 100644 --- a/plugins/scaffolder-backend/src/scaffolder/stages/legacy.ts +++ b/plugins/scaffolder-backend/src/scaffolder/stages/legacy.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { TemplateActionRegistry } from '../actions/TemplateActionRegistry'; import { FilePreparer, PreparerBuilder } from './prepare'; import Docker from 'dockerode'; import { TemplaterBuilder, TemplaterValues } from './templater'; import { PublisherBuilder } from './publish'; +import { createTemplateAction } from '../actions'; type Options = { dockerClient: Docker; @@ -27,81 +27,82 @@ type Options = { publishers: PublisherBuilder; }; -export function registerLegacyActions( - registry: TemplateActionRegistry, - options: Options, -) { +export function createLegacyActions(options: Options) { const { dockerClient, preparers, templaters, publishers } = options; - registry.register({ - id: 'legacy:prepare', - async handler(ctx) { - ctx.logger.info('Preparing the skeleton'); - const { protocol, url } = ctx.input; - const preparer = - protocol === 'file' ? new FilePreparer() : preparers.get(url as string); + return [ + createTemplateAction({ + id: 'legacy:prepare', + async handler(ctx) { + ctx.logger.info('Preparing the skeleton'); + const { protocol, url } = ctx.input; + const preparer = + protocol === 'file' + ? new FilePreparer() + : preparers.get(url as string); - await preparer.prepare({ - url: url as string, - logger: ctx.logger, - workspacePath: ctx.workspacePath, - }); - }, - }); + await preparer.prepare({ + url: url as string, + logger: ctx.logger, + workspacePath: ctx.workspacePath, + }); + }, + }), + createTemplateAction({ + id: 'legacy:template', + async handler(ctx) { + ctx.logger.info('Running the templater'); + const templater = templaters.get(ctx.input.templater as string); + await templater.run({ + workspacePath: ctx.workspacePath, + dockerClient, + logStream: ctx.logStream, + values: ctx.input.values as TemplaterValues, + }); + }, + }), + createTemplateAction({ + id: 'legacy:publish', + async handler(ctx) { + const { values } = ctx.input; + if ( + typeof values !== 'object' || + values === null || + Array.isArray(values) + ) { + throw new Error( + `Invalid values passed to publish, got ${typeof values}`, + ); + } + const storePath = values.storePath as unknown; + if (typeof storePath !== 'string') { + throw new Error( + `Invalid store path passed to publish, got ${typeof storePath}`, + ); + } + const owner = values.owner as unknown; + if (typeof owner !== 'string') { + throw new Error( + `Invalid owner passed to publish, got ${typeof owner}`, + ); + } - registry.register({ - id: 'legacy:template', - async handler(ctx) { - ctx.logger.info('Running the templater'); - const templater = templaters.get(ctx.input.templater as string); - await templater.run({ - workspacePath: ctx.workspacePath, - dockerClient, - logStream: ctx.logStream, - values: ctx.input.values as TemplaterValues, - }); - }, - }); - - registry.register({ - id: 'legacy:publish', - async handler(ctx) { - const { values } = ctx.input; - if ( - typeof values !== 'object' || - values === null || - Array.isArray(values) - ) { - throw new Error( - `Invalid values passed to publish, got ${typeof values}`, - ); - } - const storePath = values.storePath as unknown; - if (typeof storePath !== 'string') { - throw new Error( - `Invalid store path passed to publish, got ${typeof storePath}`, - ); - } - const owner = values.owner as unknown; - if (typeof owner !== 'string') { - throw new Error(`Invalid owner passed to publish, got ${typeof owner}`); - } - - const publisher = publishers.get(storePath); - ctx.logger.info('Will now store the template'); - const { remoteUrl, catalogInfoUrl } = await publisher.publish({ - values: { - ...values, - owner, - storePath, - }, - workspacePath: ctx.workspacePath, - logger: ctx.logger, - }); - ctx.output('remoteUrl', remoteUrl); - if (catalogInfoUrl) { - ctx.output('catalogInfoUrl', catalogInfoUrl); - } - }, - }); + const publisher = publishers.get(storePath); + ctx.logger.info('Will now store the template'); + const { remoteUrl, catalogInfoUrl } = await publisher.publish({ + values: { + ...values, + owner, + storePath, + }, + workspacePath: ctx.workspacePath, + logger: ctx.logger, + }); + ctx.output('remoteUrl', remoteUrl); + if (catalogInfoUrl) { + ctx.output('catalogInfoUrl', catalogInfoUrl); + } + }, + }), + ]; } diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index e9bfd0e74a..1ed0c1af7a 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -40,7 +40,7 @@ import { } from '../scaffolder/tasks'; import { templateEntityToSpec } from '../scaffolder/tasks/TemplateConverter'; import { TemplateActionRegistry } from '../scaffolder/actions/TemplateActionRegistry'; -import { registerLegacyActions } from '../scaffolder/stages/legacy'; +import { createLegacyActions } from '../scaffolder/stages/legacy'; import { getEntityBaseUrl, getWorkingDirectory } from './helpers'; import { InputError, @@ -54,16 +54,9 @@ import { TemplateEntityV1beta2, Entity, } from '@backstage/catalog-model'; -import { - createFetchPlainAction, - createFetchCookiecutterAction, - createPublishGithubAction, - createPublishBitbucketAction, - createPublishAzureAction, - createPublishGitlabAction, - createCatalogRegisterAction, -} from '../scaffolder/actions/builtin'; import { ScmIntegrations } from '@backstage/integration'; +import { TemplateAction } from '../scaffolder/actions'; +import { createBuiltinActions } from '../scaffolder/actions/builtin/createBuiltinActions'; export interface RouterOptions { preparers: PreparerBuilder; @@ -76,6 +69,7 @@ export interface RouterOptions { dockerClient: Docker; database: PluginDatabaseManager; catalogClient: CatalogApi; + actions?: TemplateAction[]; } function isAlpha1Template( @@ -109,6 +103,7 @@ export async function createRouter( dockerClient, database, catalogClient, + actions, } = options; const logger = parentLogger.child({ plugin: 'scaffolder' }); @@ -129,52 +124,25 @@ export async function createRouter( workingDirectory, }); - registerLegacyActions(actionRegistry, { - dockerClient, - preparers, - publishers, - templaters, - }); - actionRegistry.register( - createFetchPlainAction({ - reader, - integrations, - }), - ); - actionRegistry.register( - createFetchCookiecutterAction({ - reader, - integrations, - dockerClient, - templaters, - }), - ); - actionRegistry.register( - createPublishGithubAction({ - integrations, - }), - ); - actionRegistry.register( - createPublishGitlabAction({ - integrations, - }), - ); + const actionsToRegister = Array.isArray(actions) + ? actions + : [ + ...createLegacyActions({ + dockerClient, + preparers, + publishers, + templaters, + }), + ...createBuiltinActions({ + dockerClient, + integrations, + catalogClient, + templaters, + reader, + }), + ]; - actionRegistry.register( - createPublishBitbucketAction({ - integrations, - }), - ); - - actionRegistry.register( - createPublishAzureAction({ - integrations, - }), - ); - - actionRegistry.register( - createCatalogRegisterAction({ catalogClient, integrations }), - ); + actionsToRegister.forEach(action => actionRegistry.register(action)); worker.start();