github-issue-tower-defence-management 2.6.1 → 2.7.0
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 +7 -0
- package/README.md +0 -2
- package/bin/adapter/entry-points/cli/index.js +0 -5
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/cli/projectConfig.js +0 -3
- package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +1 -3
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
- package/bin/domain/usecases/CheckIssueReviewReadinessUseCase.js +4 -2
- package/bin/domain/usecases/CheckIssueReviewReadinessUseCase.js.map +1 -1
- package/bin/domain/usecases/HandleScheduledEventUseCase.js +1 -6
- package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
- package/bin/domain/usecases/IssueRejectionEvaluator.js +0 -23
- package/bin/domain/usecases/IssueRejectionEvaluator.js.map +1 -1
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +39 -69
- package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js +3 -2
- package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js.map +1 -1
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +0 -43
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
- package/bin/domain/usecases/autoStatusCheckComments.js +1 -11
- package/bin/domain/usecases/autoStatusCheckComments.js.map +1 -1
- package/bin/domain/usecases/extractNextStepAgentFromComments.js +14 -0
- package/bin/domain/usecases/extractNextStepAgentFromComments.js.map +1 -0
- package/bin/domain/usecases/triagerAgentName.js +7 -0
- package/bin/domain/usecases/triagerAgentName.js.map +1 -0
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.test.ts +0 -2
- package/src/adapter/entry-points/cli/index.ts +0 -9
- package/src/adapter/entry-points/cli/projectConfig.ts +0 -8
- package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +0 -7
- package/src/domain/usecases/CheckIssueReviewReadinessUseCase.test.ts +26 -4
- package/src/domain/usecases/CheckIssueReviewReadinessUseCase.ts +5 -3
- package/src/domain/usecases/HandleScheduledEventUseCase.test.ts +0 -28
- package/src/domain/usecases/HandleScheduledEventUseCase.ts +0 -6
- package/src/domain/usecases/IssueRejectionEvaluator.test.ts +0 -119
- package/src/domain/usecases/IssueRejectionEvaluator.ts +0 -21
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +185 -327
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +68 -138
- package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.test.ts +4 -4
- package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts +11 -5
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.test.ts +0 -313
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +1 -102
- package/src/domain/usecases/autoStatusCheckComments.ts +0 -17
- package/src/domain/usecases/extractNextStepAgentFromComments.ts +13 -0
- package/src/domain/usecases/isHumanComment.test.ts +0 -13
- package/src/domain/usecases/triagerAgentName.ts +4 -0
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/cli/projectConfig.d.ts +0 -1
- package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
- package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
- package/types/domain/usecases/CheckIssueReviewReadinessUseCase.d.ts.map +1 -1
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +1 -3
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
- package/types/domain/usecases/IssueRejectionEvaluator.d.ts +0 -1
- package/types/domain/usecases/IssueRejectionEvaluator.d.ts.map +1 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts +0 -1
- package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.d.ts.map +1 -1
- package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts +0 -1
- package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
- package/types/domain/usecases/autoStatusCheckComments.d.ts +0 -4
- package/types/domain/usecases/autoStatusCheckComments.d.ts.map +1 -1
- package/types/domain/usecases/extractNextStepAgentFromComments.d.ts +5 -0
- package/types/domain/usecases/extractNextStepAgentFromComments.d.ts.map +1 -0
- package/types/domain/usecases/triagerAgentName.d.ts +3 -0
- package/types/domain/usecases/triagerAgentName.d.ts.map +1 -0
- package/src/domain/usecases/TriagerApprovalDispatchUseCase.test.ts +0 -1051
- package/src/domain/usecases/TriagerApprovalDispatchUseCase.ts +0 -274
- package/src/domain/usecases/awaitingOwnerApprovalMessage.ts +0 -5
- package/src/domain/usecases/isPullRequestDeclaredUnnecessary.test.ts +0 -162
- package/src/domain/usecases/isPullRequestDeclaredUnnecessary.ts +0 -29
- package/src/domain/usecases/isWaitingForOwnerApproval.test.ts +0 -91
- package/src/domain/usecases/isWaitingForOwnerApproval.ts +0 -17
- package/src/domain/usecases/returnedToAwaitingWorkspaceMessage.ts +0 -5
|
@@ -122,7 +122,6 @@ type NotifyFinishedOptions = {
|
|
|
122
122
|
missingAgentName?: string;
|
|
123
123
|
sessionErrorLine?: string;
|
|
124
124
|
deferPreparation?: boolean;
|
|
125
|
-
ownerApprovalTimeoutCycles?: string;
|
|
126
125
|
};
|
|
127
126
|
|
|
128
127
|
type CheckIssueReviewReadinessOptions = {
|
|
@@ -484,7 +483,6 @@ program
|
|
|
484
483
|
labelsAsLlmAgentName: config.labelsAsLlmAgentName ?? null,
|
|
485
484
|
labelsNotRequiringPullRequest:
|
|
486
485
|
config.labelsNotRequiringPullRequest ?? null,
|
|
487
|
-
ownerApprovalTimeoutCycles: config.ownerApprovalTimeoutCycles ?? 12,
|
|
488
486
|
});
|
|
489
487
|
}
|
|
490
488
|
|
|
@@ -585,10 +583,6 @@ program
|
|
|
585
583
|
'--deferPreparation',
|
|
586
584
|
'Defer the item via the Reactivation Trigger fields (sets nextActionDate to tomorrow) without creating any issue; use for transient upstream failures',
|
|
587
585
|
)
|
|
588
|
-
.option(
|
|
589
|
-
'--ownerApprovalTimeoutCycles <count>',
|
|
590
|
-
'Number of owner-approval wait cycles before escalating to Failed Preparation (default: 12)',
|
|
591
|
-
)
|
|
592
586
|
.action(async (options: NotifyFinishedOptions) => {
|
|
593
587
|
const token = process.env.GH_TOKEN;
|
|
594
588
|
if (!token) {
|
|
@@ -730,9 +724,6 @@ program
|
|
|
730
724
|
manager: config.manager ?? null,
|
|
731
725
|
developerAgentName: config.developerAgentName ?? null,
|
|
732
726
|
deferPreparation: options.deferPreparation ?? null,
|
|
733
|
-
ownerApprovalTimeoutCycles: options.ownerApprovalTimeoutCycles
|
|
734
|
-
? Number(options.ownerApprovalTimeoutCycles)
|
|
735
|
-
: (config.ownerApprovalTimeoutCycles ?? 12),
|
|
736
727
|
});
|
|
737
728
|
});
|
|
738
729
|
|
|
@@ -32,7 +32,6 @@ export type ConfigFile = {
|
|
|
32
32
|
consoleProjects?: Record<string, string>;
|
|
33
33
|
consoleGithubTokenFileDir?: string;
|
|
34
34
|
disks?: DiskConfig[];
|
|
35
|
-
ownerApprovalTimeoutCycles?: number;
|
|
36
35
|
errorReportingRepository?: string;
|
|
37
36
|
};
|
|
38
37
|
|
|
@@ -209,10 +208,6 @@ export const loadConfigFile = (configFilePath: string): ConfigFile => {
|
|
|
209
208
|
'consoleGithubTokenFileDir',
|
|
210
209
|
),
|
|
211
210
|
disks: getDisksValue(parsed, 'disks'),
|
|
212
|
-
ownerApprovalTimeoutCycles: getNumberValue(
|
|
213
|
-
parsed,
|
|
214
|
-
'ownerApprovalTimeoutCycles',
|
|
215
|
-
),
|
|
216
211
|
errorReportingRepository: getStringValue(
|
|
217
212
|
parsed,
|
|
218
213
|
'errorReportingRepository',
|
|
@@ -410,9 +405,6 @@ export const mergeConfigs = (
|
|
|
410
405
|
cliOverrides.consoleGithubTokenFileDir ??
|
|
411
406
|
configFile.consoleGithubTokenFileDir,
|
|
412
407
|
disks: cliOverrides.disks ?? configFile.disks,
|
|
413
|
-
ownerApprovalTimeoutCycles:
|
|
414
|
-
cliOverrides.ownerApprovalTimeoutCycles ??
|
|
415
|
-
configFile.ownerApprovalTimeoutCycles,
|
|
416
408
|
errorReportingRepository:
|
|
417
409
|
readmeOverrides.errorReportingRepository ??
|
|
418
410
|
cliOverrides.errorReportingRepository ??
|
|
@@ -74,7 +74,6 @@ import { ProxyRateLimitCacheRepository } from '../../repositories/ProxyRateLimit
|
|
|
74
74
|
import { UpdateRateLimitCacheUseCase } from '../../../domain/usecases/UpdateRateLimitCacheUseCase';
|
|
75
75
|
import { RevertOrphanedPreparationUseCase } from '../../../domain/usecases/RevertOrphanedPreparationUseCase';
|
|
76
76
|
import { RevertNotReadyReviewQueueIssueUseCase } from '../../../domain/usecases/RevertNotReadyReviewQueueIssueUseCase';
|
|
77
|
-
import { TriagerApprovalDispatchUseCase } from '../../../domain/usecases/TriagerApprovalDispatchUseCase';
|
|
78
77
|
import { AgentDesignationLabelAdoptUseCase } from '../../../domain/usecases/AgentDesignationLabelAdoptUseCase';
|
|
79
78
|
import { GitHubIssueCommentRepository } from '../../repositories/GitHubIssueCommentRepository';
|
|
80
79
|
import { ProjectRequiredFieldCreateUseCase } from '../../../domain/usecases/ProjectRequiredFieldCreateUseCase';
|
|
@@ -528,11 +527,6 @@ export class HandleScheduledEventUseCaseHandler {
|
|
|
528
527
|
issueRepository,
|
|
529
528
|
issueCommentRepository,
|
|
530
529
|
);
|
|
531
|
-
const triagerApprovalDispatchUseCase = new TriagerApprovalDispatchUseCase(
|
|
532
|
-
projectRepository,
|
|
533
|
-
issueRepository,
|
|
534
|
-
issueCommentRepository,
|
|
535
|
-
);
|
|
536
530
|
const agentDesignationLabelAdoptUseCase =
|
|
537
531
|
new AgentDesignationLabelAdoptUseCase(projectRepository, issueRepository);
|
|
538
532
|
|
|
@@ -575,7 +569,6 @@ export class HandleScheduledEventUseCaseHandler {
|
|
|
575
569
|
revertOrphanedPreparationUseCase,
|
|
576
570
|
conflictedIssueRevertUseCase,
|
|
577
571
|
revertNotReadyReviewQueueIssueUseCase,
|
|
578
|
-
triagerApprovalDispatchUseCase,
|
|
579
572
|
agentDesignationLabelAdoptUseCase,
|
|
580
573
|
updateRateLimitCacheUseCase,
|
|
581
574
|
dailySecurityScanUseCase,
|
|
@@ -212,13 +212,13 @@ describe('CheckIssueReviewReadinessUseCase', () => {
|
|
|
212
212
|
});
|
|
213
213
|
});
|
|
214
214
|
|
|
215
|
-
it('should return reviewReady=true when the last report
|
|
215
|
+
it('should return reviewReady=true when the last report designates the triager and no related PR exists', async () => {
|
|
216
216
|
const issue = createMockIssue();
|
|
217
217
|
mockIssueRepository.getIssueByUrl.mockResolvedValue(issue);
|
|
218
218
|
mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
|
|
219
219
|
createMockComment({
|
|
220
220
|
content:
|
|
221
|
-
'From: :robot: Agent report\n```json\n{"
|
|
221
|
+
'From: :robot: Agent report\n```json\n{"nextStepAgent": "triager"}\n```',
|
|
222
222
|
}),
|
|
223
223
|
]);
|
|
224
224
|
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
@@ -232,13 +232,35 @@ describe('CheckIssueReviewReadinessUseCase', () => {
|
|
|
232
232
|
expect(result.reviewReady).toBe(true);
|
|
233
233
|
});
|
|
234
234
|
|
|
235
|
-
it('should keep
|
|
235
|
+
it('should keep rejecting a missing PR when the last report designates an agent other than the triager', async () => {
|
|
236
236
|
const issue = createMockIssue();
|
|
237
237
|
mockIssueRepository.getIssueByUrl.mockResolvedValue(issue);
|
|
238
238
|
mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
|
|
239
239
|
createMockComment({
|
|
240
240
|
content:
|
|
241
|
-
'From: :robot: Agent report\n```json\n{"
|
|
241
|
+
'From: :robot: Agent report\n```json\n{"nextStepAgent": "developer"}\n```',
|
|
242
|
+
}),
|
|
243
|
+
]);
|
|
244
|
+
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
245
|
+
|
|
246
|
+
const result = await useCase.run({
|
|
247
|
+
issueUrl: 'https://github.com/user/repo/issues/1',
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
expect(result.reviewReady).toBe(false);
|
|
251
|
+
expect(result.rejections).toContainEqual({
|
|
252
|
+
type: 'PULL_REQUEST_NOT_FOUND',
|
|
253
|
+
detail: 'PULL_REQUEST_NOT_FOUND',
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('should keep every rejection other than PULL_REQUEST_NOT_FOUND when the last report designates the triager', async () => {
|
|
258
|
+
const issue = createMockIssue();
|
|
259
|
+
mockIssueRepository.getIssueByUrl.mockResolvedValue(issue);
|
|
260
|
+
mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
|
|
261
|
+
createMockComment({
|
|
262
|
+
content:
|
|
263
|
+
'From: :robot: Agent report\n```json\n{"nextStepAgent": "triager"}\n```',
|
|
242
264
|
}),
|
|
243
265
|
]);
|
|
244
266
|
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
|
|
@@ -5,10 +5,11 @@ import {
|
|
|
5
5
|
PrRejectedReasonType,
|
|
6
6
|
} from './IssueRejectionEvaluator';
|
|
7
7
|
import { resolveLabelsNotRequiringPullRequest } from './resolveLabelsNotRequiringPullRequest';
|
|
8
|
-
import { isPullRequestDeclaredUnnecessary } from './isPullRequestDeclaredUnnecessary';
|
|
9
8
|
import { normalizeReportBody } from './normalizeReportBody';
|
|
10
9
|
import { isAgentReportBody } from './isAgentReportBody';
|
|
11
10
|
import { isAuthorAuthorizedForAutoStatusCheck } from './isAuthorAuthorizedForAutoStatusCheck';
|
|
11
|
+
import { extractNextStepAgentFromComments } from './extractNextStepAgentFromComments';
|
|
12
|
+
import { isTriagerAgentName } from './triagerAgentName';
|
|
12
13
|
|
|
13
14
|
type RejectedReasonType =
|
|
14
15
|
| 'ISSUE_NOT_FOUND'
|
|
@@ -94,10 +95,11 @@ export class CheckIssueReviewReadinessUseCase {
|
|
|
94
95
|
{ developerAgentName: params.developerAgentName },
|
|
95
96
|
);
|
|
96
97
|
|
|
97
|
-
const
|
|
98
|
+
const nextStepAgent = extractNextStepAgentFromComments(
|
|
98
99
|
comments,
|
|
99
100
|
isTrustedAuthor,
|
|
100
|
-
)
|
|
101
|
+
);
|
|
102
|
+
const requiredPrRejections = isTriagerAgentName(nextStepAgent)
|
|
101
103
|
? prRejections.filter(
|
|
102
104
|
(rejection) => rejection.type !== 'PULL_REQUEST_NOT_FOUND',
|
|
103
105
|
)
|
|
@@ -25,7 +25,6 @@ import { StartPreparationUseCase } from './StartPreparationUseCase';
|
|
|
25
25
|
import { RevertOrphanedPreparationUseCase } from './RevertOrphanedPreparationUseCase';
|
|
26
26
|
import { ConflictedIssueRevertUseCase } from './ConflictedIssueRevertUseCase';
|
|
27
27
|
import { RevertNotReadyReviewQueueIssueUseCase } from './RevertNotReadyReviewQueueIssueUseCase';
|
|
28
|
-
import { TriagerApprovalDispatchUseCase } from './TriagerApprovalDispatchUseCase';
|
|
29
28
|
import { AgentDesignationLabelAdoptUseCase } from './AgentDesignationLabelAdoptUseCase';
|
|
30
29
|
import { ProjectRequiredFieldCreateUseCase } from './ProjectRequiredFieldCreateUseCase';
|
|
31
30
|
import { SetupTowerDefenceProjectUseCase } from './SetupTowerDefenceProjectUseCase';
|
|
@@ -129,8 +128,6 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
129
128
|
mock<ConflictedIssueRevertUseCase>();
|
|
130
129
|
const mockRevertNotReadyReviewQueueIssueUseCase =
|
|
131
130
|
mock<RevertNotReadyReviewQueueIssueUseCase>();
|
|
132
|
-
const mockTriagerApprovalDispatchUseCase =
|
|
133
|
-
mock<TriagerApprovalDispatchUseCase>();
|
|
134
131
|
const mockAgentDesignationLabelAdoptUseCase =
|
|
135
132
|
mock<AgentDesignationLabelAdoptUseCase>();
|
|
136
133
|
const mockUpdateRateLimitCacheUseCase = mock<UpdateRateLimitCacheUseCase>();
|
|
@@ -165,7 +162,6 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
165
162
|
mockRevertOrphanedPreparationUseCase,
|
|
166
163
|
mockConflictedIssueRevertUseCase,
|
|
167
164
|
mockRevertNotReadyReviewQueueIssueUseCase,
|
|
168
|
-
mockTriagerApprovalDispatchUseCase,
|
|
169
165
|
mockAgentDesignationLabelAdoptUseCase,
|
|
170
166
|
mockUpdateRateLimitCacheUseCase,
|
|
171
167
|
mockDailySecurityScanUseCase,
|
|
@@ -282,29 +278,6 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
282
278
|
});
|
|
283
279
|
});
|
|
284
280
|
|
|
285
|
-
it('should call TriagerApprovalDispatchUseCase with project URL', async () => {
|
|
286
|
-
const input = {
|
|
287
|
-
projectName: 'test-project',
|
|
288
|
-
org: 'test-org',
|
|
289
|
-
projectUrl: 'https://github.com/test-org/test-project',
|
|
290
|
-
manager: 'test-manager',
|
|
291
|
-
workingReport: {
|
|
292
|
-
repo: 'test-repo',
|
|
293
|
-
members: ['member1'],
|
|
294
|
-
spreadsheetUrl: 'https://docs.google.com/spreadsheets/test',
|
|
295
|
-
},
|
|
296
|
-
urlOfStoryView: 'https://github.com/test-org/test-project/issues',
|
|
297
|
-
disabled: false,
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
await useCase.run(input);
|
|
301
|
-
expect(mockTriagerApprovalDispatchUseCase.run).toHaveBeenCalledWith(
|
|
302
|
-
expect.objectContaining({
|
|
303
|
-
projectUrl: 'https://github.com/test-org/test-project',
|
|
304
|
-
}),
|
|
305
|
-
);
|
|
306
|
-
});
|
|
307
|
-
|
|
308
281
|
it('should return null and skip all processing when disabled is true', async () => {
|
|
309
282
|
const input = {
|
|
310
283
|
projectName: 'test-project',
|
|
@@ -1827,7 +1800,6 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
1827
1800
|
mock<RevertOrphanedPreparationUseCase>(),
|
|
1828
1801
|
mock<ConflictedIssueRevertUseCase>(),
|
|
1829
1802
|
mock<RevertNotReadyReviewQueueIssueUseCase>(),
|
|
1830
|
-
mock<TriagerApprovalDispatchUseCase>(),
|
|
1831
1803
|
mock<AgentDesignationLabelAdoptUseCase>(),
|
|
1832
1804
|
null,
|
|
1833
1805
|
null,
|
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
import { AgentDesignationLabelAdoptUseCase } from './AgentDesignationLabelAdoptUseCase';
|
|
29
29
|
import { RevertOrphanedPreparationUseCase } from './RevertOrphanedPreparationUseCase';
|
|
30
30
|
import { RevertNotReadyReviewQueueIssueUseCase } from './RevertNotReadyReviewQueueIssueUseCase';
|
|
31
|
-
import { TriagerApprovalDispatchUseCase } from './TriagerApprovalDispatchUseCase';
|
|
32
31
|
import { isRecord } from './isRecord';
|
|
33
32
|
import { resolveLabelsAsLlmAgentName } from './resolveLabelsAsLlmAgentName';
|
|
34
33
|
import { resolveAllowedIssueAuthors } from './resolveAllowedIssueAuthors';
|
|
@@ -139,7 +138,6 @@ export class HandleScheduledEventUseCase {
|
|
|
139
138
|
readonly revertOrphanedPreparationUseCase: RevertOrphanedPreparationUseCase,
|
|
140
139
|
readonly conflictedIssueRevertUseCase: ConflictedIssueRevertUseCase,
|
|
141
140
|
readonly revertNotReadyReviewQueueIssueUseCase: RevertNotReadyReviewQueueIssueUseCase,
|
|
142
|
-
readonly triagerApprovalDispatchUseCase: TriagerApprovalDispatchUseCase,
|
|
143
141
|
readonly agentDesignationLabelAdoptUseCase: AgentDesignationLabelAdoptUseCase,
|
|
144
142
|
readonly updateRateLimitCacheUseCase: UpdateRateLimitCacheUseCase | null,
|
|
145
143
|
readonly dailySecurityScanUseCase: DailySecurityScanUseCase | null,
|
|
@@ -452,10 +450,6 @@ ${JSON.stringify(e)}
|
|
|
452
450
|
allowedIssueAuthors,
|
|
453
451
|
developerAgentName: input.developerAgentName,
|
|
454
452
|
});
|
|
455
|
-
await this.triagerApprovalDispatchUseCase.run({
|
|
456
|
-
projectUrl: input.projectUrl,
|
|
457
|
-
allowedIssueAuthors,
|
|
458
|
-
});
|
|
459
453
|
if (this.dailySecurityScanUseCase !== null && input.dailySecurityScan) {
|
|
460
454
|
await this.dailySecurityScanUseCase.run({
|
|
461
455
|
targetDates: targetDateTimes,
|
|
@@ -739,125 +739,6 @@ describe('IssueRejectionEvaluator', () => {
|
|
|
739
739
|
});
|
|
740
740
|
});
|
|
741
741
|
|
|
742
|
-
describe('pullRequestRequired: false in issue body', () => {
|
|
743
|
-
it('should not reject and not call findRelatedOpenPRs when body ends with JSON block containing pullRequestRequired: false', async () => {
|
|
744
|
-
const body = '```json\n{"pullRequestRequired": false}\n```';
|
|
745
|
-
|
|
746
|
-
const result = await evaluator.evaluate({
|
|
747
|
-
url: 'https://github.com/user/repo/issues/1',
|
|
748
|
-
labels: [],
|
|
749
|
-
isPr: false,
|
|
750
|
-
body,
|
|
751
|
-
});
|
|
752
|
-
|
|
753
|
-
expect(mockIssueRepository.findRelatedOpenPRs).not.toHaveBeenCalled();
|
|
754
|
-
expect(result.rejections).toHaveLength(0);
|
|
755
|
-
expect(result.approvedPrUrl).toBeNull();
|
|
756
|
-
});
|
|
757
|
-
|
|
758
|
-
it('should not reject even with trailing whitespace after the closing JSON block', async () => {
|
|
759
|
-
const body = '```json\n{"pullRequestRequired": false}\n```\n ';
|
|
760
|
-
|
|
761
|
-
const result = await evaluator.evaluate({
|
|
762
|
-
url: 'https://github.com/user/repo/issues/1',
|
|
763
|
-
labels: [],
|
|
764
|
-
isPr: false,
|
|
765
|
-
body,
|
|
766
|
-
});
|
|
767
|
-
|
|
768
|
-
expect(mockIssueRepository.findRelatedOpenPRs).not.toHaveBeenCalled();
|
|
769
|
-
expect(result.rejections).toHaveLength(0);
|
|
770
|
-
});
|
|
771
|
-
|
|
772
|
-
it('should still require PR when body has pullRequestRequired: true', async () => {
|
|
773
|
-
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
774
|
-
const body = '```json\n{"pullRequestRequired": true}\n```';
|
|
775
|
-
|
|
776
|
-
const result = await evaluator.evaluate({
|
|
777
|
-
url: 'https://github.com/user/repo/issues/1',
|
|
778
|
-
labels: [],
|
|
779
|
-
isPr: false,
|
|
780
|
-
body,
|
|
781
|
-
});
|
|
782
|
-
|
|
783
|
-
expect(result.rejections).toHaveLength(1);
|
|
784
|
-
expect(result.rejections[0].type).toBe('PULL_REQUEST_NOT_FOUND');
|
|
785
|
-
});
|
|
786
|
-
|
|
787
|
-
it('should still require PR when body is null', async () => {
|
|
788
|
-
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
789
|
-
|
|
790
|
-
const result = await evaluator.evaluate({
|
|
791
|
-
url: 'https://github.com/user/repo/issues/1',
|
|
792
|
-
labels: [],
|
|
793
|
-
isPr: false,
|
|
794
|
-
body: null,
|
|
795
|
-
});
|
|
796
|
-
|
|
797
|
-
expect(result.rejections).toHaveLength(1);
|
|
798
|
-
expect(result.rejections[0].type).toBe('PULL_REQUEST_NOT_FOUND');
|
|
799
|
-
});
|
|
800
|
-
|
|
801
|
-
it('should still require PR when body is undefined', async () => {
|
|
802
|
-
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
803
|
-
|
|
804
|
-
const result = await evaluator.evaluate({
|
|
805
|
-
url: 'https://github.com/user/repo/issues/1',
|
|
806
|
-
labels: [],
|
|
807
|
-
isPr: false,
|
|
808
|
-
});
|
|
809
|
-
|
|
810
|
-
expect(result.rejections).toHaveLength(1);
|
|
811
|
-
expect(result.rejections[0].type).toBe('PULL_REQUEST_NOT_FOUND');
|
|
812
|
-
});
|
|
813
|
-
|
|
814
|
-
it('should still require PR when JSON block with pullRequestRequired: false is not at end of body', async () => {
|
|
815
|
-
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
816
|
-
const body =
|
|
817
|
-
'```json\n{"pullRequestRequired": false}\n```\n\nsome text after';
|
|
818
|
-
|
|
819
|
-
const result = await evaluator.evaluate({
|
|
820
|
-
url: 'https://github.com/user/repo/issues/1',
|
|
821
|
-
labels: [],
|
|
822
|
-
isPr: false,
|
|
823
|
-
body,
|
|
824
|
-
});
|
|
825
|
-
|
|
826
|
-
expect(result.rejections).toHaveLength(1);
|
|
827
|
-
expect(result.rejections[0].type).toBe('PULL_REQUEST_NOT_FOUND');
|
|
828
|
-
});
|
|
829
|
-
|
|
830
|
-
it('should still require PR when body has invalid JSON in code block', async () => {
|
|
831
|
-
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
832
|
-
const body = '```json\n{invalid json}\n```';
|
|
833
|
-
|
|
834
|
-
const result = await evaluator.evaluate({
|
|
835
|
-
url: 'https://github.com/user/repo/issues/1',
|
|
836
|
-
labels: [],
|
|
837
|
-
isPr: false,
|
|
838
|
-
body,
|
|
839
|
-
});
|
|
840
|
-
|
|
841
|
-
expect(result.rejections).toHaveLength(1);
|
|
842
|
-
expect(result.rejections[0].type).toBe('PULL_REQUEST_NOT_FOUND');
|
|
843
|
-
});
|
|
844
|
-
|
|
845
|
-
it('should still require PR when body has pullRequestRequired not set to false', async () => {
|
|
846
|
-
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([]);
|
|
847
|
-
const body = '```json\n{"someOtherField": true}\n```';
|
|
848
|
-
|
|
849
|
-
const result = await evaluator.evaluate({
|
|
850
|
-
url: 'https://github.com/user/repo/issues/1',
|
|
851
|
-
labels: [],
|
|
852
|
-
isPr: false,
|
|
853
|
-
body,
|
|
854
|
-
});
|
|
855
|
-
|
|
856
|
-
expect(result.rejections).toHaveLength(1);
|
|
857
|
-
expect(result.rejections[0].type).toBe('PULL_REQUEST_NOT_FOUND');
|
|
858
|
-
});
|
|
859
|
-
});
|
|
860
|
-
|
|
861
742
|
describe('detectConflictEvenIfEvaluationSkipped option', () => {
|
|
862
743
|
it('should call findRelatedOpenPRs and return PULL_REQUEST_CONFLICTED when relatedOpenPrUrls is null and PR is conflicted', async () => {
|
|
863
744
|
mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
IssueRepository,
|
|
3
3
|
RelatedPullRequest,
|
|
4
4
|
} from './adapter-interfaces/IssueRepository';
|
|
5
|
-
import { normalizeReportBody } from './normalizeReportBody';
|
|
6
5
|
|
|
7
6
|
export type PrRejectedReasonType =
|
|
8
7
|
| 'PULL_REQUEST_NOT_FOUND'
|
|
@@ -243,7 +242,6 @@ export class IssueRejectionEvaluator {
|
|
|
243
242
|
return (
|
|
244
243
|
!isNonDeveloperAgent &&
|
|
245
244
|
!hasLabelNotRequiringPullRequest &&
|
|
246
|
-
this.isPullRequestRequiredByBody(issue.body) &&
|
|
247
245
|
(categoryLabels.length <= 0 || categoryLabels.includes('category:e2e'))
|
|
248
246
|
);
|
|
249
247
|
};
|
|
@@ -337,23 +335,4 @@ export class IssueRejectionEvaluator {
|
|
|
337
335
|
targetPath: string,
|
|
338
336
|
): boolean =>
|
|
339
337
|
filePath === targetPath || filePath.startsWith(`${targetPath}/`);
|
|
340
|
-
|
|
341
|
-
private isPullRequestRequiredByBody = (
|
|
342
|
-
body: string | null | undefined,
|
|
343
|
-
): boolean => {
|
|
344
|
-
if (!body) return true;
|
|
345
|
-
const match = normalizeReportBody(body)
|
|
346
|
-
.trimEnd()
|
|
347
|
-
.match(/```json\n([\s\S]*?)\n```\s*$/);
|
|
348
|
-
if (!match || !match[1]) return true;
|
|
349
|
-
let config: unknown;
|
|
350
|
-
try {
|
|
351
|
-
config = JSON.parse(match[1]);
|
|
352
|
-
} catch {
|
|
353
|
-
return true;
|
|
354
|
-
}
|
|
355
|
-
if (typeof config !== 'object' || config === null) return true;
|
|
356
|
-
if (!('pullRequestRequired' in config)) return true;
|
|
357
|
-
return Reflect.get(config, 'pullRequestRequired') !== false;
|
|
358
|
-
};
|
|
359
338
|
}
|