github-issue-tower-defence-management 1.49.0 → 1.49.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 +14 -0
- package/README.md +2 -6
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +36 -61
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
- package/bin/adapter/repositories/GitHubIssueCommentRepository.js +17 -54
- package/bin/adapter/repositories/GitHubIssueCommentRepository.js.map +1 -1
- package/bin/domain/usecases/HandleScheduledEventUseCase.js +2 -15
- package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js +2 -1
- package/bin/domain/usecases/RevertOrphanedPreparationUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.test.ts +1 -16
- package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +1 -24
- package/src/adapter/repositories/GitHubIssueCommentRepository.test.ts +173 -0
- package/src/adapter/repositories/GitHubIssueCommentRepository.ts +22 -83
- package/src/domain/usecases/HandleScheduledEventUseCase.test.ts +37 -4
- package/src/domain/usecases/HandleScheduledEventUseCase.ts +3 -23
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.ts +4 -1
- package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
- package/types/adapter/repositories/GitHubIssueCommentRepository.d.ts.map +1 -1
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +2 -7
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
- package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts +1 -0
- package/types/domain/usecases/RevertOrphanedPreparationUseCase.d.ts.map +1 -1
|
@@ -99,20 +99,9 @@ jest.mock('../../repositories/NodeLocalCommandRunner', () => ({
|
|
|
99
99
|
jest.mock('../../repositories/OauthAPIProxyClaudeRepository', () => ({
|
|
100
100
|
OauthAPIProxyClaudeRepository: jest.fn().mockImplementation(() => ({})),
|
|
101
101
|
}));
|
|
102
|
-
jest.mock(
|
|
103
|
-
'../../../domain/usecases/NotifyFinishedIssuePreparationUseCase',
|
|
104
|
-
() => ({
|
|
105
|
-
NotifyFinishedIssuePreparationUseCase: jest
|
|
106
|
-
.fn()
|
|
107
|
-
.mockImplementation(() => ({})),
|
|
108
|
-
}),
|
|
109
|
-
);
|
|
110
102
|
jest.mock('../../repositories/GitHubIssueCommentRepository', () => ({
|
|
111
103
|
GitHubIssueCommentRepository: jest.fn().mockImplementation(() => ({})),
|
|
112
104
|
}));
|
|
113
|
-
jest.mock('../../repositories/FetchWebhookRepository', () => ({
|
|
114
|
-
FetchWebhookRepository: jest.fn().mockImplementation(() => ({})),
|
|
115
|
-
}));
|
|
116
105
|
jest.mock('./situationFileWriter', () => ({
|
|
117
106
|
writeSituationFile: jest.fn().mockResolvedValue(undefined),
|
|
118
107
|
}));
|
|
@@ -270,10 +259,6 @@ describe('HandleScheduledEventUseCaseHandler', () => {
|
|
|
270
259
|
maximumPreparingIssuesCount: 10,
|
|
271
260
|
utilizationPercentageThreshold: 97,
|
|
272
261
|
},
|
|
273
|
-
notifyFinishedPreparation: {
|
|
274
|
-
thresholdForAutoReject: 30,
|
|
275
|
-
workflowBlockerResolvedWebhookUrl: null,
|
|
276
|
-
},
|
|
277
262
|
};
|
|
278
263
|
jest
|
|
279
264
|
.mocked(fs.readFileSync)
|
|
@@ -289,7 +274,7 @@ describe('HandleScheduledEventUseCaseHandler', () => {
|
|
|
289
274
|
expect(firstCallArg.config.maximumPreparingIssuesCount).toBe(10);
|
|
290
275
|
expect(firstCallArg.config.utilizationPercentageThreshold).toBe(97);
|
|
291
276
|
expect(firstCallArg.config.allowIssueCacheMinutes).toBe(5);
|
|
292
|
-
expect(firstCallArg.config.thresholdForAutoReject).toBe(
|
|
277
|
+
expect(firstCallArg.config.thresholdForAutoReject).toBe(3);
|
|
293
278
|
expect(firstCallArg.statusNames.awaitingQualityCheckStatus).toBe(
|
|
294
279
|
'Awaiting Quality Check',
|
|
295
280
|
);
|
|
@@ -35,10 +35,8 @@ import { UpdateIssueStatusByLabelUseCase } from '../../../domain/usecases/Update
|
|
|
35
35
|
import { StartPreparationUseCase } from '../../../domain/usecases/StartPreparationUseCase';
|
|
36
36
|
import { NodeLocalCommandRunner } from '../../repositories/NodeLocalCommandRunner';
|
|
37
37
|
import { OauthAPIProxyClaudeRepository } from '../../repositories/OauthAPIProxyClaudeRepository';
|
|
38
|
-
import { NotifyFinishedIssuePreparationUseCase } from '../../../domain/usecases/NotifyFinishedIssuePreparationUseCase';
|
|
39
38
|
import { RevertOrphanedPreparationUseCase } from '../../../domain/usecases/RevertOrphanedPreparationUseCase';
|
|
40
39
|
import { GitHubIssueCommentRepository } from '../../repositories/GitHubIssueCommentRepository';
|
|
41
|
-
import { FetchWebhookRepository } from '../../repositories/FetchWebhookRepository';
|
|
42
40
|
import { SetupTowerDefenceProjectUseCase } from '../../../domain/usecases/SetupTowerDefenceProjectUseCase';
|
|
43
41
|
import {
|
|
44
42
|
AWAITING_QUALITY_CHECK_STATUS_NAME,
|
|
@@ -131,17 +129,6 @@ export class HandleScheduledEventUseCaseHandler {
|
|
|
131
129
|
input.startPreparation.codexHomeCandidates,
|
|
132
130
|
}
|
|
133
131
|
: input.startPreparation,
|
|
134
|
-
notifyFinishedPreparation: input.notifyFinishedPreparation
|
|
135
|
-
? {
|
|
136
|
-
...input.notifyFinishedPreparation,
|
|
137
|
-
thresholdForAutoReject:
|
|
138
|
-
readmeConfig.thresholdForAutoReject ??
|
|
139
|
-
input.notifyFinishedPreparation.thresholdForAutoReject,
|
|
140
|
-
workflowBlockerResolvedWebhookUrl:
|
|
141
|
-
readmeConfig.workflowBlockerResolvedWebhookUrl ??
|
|
142
|
-
input.notifyFinishedPreparation.workflowBlockerResolvedWebhookUrl,
|
|
143
|
-
}
|
|
144
|
-
: input.notifyFinishedPreparation,
|
|
145
132
|
};
|
|
146
133
|
|
|
147
134
|
const systemDateRepository = new SystemDateRepository();
|
|
@@ -238,14 +225,6 @@ export class HandleScheduledEventUseCaseHandler {
|
|
|
238
225
|
const issueCommentRepository = new GitHubIssueCommentRepository(
|
|
239
226
|
input.credentials.bot.github.token,
|
|
240
227
|
);
|
|
241
|
-
const webhookRepository = new FetchWebhookRepository();
|
|
242
|
-
const notifyFinishedIssuePreparationUseCase =
|
|
243
|
-
new NotifyFinishedIssuePreparationUseCase(
|
|
244
|
-
projectRepository,
|
|
245
|
-
issueRepository,
|
|
246
|
-
issueCommentRepository,
|
|
247
|
-
webhookRepository,
|
|
248
|
-
);
|
|
249
228
|
const revertOrphanedPreparationUseCase =
|
|
250
229
|
new RevertOrphanedPreparationUseCase(
|
|
251
230
|
projectRepository,
|
|
@@ -270,7 +249,6 @@ export class HandleScheduledEventUseCaseHandler {
|
|
|
270
249
|
assignNoAssigneeIssueToManagerUseCase,
|
|
271
250
|
updateIssueStatusByLabelUseCase,
|
|
272
251
|
startPreparationUseCase,
|
|
273
|
-
notifyFinishedIssuePreparationUseCase,
|
|
274
252
|
revertOrphanedPreparationUseCase,
|
|
275
253
|
systemDateRepository,
|
|
276
254
|
googleSpreadsheetRepository,
|
|
@@ -295,8 +273,7 @@ export class HandleScheduledEventUseCaseHandler {
|
|
|
295
273
|
utilizationPercentageThreshold:
|
|
296
274
|
mergedInput.startPreparation?.utilizationPercentageThreshold ?? 90,
|
|
297
275
|
allowIssueCacheMinutes: mergedInput.allowIssueCacheMinutes,
|
|
298
|
-
thresholdForAutoReject:
|
|
299
|
-
mergedInput.notifyFinishedPreparation?.thresholdForAutoReject ?? 3,
|
|
276
|
+
thresholdForAutoReject: 3,
|
|
300
277
|
},
|
|
301
278
|
preparationProcessCheckCommand:
|
|
302
279
|
mergedInput.startPreparation?.preparationProcessCheckCommand ?? null,
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { GitHubIssueCommentRepository } from './GitHubIssueCommentRepository';
|
|
2
|
+
import { Issue } from '../../domain/entities/Issue';
|
|
3
|
+
|
|
4
|
+
const buildIssue = (url: string): Issue => ({
|
|
5
|
+
url,
|
|
6
|
+
nameWithOwner: 'HiromiShikata/test-repo',
|
|
7
|
+
number: 123,
|
|
8
|
+
title: 'Test Issue',
|
|
9
|
+
state: 'OPEN',
|
|
10
|
+
status: null,
|
|
11
|
+
story: null,
|
|
12
|
+
nextActionDate: null,
|
|
13
|
+
nextActionHour: null,
|
|
14
|
+
estimationMinutes: null,
|
|
15
|
+
dependedIssueUrls: [],
|
|
16
|
+
completionDate50PercentConfidence: null,
|
|
17
|
+
assignees: [],
|
|
18
|
+
labels: [],
|
|
19
|
+
org: 'HiromiShikata',
|
|
20
|
+
repo: 'test-repo',
|
|
21
|
+
body: '',
|
|
22
|
+
itemId: 'item-1',
|
|
23
|
+
isPr: false,
|
|
24
|
+
isInProgress: false,
|
|
25
|
+
isClosed: false,
|
|
26
|
+
createdAt: new Date('2024-01-01T00:00:00Z'),
|
|
27
|
+
author: 'testuser',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const TEST_URL = 'https://github.com/HiromiShikata/test-repo/issues/123';
|
|
31
|
+
const EXPECTED_REST_URL =
|
|
32
|
+
'https://api.github.com/repos/HiromiShikata/test-repo/issues/123/comments?per_page=100&page=1';
|
|
33
|
+
|
|
34
|
+
describe('GitHubIssueCommentRepository', () => {
|
|
35
|
+
let repository: GitHubIssueCommentRepository;
|
|
36
|
+
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
jest.restoreAllMocks();
|
|
39
|
+
repository = new GitHubIssueCommentRepository('test-token');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe('getCommentsFromIssue', () => {
|
|
43
|
+
it('fetches single page with correct REST endpoint URL and headers, and maps comments correctly', async () => {
|
|
44
|
+
const commentPayloads = [
|
|
45
|
+
{
|
|
46
|
+
user: { login: 'testuser' },
|
|
47
|
+
body: 'Comment body',
|
|
48
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
const fetchSpy = jest
|
|
52
|
+
.spyOn(global, 'fetch')
|
|
53
|
+
.mockResolvedValue(
|
|
54
|
+
new Response(JSON.stringify(commentPayloads), { status: 200 }),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const result = await repository.getCommentsFromIssue(
|
|
58
|
+
buildIssue(TEST_URL),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
|
62
|
+
expect(fetchSpy).toHaveBeenCalledWith(EXPECTED_REST_URL, {
|
|
63
|
+
headers: {
|
|
64
|
+
Authorization: 'Bearer test-token',
|
|
65
|
+
Accept: 'application/vnd.github+json',
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
expect(result).toEqual([
|
|
69
|
+
{
|
|
70
|
+
author: 'testuser',
|
|
71
|
+
content: 'Comment body',
|
|
72
|
+
createdAt: new Date('2024-01-01T00:00:00Z'),
|
|
73
|
+
},
|
|
74
|
+
]);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('fetches two pages when first response contains rel="next" Link header', async () => {
|
|
78
|
+
const page1Payloads = [
|
|
79
|
+
{
|
|
80
|
+
user: { login: 'user1' },
|
|
81
|
+
body: 'Page 1 comment',
|
|
82
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
const page2Payloads = [
|
|
86
|
+
{
|
|
87
|
+
user: { login: 'user2' },
|
|
88
|
+
body: 'Page 2 comment',
|
|
89
|
+
created_at: '2024-01-02T00:00:00Z',
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const fetchSpy = jest
|
|
94
|
+
.spyOn(global, 'fetch')
|
|
95
|
+
.mockResolvedValueOnce(
|
|
96
|
+
new Response(JSON.stringify(page1Payloads), {
|
|
97
|
+
status: 200,
|
|
98
|
+
headers: {
|
|
99
|
+
Link: '<https://api.github.com/repos/HiromiShikata/test-repo/issues/123/comments?per_page=100&page=2>; rel="next"',
|
|
100
|
+
},
|
|
101
|
+
}),
|
|
102
|
+
)
|
|
103
|
+
.mockResolvedValueOnce(
|
|
104
|
+
new Response(JSON.stringify(page2Payloads), { status: 200 }),
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const result = await repository.getCommentsFromIssue(
|
|
108
|
+
buildIssue(TEST_URL),
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
expect(fetchSpy).toHaveBeenCalledTimes(2);
|
|
112
|
+
expect(fetchSpy).toHaveBeenNthCalledWith(
|
|
113
|
+
1,
|
|
114
|
+
'https://api.github.com/repos/HiromiShikata/test-repo/issues/123/comments?per_page=100&page=1',
|
|
115
|
+
expect.anything(),
|
|
116
|
+
);
|
|
117
|
+
expect(fetchSpy).toHaveBeenNthCalledWith(
|
|
118
|
+
2,
|
|
119
|
+
'https://api.github.com/repos/HiromiShikata/test-repo/issues/123/comments?per_page=100&page=2',
|
|
120
|
+
expect.anything(),
|
|
121
|
+
);
|
|
122
|
+
expect(result).toEqual([
|
|
123
|
+
{
|
|
124
|
+
author: 'user1',
|
|
125
|
+
content: 'Page 1 comment',
|
|
126
|
+
createdAt: new Date('2024-01-01T00:00:00Z'),
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
author: 'user2',
|
|
130
|
+
content: 'Page 2 comment',
|
|
131
|
+
createdAt: new Date('2024-01-02T00:00:00Z'),
|
|
132
|
+
},
|
|
133
|
+
]);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('maps author to empty string when user field is null (ghost user)', async () => {
|
|
137
|
+
const commentPayloads = [
|
|
138
|
+
{
|
|
139
|
+
user: null,
|
|
140
|
+
body: 'Ghost comment',
|
|
141
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
142
|
+
},
|
|
143
|
+
];
|
|
144
|
+
jest
|
|
145
|
+
.spyOn(global, 'fetch')
|
|
146
|
+
.mockResolvedValue(
|
|
147
|
+
new Response(JSON.stringify(commentPayloads), { status: 200 }),
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
const result = await repository.getCommentsFromIssue(
|
|
151
|
+
buildIssue(TEST_URL),
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
expect(result[0].author).toBe('');
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('throws an error including status and statusText when response is non-2xx', async () => {
|
|
158
|
+
jest.spyOn(global, 'fetch').mockResolvedValue(
|
|
159
|
+
new Response('Not Found', {
|
|
160
|
+
status: 404,
|
|
161
|
+
statusText: 'Not Found',
|
|
162
|
+
}),
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
await expect(
|
|
166
|
+
repository.getCommentsFromIssue(buildIssue(TEST_URL)),
|
|
167
|
+
).rejects.toThrow('404');
|
|
168
|
+
await expect(
|
|
169
|
+
repository.getCommentsFromIssue(buildIssue(TEST_URL)),
|
|
170
|
+
).rejects.toThrow('Not Found');
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -2,31 +2,10 @@ import { IssueCommentRepository } from '../../domain/usecases/adapter-interfaces
|
|
|
2
2
|
import { Issue } from '../../domain/entities/Issue';
|
|
3
3
|
import { Comment } from '../../domain/entities/Comment';
|
|
4
4
|
|
|
5
|
-
type
|
|
6
|
-
|
|
7
|
-
login: string;
|
|
8
|
-
} | null;
|
|
5
|
+
type RestCommentPayload = {
|
|
6
|
+
user: { login: string } | null;
|
|
9
7
|
body: string;
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
type CommentsData = {
|
|
14
|
-
comments: {
|
|
15
|
-
pageInfo: {
|
|
16
|
-
endCursor: string;
|
|
17
|
-
hasNextPage: boolean;
|
|
18
|
-
};
|
|
19
|
-
nodes: CommentNode[];
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
type IssueCommentsResponse = {
|
|
24
|
-
data?: {
|
|
25
|
-
repository?: {
|
|
26
|
-
issue?: CommentsData;
|
|
27
|
-
pullRequest?: CommentsData;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
8
|
+
created_at: string;
|
|
30
9
|
};
|
|
31
10
|
|
|
32
11
|
type CreateCommentResponse = {
|
|
@@ -55,10 +34,10 @@ type IssueIdResponse = {
|
|
|
55
34
|
};
|
|
56
35
|
};
|
|
57
36
|
|
|
58
|
-
function
|
|
37
|
+
function isRestCommentPayloadArray(
|
|
59
38
|
value: unknown,
|
|
60
|
-
): value is
|
|
61
|
-
if (
|
|
39
|
+
): value is RestCommentPayload[] {
|
|
40
|
+
if (!Array.isArray(value)) return false;
|
|
62
41
|
return true;
|
|
63
42
|
}
|
|
64
43
|
|
|
@@ -98,86 +77,46 @@ export class GitHubIssueCommentRepository implements IssueCommentRepository {
|
|
|
98
77
|
}
|
|
99
78
|
|
|
100
79
|
async getCommentsFromIssue(issue: Issue): Promise<Comment[]> {
|
|
101
|
-
const { owner, repo, issueNumber
|
|
102
|
-
|
|
103
|
-
const entityType = isPr ? 'pullRequest' : 'issue';
|
|
104
|
-
const query = `
|
|
105
|
-
query($owner: String!, $repo: String!, $issueNumber: Int!, $after: String) {
|
|
106
|
-
repository(owner: $owner, name: $repo) {
|
|
107
|
-
${entityType}(number: $issueNumber) {
|
|
108
|
-
comments(first: 100, after: $after) {
|
|
109
|
-
pageInfo {
|
|
110
|
-
endCursor
|
|
111
|
-
hasNextPage
|
|
112
|
-
}
|
|
113
|
-
nodes {
|
|
114
|
-
author {
|
|
115
|
-
login
|
|
116
|
-
}
|
|
117
|
-
body
|
|
118
|
-
createdAt
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
`;
|
|
80
|
+
const { owner, repo, issueNumber } = this.parseIssueUrl(issue);
|
|
125
81
|
|
|
126
82
|
const comments: Comment[] = [];
|
|
127
|
-
let
|
|
83
|
+
let page = 1;
|
|
128
84
|
let hasNextPage = true;
|
|
129
85
|
|
|
130
86
|
while (hasNextPage) {
|
|
131
|
-
const
|
|
132
|
-
|
|
87
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}/comments?per_page=100&page=${page}`;
|
|
88
|
+
const response = await fetch(url, {
|
|
133
89
|
headers: {
|
|
134
90
|
Authorization: `Bearer ${this.token}`,
|
|
135
|
-
|
|
91
|
+
Accept: 'application/vnd.github+json',
|
|
136
92
|
},
|
|
137
|
-
body: JSON.stringify({
|
|
138
|
-
query,
|
|
139
|
-
variables: {
|
|
140
|
-
owner,
|
|
141
|
-
repo,
|
|
142
|
-
issueNumber,
|
|
143
|
-
after,
|
|
144
|
-
},
|
|
145
|
-
}),
|
|
146
93
|
});
|
|
147
94
|
|
|
148
95
|
if (!response.ok) {
|
|
149
96
|
throw new Error(
|
|
150
|
-
`Failed to fetch comments from GitHub
|
|
97
|
+
`Failed to fetch comments from GitHub REST API: ${response.status} ${response.statusText}`,
|
|
151
98
|
);
|
|
152
99
|
}
|
|
153
100
|
|
|
154
101
|
const responseData: unknown = await response.json();
|
|
155
|
-
if (!
|
|
156
|
-
throw new Error(
|
|
157
|
-
'Unexpected response shape when fetching comments from GitHub GraphQL API',
|
|
158
|
-
);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const issueData = isPr
|
|
162
|
-
? responseData.data?.repository?.pullRequest
|
|
163
|
-
: responseData.data?.repository?.issue;
|
|
164
|
-
if (!issueData) {
|
|
102
|
+
if (!isRestCommentPayloadArray(responseData)) {
|
|
165
103
|
throw new Error(
|
|
166
|
-
|
|
104
|
+
'Unexpected response shape when fetching comments from GitHub REST API',
|
|
167
105
|
);
|
|
168
106
|
}
|
|
169
107
|
|
|
170
|
-
const
|
|
171
|
-
for (const node of commentNodes) {
|
|
108
|
+
for (const payload of responseData) {
|
|
172
109
|
comments.push({
|
|
173
|
-
author:
|
|
174
|
-
content:
|
|
175
|
-
createdAt: new Date(
|
|
110
|
+
author: payload.user?.login ?? '',
|
|
111
|
+
content: payload.body,
|
|
112
|
+
createdAt: new Date(payload.created_at),
|
|
176
113
|
});
|
|
177
114
|
}
|
|
178
115
|
|
|
179
|
-
|
|
180
|
-
|
|
116
|
+
const linkHeader = response.headers.get('Link') ?? '';
|
|
117
|
+
hasNextPage = linkHeader.includes('rel="next"');
|
|
118
|
+
|
|
119
|
+
page++;
|
|
181
120
|
}
|
|
182
121
|
|
|
183
122
|
return comments;
|
|
@@ -20,7 +20,6 @@ import { CreateNewStoryByLabelUseCase } from './CreateNewStoryByLabelUseCase';
|
|
|
20
20
|
import { AssignNoAssigneeIssueToManagerUseCase } from './AssignNoAssigneeIssueToManagerUseCase';
|
|
21
21
|
import { UpdateIssueStatusByLabelUseCase } from './UpdateIssueStatusByLabelUseCase';
|
|
22
22
|
import { StartPreparationUseCase } from './StartPreparationUseCase';
|
|
23
|
-
import { NotifyFinishedIssuePreparationUseCase } from './NotifyFinishedIssuePreparationUseCase';
|
|
24
23
|
import { RevertOrphanedPreparationUseCase } from './RevertOrphanedPreparationUseCase';
|
|
25
24
|
import { SetupTowerDefenceProjectUseCase } from './SetupTowerDefenceProjectUseCase';
|
|
26
25
|
|
|
@@ -108,8 +107,6 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
108
107
|
const mockUpdateIssueStatusByLabelUseCase =
|
|
109
108
|
mock<UpdateIssueStatusByLabelUseCase>();
|
|
110
109
|
const mockStartPreparationUseCase = mock<StartPreparationUseCase>();
|
|
111
|
-
const mockNotifyFinishedIssuePreparationUseCase =
|
|
112
|
-
mock<NotifyFinishedIssuePreparationUseCase>();
|
|
113
110
|
const mockRevertOrphanedPreparationUseCase =
|
|
114
111
|
mock<RevertOrphanedPreparationUseCase>();
|
|
115
112
|
const mockDateRepository = mock<DateRepository>();
|
|
@@ -133,7 +130,6 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
133
130
|
mockAssignNoAssigneeIssueToManagerUseCase,
|
|
134
131
|
mockUpdateIssueStatusByLabelUseCase,
|
|
135
132
|
mockStartPreparationUseCase,
|
|
136
|
-
mockNotifyFinishedIssuePreparationUseCase,
|
|
137
133
|
mockRevertOrphanedPreparationUseCase,
|
|
138
134
|
mockDateRepository,
|
|
139
135
|
mockSpreadsheetRepository,
|
|
@@ -276,6 +272,43 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
276
272
|
);
|
|
277
273
|
});
|
|
278
274
|
|
|
275
|
+
it('should pass awaitingQualityCheckStatus to revertOrphanedPreparationUseCase when startPreparation is configured', async () => {
|
|
276
|
+
const input = {
|
|
277
|
+
projectName: 'test-project',
|
|
278
|
+
org: 'test-org',
|
|
279
|
+
projectUrl: 'https://github.com/test-org/test-project',
|
|
280
|
+
manager: 'test-manager',
|
|
281
|
+
workingReport: {
|
|
282
|
+
repo: 'test-repo',
|
|
283
|
+
members: ['member1'],
|
|
284
|
+
spreadsheetUrl: 'https://docs.google.com/spreadsheets/test',
|
|
285
|
+
},
|
|
286
|
+
urlOfStoryView: 'https://github.com/test-org/test-project/issues',
|
|
287
|
+
disabledStatus: 'disabled',
|
|
288
|
+
defaultStatus: null,
|
|
289
|
+
disabled: false,
|
|
290
|
+
allowIssueCacheMinutes: 60,
|
|
291
|
+
startPreparation: {
|
|
292
|
+
awaitingWorkspaceStatus: 'Awaiting Workspace',
|
|
293
|
+
preparationStatus: 'Preparation',
|
|
294
|
+
awaitingQualityCheckStatus: 'Awaiting Quality Check',
|
|
295
|
+
defaultAgentName: 'aw',
|
|
296
|
+
configFilePath: '/path/to/config.yml',
|
|
297
|
+
maximumPreparingIssuesCount: null,
|
|
298
|
+
preparationProcessCheckCommand: 'pgrep -f "{URL}"',
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
mockProjectRepository.getProject.mockResolvedValue(mock<Project>());
|
|
303
|
+
await useCase.run(input);
|
|
304
|
+
|
|
305
|
+
expect(mockRevertOrphanedPreparationUseCase.run).toHaveBeenCalledWith(
|
|
306
|
+
expect.objectContaining({
|
|
307
|
+
awaitingQualityCheckStatus: 'Awaiting Quality Check',
|
|
308
|
+
}),
|
|
309
|
+
);
|
|
310
|
+
});
|
|
311
|
+
|
|
279
312
|
describe('story issue creation progress logs', () => {
|
|
280
313
|
const storyInput = {
|
|
281
314
|
projectName: 'test-project',
|
|
@@ -20,10 +20,8 @@ import { CreateNewStoryByLabelUseCase } from './CreateNewStoryByLabelUseCase';
|
|
|
20
20
|
import { AssignNoAssigneeIssueToManagerUseCase } from './AssignNoAssigneeIssueToManagerUseCase';
|
|
21
21
|
import { UpdateIssueStatusByLabelUseCase } from './UpdateIssueStatusByLabelUseCase';
|
|
22
22
|
import { StartPreparationUseCase } from './StartPreparationUseCase';
|
|
23
|
-
import { NotifyFinishedIssuePreparationUseCase } from './NotifyFinishedIssuePreparationUseCase';
|
|
24
23
|
import { RevertOrphanedPreparationUseCase } from './RevertOrphanedPreparationUseCase';
|
|
25
24
|
import { SetupTowerDefenceProjectUseCase } from './SetupTowerDefenceProjectUseCase';
|
|
26
|
-
import { PREPARATION_STATUS_NAME } from '../entities/WorkflowStatus';
|
|
27
25
|
|
|
28
26
|
export class ProjectNotFoundError extends Error {
|
|
29
27
|
constructor(message: string) {
|
|
@@ -49,7 +47,6 @@ export class HandleScheduledEventUseCase {
|
|
|
49
47
|
readonly assignNoAssigneeIssueToManagerUseCase: AssignNoAssigneeIssueToManagerUseCase,
|
|
50
48
|
readonly updateIssueStatusByLabelUseCase: UpdateIssueStatusByLabelUseCase,
|
|
51
49
|
readonly startPreparationUseCase: StartPreparationUseCase,
|
|
52
|
-
readonly notifyFinishedIssuePreparationUseCase: NotifyFinishedIssuePreparationUseCase,
|
|
53
50
|
readonly revertOrphanedPreparationUseCase: RevertOrphanedPreparationUseCase,
|
|
54
51
|
readonly dateRepository: DateRepository,
|
|
55
52
|
readonly spreadsheetRepository: SpreadsheetRepository,
|
|
@@ -82,10 +79,7 @@ export class HandleScheduledEventUseCase {
|
|
|
82
79
|
codexHomeCandidates?: string[] | null;
|
|
83
80
|
awLogDirectoryPath?: string;
|
|
84
81
|
awLogStaleThresholdMinutes?: number;
|
|
85
|
-
|
|
86
|
-
notifyFinishedPreparation?: {
|
|
87
|
-
thresholdForAutoReject: number;
|
|
88
|
-
workflowBlockerResolvedWebhookUrl: string | null;
|
|
82
|
+
awaitingQualityCheckStatus?: string | null;
|
|
89
83
|
} | null;
|
|
90
84
|
}): Promise<{
|
|
91
85
|
project: Project;
|
|
@@ -338,6 +332,8 @@ ${JSON.stringify(e)}
|
|
|
338
332
|
awLogDirectoryPath: input.startPreparation.awLogDirectoryPath,
|
|
339
333
|
awLogStaleThresholdMinutes:
|
|
340
334
|
input.startPreparation.awLogStaleThresholdMinutes,
|
|
335
|
+
awaitingQualityCheckStatus:
|
|
336
|
+
input.startPreparation.awaitingQualityCheckStatus ?? undefined,
|
|
341
337
|
});
|
|
342
338
|
}
|
|
343
339
|
await this.startPreparationUseCase.run({
|
|
@@ -355,22 +351,6 @@ ${JSON.stringify(e)}
|
|
|
355
351
|
allowIssueCacheMinutes: input.allowIssueCacheMinutes,
|
|
356
352
|
});
|
|
357
353
|
}
|
|
358
|
-
if (input.notifyFinishedPreparation) {
|
|
359
|
-
const notifyFinishedPreparation = input.notifyFinishedPreparation;
|
|
360
|
-
const preparationIssues = issues.filter(
|
|
361
|
-
(issue) => issue.status === PREPARATION_STATUS_NAME,
|
|
362
|
-
);
|
|
363
|
-
for (const issue of preparationIssues) {
|
|
364
|
-
await this.notifyFinishedIssuePreparationUseCase.run({
|
|
365
|
-
projectUrl: input.projectUrl,
|
|
366
|
-
issueUrl: issue.url,
|
|
367
|
-
thresholdForAutoReject:
|
|
368
|
-
notifyFinishedPreparation.thresholdForAutoReject,
|
|
369
|
-
workflowBlockerResolvedWebhookUrl:
|
|
370
|
-
notifyFinishedPreparation.workflowBlockerResolvedWebhookUrl,
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
354
|
};
|
|
375
355
|
static createTargetDateTimes = (from: Date, to: Date): Date[] => {
|
|
376
356
|
const targetDateTimes: Date[] = [];
|
|
@@ -38,6 +38,7 @@ export class RevertOrphanedPreparationUseCase {
|
|
|
38
38
|
preparationProcessCheckCommand: string;
|
|
39
39
|
awLogDirectoryPath?: string;
|
|
40
40
|
awLogStaleThresholdMinutes?: number;
|
|
41
|
+
awaitingQualityCheckStatus?: string | null;
|
|
41
42
|
}): Promise<void> => {
|
|
42
43
|
const projectId = await this.projectRepository.findProjectIdByUrl(
|
|
43
44
|
params.projectUrl,
|
|
@@ -67,8 +68,10 @@ export class RevertOrphanedPreparationUseCase {
|
|
|
67
68
|
return;
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
const resolvedQualityCheckStatusName =
|
|
72
|
+
params.awaitingQualityCheckStatus ?? AWAITING_QUALITY_CHECK_STATUS_NAME;
|
|
70
73
|
const awaitingQualityCheckStatusOption = project.status.statuses.find(
|
|
71
|
-
(s) => s.name ===
|
|
74
|
+
(s) => s.name === resolvedQualityCheckStatusName,
|
|
72
75
|
);
|
|
73
76
|
|
|
74
77
|
for (const issue of preparationIssues) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAuB3D,qBAAa,kCAAkC;IAC7C,MAAM,GACJ,gBAAgB,MAAM,EACtB,UAAU,OAAO,KAChB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,eAAe,EAAE,IAAI,EAAE,CAAC;KACzB,GAAG,IAAI,CAAC,CAoOP;CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GitHubIssueCommentRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/GitHubIssueCommentRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iEAAiE,CAAC;AACzG,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"GitHubIssueCommentRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/GitHubIssueCommentRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iEAAiE,CAAC;AACzG,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAqDxD,qBAAa,4BAA6B,YAAW,sBAAsB;IAC7D,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,MAAM;IAE1C,OAAO,CAAC,aAAa;IAoBf,oBAAoB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;YA8C9C,cAAc;IAuDtB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAkDzE"}
|
|
@@ -20,7 +20,6 @@ import { CreateNewStoryByLabelUseCase } from './CreateNewStoryByLabelUseCase';
|
|
|
20
20
|
import { AssignNoAssigneeIssueToManagerUseCase } from './AssignNoAssigneeIssueToManagerUseCase';
|
|
21
21
|
import { UpdateIssueStatusByLabelUseCase } from './UpdateIssueStatusByLabelUseCase';
|
|
22
22
|
import { StartPreparationUseCase } from './StartPreparationUseCase';
|
|
23
|
-
import { NotifyFinishedIssuePreparationUseCase } from './NotifyFinishedIssuePreparationUseCase';
|
|
24
23
|
import { RevertOrphanedPreparationUseCase } from './RevertOrphanedPreparationUseCase';
|
|
25
24
|
import { SetupTowerDefenceProjectUseCase } from './SetupTowerDefenceProjectUseCase';
|
|
26
25
|
export declare class ProjectNotFoundError extends Error {
|
|
@@ -42,13 +41,12 @@ export declare class HandleScheduledEventUseCase {
|
|
|
42
41
|
readonly assignNoAssigneeIssueToManagerUseCase: AssignNoAssigneeIssueToManagerUseCase;
|
|
43
42
|
readonly updateIssueStatusByLabelUseCase: UpdateIssueStatusByLabelUseCase;
|
|
44
43
|
readonly startPreparationUseCase: StartPreparationUseCase;
|
|
45
|
-
readonly notifyFinishedIssuePreparationUseCase: NotifyFinishedIssuePreparationUseCase;
|
|
46
44
|
readonly revertOrphanedPreparationUseCase: RevertOrphanedPreparationUseCase;
|
|
47
45
|
readonly dateRepository: DateRepository;
|
|
48
46
|
readonly spreadsheetRepository: SpreadsheetRepository;
|
|
49
47
|
readonly projectRepository: ProjectRepository;
|
|
50
48
|
readonly issueRepository: IssueRepository;
|
|
51
|
-
constructor(setupTowerDefenceProjectUseCase: SetupTowerDefenceProjectUseCase, actionAnnouncementUseCase: ActionAnnouncementUseCase, setWorkflowManagementIssueToStoryUseCase: SetWorkflowManagementIssueToStoryUseCase, clearPastNextActionUseCase: ClearPastNextActionDateHourUseCase, analyzeProblemByIssueUseCase: AnalyzeProblemByIssueUseCase, analyzeStoriesUseCase: AnalyzeStoriesUseCase, clearDependedIssueURLUseCase: ClearDependedIssueURLUseCase, createEstimationIssueUseCase: CreateEstimationIssueUseCase, convertCheckboxToIssueInStoryIssueUseCase: ConvertCheckboxToIssueInStoryIssueUseCase, changeStatusByStoryColorUseCase: ChangeStatusByStoryColorUseCase, setNoStoryIssueToStoryUseCase: SetNoStoryIssueToStoryUseCase, createNewStoryByLabelUseCase: CreateNewStoryByLabelUseCase, assignNoAssigneeIssueToManagerUseCase: AssignNoAssigneeIssueToManagerUseCase, updateIssueStatusByLabelUseCase: UpdateIssueStatusByLabelUseCase, startPreparationUseCase: StartPreparationUseCase,
|
|
49
|
+
constructor(setupTowerDefenceProjectUseCase: SetupTowerDefenceProjectUseCase, actionAnnouncementUseCase: ActionAnnouncementUseCase, setWorkflowManagementIssueToStoryUseCase: SetWorkflowManagementIssueToStoryUseCase, clearPastNextActionUseCase: ClearPastNextActionDateHourUseCase, analyzeProblemByIssueUseCase: AnalyzeProblemByIssueUseCase, analyzeStoriesUseCase: AnalyzeStoriesUseCase, clearDependedIssueURLUseCase: ClearDependedIssueURLUseCase, createEstimationIssueUseCase: CreateEstimationIssueUseCase, convertCheckboxToIssueInStoryIssueUseCase: ConvertCheckboxToIssueInStoryIssueUseCase, changeStatusByStoryColorUseCase: ChangeStatusByStoryColorUseCase, setNoStoryIssueToStoryUseCase: SetNoStoryIssueToStoryUseCase, createNewStoryByLabelUseCase: CreateNewStoryByLabelUseCase, assignNoAssigneeIssueToManagerUseCase: AssignNoAssigneeIssueToManagerUseCase, updateIssueStatusByLabelUseCase: UpdateIssueStatusByLabelUseCase, startPreparationUseCase: StartPreparationUseCase, revertOrphanedPreparationUseCase: RevertOrphanedPreparationUseCase, dateRepository: DateRepository, spreadsheetRepository: SpreadsheetRepository, projectRepository: ProjectRepository, issueRepository: IssueRepository);
|
|
52
50
|
run: (input: {
|
|
53
51
|
projectName: string;
|
|
54
52
|
org: string;
|
|
@@ -74,10 +72,7 @@ export declare class HandleScheduledEventUseCase {
|
|
|
74
72
|
codexHomeCandidates?: string[] | null;
|
|
75
73
|
awLogDirectoryPath?: string;
|
|
76
74
|
awLogStaleThresholdMinutes?: number;
|
|
77
|
-
|
|
78
|
-
notifyFinishedPreparation?: {
|
|
79
|
-
thresholdForAutoReject: number;
|
|
80
|
-
workflowBlockerResolvedWebhookUrl: string | null;
|
|
75
|
+
awaitingQualityCheckStatus?: string | null;
|
|
81
76
|
} | null;
|
|
82
77
|
}) => Promise<{
|
|
83
78
|
project: Project;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HandleScheduledEventUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/HandleScheduledEventUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,wCAAwC,EAAE,MAAM,4CAA4C,CAAC;AACtG,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,yCAAyC,EAAE,MAAM,6CAA6C,CAAC;AACxG,OAAO,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,qCAAqC,EAAE,MAAM,yCAAyC,CAAC;AAChG,OAAO,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"HandleScheduledEventUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/HandleScheduledEventUseCase.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ export declare class RevertOrphanedPreparationUseCase {
|
|
|
14
14
|
preparationProcessCheckCommand: string;
|
|
15
15
|
awLogDirectoryPath?: string;
|
|
16
16
|
awLogStaleThresholdMinutes?: number;
|
|
17
|
+
awaitingQualityCheckStatus?: string | null;
|
|
17
18
|
}) => Promise<void>;
|
|
18
19
|
private evaluateHasRejections;
|
|
19
20
|
private resolveOpenPrsForPrItem;
|