@gh-symphony/cli 0.0.22 → 0.1.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/README.md +72 -77
- package/dist/{chunk-HMLBBZNY.js → chunk-2YF7PQUC.js} +16 -71
- package/dist/{chunk-IWFX2FMA.js → chunk-6I753NYO.js} +4 -1
- package/dist/{chunk-2TSM3INR.js → chunk-HQ7A3C7K.js} +575 -12
- package/dist/{chunk-36KYEDEO.js → chunk-MVRF7BES.js} +1 -10
- package/dist/{workflow-L3KT6HB7.js → chunk-NESHTYXQ.js} +27 -19
- package/dist/{chunk-2UW7NQLX.js → chunk-PEZUBHWJ.js} +1 -1
- package/dist/chunk-PG332ZS4.js +238 -0
- package/dist/{chunk-EEQQWTXS.js → chunk-WCOIVNHH.js} +213 -82
- package/dist/{chunk-QIRE2VXS.js → chunk-WOVNN5NW.js} +16 -17
- package/dist/{chunk-C67H3OUL.js → chunk-Z3NZOPLZ.js} +0 -81
- package/dist/{config-cmd-Z3A7V6NC.js → config-cmd-2ADPUYWA.js} +1 -1
- package/dist/{doctor-EJUMPBMW.js → doctor-2AXHIEAP.js} +464 -40
- package/dist/index.js +340 -294
- package/dist/{chunk-PUDXVBSN.js → repo-SUXYT4OK.js} +6272 -2996
- package/dist/{setup-TZJSM3QV.js → setup-UBHOMXUG.js} +57 -92
- package/dist/{upgrade-O33S2SJK.js → upgrade-355SQJ5P.js} +2 -2
- package/dist/{version-CW54Q7BK.js → version-4ILSDZQH.js} +1 -1
- package/dist/worker-entry.js +10 -5
- package/dist/workflow-S6YSZPQT.js +22 -0
- package/package.json +4 -4
- package/dist/chunk-DDL4BWSL.js +0 -146
- package/dist/chunk-DFLXHNYQ.js +0 -482
- package/dist/chunk-E7HYEEZD.js +0 -1318
- package/dist/chunk-GDE6FYN4.js +0 -26
- package/dist/chunk-GSX2FV3M.js +0 -103
- package/dist/chunk-ZHOKYUO3.js +0 -1047
- package/dist/init-54HMKNYI.js +0 -38
- package/dist/logs-GTZ4U5JE.js +0 -188
- package/dist/project-RMYMZSFV.js +0 -25
- package/dist/recover-LTLKMTRX.js +0 -133
- package/dist/repo-WI7GF6XQ.js +0 -749
- package/dist/run-IHN3ZL35.js +0 -122
- package/dist/start-RTAHQMR2.js +0 -19
- package/dist/status-F4D52OVK.js +0 -12
- package/dist/stop-MDKMJPVR.js +0 -10
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_WORKFLOW_LIFECYCLE
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WCOIVNHH.js";
|
|
5
|
+
import {
|
|
6
|
+
loadGlobalConfig,
|
|
7
|
+
loadProjectConfig
|
|
8
|
+
} from "./chunk-WOVNN5NW.js";
|
|
5
9
|
|
|
6
10
|
// ../tracker-github/src/adapter.ts
|
|
7
11
|
import { createHash } from "crypto";
|
|
@@ -23,11 +27,22 @@ var GitHubTrackerQueryError = class extends GitHubTrackerError {
|
|
|
23
27
|
};
|
|
24
28
|
var cachedGitHubGraphQLRateLimits = /* @__PURE__ */ new Map();
|
|
25
29
|
function normalizeProjectItem(projectId, item, lifecycle = DEFAULT_WORKFLOW_LIFECYCLE, priority = {}, rateLimits = null) {
|
|
26
|
-
if (item.content?.__typename !== "Issue") {
|
|
30
|
+
if (item.content?.__typename !== "Issue" && item.content?.__typename !== "PullRequest") {
|
|
27
31
|
return null;
|
|
28
32
|
}
|
|
29
33
|
const fieldValues = extractFieldValues(item.fieldValues?.nodes ?? []);
|
|
30
34
|
const state = fieldValues[lifecycle.stateFieldName] ?? "Unknown";
|
|
35
|
+
if (item.content.__typename === "PullRequest") {
|
|
36
|
+
return normalizePullRequestProjectItem(
|
|
37
|
+
projectId,
|
|
38
|
+
item,
|
|
39
|
+
item.content,
|
|
40
|
+
fieldValues,
|
|
41
|
+
state,
|
|
42
|
+
priority,
|
|
43
|
+
rateLimits
|
|
44
|
+
);
|
|
45
|
+
}
|
|
31
46
|
const repository = item.content.repository;
|
|
32
47
|
const blockedBy = (item.content.blockedBy?.nodes ?? []).flatMap(
|
|
33
48
|
(node) => node ? [
|
|
@@ -41,6 +56,10 @@ function normalizeProjectItem(projectId, item, lifecycle = DEFAULT_WORKFLOW_LIFE
|
|
|
41
56
|
const issueUpdatedAtMs = parseTimestampMs(item.content.updatedAt);
|
|
42
57
|
const itemUpdatedAtMs = parseTimestampMs(item.updatedAt);
|
|
43
58
|
const trackedUpdatedAt = itemUpdatedAtMs !== null && (issueUpdatedAtMs === null || itemUpdatedAtMs > issueUpdatedAtMs) ? item.updatedAt : item.content.updatedAt ?? item.updatedAt;
|
|
59
|
+
const linkedPullRequests = normalizePullRequestNodes(
|
|
60
|
+
item.content.closedByPullRequestsReferences?.nodes ?? []
|
|
61
|
+
);
|
|
62
|
+
const linkedPullRequestsTruncated = item.content.closedByPullRequestsReferences?.pageInfo?.hasNextPage ?? false;
|
|
44
63
|
return {
|
|
45
64
|
id: item.content.id,
|
|
46
65
|
identifier: `${repository.owner.login}/${repository.name}#${item.content.number}`,
|
|
@@ -51,7 +70,7 @@ function normalizeProjectItem(projectId, item, lifecycle = DEFAULT_WORKFLOW_LIFE
|
|
|
51
70
|
state,
|
|
52
71
|
branchName: null,
|
|
53
72
|
url: item.content.url,
|
|
54
|
-
labels: (item.content.labels?.nodes ?? [])
|
|
73
|
+
labels: normalizeLabelNames(item.content.labels?.nodes ?? []),
|
|
55
74
|
blockedBy,
|
|
56
75
|
createdAt: item.content.createdAt,
|
|
57
76
|
updatedAt: trackedUpdatedAt,
|
|
@@ -66,7 +85,44 @@ function normalizeProjectItem(projectId, item, lifecycle = DEFAULT_WORKFLOW_LIFE
|
|
|
66
85
|
bindingId: projectId,
|
|
67
86
|
itemId: item.id
|
|
68
87
|
},
|
|
69
|
-
metadata:
|
|
88
|
+
metadata: withIssueMetadata(
|
|
89
|
+
fieldValues,
|
|
90
|
+
linkedPullRequests,
|
|
91
|
+
linkedPullRequestsTruncated
|
|
92
|
+
),
|
|
93
|
+
rateLimits
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function normalizePullRequestProjectItem(projectId, item, content, fieldValues, state, priority, rateLimits) {
|
|
97
|
+
const pullRequest = normalizePullRequestNode(content);
|
|
98
|
+
const itemUpdatedAtMs = parseTimestampMs(item.updatedAt);
|
|
99
|
+
const pullRequestUpdatedAtMs = parseTimestampMs(content.updatedAt);
|
|
100
|
+
const trackedUpdatedAt = itemUpdatedAtMs !== null && (pullRequestUpdatedAtMs === null || itemUpdatedAtMs > pullRequestUpdatedAtMs) ? item.updatedAt : content.updatedAt ?? item.updatedAt;
|
|
101
|
+
return {
|
|
102
|
+
id: content.id,
|
|
103
|
+
identifier: pullRequest.identifier,
|
|
104
|
+
number: content.number,
|
|
105
|
+
title: content.title,
|
|
106
|
+
description: content.body,
|
|
107
|
+
priority: resolvePriority(item, priority),
|
|
108
|
+
state,
|
|
109
|
+
branchName: content.headRefName,
|
|
110
|
+
url: content.url,
|
|
111
|
+
labels: pullRequest.labels,
|
|
112
|
+
blockedBy: [],
|
|
113
|
+
createdAt: content.createdAt,
|
|
114
|
+
updatedAt: trackedUpdatedAt,
|
|
115
|
+
repository: pullRequest.repository,
|
|
116
|
+
tracker: {
|
|
117
|
+
adapter: "github-project",
|
|
118
|
+
bindingId: projectId,
|
|
119
|
+
itemId: item.id
|
|
120
|
+
},
|
|
121
|
+
metadata: withGitHubMetadata(fieldValues, {
|
|
122
|
+
contentType: "PullRequest",
|
|
123
|
+
pullRequest,
|
|
124
|
+
linkedPullRequests: []
|
|
125
|
+
}),
|
|
70
126
|
rateLimits
|
|
71
127
|
};
|
|
72
128
|
}
|
|
@@ -228,6 +284,70 @@ async function fetchProjectItemsPage(config, cursor, fetchImpl) {
|
|
|
228
284
|
var fetchGithubProjectIssues = fetchProjectIssues;
|
|
229
285
|
var fetchGithubIssueStatesByIds = fetchIssueStatesByIds;
|
|
230
286
|
var fetchGithubProjectIssueByRepositoryAndNumber = fetchProjectIssueByRepositoryAndNumber;
|
|
287
|
+
var upsertGithubIssueComment = upsertIssueComment;
|
|
288
|
+
async function upsertIssueComment(config, issueId, input, fetchImpl = fetch) {
|
|
289
|
+
const existingComment = await findIssueCommentByMarker(
|
|
290
|
+
config,
|
|
291
|
+
issueId,
|
|
292
|
+
input.marker,
|
|
293
|
+
fetchImpl
|
|
294
|
+
);
|
|
295
|
+
if (!existingComment) {
|
|
296
|
+
await executeGraphQLQuery(
|
|
297
|
+
config,
|
|
298
|
+
ADD_ISSUE_COMMENT_MUTATION,
|
|
299
|
+
{
|
|
300
|
+
subjectId: issueId,
|
|
301
|
+
body: input.body
|
|
302
|
+
},
|
|
303
|
+
fetchImpl
|
|
304
|
+
);
|
|
305
|
+
return "created";
|
|
306
|
+
}
|
|
307
|
+
if (existingComment.body === input.body) {
|
|
308
|
+
return "unchanged";
|
|
309
|
+
}
|
|
310
|
+
await executeGraphQLQuery(
|
|
311
|
+
config,
|
|
312
|
+
UPDATE_ISSUE_COMMENT_MUTATION,
|
|
313
|
+
{
|
|
314
|
+
commentId: existingComment.id,
|
|
315
|
+
body: input.body
|
|
316
|
+
},
|
|
317
|
+
fetchImpl
|
|
318
|
+
);
|
|
319
|
+
return "updated";
|
|
320
|
+
}
|
|
321
|
+
async function findIssueCommentByMarker(config, issueId, marker, fetchImpl) {
|
|
322
|
+
let cursor = null;
|
|
323
|
+
while (true) {
|
|
324
|
+
const data = await executeGraphQLQuery(
|
|
325
|
+
config,
|
|
326
|
+
ISSUE_COMMENTS_BY_ID_QUERY,
|
|
327
|
+
{
|
|
328
|
+
issueId,
|
|
329
|
+
cursor
|
|
330
|
+
},
|
|
331
|
+
fetchImpl
|
|
332
|
+
);
|
|
333
|
+
if (data.node?.__typename !== "Issue") {
|
|
334
|
+
throw new GitHubTrackerQueryError(
|
|
335
|
+
"GitHub GraphQL response did not include issue comments."
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
const issueNode = data.node;
|
|
339
|
+
const match = issueNode.comments.nodes?.find(
|
|
340
|
+
(comment) => comment?.body.includes(marker)
|
|
341
|
+
) ?? null;
|
|
342
|
+
if (match) {
|
|
343
|
+
return match;
|
|
344
|
+
}
|
|
345
|
+
if (!issueNode.comments.pageInfo.hasNextPage) {
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
cursor = issueNode.comments.pageInfo.endCursor;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
231
351
|
async function fetchCurrentUserLogin(config, fetchImpl) {
|
|
232
352
|
const response = await fetchImpl(resolveRestUserApiUrl(config.apiUrl), {
|
|
233
353
|
method: "GET",
|
|
@@ -255,7 +375,7 @@ async function fetchCurrentUserLogin(config, fetchImpl) {
|
|
|
255
375
|
return payload.login;
|
|
256
376
|
}
|
|
257
377
|
function isIssueAssignedToLogin(item, login) {
|
|
258
|
-
if (item.content?.__typename !== "Issue") {
|
|
378
|
+
if (item.content?.__typename !== "Issue" && item.content?.__typename !== "PullRequest") {
|
|
259
379
|
return false;
|
|
260
380
|
}
|
|
261
381
|
return (item.content.assignees?.nodes ?? []).some(
|
|
@@ -289,7 +409,7 @@ function extractFieldValues(nodes) {
|
|
|
289
409
|
}, {});
|
|
290
410
|
}
|
|
291
411
|
function normalizeIssueStateLookupNode(projectId, issue, projectItem, lifecycle = DEFAULT_WORKFLOW_LIFECYCLE, rateLimits = null) {
|
|
292
|
-
if (issue?.__typename !== "Issue") {
|
|
412
|
+
if (issue?.__typename !== "Issue" && issue?.__typename !== "PullRequest") {
|
|
293
413
|
return null;
|
|
294
414
|
}
|
|
295
415
|
if (!projectItem) {
|
|
@@ -299,6 +419,7 @@ function normalizeIssueStateLookupNode(projectId, issue, projectItem, lifecycle
|
|
|
299
419
|
const state = fieldValues[lifecycle.stateFieldName] ?? "Unknown";
|
|
300
420
|
const repository = issue.repository;
|
|
301
421
|
const identifier = `${repository.owner.login}/${repository.name}#${issue.number}`;
|
|
422
|
+
const url = issue.url ?? `${repository.url}/${issue.__typename === "PullRequest" ? "pull" : "issues"}/${issue.number}`;
|
|
302
423
|
return {
|
|
303
424
|
id: issue.id,
|
|
304
425
|
identifier,
|
|
@@ -307,8 +428,8 @@ function normalizeIssueStateLookupNode(projectId, issue, projectItem, lifecycle
|
|
|
307
428
|
description: null,
|
|
308
429
|
priority: null,
|
|
309
430
|
state,
|
|
310
|
-
branchName: null,
|
|
311
|
-
url
|
|
431
|
+
branchName: issue.__typename === "PullRequest" ? issue.headRefName ?? null : null,
|
|
432
|
+
url,
|
|
312
433
|
labels: [],
|
|
313
434
|
blockedBy: [],
|
|
314
435
|
createdAt: null,
|
|
@@ -324,7 +445,7 @@ function normalizeIssueStateLookupNode(projectId, issue, projectItem, lifecycle
|
|
|
324
445
|
bindingId: projectId,
|
|
325
446
|
itemId: projectItem.id
|
|
326
447
|
},
|
|
327
|
-
metadata: fieldValues,
|
|
448
|
+
metadata: issue.__typename === "PullRequest" ? withGitHubMetadata(fieldValues, { contentType: "PullRequest" }) : fieldValues,
|
|
328
449
|
rateLimits
|
|
329
450
|
};
|
|
330
451
|
}
|
|
@@ -345,8 +466,64 @@ function normalizeRepositoryIssueLookup(projectId, issue, projectItem, lifecycle
|
|
|
345
466
|
rateLimits
|
|
346
467
|
);
|
|
347
468
|
}
|
|
469
|
+
function normalizePullRequestNodes(nodes) {
|
|
470
|
+
return nodes.flatMap(
|
|
471
|
+
(node) => node ? [normalizePullRequestNode(node)] : []
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
function normalizePullRequestNode(node) {
|
|
475
|
+
const repository = normalizeRepositoryRef(node.repository);
|
|
476
|
+
return {
|
|
477
|
+
id: node.id,
|
|
478
|
+
number: node.number,
|
|
479
|
+
identifier: `${repository.owner}/${repository.name}#${node.number}`,
|
|
480
|
+
title: node.title,
|
|
481
|
+
body: node.body,
|
|
482
|
+
url: node.url,
|
|
483
|
+
state: node.state,
|
|
484
|
+
isDraft: node.isDraft,
|
|
485
|
+
merged: node.merged,
|
|
486
|
+
headRefName: node.headRefName,
|
|
487
|
+
baseRefName: node.baseRefName,
|
|
488
|
+
headRepository: node.headRepository ? normalizeRepositoryRef(node.headRepository) : null,
|
|
489
|
+
repository,
|
|
490
|
+
labels: normalizeLabelNames(node.labels?.nodes ?? []),
|
|
491
|
+
assignees: normalizeAssigneeLogins(node.assignees?.nodes ?? []),
|
|
492
|
+
createdAt: node.createdAt,
|
|
493
|
+
updatedAt: node.updatedAt
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
function normalizeRepositoryRef(repository) {
|
|
497
|
+
return {
|
|
498
|
+
owner: repository.owner.login,
|
|
499
|
+
name: repository.name,
|
|
500
|
+
url: repository.url,
|
|
501
|
+
cloneUrl: deriveCloneUrl(repository.url)
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
function normalizeLabelNames(nodes) {
|
|
505
|
+
return nodes.flatMap((label) => label?.name ? [label.name.toLowerCase()] : []).sort();
|
|
506
|
+
}
|
|
507
|
+
function normalizeAssigneeLogins(nodes) {
|
|
508
|
+
return nodes.flatMap((assignee) => assignee?.login ? [assignee.login] : []);
|
|
509
|
+
}
|
|
510
|
+
function withGitHubMetadata(fieldValues, metadata) {
|
|
511
|
+
return {
|
|
512
|
+
...fieldValues,
|
|
513
|
+
...metadata
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
function withIssueMetadata(fieldValues, linkedPullRequests, linkedPullRequestsTruncated = false) {
|
|
517
|
+
if (linkedPullRequests.length === 0 && !linkedPullRequestsTruncated) {
|
|
518
|
+
return fieldValues;
|
|
519
|
+
}
|
|
520
|
+
return withGitHubMetadata(fieldValues, {
|
|
521
|
+
linkedPullRequests,
|
|
522
|
+
linkedPullRequestsTruncated
|
|
523
|
+
});
|
|
524
|
+
}
|
|
348
525
|
async function resolveIssueProjectItemForStateLookup(config, issue, fetchImpl) {
|
|
349
|
-
if (issue?.__typename !== "Issue") {
|
|
526
|
+
if (issue?.__typename !== "Issue" && issue?.__typename !== "PullRequest") {
|
|
350
527
|
return null;
|
|
351
528
|
}
|
|
352
529
|
let connection = issue.projectItems;
|
|
@@ -383,7 +560,7 @@ async function fetchIssueProjectItemsPage(config, issueId, cursor, fetchImpl) {
|
|
|
383
560
|
);
|
|
384
561
|
const data = result.data;
|
|
385
562
|
const issue = data.node;
|
|
386
|
-
if (issue?.__typename !== "Issue" || !issue.projectItems) {
|
|
563
|
+
if (issue?.__typename !== "Issue" && issue?.__typename !== "PullRequest" || !issue.projectItems) {
|
|
387
564
|
throw new GitHubTrackerQueryError(
|
|
388
565
|
"GitHub GraphQL response did not include issue project items."
|
|
389
566
|
);
|
|
@@ -670,6 +847,17 @@ var PROJECT_ITEMS_QUERY = `
|
|
|
670
847
|
}
|
|
671
848
|
}
|
|
672
849
|
}
|
|
850
|
+
closedByPullRequestsReferences(first: 20) {
|
|
851
|
+
nodes {
|
|
852
|
+
...PullRequestMetadata
|
|
853
|
+
}
|
|
854
|
+
pageInfo {
|
|
855
|
+
hasNextPage
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
... on PullRequest {
|
|
860
|
+
...PullRequestMetadata
|
|
673
861
|
}
|
|
674
862
|
}
|
|
675
863
|
}
|
|
@@ -681,6 +869,45 @@ var PROJECT_ITEMS_QUERY = `
|
|
|
681
869
|
}
|
|
682
870
|
}
|
|
683
871
|
}
|
|
872
|
+
|
|
873
|
+
fragment PullRequestMetadata on PullRequest {
|
|
874
|
+
id
|
|
875
|
+
number
|
|
876
|
+
title
|
|
877
|
+
body
|
|
878
|
+
url
|
|
879
|
+
state
|
|
880
|
+
isDraft
|
|
881
|
+
merged
|
|
882
|
+
headRefName
|
|
883
|
+
baseRefName
|
|
884
|
+
headRepository {
|
|
885
|
+
name
|
|
886
|
+
url
|
|
887
|
+
owner {
|
|
888
|
+
login
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
repository {
|
|
892
|
+
name
|
|
893
|
+
url
|
|
894
|
+
owner {
|
|
895
|
+
login
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
labels(first: 20) {
|
|
899
|
+
nodes {
|
|
900
|
+
name
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
assignees(first: 20) {
|
|
904
|
+
nodes {
|
|
905
|
+
login
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
createdAt
|
|
909
|
+
updatedAt
|
|
910
|
+
}
|
|
684
911
|
`;
|
|
685
912
|
var PROJECT_FIELDS_QUERY = `
|
|
686
913
|
query ProjectFields($projectId: ID!) {
|
|
@@ -710,7 +937,57 @@ var ISSUE_STATES_BY_IDS_QUERY = `
|
|
|
710
937
|
... on Issue {
|
|
711
938
|
id
|
|
712
939
|
number
|
|
940
|
+
url
|
|
941
|
+
updatedAt
|
|
942
|
+
repository {
|
|
943
|
+
name
|
|
944
|
+
url
|
|
945
|
+
owner {
|
|
946
|
+
login
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
projectItems(first: 100, includeArchived: false) {
|
|
950
|
+
nodes {
|
|
951
|
+
id
|
|
952
|
+
updatedAt
|
|
953
|
+
project {
|
|
954
|
+
id
|
|
955
|
+
}
|
|
956
|
+
fieldValues(first: 20) {
|
|
957
|
+
nodes {
|
|
958
|
+
__typename
|
|
959
|
+
... on ProjectV2ItemFieldSingleSelectValue {
|
|
960
|
+
name
|
|
961
|
+
optionId
|
|
962
|
+
field {
|
|
963
|
+
... on ProjectV2SingleSelectField {
|
|
964
|
+
name
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
... on ProjectV2ItemFieldTextValue {
|
|
969
|
+
text
|
|
970
|
+
field {
|
|
971
|
+
... on ProjectV2FieldCommon {
|
|
972
|
+
name
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
pageInfo {
|
|
980
|
+
endCursor
|
|
981
|
+
hasNextPage
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
... on PullRequest {
|
|
986
|
+
id
|
|
987
|
+
number
|
|
988
|
+
url
|
|
713
989
|
updatedAt
|
|
990
|
+
headRefName
|
|
714
991
|
repository {
|
|
715
992
|
name
|
|
716
993
|
url
|
|
@@ -764,6 +1041,7 @@ var ISSUE_PROJECT_ITEMS_PAGE_QUERY = `
|
|
|
764
1041
|
... on Issue {
|
|
765
1042
|
id
|
|
766
1043
|
number
|
|
1044
|
+
url
|
|
767
1045
|
updatedAt
|
|
768
1046
|
repository {
|
|
769
1047
|
name
|
|
@@ -808,6 +1086,96 @@ var ISSUE_PROJECT_ITEMS_PAGE_QUERY = `
|
|
|
808
1086
|
}
|
|
809
1087
|
}
|
|
810
1088
|
}
|
|
1089
|
+
... on PullRequest {
|
|
1090
|
+
id
|
|
1091
|
+
number
|
|
1092
|
+
url
|
|
1093
|
+
updatedAt
|
|
1094
|
+
headRefName
|
|
1095
|
+
repository {
|
|
1096
|
+
name
|
|
1097
|
+
url
|
|
1098
|
+
owner {
|
|
1099
|
+
login
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
projectItems(first: 100, after: $cursor, includeArchived: false) {
|
|
1103
|
+
nodes {
|
|
1104
|
+
id
|
|
1105
|
+
updatedAt
|
|
1106
|
+
project {
|
|
1107
|
+
id
|
|
1108
|
+
}
|
|
1109
|
+
fieldValues(first: 20) {
|
|
1110
|
+
nodes {
|
|
1111
|
+
__typename
|
|
1112
|
+
... on ProjectV2ItemFieldSingleSelectValue {
|
|
1113
|
+
name
|
|
1114
|
+
optionId
|
|
1115
|
+
field {
|
|
1116
|
+
... on ProjectV2SingleSelectField {
|
|
1117
|
+
name
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
... on ProjectV2ItemFieldTextValue {
|
|
1122
|
+
text
|
|
1123
|
+
field {
|
|
1124
|
+
... on ProjectV2FieldCommon {
|
|
1125
|
+
name
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
pageInfo {
|
|
1133
|
+
endCursor
|
|
1134
|
+
hasNextPage
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
`;
|
|
1141
|
+
var ISSUE_COMMENTS_BY_ID_QUERY = `
|
|
1142
|
+
query IssueCommentsById($issueId: ID!, $cursor: String) {
|
|
1143
|
+
node(id: $issueId) {
|
|
1144
|
+
__typename
|
|
1145
|
+
... on Issue {
|
|
1146
|
+
comments(first: 100, after: $cursor) {
|
|
1147
|
+
nodes {
|
|
1148
|
+
id
|
|
1149
|
+
body
|
|
1150
|
+
}
|
|
1151
|
+
pageInfo {
|
|
1152
|
+
endCursor
|
|
1153
|
+
hasNextPage
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
`;
|
|
1160
|
+
var ADD_ISSUE_COMMENT_MUTATION = `
|
|
1161
|
+
mutation AddIssueComment($subjectId: ID!, $body: String!) {
|
|
1162
|
+
addComment(input: { subjectId: $subjectId, body: $body }) {
|
|
1163
|
+
commentEdge {
|
|
1164
|
+
node {
|
|
1165
|
+
id
|
|
1166
|
+
body
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
`;
|
|
1172
|
+
var UPDATE_ISSUE_COMMENT_MUTATION = `
|
|
1173
|
+
mutation UpdateIssueComment($commentId: ID!, $body: String!) {
|
|
1174
|
+
updateIssueComment(input: { id: $commentId, body: $body }) {
|
|
1175
|
+
issueComment {
|
|
1176
|
+
id
|
|
1177
|
+
body
|
|
1178
|
+
}
|
|
811
1179
|
}
|
|
812
1180
|
}
|
|
813
1181
|
`;
|
|
@@ -857,6 +1225,14 @@ var REPOSITORY_ISSUE_QUERY = `
|
|
|
857
1225
|
}
|
|
858
1226
|
}
|
|
859
1227
|
}
|
|
1228
|
+
closedByPullRequestsReferences(first: 20) {
|
|
1229
|
+
nodes {
|
|
1230
|
+
...RepositoryIssuePullRequestMetadata
|
|
1231
|
+
}
|
|
1232
|
+
pageInfo {
|
|
1233
|
+
hasNextPage
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
860
1236
|
projectItems(first: 20, includeArchived: false) {
|
|
861
1237
|
nodes {
|
|
862
1238
|
id
|
|
@@ -895,6 +1271,45 @@ var REPOSITORY_ISSUE_QUERY = `
|
|
|
895
1271
|
}
|
|
896
1272
|
}
|
|
897
1273
|
}
|
|
1274
|
+
|
|
1275
|
+
fragment RepositoryIssuePullRequestMetadata on PullRequest {
|
|
1276
|
+
id
|
|
1277
|
+
number
|
|
1278
|
+
title
|
|
1279
|
+
body
|
|
1280
|
+
url
|
|
1281
|
+
state
|
|
1282
|
+
isDraft
|
|
1283
|
+
merged
|
|
1284
|
+
headRefName
|
|
1285
|
+
baseRefName
|
|
1286
|
+
headRepository {
|
|
1287
|
+
name
|
|
1288
|
+
url
|
|
1289
|
+
owner {
|
|
1290
|
+
login
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
repository {
|
|
1294
|
+
name
|
|
1295
|
+
url
|
|
1296
|
+
owner {
|
|
1297
|
+
login
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
labels(first: 20) {
|
|
1301
|
+
nodes {
|
|
1302
|
+
name
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
assignees(first: 20) {
|
|
1306
|
+
nodes {
|
|
1307
|
+
login
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
createdAt
|
|
1311
|
+
updatedAt
|
|
1312
|
+
}
|
|
898
1313
|
`;
|
|
899
1314
|
|
|
900
1315
|
// ../tracker-github/src/orchestrator-adapter.ts
|
|
@@ -949,6 +1364,15 @@ var githubProjectTrackerAdapter = {
|
|
|
949
1364
|
},
|
|
950
1365
|
metadata: {}
|
|
951
1366
|
};
|
|
1367
|
+
},
|
|
1368
|
+
async upsertIssueComment(project, issue, input, dependencies = {}) {
|
|
1369
|
+
const trackerConfig = resolveGitHubTrackerConfig(project, dependencies);
|
|
1370
|
+
return upsertGithubIssueComment(
|
|
1371
|
+
trackerConfig,
|
|
1372
|
+
issue.id,
|
|
1373
|
+
input,
|
|
1374
|
+
dependencies.fetchImpl
|
|
1375
|
+
);
|
|
952
1376
|
}
|
|
953
1377
|
};
|
|
954
1378
|
async function findGithubProjectIssue(project, identifier, dependencies = {}) {
|
|
@@ -1078,8 +1502,147 @@ function parseIssueIdentifier(identifier) {
|
|
|
1078
1502
|
};
|
|
1079
1503
|
}
|
|
1080
1504
|
|
|
1505
|
+
// src/project-selection.ts
|
|
1506
|
+
import * as p from "@clack/prompts";
|
|
1507
|
+
function isInteractiveTerminal() {
|
|
1508
|
+
return process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
1509
|
+
}
|
|
1510
|
+
function explicitProjectRequiredMessage() {
|
|
1511
|
+
return "Multiple repository runtime configs are present. Run 'gh-symphony repo init' from the target repository to refresh the cwd runtime.\n";
|
|
1512
|
+
}
|
|
1513
|
+
async function inspectManagedProjectSelection(input) {
|
|
1514
|
+
if (input.requestedProjectId) {
|
|
1515
|
+
const projectConfig = await loadProjectConfig(
|
|
1516
|
+
input.configDir,
|
|
1517
|
+
input.requestedProjectId
|
|
1518
|
+
);
|
|
1519
|
+
if (!projectConfig) {
|
|
1520
|
+
return {
|
|
1521
|
+
kind: "requested_project_missing",
|
|
1522
|
+
projectId: input.requestedProjectId,
|
|
1523
|
+
message: `Project "${input.requestedProjectId}" is not configured. Run 'gh-symphony repo init' from the target repository.`
|
|
1524
|
+
};
|
|
1525
|
+
}
|
|
1526
|
+
return {
|
|
1527
|
+
kind: "resolved",
|
|
1528
|
+
projectId: input.requestedProjectId,
|
|
1529
|
+
projectConfig
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
const global = await loadGlobalConfig(input.configDir);
|
|
1533
|
+
if (!global) {
|
|
1534
|
+
return {
|
|
1535
|
+
kind: "missing_global_config",
|
|
1536
|
+
message: "No repository runtime config found. Run 'gh-symphony repo init' first."
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
const projectIds = global.projects ?? [];
|
|
1540
|
+
if (projectIds.length === 0) {
|
|
1541
|
+
return {
|
|
1542
|
+
kind: "no_projects",
|
|
1543
|
+
message: "No repository runtime config is configured. Run 'gh-symphony repo init' first."
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
if (projectIds.length > 1 && !isInteractiveTerminal()) {
|
|
1547
|
+
return {
|
|
1548
|
+
kind: "multiple_projects_require_selection",
|
|
1549
|
+
message: explicitProjectRequiredMessage().trimEnd()
|
|
1550
|
+
};
|
|
1551
|
+
}
|
|
1552
|
+
if (global.activeProject) {
|
|
1553
|
+
const projectConfig = await loadProjectConfig(
|
|
1554
|
+
input.configDir,
|
|
1555
|
+
global.activeProject
|
|
1556
|
+
);
|
|
1557
|
+
if (!projectConfig) {
|
|
1558
|
+
return {
|
|
1559
|
+
kind: "active_project_missing",
|
|
1560
|
+
projectId: global.activeProject,
|
|
1561
|
+
message: `Active project "${global.activeProject}" is configured in config.json but its project config is missing. Re-run 'gh-symphony repo init'.`
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
return {
|
|
1565
|
+
kind: "resolved",
|
|
1566
|
+
projectId: global.activeProject,
|
|
1567
|
+
projectConfig
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
if (projectIds.length === 1) {
|
|
1571
|
+
const projectId = projectIds[0];
|
|
1572
|
+
const projectConfig = await loadProjectConfig(input.configDir, projectId);
|
|
1573
|
+
if (!projectConfig) {
|
|
1574
|
+
return {
|
|
1575
|
+
kind: "configured_project_missing",
|
|
1576
|
+
projectId,
|
|
1577
|
+
message: `Configured project "${projectId}" is missing its project config file. Re-run 'gh-symphony repo init'.`
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
return {
|
|
1581
|
+
kind: "resolved",
|
|
1582
|
+
projectId,
|
|
1583
|
+
projectConfig
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
return {
|
|
1587
|
+
kind: "multiple_projects_require_selection",
|
|
1588
|
+
message: "Multiple repository runtime configs are present and no active project is set. Re-run 'gh-symphony repo init' from the target repository."
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
async function resolveManagedProjectConfig(input) {
|
|
1592
|
+
if (input.requestedProjectId) {
|
|
1593
|
+
return loadProjectConfig(input.configDir, input.requestedProjectId);
|
|
1594
|
+
}
|
|
1595
|
+
const global = await loadGlobalConfig(input.configDir);
|
|
1596
|
+
const projectIds = global?.projects ?? [];
|
|
1597
|
+
if (projectIds.length === 0) {
|
|
1598
|
+
return null;
|
|
1599
|
+
}
|
|
1600
|
+
if (projectIds.length === 1) {
|
|
1601
|
+
return loadProjectConfig(input.configDir, projectIds[0]);
|
|
1602
|
+
}
|
|
1603
|
+
if (!isInteractiveTerminal()) {
|
|
1604
|
+
process.stderr.write(explicitProjectRequiredMessage());
|
|
1605
|
+
process.exitCode = 1;
|
|
1606
|
+
return null;
|
|
1607
|
+
}
|
|
1608
|
+
const projects = await Promise.all(
|
|
1609
|
+
projectIds.map(async (projectId) => ({
|
|
1610
|
+
projectId,
|
|
1611
|
+
config: await loadProjectConfig(input.configDir, projectId)
|
|
1612
|
+
}))
|
|
1613
|
+
);
|
|
1614
|
+
const selected = await p.select({
|
|
1615
|
+
message: "Select a project:",
|
|
1616
|
+
options: projects.map(({ projectId, config }) => ({
|
|
1617
|
+
value: projectId,
|
|
1618
|
+
label: config?.displayName ?? config?.slug ?? projectId,
|
|
1619
|
+
hint: projectId === global?.activeProject ? "current" : config && config.displayName && config.displayName !== projectId ? projectId : void 0
|
|
1620
|
+
})),
|
|
1621
|
+
maxItems: 10
|
|
1622
|
+
});
|
|
1623
|
+
if (p.isCancel(selected)) {
|
|
1624
|
+
p.cancel("Cancelled.");
|
|
1625
|
+
process.exitCode = 130;
|
|
1626
|
+
return null;
|
|
1627
|
+
}
|
|
1628
|
+
return loadProjectConfig(input.configDir, selected);
|
|
1629
|
+
}
|
|
1630
|
+
function handleMissingManagedProjectConfig() {
|
|
1631
|
+
if (process.exitCode) {
|
|
1632
|
+
return;
|
|
1633
|
+
}
|
|
1634
|
+
process.stderr.write(
|
|
1635
|
+
"No repository runtime config found. Run 'gh-symphony repo init' first.\n"
|
|
1636
|
+
);
|
|
1637
|
+
process.exitCode = 1;
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1081
1640
|
export {
|
|
1641
|
+
fetchGithubProjectIssues,
|
|
1082
1642
|
fetchGithubProjectIssueByRepositoryAndNumber,
|
|
1083
1643
|
findGithubProjectIssue,
|
|
1084
|
-
resolveTrackerAdapter
|
|
1644
|
+
resolveTrackerAdapter,
|
|
1645
|
+
inspectManagedProjectSelection,
|
|
1646
|
+
resolveManagedProjectConfig,
|
|
1647
|
+
handleMissingManagedProjectConfig
|
|
1085
1648
|
};
|