github-issue-tower-defence-management 1.68.0 → 1.69.1

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.
Files changed (31) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +5 -0
  3. package/bin/adapter/entry-points/cli/index.js +9 -0
  4. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  5. package/bin/adapter/entry-points/cli/projectConfig.js +4 -0
  6. package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
  7. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +20 -8
  8. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  9. package/bin/domain/usecases/HandleScheduledEventUseCase.js +1 -0
  10. package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
  11. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +11 -5
  12. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
  13. package/bin/domain/usecases/StartPreparationUseCase.js +6 -0
  14. package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
  15. package/package.json +2 -2
  16. package/src/adapter/entry-points/cli/index.test.ts +4 -0
  17. package/src/adapter/entry-points/cli/index.ts +10 -0
  18. package/src/adapter/entry-points/cli/projectConfig.ts +6 -0
  19. package/src/domain/usecases/HandleScheduledEventUseCase.ts +3 -0
  20. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +357 -0
  21. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +32 -9
  22. package/src/domain/usecases/StartPreparationUseCase.test.ts +198 -0
  23. package/src/domain/usecases/StartPreparationUseCase.ts +10 -0
  24. package/types/adapter/entry-points/cli/projectConfig.d.ts +1 -0
  25. package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
  26. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +1 -0
  27. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
  28. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts +2 -0
  29. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
  30. package/types/domain/usecases/StartPreparationUseCase.d.ts +1 -0
  31. package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
@@ -68,6 +68,7 @@ export class NotifyFinishedIssuePreparationUseCase {
68
68
  issueUrl: string;
69
69
  thresholdForAutoReject: number;
70
70
  workflowBlockerResolvedWebhookUrl: string | null;
71
+ allowedIssueAuthors?: string[] | null;
71
72
  }): Promise<void> => {
72
73
  const project = await this.projectRepository.getByUrl(params.projectUrl);
73
74
 
@@ -167,7 +168,14 @@ export class NotifyFinishedIssuePreparationUseCase {
167
168
  const comments =
168
169
  await this.issueCommentRepository.getCommentsFromIssue(issue);
169
170
 
170
- const { rejections } = await this.collectRejections(issue, comments);
171
+ const isTrustedAuthor = (author: string): boolean =>
172
+ this.isAuthorTrusted(author, params.allowedIssueAuthors ?? null);
173
+
174
+ const { rejections } = await this.collectRejections(
175
+ issue,
176
+ comments,
177
+ isTrustedAuthor,
178
+ );
171
179
 
172
180
  const rejectionStatusMessage =
173
181
  rejections.length > 0
@@ -179,13 +187,17 @@ export class NotifyFinishedIssuePreparationUseCase {
179
187
  );
180
188
  if (
181
189
  rejections.length > 0 &&
182
- lastTargetComments.filter((comment) =>
183
- comment.content.startsWith('Auto Status Check: REJECTED'),
190
+ lastTargetComments.filter(
191
+ (comment) =>
192
+ comment.content.startsWith('Auto Status Check: REJECTED') &&
193
+ isTrustedAuthor(comment.author),
184
194
  ).length >= params.thresholdForAutoReject &&
185
- !lastTargetComments.some((comment) =>
186
- comment.content
187
- .toLowerCase()
188
- .includes('failed to pass the check automatically'),
195
+ !lastTargetComments.some(
196
+ (comment) =>
197
+ comment.content
198
+ .toLowerCase()
199
+ .includes('failed to pass the check automatically') &&
200
+ isTrustedAuthor(comment.author),
189
201
  )
190
202
  ) {
191
203
  issue.status = FAILED_PREPARATION_STATUS_NAME;
@@ -253,9 +265,16 @@ export class NotifyFinishedIssuePreparationUseCase {
253
265
  );
254
266
  };
255
267
 
268
+ private isAuthorTrusted = (
269
+ author: string,
270
+ allowedIssueAuthors: string[] | null,
271
+ ): boolean =>
272
+ allowedIssueAuthors === null || allowedIssueAuthors.includes(author);
273
+
256
274
  private collectRejections = async (
257
275
  issue: { url: string; labels: string[]; isPr: boolean },
258
- comments: { content: string }[],
276
+ comments: { author: string; content: string }[],
277
+ isTrustedAuthor: (author: string) => boolean,
259
278
  ): Promise<{
260
279
  rejections: { type: RejectedReasonType; detail: string }[];
261
280
  approvedPrUrl: string | null;
@@ -263,7 +282,11 @@ export class NotifyFinishedIssuePreparationUseCase {
263
282
  const rejections: { type: RejectedReasonType; detail: string }[] = [];
264
283
 
265
284
  const lastComment = comments[comments.length - 1];
266
- if (!lastComment || !lastComment.content.startsWith('From: :robot:')) {
285
+ if (
286
+ !lastComment ||
287
+ !isTrustedAuthor(lastComment.author) ||
288
+ !lastComment.content.startsWith('From: :robot:')
289
+ ) {
267
290
  rejections.push({
268
291
  type: 'NO_REPORT_FROM_AGENT_BOT',
269
292
  detail: 'NO_REPORT_FROM_AGENT_BOT',