@backstage/plugin-scaffolder-backend-module-gitlab 0.4.1-next.1 → 0.4.1-next.3

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 CHANGED
@@ -1,5 +1,31 @@
1
1
  # @backstage/plugin-scaffolder-backend-module-gitlab
2
2
 
3
+ ## 0.4.1-next.3
4
+
5
+ ### Patch Changes
6
+
7
+ - d44a20a: Added additional plugin metadata to `package.json`.
8
+ - Updated dependencies
9
+ - @backstage/backend-plugin-api@0.6.19-next.3
10
+ - @backstage/integration@1.12.0-next.1
11
+ - @backstage/plugin-scaffolder-node@0.4.5-next.3
12
+ - @backstage/backend-common@0.23.0-next.3
13
+ - @backstage/config@1.2.0
14
+ - @backstage/errors@1.2.4
15
+
16
+ ## 0.4.1-next.2
17
+
18
+ ### Patch Changes
19
+
20
+ - cf96041: Added `gitlab:issue:edit` action to edit existing GitLab issues
21
+ - Updated dependencies
22
+ - @backstage/backend-plugin-api@0.6.19-next.2
23
+ - @backstage/backend-common@0.23.0-next.2
24
+ - @backstage/integration@1.12.0-next.0
25
+ - @backstage/plugin-scaffolder-node@0.4.5-next.2
26
+ - @backstage/config@1.2.0
27
+ - @backstage/errors@1.2.4
28
+
3
29
  ## 0.4.1-next.1
4
30
 
5
31
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -19,7 +19,7 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
19
19
  var yaml__default = /*#__PURE__*/_interopDefaultCompat(yaml);
20
20
  var path__default = /*#__PURE__*/_interopDefaultCompat(path);
21
21
 
22
- const examples$8 = [
22
+ const examples$9 = [
23
23
  {
24
24
  description: "Initializes a git repository with the content in the workspace, and publishes it to GitLab with the default configuration.",
25
25
  example: yaml__default.default.stringify({
@@ -120,12 +120,12 @@ const examples$8 = [
120
120
  {
121
121
  name: "dev",
122
122
  create: true,
123
- protected: true,
123
+ protect: true,
124
124
  ref: "master"
125
125
  },
126
126
  {
127
127
  name: "master",
128
- protected: true
128
+ protect: true
129
129
  }
130
130
  ]
131
131
  }
@@ -169,7 +169,7 @@ function createPublishGitlabAction(options) {
169
169
  return pluginScaffolderNode.createTemplateAction({
170
170
  id: "publish:gitlab",
171
171
  description: "Initializes a git repository of the content in the workspace, and publishes it to GitLab.",
172
- examples: examples$8,
172
+ examples: examples$9,
173
173
  schema: {
174
174
  input: {
175
175
  type: "object",
@@ -537,6 +537,18 @@ const commonGitlabConfigExample = {
537
537
  repoUrl: "gitlab.com?owner=namespace-or-owner&repo=project-name",
538
538
  token: "${{ secrets.USER_OAUTH_TOKEN }}"
539
539
  };
540
+ var IssueType = /* @__PURE__ */ ((IssueType2) => {
541
+ IssueType2["ISSUE"] = "issue";
542
+ IssueType2["INCIDENT"] = "incident";
543
+ IssueType2["TEST"] = "test_case";
544
+ IssueType2["TASK"] = "task";
545
+ return IssueType2;
546
+ })(IssueType || {});
547
+ var IssueStateEvent = /* @__PURE__ */ ((IssueStateEvent2) => {
548
+ IssueStateEvent2["CLOSE"] = "close";
549
+ IssueStateEvent2["REOPEN"] = "reopen";
550
+ return IssueStateEvent2;
551
+ })(IssueStateEvent || {});
540
552
 
541
553
  const parseRepoHost = (repoUrl) => {
542
554
  let parsed;
@@ -654,7 +666,7 @@ async function checkEpicScope(client, projectId, epicId) {
654
666
  }
655
667
  }
656
668
 
657
- const examples$7 = [
669
+ const examples$8 = [
658
670
  {
659
671
  description: "Creating a group at the top level",
660
672
  example: yaml__default.default.stringify({
@@ -728,7 +740,7 @@ const createGitlabGroupEnsureExistsAction = (options) => {
728
740
  id: "gitlab:group:ensureExists",
729
741
  description: "Ensures a Gitlab group exists",
730
742
  supportsDryRun: true,
731
- examples: examples$7,
743
+ examples: examples$8,
732
744
  schema: {
733
745
  input: commonGitlabConfig.merge(
734
746
  zod.z.object({
@@ -783,7 +795,7 @@ const createGitlabGroupEnsureExistsAction = (options) => {
783
795
  });
784
796
  };
785
797
 
786
- const examples$6 = [
798
+ const examples$7 = [
787
799
  {
788
800
  description: "Create a GitLab issue with minimal options",
789
801
  example: yaml__default.default.stringify({
@@ -850,12 +862,6 @@ const examples$6 = [
850
862
  }
851
863
  ];
852
864
 
853
- var IssueType = /* @__PURE__ */ ((IssueType2) => {
854
- IssueType2["ISSUE"] = "issue";
855
- IssueType2["INCIDENT"] = "incident";
856
- IssueType2["TEST"] = "test_case";
857
- return IssueType2;
858
- })(IssueType || {});
859
865
  const issueInputProperties = zod.z.object({
860
866
  projectId: zod.z.number().describe("Project Id"),
861
867
  title: zod.z.string({ description: "Title of the issue" }),
@@ -904,7 +910,7 @@ const createGitlabIssueAction = (options) => {
904
910
  return pluginScaffolderNode.createTemplateAction({
905
911
  id: "gitlab:issues:create",
906
912
  description: "Creates a Gitlab issue.",
907
- examples: examples$6,
913
+ examples: examples$7,
908
914
  schema: {
909
915
  input: commonGitlabConfig.merge(issueInputProperties),
910
916
  output: issueOutputProperties
@@ -933,11 +939,7 @@ const createGitlabIssueAction = (options) => {
933
939
  const api = getClient({ host, integrations, token });
934
940
  let isEpicScoped = false;
935
941
  if (epicId) {
936
- isEpicScoped = await checkEpicScope(
937
- api,
938
- projectId,
939
- epicId
940
- );
942
+ isEpicScoped = await checkEpicScope(api, projectId, epicId);
941
943
  if (isEpicScoped) {
942
944
  ctx.logger.info("Epic is within Project Scope");
943
945
  } else {
@@ -985,6 +987,225 @@ const createGitlabIssueAction = (options) => {
985
987
  });
986
988
  };
987
989
 
990
+ const examples$6 = [
991
+ {
992
+ description: "Edit a GitLab issue with minimal options",
993
+ example: yaml__default.default.stringify({
994
+ steps: [
995
+ {
996
+ id: "gitlabIssue",
997
+ name: "EditIssues",
998
+ action: "gitlab:issue:edit",
999
+ input: {
1000
+ ...commonGitlabConfigExample,
1001
+ projectId: 12,
1002
+ title: "Modified Test Issue",
1003
+ description: "This is a modified description of the issue"
1004
+ }
1005
+ }
1006
+ ]
1007
+ })
1008
+ },
1009
+ {
1010
+ description: "Edit a GitLab issue with assignees and date options",
1011
+ example: yaml__default.default.stringify({
1012
+ steps: [
1013
+ {
1014
+ id: "gitlabIssue",
1015
+ name: "EditIssues",
1016
+ action: "gitlab:issue:edit",
1017
+ input: {
1018
+ ...commonGitlabConfigExample,
1019
+ projectId: 12,
1020
+ title: "Test Issue",
1021
+ assignees: [18],
1022
+ description: "This is the edited description of the issue",
1023
+ updatedAt: "2024-05-10 18:00:00.000",
1024
+ dueDate: "2024-09-28"
1025
+ }
1026
+ }
1027
+ ]
1028
+ })
1029
+ },
1030
+ {
1031
+ description: "Create a GitLab Issue with several options",
1032
+ example: yaml__default.default.stringify({
1033
+ steps: [
1034
+ {
1035
+ id: "gitlabIssue",
1036
+ name: "EditIssues",
1037
+ action: "gitlab:issue:edit",
1038
+ input: {
1039
+ ...commonGitlabConfigExample,
1040
+ projectId: 12,
1041
+ title: "Test Edit Issue",
1042
+ assignees: [18, 15],
1043
+ description: "This is the description of the issue",
1044
+ confidential: false,
1045
+ updatedAt: "2024-05-10 18:00:00.000",
1046
+ dueDate: "2024-09-28",
1047
+ discussionLocked: true,
1048
+ epicId: 1,
1049
+ labels: "phase1:label1,phase2:label2"
1050
+ }
1051
+ }
1052
+ ]
1053
+ })
1054
+ }
1055
+ ];
1056
+
1057
+ const editIssueInputProperties = zod.z.object({
1058
+ projectId: zod.z.number().describe(
1059
+ "The global ID or URL-encoded path of the project owned by the authenticated user."
1060
+ ),
1061
+ issueIid: zod.z.number().describe("The internal ID of a project's issue"),
1062
+ addLabels: zod.z.string({
1063
+ description: "Comma-separated label names to add to an issue. If a label does not already exist, this creates a new project label and assigns it to the issue."
1064
+ }).optional(),
1065
+ assignees: zod.z.array(zod.z.number(), {
1066
+ description: "IDs of the users to assign the issue to."
1067
+ }).optional(),
1068
+ confidential: zod.z.boolean({ description: "Updates an issue to be confidential." }).optional(),
1069
+ description: zod.z.string().describe("The description of an issue. Limited to 1,048,576 characters.").max(1048576).optional(),
1070
+ discussionLocked: zod.z.boolean({
1071
+ description: "Flag indicating if the issue\u2019s discussion is locked. If the discussion is locked only project members can add or edit comments."
1072
+ }).optional(),
1073
+ dueDate: zod.z.string().describe(
1074
+ "The due date. Date time string in the format YYYY-MM-DD, for example 2016-03-11."
1075
+ ).regex(/^\d{4}-\d{2}-\d{2}$/, "Invalid date format. Use YYYY-MM-DD").optional(),
1076
+ epicId: zod.z.number({
1077
+ description: "ID of the epic to add the issue to. Valid values are greater than or equal to 0."
1078
+ }).min(0, "Valid values should be equal or greater than zero").optional(),
1079
+ issueType: zod.z.nativeEnum(IssueType, {
1080
+ description: "Updates the type of issue. One of issue, incident, test_case or task."
1081
+ }).optional(),
1082
+ labels: zod.z.string({
1083
+ description: "Comma-separated label names for an issue. Set to an empty string to unassign all labels. If a label does not already exist, this creates a new project label and assigns it to the issue."
1084
+ }).optional(),
1085
+ milestoneId: zod.z.number({
1086
+ description: "The global ID of a milestone to assign the issue to. Set to 0 or provide an empty value to unassign a milestone"
1087
+ }).optional(),
1088
+ removeLabels: zod.z.string({
1089
+ description: "Comma-separated label names to remove from an issue."
1090
+ }).optional(),
1091
+ stateEvent: zod.z.nativeEnum(IssueStateEvent, {
1092
+ description: "The state event of an issue. To close the issue, use close, and to reopen it, use reopen."
1093
+ }).optional(),
1094
+ title: zod.z.string().describe("The title of an issue.").optional(),
1095
+ updatedAt: zod.z.string().describe(
1096
+ "When the issue was updated. Date time string, ISO 8601 formatted"
1097
+ ).regex(
1098
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/,
1099
+ "Invalid date format. Use YYYY-MM-DDTHH:mm:ssZ or YYYY-MM-DDTHH:mm:ss.SSSZ"
1100
+ ).optional(),
1101
+ weight: zod.z.number({ description: "The issue weight" }).min(0, "Valid values should be equal or greater than zero").max(10, "Valid values should be equal or less than 10").optional()
1102
+ });
1103
+ const editIssueOutputProperties = zod.z.object({
1104
+ issueUrl: zod.z.string({ description: "Issue WebUrl" }),
1105
+ projectId: zod.z.number({
1106
+ description: "The project id the issue belongs to WebUrl"
1107
+ }),
1108
+ issueId: zod.z.number({ description: "The issues Id" }),
1109
+ issueIid: zod.z.number({
1110
+ description: "The issues internal ID of a project's issue"
1111
+ }),
1112
+ state: zod.z.string({ description: "The state event of an issue" }),
1113
+ title: zod.z.string({ description: "The title of an issue." }),
1114
+ updatedAt: zod.z.string({ description: "The last updated time of the issue." })
1115
+ });
1116
+ const editGitlabIssueAction = (options) => {
1117
+ const { integrations } = options;
1118
+ return pluginScaffolderNode.createTemplateAction({
1119
+ id: "gitlab:issue:edit",
1120
+ description: "Edit a Gitlab issue.",
1121
+ examples: examples$6,
1122
+ schema: {
1123
+ input: commonGitlabConfig.merge(editIssueInputProperties),
1124
+ output: editIssueOutputProperties
1125
+ },
1126
+ async handler(ctx) {
1127
+ try {
1128
+ const {
1129
+ repoUrl,
1130
+ projectId,
1131
+ title,
1132
+ addLabels,
1133
+ removeLabels,
1134
+ issueIid,
1135
+ description,
1136
+ confidential = false,
1137
+ assignees = [],
1138
+ updatedAt = "",
1139
+ dueDate,
1140
+ discussionLocked = false,
1141
+ epicId,
1142
+ labels,
1143
+ issueType,
1144
+ milestoneId,
1145
+ stateEvent,
1146
+ weight,
1147
+ token
1148
+ } = commonGitlabConfig.merge(editIssueInputProperties).parse(ctx.input);
1149
+ const { host } = parseRepoUrl(repoUrl, integrations);
1150
+ const api = getClient({ host, integrations, token });
1151
+ let isEpicScoped = false;
1152
+ if (epicId) {
1153
+ isEpicScoped = await checkEpicScope(api, projectId, epicId);
1154
+ if (isEpicScoped) {
1155
+ ctx.logger.info("Epic is within Project Scope");
1156
+ } else {
1157
+ ctx.logger.warn(
1158
+ "Chosen epic is not within the Project Scope. The issue will be created without an associated epic."
1159
+ );
1160
+ }
1161
+ }
1162
+ const mappedUpdatedAt = convertDate(
1163
+ String(updatedAt),
1164
+ (/* @__PURE__ */ new Date()).toISOString()
1165
+ );
1166
+ const editIssueOptions = {
1167
+ addLabels,
1168
+ assigneeIds: assignees,
1169
+ confidential,
1170
+ description,
1171
+ discussionLocked,
1172
+ dueDate,
1173
+ epicId: isEpicScoped ? epicId : void 0,
1174
+ issueType,
1175
+ labels,
1176
+ milestoneId,
1177
+ removeLabels,
1178
+ stateEvent,
1179
+ title,
1180
+ updatedAt: mappedUpdatedAt,
1181
+ weight
1182
+ };
1183
+ const response = await api.Issues.edit(
1184
+ projectId,
1185
+ issueIid,
1186
+ editIssueOptions
1187
+ );
1188
+ ctx.output("issueId", response.id);
1189
+ ctx.output("projectId", response.project_id);
1190
+ ctx.output("issueUrl", response.web_url);
1191
+ ctx.output("issueIid", response.iid);
1192
+ ctx.output("title", response.title);
1193
+ ctx.output("state", response.state);
1194
+ ctx.output("updatedAt", response.updated_at);
1195
+ } catch (error) {
1196
+ if (error instanceof zod.z.ZodError) {
1197
+ throw new errors.InputError(`Validation error: ${error.message}`, {
1198
+ validationErrors: error.errors
1199
+ });
1200
+ }
1201
+ throw new errors.InputError(
1202
+ `Failed to edit/modify GitLab issue: ${error.message}`
1203
+ );
1204
+ }
1205
+ }
1206
+ });
1207
+ };
1208
+
988
1209
  function createGitlabApi(options) {
989
1210
  const { integrations, token: providedToken, repoUrl } = options;
990
1211
  const { host } = pluginScaffolderNode.parseRepoUrl(repoUrl, integrations);
@@ -2120,6 +2341,7 @@ const gitlabModule = backendPluginApi.createBackendModule({
2120
2341
  createGitlabProjectDeployTokenAction({ integrations }),
2121
2342
  createGitlabProjectVariableAction({ integrations }),
2122
2343
  createGitlabRepoPushAction({ integrations }),
2344
+ editGitlabIssueAction({ integrations }),
2123
2345
  createPublishGitlabAction({ config, integrations }),
2124
2346
  createPublishGitlabMergeRequestAction({ integrations }),
2125
2347
  createTriggerGitlabPipelineAction({ integrations })
@@ -2129,6 +2351,7 @@ const gitlabModule = backendPluginApi.createBackendModule({
2129
2351
  }
2130
2352
  });
2131
2353
 
2354
+ exports.IssueStateEvent = IssueStateEvent;
2132
2355
  exports.IssueType = IssueType;
2133
2356
  exports.createGitlabGroupEnsureExistsAction = createGitlabGroupEnsureExistsAction;
2134
2357
  exports.createGitlabIssueAction = createGitlabIssueAction;
@@ -2140,4 +2363,5 @@ exports.createPublishGitlabAction = createPublishGitlabAction;
2140
2363
  exports.createPublishGitlabMergeRequestAction = createPublishGitlabMergeRequestAction;
2141
2364
  exports.createTriggerGitlabPipelineAction = createTriggerGitlabPipelineAction;
2142
2365
  exports.default = gitlabModule;
2366
+ exports.editGitlabIssueAction = editGitlabIssueAction;
2143
2367
  //# sourceMappingURL=index.cjs.js.map