Merge branch 'backstage:master' into master
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-gitlab': patch
|
||||
---
|
||||
|
||||
Add examples for `publish:gitlab:merge-request` scaffolder action & improve related tests
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-gitlab': patch
|
||||
---
|
||||
|
||||
Add examples for `gitlab:group:ensureExists` scaffolder action & improve related tests
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-badges': patch
|
||||
---
|
||||
|
||||
Update README to fix invalid import command
|
||||
@@ -88,8 +88,7 @@ yarn --cwd packages/app add @backstage/plugin-badges
|
||||
This plugin requires explicit registration, so you will need to add it to your App's `plugins.ts` file:
|
||||
|
||||
```ts
|
||||
// ...
|
||||
export { badgesPlugin } from '@backstage/plugin-badges';
|
||||
import { badgesPlugin } from '@backstage/plugin-badges';
|
||||
```
|
||||
|
||||
If you don't have a `plugins.ts` file see: [troubleshooting](#troubleshooting)
|
||||
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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 { createGitlabGroupEnsureExistsAction } from './createGitlabGroupEnsureExistsAction';
|
||||
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
|
||||
import { ConfigReader } from '@backstage/core-app-api';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import yaml from 'yaml';
|
||||
import { examples } from './createGitlabGroupEnsureExistsAction.examples';
|
||||
|
||||
const mockGitlabClient = {
|
||||
Groups: {
|
||||
search: jest.fn(),
|
||||
create: jest.fn(),
|
||||
},
|
||||
};
|
||||
jest.mock('@gitbeaker/node', () => ({
|
||||
Gitlab: class {
|
||||
constructor() {
|
||||
return mockGitlabClient;
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
describe('gitlab:group:ensureExists', () => {
|
||||
const mockContext = createMockActionContext();
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it(`Should ${examples[0].description}`, async () => {
|
||||
mockGitlabClient.Groups.search.mockResolvedValue([]);
|
||||
mockGitlabClient.Groups.create.mockResolvedValue({
|
||||
id: 3,
|
||||
full_path: 'group1',
|
||||
});
|
||||
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
gitlab: [
|
||||
{
|
||||
host: 'gitlab.com',
|
||||
token: 'tokenlols',
|
||||
apiBaseUrl: 'https://api.gitlab.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
|
||||
const action = createGitlabGroupEnsureExistsAction({ integrations });
|
||||
|
||||
await action.handler({
|
||||
...mockContext,
|
||||
input: yaml.parse(examples[0].example).steps[0].input,
|
||||
});
|
||||
|
||||
expect(mockGitlabClient.Groups.create).toHaveBeenCalledWith(
|
||||
'group1',
|
||||
'group1',
|
||||
{},
|
||||
);
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith('groupId', 3);
|
||||
});
|
||||
|
||||
it(`Should ${examples[1].description}`, async () => {
|
||||
mockGitlabClient.Groups.search.mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
full_path: 'group1',
|
||||
},
|
||||
]);
|
||||
mockGitlabClient.Groups.create.mockResolvedValue({
|
||||
id: 3,
|
||||
full_path: 'group1/group2',
|
||||
});
|
||||
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
gitlab: [
|
||||
{
|
||||
host: 'gitlab.com',
|
||||
token: 'tokenlols',
|
||||
apiBaseUrl: 'https://api.gitlab.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
|
||||
const action = createGitlabGroupEnsureExistsAction({ integrations });
|
||||
|
||||
await action.handler({
|
||||
...mockContext,
|
||||
input: yaml.parse(examples[1].example).steps[0].input,
|
||||
});
|
||||
|
||||
expect(mockGitlabClient.Groups.create).toHaveBeenCalledWith(
|
||||
'group2',
|
||||
'group2',
|
||||
{
|
||||
parent_id: 1,
|
||||
},
|
||||
);
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith('groupId', 3);
|
||||
});
|
||||
|
||||
it(`Should ${examples[2].description}`, async () => {
|
||||
mockGitlabClient.Groups.search.mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
full_path: 'group1',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
full_path: 'group1/group2',
|
||||
},
|
||||
]);
|
||||
mockGitlabClient.Groups.create.mockResolvedValue({
|
||||
id: 3,
|
||||
full_path: 'group1/group2/group3',
|
||||
});
|
||||
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
gitlab: [
|
||||
{
|
||||
host: 'gitlab.com',
|
||||
token: 'tokenlols',
|
||||
apiBaseUrl: 'https://api.gitlab.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
|
||||
const action = createGitlabGroupEnsureExistsAction({ integrations });
|
||||
|
||||
await action.handler({
|
||||
...mockContext,
|
||||
input: yaml.parse(examples[2].example).steps[0].input,
|
||||
});
|
||||
|
||||
expect(mockGitlabClient.Groups.create).toHaveBeenCalledWith(
|
||||
'group3',
|
||||
'group3',
|
||||
{
|
||||
parent_id: 2,
|
||||
},
|
||||
);
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith('groupId', 3);
|
||||
});
|
||||
|
||||
it(`Should ${examples[3].description}`, async () => {
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
gitlab: [
|
||||
{
|
||||
host: 'gitlab.com',
|
||||
token: 'tokenlols',
|
||||
apiBaseUrl: 'https://api.gitlab.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
|
||||
const action = createGitlabGroupEnsureExistsAction({ integrations });
|
||||
|
||||
await action.handler({
|
||||
...mockContext,
|
||||
isDryRun: yaml.parse(examples[3].example).steps[0].isDryRun,
|
||||
input: yaml.parse(examples[3].example).steps[0].input,
|
||||
});
|
||||
|
||||
expect(mockGitlabClient.Groups.search).not.toHaveBeenCalled();
|
||||
expect(mockGitlabClient.Groups.create).not.toHaveBeenCalled();
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith('groupId', 42);
|
||||
});
|
||||
});
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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: 'Creating a group at the top level',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
id: 'gitlabGroup',
|
||||
name: 'Group',
|
||||
action: 'gitlab:group:ensureExists',
|
||||
input: {
|
||||
repoUrl: 'gitlab.com',
|
||||
path: ['group1'],
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: 'Create a group nested within another group',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
id: 'gitlabGroup',
|
||||
name: 'Group',
|
||||
action: 'gitlab:group:ensureExists',
|
||||
input: {
|
||||
repoUrl: 'gitlab.com',
|
||||
path: ['group1', 'group2'],
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: 'Create a group nested within multiple other groups',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
id: 'gitlabGroup',
|
||||
name: 'Group',
|
||||
action: 'gitlab:group:ensureExists',
|
||||
input: {
|
||||
repoUrl: 'gitlab.com',
|
||||
path: ['group1', 'group2', 'group3'],
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: 'Create a group in dry run mode',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
id: 'gitlabGroup',
|
||||
name: 'Group',
|
||||
action: 'gitlab:group:ensureExists',
|
||||
isDryRun: true,
|
||||
input: {
|
||||
repoUrl: 'https://gitlab.com/my-repo',
|
||||
path: ['group1', 'group2', 'group3'],
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
];
|
||||
+2
@@ -21,6 +21,7 @@ import { GroupSchema } from '@gitbeaker/core/dist/types/resources/Groups';
|
||||
import commonGitlabConfig from '../commonGitlabConfig';
|
||||
import { getToken } from '../util';
|
||||
import { z } from 'zod';
|
||||
import { examples } from './createGitlabGroupEnsureExistsAction.examples';
|
||||
|
||||
/**
|
||||
* Creates an `gitlab:group:ensureExists` Scaffolder action.
|
||||
@@ -36,6 +37,7 @@ export const createGitlabGroupEnsureExistsAction = (options: {
|
||||
id: 'gitlab:group:ensureExists',
|
||||
description: 'Ensures a Gitlab group exists',
|
||||
supportsDryRun: true,
|
||||
examples,
|
||||
schema: {
|
||||
input: commonGitlabConfig.merge(
|
||||
z.object({
|
||||
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright 2022 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 { createRootLogger } from '@backstage/backend-common';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
import { createPublishGitlabMergeRequestAction } from './gitlabMergeRequest';
|
||||
import { createMockDirectory } from '@backstage/backend-test-utils';
|
||||
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
|
||||
import { examples } from './gitlabMergeRequest.examples';
|
||||
import yaml from 'yaml';
|
||||
|
||||
// Make sure root logger is initialized ahead of FS mock
|
||||
createRootLogger();
|
||||
|
||||
const mockGitlabClient = {
|
||||
Namespaces: {
|
||||
show: jest.fn(),
|
||||
},
|
||||
Branches: {
|
||||
create: jest.fn(),
|
||||
},
|
||||
Commits: {
|
||||
create: jest.fn(),
|
||||
},
|
||||
MergeRequests: {
|
||||
create: jest.fn(async (_: any) => {
|
||||
return {
|
||||
default_branch: 'main',
|
||||
};
|
||||
}),
|
||||
},
|
||||
Projects: {
|
||||
create: jest.fn(),
|
||||
show: jest.fn(async (_: any) => {
|
||||
return {
|
||||
default_branch: 'main',
|
||||
};
|
||||
}),
|
||||
},
|
||||
Users: {
|
||||
current: jest.fn(),
|
||||
username: jest.fn(async (user: string) => {
|
||||
const users: string[] = ['John Smith', 'my-assignee'];
|
||||
if (!users.includes(user)) throw new Error('user does not exist');
|
||||
else
|
||||
return [
|
||||
{
|
||||
id: 123,
|
||||
},
|
||||
];
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
jest.mock('@gitbeaker/node', () => ({
|
||||
Gitlab: class {
|
||||
constructor() {
|
||||
return mockGitlabClient;
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
describe('createGitLabMergeRequest', () => {
|
||||
let instance: TemplateAction<any>;
|
||||
|
||||
const mockDir = createMockDirectory();
|
||||
const workspacePath = mockDir.resolve('workspace');
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
mockDir.clear();
|
||||
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
gitlab: [
|
||||
{
|
||||
host: 'gitlab.com',
|
||||
token: 'token',
|
||||
apiBaseUrl: 'https://api.gitlab.com',
|
||||
},
|
||||
{
|
||||
host: 'hosted.gitlab.com',
|
||||
apiBaseUrl: 'https://api.hosted.gitlab.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
instance = createPublishGitlabMergeRequestAction({ integrations });
|
||||
});
|
||||
|
||||
describe('createGitLabMergeRequestWithAssignee', () => {
|
||||
it(`Should ${examples[0].description}`, async () => {
|
||||
mockDir.setContent({
|
||||
[workspacePath]: {
|
||||
source: { 'foo.txt': 'Hello there!' },
|
||||
irrelevant: { 'bar.txt': 'Nothing to see here' },
|
||||
},
|
||||
});
|
||||
|
||||
const input = yaml.parse(examples[0].example).steps[0].input;
|
||||
const ctx = createMockActionContext({ input, workspacePath });
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith(
|
||||
'owner/repo',
|
||||
'new-mr',
|
||||
'main',
|
||||
'Create my new MR',
|
||||
{
|
||||
description: 'This MR is really good',
|
||||
removeSourceBranch: false,
|
||||
assigneeId: 123,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('assignee is not set when a valid assignee username is not passed in options', async () => {
|
||||
const input = {
|
||||
repoUrl: 'gitlab.com?repo=repo&owner=owner',
|
||||
title: 'Create my new MR',
|
||||
branchName: 'new-mr',
|
||||
description: 'This is an important change',
|
||||
removeSourceBranch: false,
|
||||
targetPath: 'Subdirectory',
|
||||
assingnee: 'John Doe',
|
||||
};
|
||||
mockDir.setContent({
|
||||
[workspacePath]: {
|
||||
source: { 'foo.txt': 'Hello there!' },
|
||||
irrelevant: { 'bar.txt': 'Nothing to see here' },
|
||||
},
|
||||
});
|
||||
|
||||
const ctx = createMockActionContext({ input, workspacePath });
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith(
|
||||
'owner/repo',
|
||||
'new-mr',
|
||||
'main',
|
||||
'Create my new MR',
|
||||
{
|
||||
description: 'This is an important change',
|
||||
removeSourceBranch: false,
|
||||
assigneeId: undefined,
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createGitLabMergeRequestWithRemoveBranch', () => {
|
||||
it(`Should ${examples[1].description}`, async () => {
|
||||
const input = yaml.parse(examples[1].example).steps[0].input;
|
||||
mockDir.setContent({
|
||||
[workspacePath]: {
|
||||
source: { 'foo.txt': 'Hello there!' },
|
||||
irrelevant: { 'bar.txt': 'Nothing to see here' },
|
||||
},
|
||||
});
|
||||
|
||||
const ctx = createMockActionContext({ input, workspacePath });
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith(
|
||||
'owner/repo',
|
||||
'new-mr',
|
||||
'main',
|
||||
'Create my new MR',
|
||||
{ description: 'This MR is really good', removeSourceBranch: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createGitLabMergeRequestWithSpecifiedTargetBranch', () => {
|
||||
it(`Should ${examples[2].description}`, async () => {
|
||||
const input = yaml.parse(examples[2].example).steps[0].input;
|
||||
mockDir.setContent({
|
||||
[workspacePath]: {
|
||||
source: { 'foo.txt': 'Hello there!' },
|
||||
irrelevant: { 'bar.txt': 'Nothing to see here' },
|
||||
},
|
||||
});
|
||||
const ctx = createMockActionContext({ input, workspacePath });
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(mockGitlabClient.Projects.show).not.toHaveBeenCalled();
|
||||
expect(mockGitlabClient.Branches.create).toHaveBeenCalledWith(
|
||||
'owner/repo',
|
||||
'new-mr',
|
||||
'test',
|
||||
);
|
||||
expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith(
|
||||
'owner/repo',
|
||||
'new-mr',
|
||||
'test',
|
||||
'Create my new MR',
|
||||
{ description: 'This MR is really good', removeSourceBranch: false },
|
||||
);
|
||||
expect(ctx.output).toHaveBeenCalledWith('targetBranchName', 'test');
|
||||
});
|
||||
});
|
||||
|
||||
describe('createGitLabMergeRequestWithCommitAction', () => {
|
||||
it(`Should ${examples[3].description}`, async () => {
|
||||
const input = yaml.parse(examples[3].example).steps[0].input;
|
||||
mockDir.setContent({
|
||||
[workspacePath]: {
|
||||
source: { 'foo.txt': 'Hello there!' },
|
||||
irrelevant: { 'bar.txt': 'Nothing to see here' },
|
||||
},
|
||||
});
|
||||
|
||||
const ctx = createMockActionContext({ input, workspacePath });
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith(
|
||||
'owner/repo',
|
||||
'new-mr',
|
||||
'Create my new MR',
|
||||
[
|
||||
{
|
||||
action: 'create',
|
||||
filePath: 'source/foo.txt',
|
||||
content: 'SGVsbG8gdGhlcmUh',
|
||||
encoding: 'base64',
|
||||
execute_filemode: false,
|
||||
},
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
it(`Should ${examples[4].description}`, async () => {
|
||||
const input = yaml.parse(examples[4].example).steps[0].input;
|
||||
mockDir.setContent({
|
||||
[workspacePath]: {
|
||||
source: { 'foo.txt': 'Hello there!' },
|
||||
irrelevant: { 'bar.txt': 'Nothing to see here' },
|
||||
},
|
||||
});
|
||||
|
||||
const ctx = createMockActionContext({ input, workspacePath });
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith(
|
||||
'owner/repo',
|
||||
'new-mr',
|
||||
'Create my new MR',
|
||||
[
|
||||
{
|
||||
action: 'delete',
|
||||
filePath: 'source/foo.txt',
|
||||
content: 'SGVsbG8gdGhlcmUh',
|
||||
encoding: 'base64',
|
||||
execute_filemode: false,
|
||||
},
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
it(`Should ${examples[5].description}`, async () => {
|
||||
const input = yaml.parse(examples[5].example).steps[0].input;
|
||||
mockDir.setContent({
|
||||
[workspacePath]: {
|
||||
source: { 'foo.txt': 'Hello there!' },
|
||||
irrelevant: { 'bar.txt': 'Nothing to see here' },
|
||||
},
|
||||
});
|
||||
|
||||
const ctx = createMockActionContext({ input, workspacePath });
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith(
|
||||
'owner/repo',
|
||||
'new-mr',
|
||||
'Create my new MR',
|
||||
[
|
||||
{
|
||||
action: 'update',
|
||||
filePath: 'source/foo.txt',
|
||||
content: 'SGVsbG8gdGhlcmUh',
|
||||
encoding: 'base64',
|
||||
execute_filemode: false,
|
||||
},
|
||||
],
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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: 'Create a merge request with a specific assignee',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
id: 'createMergeRequest',
|
||||
action: 'publish:gitlab:merge-request',
|
||||
name: 'Create a Merge Request',
|
||||
input: {
|
||||
repoUrl: 'gitlab.com?repo=repo&owner=owner',
|
||||
title: 'Create my new MR',
|
||||
description: 'This MR is really good',
|
||||
sourcePath: './path/to/my/changes',
|
||||
branchName: 'new-mr',
|
||||
assignee: 'my-assignee',
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description:
|
||||
'Create a merge request with removal of source branch after merge',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
id: 'createMergeRequest',
|
||||
action: 'publish:gitlab:merge-request',
|
||||
name: 'Create a Merge Request',
|
||||
input: {
|
||||
repoUrl: 'gitlab.com?repo=repo&owner=owner',
|
||||
title: 'Create my new MR',
|
||||
description: 'This MR is really good',
|
||||
sourcePath: './path/to/my/changes',
|
||||
branchName: 'new-mr',
|
||||
removeSourceBranch: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: 'Create a merge request with a target branch',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
id: 'createMergeRequest',
|
||||
action: 'publish:gitlab:merge-request',
|
||||
name: 'Create a Merge Request',
|
||||
input: {
|
||||
repoUrl: 'gitlab.com?repo=repo&owner=owner',
|
||||
title: 'Create my new MR',
|
||||
description: 'This MR is really good',
|
||||
sourcePath: './path/to/my/changes',
|
||||
branchName: 'new-mr',
|
||||
targetBranchName: 'test',
|
||||
targetPath: 'Subdirectory',
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: 'Create a merge request with a commit action as create',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
id: 'createMergeRequest',
|
||||
action: 'publish:gitlab:merge-request',
|
||||
name: 'Create a Merge Request',
|
||||
input: {
|
||||
repoUrl: 'gitlab.com?repo=repo&owner=owner',
|
||||
title: 'Create my new MR',
|
||||
branchName: 'new-mr',
|
||||
description: 'MR description',
|
||||
commitAction: 'create',
|
||||
targetPath: 'source',
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: 'Create a merge request with a commit action as delete',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
id: 'createMergeRequest',
|
||||
action: 'publish:gitlab:merge-request',
|
||||
name: 'Create a Merge Request',
|
||||
input: {
|
||||
repoUrl: 'gitlab.com?repo=repo&owner=owner',
|
||||
title: 'Create my new MR',
|
||||
branchName: 'new-mr',
|
||||
description: 'MR description',
|
||||
commitAction: 'delete',
|
||||
targetPath: 'source',
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: 'Create a merge request with a commit action as update',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
id: 'createMergeRequest',
|
||||
action: 'publish:gitlab:merge-request',
|
||||
name: 'Create a Merge Request',
|
||||
input: {
|
||||
repoUrl: 'gitlab.com?repo=repo&owner=owner',
|
||||
title: 'Create my new MR',
|
||||
branchName: 'new-mr',
|
||||
description: 'MR description',
|
||||
commitAction: 'update',
|
||||
targetPath: 'source',
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
];
|
||||
@@ -25,6 +25,7 @@ import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { resolveSafeChildPath } from '@backstage/backend-common';
|
||||
import { createGitlabApi } from './helpers';
|
||||
import { examples } from './gitlabMergeRequest.examples';
|
||||
|
||||
/**
|
||||
* Create a new action that creates a gitlab merge request.
|
||||
@@ -52,6 +53,7 @@ export const createPublishGitlabMergeRequestAction = (options: {
|
||||
assignee?: string;
|
||||
}>({
|
||||
id: 'publish:gitlab:merge-request',
|
||||
examples,
|
||||
schema: {
|
||||
input: {
|
||||
required: ['repoUrl', 'branchName'],
|
||||
|
||||
@@ -43644,8 +43644,8 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"testcontainers@npm:^10.0.0":
|
||||
version: 10.7.2
|
||||
resolution: "testcontainers@npm:10.7.2"
|
||||
version: 10.8.2
|
||||
resolution: "testcontainers@npm:10.8.2"
|
||||
dependencies:
|
||||
"@balena/dockerignore": ^1.0.2
|
||||
"@types/dockerode": ^3.3.24
|
||||
@@ -43662,7 +43662,7 @@ __metadata:
|
||||
ssh-remote-port-forward: ^1.0.4
|
||||
tar-fs: ^3.0.5
|
||||
tmp: ^0.2.1
|
||||
checksum: b4650509e3e072b96cd8ed75fdeeaa8a51a81cc9d45aabec26d4915cf9942e051f14fce4d23a29e70a007c2e8b3ce46f72dac602962f21c5a8d27976c846ef24
|
||||
checksum: 3a97ad705c98abc5066577699be5e791090ef2a5c45fee3a203196fa09d0cb66c7709f6ae8168c025ed97a07f1f5f0676a34e748680514e732e90671720d34c6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user