From 7c5d90e48dbb7c9cf881ae9d7b1f79756a153897 Mon Sep 17 00:00:00 2001 From: Marc Buchardt Date: Fri, 6 Oct 2023 13:51:02 +0200 Subject: [PATCH 1/3] add examples for publish:azure scaffolder action Signed-off-by: Marc Buchardt --- .../actions/builtin/publish/azure.examples.ts | 70 +++++++++++++++++++ .../actions/builtin/publish/azure.ts | 2 + 2 files changed, 72 insertions(+) create mode 100644 plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.ts new file mode 100644 index 0000000000..165275878c --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.ts @@ -0,0 +1,70 @@ +/* + * Copyright 2023 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 { TemplateExample } from '@backstage/plugin-scaffolder-node'; +import yaml from 'yaml'; + +export const examples: TemplateExample[] = [ + { + description: + 'Initializes a git repository of the content in the workspace, and publishes it to Azure.', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:azure', + name: 'Publish to Azure', + input: { + repoUrl: 'dev.azure.com/organisation/project/_git/repo', + }, + }, + ], + }), + }, + { + description: 'Add a description.', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:azure', + name: 'Publish to Azure', + input: { + repoUrl: 'dev.azure.com/organisation/project/_git/repo', + description: 'Initialize a git repository', + }, + }, + ], + }), + }, + { + description: 'Change the default branch.', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:azure', + name: 'Publish to Azure', + input: { + repoUrl: 'dev.azure.com/organisation/project/_git/repo', + description: 'Initialize a git repository', + defaultBranch: 'main', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts index b6c0226163..a7df154687 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.ts @@ -29,6 +29,7 @@ import { import { getRepoSourceDirectory, parseRepoUrl } from './util'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { Config } from '@backstage/config'; +import { examples } from './azure.examples'; /** * Creates a new action that initializes a git repository of the content in the workspace @@ -52,6 +53,7 @@ export function createPublishAzureAction(options: { gitAuthorEmail?: string; }>({ id: 'publish:azure', + examples, description: 'Initializes a git repository of the content in the workspace, and publishes it to Azure.', schema: { From 733ddf7130a06e13666870f8f23b4cd5b5125137 Mon Sep 17 00:00:00 2001 From: Marc Buchardt Date: Fri, 6 Oct 2023 14:09:21 +0200 Subject: [PATCH 2/3] Add changeset Signed-off-by: Marc Buchardt --- .changeset/twenty-carrots-smile.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/twenty-carrots-smile.md diff --git a/.changeset/twenty-carrots-smile.md b/.changeset/twenty-carrots-smile.md new file mode 100644 index 0000000000..873af7dcd3 --- /dev/null +++ b/.changeset/twenty-carrots-smile.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Add examples for `publish:Azure` scaffolder action. From fe5434912213e02d58b2aaaf12756b5a9c431b68 Mon Sep 17 00:00:00 2001 From: Marc Buchardt Date: Mon, 9 Oct 2023 13:22:56 +0200 Subject: [PATCH 3/3] Add unit tests Signed-off-by: Marc Buchardt --- .../builtin/publish/azure.examples.test.ts | 121 ++++++++++++++++++ .../actions/builtin/publish/azure.examples.ts | 9 +- 2 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.test.ts diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.test.ts new file mode 100644 index 0000000000..e4fd18ef59 --- /dev/null +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.test.ts @@ -0,0 +1,121 @@ +/* + * 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. + */ + +import yaml from 'yaml'; +import { ConfigReader } from '@backstage/config'; +import { createPublishAzureAction } from './azure'; +import { ScmIntegrations } from '@backstage/integration'; +import { getVoidLogger } from '@backstage/backend-common'; +import { WebApi } from 'azure-devops-node-api'; +import { PassThrough } from 'stream'; +import { initRepoAndPush } from '../helpers'; +import { examples } from './azure.examples'; + +jest.mock('azure-devops-node-api', () => ({ + WebApi: jest.fn(), + getPersonalAccessTokenHandler: jest.fn().mockReturnValue(() => {}), +})); + +jest.mock('../helpers', () => { + return { + initRepoAndPush: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + commitAndPushRepo: jest.fn().mockResolvedValue({ + commitHash: '220f19cc36b551763d157f1b5e4a4b446165dbd6', + }), + }; +}); + +describe('publish:azure examples', () => { + const config = new ConfigReader({ + integrations: { + azure: [ + { + host: 'dev.azure.com', + credentials: [{ personalAccessToken: 'tokenlols' }], + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const action = createPublishAzureAction({ integrations, config }); + const mockContext = { + workspacePath: 'lol', + logger: getVoidLogger(), + logStream: new PassThrough(), + output: jest.fn(), + createTemporaryDirectory: jest.fn(), + }; + + const mockGitClient = { + createRepository: jest.fn(), + }; + const mockGitApi = { + getGitApi: jest.fn().mockReturnValue(mockGitClient), + }; + + (WebApi as unknown as jest.Mock).mockImplementation(() => mockGitApi); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should call initRepoAndPush with the correct values', async () => { + mockGitClient.createRepository.mockResolvedValue({ + remoteUrl: 'https://dev.azure.com/organization/project/_git/repo', + id: '709e891c-dee7-4f91-b963-534713c0737f', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[0].example).steps[0].input, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://dev.azure.com/organization/project/_git/repo', + defaultBranch: 'master', + auth: { username: 'notempty', password: 'tokenlols' }, + logger: mockContext.logger, + commitMessage: 'initial commit', + gitAuthorInfo: {}, + }); + }); + + it('should call initRepoAndPush with a changed default branch', async () => { + mockGitClient.createRepository.mockResolvedValue({ + remoteUrl: 'https://dev.azure.com/organization/project/_git/repo', + id: '709e891c-dee7-4f91-b963-534713c0737f', + }); + + await action.handler({ + ...mockContext, + input: yaml.parse(examples[2].example).steps[0].input, + }); + + expect(initRepoAndPush).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + remoteUrl: 'https://dev.azure.com/organization/project/_git/repo', + defaultBranch: 'main', + auth: { username: 'notempty', password: 'tokenlols' }, + logger: mockContext.logger, + commitMessage: 'initial commit', + gitAuthorInfo: {}, + }); + }); +}); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.ts index 165275878c..48b57c410d 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/azure.examples.ts @@ -28,7 +28,8 @@ export const examples: TemplateExample[] = [ action: 'publish:azure', name: 'Publish to Azure', input: { - repoUrl: 'dev.azure.com/organisation/project/_git/repo', + repoUrl: + 'dev.azure.com?organization=organization&owner=project&repo=repo', }, }, ], @@ -43,7 +44,8 @@ export const examples: TemplateExample[] = [ action: 'publish:azure', name: 'Publish to Azure', input: { - repoUrl: 'dev.azure.com/organisation/project/_git/repo', + repoUrl: + 'dev.azure.com?organization=organization&owner=project&repo=repo', description: 'Initialize a git repository', }, }, @@ -59,7 +61,8 @@ export const examples: TemplateExample[] = [ action: 'publish:azure', name: 'Publish to Azure', input: { - repoUrl: 'dev.azure.com/organisation/project/_git/repo', + repoUrl: + 'dev.azure.com?organization=organization&owner=project&repo=repo', description: 'Initialize a git repository', defaultBranch: 'main', },