@backstage/plugin-scaffolder-backend-module-gitlab 0.11.10 → 0.11.11-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -3
- package/dist/actions/gitlabMergeRequest.cjs.js +28 -3
- package/dist/actions/gitlabMergeRequest.cjs.js.map +1 -1
- package/dist/actions/gitlabMergeRequest.examples.cjs.js +19 -0
- package/dist/actions/gitlabMergeRequest.examples.cjs.js.map +1 -1
- package/dist/actions/gitlabPipelineTrigger.cjs.js +30 -67
- package/dist/actions/gitlabPipelineTrigger.cjs.js.map +1 -1
- package/dist/actions/gitlabProjectVariableCreate.cjs.js +1 -1
- package/dist/actions/gitlabProjectVariableCreate.cjs.js.map +1 -1
- package/dist/actions/gitlabRepoPush.cjs.js +13 -3
- package/dist/actions/gitlabRepoPush.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/util.cjs.js +18 -1
- package/dist/util.cjs.js.map +1 -1
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,48 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-backend-module-gitlab
|
|
2
2
|
|
|
3
|
-
## 0.11.
|
|
3
|
+
## 0.11.11-next.2
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- 20595f0: The `gitlab:projectVariable:create` action no longer includes the variable value in its checkpoint key, preventing secret values from being persisted in scaffolder task state. The `gitlab:pipeline:trigger` action has been refactored so that the temporary pipeline trigger token is never serialized into checkpoint state.
|
|
8
|
+
- 4740660: Sped up `publish:gitlab:merge-request` and `gitlab:repo:push` by drastically reducing the number
|
|
9
|
+
of GitLab API requests they make.
|
|
10
|
+
|
|
11
|
+
Under the default `commitAction: 'auto'`, both actions previously downloaded the contents of every
|
|
12
|
+
file already present on the target branch in order to work out which ones had actually changed.
|
|
13
|
+
That information is available from the repository listing they already fetch, so the comparison is
|
|
14
|
+
now done locally and those per-file requests are gone. The listing itself is also fetched in larger
|
|
15
|
+
pages.
|
|
16
|
+
|
|
17
|
+
For a merge request against a repository of a few hundred files this cuts the number of requests
|
|
18
|
+
from roughly 300 to under ten, taking a step that took 5-15 seconds against a self-hosted GitLab
|
|
19
|
+
down to about 3 seconds. Which files are created, updated or skipped is unchanged, including for
|
|
20
|
+
repositories using git sha256 object format.
|
|
21
|
+
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
- @backstage/config@1.3.9-next.0
|
|
24
|
+
- @backstage/plugin-scaffolder-node@0.13.7-next.2
|
|
25
|
+
- @backstage/backend-plugin-api@1.10.1-next.1
|
|
26
|
+
- @backstage/integration@2.1.2-next.1
|
|
27
|
+
|
|
28
|
+
## 0.11.11-next.1
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- bbba6b5: Added support for requiring user-provided credentials for GitLab mutation actions when `scaffolder.requireScmUserCredentials` is enabled.
|
|
33
|
+
- cd77db3: Added an `autoMerge` boolean input to the `publish:gitlab:merge-request` scaffolder action. When set to `true`, the merge request is automatically merged once all merge checks succeed, using GitLab's auto-merge feature.
|
|
34
|
+
- Updated dependencies
|
|
35
|
+
- @backstage/integration@2.1.2-next.0
|
|
36
|
+
- @backstage/plugin-scaffolder-node@0.13.7-next.1
|
|
37
|
+
- @backstage/backend-plugin-api@1.10.1-next.0
|
|
38
|
+
|
|
39
|
+
## 0.11.10-next.0
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- 3c7c082: Fixed `gitlab:repo:push` failing with `400 Bad request - Provide at least one action` when the workspace has no file changes to commit (e.g. re-running a template against an already up-to-date branch). The action now detects an empty action list, skips the commit API call, and logs a warning whenever `allowEmpty` is not true (covering both the default of unset and an explicit `false`). The `commitHash` output is omitted in this no-op case and is now declared optional. Pass `allowEmpty: true` to retain the previous behavior of forwarding an empty commit to GitLab.
|
|
8
44
|
- Updated dependencies
|
|
9
|
-
- @backstage/
|
|
45
|
+
- @backstage/plugin-scaffolder-node@0.13.7-next.0
|
|
10
46
|
|
|
11
47
|
## 0.11.9
|
|
12
48
|
|
|
@@ -73,7 +73,10 @@ _deprecated_: \`projectid\` passed as query parameters in the \`repoUrl\``
|
|
|
73
73
|
assignReviewersFromApprovalRules: (z) => z.boolean().optional().describe(
|
|
74
74
|
"Automatically assign reviewers from the approval rules of the MR. Includes `CODEOWNERS`"
|
|
75
75
|
),
|
|
76
|
-
labels: (z) => z.string().or(z.string().array()).optional().describe("Labels with which to tag the created merge request")
|
|
76
|
+
labels: (z) => z.string().or(z.string().array()).optional().describe("Labels with which to tag the created merge request"),
|
|
77
|
+
autoMerge: (z) => z.boolean().optional().describe(
|
|
78
|
+
"Automatically merge the MR when all merge checks succeed. Uses GitLab auto-merge. Default: `false`"
|
|
79
|
+
)
|
|
77
80
|
},
|
|
78
81
|
output: {
|
|
79
82
|
targetBranchName: (z) => z.string().describe("Target branch name of the merge request"),
|
|
@@ -95,7 +98,8 @@ _deprecated_: \`projectid\` passed as query parameters in the \`repoUrl\``
|
|
|
95
98
|
sourcePath,
|
|
96
99
|
title,
|
|
97
100
|
token,
|
|
98
|
-
labels
|
|
101
|
+
labels,
|
|
102
|
+
autoMerge
|
|
99
103
|
} = ctx.input;
|
|
100
104
|
const { owner, repo, project } = pluginScaffolderNode.parseRepoUrl(repoUrl, integrations);
|
|
101
105
|
const repoID = project ? project : `${owner}/${repo}`;
|
|
@@ -166,7 +170,9 @@ _deprecated_: \`projectid\` passed as query parameters in the \`repoUrl\``
|
|
|
166
170
|
remoteFiles = await api.Repositories.allRepositoryTrees(repoID, {
|
|
167
171
|
ref: targetBranch,
|
|
168
172
|
recursive: true,
|
|
169
|
-
path: targetPath ?? void 0
|
|
173
|
+
path: targetPath ?? void 0,
|
|
174
|
+
// Pages are walked serially via the Link header, and GitLab's default is 20.
|
|
175
|
+
perPage: 100
|
|
170
176
|
});
|
|
171
177
|
} catch (e) {
|
|
172
178
|
ctx.logger.warn(
|
|
@@ -317,6 +323,25 @@ _deprecated_: \`projectid\` passed as query parameters in the \`repoUrl\``
|
|
|
317
323
|
return { mrWebUrl };
|
|
318
324
|
}
|
|
319
325
|
});
|
|
326
|
+
if (autoMerge) {
|
|
327
|
+
await ctx.checkpoint({
|
|
328
|
+
key: `auto.merge.mr.${repoID}.${branchName}`,
|
|
329
|
+
fn: async () => {
|
|
330
|
+
try {
|
|
331
|
+
await api.MergeRequests.merge(repoID, mrId, {
|
|
332
|
+
autoMerge: true
|
|
333
|
+
});
|
|
334
|
+
return null;
|
|
335
|
+
} catch (e) {
|
|
336
|
+
throw new errors.InputError(
|
|
337
|
+
`Enabling auto-merge for merge request ${mrId} failed. ${helpers.getErrorMessage(
|
|
338
|
+
e
|
|
339
|
+
)}`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
}
|
|
320
345
|
ctx.output("projectid", repoID);
|
|
321
346
|
ctx.output("targetBranchName", targetBranch);
|
|
322
347
|
ctx.output("projectPath", repoID);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitlabMergeRequest.cjs.js","sources":["../../src/actions/gitlabMergeRequest.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createTemplateAction,\n parseRepoUrl,\n SerializedFile,\n serializeDirectoryContents,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n Camelize,\n CommitAction,\n ExpandedMergeRequestSchema,\n Gitlab,\n RepositoryTreeSchema,\n SimpleUserSchema,\n} from '@gitbeaker/rest';\nimport path from 'node:path';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { InputError } from '@backstage/errors';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport { createGitlabApi, getErrorMessage } from './helpers';\nimport { examples } from './gitlabMergeRequest.examples';\n\nimport { getFileAction } from '../util';\n\nasync function getReviewersFromApprovalRules(\n api: InstanceType<typeof Gitlab>,\n mergerequestIId: number,\n repoID: string,\n ctx: any,\n): Promise<number[]> {\n try {\n // Because we don't know the code owners before the MR is created, we can't check the approval rules beforehand.\n // Getting the approval rules beforehand is very difficult, especially, because of the inheritance rules for groups.\n // Code owners take a moment to be processed and added to the approval rules after the MR is created.\n\n let mergeRequest:\n | ExpandedMergeRequestSchema\n | Camelize<ExpandedMergeRequestSchema> = await api.MergeRequests.show(\n repoID,\n mergerequestIId,\n );\n\n while (\n mergeRequest.detailed_merge_status === 'preparing' ||\n mergeRequest.detailed_merge_status === 'approvals_syncing' ||\n mergeRequest.detailed_merge_status === 'checking'\n ) {\n mergeRequest = await api.MergeRequests.show(repoID, mergeRequest.iid);\n ctx.logger.info(`${mergeRequest.detailed_merge_status}`);\n }\n\n const approvalRules = await api.MergeRequestApprovals.allApprovalRules(\n repoID,\n {\n mergerequestIId: mergeRequest.iid,\n },\n );\n\n return approvalRules\n .filter(rule => rule.eligible_approvers !== undefined)\n .map(rule => {\n return rule.eligible_approvers as SimpleUserSchema[];\n })\n .flat()\n .map(user => user.id);\n } catch (e) {\n ctx.logger.warn(\n `Failed to retrieve approval rules for MR ${mergerequestIId}: ${getErrorMessage(\n e,\n )}. Proceeding with MR creation without reviewers from approval rules.`,\n );\n return [];\n }\n}\n\nconst commitActions = ['create', 'delete', 'update', 'skip', 'auto'] as const;\n\n/**\n * Create a new action that creates a GitLab merge request.\n *\n * @public\n */\nexport const createPublishGitlabMergeRequestAction = (options: {\n integrations: ScmIntegrationRegistry;\n requireScmUserCredentials?: boolean;\n}) => {\n const { integrations, requireScmUserCredentials } = options;\n\n return createTemplateAction({\n id: 'publish:gitlab:merge-request',\n examples,\n schema: {\n input: {\n repoUrl: z =>\n z.string().describe(`\\\nAccepts the format \\`gitlab.com?repo=project_name&owner=group_name\\` where \\\n\\`project_name\\` is the repository name and \\`group_name\\` is a group or username`),\n title: z => z.string().describe('The name for the merge request'),\n description: z =>\n z\n .string()\n .optional()\n .describe('The description of the merge request'),\n branchName: z =>\n z.string().describe('The source branch name of the merge request'),\n targetBranchName: z =>\n z\n .string()\n .optional()\n .describe(\n 'The target branch name of the merge request (defaults to _default branch of repository_)',\n ),\n sourcePath: z =>\n z.string().optional().describe(`\\\nSubdirectory of working directory to copy changes from. \\\nFor reasons of backward compatibility, any specified \\`targetPath\\` input will \\\nbe applied in place of an absent/falsy value for this input. \\\nCircumvent this behavior using \\`.\\``),\n targetPath: z =>\n z\n .string()\n .optional()\n .describe('Subdirectory of repository to apply changes to'),\n token: z =>\n z\n .string()\n .optional()\n .describe('The token to use for authorization to GitLab'),\n commitAction: z =>\n z.enum(commitActions).optional().describe(`\\\nThe action to be used for \\`git\\` commit. Defaults to the custom \\`auto\\` action provided by Backstage,\nwhich uses additional API calls in order to detect whether to \\`create\\`, \\`update\\` or \\`skip\\` each source file.`),\n /** @deprecated projectID passed as query parameters in the repoUrl */\n projectid: z =>\n z\n .string()\n .optional()\n .describe(\n `\\\nProject ID/Name(slug) of the GitLab Project\n_deprecated_: \\`projectid\\` passed as query parameters in the \\`repoUrl\\``,\n ),\n removeSourceBranch: z =>\n z\n .boolean()\n .optional()\n .describe(\n 'Option to delete source branch once the MR has been merged. Default: `false`',\n ),\n assignee: z =>\n z\n .string()\n .optional()\n .describe('User this merge request will be assigned to'),\n reviewers: z =>\n z\n .string()\n .array()\n .optional()\n .describe('Users that will be assigned as reviewers'),\n assignReviewersFromApprovalRules: z =>\n z\n .boolean()\n .optional()\n .describe(\n 'Automatically assign reviewers from the approval rules of the MR. Includes `CODEOWNERS`',\n ),\n labels: z =>\n z\n .string()\n .or(z.string().array())\n .optional()\n .describe('Labels with which to tag the created merge request'),\n },\n output: {\n targetBranchName: z =>\n z.string().describe('Target branch name of the merge request'),\n projectid: z => z.string().describe('GitLab Project id/Name(slug)'),\n projectPath: z => z.string().describe('GitLab Project path'),\n mergeRequestUrl: z =>\n z.string().describe('Link to the merge request in GitLab'),\n },\n },\n async handler(ctx) {\n const {\n assignee,\n reviewers,\n branchName,\n targetBranchName,\n description,\n repoUrl,\n removeSourceBranch,\n targetPath,\n sourcePath,\n title,\n token,\n labels,\n } = ctx.input;\n\n const { owner, repo, project } = parseRepoUrl(repoUrl, integrations);\n const repoID = project ? project : `${owner}/${repo}`;\n\n const api = createGitlabApi({\n integrations,\n token,\n repoUrl,\n requireScmUserCredentials,\n });\n\n let assigneeId: number | undefined = undefined;\n\n if (assignee !== undefined) {\n try {\n const assigneeUser = await api.Users.all({ username: assignee });\n assigneeId = assigneeUser[0].id;\n } catch (e) {\n ctx.logger.warn(\n `Failed to find gitlab user id for ${assignee}: ${getErrorMessage(\n e,\n )}. Proceeding with MR creation without an assignee.`,\n );\n }\n }\n\n let reviewerIds: number[] | undefined = undefined; // Explicitly set to undefined. Strangely, passing an empty array to the API will result the other options being undefined also being explicitly passed to the Gitlab API call (e.g. assigneeId)\n if (reviewers !== undefined) {\n reviewerIds = (\n await Promise.all(\n reviewers.map(async reviewer => {\n try {\n const reviewerUser = await api.Users.all({\n username: reviewer,\n });\n return reviewerUser[0].id;\n } catch (e) {\n ctx.logger.warn(\n `Failed to find gitlab user id for ${reviewer}: ${e}. Proceeding with MR creation without reviewer.`,\n );\n return undefined;\n }\n }),\n )\n ).filter(id => id !== undefined) as number[];\n }\n\n let fileRoot: string;\n if (sourcePath) {\n fileRoot = resolveSafeChildPath(ctx.workspacePath, sourcePath);\n } else if (targetPath) {\n // for backward compatibility\n fileRoot = resolveSafeChildPath(ctx.workspacePath, targetPath);\n } else {\n fileRoot = ctx.workspacePath;\n }\n\n const fileContents = await serializeDirectoryContents(fileRoot, {\n gitignore: true,\n });\n\n let targetBranch = targetBranchName;\n if (!targetBranch) {\n const projects = await api.Projects.show(repoID);\n const defaultBranch = projects.default_branch ?? projects.defaultBranch;\n if (typeof defaultBranch !== 'string' || !defaultBranch) {\n throw new InputError(\n `The branch creation failed. Target branch was not provided, and could not find default branch from project settings. Project: ${JSON.stringify(\n project,\n )}`,\n );\n }\n targetBranch = defaultBranch;\n }\n\n let remoteFiles: RepositoryTreeSchema[] = [];\n if ((ctx.input.commitAction ?? 'auto') === 'auto') {\n try {\n remoteFiles = await api.Repositories.allRepositoryTrees(repoID, {\n ref: targetBranch,\n recursive: true,\n path: targetPath ?? undefined,\n });\n } catch (e) {\n ctx.logger.warn(\n `Could not retrieve the list of files for ${repoID} (branch: ${targetBranch}) : ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n const actions: CommitAction[] =\n ctx.input.commitAction === 'skip'\n ? []\n : (\n (\n await Promise.all(\n fileContents.map(async file => {\n const action = await getFileAction(\n { file, targetPath },\n { repoID, branch: targetBranch! },\n api,\n ctx.logger,\n remoteFiles,\n ctx.input.commitAction,\n );\n return { file, action };\n }),\n )\n ).filter(o => o.action !== 'skip') as {\n file: SerializedFile;\n action: CommitAction['action'];\n }[]\n ).map(({ file, action }) => ({\n action,\n filePath: targetPath\n ? path.posix.join(targetPath, file.path)\n : file.path,\n encoding: 'base64',\n content: file.content.toString('base64'),\n execute_filemode: file.executable,\n }));\n\n let createBranch = actions.length > 0;\n\n try {\n const branch = await api.Branches.show(repoID, branchName);\n if (createBranch) {\n const mergeRequests = await api.MergeRequests.all({\n projectId: repoID,\n source_branch: branchName,\n });\n\n if (mergeRequests.length > 0) {\n // If an open MR exists, include the MR link in the error message\n throw new InputError(\n `The branch creation failed because the branch already exists at: ${branch.web_url}. Additionally, there is a Merge Request for this branch: ${mergeRequests[0].web_url}`,\n );\n } else {\n // If no open MR, just notify about the existing branch\n throw new InputError(\n `The branch creation failed because the branch already exists at: ${branch.web_url}.`,\n );\n }\n }\n\n ctx.logger.info(\n `Using existing branch ${branchName} without modification.`,\n );\n } catch (e) {\n if (e instanceof InputError) {\n throw e;\n }\n createBranch = true;\n }\n\n if (createBranch) {\n try {\n await api.Branches.create(repoID, branchName, String(targetBranch));\n } catch (e) {\n throw new InputError(\n `The branch creation failed. Please check that your repo does not already contain a branch named '${branchName}'. ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n\n await ctx.checkpoint({\n key: `commit.to.${repoID}.${branchName}`,\n fn: async () => {\n if (actions.length) {\n try {\n const commit = await api.Commits.create(\n repoID,\n branchName,\n title,\n actions,\n );\n return commit.id;\n } catch (e) {\n throw new InputError(\n `Committing the changes to ${branchName} failed. Please check that none of the files created by the template already exists. ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n return null;\n },\n });\n\n const { mrId, mrWebUrl } = await ctx.checkpoint({\n key: `create.mr.${repoID}.${branchName}`,\n fn: async () => {\n try {\n const mergeRequest = await api.MergeRequests.create(\n repoID,\n branchName,\n String(targetBranch),\n title,\n {\n description,\n removeSourceBranch: removeSourceBranch\n ? removeSourceBranch\n : false,\n assigneeId,\n reviewerIds,\n labels,\n },\n );\n return {\n mrId: mergeRequest.iid,\n mrWebUrl: mergeRequest.web_url ?? mergeRequest.webUrl,\n };\n } catch (e) {\n throw new InputError(\n `Merge request creation failed. ${getErrorMessage(e)}`,\n );\n }\n },\n });\n\n await ctx.checkpoint({\n key: `create.mr.assign.reviewers.${repoID}.${branchName}`,\n fn: async () => {\n if (ctx.input.assignReviewersFromApprovalRules) {\n try {\n const reviewersFromApprovalRules =\n await getReviewersFromApprovalRules(api, mrId, repoID, ctx);\n if (reviewersFromApprovalRules.length > 0) {\n const eligibleUserIds = new Set([\n ...reviewersFromApprovalRules,\n ...(reviewerIds ?? []),\n ]);\n\n const mergeRequest = await api.MergeRequests.edit(\n repoID,\n mrId,\n {\n reviewerIds: Array.from(eligibleUserIds),\n },\n );\n return {\n mrWebUrl: mergeRequest.web_url ?? mergeRequest.webUrl,\n };\n }\n } catch (e) {\n ctx.logger.warn(\n `Failed to assign reviewers from approval rules: ${getErrorMessage(\n e,\n )}.`,\n );\n }\n }\n return { mrWebUrl };\n },\n });\n\n ctx.output('projectid', repoID);\n ctx.output('targetBranchName', targetBranch);\n ctx.output('projectPath', repoID);\n ctx.output('mergeRequestUrl', mrWebUrl as string);\n },\n });\n};\n"],"names":["getErrorMessage","createTemplateAction","examples","parseRepoUrl","createGitlabApi","resolveSafeChildPath","serializeDirectoryContents","InputError","getFileAction","path"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gitlabMergeRequest.cjs.js","sources":["../../src/actions/gitlabMergeRequest.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createTemplateAction,\n parseRepoUrl,\n SerializedFile,\n serializeDirectoryContents,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n Camelize,\n CommitAction,\n ExpandedMergeRequestSchema,\n Gitlab,\n RepositoryTreeSchema,\n SimpleUserSchema,\n} from '@gitbeaker/rest';\nimport path from 'node:path';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { InputError } from '@backstage/errors';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport { createGitlabApi, getErrorMessage } from './helpers';\nimport { examples } from './gitlabMergeRequest.examples';\n\nimport { getFileAction } from '../util';\n\nasync function getReviewersFromApprovalRules(\n api: InstanceType<typeof Gitlab>,\n mergerequestIId: number,\n repoID: string,\n ctx: any,\n): Promise<number[]> {\n try {\n // Because we don't know the code owners before the MR is created, we can't check the approval rules beforehand.\n // Getting the approval rules beforehand is very difficult, especially, because of the inheritance rules for groups.\n // Code owners take a moment to be processed and added to the approval rules after the MR is created.\n\n let mergeRequest:\n | ExpandedMergeRequestSchema\n | Camelize<ExpandedMergeRequestSchema> = await api.MergeRequests.show(\n repoID,\n mergerequestIId,\n );\n\n while (\n mergeRequest.detailed_merge_status === 'preparing' ||\n mergeRequest.detailed_merge_status === 'approvals_syncing' ||\n mergeRequest.detailed_merge_status === 'checking'\n ) {\n mergeRequest = await api.MergeRequests.show(repoID, mergeRequest.iid);\n ctx.logger.info(`${mergeRequest.detailed_merge_status}`);\n }\n\n const approvalRules = await api.MergeRequestApprovals.allApprovalRules(\n repoID,\n {\n mergerequestIId: mergeRequest.iid,\n },\n );\n\n return approvalRules\n .filter(rule => rule.eligible_approvers !== undefined)\n .map(rule => {\n return rule.eligible_approvers as SimpleUserSchema[];\n })\n .flat()\n .map(user => user.id);\n } catch (e) {\n ctx.logger.warn(\n `Failed to retrieve approval rules for MR ${mergerequestIId}: ${getErrorMessage(\n e,\n )}. Proceeding with MR creation without reviewers from approval rules.`,\n );\n return [];\n }\n}\n\nconst commitActions = ['create', 'delete', 'update', 'skip', 'auto'] as const;\n\n/**\n * Create a new action that creates a GitLab merge request.\n *\n * @public\n */\nexport const createPublishGitlabMergeRequestAction = (options: {\n integrations: ScmIntegrationRegistry;\n requireScmUserCredentials?: boolean;\n}) => {\n const { integrations, requireScmUserCredentials } = options;\n\n return createTemplateAction({\n id: 'publish:gitlab:merge-request',\n examples,\n schema: {\n input: {\n repoUrl: z =>\n z.string().describe(`\\\nAccepts the format \\`gitlab.com?repo=project_name&owner=group_name\\` where \\\n\\`project_name\\` is the repository name and \\`group_name\\` is a group or username`),\n title: z => z.string().describe('The name for the merge request'),\n description: z =>\n z\n .string()\n .optional()\n .describe('The description of the merge request'),\n branchName: z =>\n z.string().describe('The source branch name of the merge request'),\n targetBranchName: z =>\n z\n .string()\n .optional()\n .describe(\n 'The target branch name of the merge request (defaults to _default branch of repository_)',\n ),\n sourcePath: z =>\n z.string().optional().describe(`\\\nSubdirectory of working directory to copy changes from. \\\nFor reasons of backward compatibility, any specified \\`targetPath\\` input will \\\nbe applied in place of an absent/falsy value for this input. \\\nCircumvent this behavior using \\`.\\``),\n targetPath: z =>\n z\n .string()\n .optional()\n .describe('Subdirectory of repository to apply changes to'),\n token: z =>\n z\n .string()\n .optional()\n .describe('The token to use for authorization to GitLab'),\n commitAction: z =>\n z.enum(commitActions).optional().describe(`\\\nThe action to be used for \\`git\\` commit. Defaults to the custom \\`auto\\` action provided by Backstage,\nwhich uses additional API calls in order to detect whether to \\`create\\`, \\`update\\` or \\`skip\\` each source file.`),\n /** @deprecated projectID passed as query parameters in the repoUrl */\n projectid: z =>\n z\n .string()\n .optional()\n .describe(\n `\\\nProject ID/Name(slug) of the GitLab Project\n_deprecated_: \\`projectid\\` passed as query parameters in the \\`repoUrl\\``,\n ),\n removeSourceBranch: z =>\n z\n .boolean()\n .optional()\n .describe(\n 'Option to delete source branch once the MR has been merged. Default: `false`',\n ),\n assignee: z =>\n z\n .string()\n .optional()\n .describe('User this merge request will be assigned to'),\n reviewers: z =>\n z\n .string()\n .array()\n .optional()\n .describe('Users that will be assigned as reviewers'),\n assignReviewersFromApprovalRules: z =>\n z\n .boolean()\n .optional()\n .describe(\n 'Automatically assign reviewers from the approval rules of the MR. Includes `CODEOWNERS`',\n ),\n labels: z =>\n z\n .string()\n .or(z.string().array())\n .optional()\n .describe('Labels with which to tag the created merge request'),\n autoMerge: z =>\n z\n .boolean()\n .optional()\n .describe(\n 'Automatically merge the MR when all merge checks succeed. Uses GitLab auto-merge. Default: `false`',\n ),\n },\n output: {\n targetBranchName: z =>\n z.string().describe('Target branch name of the merge request'),\n projectid: z => z.string().describe('GitLab Project id/Name(slug)'),\n projectPath: z => z.string().describe('GitLab Project path'),\n mergeRequestUrl: z =>\n z.string().describe('Link to the merge request in GitLab'),\n },\n },\n async handler(ctx) {\n const {\n assignee,\n reviewers,\n branchName,\n targetBranchName,\n description,\n repoUrl,\n removeSourceBranch,\n targetPath,\n sourcePath,\n title,\n token,\n labels,\n autoMerge,\n } = ctx.input;\n\n const { owner, repo, project } = parseRepoUrl(repoUrl, integrations);\n const repoID = project ? project : `${owner}/${repo}`;\n\n const api = createGitlabApi({\n integrations,\n token,\n repoUrl,\n requireScmUserCredentials,\n });\n\n let assigneeId: number | undefined = undefined;\n\n if (assignee !== undefined) {\n try {\n const assigneeUser = await api.Users.all({ username: assignee });\n assigneeId = assigneeUser[0].id;\n } catch (e) {\n ctx.logger.warn(\n `Failed to find gitlab user id for ${assignee}: ${getErrorMessage(\n e,\n )}. Proceeding with MR creation without an assignee.`,\n );\n }\n }\n\n let reviewerIds: number[] | undefined = undefined; // Explicitly set to undefined. Strangely, passing an empty array to the API will result the other options being undefined also being explicitly passed to the Gitlab API call (e.g. assigneeId)\n if (reviewers !== undefined) {\n reviewerIds = (\n await Promise.all(\n reviewers.map(async reviewer => {\n try {\n const reviewerUser = await api.Users.all({\n username: reviewer,\n });\n return reviewerUser[0].id;\n } catch (e) {\n ctx.logger.warn(\n `Failed to find gitlab user id for ${reviewer}: ${e}. Proceeding with MR creation without reviewer.`,\n );\n return undefined;\n }\n }),\n )\n ).filter(id => id !== undefined) as number[];\n }\n\n let fileRoot: string;\n if (sourcePath) {\n fileRoot = resolveSafeChildPath(ctx.workspacePath, sourcePath);\n } else if (targetPath) {\n // for backward compatibility\n fileRoot = resolveSafeChildPath(ctx.workspacePath, targetPath);\n } else {\n fileRoot = ctx.workspacePath;\n }\n\n const fileContents = await serializeDirectoryContents(fileRoot, {\n gitignore: true,\n });\n\n let targetBranch = targetBranchName;\n if (!targetBranch) {\n const projects = await api.Projects.show(repoID);\n const defaultBranch = projects.default_branch ?? projects.defaultBranch;\n if (typeof defaultBranch !== 'string' || !defaultBranch) {\n throw new InputError(\n `The branch creation failed. Target branch was not provided, and could not find default branch from project settings. Project: ${JSON.stringify(\n project,\n )}`,\n );\n }\n targetBranch = defaultBranch;\n }\n\n let remoteFiles: RepositoryTreeSchema[] = [];\n if ((ctx.input.commitAction ?? 'auto') === 'auto') {\n try {\n remoteFiles = await api.Repositories.allRepositoryTrees(repoID, {\n ref: targetBranch,\n recursive: true,\n path: targetPath ?? undefined,\n // Pages are walked serially via the Link header, and GitLab's default is 20.\n perPage: 100,\n });\n } catch (e) {\n ctx.logger.warn(\n `Could not retrieve the list of files for ${repoID} (branch: ${targetBranch}) : ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n const actions: CommitAction[] =\n ctx.input.commitAction === 'skip'\n ? []\n : (\n (\n await Promise.all(\n fileContents.map(async file => {\n const action = await getFileAction(\n { file, targetPath },\n { repoID, branch: targetBranch! },\n api,\n ctx.logger,\n remoteFiles,\n ctx.input.commitAction,\n );\n return { file, action };\n }),\n )\n ).filter(o => o.action !== 'skip') as {\n file: SerializedFile;\n action: CommitAction['action'];\n }[]\n ).map(({ file, action }) => ({\n action,\n filePath: targetPath\n ? path.posix.join(targetPath, file.path)\n : file.path,\n encoding: 'base64',\n content: file.content.toString('base64'),\n execute_filemode: file.executable,\n }));\n\n let createBranch = actions.length > 0;\n\n try {\n const branch = await api.Branches.show(repoID, branchName);\n if (createBranch) {\n const mergeRequests = await api.MergeRequests.all({\n projectId: repoID,\n source_branch: branchName,\n });\n\n if (mergeRequests.length > 0) {\n // If an open MR exists, include the MR link in the error message\n throw new InputError(\n `The branch creation failed because the branch already exists at: ${branch.web_url}. Additionally, there is a Merge Request for this branch: ${mergeRequests[0].web_url}`,\n );\n } else {\n // If no open MR, just notify about the existing branch\n throw new InputError(\n `The branch creation failed because the branch already exists at: ${branch.web_url}.`,\n );\n }\n }\n\n ctx.logger.info(\n `Using existing branch ${branchName} without modification.`,\n );\n } catch (e) {\n if (e instanceof InputError) {\n throw e;\n }\n createBranch = true;\n }\n\n if (createBranch) {\n try {\n await api.Branches.create(repoID, branchName, String(targetBranch));\n } catch (e) {\n throw new InputError(\n `The branch creation failed. Please check that your repo does not already contain a branch named '${branchName}'. ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n\n await ctx.checkpoint({\n key: `commit.to.${repoID}.${branchName}`,\n fn: async () => {\n if (actions.length) {\n try {\n const commit = await api.Commits.create(\n repoID,\n branchName,\n title,\n actions,\n );\n return commit.id;\n } catch (e) {\n throw new InputError(\n `Committing the changes to ${branchName} failed. Please check that none of the files created by the template already exists. ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n return null;\n },\n });\n\n const { mrId, mrWebUrl } = await ctx.checkpoint({\n key: `create.mr.${repoID}.${branchName}`,\n fn: async () => {\n try {\n const mergeRequest = await api.MergeRequests.create(\n repoID,\n branchName,\n String(targetBranch),\n title,\n {\n description,\n removeSourceBranch: removeSourceBranch\n ? removeSourceBranch\n : false,\n assigneeId,\n reviewerIds,\n labels,\n },\n );\n return {\n mrId: mergeRequest.iid,\n mrWebUrl: mergeRequest.web_url ?? mergeRequest.webUrl,\n };\n } catch (e) {\n throw new InputError(\n `Merge request creation failed. ${getErrorMessage(e)}`,\n );\n }\n },\n });\n\n await ctx.checkpoint({\n key: `create.mr.assign.reviewers.${repoID}.${branchName}`,\n fn: async () => {\n if (ctx.input.assignReviewersFromApprovalRules) {\n try {\n const reviewersFromApprovalRules =\n await getReviewersFromApprovalRules(api, mrId, repoID, ctx);\n if (reviewersFromApprovalRules.length > 0) {\n const eligibleUserIds = new Set([\n ...reviewersFromApprovalRules,\n ...(reviewerIds ?? []),\n ]);\n\n const mergeRequest = await api.MergeRequests.edit(\n repoID,\n mrId,\n {\n reviewerIds: Array.from(eligibleUserIds),\n },\n );\n return {\n mrWebUrl: mergeRequest.web_url ?? mergeRequest.webUrl,\n };\n }\n } catch (e) {\n ctx.logger.warn(\n `Failed to assign reviewers from approval rules: ${getErrorMessage(\n e,\n )}.`,\n );\n }\n }\n return { mrWebUrl };\n },\n });\n if (autoMerge) {\n await ctx.checkpoint({\n key: `auto.merge.mr.${repoID}.${branchName}`,\n fn: async () => {\n try {\n await api.MergeRequests.merge(repoID, mrId, {\n autoMerge: true,\n });\n return null;\n } catch (e) {\n throw new InputError(\n `Enabling auto-merge for merge request ${mrId} failed. ${getErrorMessage(\n e,\n )}`,\n );\n }\n },\n });\n }\n\n ctx.output('projectid', repoID);\n ctx.output('targetBranchName', targetBranch);\n ctx.output('projectPath', repoID);\n ctx.output('mergeRequestUrl', mrWebUrl as string);\n },\n });\n};\n"],"names":["getErrorMessage","createTemplateAction","examples","parseRepoUrl","createGitlabApi","resolveSafeChildPath","serializeDirectoryContents","InputError","getFileAction","path"],"mappings":";;;;;;;;;;;;;;AAuCA,eAAe,6BAAA,CACb,GAAA,EACA,eAAA,EACA,MAAA,EACA,GAAA,EACmB;AACnB,EAAA,IAAI;AAKF,IAAA,IAAI,YAAA,GAEuC,MAAM,GAAA,CAAI,aAAA,CAAc,IAAA;AAAA,MACjE,MAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,OACE,YAAA,CAAa,0BAA0B,WAAA,IACvC,YAAA,CAAa,0BAA0B,mBAAA,IACvC,YAAA,CAAa,0BAA0B,UAAA,EACvC;AACA,MAAA,YAAA,GAAe,MAAM,GAAA,CAAI,aAAA,CAAc,IAAA,CAAK,MAAA,EAAQ,aAAa,GAAG,CAAA;AACpE,MAAA,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,CAAA,EAAG,YAAA,CAAa,qBAAqB,CAAA,CAAE,CAAA;AAAA,IACzD;AAEA,IAAA,MAAM,aAAA,GAAgB,MAAM,GAAA,CAAI,qBAAA,CAAsB,gBAAA;AAAA,MACpD,MAAA;AAAA,MACA;AAAA,QACE,iBAAiB,YAAA,CAAa;AAAA;AAChC,KACF;AAEA,IAAA,OAAO,aAAA,CACJ,OAAO,CAAA,IAAA,KAAQ,IAAA,CAAK,uBAAuB,KAAA,CAAS,CAAA,CACpD,IAAI,CAAA,IAAA,KAAQ;AACX,MAAA,OAAO,IAAA,CAAK,kBAAA;AAAA,IACd,CAAC,CAAA,CACA,IAAA,GACA,GAAA,CAAI,CAAA,IAAA,KAAQ,KAAK,EAAE,CAAA;AAAA,EACxB,SAAS,CAAA,EAAG;AACV,IAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,MACT,CAAA,yCAAA,EAA4C,eAAe,CAAA,EAAA,EAAKA,uBAAA;AAAA,QAC9D;AAAA,OACD,CAAA,oEAAA;AAAA,KACH;AACA,IAAA,OAAO,EAAC;AAAA,EACV;AACF;AAEA,MAAM,gBAAgB,CAAC,QAAA,EAAU,QAAA,EAAU,QAAA,EAAU,QAAQ,MAAM,CAAA;AAO5D,MAAM,qCAAA,GAAwC,CAAC,OAAA,KAGhD;AACJ,EAAA,MAAM,EAAE,YAAA,EAAc,yBAAA,EAA0B,GAAI,OAAA;AAEpD,EAAA,OAAOC,yCAAA,CAAqB;AAAA,IAC1B,EAAA,EAAI,8BAAA;AAAA,cACJC,oCAAA;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO;AAAA,QACL,SAAS,CAAA,CAAA,KACP,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,CAAA,4JAAA,CAEoD,CAAA;AAAA,QAC1E,OAAO,CAAA,CAAA,KAAK,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,gCAAgC,CAAA;AAAA,QAChE,WAAA,EAAa,OACX,CAAA,CACG,MAAA,GACA,QAAA,EAAS,CACT,SAAS,sCAAsC,CAAA;AAAA,QACpD,YAAY,CAAA,CAAA,KACV,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,6CAA6C,CAAA;AAAA,QACnE,kBAAkB,CAAA,CAAA,KAChB,CAAA,CACG,MAAA,EAAO,CACP,UAAS,CACT,QAAA;AAAA,UACC;AAAA,SACF;AAAA,QACJ,UAAA,EAAY,OACV,CAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,CAAA,wOAAA,CAIJ,CAAA;AAAA,QAC7B,UAAA,EAAY,OACV,CAAA,CACG,MAAA,GACA,QAAA,EAAS,CACT,SAAS,gDAAgD,CAAA;AAAA,QAC9D,KAAA,EAAO,OACL,CAAA,CACG,MAAA,GACA,QAAA,EAAS,CACT,SAAS,8CAA8C,CAAA;AAAA,QAC5D,YAAA,EAAc,OACZ,CAAA,CAAE,IAAA,CAAK,aAAa,CAAA,CAAE,QAAA,GAAW,QAAA,CAAS,CAAA;AAAA,kHAAA,CAE+D,CAAA;AAAA;AAAA,QAE3G,WAAW,CAAA,CAAA,KACT,CAAA,CACG,MAAA,EAAO,CACP,UAAS,CACT,QAAA;AAAA,UACC,CAAA;AAAA,yEAAA;AAAA,SAGF;AAAA,QACJ,oBAAoB,CAAA,CAAA,KAClB,CAAA,CACG,OAAA,EAAQ,CACR,UAAS,CACT,QAAA;AAAA,UACC;AAAA,SACF;AAAA,QACJ,QAAA,EAAU,OACR,CAAA,CACG,MAAA,GACA,QAAA,EAAS,CACT,SAAS,6CAA6C,CAAA;AAAA,QAC3D,SAAA,EAAW,CAAA,CAAA,KACT,CAAA,CACG,MAAA,EAAO,CACP,OAAM,CACN,QAAA,EAAS,CACT,QAAA,CAAS,0CAA0C,CAAA;AAAA,QACxD,kCAAkC,CAAA,CAAA,KAChC,CAAA,CACG,OAAA,EAAQ,CACR,UAAS,CACT,QAAA;AAAA,UACC;AAAA,SACF;AAAA,QACJ,MAAA,EAAQ,CAAA,CAAA,KACN,CAAA,CACG,MAAA,GACA,EAAA,CAAG,CAAA,CAAE,MAAA,EAAO,CAAE,OAAO,CAAA,CACrB,QAAA,EAAS,CACT,SAAS,oDAAoD,CAAA;AAAA,QAClE,WAAW,CAAA,CAAA,KACT,CAAA,CACG,OAAA,EAAQ,CACR,UAAS,CACT,QAAA;AAAA,UACC;AAAA;AACF,OACN;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,kBAAkB,CAAA,CAAA,KAChB,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,yCAAyC,CAAA;AAAA,QAC/D,WAAW,CAAA,CAAA,KAAK,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,8BAA8B,CAAA;AAAA,QAClE,aAAa,CAAA,CAAA,KAAK,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,qBAAqB,CAAA;AAAA,QAC3D,iBAAiB,CAAA,CAAA,KACf,CAAA,CAAE,MAAA,EAAO,CAAE,SAAS,qCAAqC;AAAA;AAC7D,KACF;AAAA,IACA,MAAM,QAAQ,GAAA,EAAK;AACjB,MAAA,MAAM;AAAA,QACJ,QAAA;AAAA,QACA,SAAA;AAAA,QACA,UAAA;AAAA,QACA,gBAAA;AAAA,QACA,WAAA;AAAA,QACA,OAAA;AAAA,QACA,kBAAA;AAAA,QACA,UAAA;AAAA,QACA,UAAA;AAAA,QACA,KAAA;AAAA,QACA,KAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,UACE,GAAA,CAAI,KAAA;AAER,MAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAM,SAAQ,GAAIC,iCAAA,CAAa,SAAS,YAAY,CAAA;AACnE,MAAA,MAAM,SAAS,OAAA,GAAU,OAAA,GAAU,CAAA,EAAG,KAAK,IAAI,IAAI,CAAA,CAAA;AAEnD,MAAA,MAAM,MAAMC,uBAAA,CAAgB;AAAA,QAC1B,YAAA;AAAA,QACA,KAAA;AAAA,QACA,OAAA;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,IAAI,UAAA,GAAiC,MAAA;AAErC,MAAA,IAAI,aAAa,MAAA,EAAW;AAC1B,QAAA,IAAI;AACF,UAAA,MAAM,YAAA,GAAe,MAAM,GAAA,CAAI,KAAA,CAAM,IAAI,EAAE,QAAA,EAAU,UAAU,CAAA;AAC/D,UAAA,UAAA,GAAa,YAAA,CAAa,CAAC,CAAA,CAAE,EAAA;AAAA,QAC/B,SAAS,CAAA,EAAG;AACV,UAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,YACT,CAAA,kCAAA,EAAqC,QAAQ,CAAA,EAAA,EAAKJ,uBAAA;AAAA,cAChD;AAAA,aACD,CAAA,kDAAA;AAAA,WACH;AAAA,QACF;AAAA,MACF;AAEA,MAAA,IAAI,WAAA,GAAoC,MAAA;AACxC,MAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,QAAA,WAAA,GAAA,CACE,MAAM,OAAA,CAAQ,GAAA;AAAA,UACZ,SAAA,CAAU,GAAA,CAAI,OAAM,QAAA,KAAY;AAC9B,YAAA,IAAI;AACF,cAAA,MAAM,YAAA,GAAe,MAAM,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI;AAAA,gBACvC,QAAA,EAAU;AAAA,eACX,CAAA;AACD,cAAA,OAAO,YAAA,CAAa,CAAC,CAAA,CAAE,EAAA;AAAA,YACzB,SAAS,CAAA,EAAG;AACV,cAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,gBACT,CAAA,kCAAA,EAAqC,QAAQ,CAAA,EAAA,EAAK,CAAC,CAAA,+CAAA;AAAA,eACrD;AACA,cAAA,OAAO,MAAA;AAAA,YACT;AAAA,UACF,CAAC;AAAA,SACH,EACA,MAAA,CAAO,CAAA,EAAA,KAAM,EAAA,KAAO,MAAS,CAAA;AAAA,MACjC;AAEA,MAAA,IAAI,QAAA;AACJ,MAAA,IAAI,UAAA,EAAY;AACd,QAAA,QAAA,GAAWK,qCAAA,CAAqB,GAAA,CAAI,aAAA,EAAe,UAAU,CAAA;AAAA,MAC/D,WAAW,UAAA,EAAY;AAErB,QAAA,QAAA,GAAWA,qCAAA,CAAqB,GAAA,CAAI,aAAA,EAAe,UAAU,CAAA;AAAA,MAC/D,CAAA,MAAO;AACL,QAAA,QAAA,GAAW,GAAA,CAAI,aAAA;AAAA,MACjB;AAEA,MAAA,MAAM,YAAA,GAAe,MAAMC,+CAAA,CAA2B,QAAA,EAAU;AAAA,QAC9D,SAAA,EAAW;AAAA,OACZ,CAAA;AAED,MAAA,IAAI,YAAA,GAAe,gBAAA;AACnB,MAAA,IAAI,CAAC,YAAA,EAAc;AACjB,QAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,QAAA,CAAS,KAAK,MAAM,CAAA;AAC/C,QAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,cAAA,IAAkB,QAAA,CAAS,aAAA;AAC1D,QAAA,IAAI,OAAO,aAAA,KAAkB,QAAA,IAAY,CAAC,aAAA,EAAe;AACvD,UAAA,MAAM,IAAIC,iBAAA;AAAA,YACR,iIAAiI,IAAA,CAAK,SAAA;AAAA,cACpI;AAAA,aACD,CAAA;AAAA,WACH;AAAA,QACF;AACA,QAAA,YAAA,GAAe,aAAA;AAAA,MACjB;AAEA,MAAA,IAAI,cAAsC,EAAC;AAC3C,MAAA,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,YAAA,IAAgB,MAAA,MAAY,MAAA,EAAQ;AACjD,QAAA,IAAI;AACF,UAAA,WAAA,GAAc,MAAM,GAAA,CAAI,YAAA,CAAa,kBAAA,CAAmB,MAAA,EAAQ;AAAA,YAC9D,GAAA,EAAK,YAAA;AAAA,YACL,SAAA,EAAW,IAAA;AAAA,YACX,MAAM,UAAA,IAAc,KAAA,CAAA;AAAA;AAAA,YAEpB,OAAA,EAAS;AAAA,WACV,CAAA;AAAA,QACH,SAAS,CAAA,EAAG;AACV,UAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,YACT,CAAA,yCAAA,EAA4C,MAAM,CAAA,UAAA,EAAa,YAAY,CAAA,IAAA,EAAOP,uBAAA;AAAA,cAChF;AAAA,aACD,CAAA;AAAA,WACH;AAAA,QACF;AAAA,MACF;AACA,MAAA,MAAM,OAAA,GACJ,IAAI,KAAA,CAAM,YAAA,KAAiB,SACvB,EAAC,GAAA,CAGG,MAAM,OAAA,CAAQ,GAAA;AAAA,QACZ,YAAA,CAAa,GAAA,CAAI,OAAM,IAAA,KAAQ;AAC7B,UAAA,MAAM,SAAS,MAAMQ,kBAAA;AAAA,YACnB,EAAE,MAAM,UAAA,EAAW;AAAA,YACnB,EAAE,MAAA,EAAQ,MAAA,EAAQ,YAAA,EAAc;AAAA,YAChC,GAAA;AAAA,YACA,GAAA,CAAI,MAAA;AAAA,YACJ,WAAA;AAAA,YACA,IAAI,KAAA,CAAM;AAAA,WACZ;AACA,UAAA,OAAO,EAAE,MAAM,MAAA,EAAO;AAAA,QACxB,CAAC;AAAA,OACH,EACA,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,MAAA,KAAW,MAAM,CAAA,CAIjC,GAAA,CAAI,CAAC,EAAE,IAAA,EAAM,MAAA,EAAO,MAAO;AAAA,QAC3B,MAAA;AAAA,QACA,QAAA,EAAU,aACNC,qBAAA,CAAK,KAAA,CAAM,KAAK,UAAA,EAAY,IAAA,CAAK,IAAI,CAAA,GACrC,IAAA,CAAK,IAAA;AAAA,QACT,QAAA,EAAU,QAAA;AAAA,QACV,OAAA,EAAS,IAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,QAAQ,CAAA;AAAA,QACvC,kBAAkB,IAAA,CAAK;AAAA,OACzB,CAAE,CAAA;AAER,MAAA,IAAI,YAAA,GAAe,QAAQ,MAAA,GAAS,CAAA;AAEpC,MAAA,IAAI;AACF,QAAA,MAAM,SAAS,MAAM,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,QAAQ,UAAU,CAAA;AACzD,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,MAAM,aAAA,GAAgB,MAAM,GAAA,CAAI,aAAA,CAAc,GAAA,CAAI;AAAA,YAChD,SAAA,EAAW,MAAA;AAAA,YACX,aAAA,EAAe;AAAA,WAChB,CAAA;AAED,UAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAE5B,YAAA,MAAM,IAAIF,iBAAA;AAAA,cACR,oEAAoE,MAAA,CAAO,OAAO,6DAA6D,aAAA,CAAc,CAAC,EAAE,OAAO,CAAA;AAAA,aACzK;AAAA,UACF,CAAA,MAAO;AAEL,YAAA,MAAM,IAAIA,iBAAA;AAAA,cACR,CAAA,iEAAA,EAAoE,OAAO,OAAO,CAAA,CAAA;AAAA,aACpF;AAAA,UACF;AAAA,QACF;AAEA,QAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,UACT,yBAAyB,UAAU,CAAA,sBAAA;AAAA,SACrC;AAAA,MACF,SAAS,CAAA,EAAG;AACV,QAAA,IAAI,aAAaA,iBAAA,EAAY;AAC3B,UAAA,MAAM,CAAA;AAAA,QACR;AACA,QAAA,YAAA,GAAe,IAAA;AAAA,MACjB;AAEA,MAAA,IAAI,YAAA,EAAc;AAChB,QAAA,IAAI;AACF,UAAA,MAAM,IAAI,QAAA,CAAS,MAAA,CAAO,QAAQ,UAAA,EAAY,MAAA,CAAO,YAAY,CAAC,CAAA;AAAA,QACpE,SAAS,CAAA,EAAG;AACV,UAAA,MAAM,IAAIA,iBAAA;AAAA,YACR,CAAA,iGAAA,EAAoG,UAAU,CAAA,GAAA,EAAMP,uBAAA;AAAA,cAClH;AAAA,aACD,CAAA;AAAA,WACH;AAAA,QACF;AAAA,MACF;AAEA,MAAA,MAAM,IAAI,UAAA,CAAW;AAAA,QACnB,GAAA,EAAK,CAAA,UAAA,EAAa,MAAM,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA;AAAA,QACtC,IAAI,YAAY;AACd,UAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,YAAA,IAAI;AACF,cAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,OAAA,CAAQ,MAAA;AAAA,gBAC/B,MAAA;AAAA,gBACA,UAAA;AAAA,gBACA,KAAA;AAAA,gBACA;AAAA,eACF;AACA,cAAA,OAAO,MAAA,CAAO,EAAA;AAAA,YAChB,SAAS,CAAA,EAAG;AACV,cAAA,MAAM,IAAIO,iBAAA;AAAA,gBACR,CAAA,0BAAA,EAA6B,UAAU,CAAA,qFAAA,EAAwFP,uBAAA;AAAA,kBAC7H;AAAA,iBACD,CAAA;AAAA,eACH;AAAA,YACF;AAAA,UACF;AACA,UAAA,OAAO,IAAA;AAAA,QACT;AAAA,OACD,CAAA;AAED,MAAA,MAAM,EAAE,IAAA,EAAM,QAAA,EAAS,GAAI,MAAM,IAAI,UAAA,CAAW;AAAA,QAC9C,GAAA,EAAK,CAAA,UAAA,EAAa,MAAM,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA;AAAA,QACtC,IAAI,YAAY;AACd,UAAA,IAAI;AACF,YAAA,MAAM,YAAA,GAAe,MAAM,GAAA,CAAI,aAAA,CAAc,MAAA;AAAA,cAC3C,MAAA;AAAA,cACA,UAAA;AAAA,cACA,OAAO,YAAY,CAAA;AAAA,cACnB,KAAA;AAAA,cACA;AAAA,gBACE,WAAA;AAAA,gBACA,kBAAA,EAAoB,qBAChB,kBAAA,GACA,KAAA;AAAA,gBACJ,UAAA;AAAA,gBACA,WAAA;AAAA,gBACA;AAAA;AACF,aACF;AACA,YAAA,OAAO;AAAA,cACL,MAAM,YAAA,CAAa,GAAA;AAAA,cACnB,QAAA,EAAU,YAAA,CAAa,OAAA,IAAW,YAAA,CAAa;AAAA,aACjD;AAAA,UACF,SAAS,CAAA,EAAG;AACV,YAAA,MAAM,IAAIO,iBAAA;AAAA,cACR,CAAA,+BAAA,EAAkCP,uBAAA,CAAgB,CAAC,CAAC,CAAA;AAAA,aACtD;AAAA,UACF;AAAA,QACF;AAAA,OACD,CAAA;AAED,MAAA,MAAM,IAAI,UAAA,CAAW;AAAA,QACnB,GAAA,EAAK,CAAA,2BAAA,EAA8B,MAAM,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA;AAAA,QACvD,IAAI,YAAY;AACd,UAAA,IAAI,GAAA,CAAI,MAAM,gCAAA,EAAkC;AAC9C,YAAA,IAAI;AACF,cAAA,MAAM,6BACJ,MAAM,6BAAA,CAA8B,GAAA,EAAK,IAAA,EAAM,QAAQ,GAAG,CAAA;AAC5D,cAAA,IAAI,0BAAA,CAA2B,SAAS,CAAA,EAAG;AACzC,gBAAA,MAAM,eAAA,uBAAsB,GAAA,CAAI;AAAA,kBAC9B,GAAG,0BAAA;AAAA,kBACH,GAAI,eAAe;AAAC,iBACrB,CAAA;AAED,gBAAA,MAAM,YAAA,GAAe,MAAM,GAAA,CAAI,aAAA,CAAc,IAAA;AAAA,kBAC3C,MAAA;AAAA,kBACA,IAAA;AAAA,kBACA;AAAA,oBACE,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,eAAe;AAAA;AACzC,iBACF;AACA,gBAAA,OAAO;AAAA,kBACL,QAAA,EAAU,YAAA,CAAa,OAAA,IAAW,YAAA,CAAa;AAAA,iBACjD;AAAA,cACF;AAAA,YACF,SAAS,CAAA,EAAG;AACV,cAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,gBACT,CAAA,gDAAA,EAAmDA,uBAAA;AAAA,kBACjD;AAAA,iBACD,CAAA,CAAA;AAAA,eACH;AAAA,YACF;AAAA,UACF;AACA,UAAA,OAAO,EAAE,QAAA,EAAS;AAAA,QACpB;AAAA,OACD,CAAA;AACD,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,MAAM,IAAI,UAAA,CAAW;AAAA,UACnB,GAAA,EAAK,CAAA,cAAA,EAAiB,MAAM,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA;AAAA,UAC1C,IAAI,YAAY;AACd,YAAA,IAAI;AACF,cAAA,MAAM,GAAA,CAAI,aAAA,CAAc,KAAA,CAAM,MAAA,EAAQ,IAAA,EAAM;AAAA,gBAC1C,SAAA,EAAW;AAAA,eACZ,CAAA;AACD,cAAA,OAAO,IAAA;AAAA,YACT,SAAS,CAAA,EAAG;AACV,cAAA,MAAM,IAAIO,iBAAA;AAAA,gBACR,CAAA,sCAAA,EAAyC,IAAI,CAAA,SAAA,EAAYP,uBAAA;AAAA,kBACvD;AAAA,iBACD,CAAA;AAAA,eACH;AAAA,YACF;AAAA,UACF;AAAA,SACD,CAAA;AAAA,MACH;AAEA,MAAA,GAAA,CAAI,MAAA,CAAO,aAAa,MAAM,CAAA;AAC9B,MAAA,GAAA,CAAI,MAAA,CAAO,oBAAoB,YAAY,CAAA;AAC3C,MAAA,GAAA,CAAI,MAAA,CAAO,eAAe,MAAM,CAAA;AAChC,MAAA,GAAA,CAAI,MAAA,CAAO,mBAAmB,QAAkB,CAAA;AAAA,IAClD;AAAA,GACD,CAAA;AACH;;;;"}
|
|
@@ -127,6 +127,25 @@ const examples = [
|
|
|
127
127
|
}
|
|
128
128
|
]
|
|
129
129
|
})
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
description: "Create a merge request that auto-merges when the pipeline succeeds",
|
|
133
|
+
example: yaml__default.default.stringify({
|
|
134
|
+
steps: [
|
|
135
|
+
{
|
|
136
|
+
id: "createMergeRequest",
|
|
137
|
+
action: "publish:gitlab:merge-request",
|
|
138
|
+
name: "Create a Merge Request",
|
|
139
|
+
input: {
|
|
140
|
+
repoUrl: "gitlab.com?repo=repo&owner=owner",
|
|
141
|
+
title: "Create my new MR",
|
|
142
|
+
branchName: "new-mr",
|
|
143
|
+
description: "MR description",
|
|
144
|
+
autoMerge: true
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
})
|
|
130
149
|
}
|
|
131
150
|
];
|
|
132
151
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitlabMergeRequest.examples.cjs.js","sources":["../../src/actions/gitlabMergeRequest.examples.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { TemplateExample } from '@backstage/plugin-scaffolder-node';\nimport yaml from 'yaml';\n\nexport const examples: TemplateExample[] = [\n {\n description: 'Create a merge request with a specific assignee',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n description: 'This MR is really good',\n sourcePath: './path/to/my/changes',\n branchName: 'new-mr',\n assignee: 'my-assignee',\n },\n },\n ],\n }),\n },\n {\n description:\n 'Create a merge request with removal of source branch after merge',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n description: 'This MR is really good',\n sourcePath: './path/to/my/changes',\n branchName: 'new-mr',\n removeSourceBranch: true,\n },\n },\n ],\n }),\n },\n {\n description: 'Create a merge request with a target branch',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n description: 'This MR is really good',\n sourcePath: './path/to/my/changes',\n branchName: 'new-mr',\n targetBranchName: 'test',\n targetPath: 'Subdirectory',\n },\n },\n ],\n }),\n },\n {\n description: 'Create a merge request with a commit action as create',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n branchName: 'new-mr',\n description: 'MR description',\n commitAction: 'create',\n targetPath: 'source',\n },\n },\n ],\n }),\n },\n {\n description: 'Create a merge request with a commit action as delete',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n branchName: 'new-mr',\n description: 'MR description',\n commitAction: 'delete',\n targetPath: 'source',\n },\n },\n ],\n }),\n },\n {\n description: 'Create a merge request with a commit action as update',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n branchName: 'new-mr',\n description: 'MR description',\n commitAction: 'update',\n targetPath: 'source',\n },\n },\n ],\n }),\n },\n];\n"],"names":["yaml"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gitlabMergeRequest.examples.cjs.js","sources":["../../src/actions/gitlabMergeRequest.examples.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { TemplateExample } from '@backstage/plugin-scaffolder-node';\nimport yaml from 'yaml';\n\nexport const examples: TemplateExample[] = [\n {\n description: 'Create a merge request with a specific assignee',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n description: 'This MR is really good',\n sourcePath: './path/to/my/changes',\n branchName: 'new-mr',\n assignee: 'my-assignee',\n },\n },\n ],\n }),\n },\n {\n description:\n 'Create a merge request with removal of source branch after merge',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n description: 'This MR is really good',\n sourcePath: './path/to/my/changes',\n branchName: 'new-mr',\n removeSourceBranch: true,\n },\n },\n ],\n }),\n },\n {\n description: 'Create a merge request with a target branch',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n description: 'This MR is really good',\n sourcePath: './path/to/my/changes',\n branchName: 'new-mr',\n targetBranchName: 'test',\n targetPath: 'Subdirectory',\n },\n },\n ],\n }),\n },\n {\n description: 'Create a merge request with a commit action as create',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n branchName: 'new-mr',\n description: 'MR description',\n commitAction: 'create',\n targetPath: 'source',\n },\n },\n ],\n }),\n },\n {\n description: 'Create a merge request with a commit action as delete',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n branchName: 'new-mr',\n description: 'MR description',\n commitAction: 'delete',\n targetPath: 'source',\n },\n },\n ],\n }),\n },\n {\n description: 'Create a merge request with a commit action as update',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n branchName: 'new-mr',\n description: 'MR description',\n commitAction: 'update',\n targetPath: 'source',\n },\n },\n ],\n }),\n },\n {\n description:\n 'Create a merge request that auto-merges when the pipeline succeeds',\n example: yaml.stringify({\n steps: [\n {\n id: 'createMergeRequest',\n action: 'publish:gitlab:merge-request',\n name: 'Create a Merge Request',\n input: {\n repoUrl: 'gitlab.com?repo=repo&owner=owner',\n title: 'Create my new MR',\n branchName: 'new-mr',\n description: 'MR description',\n autoMerge: true,\n },\n },\n ],\n }),\n },\n];\n"],"names":["yaml"],"mappings":"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"}
|
|
@@ -40,8 +40,6 @@ const createTriggerGitlabPipelineAction = (options) => {
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
async handler(ctx) {
|
|
43
|
-
let pipelineTriggerToken = void 0;
|
|
44
|
-
let pipelineTriggerId = void 0;
|
|
45
43
|
const { repoUrl, projectId, tokenDescription, token, branch, variables } = ctx.input;
|
|
46
44
|
const { host } = util.parseRepoUrl(repoUrl, integrations);
|
|
47
45
|
const api = util.getClient({
|
|
@@ -50,76 +48,41 @@ const createTriggerGitlabPipelineAction = (options) => {
|
|
|
50
48
|
token,
|
|
51
49
|
requireScmUserCredentials
|
|
52
50
|
});
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
tokenDescription
|
|
60
|
-
);
|
|
61
|
-
return {
|
|
62
|
-
pipelineTriggerToken: res.token,
|
|
63
|
-
pipelineTriggerId: res.id
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
}));
|
|
67
|
-
if (!pipelineTriggerToken) {
|
|
68
|
-
ctx.logger.error(
|
|
69
|
-
`Failed to create pipeline token for project ${projectId}.`
|
|
70
|
-
);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
ctx.logger.info(
|
|
74
|
-
`Pipeline token id ${pipelineTriggerId} created for project ${projectId}.`
|
|
75
|
-
);
|
|
76
|
-
const pipelineTriggerResponse = await api.PipelineTriggerTokens.trigger(
|
|
77
|
-
projectId,
|
|
78
|
-
branch,
|
|
79
|
-
pipelineTriggerToken,
|
|
80
|
-
{ variables }
|
|
81
|
-
);
|
|
82
|
-
if (!pipelineTriggerResponse.id) {
|
|
83
|
-
ctx.logger.error(
|
|
84
|
-
`Failed to trigger pipeline for project ${projectId}.`
|
|
51
|
+
const pipelineUrl = await ctx.checkpoint({
|
|
52
|
+
key: `trigger.pipeline.${projectId}.${branch}.${tokenDescription}`,
|
|
53
|
+
fn: async () => {
|
|
54
|
+
const triggerToken = await api.PipelineTriggerTokens.create(
|
|
55
|
+
projectId,
|
|
56
|
+
tokenDescription
|
|
85
57
|
);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
ctx.logger.info(
|
|
89
|
-
`Pipeline id ${pipelineTriggerResponse.id} for project ${projectId} triggered.`
|
|
90
|
-
);
|
|
91
|
-
ctx.output("pipelineUrl", pipelineTriggerResponse.web_url);
|
|
92
|
-
} catch (error) {
|
|
93
|
-
throw new errors.InputError(
|
|
94
|
-
`Failed to trigger Pipeline: ${helpers.getErrorMessage(error)}`
|
|
95
|
-
);
|
|
96
|
-
} finally {
|
|
97
|
-
if (pipelineTriggerId) {
|
|
98
58
|
try {
|
|
99
|
-
await
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
projectId,
|
|
105
|
-
pipelineTriggerId
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
ctx.logger.info(
|
|
111
|
-
// in version 18.0 of gitlab this was also deleting the pipeline
|
|
112
|
-
// this is a problem in gitlab which is fixed in version 18.1
|
|
113
|
-
// https://gitlab.com/gitlab-org/gitlab/-/issues/546669
|
|
114
|
-
`Deleted pipeline trigger token with token id: ${pipelineTriggerId}.`
|
|
115
|
-
);
|
|
116
|
-
} catch (error) {
|
|
117
|
-
ctx.logger.error(
|
|
118
|
-
`Failed to delete pipeline trigger token with token id: ${pipelineTriggerId}.`
|
|
59
|
+
const pipeline = await api.PipelineTriggerTokens.trigger(
|
|
60
|
+
projectId,
|
|
61
|
+
branch,
|
|
62
|
+
triggerToken.token,
|
|
63
|
+
{ variables }
|
|
119
64
|
);
|
|
65
|
+
if (!pipeline.id) {
|
|
66
|
+
throw new errors.InputError(
|
|
67
|
+
`Failed to trigger pipeline for project ${projectId}`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return pipeline.web_url;
|
|
71
|
+
} finally {
|
|
72
|
+
try {
|
|
73
|
+
await api.PipelineTriggerTokens.remove(
|
|
74
|
+
projectId,
|
|
75
|
+
triggerToken.id
|
|
76
|
+
);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
ctx.logger.error(
|
|
79
|
+
`Failed to delete pipeline trigger token ${triggerToken.id}: ${helpers.getErrorMessage(error)}`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
120
82
|
}
|
|
121
83
|
}
|
|
122
|
-
}
|
|
84
|
+
});
|
|
85
|
+
ctx.output("pipelineUrl", pipelineUrl);
|
|
123
86
|
}
|
|
124
87
|
});
|
|
125
88
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitlabPipelineTrigger.cjs.js","sources":["../../src/actions/gitlabPipelineTrigger.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport {\n ExpandedPipelineSchema,\n PipelineTriggerTokenSchema,\n} from '@gitbeaker/rest';\nimport { getClient, parseRepoUrl } from '../util';\nimport { examples } from './gitlabPipelineTrigger.examples';\nimport { getErrorMessage } from './helpers';\n\n/**\n * Creates a `gitlab:pipeline:trigger` Scaffolder action.\n *\n * @param options - Templating configuration.\n * @public\n */\nexport const createTriggerGitlabPipelineAction = (options: {\n integrations: ScmIntegrationRegistry;\n requireScmUserCredentials?: boolean;\n}) => {\n const { integrations, requireScmUserCredentials } = options;\n return createTemplateAction({\n id: 'gitlab:pipeline:trigger',\n description: 'Triggers a GitLab Pipeline.',\n examples,\n schema: {\n input: {\n repoUrl: z =>\n z.string({\n description: `Accepts the format 'gitlab.com?repo=project_name&owner=group_name' where 'project_name' is the repository name and 'group_name' is a group or username`,\n }),\n token: z =>\n z\n .string({\n description: 'The token to use for authorization to GitLab',\n })\n .optional(),\n projectId: z =>\n z.number({\n description: 'Project Id',\n }),\n tokenDescription: z =>\n z.string({\n description: 'Pipeline token description',\n }),\n branch: z =>\n z.string({\n description: 'Project branch',\n }),\n variables: z =>\n z\n .record(z.string(), z.string(), {\n description:\n 'A object/record of key-valued strings containing the pipeline variables.',\n })\n .optional(),\n },\n output: {\n pipelineUrl: z =>\n z.string({\n description: 'Pipeline Url',\n }),\n },\n },\n async handler(ctx) {\n
|
|
1
|
+
{"version":3,"file":"gitlabPipelineTrigger.cjs.js","sources":["../../src/actions/gitlabPipelineTrigger.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { InputError } from '@backstage/errors';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport {\n ExpandedPipelineSchema,\n PipelineTriggerTokenSchema,\n} from '@gitbeaker/rest';\nimport { getClient, parseRepoUrl } from '../util';\nimport { examples } from './gitlabPipelineTrigger.examples';\nimport { getErrorMessage } from './helpers';\n\n/**\n * Creates a `gitlab:pipeline:trigger` Scaffolder action.\n *\n * @param options - Templating configuration.\n * @public\n */\nexport const createTriggerGitlabPipelineAction = (options: {\n integrations: ScmIntegrationRegistry;\n requireScmUserCredentials?: boolean;\n}) => {\n const { integrations, requireScmUserCredentials } = options;\n return createTemplateAction({\n id: 'gitlab:pipeline:trigger',\n description: 'Triggers a GitLab Pipeline.',\n examples,\n schema: {\n input: {\n repoUrl: z =>\n z.string({\n description: `Accepts the format 'gitlab.com?repo=project_name&owner=group_name' where 'project_name' is the repository name and 'group_name' is a group or username`,\n }),\n token: z =>\n z\n .string({\n description: 'The token to use for authorization to GitLab',\n })\n .optional(),\n projectId: z =>\n z.number({\n description: 'Project Id',\n }),\n tokenDescription: z =>\n z.string({\n description: 'Pipeline token description',\n }),\n branch: z =>\n z.string({\n description: 'Project branch',\n }),\n variables: z =>\n z\n .record(z.string(), z.string(), {\n description:\n 'A object/record of key-valued strings containing the pipeline variables.',\n })\n .optional(),\n },\n output: {\n pipelineUrl: z =>\n z.string({\n description: 'Pipeline Url',\n }),\n },\n },\n async handler(ctx) {\n const { repoUrl, projectId, tokenDescription, token, branch, variables } =\n ctx.input;\n\n const { host } = parseRepoUrl(repoUrl, integrations);\n const api = getClient({\n host,\n integrations,\n token,\n requireScmUserCredentials,\n });\n\n const pipelineUrl = await ctx.checkpoint({\n key: `trigger.pipeline.${projectId}.${branch}.${tokenDescription}`,\n fn: async () => {\n const triggerToken = (await api.PipelineTriggerTokens.create(\n projectId,\n tokenDescription,\n )) as PipelineTriggerTokenSchema;\n\n try {\n const pipeline = (await api.PipelineTriggerTokens.trigger(\n projectId,\n branch,\n triggerToken.token,\n { variables },\n )) as ExpandedPipelineSchema;\n\n if (!pipeline.id) {\n throw new InputError(\n `Failed to trigger pipeline for project ${projectId}`,\n );\n }\n\n // Only this non-secret value enters checkpoint state.\n return pipeline.web_url;\n } finally {\n try {\n await api.PipelineTriggerTokens.remove(\n projectId,\n triggerToken.id,\n );\n } catch (error) {\n ctx.logger.error(\n `Failed to delete pipeline trigger token ${\n triggerToken.id\n }: ${getErrorMessage(error)}`,\n );\n }\n }\n },\n });\n\n ctx.output('pipelineUrl', pipelineUrl);\n },\n });\n};\n"],"names":["createTemplateAction","examples","parseRepoUrl","getClient","InputError","getErrorMessage"],"mappings":"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"}
|
|
@@ -68,7 +68,7 @@ const createGitlabProjectVariableAction = (options) => {
|
|
|
68
68
|
requireScmUserCredentials
|
|
69
69
|
});
|
|
70
70
|
await ctx.checkpoint({
|
|
71
|
-
key: `create.project.variables.${projectId}.${key}.${
|
|
71
|
+
key: `create.project.variables.${projectId}.${key}.${environmentScope}`,
|
|
72
72
|
fn: async () => {
|
|
73
73
|
await api.ProjectVariables.create(projectId, key, value, {
|
|
74
74
|
variableType,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitlabProjectVariableCreate.cjs.js","sources":["../../src/actions/gitlabProjectVariableCreate.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { VariableType } from '@gitbeaker/rest';\nimport { getClient, parseRepoUrl } from '../util';\nimport { examples } from './gitlabProjectVariableCreate.examples';\n\n/**\n * Creates a `gitlab:projectVariable:create` Scaffolder action.\n *\n * @param options - Templating configuration.\n * @public\n */\nexport const createGitlabProjectVariableAction = (options: {\n integrations: ScmIntegrationRegistry;\n requireScmUserCredentials?: boolean;\n}) => {\n const { integrations, requireScmUserCredentials } = options;\n return createTemplateAction({\n id: 'gitlab:projectVariable:create',\n examples,\n schema: {\n input: {\n repoUrl: z =>\n z.string({\n description: `Accepts the format 'gitlab.com?repo=project_name&owner=group_name' where 'project_name' is the repository name and 'group_name' is a group or username`,\n }),\n token: z =>\n z\n .string({\n description: 'The token to use for authorization to GitLab',\n })\n .optional(),\n projectId: z =>\n z.union([z.number(), z.string()], {\n description: 'Project ID',\n }),\n key: z =>\n z\n .string({\n description:\n 'The key of a variable; must have no more than 255 characters; only A-Z, a-z, 0-9, and _ are allowed',\n })\n .regex(/^[A-Za-z0-9_]{1,255}$/),\n value: z =>\n z.string({\n description: 'The value of a variable',\n }),\n variableType: z =>\n z.string({\n description: 'Variable Type (env_var or file)',\n }),\n variableProtected: z =>\n z\n .boolean({\n description: 'Whether the variable is protected',\n })\n .default(false)\n .optional(),\n masked: z =>\n z\n .boolean({\n description: 'Whether the variable is masked',\n })\n .default(false)\n .optional(),\n maskedAndHidden: z =>\n z\n .boolean({\n description: 'Whether the variable is masked and hidden',\n })\n .default(false)\n .optional(),\n raw: z =>\n z\n .boolean({\n description: 'Whether the variable is expandable',\n })\n .default(false)\n .optional(),\n environmentScope: z =>\n z\n .string({\n description: 'The environment_scope of the variable',\n })\n .default('*')\n .optional(),\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n projectId,\n key,\n value,\n variableType,\n variableProtected = false,\n masked = false,\n maskedAndHidden = false,\n raw = false,\n environmentScope = '*',\n token,\n } = ctx.input;\n\n const { host } = parseRepoUrl(repoUrl, integrations);\n\n const api = getClient({\n host,\n integrations,\n token,\n requireScmUserCredentials,\n });\n\n await ctx.checkpoint({\n key: `create.project.variables.${projectId}.${key}.${
|
|
1
|
+
{"version":3,"file":"gitlabProjectVariableCreate.cjs.js","sources":["../../src/actions/gitlabProjectVariableCreate.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { VariableType } from '@gitbeaker/rest';\nimport { getClient, parseRepoUrl } from '../util';\nimport { examples } from './gitlabProjectVariableCreate.examples';\n\n/**\n * Creates a `gitlab:projectVariable:create` Scaffolder action.\n *\n * @param options - Templating configuration.\n * @public\n */\nexport const createGitlabProjectVariableAction = (options: {\n integrations: ScmIntegrationRegistry;\n requireScmUserCredentials?: boolean;\n}) => {\n const { integrations, requireScmUserCredentials } = options;\n return createTemplateAction({\n id: 'gitlab:projectVariable:create',\n examples,\n schema: {\n input: {\n repoUrl: z =>\n z.string({\n description: `Accepts the format 'gitlab.com?repo=project_name&owner=group_name' where 'project_name' is the repository name and 'group_name' is a group or username`,\n }),\n token: z =>\n z\n .string({\n description: 'The token to use for authorization to GitLab',\n })\n .optional(),\n projectId: z =>\n z.union([z.number(), z.string()], {\n description: 'Project ID',\n }),\n key: z =>\n z\n .string({\n description:\n 'The key of a variable; must have no more than 255 characters; only A-Z, a-z, 0-9, and _ are allowed',\n })\n .regex(/^[A-Za-z0-9_]{1,255}$/),\n value: z =>\n z.string({\n description: 'The value of a variable',\n }),\n variableType: z =>\n z.string({\n description: 'Variable Type (env_var or file)',\n }),\n variableProtected: z =>\n z\n .boolean({\n description: 'Whether the variable is protected',\n })\n .default(false)\n .optional(),\n masked: z =>\n z\n .boolean({\n description: 'Whether the variable is masked',\n })\n .default(false)\n .optional(),\n maskedAndHidden: z =>\n z\n .boolean({\n description: 'Whether the variable is masked and hidden',\n })\n .default(false)\n .optional(),\n raw: z =>\n z\n .boolean({\n description: 'Whether the variable is expandable',\n })\n .default(false)\n .optional(),\n environmentScope: z =>\n z\n .string({\n description: 'The environment_scope of the variable',\n })\n .default('*')\n .optional(),\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n projectId,\n key,\n value,\n variableType,\n variableProtected = false,\n masked = false,\n maskedAndHidden = false,\n raw = false,\n environmentScope = '*',\n token,\n } = ctx.input;\n\n const { host } = parseRepoUrl(repoUrl, integrations);\n\n const api = getClient({\n host,\n integrations,\n token,\n requireScmUserCredentials,\n });\n\n await ctx.checkpoint({\n key: `create.project.variables.${projectId}.${key}.${environmentScope}`,\n fn: async () => {\n await api.ProjectVariables.create(projectId, key, value, {\n variableType: variableType as VariableType,\n protected: variableProtected,\n masked,\n masked_and_hidden: maskedAndHidden,\n raw,\n environmentScope,\n });\n },\n });\n },\n });\n};\n"],"names":["createTemplateAction","examples","parseRepoUrl","getClient"],"mappings":"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"}
|
|
@@ -52,8 +52,8 @@ const createGitlabRepoPushAction = (options) => {
|
|
|
52
52
|
description: "Gitlab Project path"
|
|
53
53
|
}),
|
|
54
54
|
commitHash: (z) => z.string({
|
|
55
|
-
description: "The git commit hash of the commit"
|
|
56
|
-
})
|
|
55
|
+
description: "The git commit hash of the commit, or omitted when there were no file changes to commit and `allowEmpty` is not true (covers both the default of unset and an explicit `false`)."
|
|
56
|
+
}).optional()
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
async handler(ctx) {
|
|
@@ -89,7 +89,9 @@ const createGitlabRepoPushAction = (options) => {
|
|
|
89
89
|
remoteFiles = await api.Repositories.allRepositoryTrees(repoID, {
|
|
90
90
|
ref: branchName,
|
|
91
91
|
recursive: true,
|
|
92
|
-
path: targetPath ?? void 0
|
|
92
|
+
path: targetPath ?? void 0,
|
|
93
|
+
// Pages are walked serially via the Link header, and GitLab's default is 20.
|
|
94
|
+
perPage: 100
|
|
93
95
|
});
|
|
94
96
|
} catch (e) {
|
|
95
97
|
ctx.logger.warn(
|
|
@@ -149,6 +151,14 @@ const createGitlabRepoPushAction = (options) => {
|
|
|
149
151
|
);
|
|
150
152
|
}
|
|
151
153
|
}
|
|
154
|
+
if (actions.length === 0 && !allowEmpty) {
|
|
155
|
+
ctx.logger.warn(
|
|
156
|
+
`No file changes to commit to ${repoID} on branch '${branchName}'; skipping commit. Set 'allowEmpty: true' to create an empty commit.`
|
|
157
|
+
);
|
|
158
|
+
ctx.output("projectid", repoID);
|
|
159
|
+
ctx.output("projectPath", repoID);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
152
162
|
try {
|
|
153
163
|
const commitId = await ctx.checkpoint({
|
|
154
164
|
key: `commit.create.${repoID}.${branchName}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitlabRepoPush.cjs.js","sources":["../../src/actions/gitlabRepoPush.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport path from 'node:path';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { InputError } from '@backstage/errors';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport {\n createTemplateAction,\n parseRepoUrl,\n serializeDirectoryContents,\n} from '@backstage/plugin-scaffolder-node';\nimport { CommitAction } from '@gitbeaker/rest';\nimport { createGitlabApi, getErrorMessage } from './helpers';\nimport { examples } from './gitlabRepoPush.examples';\nimport { getFileAction } from '../util';\nimport { SerializedFile } from '@backstage/plugin-scaffolder-node';\nimport { RepositoryTreeSchema } from '@gitbeaker/rest';\n\n/**\n * Create a new action that commits into a gitlab repository.\n *\n * @public\n */\nexport const createGitlabRepoPushAction = (options: {\n integrations: ScmIntegrationRegistry;\n requireScmUserCredentials?: boolean;\n}) => {\n const { integrations, requireScmUserCredentials } = options;\n\n return createTemplateAction({\n id: 'gitlab:repo:push',\n examples,\n schema: {\n input: {\n repoUrl: z =>\n z.string({\n description: `Accepts the format 'gitlab.com?repo=project_name&owner=group_name' where 'project_name' is the repository name and 'group_name' is a group or username`,\n }),\n branchName: z =>\n z.string({\n description: 'The branch name for the commit',\n }),\n commitMessage: z =>\n z.string({\n description: `The commit message`,\n }),\n sourcePath: z =>\n z\n .string({\n description:\n 'Subdirectory of working directory to copy changes from',\n })\n .optional(),\n targetPath: z =>\n z\n .string({\n description: 'Subdirectory of repository to apply changes to',\n })\n .optional(),\n token: z =>\n z\n .string({\n description: 'The token to use for authorization to GitLab',\n })\n .optional(),\n commitAction: z =>\n z\n .enum(['create', 'update', 'delete', 'auto'], {\n description:\n 'The action to be used for git commit. Defaults to create, but can be set to update or delete',\n })\n .optional(),\n allowEmpty: z =>\n z\n .boolean({\n description: 'Allow an empty commit to be created.',\n })\n .optional(),\n },\n output: {\n projectid: z =>\n z.string({\n description: 'Gitlab Project id/Name(slug)',\n }),\n projectPath: z =>\n z.string({\n description: 'Gitlab Project path',\n }),\n commitHash: z =>\n z.string({\n description: 'The git commit hash of the commit',\n }),\n },\n },\n async handler(ctx) {\n const {\n branchName,\n repoUrl,\n targetPath,\n sourcePath,\n token,\n commitAction,\n allowEmpty,\n } = ctx.input;\n\n const { owner, repo, project } = parseRepoUrl(repoUrl, integrations);\n const repoID = project ? project : `${owner}/${repo}`;\n\n const api = createGitlabApi({\n integrations,\n token,\n repoUrl,\n requireScmUserCredentials,\n });\n\n let fileRoot: string;\n if (sourcePath) {\n fileRoot = resolveSafeChildPath(ctx.workspacePath, sourcePath);\n } else {\n fileRoot = ctx.workspacePath;\n }\n\n const fileContents = await serializeDirectoryContents(fileRoot, {\n gitignore: true,\n });\n\n let remoteFiles: RepositoryTreeSchema[] = [];\n if ((ctx.input.commitAction ?? 'auto') === 'auto') {\n try {\n remoteFiles = await api.Repositories.allRepositoryTrees(repoID, {\n ref: branchName,\n recursive: true,\n path: targetPath ?? undefined,\n });\n } catch (e) {\n ctx.logger.warn(\n `Could not retrieve the list of files for ${repoID} (branch: ${branchName}) : ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n\n const fileActionMap: {\n file: SerializedFile;\n action: 'create' | 'delete' | 'update' | 'skip';\n }[] = [];\n for (const file of fileContents) {\n const action = await getFileAction(\n { file, targetPath },\n { repoID, branch: branchName },\n api,\n ctx.logger,\n remoteFiles,\n ctx.input.commitAction,\n );\n fileActionMap.push({ file, action });\n }\n\n const actions: CommitAction[] = fileActionMap\n .filter(o => o.action !== 'skip')\n .map(({ file, action }) => ({\n action: action as CommitAction['action'],\n filePath: targetPath\n ? path.posix.join(targetPath, file.path)\n : file.path,\n encoding: 'base64',\n content: file.content.toString('base64'),\n execute_filemode: file.executable,\n }));\n\n const branchExists = await ctx.checkpoint({\n key: `branch.exists.${repoID}.${branchName}`,\n fn: async () => {\n try {\n await api.Branches.show(repoID, branchName);\n return true;\n } catch (e: any) {\n if (e.cause?.response?.status !== 404) {\n throw new InputError(\n `Failed to check status of branch '${branchName}'. Please make sure that branch already exists or Backstage has permissions to create one. ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n return false;\n },\n });\n\n if (!branchExists) {\n // create a branch using the default branch as ref\n try {\n const projects = await api.Projects.show(repoID);\n const { default_branch: defaultBranch } = projects;\n await api.Branches.create(repoID, branchName, String(defaultBranch));\n } catch (e) {\n throw new InputError(\n `The branch '${branchName}' was not found and creation failed with error. Please make sure that branch already exists or Backstage has permissions to create one. ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n\n try {\n const commitId = await ctx.checkpoint({\n key: `commit.create.${repoID}.${branchName}`,\n fn: async () => {\n const commit =\n allowEmpty !== undefined\n ? await api.Commits.create(\n repoID,\n branchName,\n ctx.input.commitMessage,\n actions,\n { allowEmpty } as any,\n )\n : await api.Commits.create(\n repoID,\n branchName,\n ctx.input.commitMessage,\n actions,\n );\n return commit.id;\n },\n });\n\n ctx.output('projectid', repoID);\n ctx.output('projectPath', repoID);\n ctx.output('commitHash', commitId);\n } catch (e) {\n if (commitAction !== 'create') {\n throw new InputError(\n `Committing the changes to ${branchName} failed. Please verify that all files you're trying to modify exist in the repository. ${getErrorMessage(\n e,\n )}`,\n );\n }\n throw new InputError(\n `Committing the changes to ${branchName} failed. Please check that none of the files created by the template already exists. ${getErrorMessage(\n e,\n )}`,\n );\n }\n },\n });\n};\n"],"names":["createTemplateAction","examples","parseRepoUrl","createGitlabApi","resolveSafeChildPath","serializeDirectoryContents","getErrorMessage","getFileAction","path","InputError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gitlabRepoPush.cjs.js","sources":["../../src/actions/gitlabRepoPush.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport path from 'node:path';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { InputError } from '@backstage/errors';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport {\n createTemplateAction,\n parseRepoUrl,\n serializeDirectoryContents,\n} from '@backstage/plugin-scaffolder-node';\nimport { CommitAction } from '@gitbeaker/rest';\nimport { createGitlabApi, getErrorMessage } from './helpers';\nimport { examples } from './gitlabRepoPush.examples';\nimport { getFileAction } from '../util';\nimport { SerializedFile } from '@backstage/plugin-scaffolder-node';\nimport { RepositoryTreeSchema } from '@gitbeaker/rest';\n\n/**\n * Create a new action that commits into a gitlab repository.\n *\n * @public\n */\nexport const createGitlabRepoPushAction = (options: {\n integrations: ScmIntegrationRegistry;\n requireScmUserCredentials?: boolean;\n}) => {\n const { integrations, requireScmUserCredentials } = options;\n\n return createTemplateAction({\n id: 'gitlab:repo:push',\n examples,\n schema: {\n input: {\n repoUrl: z =>\n z.string({\n description: `Accepts the format 'gitlab.com?repo=project_name&owner=group_name' where 'project_name' is the repository name and 'group_name' is a group or username`,\n }),\n branchName: z =>\n z.string({\n description: 'The branch name for the commit',\n }),\n commitMessage: z =>\n z.string({\n description: `The commit message`,\n }),\n sourcePath: z =>\n z\n .string({\n description:\n 'Subdirectory of working directory to copy changes from',\n })\n .optional(),\n targetPath: z =>\n z\n .string({\n description: 'Subdirectory of repository to apply changes to',\n })\n .optional(),\n token: z =>\n z\n .string({\n description: 'The token to use for authorization to GitLab',\n })\n .optional(),\n commitAction: z =>\n z\n .enum(['create', 'update', 'delete', 'auto'], {\n description:\n 'The action to be used for git commit. Defaults to create, but can be set to update or delete',\n })\n .optional(),\n allowEmpty: z =>\n z\n .boolean({\n description: 'Allow an empty commit to be created.',\n })\n .optional(),\n },\n output: {\n projectid: z =>\n z.string({\n description: 'Gitlab Project id/Name(slug)',\n }),\n projectPath: z =>\n z.string({\n description: 'Gitlab Project path',\n }),\n commitHash: z =>\n z\n .string({\n description:\n 'The git commit hash of the commit, or omitted when there were no file changes to commit and `allowEmpty` is not true (covers both the default of unset and an explicit `false`).',\n })\n .optional(),\n },\n },\n async handler(ctx) {\n const {\n branchName,\n repoUrl,\n targetPath,\n sourcePath,\n token,\n commitAction,\n allowEmpty,\n } = ctx.input;\n\n const { owner, repo, project } = parseRepoUrl(repoUrl, integrations);\n const repoID = project ? project : `${owner}/${repo}`;\n\n const api = createGitlabApi({\n integrations,\n token,\n repoUrl,\n requireScmUserCredentials,\n });\n\n let fileRoot: string;\n if (sourcePath) {\n fileRoot = resolveSafeChildPath(ctx.workspacePath, sourcePath);\n } else {\n fileRoot = ctx.workspacePath;\n }\n\n const fileContents = await serializeDirectoryContents(fileRoot, {\n gitignore: true,\n });\n\n let remoteFiles: RepositoryTreeSchema[] = [];\n if ((ctx.input.commitAction ?? 'auto') === 'auto') {\n try {\n remoteFiles = await api.Repositories.allRepositoryTrees(repoID, {\n ref: branchName,\n recursive: true,\n path: targetPath ?? undefined,\n // Pages are walked serially via the Link header, and GitLab's default is 20.\n perPage: 100,\n });\n } catch (e) {\n ctx.logger.warn(\n `Could not retrieve the list of files for ${repoID} (branch: ${branchName}) : ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n\n const fileActionMap: {\n file: SerializedFile;\n action: 'create' | 'delete' | 'update' | 'skip';\n }[] = [];\n for (const file of fileContents) {\n const action = await getFileAction(\n { file, targetPath },\n { repoID, branch: branchName },\n api,\n ctx.logger,\n remoteFiles,\n ctx.input.commitAction,\n );\n fileActionMap.push({ file, action });\n }\n\n const actions: CommitAction[] = fileActionMap\n .filter(o => o.action !== 'skip')\n .map(({ file, action }) => ({\n action: action as CommitAction['action'],\n filePath: targetPath\n ? path.posix.join(targetPath, file.path)\n : file.path,\n encoding: 'base64',\n content: file.content.toString('base64'),\n execute_filemode: file.executable,\n }));\n\n const branchExists = await ctx.checkpoint({\n key: `branch.exists.${repoID}.${branchName}`,\n fn: async () => {\n try {\n await api.Branches.show(repoID, branchName);\n return true;\n } catch (e: any) {\n if (e.cause?.response?.status !== 404) {\n throw new InputError(\n `Failed to check status of branch '${branchName}'. Please make sure that branch already exists or Backstage has permissions to create one. ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n return false;\n },\n });\n\n if (!branchExists) {\n // create a branch using the default branch as ref\n try {\n const projects = await api.Projects.show(repoID);\n const { default_branch: defaultBranch } = projects;\n await api.Branches.create(repoID, branchName, String(defaultBranch));\n } catch (e) {\n throw new InputError(\n `The branch '${branchName}' was not found and creation failed with error. Please make sure that branch already exists or Backstage has permissions to create one. ${getErrorMessage(\n e,\n )}`,\n );\n }\n }\n\n if (actions.length === 0 && !allowEmpty) {\n ctx.logger.warn(\n `No file changes to commit to ${repoID} on branch '${branchName}'; skipping commit. Set 'allowEmpty: true' to create an empty commit.`,\n );\n ctx.output('projectid', repoID);\n ctx.output('projectPath', repoID);\n return;\n }\n\n try {\n const commitId = await ctx.checkpoint({\n key: `commit.create.${repoID}.${branchName}`,\n fn: async () => {\n const commit =\n allowEmpty !== undefined\n ? await api.Commits.create(\n repoID,\n branchName,\n ctx.input.commitMessage,\n actions,\n { allowEmpty } as any,\n )\n : await api.Commits.create(\n repoID,\n branchName,\n ctx.input.commitMessage,\n actions,\n );\n return commit.id;\n },\n });\n\n ctx.output('projectid', repoID);\n ctx.output('projectPath', repoID);\n ctx.output('commitHash', commitId);\n } catch (e) {\n if (commitAction !== 'create') {\n throw new InputError(\n `Committing the changes to ${branchName} failed. Please verify that all files you're trying to modify exist in the repository. ${getErrorMessage(\n e,\n )}`,\n );\n }\n throw new InputError(\n `Committing the changes to ${branchName} failed. Please check that none of the files created by the template already exists. ${getErrorMessage(\n e,\n )}`,\n );\n }\n },\n });\n};\n"],"names":["createTemplateAction","examples","parseRepoUrl","createGitlabApi","resolveSafeChildPath","serializeDirectoryContents","getErrorMessage","getFileAction","path","InputError"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -203,6 +203,7 @@ declare const createPublishGitlabMergeRequestAction: (options: {
|
|
|
203
203
|
reviewers?: string[] | undefined;
|
|
204
204
|
assignReviewersFromApprovalRules?: boolean | undefined;
|
|
205
205
|
labels?: string | string[] | undefined;
|
|
206
|
+
autoMerge?: boolean | undefined;
|
|
206
207
|
}, {
|
|
207
208
|
targetBranchName: string;
|
|
208
209
|
projectid: string;
|
|
@@ -317,7 +318,7 @@ declare const createGitlabRepoPushAction: (options: {
|
|
|
317
318
|
}, {
|
|
318
319
|
projectid: string;
|
|
319
320
|
projectPath: string;
|
|
320
|
-
commitHash
|
|
321
|
+
commitHash?: string | undefined;
|
|
321
322
|
}, "v2">;
|
|
322
323
|
|
|
323
324
|
/**
|
package/dist/util.cjs.js
CHANGED
|
@@ -136,10 +136,27 @@ function computeSha256(file) {
|
|
|
136
136
|
hash.update(file.content);
|
|
137
137
|
return hash.digest("hex");
|
|
138
138
|
}
|
|
139
|
+
function blobIdAlgorithm(id) {
|
|
140
|
+
if (typeof id !== "string") return void 0;
|
|
141
|
+
if (/^[0-9a-f]{40}$/.test(id)) return "sha1";
|
|
142
|
+
if (/^[0-9a-f]{64}$/.test(id)) return "sha256";
|
|
143
|
+
return void 0;
|
|
144
|
+
}
|
|
145
|
+
function computeGitBlobId(file, algorithm) {
|
|
146
|
+
const hash = node_crypto.createHash(algorithm);
|
|
147
|
+
hash.update(`blob ${file.content.length}\0`);
|
|
148
|
+
hash.update(file.content);
|
|
149
|
+
return hash.digest("hex");
|
|
150
|
+
}
|
|
139
151
|
async function getFileAction(fileInfo, target, api, logger, remoteFiles, defaultCommitAction = "auto") {
|
|
140
152
|
if (defaultCommitAction === "auto") {
|
|
141
153
|
const filePath = path__default.default.join(fileInfo.targetPath ?? "", fileInfo.file.path);
|
|
142
|
-
|
|
154
|
+
const remoteFile = remoteFiles?.find((entry) => entry.path === filePath);
|
|
155
|
+
if (remoteFile) {
|
|
156
|
+
const algorithm = blobIdAlgorithm(remoteFile.id);
|
|
157
|
+
if (algorithm) {
|
|
158
|
+
return computeGitBlobId(fileInfo.file, algorithm) === remoteFile.id ? "skip" : "update";
|
|
159
|
+
}
|
|
143
160
|
try {
|
|
144
161
|
const targetFile = await api.RepositoryFiles.show(
|
|
145
162
|
target.repoID,
|
package/dist/util.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.cjs.js","sources":["../src/util.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { InputError } from '@backstage/errors';\nimport {\n GitLabIntegration,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { Gitlab, GroupSchema, RepositoryTreeSchema } from '@gitbeaker/rest';\nimport { z } from 'zod/v3';\nimport commonGitlabConfig from './commonGitlabConfig';\n\nimport { SerializedFile } from '@backstage/plugin-scaffolder-node';\n\nimport { createHash } from 'node:crypto';\nimport path from 'node:path';\n\nexport const parseRepoHost = (repoUrl: string): string => {\n let parsed;\n try {\n parsed = new URL(`https://${repoUrl}`);\n } catch (error) {\n throw new InputError(\n `Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`,\n );\n }\n return parsed.host;\n};\n\nexport const getToken = (\n config: z.infer<typeof commonGitlabConfig>,\n integrations: ScmIntegrationRegistry,\n requireScmUserCredentials = false,\n): { token: string; integrationConfig: GitLabIntegration } => {\n const host = parseRepoHost(config.repoUrl);\n const integrationConfig = integrations.gitlab.byHost(host);\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (requireScmUserCredentials && !config.token) {\n throw new InputError(\n `No user credentials provided for host ${host}, but scaffolder.requireScmUserCredentials is enabled`,\n );\n }\n\n const token = config.token || integrationConfig.config.token!;\n\n return { token: token, integrationConfig: integrationConfig };\n};\n\nexport type RepoSpec = {\n repo: string;\n host: string;\n owner?: string;\n};\n\nexport const parseRepoUrl = (\n repoUrl: string,\n integrations: ScmIntegrationRegistry,\n): RepoSpec => {\n let parsed;\n try {\n parsed = new URL(`https://${repoUrl}`);\n } catch (error) {\n throw new InputError(\n `Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`,\n );\n }\n const host = parsed.host;\n const owner = parsed.searchParams.get('owner') ?? undefined;\n const repo: string = parsed.searchParams.get('repo')!;\n\n const type = integrations.byHost(host)?.type;\n\n if (!type) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n return { host, owner, repo };\n};\n\nexport function getClient(props: {\n host: string;\n token?: string;\n integrations: ScmIntegrationRegistry;\n requireScmUserCredentials?: boolean;\n}): InstanceType<typeof Gitlab> {\n const { host, token, integrations, requireScmUserCredentials } = props;\n const integrationConfig = integrations.gitlab.byHost(host);\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (requireScmUserCredentials && !token) {\n throw new InputError(\n `No user credentials provided for host ${host}, but scaffolder.requireScmUserCredentials is enabled`,\n );\n }\n\n const { config } = integrationConfig;\n\n if (!config.token && !token) {\n throw new InputError(`No token available for host ${host}`);\n }\n\n const requestToken = token || config.token!;\n const tokenType = token ? 'oauthToken' : 'token';\n\n const gitlabOptions: any = {\n host: config.baseUrl,\n };\n\n gitlabOptions[tokenType] = requestToken;\n return new Gitlab(gitlabOptions);\n}\n\nexport function convertDate(\n inputDate: string | undefined,\n defaultDate: string,\n) {\n try {\n return inputDate\n ? new Date(inputDate).toISOString()\n : new Date(defaultDate).toISOString();\n } catch (error) {\n throw new InputError(`Error converting input date - ${error}`);\n }\n}\n\nexport async function getTopLevelParentGroup(\n client: InstanceType<typeof Gitlab>,\n groupId: number,\n): Promise<GroupSchema> {\n try {\n const topParentGroup = await client.Groups.show(groupId);\n if (topParentGroup.parent_id) {\n return getTopLevelParentGroup(client, topParentGroup.parent_id as number);\n }\n return topParentGroup as GroupSchema;\n } catch (error: any) {\n throw new InputError(\n `Error finding top-level parent group ID: ${error.message}`,\n );\n }\n}\n\nexport async function checkEpicScope(\n client: InstanceType<typeof Gitlab>,\n projectId: number,\n epicId: number,\n) {\n try {\n // If project exists, get the top level group id\n const project = await client.Projects.show(projectId);\n if (!project) {\n throw new InputError(\n `Project with id ${projectId} not found. Check your GitLab instance.`,\n );\n }\n const topParentGroup = await getTopLevelParentGroup(\n client,\n project.namespace.id,\n );\n if (!topParentGroup) {\n throw new InputError(`Couldn't find a suitable top-level parent group.`);\n }\n // Get the epic\n const epic = (await client.Epics.all(topParentGroup.id)).find(\n (x: any) => x.id === epicId,\n );\n if (!epic) {\n throw new InputError(\n `Epic with id ${epicId} not found in the top-level parent group ${topParentGroup.name}.`,\n );\n }\n\n const epicGroup = await client.Groups.show(epic.group_id as number);\n const projectNamespace: string = project.path_with_namespace as string;\n return projectNamespace.startsWith(epicGroup.full_path as string);\n } catch (error: any) {\n throw new InputError(`Could not find epic scope: ${error.message}`);\n }\n}\n\nfunction computeSha256(file: SerializedFile): string {\n const hash = createHash('sha256');\n hash.update(file.content);\n return hash.digest('hex');\n}\n\nexport async function getFileAction(\n fileInfo: { file: SerializedFile; targetPath?: string },\n target: { repoID: string; branch: string },\n api: InstanceType<typeof Gitlab>,\n logger: LoggerService,\n remoteFiles: RepositoryTreeSchema[],\n defaultCommitAction:\n | 'create'\n | 'delete'\n | 'update'\n | 'skip'\n | 'auto' = 'auto',\n): Promise<'create' | 'delete' | 'update' | 'skip'> {\n if (defaultCommitAction === 'auto') {\n const filePath = path.join(fileInfo.targetPath ?? '', fileInfo.file.path);\n\n if (remoteFiles?.some(remoteFile => remoteFile.path === filePath)) {\n try {\n const targetFile = await api.RepositoryFiles.show(\n target.repoID,\n filePath,\n target.branch,\n );\n if (computeSha256(fileInfo.file) === targetFile.content_sha256) {\n return 'skip';\n }\n } catch (error) {\n logger.warn(\n `Unable to retrieve detailed information for remote file ${filePath}`,\n );\n }\n return 'update';\n }\n return 'create';\n }\n return defaultCommitAction;\n}\n"],"names":["InputError","Gitlab","createHash","path"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"util.cjs.js","sources":["../src/util.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { InputError } from '@backstage/errors';\nimport {\n GitLabIntegration,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { Gitlab, GroupSchema, RepositoryTreeSchema } from '@gitbeaker/rest';\nimport { z } from 'zod/v3';\nimport commonGitlabConfig from './commonGitlabConfig';\n\nimport { SerializedFile } from '@backstage/plugin-scaffolder-node';\n\nimport { createHash } from 'node:crypto';\nimport path from 'node:path';\n\nexport const parseRepoHost = (repoUrl: string): string => {\n let parsed;\n try {\n parsed = new URL(`https://${repoUrl}`);\n } catch (error) {\n throw new InputError(\n `Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`,\n );\n }\n return parsed.host;\n};\n\nexport const getToken = (\n config: z.infer<typeof commonGitlabConfig>,\n integrations: ScmIntegrationRegistry,\n requireScmUserCredentials = false,\n): { token: string; integrationConfig: GitLabIntegration } => {\n const host = parseRepoHost(config.repoUrl);\n const integrationConfig = integrations.gitlab.byHost(host);\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (requireScmUserCredentials && !config.token) {\n throw new InputError(\n `No user credentials provided for host ${host}, but scaffolder.requireScmUserCredentials is enabled`,\n );\n }\n\n const token = config.token || integrationConfig.config.token!;\n\n return { token: token, integrationConfig: integrationConfig };\n};\n\nexport type RepoSpec = {\n repo: string;\n host: string;\n owner?: string;\n};\n\nexport const parseRepoUrl = (\n repoUrl: string,\n integrations: ScmIntegrationRegistry,\n): RepoSpec => {\n let parsed;\n try {\n parsed = new URL(`https://${repoUrl}`);\n } catch (error) {\n throw new InputError(\n `Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`,\n );\n }\n const host = parsed.host;\n const owner = parsed.searchParams.get('owner') ?? undefined;\n const repo: string = parsed.searchParams.get('repo')!;\n\n const type = integrations.byHost(host)?.type;\n\n if (!type) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n return { host, owner, repo };\n};\n\nexport function getClient(props: {\n host: string;\n token?: string;\n integrations: ScmIntegrationRegistry;\n requireScmUserCredentials?: boolean;\n}): InstanceType<typeof Gitlab> {\n const { host, token, integrations, requireScmUserCredentials } = props;\n const integrationConfig = integrations.gitlab.byHost(host);\n\n if (!integrationConfig) {\n throw new InputError(\n `No matching integration configuration for host ${host}, please check your integrations config`,\n );\n }\n\n if (requireScmUserCredentials && !token) {\n throw new InputError(\n `No user credentials provided for host ${host}, but scaffolder.requireScmUserCredentials is enabled`,\n );\n }\n\n const { config } = integrationConfig;\n\n if (!config.token && !token) {\n throw new InputError(`No token available for host ${host}`);\n }\n\n const requestToken = token || config.token!;\n const tokenType = token ? 'oauthToken' : 'token';\n\n const gitlabOptions: any = {\n host: config.baseUrl,\n };\n\n gitlabOptions[tokenType] = requestToken;\n return new Gitlab(gitlabOptions);\n}\n\nexport function convertDate(\n inputDate: string | undefined,\n defaultDate: string,\n) {\n try {\n return inputDate\n ? new Date(inputDate).toISOString()\n : new Date(defaultDate).toISOString();\n } catch (error) {\n throw new InputError(`Error converting input date - ${error}`);\n }\n}\n\nexport async function getTopLevelParentGroup(\n client: InstanceType<typeof Gitlab>,\n groupId: number,\n): Promise<GroupSchema> {\n try {\n const topParentGroup = await client.Groups.show(groupId);\n if (topParentGroup.parent_id) {\n return getTopLevelParentGroup(client, topParentGroup.parent_id as number);\n }\n return topParentGroup as GroupSchema;\n } catch (error: any) {\n throw new InputError(\n `Error finding top-level parent group ID: ${error.message}`,\n );\n }\n}\n\nexport async function checkEpicScope(\n client: InstanceType<typeof Gitlab>,\n projectId: number,\n epicId: number,\n) {\n try {\n // If project exists, get the top level group id\n const project = await client.Projects.show(projectId);\n if (!project) {\n throw new InputError(\n `Project with id ${projectId} not found. Check your GitLab instance.`,\n );\n }\n const topParentGroup = await getTopLevelParentGroup(\n client,\n project.namespace.id,\n );\n if (!topParentGroup) {\n throw new InputError(`Couldn't find a suitable top-level parent group.`);\n }\n // Get the epic\n const epic = (await client.Epics.all(topParentGroup.id)).find(\n (x: any) => x.id === epicId,\n );\n if (!epic) {\n throw new InputError(\n `Epic with id ${epicId} not found in the top-level parent group ${topParentGroup.name}.`,\n );\n }\n\n const epicGroup = await client.Groups.show(epic.group_id as number);\n const projectNamespace: string = project.path_with_namespace as string;\n return projectNamespace.startsWith(epicGroup.full_path as string);\n } catch (error: any) {\n throw new InputError(`Could not find epic scope: ${error.message}`);\n }\n}\n\nfunction computeSha256(file: SerializedFile): string {\n const hash = createHash('sha256');\n hash.update(file.content);\n return hash.digest('hex');\n}\n\n/**\n * The hash a repository uses for its object ids, derived from the width of one of them. Git's\n * default object format is sha1; repositories created with `--object-format=sha256` use sha256.\n */\nfunction blobIdAlgorithm(id: unknown): 'sha1' | 'sha256' | undefined {\n if (typeof id !== 'string') return undefined;\n if (/^[0-9a-f]{40}$/.test(id)) return 'sha1';\n if (/^[0-9a-f]{64}$/.test(id)) return 'sha256';\n return undefined;\n}\n\n/** A file's git object id: hash of `blob <byte length>\\0` followed by its contents. */\nfunction computeGitBlobId(\n file: SerializedFile,\n algorithm: 'sha1' | 'sha256',\n): string {\n const hash = createHash(algorithm);\n hash.update(`blob ${file.content.length}\\0`);\n hash.update(file.content);\n return hash.digest('hex');\n}\n\nexport async function getFileAction(\n fileInfo: { file: SerializedFile; targetPath?: string },\n target: { repoID: string; branch: string },\n api: InstanceType<typeof Gitlab>,\n logger: LoggerService,\n remoteFiles: RepositoryTreeSchema[],\n defaultCommitAction:\n | 'create'\n | 'delete'\n | 'update'\n | 'skip'\n | 'auto' = 'auto',\n): Promise<'create' | 'delete' | 'update' | 'skip'> {\n if (defaultCommitAction === 'auto') {\n const filePath = path.join(fileInfo.targetPath ?? '', fileInfo.file.path);\n\n const remoteFile = remoteFiles?.find(entry => entry.path === filePath);\n\n if (remoteFile) {\n // The tree listing already carries every blob's object id, so an unchanged file can be\n // recognised without fetching its contents. Fall through to the request below only if\n // the id isn't one we can compare against.\n const algorithm = blobIdAlgorithm(remoteFile.id);\n if (algorithm) {\n return computeGitBlobId(fileInfo.file, algorithm) === remoteFile.id\n ? 'skip'\n : 'update';\n }\n\n try {\n const targetFile = await api.RepositoryFiles.show(\n target.repoID,\n filePath,\n target.branch,\n );\n if (computeSha256(fileInfo.file) === targetFile.content_sha256) {\n return 'skip';\n }\n } catch (error) {\n logger.warn(\n `Unable to retrieve detailed information for remote file ${filePath}`,\n );\n }\n return 'update';\n }\n return 'create';\n }\n return defaultCommitAction;\n}\n"],"names":["InputError","Gitlab","createHash","path"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-scaffolder-backend-module-gitlab",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.11-next.2",
|
|
4
4
|
"backstage": {
|
|
5
5
|
"role": "backend-plugin-module",
|
|
6
6
|
"pluginId": "scaffolder",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"test": "backstage-cli package test"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@backstage/backend-plugin-api": "
|
|
57
|
-
"@backstage/config": "
|
|
58
|
-
"@backstage/errors": "
|
|
59
|
-
"@backstage/integration": "
|
|
60
|
-
"@backstage/plugin-scaffolder-node": "
|
|
56
|
+
"@backstage/backend-plugin-api": "1.10.1-next.1",
|
|
57
|
+
"@backstage/config": "1.3.9-next.0",
|
|
58
|
+
"@backstage/errors": "1.3.1",
|
|
59
|
+
"@backstage/integration": "2.1.2-next.1",
|
|
60
|
+
"@backstage/plugin-scaffolder-node": "0.13.7-next.2",
|
|
61
61
|
"@gitbeaker/core": "^43.8.0",
|
|
62
62
|
"@gitbeaker/requester-utils": "^43.8.0",
|
|
63
63
|
"@gitbeaker/rest": "^43.8.0",
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"zod": "^3.25.76 || ^4.0.0"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"@backstage/backend-test-utils": "
|
|
70
|
-
"@backstage/cli": "
|
|
71
|
-
"@backstage/plugin-scaffolder-node-test-utils": "
|
|
69
|
+
"@backstage/backend-test-utils": "1.11.7-next.1",
|
|
70
|
+
"@backstage/cli": "0.36.6-next.1",
|
|
71
|
+
"@backstage/plugin-scaffolder-node-test-utils": "0.3.15-next.1"
|
|
72
72
|
}
|
|
73
73
|
}
|