github-issue-tower-defence-management 1.123.2 → 1.123.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js +29 -2
- package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.test.ts +190 -0
- package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts +40 -10
- package/types/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [1.123.3](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.123.2...v1.123.3) (2026-07-17)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **revert-review-queue:** contain archived project item update failures so an archived item does not abort the schedule cycle ([#1193](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/issues/1193)) ([6034127](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/6034127c4aeff0cebfc8a4a914eff36781e878f4))
|
|
7
|
+
|
|
1
8
|
## [1.123.2](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.123.1...v1.123.2) (2026-07-17)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -4,6 +4,15 @@ exports.RevertNotReadyReviewQueueIssueUseCase = void 0;
|
|
|
4
4
|
const IssueRejectionEvaluator_1 = require("./IssueRejectionEvaluator");
|
|
5
5
|
const ChangeTargetPullRequestApprover_1 = require("./ChangeTargetPullRequestApprover");
|
|
6
6
|
const WorkflowStatus_1 = require("../entities/WorkflowStatus");
|
|
7
|
+
// GitHub rejects field mutations against archived project items with
|
|
8
|
+
// "The item is archived and cannot be updated". Such a failure is specific to
|
|
9
|
+
// the single item being reverted, so it must not abort the whole schedule
|
|
10
|
+
// cycle (the same containment policy as the transient GraphQL error handling
|
|
11
|
+
// and the findRelatedOpenPRs NOT_FOUND handling).
|
|
12
|
+
const isArchivedProjectItemError = (error) => {
|
|
13
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
14
|
+
return message.toLowerCase().includes('archived');
|
|
15
|
+
};
|
|
7
16
|
const isAuthorAuthorizedForAutoStatusCheck = (author, allowedIssueAuthors) => {
|
|
8
17
|
if (allowedIssueAuthors === null || allowedIssueAuthors === undefined) {
|
|
9
18
|
return false;
|
|
@@ -47,7 +56,16 @@ class RevertNotReadyReviewQueueIssueUseCase {
|
|
|
47
56
|
relatedOpenPrUrls: relatedOpenPrUrlsByIssueUrl.get(issue.url) ?? [],
|
|
48
57
|
});
|
|
49
58
|
if (rejections.length > 0) {
|
|
50
|
-
|
|
59
|
+
try {
|
|
60
|
+
await this.issueRepository.updateStatus(project, issue, awaitingWorkspaceStatusOption.id);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (isArchivedProjectItemError(error)) {
|
|
64
|
+
console.warn(`RevertNotReadyReviewQueueIssueUseCase: project item is archived and cannot be updated, skipping revert. issueUrl: ${issue.url}`);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
51
69
|
await this.issueCommentRepository.createComment(issue, `Auto Status Check: REJECTED\n${rejections.map((r) => `- ${r.detail}`).join('\n')}`);
|
|
52
70
|
continue;
|
|
53
71
|
}
|
|
@@ -65,7 +83,16 @@ class RevertNotReadyReviewQueueIssueUseCase {
|
|
|
65
83
|
}
|
|
66
84
|
const { rejections } = await this.issueRejectionEvaluator.evaluate(pullRequest, params.labelsAsLlmAgentName ?? []);
|
|
67
85
|
if (rejections.length > 0) {
|
|
68
|
-
|
|
86
|
+
try {
|
|
87
|
+
await this.issueRepository.updateStatus(project, pullRequest, awaitingWorkspaceStatusOption.id);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (isArchivedProjectItemError(error)) {
|
|
91
|
+
console.warn(`RevertNotReadyReviewQueueIssueUseCase: project item is archived and cannot be updated, skipping revert. prUrl: ${pullRequest.url}`);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
69
96
|
if (projectStory) {
|
|
70
97
|
await this.issueRepository.updateStory({ ...project, story: projectStory }, pullRequest, projectStory.workflowManagementStory.id);
|
|
71
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RevertNotReadyReviewQueueIssueUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"RevertNotReadyReviewQueueIssueUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1507,4 +1507,194 @@ describe('RevertNotReadyReviewQueueIssueUseCase', () => {
|
|
|
1507
1507
|
});
|
|
1508
1508
|
});
|
|
1509
1509
|
});
|
|
1510
|
+
|
|
1511
|
+
describe('archived project item containment', () => {
|
|
1512
|
+
let warnSpy: jest.SpyInstance;
|
|
1513
|
+
|
|
1514
|
+
beforeEach(() => {
|
|
1515
|
+
warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
1516
|
+
});
|
|
1517
|
+
|
|
1518
|
+
afterEach(() => {
|
|
1519
|
+
warnSpy.mockRestore();
|
|
1520
|
+
});
|
|
1521
|
+
|
|
1522
|
+
it('should skip an archived issue on updateStatus failure and continue with remaining issues', async () => {
|
|
1523
|
+
const archivedIssue = createMockIssue({
|
|
1524
|
+
number: 1,
|
|
1525
|
+
url: 'https://github.com/user/repo/issues/1',
|
|
1526
|
+
itemId: 'archived-item',
|
|
1527
|
+
status: 'Awaiting Quality Check',
|
|
1528
|
+
});
|
|
1529
|
+
const normalIssue = createMockIssue({
|
|
1530
|
+
number: 2,
|
|
1531
|
+
url: 'https://github.com/user/repo/issues/2',
|
|
1532
|
+
itemId: 'normal-item',
|
|
1533
|
+
status: 'Awaiting Quality Check',
|
|
1534
|
+
});
|
|
1535
|
+
mockIssueRepository.getAllIssues.mockResolvedValue({
|
|
1536
|
+
project: mockProject,
|
|
1537
|
+
issues: [archivedIssue, normalIssue],
|
|
1538
|
+
cacheUsed: false,
|
|
1539
|
+
});
|
|
1540
|
+
mockIssueRepository.updateStatus.mockImplementation(
|
|
1541
|
+
(_project: Project, issue: Issue) =>
|
|
1542
|
+
issue.url === archivedIssue.url
|
|
1543
|
+
? Promise.reject(
|
|
1544
|
+
new Error('The item is archived and cannot be updated'),
|
|
1545
|
+
)
|
|
1546
|
+
: Promise.resolve(undefined),
|
|
1547
|
+
);
|
|
1548
|
+
|
|
1549
|
+
await useCase.run({
|
|
1550
|
+
projectUrl: 'https://github.com/users/user/projects/1',
|
|
1551
|
+
allowedIssueAuthors: ['owner'],
|
|
1552
|
+
});
|
|
1553
|
+
|
|
1554
|
+
expect(mockIssueRepository.updateStatus).toHaveBeenCalledWith(
|
|
1555
|
+
mockProject,
|
|
1556
|
+
archivedIssue,
|
|
1557
|
+
'awaiting-workspace-id',
|
|
1558
|
+
);
|
|
1559
|
+
expect(mockIssueRepository.updateStatus).toHaveBeenCalledWith(
|
|
1560
|
+
mockProject,
|
|
1561
|
+
normalIssue,
|
|
1562
|
+
'awaiting-workspace-id',
|
|
1563
|
+
);
|
|
1564
|
+
expect(mockIssueCommentRepository.createComment).not.toHaveBeenCalledWith(
|
|
1565
|
+
archivedIssue,
|
|
1566
|
+
expect.anything(),
|
|
1567
|
+
);
|
|
1568
|
+
expect(mockIssueCommentRepository.createComment).toHaveBeenCalledWith(
|
|
1569
|
+
normalIssue,
|
|
1570
|
+
expect.stringContaining('Auto Status Check: REJECTED'),
|
|
1571
|
+
);
|
|
1572
|
+
expect(warnSpy).toHaveBeenCalledWith(
|
|
1573
|
+
expect.stringContaining(archivedIssue.url),
|
|
1574
|
+
);
|
|
1575
|
+
});
|
|
1576
|
+
|
|
1577
|
+
it('should propagate a non-archived updateStatus error for issues unchanged', async () => {
|
|
1578
|
+
const issue = createMockIssue({
|
|
1579
|
+
status: 'Awaiting Quality Check',
|
|
1580
|
+
});
|
|
1581
|
+
mockIssueRepository.getAllIssues.mockResolvedValue({
|
|
1582
|
+
project: mockProject,
|
|
1583
|
+
issues: [issue],
|
|
1584
|
+
cacheUsed: false,
|
|
1585
|
+
});
|
|
1586
|
+
mockIssueRepository.updateStatus.mockRejectedValue(
|
|
1587
|
+
new Error('Something went wrong'),
|
|
1588
|
+
);
|
|
1589
|
+
|
|
1590
|
+
await expect(
|
|
1591
|
+
useCase.run({
|
|
1592
|
+
projectUrl: 'https://github.com/users/user/projects/1',
|
|
1593
|
+
allowedIssueAuthors: ['owner'],
|
|
1594
|
+
}),
|
|
1595
|
+
).rejects.toThrow('Something went wrong');
|
|
1596
|
+
|
|
1597
|
+
expect(mockIssueCommentRepository.createComment).not.toHaveBeenCalled();
|
|
1598
|
+
});
|
|
1599
|
+
|
|
1600
|
+
it('should skip an archived Unread pull request on updateStatus failure and continue with remaining pull requests', async () => {
|
|
1601
|
+
const archivedPullRequest = createMockPullRequest({
|
|
1602
|
+
number: 1,
|
|
1603
|
+
url: 'https://github.com/user/repo/pull/1',
|
|
1604
|
+
itemId: 'archived-pr-item',
|
|
1605
|
+
status: 'Unread',
|
|
1606
|
+
});
|
|
1607
|
+
const normalPullRequest = createMockPullRequest({
|
|
1608
|
+
number: 2,
|
|
1609
|
+
url: 'https://github.com/user/repo/pull/2',
|
|
1610
|
+
itemId: 'normal-pr-item',
|
|
1611
|
+
status: 'Unread',
|
|
1612
|
+
});
|
|
1613
|
+
mockIssueRepository.getAllIssues.mockResolvedValue({
|
|
1614
|
+
project: mockProject,
|
|
1615
|
+
issues: [archivedPullRequest, normalPullRequest],
|
|
1616
|
+
cacheUsed: false,
|
|
1617
|
+
});
|
|
1618
|
+
mockIssueRepository.getOpenPullRequest.mockImplementation(
|
|
1619
|
+
(prUrl: string) =>
|
|
1620
|
+
Promise.resolve({
|
|
1621
|
+
...createReadyPr(prUrl),
|
|
1622
|
+
isConflicted: true,
|
|
1623
|
+
}),
|
|
1624
|
+
);
|
|
1625
|
+
mockIssueRepository.updateStatus.mockImplementation(
|
|
1626
|
+
(_project: Project, issue: Issue) =>
|
|
1627
|
+
issue.url === archivedPullRequest.url
|
|
1628
|
+
? Promise.reject(
|
|
1629
|
+
new Error('The item is archived and cannot be updated'),
|
|
1630
|
+
)
|
|
1631
|
+
: Promise.resolve(undefined),
|
|
1632
|
+
);
|
|
1633
|
+
|
|
1634
|
+
await useCase.run({
|
|
1635
|
+
projectUrl: 'https://github.com/users/user/projects/1',
|
|
1636
|
+
allowedIssueAuthors: ['owner'],
|
|
1637
|
+
});
|
|
1638
|
+
|
|
1639
|
+
expect(mockIssueRepository.updateStatus).toHaveBeenCalledWith(
|
|
1640
|
+
mockProject,
|
|
1641
|
+
archivedPullRequest,
|
|
1642
|
+
'awaiting-workspace-id',
|
|
1643
|
+
);
|
|
1644
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalledWith(
|
|
1645
|
+
expect.anything(),
|
|
1646
|
+
archivedPullRequest,
|
|
1647
|
+
expect.anything(),
|
|
1648
|
+
);
|
|
1649
|
+
expect(mockIssueCommentRepository.createComment).not.toHaveBeenCalledWith(
|
|
1650
|
+
archivedPullRequest,
|
|
1651
|
+
expect.anything(),
|
|
1652
|
+
);
|
|
1653
|
+
expect(mockIssueRepository.updateStatus).toHaveBeenCalledWith(
|
|
1654
|
+
mockProject,
|
|
1655
|
+
normalPullRequest,
|
|
1656
|
+
'awaiting-workspace-id',
|
|
1657
|
+
);
|
|
1658
|
+
expect(mockIssueRepository.updateStory).toHaveBeenCalledWith(
|
|
1659
|
+
expect.objectContaining({ id: 'project-1' }),
|
|
1660
|
+
normalPullRequest,
|
|
1661
|
+
'workflow-management-story-id',
|
|
1662
|
+
);
|
|
1663
|
+
expect(mockIssueCommentRepository.createComment).toHaveBeenCalledWith(
|
|
1664
|
+
normalPullRequest,
|
|
1665
|
+
expect.stringContaining('Auto Status Check: REJECTED'),
|
|
1666
|
+
);
|
|
1667
|
+
expect(warnSpy).toHaveBeenCalledWith(
|
|
1668
|
+
expect.stringContaining(archivedPullRequest.url),
|
|
1669
|
+
);
|
|
1670
|
+
});
|
|
1671
|
+
|
|
1672
|
+
it('should propagate a non-archived updateStatus error for Unread pull requests unchanged', async () => {
|
|
1673
|
+
const pullRequest = createMockPullRequest({
|
|
1674
|
+
status: 'Unread',
|
|
1675
|
+
});
|
|
1676
|
+
mockIssueRepository.getAllIssues.mockResolvedValue({
|
|
1677
|
+
project: mockProject,
|
|
1678
|
+
issues: [pullRequest],
|
|
1679
|
+
cacheUsed: false,
|
|
1680
|
+
});
|
|
1681
|
+
mockIssueRepository.getOpenPullRequest.mockResolvedValue({
|
|
1682
|
+
...createReadyPr(),
|
|
1683
|
+
isConflicted: true,
|
|
1684
|
+
});
|
|
1685
|
+
mockIssueRepository.updateStatus.mockRejectedValue(
|
|
1686
|
+
new Error('Something went wrong'),
|
|
1687
|
+
);
|
|
1688
|
+
|
|
1689
|
+
await expect(
|
|
1690
|
+
useCase.run({
|
|
1691
|
+
projectUrl: 'https://github.com/users/user/projects/1',
|
|
1692
|
+
allowedIssueAuthors: ['owner'],
|
|
1693
|
+
}),
|
|
1694
|
+
).rejects.toThrow('Something went wrong');
|
|
1695
|
+
|
|
1696
|
+
expect(mockIssueRepository.updateStory).not.toHaveBeenCalled();
|
|
1697
|
+
expect(mockIssueCommentRepository.createComment).not.toHaveBeenCalled();
|
|
1698
|
+
});
|
|
1699
|
+
});
|
|
1510
1700
|
});
|
|
@@ -10,6 +10,16 @@ import {
|
|
|
10
10
|
DEFAULT_STATUS_NAME,
|
|
11
11
|
} from '../entities/WorkflowStatus';
|
|
12
12
|
|
|
13
|
+
// GitHub rejects field mutations against archived project items with
|
|
14
|
+
// "The item is archived and cannot be updated". Such a failure is specific to
|
|
15
|
+
// the single item being reverted, so it must not abort the whole schedule
|
|
16
|
+
// cycle (the same containment policy as the transient GraphQL error handling
|
|
17
|
+
// and the findRelatedOpenPRs NOT_FOUND handling).
|
|
18
|
+
const isArchivedProjectItemError = (error: unknown): boolean => {
|
|
19
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
20
|
+
return message.toLowerCase().includes('archived');
|
|
21
|
+
};
|
|
22
|
+
|
|
13
23
|
const isAuthorAuthorizedForAutoStatusCheck = (
|
|
14
24
|
author: string,
|
|
15
25
|
allowedIssueAuthors: string[] | null | undefined,
|
|
@@ -113,11 +123,21 @@ export class RevertNotReadyReviewQueueIssueUseCase {
|
|
|
113
123
|
},
|
|
114
124
|
);
|
|
115
125
|
if (rejections.length > 0) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
126
|
+
try {
|
|
127
|
+
await this.issueRepository.updateStatus(
|
|
128
|
+
project,
|
|
129
|
+
issue,
|
|
130
|
+
awaitingWorkspaceStatusOption.id,
|
|
131
|
+
);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
if (isArchivedProjectItemError(error)) {
|
|
134
|
+
console.warn(
|
|
135
|
+
`RevertNotReadyReviewQueueIssueUseCase: project item is archived and cannot be updated, skipping revert. issueUrl: ${issue.url}`,
|
|
136
|
+
);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
121
141
|
await this.issueCommentRepository.createComment(
|
|
122
142
|
issue,
|
|
123
143
|
`Auto Status Check: REJECTED\n${rejections.map((r) => `- ${r.detail}`).join('\n')}`,
|
|
@@ -159,11 +179,21 @@ export class RevertNotReadyReviewQueueIssueUseCase {
|
|
|
159
179
|
params.labelsAsLlmAgentName ?? [],
|
|
160
180
|
);
|
|
161
181
|
if (rejections.length > 0) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
182
|
+
try {
|
|
183
|
+
await this.issueRepository.updateStatus(
|
|
184
|
+
project,
|
|
185
|
+
pullRequest,
|
|
186
|
+
awaitingWorkspaceStatusOption.id,
|
|
187
|
+
);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
if (isArchivedProjectItemError(error)) {
|
|
190
|
+
console.warn(
|
|
191
|
+
`RevertNotReadyReviewQueueIssueUseCase: project item is archived and cannot be updated, skipping revert. prUrl: ${pullRequest.url}`,
|
|
192
|
+
);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
167
197
|
if (projectStory) {
|
|
168
198
|
await this.issueRepository.updateStory(
|
|
169
199
|
{ ...project, story: projectStory },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RevertNotReadyReviewQueueIssueUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;
|
|
1
|
+
{"version":3,"file":"RevertNotReadyReviewQueueIssueUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAgCrF,qBAAa,qCAAqC;IAK9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAIlC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAWhC,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAnBzC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA0B;IAClE,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAkC;gBAG/D,iBAAiB,EAAE,IAAI,CACtC,iBAAiB,EACjB,oBAAoB,GAAG,YAAY,CACpC,EACgB,eAAe,EAAE,IAAI,CACpC,eAAe,EACb,cAAc,GACd,cAAc,GACd,aAAa,GACb,oBAAoB,GACpB,oBAAoB,GACpB,gCAAgC,GAChC,oBAAoB,GACpB,iCAAiC,CACpC,EACgB,sBAAsB,EAAE,IAAI,CAC3C,sBAAsB,EACtB,eAAe,CAChB;IAQH,GAAG,GAAU,QAAQ;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QACvC,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;QACxD,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;KACvC,KAAG,OAAO,CAAC,IAAI,CAAC,CA0If;IAQF,OAAO,CAAC,gCAAgC,CAsBtC;CACH"}
|