@mutmutco/cli 4.5.135 → 4.5.136
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/dist/main.cjs +163 -17
- package/dist/runbook-sweep.cjs +3 -0
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -17509,6 +17509,7 @@ function assertGitBashOnWindowsForJervHubRelease(repo, platform2 = process.platf
|
|
|
17509
17509
|
|
|
17510
17510
|
// src/train-apply-correlation.ts
|
|
17511
17511
|
var import_node_fs19 = require("node:fs");
|
|
17512
|
+
init_github_quota();
|
|
17512
17513
|
var import_node_path17 = require("node:path");
|
|
17513
17514
|
|
|
17514
17515
|
// src/fleet-lockstep-enforce.ts
|
|
@@ -18274,10 +18275,10 @@ var rollout_plan_default = {
|
|
|
18274
18275
|
note: "The v4.0.0 stamp happens at cut time (D6e #4463); until then the candidate is the origin/development head artifacts (built cli/dist + npm pack), identity proven by dist content hash (D6a)."
|
|
18275
18276
|
},
|
|
18276
18277
|
baseline: {
|
|
18277
|
-
version: "4.5.
|
|
18278
|
-
tag: "v4.5.
|
|
18279
|
-
commit: "
|
|
18280
|
-
npm: "@mutmutco/cli@4.5.
|
|
18278
|
+
version: "4.5.136",
|
|
18279
|
+
tag: "v4.5.136",
|
|
18280
|
+
commit: "642526387569",
|
|
18281
|
+
npm: "@mutmutco/cli@4.5.136"
|
|
18281
18282
|
},
|
|
18282
18283
|
exitCriterion: "fleet-n-of-n",
|
|
18283
18284
|
hubOnlyShortcut: "forbidden",
|
|
@@ -18294,14 +18295,14 @@ var rollout_plan_default = {
|
|
|
18294
18295
|
repo: "mutmutco/mmi-hub",
|
|
18295
18296
|
role: "canary",
|
|
18296
18297
|
schedule: "train",
|
|
18297
|
-
v3Target: "v4.5.
|
|
18298
|
+
v3Target: "v4.5.136"
|
|
18298
18299
|
}
|
|
18299
18300
|
],
|
|
18300
18301
|
rollbackTrigger: "Any red inside the post-contract soak window: `devops train gate` FAIL attributable to the v4 doors, Hub endpoint health probe failure, a pre-v4 client admitted instead of receiving actionable HTTP 426, or npm consumer install/doctor failure on the v4-only dist.",
|
|
18301
18302
|
rollback: {
|
|
18302
18303
|
independent: true,
|
|
18303
|
-
mechanism: "npm dist-tag latest -> 4.5.
|
|
18304
|
-
v3Target: "v4.5.
|
|
18304
|
+
mechanism: "npm dist-tag latest -> 4.5.136 and redeploy the Hub Lambda from tag v4.5.136 (642526387569); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
18305
|
+
v3Target: "v4.5.136 (@mutmutco/cli@4.5.136, tag commit 642526387569 \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
18305
18306
|
}
|
|
18306
18307
|
},
|
|
18307
18308
|
{
|
|
@@ -20419,11 +20420,22 @@ async function loadReleaseTrackBranchHints(deps) {
|
|
|
20419
20420
|
]);
|
|
20420
20421
|
return { hasDevelopmentBranch, hasMainBranch, hasRcBranch };
|
|
20421
20422
|
}
|
|
20423
|
+
async function readTrainLogin(deps, waitMs = 18e4, attempts = 5) {
|
|
20424
|
+
for (let i = 1; ; i++) {
|
|
20425
|
+
try {
|
|
20426
|
+
return requireValue(clean2(await deps.run("gh", ["api", "user", "--jq", ".login"])), "GitHub login");
|
|
20427
|
+
} catch (e) {
|
|
20428
|
+
if (i >= attempts || !isRateLimitText(e instanceof Error ? e.message : String(e))) throw e;
|
|
20429
|
+
deps.warn?.(`GitHub login read rate-limited; retrying in ${waitMs / 6e4} min (${i}/${attempts - 1})`);
|
|
20430
|
+
await resolveSleep(deps)(waitMs);
|
|
20431
|
+
}
|
|
20432
|
+
}
|
|
20433
|
+
}
|
|
20422
20434
|
async function buildTrainApplyContext(deps) {
|
|
20423
20435
|
const repo = requireValue(clean2(await deps.run("gh", ["repo", "view", "--json", "nameWithOwner", "--jq", ".nameWithOwner"])), "repo");
|
|
20424
20436
|
const [owner, name] = repo.split("/");
|
|
20425
20437
|
if (!owner || !name) throw new Error(`repo must be owner/name, got ${repo}`);
|
|
20426
|
-
const login =
|
|
20438
|
+
const login = await readTrainLogin(deps);
|
|
20427
20439
|
const verdict = await deps.trainAuthority(repo);
|
|
20428
20440
|
if (!verdict.ok) throw new Error(`${commandAuthorityLabel(owner)}: train authority could not be verified (${verdict.error})`);
|
|
20429
20441
|
if (!verdict.train) {
|
|
@@ -22443,7 +22455,7 @@ async function runTenantRedeploy(deps, options) {
|
|
|
22443
22455
|
const repo = options.repo;
|
|
22444
22456
|
const [owner, name] = repo.split("/");
|
|
22445
22457
|
if (!owner || !name) throw new Error(`repo must be owner/name, got ${repo}`);
|
|
22446
|
-
const login =
|
|
22458
|
+
const login = await readTrainLogin(deps);
|
|
22447
22459
|
const verdict = await deps.trainAuthority(repo);
|
|
22448
22460
|
if (!verdict.ok) throw new Error(`${commandAuthorityLabel(owner)}: train authority could not be verified (${verdict.error})`);
|
|
22449
22461
|
if (!verdict.train) throw new Error(`${commandAuthorityLabel(owner)}: @${login} is ${verdict.role} \u2014 no train authority on ${repo}`);
|
|
@@ -39845,6 +39857,7 @@ function boardAdvanceFailureMessage(result) {
|
|
|
39845
39857
|
}
|
|
39846
39858
|
|
|
39847
39859
|
// src/pr-land.ts
|
|
39860
|
+
var PR_LAND_QUEUE_TIMEOUT_MS = 45 * 6e4;
|
|
39848
39861
|
function prHeadBehindBase(input) {
|
|
39849
39862
|
if ((input.mergeStateStatus ?? "").toUpperCase() === "BEHIND") return true;
|
|
39850
39863
|
return /out[- ]of[- ]date|not up to date|up to date with the base|update (?:the|your) branch/i.test(input.message ?? "");
|
|
@@ -39968,6 +39981,17 @@ async function runPrLand(prNumber, options, deps) {
|
|
|
39968
39981
|
}
|
|
39969
39982
|
const ciPolicy = await deps.resolveCiPolicy(repo);
|
|
39970
39983
|
base.ciPolicy = ciPolicy;
|
|
39984
|
+
const hasQueue = await deps.hasMergeQueue?.(repo, resolved.base) ?? false;
|
|
39985
|
+
let queueSnapshot;
|
|
39986
|
+
if (hasQueue) {
|
|
39987
|
+
base.mergeQueue = { base: resolved.base, state: "queued" };
|
|
39988
|
+
if (!deps.readMergeQueue) throw new Error("merge queue reader unavailable");
|
|
39989
|
+
queueSnapshot = await deps.readMergeQueue(prNumber, repo);
|
|
39990
|
+
if (queueSnapshot.isInMergeQueue || queueSnapshot.state === "MERGED") {
|
|
39991
|
+
base.mergeStatus = "auto-merge-enqueued";
|
|
39992
|
+
return pollPrMergeQueue(prNumber, options, deps, base, queueSnapshot);
|
|
39993
|
+
}
|
|
39994
|
+
}
|
|
39971
39995
|
const checksWaitError = (checksWait) => {
|
|
39972
39996
|
if (checksWait.status === "conflicting") {
|
|
39973
39997
|
return `checks-wait conflicting: ${checksWait.reason ?? "PR is conflicting with the base branch"}`;
|
|
@@ -40003,6 +40027,14 @@ async function runPrLand(prNumber, options, deps) {
|
|
|
40003
40027
|
if (merge.mergeStatus === "failed") {
|
|
40004
40028
|
return { ...base, error: merge.error ?? "merge failed" };
|
|
40005
40029
|
}
|
|
40030
|
+
if (hasQueue) {
|
|
40031
|
+
if (merge.mergeStatus === "merged") {
|
|
40032
|
+
return queueMerged(base, deps);
|
|
40033
|
+
}
|
|
40034
|
+
const deadline = (deps.now ?? (() => Date.now()))() + PR_LAND_QUEUE_TIMEOUT_MS;
|
|
40035
|
+
await (deps.sleep ?? ((ms) => new Promise((resolve8) => setTimeout(resolve8, ms))))(PR_LAND_POLL_MS);
|
|
40036
|
+
return pollPrMergeQueue(prNumber, options, deps, base, void 0, deadline);
|
|
40037
|
+
}
|
|
40006
40038
|
if (merge.mergeStatus === "merged") {
|
|
40007
40039
|
return {
|
|
40008
40040
|
...base,
|
|
@@ -40025,6 +40057,53 @@ async function runPrLand(prNumber, options, deps) {
|
|
|
40025
40057
|
error: "auto-merge enqueued but PR did not reach MERGED within timeout \u2014 poll manually with gh pr view"
|
|
40026
40058
|
};
|
|
40027
40059
|
}
|
|
40060
|
+
function queueMerged(base, deps) {
|
|
40061
|
+
const result = {
|
|
40062
|
+
...base,
|
|
40063
|
+
status: "merged-via-queue",
|
|
40064
|
+
mergeStatus: "merged",
|
|
40065
|
+
mergeQueue: { ...base.mergeQueue, state: "merged" },
|
|
40066
|
+
branchFinality: prLandedBranchFinality(base.pr, base.base)
|
|
40067
|
+
};
|
|
40068
|
+
deps.queueProgress?.(result);
|
|
40069
|
+
return result;
|
|
40070
|
+
}
|
|
40071
|
+
async function pollPrMergeQueue(pr, options, deps, base, snapshot, deadlineMs) {
|
|
40072
|
+
const now = deps.now ?? (() => Date.now());
|
|
40073
|
+
const sleep2 = deps.sleep ?? ((ms) => new Promise((resolve8) => setTimeout(resolve8, ms)));
|
|
40074
|
+
const deadline = deadlineMs ?? now() + PR_LAND_QUEUE_TIMEOUT_MS;
|
|
40075
|
+
while (now() < deadline) {
|
|
40076
|
+
const read = snapshot ?? await deps.readMergeQueue(pr, base.repo);
|
|
40077
|
+
snapshot = void 0;
|
|
40078
|
+
if (read.state === "MERGED") return queueMerged(base, deps);
|
|
40079
|
+
if (read.isInMergeQueue) {
|
|
40080
|
+
base.mergeQueue = {
|
|
40081
|
+
base: base.base,
|
|
40082
|
+
state: "queued",
|
|
40083
|
+
...read.mergeQueueEntry ? { position: read.mergeQueueEntry.position, entryState: read.mergeQueueEntry.state } : {}
|
|
40084
|
+
};
|
|
40085
|
+
deps.queueProgress?.(base);
|
|
40086
|
+
if (options.enqueueOnly) return { ...base, status: "queued" };
|
|
40087
|
+
} else if (read.state === "OPEN" && !read.autoMergeRequest) {
|
|
40088
|
+
const run = await deps.findMergeGroupRun(pr, base.repo, base.base);
|
|
40089
|
+
const result2 = {
|
|
40090
|
+
...base,
|
|
40091
|
+
mergeQueue: { ...base.mergeQueue, state: "ejected", ...run ? { ejectedRun: run } : {} },
|
|
40092
|
+
error: `merge queue ejected PR #${pr} \u2014 ${run ? `merge_group run ${run.id} ${run.conclusion} ${run.url}` : "merge_group run not found"}`
|
|
40093
|
+
};
|
|
40094
|
+
deps.queueProgress?.(result2);
|
|
40095
|
+
return result2;
|
|
40096
|
+
}
|
|
40097
|
+
await sleep2(PR_LAND_POLL_MS);
|
|
40098
|
+
}
|
|
40099
|
+
const result = {
|
|
40100
|
+
...base,
|
|
40101
|
+
mergeQueue: { ...base.mergeQueue, state: "timeout" },
|
|
40102
|
+
error: "merge queue did not reach MERGED within 45 minutes \u2014 rerun pr land to resume polling"
|
|
40103
|
+
};
|
|
40104
|
+
deps.queueProgress?.(result);
|
|
40105
|
+
return result;
|
|
40106
|
+
}
|
|
40028
40107
|
|
|
40029
40108
|
// src/test-policy-core.ts
|
|
40030
40109
|
var import_node_child_process13 = require("node:child_process");
|
|
@@ -41085,18 +41164,19 @@ async function ghMergeAutoEnqueue(prNumber, repo, method, extra) {
|
|
|
41085
41164
|
bodyText: method === "--squash" ? extra?.bodyText : void 0
|
|
41086
41165
|
});
|
|
41087
41166
|
try {
|
|
41088
|
-
return await mergeAutoEnqueueWithBody(prNumber, args, method, io, overrideBody?.path);
|
|
41167
|
+
return await mergeAutoEnqueueWithBody(prNumber, args, method, io, overrideBody?.path, extra?.mergeQueue);
|
|
41089
41168
|
} finally {
|
|
41090
41169
|
overrideBody?.cleanup();
|
|
41091
41170
|
}
|
|
41092
41171
|
}
|
|
41093
|
-
async function mergeAutoEnqueueWithBody(prNumber, args, method, io, bodyFile) {
|
|
41172
|
+
async function mergeAutoEnqueueWithBody(prNumber, args, method, io, bodyFile, mergeQueue = false) {
|
|
41094
41173
|
const headRef = (await io.gh(["pr", "view", prNumber, ...args, "--json", "headRefName", "--jq", ".headRefName"], GC_GH_TIMEOUT_MS).catch(() => "")).trim();
|
|
41095
41174
|
const deleteBranch = !isProtectedBranch(headRef);
|
|
41096
41175
|
const readMergeState = () => readGhPrStateWithRetry(
|
|
41097
41176
|
() => io.gh(["pr", "view", prNumber, ...args, "--json", "state", "--jq", ".state"], GC_GH_TIMEOUT_MS)
|
|
41098
41177
|
);
|
|
41099
41178
|
const confirmEnqueueOutcome = async () => {
|
|
41179
|
+
if (mergeQueue) return { mergeStatus: "auto-merge-enqueued" };
|
|
41100
41180
|
const stateRead = await readMergeState();
|
|
41101
41181
|
if (!stateRead.ok) {
|
|
41102
41182
|
return { mergeStatus: "failed", error: `could not read PR state after merge: ${stateRead.error}` };
|
|
@@ -41872,6 +41952,57 @@ function applyChecklistCheck(body, query, checked) {
|
|
|
41872
41952
|
return { ok: true, edit: setChecklistMarker(body, sel.item, checked), item: sel.item };
|
|
41873
41953
|
}
|
|
41874
41954
|
|
|
41955
|
+
// src/pr-merge-queue.ts
|
|
41956
|
+
init_cli_shared();
|
|
41957
|
+
var readApi = async (args) => {
|
|
41958
|
+
const env = await ghReadEnv();
|
|
41959
|
+
return (await execFileP("gh", ["api", ...args], {
|
|
41960
|
+
timeout: 2e4,
|
|
41961
|
+
...env ? { env } : {}
|
|
41962
|
+
})).stdout;
|
|
41963
|
+
};
|
|
41964
|
+
async function queueGraphql(repo, fields, gh2) {
|
|
41965
|
+
const [owner, name] = repo.split("/");
|
|
41966
|
+
const response = JSON.parse(await gh2(["graphql", "-f", `query=query { repository(owner:${JSON.stringify(owner)},name:${JSON.stringify(name)}) { ${fields} } }`]));
|
|
41967
|
+
if (response.errors?.length) throw new Error(response.errors.map((e) => e.message).join("; "));
|
|
41968
|
+
if (!response.data?.repository) throw new Error("merge queue repository read failed");
|
|
41969
|
+
return response.data.repository;
|
|
41970
|
+
}
|
|
41971
|
+
async function hasPrMergeQueue(repo, base, gh2 = readApi) {
|
|
41972
|
+
const result = await queueGraphql(repo, `mergeQueue(branch:${JSON.stringify(base)}) { id }`, gh2);
|
|
41973
|
+
return result.mergeQueue !== null;
|
|
41974
|
+
}
|
|
41975
|
+
async function readPrMergeQueue(pr, repo, gh2 = readApi) {
|
|
41976
|
+
if (!/^\d+$/.test(pr)) throw new Error("merge queue read requires a PR number");
|
|
41977
|
+
const result = await queueGraphql(
|
|
41978
|
+
repo,
|
|
41979
|
+
`pullRequest(number:${pr}) { state isInMergeQueue mergeQueueEntry { state position } autoMergeRequest { enabledAt } }`,
|
|
41980
|
+
gh2
|
|
41981
|
+
);
|
|
41982
|
+
if (!result.pullRequest) throw new Error(`merge queue PR #${pr} not found`);
|
|
41983
|
+
return result.pullRequest;
|
|
41984
|
+
}
|
|
41985
|
+
async function findPrMergeGroupRun(pr, repo, base, gh2 = readApi) {
|
|
41986
|
+
const pages = JSON.parse(await gh2([`repos/${repo}/actions/runs?event=merge_group&per_page=100`, "--paginate", "--slurp"]));
|
|
41987
|
+
const prefix = `gh-readonly-queue/${base}/pr-${pr}-`;
|
|
41988
|
+
const run = pages.flatMap((page) => page.workflow_runs).filter((run2) => run2.head_branch?.startsWith(prefix)).sort((a, b) => b.created_at.localeCompare(a.created_at) || b.id - a.id)[0];
|
|
41989
|
+
return run ? { id: run.id, url: run.html_url, conclusion: run.conclusion } : void 0;
|
|
41990
|
+
}
|
|
41991
|
+
function prMergeQueueLine(result) {
|
|
41992
|
+
const queue = result.mergeQueue;
|
|
41993
|
+
if (!queue) return void 0;
|
|
41994
|
+
switch (queue.state) {
|
|
41995
|
+
case "queued":
|
|
41996
|
+
return `pr land: PR #${result.pr} queued on ${queue.base}${queue.position === void 0 ? "" : ` (position ${queue.position})`}`;
|
|
41997
|
+
case "merged":
|
|
41998
|
+
return `pr land: PR #${result.pr} merged via merge queue`;
|
|
41999
|
+
case "ejected":
|
|
42000
|
+
return `pr land: PR #${result.pr} ejected from merge queue \u2014 ${queue.ejectedRun ? `merge_group run ${queue.ejectedRun.id} ${queue.ejectedRun.conclusion} ${queue.ejectedRun.url}` : "merge_group run not found"}`;
|
|
42001
|
+
case "timeout":
|
|
42002
|
+
return `pr land: PR #${result.pr} merge queue timeout on ${queue.base}`;
|
|
42003
|
+
}
|
|
42004
|
+
}
|
|
42005
|
+
|
|
41875
42006
|
// src/command-register-collaboration.ts
|
|
41876
42007
|
init_github_client();
|
|
41877
42008
|
init_github_quota();
|
|
@@ -46819,7 +46950,7 @@ ${list}`);
|
|
|
46819
46950
|
}
|
|
46820
46951
|
class PrHeadBehindBaseError extends Error {
|
|
46821
46952
|
}
|
|
46822
|
-
pr.command("land <number>").description("agent merge path (#1440): train probe \u2014 checks-wait \u2014 merge --auto \u2014 poll enqueued \u2014 development PRs only").option("--json", "machine-readable output").option("--repo <owner/repo>", "target repo (defaults to the PR repo)").option("--no-require-train", "skip train-authority preflight (not recommended for autonomous agents)").option("--force", "acknowledge and land past a remaining prunable/severe scratch housekeeping block (advisory kept plans/ never blocks, #3012) or a negated-closing-keyword (#3718) or ambiguous-cross-repo-closing (#4279) refusal").option("--without-review <reason>", "compatibility option; shared merge helpers do not require a review verdict").action(async (number, o) => {
|
|
46953
|
+
pr.command("land <number>").description("agent merge path (#1440): train probe \u2014 checks-wait \u2014 merge --auto \u2014 poll enqueued \u2014 development PRs only").option("--json", "machine-readable output").option("--repo <owner/repo>", "target repo (defaults to the PR repo)").option("--enqueue-only", "return once queue membership is confirmed; without a merge queue, land normally").option("--no-require-train", "skip train-authority preflight (not recommended for autonomous agents)").option("--force", "acknowledge and land past a remaining prunable/severe scratch housekeeping block (advisory kept plans/ never blocks, #3012) or a negated-closing-keyword (#3718) or ambiguous-cross-repo-closing (#4279) refusal").option("--without-review <reason>", "compatibility option; shared merge helpers do not require a review verdict").action(async (number, o) => {
|
|
46823
46954
|
if (/^(?:[^/]+\/[^/]+)?#\d+$/.test(number.trim())) {
|
|
46824
46955
|
try {
|
|
46825
46956
|
const parsed = parseIssueRef(number, o.repo);
|
|
@@ -46854,7 +46985,14 @@ ${list}`);
|
|
|
46854
46985
|
return;
|
|
46855
46986
|
}
|
|
46856
46987
|
if (landClosingGuardVerdict.message) console.warn(landClosingGuardVerdict.message);
|
|
46857
|
-
|
|
46988
|
+
let mergeQueueEnabled = false;
|
|
46989
|
+
const result = await runPrLand(number, { repo: o.repo, requireTrain: o.requireTrain !== false, enqueueOnly: o.enqueueOnly }, {
|
|
46990
|
+
hasMergeQueue: async (repo, base) => mergeQueueEnabled = await hasPrMergeQueue(repo, base),
|
|
46991
|
+
readMergeQueue: readPrMergeQueue,
|
|
46992
|
+
findMergeGroupRun: findPrMergeGroupRun,
|
|
46993
|
+
queueProgress: (receipt) => {
|
|
46994
|
+
if (!o.json) printLine(prMergeQueueLine(receipt));
|
|
46995
|
+
},
|
|
46858
46996
|
resolveRepo: async (prNumber, repoOpt) => {
|
|
46859
46997
|
const knownRepo = repoOpt ?? await resolveRepo(o.repo).catch(() => void 0) ?? o.repo;
|
|
46860
46998
|
let repoFromGh = "";
|
|
@@ -46944,7 +47082,8 @@ ${list}`);
|
|
|
46944
47082
|
},
|
|
46945
47083
|
mergeAuto: (prNumber, repo) => ghMergeAutoEnqueue(prNumber, repo, "--squash", {
|
|
46946
47084
|
allowedClosing: landClosingGuardInput?.closing,
|
|
46947
|
-
bodyText: landSquashBody
|
|
47085
|
+
bodyText: landSquashBody,
|
|
47086
|
+
mergeQueue: mergeQueueEnabled
|
|
46948
47087
|
}),
|
|
46949
47088
|
updateBranch: (prNumber, repo) => prLandUpdateBranch(prNumber, repo, Boolean(o.repo)),
|
|
46950
47089
|
pollMerged: async (prNumber, repo, deadlineMs) => {
|
|
@@ -46968,7 +47107,7 @@ ${list}`);
|
|
|
46968
47107
|
return false;
|
|
46969
47108
|
}
|
|
46970
47109
|
});
|
|
46971
|
-
if (result.status !== "failed") {
|
|
47110
|
+
if (result.status !== "failed" && result.status !== "queued") {
|
|
46972
47111
|
const boardAdvance = await advanceClosedIssuesToDone2(number, result.repo);
|
|
46973
47112
|
const crossRepoFilingIssue = result.repo ? await reconcileCrossRepoFilingIssue(defaultGitHubClient(), result.repo, Number(number)) : { status: "failed", error: "could not resolve the PR repo for cross-repo filing-issue reconciliation" };
|
|
46974
47113
|
const recovery = result.repo ? buildPostMergeReconRecovery({
|
|
@@ -47620,7 +47759,13 @@ function trainApplyDeps() {
|
|
|
47620
47759
|
// Slack release announcement (#883/#6521/#6523): the org alerts channel for the Hub, the project's own
|
|
47621
47760
|
// registry releaseChannel META for a product repo — best-effort inside announceRelease itself.
|
|
47622
47761
|
announce: (args) => announceRelease({
|
|
47623
|
-
|
|
47762
|
+
// #8236: the announcement reads an already-PUBLISHED Release, so its `release view` rides the App
|
|
47763
|
+
// read pool like the train's other reads (#8030), never the owner's personal REST quota. Scoped
|
|
47764
|
+
// here, not in isAppRoutableGhReadArgs: other train paths may view a draft the App cannot see.
|
|
47765
|
+
run: async (file, cmdArgs) => {
|
|
47766
|
+
const env = file === "gh" && (cmdArgs[0] === "release" && cmdArgs[1] === "view" || isAppRoutableGhReadArgs(cmdArgs)) ? await ghReadEnv() : void 0;
|
|
47767
|
+
return (await execFileP(file, cmdArgs, { timeout: GH_TRAIN_TIMEOUT_MS, ...env ? { env } : {} })).stdout;
|
|
47768
|
+
},
|
|
47624
47769
|
postAnnouncement: async (payload) => {
|
|
47625
47770
|
const res = await releaseAnnouncement(payload, registryClientDeps(await loadConfig()));
|
|
47626
47771
|
const body = res.body;
|
|
@@ -50919,7 +51064,8 @@ var surfaces_default = {
|
|
|
50919
51064
|
],
|
|
50920
51065
|
outputs: [
|
|
50921
51066
|
"cli/dist/index.cjs",
|
|
50922
|
-
"cli/dist/main.cjs"
|
|
51067
|
+
"cli/dist/main.cjs",
|
|
51068
|
+
"cli/dist/runbook-sweep.cjs"
|
|
50923
51069
|
]
|
|
50924
51070
|
}
|
|
50925
51071
|
],
|
package/dist/runbook-sweep.cjs
CHANGED
package/package.json
CHANGED