npm-cli-gh-issue-preparator 1.21.0 → 1.22.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.
Files changed (27) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +8 -0
  3. package/bin/adapter/entry-points/cli/index.js +15 -1
  4. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  5. package/bin/adapter/repositories/FetchWebhookRepository.js +15 -0
  6. package/bin/adapter/repositories/FetchWebhookRepository.js.map +1 -0
  7. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js +25 -1
  8. package/bin/domain/usecases/NotifyFinishedIssuePreparationUseCase.js.map +1 -1
  9. package/bin/domain/usecases/adapter-interfaces/WebhookRepository.js +3 -0
  10. package/bin/domain/usecases/adapter-interfaces/WebhookRepository.js.map +1 -0
  11. package/config.example.yml +1 -0
  12. package/package.json +1 -1
  13. package/src/adapter/entry-points/cli/index.test.ts +96 -0
  14. package/src/adapter/entry-points/cli/index.ts +33 -1
  15. package/src/adapter/repositories/FetchWebhookRepository.test.ts +50 -0
  16. package/src/adapter/repositories/FetchWebhookRepository.ts +12 -0
  17. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +336 -0
  18. package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts +51 -1
  19. package/src/domain/usecases/adapter-interfaces/WebhookRepository.ts +3 -0
  20. package/types/adapter/entry-points/cli/index.d.ts +1 -0
  21. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  22. package/types/adapter/repositories/FetchWebhookRepository.d.ts +5 -0
  23. package/types/adapter/repositories/FetchWebhookRepository.d.ts.map +1 -0
  24. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts +5 -1
  25. package/types/domain/usecases/NotifyFinishedIssuePreparationUseCase.d.ts.map +1 -1
  26. package/types/domain/usecases/adapter-interfaces/WebhookRepository.d.ts +4 -0
  27. package/types/domain/usecases/adapter-interfaces/WebhookRepository.d.ts.map +1 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [1.22.0](https://github.com/HiromiShikata/npm-cli-gh-issue-preparator/compare/v1.21.0...v1.22.0) (2026-03-09)
2
+
3
+
4
+ ### Features
5
+
6
+ * **core:** send webhook notification when workflow blocker issue status changes to awaiting quality check ([1269936](https://github.com/HiromiShikata/npm-cli-gh-issue-preparator/commit/1269936add37747b524cc151524c81aadd6c17e8))
7
+
1
8
  # [1.21.0](https://github.com/HiromiShikata/npm-cli-gh-issue-preparator/compare/v1.20.0...v1.21.0) (2026-03-09)
2
9
 
3
10
 
package/README.md CHANGED
@@ -50,6 +50,14 @@ npx npm-cli-gh-issue-preparator startDaemon --configFilePath ./config.yml --proj
50
50
  npx npm-cli-gh-issue-preparator notifyFinishedIssuePreparation --configFilePath ./config.yml --issueUrl <issueUrl>
51
51
  ```
52
52
 
53
+ ### Notify finished issue preparation with webhook notification
54
+
55
+ ```
56
+ npx npm-cli-gh-issue-preparator notifyFinishedIssuePreparation --configFilePath ./config.yml --issueUrl <issueUrl> --workflowBlockerResolvedWebhookUrl 'https://example.com/webhook?url={URL}&message={MESSAGE}'
57
+ ```
58
+
59
+ When a workflow blocker issue's status changes to awaiting quality check, a GET request is sent to the specified webhook URL. The `{URL}` and `{MESSAGE}` placeholders are replaced with URL-encoded values.
60
+
53
61
  ## Contributing
54
62
 
55
63
  See [CONTRIBUTING.md](./CONTRIBUTING.md)
@@ -51,6 +51,7 @@ const TowerDefenceProjectRepository_1 = require("../../repositories/TowerDefence
51
51
  const GitHubIssueCommentRepository_1 = require("../../repositories/GitHubIssueCommentRepository");
52
52
  const NodeLocalCommandRunner_1 = require("../../repositories/NodeLocalCommandRunner");
53
53
  const OauthAPIClaudeRepository_1 = require("../../repositories/OauthAPIClaudeRepository");
54
+ const FetchWebhookRepository_1 = require("../../repositories/FetchWebhookRepository");
54
55
  const getStringValue = (obj, key) => {
55
56
  const value = obj[key];
56
57
  return typeof value === 'string' ? value : undefined;
@@ -78,6 +79,7 @@ const loadConfigFile = (configFilePath) => {
78
79
  allowedIssueAuthors: getStringValue(parsed, 'allowedIssueAuthors'),
79
80
  awaitingQualityCheckStatus: getStringValue(parsed, 'awaitingQualityCheckStatus'),
80
81
  thresholdForAutoReject: getNumberValue(parsed, 'thresholdForAutoReject'),
82
+ workflowBlockerResolvedWebhookUrl: getStringValue(parsed, 'workflowBlockerResolvedWebhookUrl'),
81
83
  };
82
84
  }
83
85
  catch (error) {
@@ -198,6 +200,7 @@ program
198
200
  .option('--awaitingWorkspaceStatus <status>', 'Status for issues awaiting workspace')
199
201
  .option('--awaitingQualityCheckStatus <status>', 'Status for issues awaiting quality check')
200
202
  .option('--thresholdForAutoReject <count>', 'Threshold for auto-escalation after consecutive rejections (default: 3)')
203
+ .option('--workflowBlockerResolvedWebhookUrl <url>', 'Webhook URL to notify when a workflow blocker issue status changes to awaiting quality check. Supports {URL} and {MESSAGE} placeholders.')
201
204
  .action(async (options) => {
202
205
  const token = process.env.GH_TOKEN;
203
206
  if (!token) {
@@ -225,10 +228,20 @@ program
225
228
  console.error('awaitingQualityCheckStatus is required. Provide via --awaitingQualityCheckStatus or config file.');
226
229
  process.exit(1);
227
230
  }
231
+ const workflowBlockerResolvedWebhookUrl = options.workflowBlockerResolvedWebhookUrl ??
232
+ config.workflowBlockerResolvedWebhookUrl ??
233
+ null;
228
234
  const projectRepository = new TowerDefenceProjectRepository_1.TowerDefenceProjectRepository(options.configFilePath, token);
235
+ const towerDefenceIssueRepository = new TowerDefenceIssueRepository_1.TowerDefenceIssueRepository(options.configFilePath, token);
229
236
  const graphqlIssueRepository = new GraphqlIssueRepository_1.GraphqlIssueRepository(token);
230
237
  const issueCommentRepository = new GitHubIssueCommentRepository_1.GitHubIssueCommentRepository(token);
231
- const useCase = new NotifyFinishedIssuePreparationUseCase_1.NotifyFinishedIssuePreparationUseCase(projectRepository, graphqlIssueRepository, issueCommentRepository);
238
+ const webhookRepository = new FetchWebhookRepository_1.FetchWebhookRepository();
239
+ const useCase = new NotifyFinishedIssuePreparationUseCase_1.NotifyFinishedIssuePreparationUseCase(projectRepository, {
240
+ get: graphqlIssueRepository.get.bind(graphqlIssueRepository),
241
+ update: graphqlIssueRepository.update.bind(graphqlIssueRepository),
242
+ findRelatedOpenPRs: graphqlIssueRepository.findRelatedOpenPRs.bind(graphqlIssueRepository),
243
+ getStoryObjectMap: towerDefenceIssueRepository.getStoryObjectMap.bind(towerDefenceIssueRepository),
244
+ }, issueCommentRepository, webhookRepository);
232
245
  let thresholdForAutoReject = 3;
233
246
  const rawThreshold = options.thresholdForAutoReject ?? config.thresholdForAutoReject;
234
247
  if (rawThreshold !== undefined) {
@@ -248,6 +261,7 @@ program
248
261
  awaitingWorkspaceStatus,
249
262
  awaitingQualityCheckStatus,
250
263
  thresholdForAutoReject,
264
+ workflowBlockerResolvedWebhookUrl,
251
265
  });
252
266
  });
253
267
  /* istanbul ignore next */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FetchWebhookRepository = void 0;
4
+ class FetchWebhookRepository {
5
+ constructor() {
6
+ this.sendGetRequest = async (url) => {
7
+ const response = await fetch(url);
8
+ if (!response.ok) {
9
+ throw new Error(`Webhook request failed with status ${response.status}: ${response.statusText}`);
10
+ }
11
+ };
12
+ }
13
+ }
14
+ exports.FetchWebhookRepository = FetchWebhookRepository;
15
+ //# sourceMappingURL=FetchWebhookRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FetchWebhookRepository.js","sourceRoot":"","sources":["../../../src/adapter/repositories/FetchWebhookRepository.ts"],"names":[],"mappings":";;;AAEA,MAAa,sBAAsB;IAAnC;QACE,mBAAc,GAAG,KAAK,EAAE,GAAW,EAAiB,EAAE;YACpD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CACb,sCAAsC,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAChF,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;CAAA;AATD,wDASC"}
@@ -16,10 +16,11 @@ class IllegalIssueStatusError extends Error {
16
16
  }
17
17
  exports.IllegalIssueStatusError = IllegalIssueStatusError;
18
18
  class NotifyFinishedIssuePreparationUseCase {
19
- constructor(projectRepository, issueRepository, issueCommentRepository) {
19
+ constructor(projectRepository, issueRepository, issueCommentRepository, webhookRepository) {
20
20
  this.projectRepository = projectRepository;
21
21
  this.issueRepository = issueRepository;
22
22
  this.issueCommentRepository = issueCommentRepository;
23
+ this.webhookRepository = webhookRepository;
23
24
  this.run = async (params) => {
24
25
  let project = await this.projectRepository.getByUrl(params.projectUrl);
25
26
  project = await this.projectRepository.prepareStatus(params.preparationStatus, project);
@@ -39,6 +40,7 @@ class NotifyFinishedIssuePreparationUseCase {
39
40
  issue.status = params.awaitingQualityCheckStatus;
40
41
  await this.issueRepository.update(issue, project);
41
42
  await this.issueCommentRepository.createComment(issue, `Failed to pass the check autimatically for ${params.thresholdForAutoReject} times`);
43
+ await this.sendWorkflowBlockerNotification(params.issueUrl, params.workflowBlockerResolvedWebhookUrl, project);
42
44
  return;
43
45
  }
44
46
  const rejections = [];
@@ -101,12 +103,34 @@ class NotifyFinishedIssuePreparationUseCase {
101
103
  if (rejections.length <= 0) {
102
104
  issue.status = params.awaitingQualityCheckStatus;
103
105
  await this.issueRepository.update(issue, project);
106
+ await this.sendWorkflowBlockerNotification(params.issueUrl, params.workflowBlockerResolvedWebhookUrl, project);
104
107
  return;
105
108
  }
106
109
  issue.status = params.awaitingWorkspaceStatus;
107
110
  await this.issueRepository.update(issue, project);
108
111
  await this.issueCommentRepository.createComment(issue, `Auto Status Check: REJECTED\n${rejections.map((r) => `- ${r.detail}`).join('\n')}`);
109
112
  };
113
+ this.sendWorkflowBlockerNotification = async (issueUrl, webhookUrlTemplate, project) => {
114
+ if (webhookUrlTemplate === null) {
115
+ return;
116
+ }
117
+ try {
118
+ const storyObjectMap = await this.issueRepository.getStoryObjectMap(project);
119
+ const isWorkflowBlocker = Array.from(storyObjectMap.entries()).some(([storyName, storyObject]) => storyName.toLowerCase().includes('workflow blocker') &&
120
+ storyObject.issues.some((issue) => issue.url === issueUrl));
121
+ if (!isWorkflowBlocker) {
122
+ return;
123
+ }
124
+ const message = `Workflow blocker resolved: ${issueUrl}`;
125
+ const webhookUrl = webhookUrlTemplate
126
+ .replace('{URL}', encodeURIComponent(issueUrl))
127
+ .replace('{MESSAGE}', encodeURIComponent(message));
128
+ await this.webhookRepository.sendGetRequest(webhookUrl);
129
+ }
130
+ catch (error) {
131
+ console.warn('Failed to send workflow blocker notification:', error);
132
+ }
133
+ };
110
134
  }
111
135
  }
112
136
  exports.NotifyFinishedIssuePreparationUseCase = NotifyFinishedIssuePreparationUseCase;
@@ -1 +1 @@
1
- {"version":3,"file":"NotifyFinishedIssuePreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NotifyFinishedIssuePreparationUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=WebhookRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebhookRepository.js","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/WebhookRepository.ts"],"names":[],"mappings":""}
@@ -20,3 +20,4 @@ preparationStatus: 'Preparation'
20
20
  defaultAgentName: 'impl'
21
21
  allowedIssueAuthors: 'HiromiShikata,other-author'
22
22
  awaitingQualityCheckStatus: 'Awaiting quality check'
23
+ workflowBlockerResolvedWebhookUrl: 'https://example.com/webhook?url={URL}&message={MESSAGE}'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "npm-cli-gh-issue-preparator",
3
- "version": "1.21.0",
3
+ "version": "1.22.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "scripts": {
@@ -29,6 +29,11 @@ jest.mock('../../repositories/OauthAPIClaudeRepository', () => ({
29
29
  isClaudeAvailable: jest.fn(),
30
30
  })),
31
31
  }));
32
+ jest.mock('../../repositories/FetchWebhookRepository', () => ({
33
+ FetchWebhookRepository: jest.fn().mockImplementation(() => ({
34
+ sendGetRequest: jest.fn(),
35
+ })),
36
+ }));
32
37
 
33
38
  describe('CLI', () => {
34
39
  const originalEnv = process.env;
@@ -90,6 +95,7 @@ describe('CLI', () => {
90
95
  awaitingQualityCheckStatus: 'Awaiting QC',
91
96
  thresholdForAutoReject: 5,
92
97
  allowedIssueAuthors: 'user1,user2',
98
+ workflowBlockerResolvedWebhookUrl: 'https://example.com/webhook',
93
99
  };
94
100
  writeConfig(config);
95
101
 
@@ -1073,6 +1079,7 @@ describe('CLI', () => {
1073
1079
  awaitingWorkspaceStatus: 'Awaiting',
1074
1080
  awaitingQualityCheckStatus: 'Awaiting QC',
1075
1081
  thresholdForAutoReject: 3,
1082
+ workflowBlockerResolvedWebhookUrl: null,
1076
1083
  });
1077
1084
  });
1078
1085
 
@@ -1111,6 +1118,7 @@ describe('CLI', () => {
1111
1118
  awaitingWorkspaceStatus: 'Awaiting',
1112
1119
  awaitingQualityCheckStatus: 'Override QC',
1113
1120
  thresholdForAutoReject: 3,
1121
+ workflowBlockerResolvedWebhookUrl: null,
1114
1122
  });
1115
1123
  });
1116
1124
 
@@ -1151,6 +1159,7 @@ describe('CLI', () => {
1151
1159
  awaitingWorkspaceStatus: 'Awaiting',
1152
1160
  awaitingQualityCheckStatus: 'Awaiting QC',
1153
1161
  thresholdForAutoReject: 5,
1162
+ workflowBlockerResolvedWebhookUrl: null,
1154
1163
  });
1155
1164
  });
1156
1165
 
@@ -1193,6 +1202,7 @@ describe('CLI', () => {
1193
1202
  awaitingWorkspaceStatus: 'Awaiting',
1194
1203
  awaitingQualityCheckStatus: 'Awaiting QC',
1195
1204
  thresholdForAutoReject: 7,
1205
+ workflowBlockerResolvedWebhookUrl: null,
1196
1206
  });
1197
1207
  });
1198
1208
 
@@ -1400,5 +1410,91 @@ describe('CLI', () => {
1400
1410
  consoleErrorSpy.mockRestore();
1401
1411
  processExitSpy.mockRestore();
1402
1412
  });
1413
+
1414
+ it('should pass workflowBlockerResolvedWebhookUrl from config file', async () => {
1415
+ const configWithWebhook = {
1416
+ ...defaultConfig,
1417
+ workflowBlockerResolvedWebhookUrl:
1418
+ 'https://example.com/webhook?url={URL}',
1419
+ };
1420
+ writeConfig(configWithWebhook);
1421
+
1422
+ const mockRun = jest.fn().mockResolvedValue(undefined);
1423
+ const MockedNotifyFinishedUseCase = jest.mocked(
1424
+ NotifyFinishedIssuePreparationUseCase,
1425
+ );
1426
+
1427
+ MockedNotifyFinishedUseCase.mockImplementation(function (
1428
+ this: NotifyFinishedIssuePreparationUseCase,
1429
+ ) {
1430
+ this.run = mockRun;
1431
+ return this;
1432
+ });
1433
+
1434
+ await program.parseAsync([
1435
+ 'node',
1436
+ 'test',
1437
+ 'notifyFinishedIssuePreparation',
1438
+ '--configFilePath',
1439
+ configFilePath,
1440
+ '--issueUrl',
1441
+ 'https://github.com/test/issue/1',
1442
+ ]);
1443
+
1444
+ expect(mockRun).toHaveBeenCalledTimes(1);
1445
+ expect(mockRun).toHaveBeenCalledWith({
1446
+ projectUrl: 'https://github.com/test/project',
1447
+ issueUrl: 'https://github.com/test/issue/1',
1448
+ preparationStatus: 'Preparing',
1449
+ awaitingWorkspaceStatus: 'Awaiting',
1450
+ awaitingQualityCheckStatus: 'Awaiting QC',
1451
+ thresholdForAutoReject: 3,
1452
+ workflowBlockerResolvedWebhookUrl:
1453
+ 'https://example.com/webhook?url={URL}',
1454
+ });
1455
+ });
1456
+
1457
+ it('should pass workflowBlockerResolvedWebhookUrl from CLI overriding config', async () => {
1458
+ const configWithWebhook = {
1459
+ ...defaultConfig,
1460
+ workflowBlockerResolvedWebhookUrl: 'https://example.com/config-webhook',
1461
+ };
1462
+ writeConfig(configWithWebhook);
1463
+
1464
+ const mockRun = jest.fn().mockResolvedValue(undefined);
1465
+ const MockedNotifyFinishedUseCase = jest.mocked(
1466
+ NotifyFinishedIssuePreparationUseCase,
1467
+ );
1468
+
1469
+ MockedNotifyFinishedUseCase.mockImplementation(function (
1470
+ this: NotifyFinishedIssuePreparationUseCase,
1471
+ ) {
1472
+ this.run = mockRun;
1473
+ return this;
1474
+ });
1475
+
1476
+ await program.parseAsync([
1477
+ 'node',
1478
+ 'test',
1479
+ 'notifyFinishedIssuePreparation',
1480
+ '--configFilePath',
1481
+ configFilePath,
1482
+ '--issueUrl',
1483
+ 'https://github.com/test/issue/1',
1484
+ '--workflowBlockerResolvedWebhookUrl',
1485
+ 'https://example.com/cli-webhook',
1486
+ ]);
1487
+
1488
+ expect(mockRun).toHaveBeenCalledTimes(1);
1489
+ expect(mockRun).toHaveBeenCalledWith({
1490
+ projectUrl: 'https://github.com/test/project',
1491
+ issueUrl: 'https://github.com/test/issue/1',
1492
+ preparationStatus: 'Preparing',
1493
+ awaitingWorkspaceStatus: 'Awaiting',
1494
+ awaitingQualityCheckStatus: 'Awaiting QC',
1495
+ thresholdForAutoReject: 3,
1496
+ workflowBlockerResolvedWebhookUrl: 'https://example.com/cli-webhook',
1497
+ });
1498
+ });
1403
1499
  });
1404
1500
  });
@@ -13,6 +13,7 @@ import { TowerDefenceProjectRepository } from '../../repositories/TowerDefencePr
13
13
  import { GitHubIssueCommentRepository } from '../../repositories/GitHubIssueCommentRepository';
14
14
  import { NodeLocalCommandRunner } from '../../repositories/NodeLocalCommandRunner';
15
15
  import { OauthAPIClaudeRepository } from '../../repositories/OauthAPIClaudeRepository';
16
+ import { FetchWebhookRepository } from '../../repositories/FetchWebhookRepository';
16
17
 
17
18
  type ConfigFile = {
18
19
  projectUrl?: string;
@@ -25,6 +26,7 @@ type ConfigFile = {
25
26
  allowedIssueAuthors?: string;
26
27
  awaitingQualityCheckStatus?: string;
27
28
  thresholdForAutoReject?: number;
29
+ workflowBlockerResolvedWebhookUrl?: string;
28
30
  };
29
31
 
30
32
  type StartDaemonOptions = {
@@ -46,6 +48,7 @@ type NotifyFinishedOptions = {
46
48
  awaitingWorkspaceStatus?: string;
47
49
  awaitingQualityCheckStatus?: string;
48
50
  thresholdForAutoReject?: string;
51
+ workflowBlockerResolvedWebhookUrl?: string;
49
52
  configFilePath: string;
50
53
  };
51
54
 
@@ -98,6 +101,10 @@ const loadConfigFile = (configFilePath: string): ConfigFile => {
98
101
  'awaitingQualityCheckStatus',
99
102
  ),
100
103
  thresholdForAutoReject: getNumberValue(parsed, 'thresholdForAutoReject'),
104
+ workflowBlockerResolvedWebhookUrl: getStringValue(
105
+ parsed,
106
+ 'workflowBlockerResolvedWebhookUrl',
107
+ ),
101
108
  };
102
109
  } catch (error) {
103
110
  const message = error instanceof Error ? error.message : String(error);
@@ -294,6 +301,10 @@ program
294
301
  '--thresholdForAutoReject <count>',
295
302
  'Threshold for auto-escalation after consecutive rejections (default: 3)',
296
303
  )
304
+ .option(
305
+ '--workflowBlockerResolvedWebhookUrl <url>',
306
+ 'Webhook URL to notify when a workflow blocker issue status changes to awaiting quality check. Supports {URL} and {MESSAGE} placeholders.',
307
+ )
297
308
  .action(async (options: NotifyFinishedOptions) => {
298
309
  const token = process.env.GH_TOKEN;
299
310
  if (!token) {
@@ -336,17 +347,37 @@ program
336
347
  process.exit(1);
337
348
  }
338
349
 
350
+ const workflowBlockerResolvedWebhookUrl: string | null =
351
+ options.workflowBlockerResolvedWebhookUrl ??
352
+ config.workflowBlockerResolvedWebhookUrl ??
353
+ null;
354
+
339
355
  const projectRepository = new TowerDefenceProjectRepository(
340
356
  options.configFilePath,
341
357
  token,
342
358
  );
359
+ const towerDefenceIssueRepository = new TowerDefenceIssueRepository(
360
+ options.configFilePath,
361
+ token,
362
+ );
343
363
  const graphqlIssueRepository = new GraphqlIssueRepository(token);
344
364
  const issueCommentRepository = new GitHubIssueCommentRepository(token);
365
+ const webhookRepository = new FetchWebhookRepository();
345
366
 
346
367
  const useCase = new NotifyFinishedIssuePreparationUseCase(
347
368
  projectRepository,
348
- graphqlIssueRepository,
369
+ {
370
+ get: graphqlIssueRepository.get.bind(graphqlIssueRepository),
371
+ update: graphqlIssueRepository.update.bind(graphqlIssueRepository),
372
+ findRelatedOpenPRs: graphqlIssueRepository.findRelatedOpenPRs.bind(
373
+ graphqlIssueRepository,
374
+ ),
375
+ getStoryObjectMap: towerDefenceIssueRepository.getStoryObjectMap.bind(
376
+ towerDefenceIssueRepository,
377
+ ),
378
+ },
349
379
  issueCommentRepository,
380
+ webhookRepository,
350
381
  );
351
382
 
352
383
  let thresholdForAutoReject = 3;
@@ -374,6 +405,7 @@ program
374
405
  awaitingWorkspaceStatus,
375
406
  awaitingQualityCheckStatus,
376
407
  thresholdForAutoReject,
408
+ workflowBlockerResolvedWebhookUrl,
377
409
  });
378
410
  });
379
411
 
@@ -0,0 +1,50 @@
1
+ import { FetchWebhookRepository } from './FetchWebhookRepository';
2
+
3
+ describe('FetchWebhookRepository', () => {
4
+ let repository: FetchWebhookRepository;
5
+ const originalFetch = global.fetch;
6
+
7
+ beforeEach(() => {
8
+ repository = new FetchWebhookRepository();
9
+ });
10
+
11
+ afterEach(() => {
12
+ global.fetch = originalFetch;
13
+ });
14
+
15
+ it('should send GET request to the provided URL', async () => {
16
+ const mockFetch = jest.fn().mockResolvedValue({
17
+ ok: true,
18
+ status: 200,
19
+ });
20
+ global.fetch = mockFetch;
21
+
22
+ await repository.sendGetRequest('https://example.com/webhook');
23
+
24
+ expect(mockFetch).toHaveBeenCalledWith('https://example.com/webhook');
25
+ });
26
+
27
+ it('should throw error when response is not ok', async () => {
28
+ const mockFetch = jest.fn().mockResolvedValue({
29
+ ok: false,
30
+ status: 500,
31
+ statusText: 'Internal Server Error',
32
+ });
33
+ global.fetch = mockFetch;
34
+
35
+ await expect(
36
+ repository.sendGetRequest('https://example.com/webhook'),
37
+ ).rejects.toThrow(
38
+ 'Webhook request failed with status 500: Internal Server Error',
39
+ );
40
+ });
41
+
42
+ it('should propagate network errors', async () => {
43
+ const mockFetch = jest.fn().mockRejectedValue(new Error('Network error'));
44
+ global.fetch = mockFetch;
45
+
46
+ await expect(
47
+ repository.sendGetRequest('https://example.com/webhook'),
48
+ ).rejects.toThrow('Network error');
49
+ });
50
+ });
@@ -0,0 +1,12 @@
1
+ import { WebhookRepository } from '../../domain/usecases/adapter-interfaces/WebhookRepository';
2
+
3
+ export class FetchWebhookRepository implements WebhookRepository {
4
+ sendGetRequest = async (url: string): Promise<void> => {
5
+ const response = await fetch(url);
6
+ if (!response.ok) {
7
+ throw new Error(
8
+ `Webhook request failed with status ${response.status}: ${response.statusText}`,
9
+ );
10
+ }
11
+ };
12
+ }
@@ -2,9 +2,11 @@ import { NotifyFinishedIssuePreparationUseCase } from './NotifyFinishedIssuePrep
2
2
  import { IssueRepository } from './adapter-interfaces/IssueRepository';
3
3
  import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
4
4
  import { IssueCommentRepository } from './adapter-interfaces/IssueCommentRepository';
5
+ import { WebhookRepository } from './adapter-interfaces/WebhookRepository';
5
6
  import { Issue } from '../entities/Issue';
6
7
  import { Project } from '../entities/Project';
7
8
  import { Comment } from '../entities/Comment';
9
+ import { StoryObjectMap } from '../entities/StoryObjectMap';
8
10
 
9
11
  type Mocked<T> = jest.Mocked<T> & jest.MockedObject<T>;
10
12
 
@@ -66,6 +68,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
66
68
  let mockProjectRepository: Mocked<ProjectRepository>;
67
69
  let mockIssueRepository: Mocked<IssueRepository>;
68
70
  let mockIssueCommentRepository: Mocked<IssueCommentRepository>;
71
+ let mockWebhookRepository: Mocked<WebhookRepository>;
69
72
  let mockProject: Project;
70
73
 
71
74
  beforeEach(() => {
@@ -96,10 +99,15 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
96
99
  createComment: jest.fn(),
97
100
  };
98
101
 
102
+ mockWebhookRepository = {
103
+ sendGetRequest: jest.fn(),
104
+ };
105
+
99
106
  useCase = new NotifyFinishedIssuePreparationUseCase(
100
107
  mockProjectRepository,
101
108
  mockIssueRepository,
102
109
  mockIssueCommentRepository,
110
+ mockWebhookRepository,
103
111
  );
104
112
  });
105
113
 
@@ -140,6 +148,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
140
148
  awaitingWorkspaceStatus: 'Awaiting Workspace',
141
149
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
142
150
  thresholdForAutoReject: 3,
151
+ workflowBlockerResolvedWebhookUrl: null,
143
152
  });
144
153
 
145
154
  expect(mockProjectRepository.prepareStatus).toHaveBeenCalledTimes(3);
@@ -190,6 +199,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
190
199
  awaitingWorkspaceStatus: 'Awaiting Workspace',
191
200
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
192
201
  thresholdForAutoReject: 3,
202
+ workflowBlockerResolvedWebhookUrl: null,
193
203
  });
194
204
 
195
205
  expect(mockIssueRepository.update).toHaveBeenCalledTimes(1);
@@ -214,6 +224,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
214
224
  awaitingWorkspaceStatus: 'Awaiting Workspace',
215
225
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
216
226
  thresholdForAutoReject: 3,
227
+ workflowBlockerResolvedWebhookUrl: null,
217
228
  }),
218
229
  ).rejects.toThrow(
219
230
  'Issue not found: https://github.com/user/repo/issues/999',
@@ -237,6 +248,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
237
248
  awaitingWorkspaceStatus: 'Awaiting Workspace',
238
249
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
239
250
  thresholdForAutoReject: 3,
251
+ workflowBlockerResolvedWebhookUrl: null,
240
252
  }),
241
253
  ).rejects.toThrow(
242
254
  'Illegal issue status for https://github.com/user/repo/issues/1: expected Preparation, but got Done',
@@ -275,6 +287,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
275
287
  awaitingWorkspaceStatus: 'Awaiting Workspace',
276
288
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
277
289
  thresholdForAutoReject: 3,
290
+ workflowBlockerResolvedWebhookUrl: null,
278
291
  });
279
292
 
280
293
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -321,6 +334,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
321
334
  awaitingWorkspaceStatus: 'Awaiting Workspace',
322
335
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
323
336
  thresholdForAutoReject: 3,
337
+ workflowBlockerResolvedWebhookUrl: null,
324
338
  });
325
339
 
326
340
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -365,6 +379,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
365
379
  awaitingWorkspaceStatus: 'Awaiting Workspace',
366
380
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
367
381
  thresholdForAutoReject: 3,
382
+ workflowBlockerResolvedWebhookUrl: null,
368
383
  });
369
384
 
370
385
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -397,6 +412,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
397
412
  awaitingWorkspaceStatus: 'Awaiting Workspace',
398
413
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
399
414
  thresholdForAutoReject: 3,
415
+ workflowBlockerResolvedWebhookUrl: null,
400
416
  });
401
417
 
402
418
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -446,6 +462,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
446
462
  awaitingWorkspaceStatus: 'Awaiting Workspace',
447
463
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
448
464
  thresholdForAutoReject: 3,
465
+ workflowBlockerResolvedWebhookUrl: null,
449
466
  });
450
467
 
451
468
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -489,6 +506,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
489
506
  awaitingWorkspaceStatus: 'Awaiting Workspace',
490
507
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
491
508
  thresholdForAutoReject: 3,
509
+ workflowBlockerResolvedWebhookUrl: null,
492
510
  });
493
511
 
494
512
  expect(mockIssueRepository.update).not.toHaveBeenCalledWith(
@@ -532,6 +550,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
532
550
  awaitingWorkspaceStatus: 'Awaiting Workspace',
533
551
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
534
552
  thresholdForAutoReject: 3,
553
+ workflowBlockerResolvedWebhookUrl: null,
535
554
  });
536
555
 
537
556
  expect(mockIssueRepository.update).not.toHaveBeenCalledWith(
@@ -562,6 +581,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
562
581
  awaitingWorkspaceStatus: 'Awaiting Workspace',
563
582
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
564
583
  thresholdForAutoReject: 3,
584
+ workflowBlockerResolvedWebhookUrl: null,
565
585
  });
566
586
 
567
587
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -617,6 +637,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
617
637
  awaitingWorkspaceStatus: 'Awaiting Workspace',
618
638
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
619
639
  thresholdForAutoReject: 3,
640
+ workflowBlockerResolvedWebhookUrl: null,
620
641
  });
621
642
 
622
643
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -663,6 +684,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
663
684
  awaitingWorkspaceStatus: 'Awaiting Workspace',
664
685
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
665
686
  thresholdForAutoReject: 3,
687
+ workflowBlockerResolvedWebhookUrl: null,
666
688
  });
667
689
 
668
690
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -709,6 +731,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
709
731
  awaitingWorkspaceStatus: 'Awaiting Workspace',
710
732
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
711
733
  thresholdForAutoReject: 3,
734
+ workflowBlockerResolvedWebhookUrl: null,
712
735
  });
713
736
 
714
737
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -755,6 +778,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
755
778
  awaitingWorkspaceStatus: 'Awaiting Workspace',
756
779
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
757
780
  thresholdForAutoReject: 3,
781
+ workflowBlockerResolvedWebhookUrl: null,
758
782
  });
759
783
 
760
784
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -807,6 +831,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
807
831
  awaitingWorkspaceStatus: 'Awaiting Workspace',
808
832
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
809
833
  thresholdForAutoReject: 3,
834
+ workflowBlockerResolvedWebhookUrl: null,
810
835
  });
811
836
 
812
837
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -859,6 +884,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
859
884
  awaitingWorkspaceStatus: 'Awaiting Workspace',
860
885
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
861
886
  thresholdForAutoReject: 3,
887
+ workflowBlockerResolvedWebhookUrl: null,
862
888
  });
863
889
 
864
890
  expect(mockIssueCommentRepository.createComment).toHaveBeenCalledWith(
@@ -899,6 +925,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
899
925
  awaitingWorkspaceStatus: 'Awaiting Workspace',
900
926
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
901
927
  thresholdForAutoReject: 3,
928
+ workflowBlockerResolvedWebhookUrl: null,
902
929
  });
903
930
 
904
931
  expect(mockIssueRepository.update).toHaveBeenCalledWith(
@@ -935,6 +962,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
935
962
  awaitingWorkspaceStatus: 'Awaiting Workspace',
936
963
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
937
964
  thresholdForAutoReject: 3,
965
+ workflowBlockerResolvedWebhookUrl: null,
938
966
  });
939
967
 
940
968
  expect(mockIssueRepository.findRelatedOpenPRs).not.toHaveBeenCalled();
@@ -977,6 +1005,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
977
1005
  awaitingWorkspaceStatus: 'Awaiting Workspace',
978
1006
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
979
1007
  thresholdForAutoReject: 3,
1008
+ workflowBlockerResolvedWebhookUrl: null,
980
1009
  });
981
1010
 
982
1011
  expect(mockIssueRepository.findRelatedOpenPRs).toHaveBeenCalled();
@@ -1010,6 +1039,7 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1010
1039
  awaitingWorkspaceStatus: 'Awaiting Workspace',
1011
1040
  awaitingQualityCheckStatus: 'Awaiting Quality Check',
1012
1041
  thresholdForAutoReject: 3,
1042
+ workflowBlockerResolvedWebhookUrl: null,
1013
1043
  });
1014
1044
 
1015
1045
  expect(mockIssueRepository.findRelatedOpenPRs).not.toHaveBeenCalled();
@@ -1026,4 +1056,310 @@ describe('NotifyFinishedIssuePreparationUseCase', () => {
1026
1056
  expect.stringContaining('NO_REPORT_FROM_AGENT_BOT'),
1027
1057
  );
1028
1058
  });
1059
+
1060
+ describe('workflow blocker webhook notification', () => {
1061
+ const createWorkflowBlockerStoryObjectMap = (
1062
+ issueUrl: string,
1063
+ ): StoryObjectMap => {
1064
+ const map: StoryObjectMap = new Map();
1065
+ map.set('Workflow Blocker Story', {
1066
+ story: {
1067
+ id: 'story-1',
1068
+ name: 'Workflow Blocker Story',
1069
+ color: 'GRAY',
1070
+ description: '',
1071
+ },
1072
+ storyIssue: null,
1073
+ issues: [createMockIssue({ url: issueUrl })],
1074
+ });
1075
+ return map;
1076
+ };
1077
+
1078
+ const createNonBlockerStoryObjectMap = (): StoryObjectMap => {
1079
+ const map: StoryObjectMap = new Map();
1080
+ map.set('Regular Story', {
1081
+ story: {
1082
+ id: 'story-2',
1083
+ name: 'Regular Story',
1084
+ color: 'GRAY',
1085
+ description: '',
1086
+ },
1087
+ storyIssue: null,
1088
+ issues: [
1089
+ createMockIssue({
1090
+ url: 'https://github.com/user/repo/issues/99',
1091
+ }),
1092
+ ],
1093
+ });
1094
+ return map;
1095
+ };
1096
+
1097
+ it('should send webhook when workflow blocker issue status changes to awaitingQualityCheckStatus on checks pass', async () => {
1098
+ const issue = createMockIssue({
1099
+ url: 'https://github.com/user/repo/issues/1',
1100
+ status: 'Preparation',
1101
+ });
1102
+
1103
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
1104
+ mockIssueRepository.get.mockResolvedValue(issue);
1105
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1106
+ createMockComment({ content: 'From: Test report' }),
1107
+ ]);
1108
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1109
+ {
1110
+ url: 'https://github.com/user/repo/pull/1',
1111
+ isConflicted: false,
1112
+ isPassedAllCiJob: true,
1113
+ isCiStateSuccess: true,
1114
+ isResolvedAllReviewComments: true,
1115
+ isBranchOutOfDate: false,
1116
+ missingRequiredCheckNames: [],
1117
+ },
1118
+ ]);
1119
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
1120
+ createWorkflowBlockerStoryObjectMap(
1121
+ 'https://github.com/user/repo/issues/1',
1122
+ ),
1123
+ );
1124
+
1125
+ await useCase.run({
1126
+ projectUrl: 'https://github.com/users/user/projects/1',
1127
+ issueUrl: 'https://github.com/user/repo/issues/1',
1128
+ preparationStatus: 'Preparation',
1129
+ awaitingWorkspaceStatus: 'Awaiting Workspace',
1130
+ awaitingQualityCheckStatus: 'Awaiting Quality Check',
1131
+ thresholdForAutoReject: 3,
1132
+ workflowBlockerResolvedWebhookUrl:
1133
+ 'https://example.com/webhook?url={URL}&msg={MESSAGE}',
1134
+ });
1135
+
1136
+ expect(mockWebhookRepository.sendGetRequest).toHaveBeenCalledWith(
1137
+ `https://example.com/webhook?url=${encodeURIComponent('https://github.com/user/repo/issues/1')}&msg=${encodeURIComponent('Workflow blocker resolved: https://github.com/user/repo/issues/1')}`,
1138
+ );
1139
+ });
1140
+
1141
+ it('should send webhook when workflow blocker issue auto-escalates', async () => {
1142
+ const issue = createMockIssue({
1143
+ url: 'https://github.com/user/repo/issues/1',
1144
+ status: 'Preparation',
1145
+ });
1146
+
1147
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
1148
+ mockIssueRepository.get.mockResolvedValue(issue);
1149
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1150
+ createMockComment({
1151
+ content: 'Auto Status Check: REJECTED - first',
1152
+ }),
1153
+ createMockComment({
1154
+ content: 'Auto Status Check: REJECTED - second',
1155
+ }),
1156
+ createMockComment({
1157
+ content: 'Auto Status Check: REJECTED - third',
1158
+ }),
1159
+ ]);
1160
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
1161
+ createWorkflowBlockerStoryObjectMap(
1162
+ 'https://github.com/user/repo/issues/1',
1163
+ ),
1164
+ );
1165
+
1166
+ await useCase.run({
1167
+ projectUrl: 'https://github.com/users/user/projects/1',
1168
+ issueUrl: 'https://github.com/user/repo/issues/1',
1169
+ preparationStatus: 'Preparation',
1170
+ awaitingWorkspaceStatus: 'Awaiting Workspace',
1171
+ awaitingQualityCheckStatus: 'Awaiting Quality Check',
1172
+ thresholdForAutoReject: 3,
1173
+ workflowBlockerResolvedWebhookUrl:
1174
+ 'https://example.com/notify={MESSAGE}',
1175
+ });
1176
+
1177
+ expect(mockWebhookRepository.sendGetRequest).toHaveBeenCalledTimes(1);
1178
+ expect(mockWebhookRepository.sendGetRequest).toHaveBeenCalledWith(
1179
+ expect.stringContaining('https://example.com/notify='),
1180
+ );
1181
+ });
1182
+
1183
+ it('should not send webhook for non-blocker issues', async () => {
1184
+ const issue = createMockIssue({
1185
+ url: 'https://github.com/user/repo/issues/1',
1186
+ status: 'Preparation',
1187
+ });
1188
+
1189
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
1190
+ mockIssueRepository.get.mockResolvedValue(issue);
1191
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1192
+ createMockComment({ content: 'From: Test report' }),
1193
+ ]);
1194
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1195
+ {
1196
+ url: 'https://github.com/user/repo/pull/1',
1197
+ isConflicted: false,
1198
+ isPassedAllCiJob: true,
1199
+ isCiStateSuccess: true,
1200
+ isResolvedAllReviewComments: true,
1201
+ isBranchOutOfDate: false,
1202
+ missingRequiredCheckNames: [],
1203
+ },
1204
+ ]);
1205
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
1206
+ createNonBlockerStoryObjectMap(),
1207
+ );
1208
+
1209
+ await useCase.run({
1210
+ projectUrl: 'https://github.com/users/user/projects/1',
1211
+ issueUrl: 'https://github.com/user/repo/issues/1',
1212
+ preparationStatus: 'Preparation',
1213
+ awaitingWorkspaceStatus: 'Awaiting Workspace',
1214
+ awaitingQualityCheckStatus: 'Awaiting Quality Check',
1215
+ thresholdForAutoReject: 3,
1216
+ workflowBlockerResolvedWebhookUrl:
1217
+ 'https://example.com/webhook?msg={MESSAGE}',
1218
+ });
1219
+
1220
+ expect(mockWebhookRepository.sendGetRequest).not.toHaveBeenCalled();
1221
+ });
1222
+
1223
+ it('should not send webhook when URL is null', async () => {
1224
+ const issue = createMockIssue({
1225
+ url: 'https://github.com/user/repo/issues/1',
1226
+ status: 'Preparation',
1227
+ });
1228
+
1229
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
1230
+ mockIssueRepository.get.mockResolvedValue(issue);
1231
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1232
+ createMockComment({ content: 'From: Test report' }),
1233
+ ]);
1234
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1235
+ {
1236
+ url: 'https://github.com/user/repo/pull/1',
1237
+ isConflicted: false,
1238
+ isPassedAllCiJob: true,
1239
+ isCiStateSuccess: true,
1240
+ isResolvedAllReviewComments: true,
1241
+ isBranchOutOfDate: false,
1242
+ missingRequiredCheckNames: [],
1243
+ },
1244
+ ]);
1245
+
1246
+ await useCase.run({
1247
+ projectUrl: 'https://github.com/users/user/projects/1',
1248
+ issueUrl: 'https://github.com/user/repo/issues/1',
1249
+ preparationStatus: 'Preparation',
1250
+ awaitingWorkspaceStatus: 'Awaiting Workspace',
1251
+ awaitingQualityCheckStatus: 'Awaiting Quality Check',
1252
+ thresholdForAutoReject: 3,
1253
+ workflowBlockerResolvedWebhookUrl: null,
1254
+ });
1255
+
1256
+ expect(mockIssueRepository.getStoryObjectMap).not.toHaveBeenCalled();
1257
+ expect(mockWebhookRepository.sendGetRequest).not.toHaveBeenCalled();
1258
+ });
1259
+
1260
+ it('should log warning and not block workflow when webhook fails', async () => {
1261
+ const issue = createMockIssue({
1262
+ url: 'https://github.com/user/repo/issues/1',
1263
+ status: 'Preparation',
1264
+ });
1265
+
1266
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
1267
+ mockIssueRepository.get.mockResolvedValue(issue);
1268
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1269
+ createMockComment({ content: 'From: Test report' }),
1270
+ ]);
1271
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1272
+ {
1273
+ url: 'https://github.com/user/repo/pull/1',
1274
+ isConflicted: false,
1275
+ isPassedAllCiJob: true,
1276
+ isCiStateSuccess: true,
1277
+ isResolvedAllReviewComments: true,
1278
+ isBranchOutOfDate: false,
1279
+ missingRequiredCheckNames: [],
1280
+ },
1281
+ ]);
1282
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
1283
+ createWorkflowBlockerStoryObjectMap(
1284
+ 'https://github.com/user/repo/issues/1',
1285
+ ),
1286
+ );
1287
+ mockWebhookRepository.sendGetRequest.mockRejectedValue(
1288
+ new Error('Network error'),
1289
+ );
1290
+
1291
+ const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation();
1292
+
1293
+ await useCase.run({
1294
+ projectUrl: 'https://github.com/users/user/projects/1',
1295
+ issueUrl: 'https://github.com/user/repo/issues/1',
1296
+ preparationStatus: 'Preparation',
1297
+ awaitingWorkspaceStatus: 'Awaiting Workspace',
1298
+ awaitingQualityCheckStatus: 'Awaiting Quality Check',
1299
+ thresholdForAutoReject: 3,
1300
+ workflowBlockerResolvedWebhookUrl:
1301
+ 'https://example.com/webhook?msg={MESSAGE}',
1302
+ });
1303
+
1304
+ expect(consoleWarnSpy).toHaveBeenCalledWith(
1305
+ 'Failed to send workflow blocker notification:',
1306
+ expect.any(Error),
1307
+ );
1308
+ expect(mockIssueRepository.update).toHaveBeenCalledWith(
1309
+ expect.objectContaining({
1310
+ status: 'Awaiting Quality Check',
1311
+ }),
1312
+ mockProject,
1313
+ );
1314
+
1315
+ consoleWarnSpy.mockRestore();
1316
+ });
1317
+
1318
+ it('should URL-encode placeholders in webhook URL', async () => {
1319
+ const issue = createMockIssue({
1320
+ url: 'https://github.com/user/repo/issues/1',
1321
+ status: 'Preparation',
1322
+ });
1323
+
1324
+ mockProjectRepository.getByUrl.mockResolvedValue(mockProject);
1325
+ mockIssueRepository.get.mockResolvedValue(issue);
1326
+ mockIssueCommentRepository.getCommentsFromIssue.mockResolvedValue([
1327
+ createMockComment({ content: 'From: Test report' }),
1328
+ ]);
1329
+ mockIssueRepository.findRelatedOpenPRs.mockResolvedValue([
1330
+ {
1331
+ url: 'https://github.com/user/repo/pull/1',
1332
+ isConflicted: false,
1333
+ isPassedAllCiJob: true,
1334
+ isCiStateSuccess: true,
1335
+ isResolvedAllReviewComments: true,
1336
+ isBranchOutOfDate: false,
1337
+ missingRequiredCheckNames: [],
1338
+ },
1339
+ ]);
1340
+ mockIssueRepository.getStoryObjectMap.mockResolvedValue(
1341
+ createWorkflowBlockerStoryObjectMap(
1342
+ 'https://github.com/user/repo/issues/1',
1343
+ ),
1344
+ );
1345
+
1346
+ await useCase.run({
1347
+ projectUrl: 'https://github.com/users/user/projects/1',
1348
+ issueUrl: 'https://github.com/user/repo/issues/1',
1349
+ preparationStatus: 'Preparation',
1350
+ awaitingWorkspaceStatus: 'Awaiting Workspace',
1351
+ awaitingQualityCheckStatus: 'Awaiting Quality Check',
1352
+ thresholdForAutoReject: 3,
1353
+ workflowBlockerResolvedWebhookUrl:
1354
+ 'https://example.com/runTasker/notify=:={MESSAGE}',
1355
+ });
1356
+
1357
+ const calledUrl = mockWebhookRepository.sendGetRequest.mock.calls[0][0];
1358
+ expect(calledUrl).not.toContain('{MESSAGE}');
1359
+ expect(calledUrl).not.toContain('{URL}');
1360
+ expect(calledUrl).toContain(
1361
+ encodeURIComponent('Workflow blocker resolved:'),
1362
+ );
1363
+ });
1364
+ });
1029
1365
  });
@@ -1,6 +1,7 @@
1
1
  import { IssueRepository } from './adapter-interfaces/IssueRepository';
2
2
  import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
3
3
  import { IssueCommentRepository } from './adapter-interfaces/IssueCommentRepository';
4
+ import { WebhookRepository } from './adapter-interfaces/WebhookRepository';
4
5
 
5
6
  export class IssueNotFoundError extends Error {
6
7
  constructor(issueUrl: string) {
@@ -37,12 +38,16 @@ export class NotifyFinishedIssuePreparationUseCase {
37
38
  >,
38
39
  private readonly issueRepository: Pick<
39
40
  IssueRepository,
40
- 'get' | 'update' | 'findRelatedOpenPRs'
41
+ 'get' | 'update' | 'findRelatedOpenPRs' | 'getStoryObjectMap'
41
42
  >,
42
43
  private readonly issueCommentRepository: Pick<
43
44
  IssueCommentRepository,
44
45
  'getCommentsFromIssue' | 'createComment'
45
46
  >,
47
+ private readonly webhookRepository: Pick<
48
+ WebhookRepository,
49
+ 'sendGetRequest'
50
+ >,
46
51
  ) {}
47
52
 
48
53
  run = async (params: {
@@ -52,6 +57,7 @@ export class NotifyFinishedIssuePreparationUseCase {
52
57
  awaitingWorkspaceStatus: string;
53
58
  awaitingQualityCheckStatus: string;
54
59
  thresholdForAutoReject: number;
60
+ workflowBlockerResolvedWebhookUrl: string | null;
55
61
  }): Promise<void> => {
56
62
  let project = await this.projectRepository.getByUrl(params.projectUrl);
57
63
  project = await this.projectRepository.prepareStatus(
@@ -98,6 +104,11 @@ export class NotifyFinishedIssuePreparationUseCase {
98
104
  issue,
99
105
  `Failed to pass the check autimatically for ${params.thresholdForAutoReject} times`,
100
106
  );
107
+ await this.sendWorkflowBlockerNotification(
108
+ params.issueUrl,
109
+ params.workflowBlockerResolvedWebhookUrl,
110
+ project,
111
+ );
101
112
  return;
102
113
  }
103
114
 
@@ -165,6 +176,11 @@ export class NotifyFinishedIssuePreparationUseCase {
165
176
  if (rejections.length <= 0) {
166
177
  issue.status = params.awaitingQualityCheckStatus;
167
178
  await this.issueRepository.update(issue, project);
179
+ await this.sendWorkflowBlockerNotification(
180
+ params.issueUrl,
181
+ params.workflowBlockerResolvedWebhookUrl,
182
+ project,
183
+ );
168
184
  return;
169
185
  }
170
186
 
@@ -176,4 +192,38 @@ export class NotifyFinishedIssuePreparationUseCase {
176
192
  `Auto Status Check: REJECTED\n${rejections.map((r) => `- ${r.detail}`).join('\n')}`,
177
193
  );
178
194
  };
195
+
196
+ private sendWorkflowBlockerNotification = async (
197
+ issueUrl: string,
198
+ webhookUrlTemplate: string | null,
199
+ project: Parameters<IssueRepository['getStoryObjectMap']>[0],
200
+ ): Promise<void> => {
201
+ if (webhookUrlTemplate === null) {
202
+ return;
203
+ }
204
+
205
+ try {
206
+ const storyObjectMap =
207
+ await this.issueRepository.getStoryObjectMap(project);
208
+
209
+ const isWorkflowBlocker = Array.from(storyObjectMap.entries()).some(
210
+ ([storyName, storyObject]) =>
211
+ storyName.toLowerCase().includes('workflow blocker') &&
212
+ storyObject.issues.some((issue) => issue.url === issueUrl),
213
+ );
214
+
215
+ if (!isWorkflowBlocker) {
216
+ return;
217
+ }
218
+
219
+ const message = `Workflow blocker resolved: ${issueUrl}`;
220
+ const webhookUrl = webhookUrlTemplate
221
+ .replace('{URL}', encodeURIComponent(issueUrl))
222
+ .replace('{MESSAGE}', encodeURIComponent(message));
223
+
224
+ await this.webhookRepository.sendGetRequest(webhookUrl);
225
+ } catch (error) {
226
+ console.warn('Failed to send workflow blocker notification:', error);
227
+ }
228
+ };
179
229
  }
@@ -0,0 +1,3 @@
1
+ export interface WebhookRepository {
2
+ sendGetRequest(url: string): Promise<void>;
3
+ }
@@ -11,6 +11,7 @@ type ConfigFile = {
11
11
  allowedIssueAuthors?: string;
12
12
  awaitingQualityCheckStatus?: string;
13
13
  thresholdForAutoReject?: number;
14
+ workflowBlockerResolvedWebhookUrl?: string;
14
15
  };
15
16
  declare const loadConfigFile: (configFilePath: string) => ConfigFile;
16
17
  declare const program: Command;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,KAAK,UAAU,GAAG;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AA2CF,QAAA,MAAM,cAAc,GAAI,gBAAgB,MAAM,KAAG,UAsChD,CAAC;AAEF,QAAA,MAAM,OAAO,SAAgB,CAAC;AAkR9B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,KAAK,UAAU,GAAG;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iCAAiC,CAAC,EAAE,MAAM,CAAC;CAC5C,CAAC;AA4CF,QAAA,MAAM,cAAc,GAAI,gBAAgB,MAAM,KAAG,UA0ChD,CAAC;AAEF,QAAA,MAAM,OAAO,SAAgB,CAAC;AA2S9B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { WebhookRepository } from '../../domain/usecases/adapter-interfaces/WebhookRepository';
2
+ export declare class FetchWebhookRepository implements WebhookRepository {
3
+ sendGetRequest: (url: string) => Promise<void>;
4
+ }
5
+ //# sourceMappingURL=FetchWebhookRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FetchWebhookRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/FetchWebhookRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4DAA4D,CAAC;AAE/F,qBAAa,sBAAuB,YAAW,iBAAiB;IAC9D,cAAc,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAOjD;CACH"}
@@ -1,6 +1,7 @@
1
1
  import { IssueRepository } from './adapter-interfaces/IssueRepository';
2
2
  import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
3
3
  import { IssueCommentRepository } from './adapter-interfaces/IssueCommentRepository';
4
+ import { WebhookRepository } from './adapter-interfaces/WebhookRepository';
4
5
  export declare class IssueNotFoundError extends Error {
5
6
  constructor(issueUrl: string);
6
7
  }
@@ -11,7 +12,8 @@ export declare class NotifyFinishedIssuePreparationUseCase {
11
12
  private readonly projectRepository;
12
13
  private readonly issueRepository;
13
14
  private readonly issueCommentRepository;
14
- constructor(projectRepository: Pick<ProjectRepository, 'getByUrl' | 'prepareStatus'>, issueRepository: Pick<IssueRepository, 'get' | 'update' | 'findRelatedOpenPRs'>, issueCommentRepository: Pick<IssueCommentRepository, 'getCommentsFromIssue' | 'createComment'>);
15
+ private readonly webhookRepository;
16
+ constructor(projectRepository: Pick<ProjectRepository, 'getByUrl' | 'prepareStatus'>, issueRepository: Pick<IssueRepository, 'get' | 'update' | 'findRelatedOpenPRs' | 'getStoryObjectMap'>, issueCommentRepository: Pick<IssueCommentRepository, 'getCommentsFromIssue' | 'createComment'>, webhookRepository: Pick<WebhookRepository, 'sendGetRequest'>);
15
17
  run: (params: {
16
18
  projectUrl: string;
17
19
  issueUrl: string;
@@ -19,6 +21,8 @@ export declare class NotifyFinishedIssuePreparationUseCase {
19
21
  awaitingWorkspaceStatus: string;
20
22
  awaitingQualityCheckStatus: string;
21
23
  thresholdForAutoReject: number;
24
+ workflowBlockerResolvedWebhookUrl: string | null;
22
25
  }) => Promise<void>;
26
+ private sendWorkflowBlockerNotification;
23
27
  }
24
28
  //# sourceMappingURL=NotifyFinishedIssuePreparationUseCase.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NotifyFinishedIssuePreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAErF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,QAAQ,EAAE,MAAM;CAI7B;AACD,qBAAa,uBAAwB,SAAQ,KAAK;gBAE9C,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,cAAc,EAAE,MAAM,GAAG,IAAI;CAOhC;AAUD,qBAAa,qCAAqC;IAE9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAIlC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAIhC,OAAO,CAAC,QAAQ,CAAC,sBAAsB;gBARtB,iBAAiB,EAAE,IAAI,CACtC,iBAAiB,EACjB,UAAU,GAAG,eAAe,CAC7B,EACgB,eAAe,EAAE,IAAI,CACpC,eAAe,EACf,KAAK,GAAG,QAAQ,GAAG,oBAAoB,CACxC,EACgB,sBAAsB,EAAE,IAAI,CAC3C,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC;IAGH,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,uBAAuB,EAAE,MAAM,CAAC;QAChC,0BAA0B,EAAE,MAAM,CAAC;QACnC,sBAAsB,EAAE,MAAM,CAAC;KAChC,KAAG,OAAO,CAAC,IAAI,CAAC,CA2Hf;CACH"}
1
+ {"version":3,"file":"NotifyFinishedIssuePreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/NotifyFinishedIssuePreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAE3E,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,QAAQ,EAAE,MAAM;CAI7B;AACD,qBAAa,uBAAwB,SAAQ,KAAK;gBAE9C,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,cAAc,EAAE,MAAM,GAAG,IAAI;CAOhC;AAUD,qBAAa,qCAAqC;IAE9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAIlC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAIhC,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAIvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAZjB,iBAAiB,EAAE,IAAI,CACtC,iBAAiB,EACjB,UAAU,GAAG,eAAe,CAC7B,EACgB,eAAe,EAAE,IAAI,CACpC,eAAe,EACf,KAAK,GAAG,QAAQ,GAAG,oBAAoB,GAAG,mBAAmB,CAC9D,EACgB,sBAAsB,EAAE,IAAI,CAC3C,sBAAsB,EACtB,sBAAsB,GAAG,eAAe,CACzC,EACgB,iBAAiB,EAAE,IAAI,CACtC,iBAAiB,EACjB,gBAAgB,CACjB;IAGH,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,uBAAuB,EAAE,MAAM,CAAC;QAChC,0BAA0B,EAAE,MAAM,CAAC;QACnC,sBAAsB,EAAE,MAAM,CAAC;QAC/B,iCAAiC,EAAE,MAAM,GAAG,IAAI,CAAC;KAClD,KAAG,OAAO,CAAC,IAAI,CAAC,CAqIf;IAEF,OAAO,CAAC,+BAA+B,CAgCrC;CACH"}
@@ -0,0 +1,4 @@
1
+ export interface WebhookRepository {
2
+ sendGetRequest(url: string): Promise<void>;
3
+ }
4
+ //# sourceMappingURL=WebhookRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebhookRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/WebhookRepository.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C"}