@feigi/fleet-ctl 3.82.20 → 3.82.21
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/package.json
CHANGED
|
@@ -20,7 +20,12 @@
|
|
|
20
20
|
// lack a member row (nothing from that run was checked). `--live`
|
|
21
21
|
// (a run in progress; CI never passes it) adds a WARNING, never a
|
|
22
22
|
// failure, per PR whose run-ledger row carries `reviewed=` but which has
|
|
23
|
-
// no row here
|
|
23
|
+
// no row here, except a PR that closes no issue: `append` keys a row on
|
|
24
|
+
// exactly one ticket and refuses it, so it is named in a `note` line and
|
|
25
|
+
// never warned about. A read of that PR that does not answer keeps the
|
|
26
|
+
// warning, after a line naming why the read failed. Both reads of a PR's
|
|
27
|
+
// closing references ignore an ambient GH_REPO and give `gh` 60s.
|
|
28
|
+
// `--ledger <path>` names another ledger than the run's own.
|
|
24
29
|
//
|
|
25
30
|
// `tier` resolution, in order (never tie-broken by `run_date`: the two files'
|
|
26
31
|
// `run_date`s mean different things — this file's header measures 92 of 267
|
|
@@ -445,20 +450,37 @@ function readLedger(ledgerFile, requireFile) {
|
|
|
445
450
|
}
|
|
446
451
|
}
|
|
447
452
|
|
|
448
|
-
|
|
453
|
+
// A PR's closingIssuesReferences array, or an Error naming why it could not be
|
|
454
|
+
// read. GH_REPO is blanked so an ambient one naming another repository never
|
|
455
|
+
// decides which PR is read; the timeout keeps a hung `gh` from stalling
|
|
456
|
+
// `append` or a close-out's `check --live`.
|
|
457
|
+
const GH_TIMEOUT_MS = 60_000;
|
|
458
|
+
function closingRefs(pr) {
|
|
449
459
|
let raw;
|
|
450
460
|
try {
|
|
451
|
-
raw = execFileSync("gh", ["pr", "view", pr, "--json", "closingIssuesReferences"], {
|
|
461
|
+
raw = execFileSync("gh", ["pr", "view", String(pr), "--json", "closingIssuesReferences"], {
|
|
462
|
+
encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, GH_REPO: "" }, timeout: GH_TIMEOUT_MS,
|
|
463
|
+
});
|
|
452
464
|
} catch (e) {
|
|
453
|
-
|
|
465
|
+
throw new Error(`gh pr view ${pr} failed: ${e.stderr?.trim() || e.message}`);
|
|
454
466
|
}
|
|
455
467
|
let refs;
|
|
456
468
|
try {
|
|
457
469
|
refs = JSON.parse(raw).closingIssuesReferences;
|
|
458
470
|
} catch (e) {
|
|
459
|
-
|
|
471
|
+
throw new Error(`gh pr view ${pr} returned unreadable JSON: ${e.message}`);
|
|
472
|
+
}
|
|
473
|
+
if (!Array.isArray(refs)) throw new Error(`gh pr view ${pr} returned no closingIssuesReferences array`);
|
|
474
|
+
return refs;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function closingTicket(pr) {
|
|
478
|
+
let refs;
|
|
479
|
+
try {
|
|
480
|
+
refs = closingRefs(pr);
|
|
481
|
+
} catch (e) {
|
|
482
|
+
die(e.message);
|
|
460
483
|
}
|
|
461
|
-
if (!Array.isArray(refs)) die(`gh pr view ${pr} returned no closingIssuesReferences array`);
|
|
462
484
|
const numbers = [...new Set(refs.map((r) => r?.number))];
|
|
463
485
|
if (numbers.length !== 1 || !Number.isInteger(numbers[0])) {
|
|
464
486
|
die(`PR #${pr} closes ${numbers.length === 0 ? "no issue" : `${numbers.length} issues (${numbers.map((n) => `#${n}`).join(", ")})`} per GitHub's closingIssuesReferences — a tier-outcomes row keys on exactly one ticket`);
|
|
@@ -534,6 +556,20 @@ function append(pr, paths) {
|
|
|
534
556
|
console.log(line);
|
|
535
557
|
}
|
|
536
558
|
|
|
559
|
+
// True only when `gh` answered and the PR's closingIssuesReferences is an empty
|
|
560
|
+
// array. Any other outcome (gh failing, unreadable JSON, a non-array) is false
|
|
561
|
+
// after a line naming why: a PR whose closing references cannot be read keeps
|
|
562
|
+
// its warning. That line never reads `WARNING PR #`, which closeout.mjs turns
|
|
563
|
+
// into a NEED.
|
|
564
|
+
function closesNoIssue(pr) {
|
|
565
|
+
try {
|
|
566
|
+
return closingRefs(pr).length === 0;
|
|
567
|
+
} catch (e) {
|
|
568
|
+
console.error(`${NAME}: could not read the closing references of PR #${pr}: ${e.message}`);
|
|
569
|
+
return false;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
537
573
|
function check(paths) {
|
|
538
574
|
for (const flag of Object.keys(APPEND_FLAGS)) {
|
|
539
575
|
if (arg(flag) !== null) die(`--${flag} is an append flag`);
|
|
@@ -546,6 +582,10 @@ function check(paths) {
|
|
|
546
582
|
if (has("live")) {
|
|
547
583
|
const ledger = readLedger(paths.ledger, true);
|
|
548
584
|
for (const pr of unrecordedReviewedPrs(ledger, rows)) {
|
|
585
|
+
if (closesNoIssue(pr)) {
|
|
586
|
+
console.error(`${NAME}: note PR #${pr} carries reviewed= on the ledger and closes no issue, so it takes no row in ${paths.file}`);
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
549
589
|
console.error(`${NAME}: WARNING PR #${pr} carries reviewed= on the ledger but has no row in ${paths.file} — run \`tier-outcomes.mjs append ${pr}\` if it is an implementer PR`);
|
|
550
590
|
}
|
|
551
591
|
}
|
package/skills/run-team/SKILL.md
CHANGED
|
@@ -211,6 +211,7 @@ owes beyond its call:
|
|
|
211
211
|
a recorded stop as the end of the run. A `NEED tier-outcomes append
|
|
212
212
|
<pr>` is a PR the ledger marks reviewed with no verdict row: append it with
|
|
213
213
|
the verdict you rule (**Guard: accumulate per PR**) and run `finish` again.
|
|
214
|
+
A reviewed PR that closes no issue takes no row and is never a NEED.
|
|
214
215
|
A step it fails is explained in references/close-out.md. Exit 0 is the run
|
|
215
216
|
closed.
|
|
216
217
|
Drain only when a documented trigger fired, and name the trigger in `--reason`.
|
|
@@ -24,8 +24,10 @@
|
|
|
24
24
|
`fleet-heartbeat.mjs --stop` last, because every reader takes a recorded
|
|
25
25
|
stop as the end of the run. A `NEED tier-outcomes append <pr>` is a PR
|
|
26
26
|
the ledger marks reviewed with no verdict row: append it with the verdict
|
|
27
|
-
you rule (**Guard: accumulate per PR**) and run `finish` again. A
|
|
28
|
-
|
|
27
|
+
you rule (**Guard: accumulate per PR**) and run `finish` again. A reviewed
|
|
28
|
+
PR that closes no issue, a `Refs`-only step for instance, takes no row: the
|
|
29
|
+
check names it in a `note` line and never asks for one. A step it fails is
|
|
30
|
+
explained in references/close-out.md. Exit 0 is the run closed.
|
|
29
31
|
Drain only when a documented trigger fired, and name the trigger in `--reason`.
|
|
30
32
|
**Undrain** only when the maintainer asks, never a drain that budget or
|
|
31
33
|
context exhaustion caused (references/close-out.md).
|
|
@@ -83,7 +85,10 @@ and none could be compared, so nothing from that run was checked: append the
|
|
|
83
85
|
run's member rows if they are missing, or blank each named row's `tier` and say
|
|
84
86
|
why in `note`.
|
|
85
87
|
Each WARNING names a PR this run's ledger marks `reviewed=` that has no row yet
|
|
86
|
-
— append it before committing if it is an implementer PR.
|
|
88
|
+
— append it before committing if it is an implementer PR. A reviewed PR that
|
|
89
|
+
closes no issue is named in a `note` line instead: it takes no row. A line
|
|
90
|
+
saying the PR's closing references could not be read comes before that PR's
|
|
91
|
+
WARNING and says why.
|
|
87
92
|
|
|
88
93
|
## Drain the pending ticket-features rows and refresh the cost guard
|
|
89
94
|
|