github-issue-tower-defence-management 1.185.0 → 1.186.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +2 -0
- package/bin/adapter/entry-points/cli/index.js +2 -1
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/console/consoleOperationApi.js +43 -1
- package/bin/adapter/entry-points/console/consoleOperationApi.js.map +1 -1
- package/bin/adapter/entry-points/console/consoleProjectResolver.js +7 -1
- package/bin/adapter/entry-points/console/consoleProjectResolver.js.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/index-wj6o8qvo.js +86 -0
- package/bin/adapter/entry-points/console/ui-dist/assets/index-yZy1TUOo.css +2 -0
- package/bin/adapter/entry-points/console/ui-dist/index.html +2 -2
- package/bin/adapter/entry-points/console/webServer.js +3 -0
- package/bin/adapter/entry-points/console/webServer.js.map +1 -1
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +5 -1
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
- package/bin/adapter/entry-points/handlers/tokenStatusWriter.js +1 -0
- package/bin/adapter/entry-points/handlers/tokenStatusWriter.js.map +1 -1
- package/bin/adapter/repositories/ProcClaudeHandoverSessionRepository.js +40 -3
- package/bin/adapter/repositories/ProcClaudeHandoverSessionRepository.js.map +1 -1
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +36 -0
- package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
- package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js +12 -0
- package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js.map +1 -1
- package/bin/domain/entities/Project.js +11 -1
- package/bin/domain/entities/Project.js.map +1 -1
- package/bin/domain/usecases/HandleScheduledEventUseCase.js +12 -1
- package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -1
- package/bin/domain/usecases/IssueNoStatusUpdateUseCase.js +36 -0
- package/bin/domain/usecases/IssueNoStatusUpdateUseCase.js.map +1 -0
- package/bin/domain/usecases/IssueRejectionEvaluator.js +19 -0
- package/bin/domain/usecases/IssueRejectionEvaluator.js.map +1 -1
- package/bin/domain/usecases/QualityCheckAdvanceUseCase.js +1 -0
- package/bin/domain/usecases/QualityCheckAdvanceUseCase.js.map +1 -1
- package/bin/domain/usecases/ReopenedDoneIssueRevertUseCase.js +36 -0
- package/bin/domain/usecases/ReopenedDoneIssueRevertUseCase.js.map +1 -0
- package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js +2 -5
- package/bin/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.js.map +1 -1
- package/bin/domain/usecases/TokenExhaustionHandoverUseCase.js +9 -1
- package/bin/domain/usecases/TokenExhaustionHandoverUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.ts +14 -10
- package/src/adapter/entry-points/console/consoleOperationApi.test.ts +199 -0
- package/src/adapter/entry-points/console/consoleOperationApi.ts +65 -0
- package/src/adapter/entry-points/console/consoleProjectResolver.test.ts +26 -0
- package/src/adapter/entry-points/console/consoleProjectResolver.ts +8 -1
- package/src/adapter/entry-points/console/dashboardEmitterComposerKey.test.ts +1 -0
- package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +40 -0
- package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +18 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.stories.tsx +4 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.test.tsx +114 -141
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.tsx +84 -3
- package/src/adapter/entry-points/console/ui/src/features/console/lib/consoleApi.ts +23 -0
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +73 -0
- package/src/adapter/entry-points/console/ui/src/index.css +35 -0
- package/src/adapter/entry-points/console/ui-dist/assets/index-wj6o8qvo.js +86 -0
- package/src/adapter/entry-points/console/ui-dist/assets/index-yZy1TUOo.css +2 -0
- package/src/adapter/entry-points/console/ui-dist/index.html +2 -2
- package/src/adapter/entry-points/console/webServer.ts +7 -0
- package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +11 -0
- package/src/adapter/entry-points/handlers/InTmuxByHumanSessionTokenCountHandler.test.ts +1 -0
- package/src/adapter/entry-points/handlers/dashboardRowWriter.test.ts +1 -0
- package/src/adapter/entry-points/handlers/inTmuxByHumanDataWriter.test.ts +1 -0
- package/src/adapter/entry-points/handlers/inTmuxByHumanSessionReconciler.test.ts +1 -0
- package/src/adapter/entry-points/handlers/notifySilentTmuxSessions.test.ts +1 -0
- package/src/adapter/entry-points/handlers/ownerCallFileCleaner.test.ts +1 -0
- package/src/adapter/entry-points/handlers/situationFileWriter.test.ts +1 -0
- package/src/adapter/entry-points/handlers/staleTmuxSessionCleaner.test.ts +1 -0
- package/src/adapter/entry-points/handlers/tokenStatusWriter.test.ts +1 -0
- package/src/adapter/entry-points/handlers/tokenStatusWriter.ts +1 -0
- package/src/adapter/repositories/GitHubIssueCommentRepository.test.ts +1 -0
- package/src/adapter/repositories/ProcClaudeHandoverSessionRepository.test.ts +48 -0
- package/src/adapter/repositories/ProcClaudeHandoverSessionRepository.ts +55 -2
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +90 -0
- package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +48 -2
- package/src/adapter/repositories/issue/GraphqlProjectItemRepository.test.ts +107 -0
- package/src/adapter/repositories/issue/GraphqlProjectItemRepository.ts +20 -0
- package/src/adapter/repositories/issue/RestIssueRepository.test.ts +1 -0
- package/src/domain/entities/ClaudeHandoverSession.ts +1 -0
- package/src/domain/entities/Issue.ts +1 -0
- package/src/domain/entities/Project.ts +11 -2
- package/src/domain/usecases/AgentDesignationLabelAdoptUseCase.test.ts +1 -0
- package/src/domain/usecases/CheckIssueReviewReadinessUseCase.test.ts +1 -0
- package/src/domain/usecases/GetStoryObjectMapUseCase.test.ts +1 -0
- package/src/domain/usecases/HandleScheduledEventUseCase.test.ts +144 -0
- package/src/domain/usecases/HandleScheduledEventUseCase.ts +16 -0
- package/src/domain/usecases/InTmuxByHumanSessionTokenCountUseCase.test.ts +1 -0
- package/src/domain/usecases/IssueNoStatusUpdateUseCase.test.ts +165 -0
- package/src/domain/usecases/IssueNoStatusUpdateUseCase.ts +44 -0
- package/src/domain/usecases/IssueRejectionEvaluator.test.ts +120 -0
- package/src/domain/usecases/IssueRejectionEvaluator.ts +21 -0
- package/src/domain/usecases/NotifyFinishedIssuePreparationUseCase.test.ts +1 -0
- package/src/domain/usecases/NotifySilentLiveSessionsUseCase.test.ts +1 -0
- package/src/domain/usecases/QualityCheckAdvanceUseCase.test.ts +34 -0
- package/src/domain/usecases/QualityCheckAdvanceUseCase.ts +1 -0
- package/src/domain/usecases/ReopenedDoneIssueRevertUseCase.test.ts +188 -0
- package/src/domain/usecases/ReopenedDoneIssueRevertUseCase.ts +57 -0
- package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.test.ts +44 -0
- package/src/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.ts +4 -12
- package/src/domain/usecases/RevertOrphanedPreparationUseCase.test.ts +1 -0
- package/src/domain/usecases/SetupTowerDefenceProjectUseCase.test.ts +1 -0
- package/src/domain/usecases/StaleTmuxSessionKillUseCase.test.ts +1 -0
- package/src/domain/usecases/StartPreparationUseCase.test.ts +1 -0
- package/src/domain/usecases/TokenExhaustionHandoverUseCase.test.ts +59 -1
- package/src/domain/usecases/TokenExhaustionHandoverUseCase.ts +14 -1
- package/src/domain/usecases/TriagerApprovalDispatchUseCase.test.ts +1 -0
- package/src/domain/usecases/adapter-interfaces/IssueRepository.ts +5 -0
- package/src/domain/usecases/console/GenerateConsoleListsUseCase.test.ts +1 -0
- package/src/domain/usecases/dashboard/GenerateDashboardRowUseCase.test.ts +1 -0
- package/src/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.test.ts +1 -0
- package/src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.test.ts +1 -0
- package/src/domain/usecases/issueReactivationTriggerIsPending.test.ts +1 -0
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts +2 -0
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
- package/types/adapter/entry-points/console/consoleProjectResolver.d.ts +1 -0
- package/types/adapter/entry-points/console/consoleProjectResolver.d.ts.map +1 -1
- package/types/adapter/entry-points/console/webServer.d.ts +2 -0
- package/types/adapter/entry-points/console/webServer.d.ts.map +1 -1
- package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
- package/types/adapter/entry-points/handlers/tokenStatusWriter.d.ts.map +1 -1
- package/types/adapter/repositories/ProcClaudeHandoverSessionRepository.d.ts +1 -0
- package/types/adapter/repositories/ProcClaudeHandoverSessionRepository.d.ts.map +1 -1
- package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +4 -1
- package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
- package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts +1 -0
- package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts.map +1 -1
- package/types/domain/entities/ClaudeHandoverSession.d.ts +1 -0
- package/types/domain/entities/ClaudeHandoverSession.d.ts.map +1 -1
- package/types/domain/entities/Issue.d.ts +1 -0
- package/types/domain/entities/Issue.d.ts.map +1 -1
- package/types/domain/entities/Project.d.ts +2 -1
- package/types/domain/entities/Project.d.ts.map +1 -1
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +6 -1
- package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -1
- package/types/domain/usecases/IssueNoStatusUpdateUseCase.d.ts +12 -0
- package/types/domain/usecases/IssueNoStatusUpdateUseCase.d.ts.map +1 -0
- package/types/domain/usecases/IssueRejectionEvaluator.d.ts +1 -0
- package/types/domain/usecases/IssueRejectionEvaluator.d.ts.map +1 -1
- package/types/domain/usecases/QualityCheckAdvanceUseCase.d.ts.map +1 -1
- package/types/domain/usecases/ReopenedDoneIssueRevertUseCase.d.ts +12 -0
- package/types/domain/usecases/ReopenedDoneIssueRevertUseCase.d.ts.map +1 -0
- package/types/domain/usecases/RevertNotReadyReviewQueueIssueUseCase.d.ts.map +1 -1
- package/types/domain/usecases/TokenExhaustionHandoverUseCase.d.ts +1 -0
- package/types/domain/usecases/TokenExhaustionHandoverUseCase.d.ts.map +1 -1
- package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts +3 -0
- package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/index-8Ni5iu-C.css +0 -2
- package/bin/adapter/entry-points/console/ui-dist/assets/index-DQT4HL0G.js +0 -86
- package/src/adapter/entry-points/console/ui-dist/assets/index-8Ni5iu-C.css +0 -2
- package/src/adapter/entry-points/console/ui-dist/assets/index-DQT4HL0G.js +0 -86
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
PullRequestReviewCommentSide,
|
|
10
10
|
PullRequestReviewInlineLocation,
|
|
11
11
|
} from '../../../domain/usecases/adapter-interfaces/IssueRepository';
|
|
12
|
-
import { Project } from '../../../domain/entities/Project';
|
|
12
|
+
import { FieldOption, Project } from '../../../domain/entities/Project';
|
|
13
13
|
import { Issue } from '../../../domain/entities/Issue';
|
|
14
14
|
import { SearchedIssue } from '../../../domain/entities/SearchedIssue';
|
|
15
15
|
import { StoryObjectMap } from '../../../domain/entities/StoryObjectMap';
|
|
@@ -28,7 +28,10 @@ import {
|
|
|
28
28
|
ProjectIssuesCacheRepository,
|
|
29
29
|
} from '../ProjectIssuesCacheRepository';
|
|
30
30
|
import { BaseGitHubRepository } from '../BaseGitHubRepository';
|
|
31
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
fetchGithubGraphql,
|
|
33
|
+
postGithubGraphqlJson,
|
|
34
|
+
} from '../githubGraphqlClient';
|
|
32
35
|
import { normalizeFieldName } from '../utils';
|
|
33
36
|
import { LocalStorageRepository } from '../LocalStorageRepository';
|
|
34
37
|
import { Member } from '../../../domain/entities/Member';
|
|
@@ -687,6 +690,7 @@ export class ApiV3CheerioRestIssueRepository
|
|
|
687
690
|
closingIssueReferenceUrls: item.closingIssueReferenceUrls,
|
|
688
691
|
agent,
|
|
689
692
|
isRepoArchived: item.isRepoArchived,
|
|
693
|
+
stateReason: item.stateReason,
|
|
690
694
|
};
|
|
691
695
|
};
|
|
692
696
|
private restoreIssuesFromCache = (rawIssues: unknown): Issue[] | null => {
|
|
@@ -723,12 +727,20 @@ export class ApiV3CheerioRestIssueRepository
|
|
|
723
727
|
? issue.closingIssueReferenceUrls
|
|
724
728
|
: [];
|
|
725
729
|
|
|
730
|
+
const stateReason =
|
|
731
|
+
'stateReason' in issue &&
|
|
732
|
+
(issue.stateReason === 'COMPLETED' ||
|
|
733
|
+
issue.stateReason === 'NOT_PLANNED' ||
|
|
734
|
+
issue.stateReason === 'REOPENED')
|
|
735
|
+
? issue.stateReason
|
|
736
|
+
: null;
|
|
726
737
|
return {
|
|
727
738
|
...issue,
|
|
728
739
|
nextActionDate: nextActionDate,
|
|
729
740
|
completionDate50PercentConfidence: completionDate50PercentConfidence,
|
|
730
741
|
createdAt: createdAt,
|
|
731
742
|
closingIssueReferenceUrls: closingIssueReferenceUrls,
|
|
743
|
+
stateReason: stateReason,
|
|
732
744
|
};
|
|
733
745
|
});
|
|
734
746
|
|
|
@@ -1071,6 +1083,40 @@ export class ApiV3CheerioRestIssueRepository
|
|
|
1071
1083
|
{ singleSelectOptionId: storyOptionId },
|
|
1072
1084
|
);
|
|
1073
1085
|
};
|
|
1086
|
+
updateStoryOptionColor = async (
|
|
1087
|
+
project: Project & { story: NonNullable<Project['story']> },
|
|
1088
|
+
storyOptionId: string,
|
|
1089
|
+
newColor: FieldOption['color'],
|
|
1090
|
+
): Promise<void> => {
|
|
1091
|
+
const mutation = `mutation UpdateStoryOptionColor($fieldId: ID!, $options: [ProjectV2SingleSelectFieldOptionInput!]!) {
|
|
1092
|
+
updateProjectV2Field(input: {
|
|
1093
|
+
fieldId: $fieldId
|
|
1094
|
+
singleSelectOptions: $options
|
|
1095
|
+
}) {
|
|
1096
|
+
projectV2Field {
|
|
1097
|
+
... on ProjectV2SingleSelectField {
|
|
1098
|
+
options { id name color description }
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}`;
|
|
1103
|
+
const options = project.story.stories.map((opt) => ({
|
|
1104
|
+
id: opt.id,
|
|
1105
|
+
name: opt.name,
|
|
1106
|
+
color: opt.id === storyOptionId ? newColor : opt.color,
|
|
1107
|
+
description: opt.description,
|
|
1108
|
+
}));
|
|
1109
|
+
const response = await postGithubGraphqlJson<{
|
|
1110
|
+
errors?: { message: string }[];
|
|
1111
|
+
}>({
|
|
1112
|
+
ghToken: this.ghToken,
|
|
1113
|
+
query: mutation,
|
|
1114
|
+
variables: { fieldId: project.story.fieldId, options },
|
|
1115
|
+
});
|
|
1116
|
+
if (response.errors && response.errors.length > 0) {
|
|
1117
|
+
throw new Error(response.errors.map((e) => e.message).join('; '));
|
|
1118
|
+
}
|
|
1119
|
+
};
|
|
1074
1120
|
clearProjectField = async (
|
|
1075
1121
|
project: Project,
|
|
1076
1122
|
fieldId: string,
|
|
@@ -781,6 +781,80 @@ describe('GraphqlProjectItemRepository', () => {
|
|
|
781
781
|
);
|
|
782
782
|
warnSpy.mockRestore();
|
|
783
783
|
});
|
|
784
|
+
|
|
785
|
+
it('requests stateReason in the Issue content fragment of the GraphQL query', async () => {
|
|
786
|
+
const repository = new GraphqlProjectItemRepository(
|
|
787
|
+
new LocalStorageRepository(),
|
|
788
|
+
'dummy-token',
|
|
789
|
+
);
|
|
790
|
+
mockPost.mockReturnValueOnce(makePageResponse(false, 'cursor-1', 1));
|
|
791
|
+
|
|
792
|
+
await repository.fetchProjectItems('test-project-id');
|
|
793
|
+
|
|
794
|
+
const sentQuery = extractRequestedQueryFromMockCall(
|
|
795
|
+
mockPost.mock.calls[0],
|
|
796
|
+
);
|
|
797
|
+
expect(sentQuery).toContain('stateReason');
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
it('maps stateReason REOPENED from Issue content node to ProjectItem.stateReason', async () => {
|
|
801
|
+
const repository = new GraphqlProjectItemRepository(
|
|
802
|
+
new LocalStorageRepository(),
|
|
803
|
+
'dummy-token',
|
|
804
|
+
);
|
|
805
|
+
mockPost.mockReturnValueOnce(
|
|
806
|
+
mockJsonResponse({
|
|
807
|
+
data: {
|
|
808
|
+
node: {
|
|
809
|
+
items: {
|
|
810
|
+
totalCount: 1,
|
|
811
|
+
pageInfo: {
|
|
812
|
+
endCursor: 'cursor-1',
|
|
813
|
+
startCursor: 'cursor-start',
|
|
814
|
+
hasNextPage: false,
|
|
815
|
+
},
|
|
816
|
+
nodes: [
|
|
817
|
+
{
|
|
818
|
+
id: 'item-1',
|
|
819
|
+
fieldValues: { nodes: [] },
|
|
820
|
+
content: {
|
|
821
|
+
repository: { nameWithOwner: 'owner/repo' },
|
|
822
|
+
number: 1,
|
|
823
|
+
title: 'Test Issue',
|
|
824
|
+
state: 'OPEN',
|
|
825
|
+
stateReason: 'REOPENED',
|
|
826
|
+
url: 'https://github.com/owner/repo/issues/1',
|
|
827
|
+
body: 'body',
|
|
828
|
+
createdAt: '2024-01-01T00:00:00Z',
|
|
829
|
+
labels: { nodes: [] },
|
|
830
|
+
assignees: { nodes: [] },
|
|
831
|
+
},
|
|
832
|
+
},
|
|
833
|
+
],
|
|
834
|
+
},
|
|
835
|
+
},
|
|
836
|
+
},
|
|
837
|
+
}),
|
|
838
|
+
);
|
|
839
|
+
|
|
840
|
+
const result = await repository.fetchProjectItems('test-project-id');
|
|
841
|
+
|
|
842
|
+
expect(result).toHaveLength(1);
|
|
843
|
+
expect(result[0].stateReason).toBe('REOPENED');
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
it('maps stateReason to null when the field is absent from the content node', async () => {
|
|
847
|
+
const repository = new GraphqlProjectItemRepository(
|
|
848
|
+
new LocalStorageRepository(),
|
|
849
|
+
'dummy-token',
|
|
850
|
+
);
|
|
851
|
+
mockPost.mockReturnValueOnce(makePageResponse(false, 'cursor-1', 1));
|
|
852
|
+
|
|
853
|
+
const result = await repository.fetchProjectItems('test-project-id');
|
|
854
|
+
|
|
855
|
+
expect(result).toHaveLength(1);
|
|
856
|
+
expect(result[0].stateReason).toBeNull();
|
|
857
|
+
});
|
|
784
858
|
});
|
|
785
859
|
|
|
786
860
|
const extractRequestedVariablesFromMockCall = (
|
|
@@ -1665,5 +1739,38 @@ describe('GraphqlProjectItemRepository', () => {
|
|
|
1665
1739
|
|
|
1666
1740
|
warnSpy.mockRestore();
|
|
1667
1741
|
});
|
|
1742
|
+
|
|
1743
|
+
it('maps stateReason from the single-item Issue response', async () => {
|
|
1744
|
+
const localStorageRepository = new LocalStorageRepository();
|
|
1745
|
+
const repository = new GraphqlProjectItemRepository(
|
|
1746
|
+
localStorageRepository,
|
|
1747
|
+
'dummy-token',
|
|
1748
|
+
);
|
|
1749
|
+
|
|
1750
|
+
mockPost.mockReturnValueOnce(
|
|
1751
|
+
mockJsonResponse({
|
|
1752
|
+
data: {
|
|
1753
|
+
repository: {
|
|
1754
|
+
issue: {
|
|
1755
|
+
...makeContentNode(
|
|
1756
|
+
'https://github.com/owner/repo/issues/42',
|
|
1757
|
+
42,
|
|
1758
|
+
'Reopened Issue',
|
|
1759
|
+
),
|
|
1760
|
+
stateReason: 'REOPENED',
|
|
1761
|
+
},
|
|
1762
|
+
pullRequest: null,
|
|
1763
|
+
},
|
|
1764
|
+
},
|
|
1765
|
+
}),
|
|
1766
|
+
);
|
|
1767
|
+
|
|
1768
|
+
const result = await repository.fetchProjectItemByUrl(
|
|
1769
|
+
'https://github.com/owner/repo/issues/42',
|
|
1770
|
+
);
|
|
1771
|
+
|
|
1772
|
+
expect(result).not.toBeNull();
|
|
1773
|
+
expect(result?.stateReason).toBe('REOPENED');
|
|
1774
|
+
});
|
|
1668
1775
|
});
|
|
1669
1776
|
});
|
|
@@ -18,6 +18,7 @@ export type ProjectItem = {
|
|
|
18
18
|
author: string;
|
|
19
19
|
closingIssueReferenceUrls: string[];
|
|
20
20
|
isRepoArchived: boolean;
|
|
21
|
+
stateReason: 'COMPLETED' | 'NOT_PLANNED' | 'REOPENED' | null;
|
|
21
22
|
customFields: {
|
|
22
23
|
name: string;
|
|
23
24
|
value: string | null;
|
|
@@ -51,6 +52,7 @@ type ProjectV2ItemContentNode = {
|
|
|
51
52
|
labels: { nodes: { name: string }[] };
|
|
52
53
|
assignees: { nodes: { login: string }[] };
|
|
53
54
|
closingIssuesReferences?: { nodes: { url: string }[] };
|
|
55
|
+
stateReason?: string | null;
|
|
54
56
|
};
|
|
55
57
|
type ProjectV2ItemNode = {
|
|
56
58
|
id: string;
|
|
@@ -121,6 +123,7 @@ const PROJECT_V2_ITEM_FIELD_VALUES_AND_CONTENT_SELECTION = `
|
|
|
121
123
|
number
|
|
122
124
|
title
|
|
123
125
|
state
|
|
126
|
+
stateReason
|
|
124
127
|
url
|
|
125
128
|
body
|
|
126
129
|
createdAt
|
|
@@ -186,6 +189,19 @@ export const RATE_LIMIT_MAX_BACKOFF_MS = 300000;
|
|
|
186
189
|
const sleep = (ms: number): Promise<void> =>
|
|
187
190
|
new Promise((resolve) => setTimeout(resolve, ms));
|
|
188
191
|
|
|
192
|
+
const toStateReason = (
|
|
193
|
+
value: string | null | undefined,
|
|
194
|
+
): 'COMPLETED' | 'NOT_PLANNED' | 'REOPENED' | null => {
|
|
195
|
+
if (
|
|
196
|
+
value === 'COMPLETED' ||
|
|
197
|
+
value === 'NOT_PLANNED' ||
|
|
198
|
+
value === 'REOPENED'
|
|
199
|
+
) {
|
|
200
|
+
return value;
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
};
|
|
204
|
+
|
|
189
205
|
const parseNonNegativeIntegerHeader = (value: string | null): number | null => {
|
|
190
206
|
if (value === null) {
|
|
191
207
|
return null;
|
|
@@ -634,6 +650,7 @@ query GetProjectItems($projectId: ID!, $after: String, $first: Int!, $query: Str
|
|
|
634
650
|
?.map((node) => node.url)
|
|
635
651
|
.filter((url) => url.length > 0) || [],
|
|
636
652
|
isRepoArchived: item.content.repository.isArchived ?? false,
|
|
653
|
+
stateReason: toStateReason(item.content.stateReason),
|
|
637
654
|
customFields: item.fieldValues.nodes
|
|
638
655
|
.filter((field) => !!field.field)
|
|
639
656
|
.map((field) => {
|
|
@@ -1049,6 +1066,7 @@ query GetProjectFields($owner: String!, $repository: String!, $issueNumber: Int!
|
|
|
1049
1066
|
number
|
|
1050
1067
|
title
|
|
1051
1068
|
state
|
|
1069
|
+
stateReason
|
|
1052
1070
|
url
|
|
1053
1071
|
body
|
|
1054
1072
|
createdAt
|
|
@@ -1222,6 +1240,7 @@ query GetProjectFields($owner: String!, $repository: String!, $issueNumber: Int!
|
|
|
1222
1240
|
number: number;
|
|
1223
1241
|
title: string;
|
|
1224
1242
|
state: string;
|
|
1243
|
+
stateReason?: string | null;
|
|
1225
1244
|
url: string;
|
|
1226
1245
|
body: string;
|
|
1227
1246
|
createdAt: string;
|
|
@@ -1309,6 +1328,7 @@ query GetProjectFields($owner: String!, $repository: String!, $issueNumber: Int!
|
|
|
1309
1328
|
?.map((node) => node.url)
|
|
1310
1329
|
.filter((url) => url.length > 0) || [],
|
|
1311
1330
|
isRepoArchived: content.repository.isArchived ?? false,
|
|
1331
|
+
stateReason: toStateReason(content.stateReason),
|
|
1312
1332
|
customFields: item.fieldValues.nodes
|
|
1313
1333
|
.filter((field) => !!field.field)
|
|
1314
1334
|
.map((field) => {
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
export const FIELD_OPTION_COLORS = [
|
|
2
|
+
'GRAY',
|
|
3
|
+
'BLUE',
|
|
4
|
+
'GREEN',
|
|
5
|
+
'YELLOW',
|
|
6
|
+
'ORANGE',
|
|
7
|
+
'RED',
|
|
8
|
+
'PINK',
|
|
9
|
+
'PURPLE',
|
|
10
|
+
] as const;
|
|
1
11
|
export type StoryOption = FieldOption;
|
|
2
12
|
export type FieldOption = {
|
|
3
13
|
id: string;
|
|
4
14
|
name: string;
|
|
5
|
-
color:
|
|
6
|
-
'GRAY' | 'BLUE' | 'GREEN' | 'YELLOW' | 'ORANGE' | 'RED' | 'PINK' | 'PURPLE';
|
|
15
|
+
color: (typeof FIELD_OPTION_COLORS)[number];
|
|
7
16
|
description: string;
|
|
8
17
|
};
|
|
9
18
|
|
|
@@ -21,6 +21,7 @@ import { SetNoStoryIssueToStoryUseCase } from './SetNoStoryIssueToStoryUseCase';
|
|
|
21
21
|
import { CreateNewStoryByLabelUseCase } from './CreateNewStoryByLabelUseCase';
|
|
22
22
|
import { AssignNoAssigneeIssueToManagerUseCase } from './AssignNoAssigneeIssueToManagerUseCase';
|
|
23
23
|
import { UpdateIssueStatusByLabelUseCase } from './UpdateIssueStatusByLabelUseCase';
|
|
24
|
+
import { IssueNoStatusUpdateUseCase } from './IssueNoStatusUpdateUseCase';
|
|
24
25
|
import { StartPreparationUseCase } from './StartPreparationUseCase';
|
|
25
26
|
import { RevertOrphanedPreparationUseCase } from './RevertOrphanedPreparationUseCase';
|
|
26
27
|
import { RevertNotReadyReviewQueueIssueUseCase } from './RevertNotReadyReviewQueueIssueUseCase';
|
|
@@ -31,6 +32,7 @@ import { SetupTowerDefenceProjectUseCase } from './SetupTowerDefenceProjectUseCa
|
|
|
31
32
|
import { UpdateRateLimitCacheUseCase } from './UpdateRateLimitCacheUseCase';
|
|
32
33
|
import { DailySecurityScanUseCase } from './DailySecurityScanUseCase';
|
|
33
34
|
import { QualityCheckAdvanceUseCase } from './QualityCheckAdvanceUseCase';
|
|
35
|
+
import { ReopenedDoneIssueRevertUseCase } from './ReopenedDoneIssueRevertUseCase';
|
|
34
36
|
|
|
35
37
|
describe('HandleScheduledEventUseCase', () => {
|
|
36
38
|
describe('createTargetDateTimes', () => {
|
|
@@ -121,6 +123,7 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
121
123
|
mock<AssignNoAssigneeIssueToManagerUseCase>();
|
|
122
124
|
const mockUpdateIssueStatusByLabelUseCase =
|
|
123
125
|
mock<UpdateIssueStatusByLabelUseCase>();
|
|
126
|
+
const mockIssueNoStatusUpdateUseCase = mock<IssueNoStatusUpdateUseCase>();
|
|
124
127
|
const mockStartPreparationUseCase = mock<StartPreparationUseCase>();
|
|
125
128
|
const mockRevertOrphanedPreparationUseCase =
|
|
126
129
|
mock<RevertOrphanedPreparationUseCase>();
|
|
@@ -133,6 +136,8 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
133
136
|
const mockUpdateRateLimitCacheUseCase = mock<UpdateRateLimitCacheUseCase>();
|
|
134
137
|
const mockDailySecurityScanUseCase = mock<DailySecurityScanUseCase>();
|
|
135
138
|
const mockAdvanceQualityCheckUseCase = mock<QualityCheckAdvanceUseCase>();
|
|
139
|
+
const mockReopenedDoneIssueRevertUseCase =
|
|
140
|
+
mock<ReopenedDoneIssueRevertUseCase>();
|
|
136
141
|
const mockDateRepository = mock<DateRepository>();
|
|
137
142
|
const mockSpreadsheetRepository = mock<SpreadsheetRepository>();
|
|
138
143
|
const mockProjectRepository = mock<ProjectRepository>();
|
|
@@ -156,6 +161,7 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
156
161
|
mockCreateNewStoryByLabelUseCase,
|
|
157
162
|
mockAssignNoAssigneeIssueToManagerUseCase,
|
|
158
163
|
mockUpdateIssueStatusByLabelUseCase,
|
|
164
|
+
mockIssueNoStatusUpdateUseCase,
|
|
159
165
|
mockStartPreparationUseCase,
|
|
160
166
|
mockRevertOrphanedPreparationUseCase,
|
|
161
167
|
mockRevertNotReadyReviewQueueIssueUseCase,
|
|
@@ -164,6 +170,7 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
164
170
|
mockUpdateRateLimitCacheUseCase,
|
|
165
171
|
mockDailySecurityScanUseCase,
|
|
166
172
|
mockAdvanceQualityCheckUseCase,
|
|
173
|
+
mockReopenedDoneIssueRevertUseCase,
|
|
167
174
|
mockDateRepository,
|
|
168
175
|
mockSpreadsheetRepository,
|
|
169
176
|
mockProjectRepository,
|
|
@@ -240,6 +247,41 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
240
247
|
});
|
|
241
248
|
});
|
|
242
249
|
|
|
250
|
+
it('should call IssueNoStatusUpdateUseCase with project and issues when startPreparation is configured', async () => {
|
|
251
|
+
const input = {
|
|
252
|
+
projectName: 'test-project',
|
|
253
|
+
org: 'test-org',
|
|
254
|
+
projectUrl: 'https://github.com/test-org/test-project',
|
|
255
|
+
manager: 'test-manager',
|
|
256
|
+
workingReport: {
|
|
257
|
+
repo: 'test-repo',
|
|
258
|
+
members: ['member1'],
|
|
259
|
+
spreadsheetUrl: 'https://docs.google.com/spreadsheets/test',
|
|
260
|
+
},
|
|
261
|
+
urlOfStoryView: 'https://github.com/test-org/test-project/issues',
|
|
262
|
+
disabled: false,
|
|
263
|
+
startPreparation: {
|
|
264
|
+
defaultAgentName: 'agent1',
|
|
265
|
+
configFilePath: '/path/to/config.yml',
|
|
266
|
+
maximumPreparingIssuesCount: null,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
const mockProject = mock<Project>();
|
|
271
|
+
const mockIssues = [mock<Issue>()];
|
|
272
|
+
mockIssueRepository.getAllIssues.mockResolvedValue({
|
|
273
|
+
issues: mockIssues,
|
|
274
|
+
project: mockProject,
|
|
275
|
+
cacheUsed: false,
|
|
276
|
+
});
|
|
277
|
+
await useCase.run(input);
|
|
278
|
+
|
|
279
|
+
expect(mockIssueNoStatusUpdateUseCase.run).toHaveBeenCalledWith({
|
|
280
|
+
project: mockProject,
|
|
281
|
+
issues: mockIssues,
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
|
|
243
285
|
it('should call TriagerApprovalDispatchUseCase with project URL', async () => {
|
|
244
286
|
const input = {
|
|
245
287
|
projectName: 'test-project',
|
|
@@ -1616,6 +1658,105 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
1616
1658
|
expect(mockStartPreparationUseCase.run).toHaveBeenCalled();
|
|
1617
1659
|
});
|
|
1618
1660
|
});
|
|
1661
|
+
|
|
1662
|
+
describe('reopenedDoneIssueRevertUseCase', () => {
|
|
1663
|
+
const baseInput = {
|
|
1664
|
+
projectName: 'test-project',
|
|
1665
|
+
org: 'test-org',
|
|
1666
|
+
projectUrl: 'https://github.com/test-org/test-project',
|
|
1667
|
+
manager: 'test-manager',
|
|
1668
|
+
workingReport: {
|
|
1669
|
+
repo: 'test-repo',
|
|
1670
|
+
members: ['member1'],
|
|
1671
|
+
spreadsheetUrl: 'https://docs.google.com/spreadsheets/test',
|
|
1672
|
+
},
|
|
1673
|
+
urlOfStoryView: 'https://github.com/test-org/test-project/issues',
|
|
1674
|
+
disabled: false,
|
|
1675
|
+
};
|
|
1676
|
+
|
|
1677
|
+
it('does not call reopenedDoneIssueRevertUseCase when startPreparation is absent', async () => {
|
|
1678
|
+
await useCase.run(baseInput);
|
|
1679
|
+
|
|
1680
|
+
expect(mockReopenedDoneIssueRevertUseCase.run).not.toHaveBeenCalled();
|
|
1681
|
+
});
|
|
1682
|
+
|
|
1683
|
+
it('does not call reopenedDoneIssueRevertUseCase when autoRevertReopenedDoneEnabled is absent', async () => {
|
|
1684
|
+
await useCase.run({
|
|
1685
|
+
...baseInput,
|
|
1686
|
+
startPreparation: {
|
|
1687
|
+
defaultAgentName: 'agent1',
|
|
1688
|
+
configFilePath: '/path/to/config.yml',
|
|
1689
|
+
maximumPreparingIssuesCount: null,
|
|
1690
|
+
autoAdvanceQualityCheckEnabled: false,
|
|
1691
|
+
},
|
|
1692
|
+
});
|
|
1693
|
+
|
|
1694
|
+
expect(mockReopenedDoneIssueRevertUseCase.run).not.toHaveBeenCalled();
|
|
1695
|
+
});
|
|
1696
|
+
|
|
1697
|
+
it('does not call reopenedDoneIssueRevertUseCase when autoRevertReopenedDoneEnabled is false', async () => {
|
|
1698
|
+
await useCase.run({
|
|
1699
|
+
...baseInput,
|
|
1700
|
+
startPreparation: {
|
|
1701
|
+
defaultAgentName: 'agent1',
|
|
1702
|
+
configFilePath: '/path/to/config.yml',
|
|
1703
|
+
maximumPreparingIssuesCount: null,
|
|
1704
|
+
autoAdvanceQualityCheckEnabled: false,
|
|
1705
|
+
autoRevertReopenedDoneEnabled: false,
|
|
1706
|
+
},
|
|
1707
|
+
});
|
|
1708
|
+
|
|
1709
|
+
expect(mockReopenedDoneIssueRevertUseCase.run).not.toHaveBeenCalled();
|
|
1710
|
+
});
|
|
1711
|
+
|
|
1712
|
+
it('calls reopenedDoneIssueRevertUseCase with project and issues when autoRevertReopenedDoneEnabled is true', async () => {
|
|
1713
|
+
const mockProject = mock<Project>();
|
|
1714
|
+
const mockIssues: Issue[] = [];
|
|
1715
|
+
mockIssueRepository.getAllIssues.mockResolvedValue({
|
|
1716
|
+
issues: mockIssues,
|
|
1717
|
+
project: mockProject,
|
|
1718
|
+
cacheUsed: false,
|
|
1719
|
+
});
|
|
1720
|
+
|
|
1721
|
+
await useCase.run({
|
|
1722
|
+
...baseInput,
|
|
1723
|
+
startPreparation: {
|
|
1724
|
+
defaultAgentName: 'agent1',
|
|
1725
|
+
configFilePath: '/path/to/config.yml',
|
|
1726
|
+
maximumPreparingIssuesCount: null,
|
|
1727
|
+
autoAdvanceQualityCheckEnabled: false,
|
|
1728
|
+
autoRevertReopenedDoneEnabled: true,
|
|
1729
|
+
},
|
|
1730
|
+
});
|
|
1731
|
+
|
|
1732
|
+
expect(mockReopenedDoneIssueRevertUseCase.run).toHaveBeenCalledWith({
|
|
1733
|
+
project: mockProject,
|
|
1734
|
+
issues: mockIssues,
|
|
1735
|
+
});
|
|
1736
|
+
});
|
|
1737
|
+
|
|
1738
|
+
it('continues to startPreparationUseCase when reopenedDoneIssueRevertUseCase.run rejects', async () => {
|
|
1739
|
+
mockReopenedDoneIssueRevertUseCase.run.mockRejectedValue(
|
|
1740
|
+
new AggregateError(
|
|
1741
|
+
[new Error('GitHub API error')],
|
|
1742
|
+
'Failed to revert 1 reopened Done issue(s)',
|
|
1743
|
+
),
|
|
1744
|
+
);
|
|
1745
|
+
|
|
1746
|
+
await useCase.run({
|
|
1747
|
+
...baseInput,
|
|
1748
|
+
startPreparation: {
|
|
1749
|
+
defaultAgentName: 'agent1',
|
|
1750
|
+
configFilePath: '/path/to/config.yml',
|
|
1751
|
+
maximumPreparingIssuesCount: null,
|
|
1752
|
+
autoAdvanceQualityCheckEnabled: false,
|
|
1753
|
+
autoRevertReopenedDoneEnabled: true,
|
|
1754
|
+
},
|
|
1755
|
+
});
|
|
1756
|
+
|
|
1757
|
+
expect(mockStartPreparationUseCase.run).toHaveBeenCalled();
|
|
1758
|
+
});
|
|
1759
|
+
});
|
|
1619
1760
|
});
|
|
1620
1761
|
|
|
1621
1762
|
describe('storyIssues', () => {
|
|
@@ -1637,6 +1778,7 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
1637
1778
|
mock<CreateNewStoryByLabelUseCase>(),
|
|
1638
1779
|
mock<AssignNoAssigneeIssueToManagerUseCase>(),
|
|
1639
1780
|
mock<UpdateIssueStatusByLabelUseCase>(),
|
|
1781
|
+
mock<IssueNoStatusUpdateUseCase>(),
|
|
1640
1782
|
mock<StartPreparationUseCase>(),
|
|
1641
1783
|
mock<RevertOrphanedPreparationUseCase>(),
|
|
1642
1784
|
mock<RevertNotReadyReviewQueueIssueUseCase>(),
|
|
@@ -1645,6 +1787,7 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
1645
1787
|
null,
|
|
1646
1788
|
null,
|
|
1647
1789
|
mock<QualityCheckAdvanceUseCase>(),
|
|
1790
|
+
mock<ReopenedDoneIssueRevertUseCase>(),
|
|
1648
1791
|
mock<DateRepository>(),
|
|
1649
1792
|
mock<SpreadsheetRepository>(),
|
|
1650
1793
|
mock<ProjectRepository>(),
|
|
@@ -1701,6 +1844,7 @@ describe('HandleScheduledEventUseCase', () => {
|
|
|
1701
1844
|
author: '',
|
|
1702
1845
|
closingIssueReferenceUrls: [],
|
|
1703
1846
|
agent: null,
|
|
1847
|
+
stateReason: null,
|
|
1704
1848
|
};
|
|
1705
1849
|
|
|
1706
1850
|
it('should return storyIssue as null when the only matching issue is closed', async () => {
|
|
@@ -21,6 +21,7 @@ import { SetNoStoryIssueToStoryUseCase } from './SetNoStoryIssueToStoryUseCase';
|
|
|
21
21
|
import { CreateNewStoryByLabelUseCase } from './CreateNewStoryByLabelUseCase';
|
|
22
22
|
import { AssignNoAssigneeIssueToManagerUseCase } from './AssignNoAssigneeIssueToManagerUseCase';
|
|
23
23
|
import { UpdateIssueStatusByLabelUseCase } from './UpdateIssueStatusByLabelUseCase';
|
|
24
|
+
import { IssueNoStatusUpdateUseCase } from './IssueNoStatusUpdateUseCase';
|
|
24
25
|
import {
|
|
25
26
|
RotationOrderEntry,
|
|
26
27
|
StartPreparationUseCase,
|
|
@@ -40,6 +41,7 @@ import {
|
|
|
40
41
|
DailySecurityScanUseCase,
|
|
41
42
|
} from './DailySecurityScanUseCase';
|
|
42
43
|
import { QualityCheckAdvanceUseCase } from './QualityCheckAdvanceUseCase';
|
|
44
|
+
import { ReopenedDoneIssueRevertUseCase } from './ReopenedDoneIssueRevertUseCase';
|
|
43
45
|
|
|
44
46
|
export class ProjectNotFoundError extends Error {
|
|
45
47
|
constructor(message: string) {
|
|
@@ -133,6 +135,7 @@ export class HandleScheduledEventUseCase {
|
|
|
133
135
|
readonly createNewStoryByLabelUseCase: CreateNewStoryByLabelUseCase,
|
|
134
136
|
readonly assignNoAssigneeIssueToManagerUseCase: AssignNoAssigneeIssueToManagerUseCase,
|
|
135
137
|
readonly updateIssueStatusByLabelUseCase: UpdateIssueStatusByLabelUseCase,
|
|
138
|
+
readonly issueNoStatusUpdateUseCase: IssueNoStatusUpdateUseCase,
|
|
136
139
|
readonly startPreparationUseCase: StartPreparationUseCase,
|
|
137
140
|
readonly revertOrphanedPreparationUseCase: RevertOrphanedPreparationUseCase,
|
|
138
141
|
readonly revertNotReadyReviewQueueIssueUseCase: RevertNotReadyReviewQueueIssueUseCase,
|
|
@@ -141,6 +144,7 @@ export class HandleScheduledEventUseCase {
|
|
|
141
144
|
readonly updateRateLimitCacheUseCase: UpdateRateLimitCacheUseCase | null,
|
|
142
145
|
readonly dailySecurityScanUseCase: DailySecurityScanUseCase | null,
|
|
143
146
|
readonly qualityCheckAdvanceUseCase: QualityCheckAdvanceUseCase,
|
|
147
|
+
readonly reopenedDoneIssueRevertUseCase: ReopenedDoneIssueRevertUseCase,
|
|
144
148
|
readonly dateRepository: DateRepository,
|
|
145
149
|
readonly spreadsheetRepository: SpreadsheetRepository,
|
|
146
150
|
readonly projectRepository: ProjectRepository,
|
|
@@ -180,6 +184,7 @@ export class HandleScheduledEventUseCase {
|
|
|
180
184
|
awLogStaleThresholdMinutes?: number;
|
|
181
185
|
awaitingQualityCheckStatus?: string | null;
|
|
182
186
|
autoAdvanceQualityCheckEnabled?: boolean;
|
|
187
|
+
autoRevertReopenedDoneEnabled?: boolean;
|
|
183
188
|
labelsAsLlmAgentName?: string[] | null;
|
|
184
189
|
} | null;
|
|
185
190
|
thresholdForAutoReject?: number;
|
|
@@ -473,6 +478,16 @@ ${JSON.stringify(e)}
|
|
|
473
478
|
allowedIssueAuthors,
|
|
474
479
|
});
|
|
475
480
|
}
|
|
481
|
+
if (input.startPreparation.autoRevertReopenedDoneEnabled) {
|
|
482
|
+
try {
|
|
483
|
+
await this.reopenedDoneIssueRevertUseCase.run({ project, issues });
|
|
484
|
+
} catch (revertError) {
|
|
485
|
+
console.error(
|
|
486
|
+
`[HandleScheduledEvent] Failed to revert reopened Done issues for project ${project.url}: ${revertError instanceof Error ? revertError.message : String(revertError)}`,
|
|
487
|
+
revertError,
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
476
491
|
if (input.startPreparation.autoAdvanceQualityCheckEnabled) {
|
|
477
492
|
try {
|
|
478
493
|
await this.qualityCheckAdvanceUseCase.run({
|
|
@@ -489,6 +504,7 @@ ${JSON.stringify(e)}
|
|
|
489
504
|
);
|
|
490
505
|
}
|
|
491
506
|
}
|
|
507
|
+
await this.issueNoStatusUpdateUseCase.run({ project, issues });
|
|
492
508
|
const preparationResult = await this.startPreparationUseCase.run({
|
|
493
509
|
projectUrl: input.projectUrl,
|
|
494
510
|
defaultAgentName: input.startPreparation.defaultAgentName,
|