diff --git a/.changeset/mighty-humans-tan.md b/.changeset/mighty-humans-tan.md new file mode 100644 index 0000000000..24e209a701 --- /dev/null +++ b/.changeset/mighty-humans-tan.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gerrit': minor +--- + +Add examples for publish:gerrit:review scaffolder action & improve related tests diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.test.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.test.ts new file mode 100644 index 0000000000..d1bc594d54 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.test.ts @@ -0,0 +1,245 @@ +/* + * 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. + */ + +jest.mock('@backstage/plugin-scaffolder-node', () => { + return { + ...jest.requireActual('@backstage/plugin-scaffolder-node'), + commitAndPushRepo: jest.fn(), + }; +}); + +import { createPublishGerritReviewAction } from './gerritReview'; +import { ScmIntegrations } from '@backstage/integration'; +import { ConfigReader } from '@backstage/config'; +import { commitAndPushRepo } from '@backstage/plugin-scaffolder-node'; +import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils'; +import yaml from 'yaml'; +import { examples } from './gerritReview.examples'; + +describe('publish:gerrit:review', () => { + const config = new ConfigReader({ + integrations: { + gerrit: [ + { + host: 'gerrithost.org', + username: 'gerrituser', + password: 'usertoken', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const action = createPublishGerritReviewAction({ integrations, config }); + const mockContext = createMockActionContext({ + input: { + repoUrl: + 'gerrithost.org?owner=owner&workspace=parent&project=project&repo=repo', + gitCommitMessage: 'Review from backstage', + }, + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it(`Should ${examples[0].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[0].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: {}, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[1].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[1].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: { + email: undefined, + name: 'Test User', + }, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[2].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[2].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: { + email: 'test.user@example.com', + name: 'Test User', + }, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[3].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[3].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: mockContext.workspacePath, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: {}, + branch: 'develop', + remoteRef: 'refs/for/develop', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/develop', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[4].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[4].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}/src`, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: {}, + branch: 'master', + remoteRef: 'refs/for/master', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/master', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + it(`Should ${examples[5].description}`, async () => { + expect.assertions(3); + + const input = yaml.parse(examples[5].example).steps[0].input; + await action.handler({ + ...mockContext, + input, + }); + + expect(commitAndPushRepo).toHaveBeenCalledWith({ + dir: `${mockContext.workspacePath}/src`, + auth: { username: 'gerrituser', password: 'usertoken' }, + logger: mockContext.logger, + commitMessage: expect.stringContaining('Initial Commit Message'), + gitAuthorInfo: { + email: 'test.user@example.com', + name: 'Test User', + }, + branch: 'develop', + remoteRef: 'refs/for/develop', + }); + + expect(mockContext.output).toHaveBeenCalledWith( + 'repoContentsUrl', + 'https://gerrithost.org/repo/+/refs/heads/develop', + ); + expect(mockContext.output).toHaveBeenCalledWith( + 'reviewUrl', + expect.stringMatching(new RegExp('^https://gerrithost.org/#/q/I')), + ); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); +}); diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.ts new file mode 100644 index 0000000000..fc01fd1ce3 --- /dev/null +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.examples.ts @@ -0,0 +1,126 @@ +/* + * 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: 'Creates a new Gerrit review with minimal options', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with gitAuthorName', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'Test User', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with gitAuthorEmail', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with custom branch', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + branch: 'develop', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with custom sourcePath', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + sourcePath: './src', + }, + }, + ], + }), + }, + { + description: 'Creates a new Gerrit review with all properties', + example: yaml.stringify({ + steps: [ + { + id: 'publish', + action: 'publish:gerrit:review', + name: 'Publish new gerrit review', + input: { + repoUrl: 'gerrithost.org?repo=repo&owner=owner', + gitCommitMessage: 'Initial Commit Message', + gitAuthorName: 'Test User', + gitAuthorEmail: 'test.user@example.com', + branch: 'develop', + sourcePath: './src', + }, + }, + ], + }), + }, +]; diff --git a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts index bd8d0321ab..b4f844b08f 100644 --- a/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts +++ b/plugins/scaffolder-backend-module-gerrit/src/actions/gerritReview.ts @@ -24,6 +24,7 @@ import { getRepoSourceDirectory, parseRepoUrl, } from '@backstage/plugin-scaffolder-node'; +import { examples } from './gerritReview.examples'; const generateGerritChangeId = (): string => { const changeId = crypto.randomBytes(20).toString('hex'); @@ -50,6 +51,7 @@ export function createPublishGerritReviewAction(options: { }>({ id: 'publish:gerrit:review', description: 'Creates a new Gerrit review.', + examples, schema: { input: { type: 'object',