Merge pull request #8277 from Balasundaram/scaffolder-gitlab-mr-publish-v2
Scaffolder gitlab mr publish v2
This commit is contained in:
@@ -179,6 +179,13 @@ export function createPublishGitlabAction(options: {
|
||||
config: Config;
|
||||
}): TemplateAction<any>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createPublishGitlabMergeRequestAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const createPublishGitlabMergeRequestAction: (options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
}) => TemplateAction<any>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
createPublishGithubAction,
|
||||
createPublishGithubPullRequestAction,
|
||||
createPublishGitlabAction,
|
||||
createPublishGitlabMergeRequestAction,
|
||||
} from './publish';
|
||||
import {
|
||||
createGithubActionsDispatchAction,
|
||||
@@ -72,6 +73,9 @@ export const createBuiltinActions = (options: {
|
||||
integrations,
|
||||
config,
|
||||
}),
|
||||
createPublishGitlabMergeRequestAction({
|
||||
integrations,
|
||||
}),
|
||||
createPublishBitbucketAction({
|
||||
integrations,
|
||||
config,
|
||||
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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 { createTemplateAction } from '../../createTemplateAction';
|
||||
import { readFile } from 'fs-extra';
|
||||
import { Gitlab } from '@gitbeaker/node';
|
||||
import globby from 'globby';
|
||||
import { Types } from '@gitbeaker/core';
|
||||
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { parseRepoUrl } from './util';
|
||||
import { resolveSafeChildPath } from '@backstage/backend-common';
|
||||
|
||||
export type GitlabMergeRequestActionInput = {
|
||||
projectid: string;
|
||||
repoUrl: string;
|
||||
title: string;
|
||||
description: string;
|
||||
branchName: string;
|
||||
targetPath: string;
|
||||
};
|
||||
|
||||
export const createPublishGitlabMergeRequestAction = (options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
}) => {
|
||||
const { integrations } = options;
|
||||
|
||||
return createTemplateAction<GitlabMergeRequestActionInput>({
|
||||
id: 'publish:gitlab:merge-request',
|
||||
schema: {
|
||||
input: {
|
||||
required: ['projectid', 'repoUrl', 'targetPath', 'branchName'],
|
||||
type: 'object',
|
||||
properties: {
|
||||
repoUrl: {
|
||||
type: 'string',
|
||||
title: 'Repository Location',
|
||||
description: `Accepts the format 'gitlab.com/group_name/project_name' where 'project_name' is the repository name and 'group_name' is a group or username`,
|
||||
},
|
||||
projectid: {
|
||||
type: 'string',
|
||||
title: 'projectid',
|
||||
description: 'Project ID/Name(slug) of the Gitlab Project',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
title: 'Merge Request Name',
|
||||
description: 'The name for the merge request',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
title: 'Merge Request Description',
|
||||
description: 'The description of the merge request',
|
||||
},
|
||||
branchName: {
|
||||
type: 'string',
|
||||
title: 'Destination Branch name',
|
||||
description: 'The description of the merge request',
|
||||
},
|
||||
targetPath: {
|
||||
type: 'string',
|
||||
title: 'Repository Subdirectory',
|
||||
description: 'Subdirectory of repository to apply changes to',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
projectid: {
|
||||
title: 'Gitlab Project id/Name(slug)',
|
||||
type: 'string',
|
||||
},
|
||||
mergeRequestURL: {
|
||||
title: 'MergeRequest(MR) URL',
|
||||
type: 'string',
|
||||
description: 'Link to the merge request in GitLab',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
async handler(ctx) {
|
||||
const repoUrl = ctx.input.repoUrl;
|
||||
const { host } = parseRepoUrl(repoUrl, integrations);
|
||||
const integrationConfig = integrations.gitlab.byHost(host);
|
||||
|
||||
const actions: Types.CommitAction[] = [];
|
||||
|
||||
const destinationBranch = ctx.input.branchName;
|
||||
|
||||
if (!integrationConfig) {
|
||||
throw new InputError(
|
||||
`No matching integration configuration for host ${host}, please check your integrations config`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!integrationConfig.config.token) {
|
||||
throw new InputError(`No token available for host ${host}`);
|
||||
}
|
||||
|
||||
const api = new Gitlab({
|
||||
host: integrationConfig.config.baseUrl,
|
||||
token: integrationConfig.config.token,
|
||||
});
|
||||
|
||||
const fileRoot = ctx.workspacePath;
|
||||
const localFilePaths = await globby([`${ctx.input.targetPath}/**`], {
|
||||
cwd: fileRoot,
|
||||
gitignore: true,
|
||||
dot: true,
|
||||
});
|
||||
|
||||
const fileContents = await Promise.all(
|
||||
localFilePaths.map(p => readFile(resolveSafeChildPath(fileRoot, p))),
|
||||
);
|
||||
|
||||
const repoFilePaths = localFilePaths.map(repoFilePath => {
|
||||
return repoFilePath;
|
||||
});
|
||||
|
||||
for (let i = 0; i < repoFilePaths.length; i++) {
|
||||
actions.push({
|
||||
action: 'create',
|
||||
filePath: repoFilePaths[i],
|
||||
content: fileContents[i].toString(),
|
||||
});
|
||||
}
|
||||
|
||||
const projects = await api.Projects.show(ctx.input.projectid);
|
||||
|
||||
const { default_branch: defaultBranch } = projects;
|
||||
|
||||
try {
|
||||
await api.Branches.create(
|
||||
ctx.input.projectid,
|
||||
destinationBranch,
|
||||
String(defaultBranch),
|
||||
);
|
||||
} catch (e) {
|
||||
throw new InputError(`The branch creation failed ${e}`);
|
||||
}
|
||||
|
||||
try {
|
||||
await api.Commits.create(
|
||||
ctx.input.projectid,
|
||||
destinationBranch,
|
||||
ctx.input.title,
|
||||
actions,
|
||||
);
|
||||
} catch (e) {
|
||||
throw new InputError(
|
||||
`Committing the changes to ${destinationBranch} failed ${e}`,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const mergeRequestUrl = await api.MergeRequests.create(
|
||||
ctx.input.projectid,
|
||||
destinationBranch,
|
||||
String(defaultBranch),
|
||||
ctx.input.title,
|
||||
{ description: ctx.input.description },
|
||||
).then((mergeRequest: { web_url: string }) => {
|
||||
return mergeRequest.web_url;
|
||||
});
|
||||
ctx.output('projectid', ctx.input.projectid);
|
||||
ctx.output('mergeRequestUrl', mergeRequestUrl);
|
||||
} catch (e) {
|
||||
throw new InputError(`Merge request creation failed${e}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -20,3 +20,4 @@ export { createPublishFileAction } from './file';
|
||||
export { createPublishGithubAction } from './github';
|
||||
export { createPublishGithubPullRequestAction } from './githubPullRequest';
|
||||
export { createPublishGitlabAction } from './gitlab';
|
||||
export { createPublishGitlabMergeRequestAction } from './gitlabMergeRequest';
|
||||
|
||||
Reference in New Issue
Block a user