pm-github 2026.10.13 → 2026.10.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +174 -3
- package/dist/closeout.d.ts +83 -0
- package/dist/closeout.d.ts.map +1 -0
- package/dist/closeout.js +422 -0
- package/dist/closeout.js.map +1 -0
- package/dist/index.d.ts +399 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +887 -13
- package/dist/index.js.map +1 -1
- package/manifest.json +2 -2
- package/package.json +4 -3
package/dist/closeout.js
ADDED
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
/** Close delivered tracker items using merged pull requests and head-check evidence. */
|
|
2
|
+
import { close, listAllComplete, certifyCompleteListResult, PmCliError } from "@unbrained/pm-cli/sdk";
|
|
3
|
+
/** Reject non-object API payloads before reading safety-critical fields. */
|
|
4
|
+
function record(value) {
|
|
5
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
6
|
+
throw new Error("Invalid GitHub evidence object.");
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
/** Require nonempty API strings without coercing arbitrary values. */
|
|
10
|
+
function text(value) {
|
|
11
|
+
if (typeof value !== "string" || value.length === 0)
|
|
12
|
+
throw new Error("Missing GitHub evidence field.");
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
/** Accept ISO dates or timestamps with a timezone, rejecting rolled calendar dates. */
|
|
16
|
+
function isoDate(value) {
|
|
17
|
+
if (!/^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2}))?$/.test(value)
|
|
18
|
+
|| !Number.isFinite(Date.parse(value))
|
|
19
|
+
|| new Date(`${value.slice(0, 10)}T00:00:00Z`).toISOString().slice(0, 10) !== value.slice(0, 10)) {
|
|
20
|
+
throw new Error("--since and merge times must be valid ISO dates or timestamps with a timezone.");
|
|
21
|
+
}
|
|
22
|
+
return new Date(value).toISOString();
|
|
23
|
+
}
|
|
24
|
+
/** Normalize repeatable flags without silently dropping malformed members. */
|
|
25
|
+
function repeated(options, key) {
|
|
26
|
+
if (options[key] === undefined)
|
|
27
|
+
return [];
|
|
28
|
+
const values = Array.isArray(options[key]) ? options[key] : [options[key]];
|
|
29
|
+
if (values.length === 0 || values.some(value => typeof value !== "string" || value.trim() === ""))
|
|
30
|
+
throw new Error(`--${key} requires a value.`);
|
|
31
|
+
return [...new Set(values.map(value => value.trim()))];
|
|
32
|
+
}
|
|
33
|
+
/** Read one payload with the shared authenticated retry/redirect transport. */
|
|
34
|
+
async function payload(api, endpoint) {
|
|
35
|
+
return JSON.parse((await api.get(`${api.base}${endpoint}`)).body);
|
|
36
|
+
}
|
|
37
|
+
/** Drain same-endpoint pagination; reject cycles, foreign links and truncated totals. */
|
|
38
|
+
async function pages(api, endpoint, checks = false, done) {
|
|
39
|
+
let next = `${api.base}${endpoint}`;
|
|
40
|
+
const initial = new URL(next);
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
const rows = [];
|
|
43
|
+
let total;
|
|
44
|
+
while (next) {
|
|
45
|
+
const url = new URL(next);
|
|
46
|
+
if (url.origin !== initial.origin || url.pathname !== initial.pathname || seen.has(next))
|
|
47
|
+
throw new Error("Unverifiable GitHub pagination.");
|
|
48
|
+
seen.add(next);
|
|
49
|
+
const response = await api.get(next);
|
|
50
|
+
const value = JSON.parse(response.body);
|
|
51
|
+
let page = value;
|
|
52
|
+
if (checks) {
|
|
53
|
+
const envelope = record(value);
|
|
54
|
+
if (!Number.isSafeInteger(envelope.total_count) || Number(envelope.total_count) < 0)
|
|
55
|
+
throw new Error("Missing check-run count.");
|
|
56
|
+
if (total !== undefined && total !== envelope.total_count)
|
|
57
|
+
throw new Error("Check-run count changed during pagination.");
|
|
58
|
+
total = Number(envelope.total_count);
|
|
59
|
+
page = envelope.check_runs;
|
|
60
|
+
}
|
|
61
|
+
if (!Array.isArray(page))
|
|
62
|
+
throw new Error("Incomplete GitHub evidence page.");
|
|
63
|
+
rows.push(...page);
|
|
64
|
+
// A caller-proven ordered listing can stop once a page reaches rows that can no longer match.
|
|
65
|
+
next = done !== undefined && page.some(done) ? undefined : api.next(response.linkHeader);
|
|
66
|
+
}
|
|
67
|
+
if (total !== undefined && rows.length !== total)
|
|
68
|
+
throw new Error("Incomplete check-run evidence.");
|
|
69
|
+
return rows;
|
|
70
|
+
}
|
|
71
|
+
/** Decode the base-repository identity and retain only selected PR evidence. */
|
|
72
|
+
function pullRequest(value, repo, number) {
|
|
73
|
+
const raw = record(value);
|
|
74
|
+
const base = record(raw.base);
|
|
75
|
+
const baseRepo = record(base.repo);
|
|
76
|
+
const head = record(raw.head);
|
|
77
|
+
if (raw.number !== number || text(baseRepo.full_name).toLowerCase() !== repo.toLowerCase()
|
|
78
|
+
|| text(raw.html_url).toLowerCase() !== `https://github.com/${repo}/pull/${number}`.toLowerCase()
|
|
79
|
+
|| (raw.body !== null && typeof raw.body !== "string"))
|
|
80
|
+
throw new Error("Pull-request identity or body is unverifiable.");
|
|
81
|
+
return {
|
|
82
|
+
number, body: raw.body, merged: raw.merged === true,
|
|
83
|
+
merged_at: raw.merged_at, merge_commit_sha: raw.merge_commit_sha,
|
|
84
|
+
html_url: raw.html_url, head: { sha: text(head.sha) },
|
|
85
|
+
base: { ref: text(base.ref), repo: { full_name: baseRepo.full_name } },
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Require complete, well-formed merge facts before any check queries or writes. */
|
|
89
|
+
function mergeEvidence(pr) {
|
|
90
|
+
return pr.merged && typeof pr.merged_at === "string" && isoDate(pr.merged_at).length > 0
|
|
91
|
+
&& typeof pr.merge_commit_sha === "string" && /^[a-f0-9]{40}$/.test(pr.merge_commit_sha)
|
|
92
|
+
&& /^[a-f0-9]{40}$/.test(pr.head.sha);
|
|
93
|
+
}
|
|
94
|
+
/** Treat only permission and not-found responses as protection metadata gaps. */
|
|
95
|
+
async function readProtectionSource(read) {
|
|
96
|
+
try {
|
|
97
|
+
return await read();
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
if (error instanceof Error && /HTTP (403|404)$/.test(error.message))
|
|
101
|
+
return null;
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** Combine all readable app-bound contexts without discarding known requirements. */
|
|
106
|
+
async function requirements(api, repo, branch) {
|
|
107
|
+
const classic = await readProtectionSource(async () => record(await payload(api, `/repos/${repo}/branches/${encodeURIComponent(branch)}/protection/required_status_checks`)));
|
|
108
|
+
const rules = await readProtectionSource(() => pages(api, `/repos/${repo}/rules/branches/${encodeURIComponent(branch)}?per_page=100`));
|
|
109
|
+
const checks = [];
|
|
110
|
+
if (classic !== null) {
|
|
111
|
+
if (!Array.isArray(classic.contexts) || !Array.isArray(classic.checks))
|
|
112
|
+
throw new Error("Missing required-check definitions.");
|
|
113
|
+
checks.push(...classic.checks.map(value => {
|
|
114
|
+
const check = record(value);
|
|
115
|
+
const app = check.app_id;
|
|
116
|
+
if (app !== null && app !== undefined && (!Number.isSafeInteger(app) || Number(app) < -1))
|
|
117
|
+
throw new Error("Invalid required-check app.");
|
|
118
|
+
return { name: text(check.context), app: typeof app === "number" && app >= 0 ? app : null };
|
|
119
|
+
}));
|
|
120
|
+
for (const context of classic.contexts) {
|
|
121
|
+
const name = text(context);
|
|
122
|
+
if (!checks.some(check => check.name === name))
|
|
123
|
+
checks.push({ name, app: null });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
for (const value of rules ?? []) {
|
|
127
|
+
const rule = record(value);
|
|
128
|
+
if (rule.type !== "required_status_checks")
|
|
129
|
+
continue;
|
|
130
|
+
const parameters = record(rule.parameters);
|
|
131
|
+
if (!Array.isArray(parameters.required_status_checks))
|
|
132
|
+
throw new Error("Missing ruleset checks.");
|
|
133
|
+
for (const value of parameters.required_status_checks) {
|
|
134
|
+
const check = record(value);
|
|
135
|
+
const app = check.integration_id;
|
|
136
|
+
if (app !== null && app !== undefined && (!Number.isSafeInteger(app) || Number(app) < 0))
|
|
137
|
+
throw new Error("Invalid ruleset app.");
|
|
138
|
+
checks.push({ name: text(check.context), app: typeof app === "number" ? app : null });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return { checks, fallback: classic === null || rules === null || checks.length === 0 };
|
|
142
|
+
}
|
|
143
|
+
/** Verify required checks or the explicitly reported conservative fallback at the PR head. */
|
|
144
|
+
export async function checkCloseoutHead(api, repo, pr) {
|
|
145
|
+
const result = { pr: pr.number, rule: "unavailable", reason: "Head check evidence unavailable or incomplete.", passed: [], ok: false };
|
|
146
|
+
try {
|
|
147
|
+
const policy = await requirements(api, repo, pr.base.ref);
|
|
148
|
+
result.rule = policy.fallback ? "fallback" : "required";
|
|
149
|
+
const runs = (await pages(api, `/repos/${repo}/commits/${pr.head.sha}/check-runs?filter=latest&per_page=100`, true)).map(value => {
|
|
150
|
+
const run = record(value);
|
|
151
|
+
const app = record(run.app);
|
|
152
|
+
if (run.head_sha !== pr.head.sha || !Number.isSafeInteger(app.id)
|
|
153
|
+
|| (run.conclusion !== null && typeof run.conclusion !== "string"))
|
|
154
|
+
throw new Error("Invalid head check run.");
|
|
155
|
+
return { name: text(run.name), head_sha: run.head_sha, status: text(run.status), conclusion: run.conclusion, app: { id: Number(app.id) } };
|
|
156
|
+
});
|
|
157
|
+
const statuses = new Map();
|
|
158
|
+
for (const value of await pages(api, `/repos/${repo}/commits/${pr.head.sha}/statuses?per_page=100`)) {
|
|
159
|
+
const status = record(value);
|
|
160
|
+
const context = text(status.context);
|
|
161
|
+
if (!statuses.has(context))
|
|
162
|
+
statuses.set(context, { context, state: text(status.state) });
|
|
163
|
+
}
|
|
164
|
+
for (const check of policy.checks) {
|
|
165
|
+
const matching = runs.filter(run => run.name === check.name && (check.app === null || run.app.id === check.app));
|
|
166
|
+
const legacy = statuses.get(check.name);
|
|
167
|
+
if (matching.length === 0 && (!legacy || check.app !== null)) {
|
|
168
|
+
result.reason = `Required check missing at head: ${check.name}`;
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
if (matching.some(run => run.status !== "completed" || run.conclusion !== "success") || (legacy && legacy.state !== "success")) {
|
|
172
|
+
result.reason = `Required check did not conclude success at head: ${check.name}`;
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (!policy.fallback) {
|
|
177
|
+
result.reason = "Required head checks concluded success (branch-protection and ruleset rule).";
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
if (runs.length === 0) {
|
|
181
|
+
result.reason = "Fallback rule: no check runs at head; evidence missing.";
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
if (runs.some(run => run.status !== "completed" || !["success", "neutral", "skipped"].includes(String(run.conclusion)))
|
|
185
|
+
|| [...statuses.values()].some(status => status.state !== "success")) {
|
|
186
|
+
result.reason = "Fallback rule: every head run must be completed with success, neutral or skipped, and head statuses must succeed.";
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
result.reason = "Fallback rule: readable required checks succeeded; protection unavailable or no required contexts; every head run completed with success, neutral or skipped; head statuses succeeded.";
|
|
190
|
+
}
|
|
191
|
+
result.passed = [...new Set([...runs.filter(run => run.status === "completed" && run.conclusion === "success").map(run => run.name),
|
|
192
|
+
...[...statuses.values()].filter(status => status.state === "success").map(status => status.context)])].sort();
|
|
193
|
+
result.ok = true;
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// Never echo an API body, exception payload, PR body or comment into the report.
|
|
197
|
+
}
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
/** Statuses that already ended an item's lifecycle. */
|
|
201
|
+
const TERMINAL_STATUSES = ["closed", "canceled"];
|
|
202
|
+
/** GitHub-style closing keywords that declare delivery of the link they directly precede. */
|
|
203
|
+
const CLOSING_KEYWORDS = new Set(["close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved", "deliver", "delivers", "delivered"]);
|
|
204
|
+
/**
|
|
205
|
+
* Whether a closing keyword directly precedes a link, given the line text before the link.
|
|
206
|
+
*
|
|
207
|
+
* Only earlier links (markdown or bare), commas and "and" may sit between the keyword and the link, so
|
|
208
|
+
* `Delivers [a](…) and [b](…)` declares both while `Not fixed here; see <link>` declares nothing.
|
|
209
|
+
* Scans backwards with plain string operations; no backtracking pattern touches PR text.
|
|
210
|
+
*/
|
|
211
|
+
export function declaresDelivery(prefix) {
|
|
212
|
+
let rest = prefix;
|
|
213
|
+
// The link may be the target of a markdown label: `Closes [pm-x](`.
|
|
214
|
+
if (rest.endsWith("]("))
|
|
215
|
+
rest = rest.slice(0, Math.max(0, rest.lastIndexOf("[")));
|
|
216
|
+
for (;;) {
|
|
217
|
+
rest = rest.trimEnd();
|
|
218
|
+
if (rest.endsWith(",")) {
|
|
219
|
+
rest = rest.slice(0, -1);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
if (rest.endsWith(")")) {
|
|
223
|
+
// Skip one earlier markdown link `[label](url)`; any other parenthetical ends the scan.
|
|
224
|
+
const target = rest.lastIndexOf("](");
|
|
225
|
+
const label = target < 0 ? -1 : rest.lastIndexOf("[", target);
|
|
226
|
+
if (label < 0 || /\s/.test(rest.slice(target + 2, -1)))
|
|
227
|
+
return false;
|
|
228
|
+
rest = rest.slice(0, label);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
const cut = Math.max(rest.lastIndexOf(" "), rest.lastIndexOf("\t")) + 1;
|
|
232
|
+
const word = rest.slice(cut);
|
|
233
|
+
if (word.toLowerCase() === "and" || word.startsWith("https://")) {
|
|
234
|
+
rest = rest.slice(0, cut);
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
let bare = word;
|
|
238
|
+
while (bare.endsWith(":") || bare.endsWith("*") || bare.endsWith("_"))
|
|
239
|
+
bare = bare.slice(0, -1);
|
|
240
|
+
while (bare.startsWith("*") || bare.startsWith("_"))
|
|
241
|
+
bare = bare.slice(1);
|
|
242
|
+
return CLOSING_KEYWORDS.has(bare.toLowerCase());
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/** Extract only canonical tracker links, retaining foreign references solely for skip rows. */
|
|
246
|
+
export function extractCloseoutItems(body) {
|
|
247
|
+
const links = body.matchAll(/https:\/\/github\.com\/([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)\/blob\/main\/\.agents\/pm\/((?:[^/\s?#<>)\]"']+\/)+)([^/\s?#<>)\]"']+)\.toon(?=$|[\s?#<>)\]"'])/g);
|
|
248
|
+
const seen = new Set();
|
|
249
|
+
const refs = [];
|
|
250
|
+
return [...links].flatMap(match => {
|
|
251
|
+
let components;
|
|
252
|
+
try {
|
|
253
|
+
components = [...match[2].slice(0, -1).split("/"), match[3]].map(decodeURIComponent);
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return [];
|
|
257
|
+
}
|
|
258
|
+
if (components.some(component => /^\.{1,2}$|[/\\\0]/.test(component)))
|
|
259
|
+
return [];
|
|
260
|
+
const item = components.at(-1);
|
|
261
|
+
const key = `${match[1].toLowerCase()}/${item}`;
|
|
262
|
+
const declared = declaresDelivery(body.slice(body.lastIndexOf("\n", match.index) + 1, match.index));
|
|
263
|
+
if (seen.has(key)) {
|
|
264
|
+
// A later "Closes <link>" line still declares an item an earlier line only mentioned.
|
|
265
|
+
if (declared)
|
|
266
|
+
for (const entry of refs)
|
|
267
|
+
if (entry.key === key)
|
|
268
|
+
entry.declared = true;
|
|
269
|
+
return [];
|
|
270
|
+
}
|
|
271
|
+
seen.add(key);
|
|
272
|
+
const entry = { key, repo: match[1], item, declared };
|
|
273
|
+
refs.push(entry);
|
|
274
|
+
return [entry];
|
|
275
|
+
}).map(({ repo, item, declared }) => ({ repo, item, declared }));
|
|
276
|
+
}
|
|
277
|
+
/** Render only the allowed GitHub facts; never include body, title or comment text. */
|
|
278
|
+
function closeReason(pr, passed) {
|
|
279
|
+
return JSON.stringify({ pr: pr.number, url: pr.html_url, merge_commit_sha: pr.merge_commit_sha,
|
|
280
|
+
head_sha: pr.head.sha, merged_at: pr.merged_at, checks: passed });
|
|
281
|
+
}
|
|
282
|
+
/** Report SDK refusal codes without exposing paths, identities or arbitrary error prose. */
|
|
283
|
+
export function closeoutFailureReason(error) {
|
|
284
|
+
if (error instanceof PmCliError) {
|
|
285
|
+
const code = error.code;
|
|
286
|
+
if (typeof code === "string" && /^[a-z][a-z0-9_]{0,79}$/.test(code))
|
|
287
|
+
return `SDK close refused: ${code}.`;
|
|
288
|
+
return `SDK close refused (exit ${error.exitCode}).`;
|
|
289
|
+
}
|
|
290
|
+
return "SDK close failed (unclassified error).";
|
|
291
|
+
}
|
|
292
|
+
/** Invalid selectors or repository input: the caller must change the command, so the host maps it to a usage exit. */
|
|
293
|
+
export class CloseoutUsageError extends Error {
|
|
294
|
+
}
|
|
295
|
+
/** Re-throw a selector parser's failure as a usage error. */
|
|
296
|
+
function usage(parse) {
|
|
297
|
+
try {
|
|
298
|
+
return parse();
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
throw new CloseoutUsageError(error.message);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Describe the verified check evidence for a passed gate without overstating it.
|
|
306
|
+
*
|
|
307
|
+
* The required rule states that the required checks were satisfied and lists every successful head check (optional
|
|
308
|
+
* ones included). The fallback rule (no readable required contexts)
|
|
309
|
+
* may pass on neutral or skipped runs alone, so it states that policy and lists successful checks only when any exist.
|
|
310
|
+
*/
|
|
311
|
+
export function checkEvidence(gate) {
|
|
312
|
+
// gate.passed holds every successful head check, optional ones included, so it is never labelled as the required set.
|
|
313
|
+
if (gate.rule === "required")
|
|
314
|
+
return `required checks satisfied; successful head checks: ${gate.passed.join(", ")}`;
|
|
315
|
+
const successes = gate.passed.length > 0 ? `successful checks: ${gate.passed.join(", ")}` : "no check reported success";
|
|
316
|
+
return `no readable required checks, so every completed head check run had to succeed, be neutral or be skipped; ${successes}`;
|
|
317
|
+
}
|
|
318
|
+
/** Plan all selected PRs before closing eligible items through the real SDK. */
|
|
319
|
+
export async function runCloseout(pmRoot, repo, options, api) {
|
|
320
|
+
if (!repo || !/^(?!\.{1,2}\/)[A-Za-z0-9_.-]+\/(?!\.{1,2}$)[A-Za-z0-9_.-]+$/.test(repo))
|
|
321
|
+
throw new CloseoutUsageError("closeout requires --repo owner/repo or PM_GITHUB_REPO.");
|
|
322
|
+
const numbers = usage(() => repeated(options, "pr")).map(value => {
|
|
323
|
+
if (!/^[1-9]\d*$/.test(value) || !Number.isSafeInteger(Number(value)))
|
|
324
|
+
throw new CloseoutUsageError("--pr requires positive pull-request numbers.");
|
|
325
|
+
return Number(value);
|
|
326
|
+
});
|
|
327
|
+
const since = options.since === undefined ? undefined : usage(() => isoDate(text(options.since)));
|
|
328
|
+
if ((numbers.length === 0) === (since === undefined))
|
|
329
|
+
throw new CloseoutUsageError("Select either repeatable --pr <n> or --since <ISO date>.");
|
|
330
|
+
const skip = new Set(usage(() => repeated(options, "skip")));
|
|
331
|
+
const apply = options.apply === true && options["dry-run"] !== true && options.dryRun !== true;
|
|
332
|
+
if (since !== undefined) {
|
|
333
|
+
// Rows arrive newest-updated first and a merge never postdates its PR's update, so a row updated
|
|
334
|
+
// before the cutoff proves no later row can have merged at or after it.
|
|
335
|
+
const cutoff = Date.parse(since);
|
|
336
|
+
const older = (row) => typeof row === "object" && row !== null && Date.parse(String(row.updated_at)) < cutoff;
|
|
337
|
+
for (const value of await pages(api, `/repos/${repo}/pulls?state=closed&sort=updated&direction=desc&per_page=100`, false, older)) {
|
|
338
|
+
const pr = record(value);
|
|
339
|
+
if (pr.merged_at !== null && Date.parse(isoDate(text(pr.merged_at))) >= Date.parse(since)) {
|
|
340
|
+
if (!Number.isSafeInteger(pr.number) || Number(pr.number) < 1)
|
|
341
|
+
throw new Error("Invalid selected pull-request number.");
|
|
342
|
+
numbers.push(Number(pr.number));
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
const corpus = certifyCompleteListResult(await listAllComplete({}, { pmRoot, noExtensions: true }));
|
|
347
|
+
const items = new Map(corpus.items.map(item => [item.id, item]));
|
|
348
|
+
// Containers close when their children are done, never because a pull request mentions them.
|
|
349
|
+
const activeChildren = new Map();
|
|
350
|
+
for (const item of corpus.items) {
|
|
351
|
+
const parent = item.parent;
|
|
352
|
+
if (typeof parent === "string" && !TERMINAL_STATUSES.includes(item.status))
|
|
353
|
+
activeChildren.set(parent, (activeChildren.get(parent) ?? 0) + 1);
|
|
354
|
+
}
|
|
355
|
+
const selected = new Set();
|
|
356
|
+
const plan = [];
|
|
357
|
+
const checks = [];
|
|
358
|
+
const closures = [];
|
|
359
|
+
for (const number of [...new Set(numbers)].sort((a, b) => a - b)) {
|
|
360
|
+
const pr = pullRequest(await payload(api, `/repos/${repo}/pulls/${number}`), repo, number);
|
|
361
|
+
let gate = { pr: number, rule: "unavailable", ok: false, passed: [], reason: "Pull request is not merged or merge evidence is incomplete." };
|
|
362
|
+
if (mergeEvidence(pr))
|
|
363
|
+
gate = await checkCloseoutHead(api, repo, pr);
|
|
364
|
+
checks.push(gate);
|
|
365
|
+
for (const ref of extractCloseoutItems(pr.body ?? "")) {
|
|
366
|
+
let reason;
|
|
367
|
+
if (ref.repo.toLowerCase() !== repo.toLowerCase())
|
|
368
|
+
reason = "Link points to another repository.";
|
|
369
|
+
else if (!items.has(ref.item))
|
|
370
|
+
reason = "Item does not exist in the tracker.";
|
|
371
|
+
else if (skip.has(ref.item))
|
|
372
|
+
reason = "Explicitly excluded by --skip.";
|
|
373
|
+
else if (TERMINAL_STATUSES.includes(items.get(ref.item).status))
|
|
374
|
+
reason = "Item is already closed or canceled.";
|
|
375
|
+
else if (!gate.ok)
|
|
376
|
+
reason = gate.reason;
|
|
377
|
+
else if (items.get(ref.item).type === "Epic")
|
|
378
|
+
reason = "Epics close when their children are done, not by a pull request.";
|
|
379
|
+
else if (activeChildren.has(ref.item))
|
|
380
|
+
reason = `Item has ${activeChildren.get(ref.item)} non-terminal child item(s).`;
|
|
381
|
+
else if (items.get(ref.item).status !== "in_progress" && !ref.declared) {
|
|
382
|
+
reason = `Item is ${items.get(ref.item).status}, not in progress; a mention is not delivery. Prefix its link with Closes, Fixes, Resolves or Delivers to close it.`;
|
|
383
|
+
}
|
|
384
|
+
else if (selected.has(ref.item))
|
|
385
|
+
reason = "Item already selected by another pull request.";
|
|
386
|
+
else {
|
|
387
|
+
reason = gate.reason;
|
|
388
|
+
selected.add(ref.item);
|
|
389
|
+
const row = { item: ref.item, pr: number, action: "close", reason };
|
|
390
|
+
const criteria = items.get(ref.item).acceptance_criteria;
|
|
391
|
+
closures.push({ row, reason: closeReason(pr, gate.passed), at: pr.merged_at,
|
|
392
|
+
resolution: `Delivered by ${pr.html_url} (merge ${pr.merge_commit_sha.slice(0, 12)}, head ${pr.head.sha.slice(0, 12)})`,
|
|
393
|
+
expectedResult: typeof criteria === "string" && criteria.trim().length > 0 ? criteria
|
|
394
|
+
: "Delivered by the linked pull request, merged after its head check gate passed.",
|
|
395
|
+
actualResult: `Merged at ${pr.merged_at}; ${checkEvidence(gate)}`,
|
|
396
|
+
});
|
|
397
|
+
plan.push(row);
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
plan.push({ item: ref.item, pr: number, action: "skip", reason });
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
let closed = 0;
|
|
404
|
+
let failed = 0;
|
|
405
|
+
if (apply) {
|
|
406
|
+
for (const entry of closures) {
|
|
407
|
+
try {
|
|
408
|
+
await close(entry.row.item, entry.reason, { author: "pm-github", completedAt: entry.at,
|
|
409
|
+
resolution: entry.resolution, expectedResult: entry.expectedResult, actualResult: entry.actualResult,
|
|
410
|
+
}, { pmRoot, noExtensions: true });
|
|
411
|
+
closed++;
|
|
412
|
+
}
|
|
413
|
+
catch (error) {
|
|
414
|
+
failed++;
|
|
415
|
+
entry.row.action = "skip";
|
|
416
|
+
entry.row.reason = closeoutFailureReason(error);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return { command: "github closeout", repo, dry_run: !apply, plan, checks, closed, failed };
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=closeout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"closeout.js","sourceRoot":"","sources":["../closeout.ts"],"names":[],"mappings":"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"}
|