diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts deleted file mode 100644 index 3ce3052956..0000000000 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/cookiecutter.test.ts +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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. - */ -jest.mock('./helpers'); - -import { getVoidLogger, UrlReader } from '@backstage/backend-common'; -import { ConfigReader } from '@backstage/config'; -import { ScmIntegrations } from '@backstage/integration'; -import mock from 'mock-fs'; -import os from 'os'; -import { resolve as resolvePath } from 'path'; -import { PassThrough } from 'stream'; -import { Templaters } from '../../../stages/templater'; -import { createFetchCookiecutterAction } from './cookiecutter'; -import { fetchContents } from './helpers'; - -describe('fetch:cookiecutter', () => { - const integrations = ScmIntegrations.fromConfig( - new ConfigReader({ - integrations: { - azure: [ - { host: 'dev.azure.com', token: 'tokenlols' }, - { host: 'myazurehostnotoken.com' }, - ], - }, - }), - ); - - const templaters = new Templaters(); - const cookiecutterTemplater = { run: jest.fn() }; - const mockTmpDir = os.tmpdir(); - const mockContext = { - input: { - url: 'https://google.com/cookie/cutter', - targetPath: 'something', - values: { - help: 'me', - }, - }, - baseUrl: 'somebase', - workspacePath: mockTmpDir, - logger: getVoidLogger(), - logStream: new PassThrough(), - output: jest.fn(), - createTemporaryDirectory: jest.fn().mockResolvedValue(mockTmpDir), - }; - - const mockReader: UrlReader = { - read: jest.fn(), - readTree: jest.fn(), - search: jest.fn(), - }; - - const action = createFetchCookiecutterAction({ - integrations, - templaters, - reader: mockReader, - }); - - templaters.register('cookiecutter', cookiecutterTemplater); - - beforeEach(() => { - mock({ [`${mockContext.workspacePath}/result`]: {} }); - jest.restoreAllMocks(); - }); - - afterEach(() => { - mock.restore(); - }); - - it('should call fetchContents with the correct values', async () => { - await action.handler(mockContext); - - expect(fetchContents).toHaveBeenCalledWith({ - reader: mockReader, - integrations, - baseUrl: mockContext.baseUrl, - fetchUrl: mockContext.input.url, - outputPath: resolvePath( - mockContext.workspacePath, - `template/{{cookiecutter and 'contents'}}`, - ), - }); - }); - - it('should execute the cookiecutter templater with the correct values', async () => { - await action.handler(mockContext); - - expect(cookiecutterTemplater.run).toHaveBeenCalledWith({ - workspacePath: mockTmpDir, - logStream: mockContext.logStream, - values: mockContext.input.values, - }); - }); - - it('should execute the cookiecutter templater with optional inputs if they are present and valid', async () => { - await action.handler({ - ...mockContext, - input: { - ...mockContext.input, - copyWithoutRender: ['goreleaser.yml'], - extensions: [ - 'jinja2_custom_filters_extension.string_filters_extension.StringFilterExtension', - ], - imageName: 'foo/cookiecutter-image-with-extensions', - }, - }); - - expect(cookiecutterTemplater.run).toHaveBeenCalledWith({ - workspacePath: mockTmpDir, - logStream: mockContext.logStream, - values: { - ...mockContext.input.values, - _copy_without_render: ['goreleaser.yml'], - _extensions: [ - 'jinja2_custom_filters_extension.string_filters_extension.StringFilterExtension', - ], - imageName: 'foo/cookiecutter-image-with-extensions', - }, - }); - }); - - it('should throw if copyWithoutRender is not an Array', async () => { - await expect( - action.handler({ - ...mockContext, - input: { - ...mockContext.input, - copyWithoutRender: 'xyz', - }, - }), - ).rejects.toThrow(/copyWithoutRender must be an Array/); - }); - - it('should throw if extensions is not an Array', async () => { - await expect( - action.handler({ - ...mockContext, - input: { - ...mockContext.input, - extensions: 'xyz', - }, - }), - ).rejects.toThrow(/extensions must be an Array/); - }); - - it('should throw if there is no cookiecutter templater initialized', async () => { - const templatersWithoutCookiecutter = new Templaters(); - - const newAction = createFetchCookiecutterAction({ - integrations, - templaters: templatersWithoutCookiecutter, - reader: mockReader, - }); - - await expect(newAction.handler(mockContext)).rejects.toThrow( - /No templater registered/, - ); - }); - - it('should throw if the target directory is outside of the workspace path', async () => { - await expect( - action.handler({ - ...mockContext, - input: { - ...mockContext.input, - targetPath: '/foo', - }, - }), - ).rejects.toThrow( - /Relative path is not allowed to refer to a directory outside its parent/, - ); - }); -}); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.test.ts index 1dc29ea763..30995dee38 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.test.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * 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. @@ -13,19 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -jest.mock('../../../stages/publish/helpers'); jest.mock('azure-devops-node-api', () => ({ WebApi: jest.fn(), getPersonalAccessTokenHandler: jest.fn().mockReturnValue(() => {}), })); +jest.mock('../helpers'); + import { createPublishAzureAction } from './azure'; import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { WebApi } from 'azure-devops-node-api'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../../../stages/publish/helpers'; +import { initRepoAndPush } from '../helpers'; describe('publish:azure', () => { const config = new ConfigReader({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.test.ts index 0e5f8df72b..9fe245935b 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/bitbucket.test.ts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -jest.mock('../../../stages/publish/helpers'); + +jest.mock('../helpers'); import { createPublishBitbucketAction } from './bitbucket'; import { rest } from 'msw'; @@ -23,7 +24,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../../../stages/publish/helpers'; +import { initRepoAndPush } from '../helpers'; describe('publish:bitbucket', () => { const config = new ConfigReader({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts index 0b277c4739..f0725d6e8e 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * 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. @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -jest.mock('../../../stages/publish/helpers'); + +jest.mock('../helpers'); jest.mock('@octokit/rest'); import { createPublishGithubAction } from './github'; @@ -21,7 +22,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../../../stages/publish/helpers'; +import { initRepoAndPush } from '../helpers'; import { when } from 'jest-when'; describe('publish:github', () => { diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.test.ts index 25a129d905..5150205a08 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/gitlab.test.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -jest.mock('../../../stages/publish/helpers'); +jest.mock('../helpers'); jest.mock('@gitbeaker/node'); import { createPublishGitlabAction } from './gitlab'; @@ -21,7 +21,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { ConfigReader } from '@backstage/config'; import { getVoidLogger } from '@backstage/backend-common'; import { PassThrough } from 'stream'; -import { initRepoAndPush } from '../../../stages/publish/helpers'; +import { initRepoAndPush } from '../helpers'; describe('publish:gitlab', () => { const config = new ConfigReader({ diff --git a/plugins/scaffolder-backend/src/service/router.test.ts b/plugins/scaffolder-backend/src/service/router.test.ts index b43b62a413..d91ec2b7d0 100644 --- a/plugins/scaffolder-backend/src/service/router.test.ts +++ b/plugins/scaffolder-backend/src/service/router.test.ts @@ -33,12 +33,13 @@ import { PluginDatabaseManager, DatabaseManager, UrlReaders, + DockerContainerRunner, } from '@backstage/backend-common'; import { CatalogApi } from '@backstage/catalog-client'; import { ConfigReader } from '@backstage/config'; import express from 'express'; import request from 'supertest'; -import { Preparers, Publishers, Templaters } from '../scaffolder'; +import { TemplateEntityV1beta2 } from '../../../../packages/catalog-model/src'; import { createRouter } from './router'; const createCatalogClient = (templates: any[] = []) => @@ -66,8 +67,8 @@ const mockUrlReader = UrlReaders.default({ describe('createRouter', () => { let app: express.Express; - const template = { - apiVersion: 'backstage.io/v1alpha1', + const template: TemplateEntityV1beta2 = { + apiVersion: 'backstage.io/v1beta2', kind: 'Template', metadata: { description: 'Create a new CRA website project', @@ -80,42 +81,19 @@ describe('createRouter', () => { }, spec: { owner: 'web@example.com', - path: '.', - schema: { - properties: { - component_id: { - description: 'Unique name of the component', - title: 'Name', - type: 'string', - }, - description: { - description: 'Description of the component', - title: 'Description', - type: 'string', - }, - use_typescript: { - default: true, - description: 'Include TypeScript', - title: 'Use TypeScript', - type: 'boolean', - }, - }, - required: ['component_id', 'use_typescript'], - }, - templater: 'cra', type: 'website', + steps: [], + parameters: [], }, }; beforeAll(async () => { const router = await createRouter({ logger: getVoidLogger(), - preparers: new Preparers(), - templaters: new Templaters(), - publishers: new Publishers(), config: new ConfigReader({}), database: createDatabase(), catalogClient: createCatalogClient([template]), + containerRunner: new DockerContainerRunner({} as any), reader: mockUrlReader, }); app = express().use(router); diff --git a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx index 29758f4ac3..65386b60b3 100644 --- a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx +++ b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx @@ -21,6 +21,7 @@ import { Header, ItemCardGrid, Lifecycle, + WarningPanel, Page, Progress, SupportButton, diff --git a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx index ad91fc6cfd..9d2e827be9 100644 --- a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx @@ -16,7 +16,7 @@ import { Entity, RELATION_OWNED_BY, - TemplateEntityV1alpha1, + TemplateEntityV1beta2, } from '@backstage/catalog-model'; import { ScmIntegrationIcon, @@ -93,7 +93,7 @@ const useDeprecationStyles = makeStyles(theme => ({ })); export type TemplateCardProps = { - template: TemplateEntityV1alpha1; + template: TemplateEntityV1beta2; deprecated?: boolean; }; @@ -106,7 +106,7 @@ type TemplateProps = { }; const getTemplateCardProps = ( - template: TemplateEntityV1alpha1, + template: TemplateEntityV1beta2, ): TemplateProps & { key: string } => { return { key: template.metadata.uid!,