@mutmutco/cli 4.6.32 → 4.6.34
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 +167 -32
- package/package.json +1 -1
package/dist/main.cjs
CHANGED
|
@@ -27062,6 +27062,71 @@ function contentPutInputArgs(repo, path2, inputFile) {
|
|
|
27062
27062
|
inputFile
|
|
27063
27063
|
];
|
|
27064
27064
|
}
|
|
27065
|
+
var BANK_REQUEST_REPO = "mutmutco/Jerv-Hub";
|
|
27066
|
+
var BANK_REQUEST_LABEL = "bank-request";
|
|
27067
|
+
var BANK_REQUEST_SOURCE = "MMI-Hub#9958";
|
|
27068
|
+
function bankRequestTitle(repoName2) {
|
|
27069
|
+
return `bank-request: coding-agent::${repoName2}`;
|
|
27070
|
+
}
|
|
27071
|
+
function bankRequestBody(fullName) {
|
|
27072
|
+
return `Create the coding-agent memory bank for \`${fullName}\` (asked by \`mmi-cli devops bootstrap apply\`; see ${BANK_REQUEST_SOURCE}).`;
|
|
27073
|
+
}
|
|
27074
|
+
function planBankRequest(fullName, existing) {
|
|
27075
|
+
const parsed = parseOwnerRepo(fullName);
|
|
27076
|
+
const base = { title: bankRequestTitle(parsed.name), label: BANK_REQUEST_LABEL, body: bankRequestBody(parsed.fullName) };
|
|
27077
|
+
if (existing == null) return { ...base, action: "skip", reason: `could not read ${BANK_REQUEST_REPO} issues` };
|
|
27078
|
+
const found = existing.find((issue) => issue?.title === base.title);
|
|
27079
|
+
if (found) {
|
|
27080
|
+
return {
|
|
27081
|
+
...base,
|
|
27082
|
+
action: "exists",
|
|
27083
|
+
number: found.number,
|
|
27084
|
+
state: found.state ?? "open",
|
|
27085
|
+
url: found.url ?? `https://github.com/${BANK_REQUEST_REPO}/issues/${found.number}`
|
|
27086
|
+
};
|
|
27087
|
+
}
|
|
27088
|
+
return { ...base, action: "create" };
|
|
27089
|
+
}
|
|
27090
|
+
var oneLine = (e) => String(e?.message ?? e).split("\n")[0].trim();
|
|
27091
|
+
function bankRequestManualStep(request, reason) {
|
|
27092
|
+
return `file it by hand at https://github.com/${BANK_REQUEST_REPO}/issues/new \u2014 title "${request.title}", label ${request.label}, body: ${request.body} (${reason})`;
|
|
27093
|
+
}
|
|
27094
|
+
function renderBankRequestPlan(result) {
|
|
27095
|
+
return [
|
|
27096
|
+
"bootstrap apply \u2014 coding-agent memory bank request (dry-run; no issue filed):",
|
|
27097
|
+
` PLAN file issue "${result.title}" (label ${result.label}) in ${BANK_REQUEST_REPO}`,
|
|
27098
|
+
` body: ${result.body}`
|
|
27099
|
+
].join("\n");
|
|
27100
|
+
}
|
|
27101
|
+
function renderBankRequestLine(result) {
|
|
27102
|
+
if (result.status === "opened") {
|
|
27103
|
+
return `memory bank request: ${BANK_REQUEST_REPO}#${result.number} opened \u2014 "${result.title}" (label ${result.label})${result.url ? ` ${result.url}` : ""}`;
|
|
27104
|
+
}
|
|
27105
|
+
if (result.status === "exists") {
|
|
27106
|
+
return `memory bank request: already requested \u2014 ${BANK_REQUEST_REPO}#${result.number} (${result.state})${result.url ? ` ${result.url}` : ""}`;
|
|
27107
|
+
}
|
|
27108
|
+
return `memory bank request: SKIPPED (${result.reason ?? "not attempted"}) \u2014 ${bankRequestManualStep(result, result.reason ?? "not attempted")}`;
|
|
27109
|
+
}
|
|
27110
|
+
async function runBankRequest(fullName, options, deps) {
|
|
27111
|
+
const parsed = parseOwnerRepo(fullName);
|
|
27112
|
+
const request = { title: bankRequestTitle(parsed.name), label: BANK_REQUEST_LABEL, body: bankRequestBody(parsed.fullName) };
|
|
27113
|
+
if (options.dryRun) return { ...request, status: "planned" };
|
|
27114
|
+
let existing;
|
|
27115
|
+
try {
|
|
27116
|
+
existing = await deps.listIssues();
|
|
27117
|
+
} catch (e) {
|
|
27118
|
+
return { ...request, status: "skipped", reason: `could not read ${BANK_REQUEST_REPO} issues: ${oneLine(e)}` };
|
|
27119
|
+
}
|
|
27120
|
+
const plan = planBankRequest(fullName, existing);
|
|
27121
|
+
if (plan.action === "exists") return { ...request, status: "exists", number: plan.number, state: plan.state, url: plan.url };
|
|
27122
|
+
if (plan.action === "skip") return { ...request, status: "skipped", reason: plan.reason };
|
|
27123
|
+
try {
|
|
27124
|
+
const created = await deps.createIssue(request);
|
|
27125
|
+
return { ...request, status: "opened", number: created.number, url: created.url };
|
|
27126
|
+
} catch (e) {
|
|
27127
|
+
return { ...request, status: "skipped", reason: `App issue write failed: ${oneLine(e)}` };
|
|
27128
|
+
}
|
|
27129
|
+
}
|
|
27065
27130
|
|
|
27066
27131
|
// src/train-apply-contracts.ts
|
|
27067
27132
|
var import_node_fs21 = require("node:fs");
|
|
@@ -28301,10 +28366,10 @@ var rollout_plan_default = {
|
|
|
28301
28366
|
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)."
|
|
28302
28367
|
},
|
|
28303
28368
|
baseline: {
|
|
28304
|
-
version: "4.6.
|
|
28305
|
-
tag: "v4.6.
|
|
28306
|
-
commit: "
|
|
28307
|
-
npm: "@mutmutco/cli@4.6.
|
|
28369
|
+
version: "4.6.34",
|
|
28370
|
+
tag: "v4.6.34",
|
|
28371
|
+
commit: "a094b40adf8d",
|
|
28372
|
+
npm: "@mutmutco/cli@4.6.34"
|
|
28308
28373
|
},
|
|
28309
28374
|
exitCriterion: "fleet-n-of-n",
|
|
28310
28375
|
hubOnlyShortcut: "forbidden",
|
|
@@ -28321,14 +28386,14 @@ var rollout_plan_default = {
|
|
|
28321
28386
|
repo: "mutmutco/mmi-hub",
|
|
28322
28387
|
role: "canary",
|
|
28323
28388
|
schedule: "train",
|
|
28324
|
-
v3Target: "v4.6.
|
|
28389
|
+
v3Target: "v4.6.34"
|
|
28325
28390
|
}
|
|
28326
28391
|
],
|
|
28327
28392
|
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.",
|
|
28328
28393
|
rollback: {
|
|
28329
28394
|
independent: true,
|
|
28330
|
-
mechanism: "npm dist-tag latest -> 4.6.
|
|
28331
|
-
v3Target: "v4.6.
|
|
28395
|
+
mechanism: "npm dist-tag latest -> 4.6.34 and redeploy the Hub Lambda from tag v4.6.34 (a094b40adf8d); installed clients repair via `mmi-cli doctor`. No other cohort is touched.",
|
|
28396
|
+
v3Target: "v4.6.34 (@mutmutco/cli@4.6.34, tag commit a094b40adf8d \u2014 last known-good release carrying the repo-index v4-only contract)"
|
|
28332
28397
|
}
|
|
28333
28398
|
},
|
|
28334
28399
|
{
|
|
@@ -51508,6 +51573,7 @@ function registerBootstrapCommands(program3) {
|
|
|
51508
51573
|
}
|
|
51509
51574
|
const actions = [];
|
|
51510
51575
|
const applied = [];
|
|
51576
|
+
let bankRequest = null;
|
|
51511
51577
|
let applyDeployModel;
|
|
51512
51578
|
let applyProjectType;
|
|
51513
51579
|
try {
|
|
@@ -51986,6 +52052,48 @@ ${onlyManagedBlock ? `Only the marker-bounded Hub-managed block inside repo-owne
|
|
|
51986
52052
|
applied.push(`ddb register ${registerPayload.slug} (failed: ${why})`);
|
|
51987
52053
|
}
|
|
51988
52054
|
}
|
|
52055
|
+
if (!onlyTarget) {
|
|
52056
|
+
bankRequest = await runBankRequest(repo, { dryRun: !o.execute }, {
|
|
52057
|
+
listIssues: async () => {
|
|
52058
|
+
const listed = await gh2([
|
|
52059
|
+
"issue",
|
|
52060
|
+
"list",
|
|
52061
|
+
"--repo",
|
|
52062
|
+
BANK_REQUEST_REPO,
|
|
52063
|
+
"--state",
|
|
52064
|
+
"all",
|
|
52065
|
+
"--search",
|
|
52066
|
+
`in:title "${bankRequestTitle(parsedRepo.name)}"`,
|
|
52067
|
+
"--json",
|
|
52068
|
+
"number,title,state,url",
|
|
52069
|
+
"--limit",
|
|
52070
|
+
"50"
|
|
52071
|
+
]);
|
|
52072
|
+
const rows = JSON.parse(listed.stdout || "[]");
|
|
52073
|
+
if (!Array.isArray(rows)) throw new Error("issue list is not an array");
|
|
52074
|
+
return rows;
|
|
52075
|
+
},
|
|
52076
|
+
createIssue: async (request) => {
|
|
52077
|
+
const out = await gh2([
|
|
52078
|
+
"issue",
|
|
52079
|
+
"create",
|
|
52080
|
+
"--repo",
|
|
52081
|
+
BANK_REQUEST_REPO,
|
|
52082
|
+
"--title",
|
|
52083
|
+
request.title,
|
|
52084
|
+
"--body",
|
|
52085
|
+
request.body,
|
|
52086
|
+
"--label",
|
|
52087
|
+
request.label
|
|
52088
|
+
]);
|
|
52089
|
+
const url = out.stdout.trim().split("\n").pop()?.trim() ?? "";
|
|
52090
|
+
const number = Number(/(\d+)$/.exec(url)?.[1]);
|
|
52091
|
+
if (!url || !Number.isFinite(number)) throw new Error(`issue create returned no issue URL: ${out.stdout.trim().slice(0, 200)}`);
|
|
52092
|
+
return { number, url };
|
|
52093
|
+
}
|
|
52094
|
+
});
|
|
52095
|
+
if (o.execute) applied.push(renderBankRequestLine(bankRequest));
|
|
52096
|
+
}
|
|
51989
52097
|
if (o.execute && !onlyTarget) {
|
|
51990
52098
|
const github = await readBootstrapGitHubFacts(repo, effectiveTrack, controlClient);
|
|
51991
52099
|
controlDeployFacts = await fetchDeployFactsBySlug(slug, registryClientDeps(await loadConfig()));
|
|
@@ -52081,13 +52189,15 @@ ${onlyManagedBlock ? `Only the marker-bounded Hub-managed block inside repo-owne
|
|
|
52081
52189
|
return failGraceful(`bootstrap apply: cannot plan labels/environments; no writes made: ${e.message}`);
|
|
52082
52190
|
}
|
|
52083
52191
|
}
|
|
52084
|
-
if (o.json) console.log(JSON.stringify({ repo, class: o.class, sourceSha: seedSource.sha, only: onlyTarget || null, execute: o.execute, seedDelivery: seedPlan.mode, seedBranch: seedPlan.branch, seedBaseSha: scopedPlan?.baseSha, seedPrUrl, actions, controlPlane: controlRows, labels: ancillaryPlan, environments: environmentPlan, applied, ddbWrites }, null, 2));
|
|
52192
|
+
if (o.json) console.log(JSON.stringify({ repo, class: o.class, sourceSha: seedSource.sha, only: onlyTarget || null, execute: o.execute, seedDelivery: seedPlan.mode, seedBranch: seedPlan.branch, seedBaseSha: scopedPlan?.baseSha, seedPrUrl, actions, controlPlane: controlRows, labels: ancillaryPlan, environments: environmentPlan, bankRequest, applied, ddbWrites }, null, 2));
|
|
52085
52193
|
else {
|
|
52086
52194
|
console.log(renderSeedPlan(actions));
|
|
52087
52195
|
if (controlRows.length) console.log(`
|
|
52088
52196
|
${renderBootstrapControlPlan(controlRows)}`);
|
|
52089
52197
|
if (ancillaryPlan && environmentPlan) console.log(`
|
|
52090
52198
|
${renderBootstrapAncillaryPlan(ancillaryPlan, environmentPlan, repoEnvironmentSpecs(repo, effectiveTrack, suiteSlug).filter((spec) => spec.exception).map((spec) => ({ name: spec.name, detail: spec.exception })))}`);
|
|
52199
|
+
if (bankRequest?.status === "planned") console.log(`
|
|
52200
|
+
${renderBankRequestPlan(bankRequest)}`);
|
|
52091
52201
|
if (o.execute) console.log(`
|
|
52092
52202
|
LIVE apply to ${repo}:
|
|
52093
52203
|
${applied.join("\n ")}`);
|
|
@@ -56455,6 +56565,7 @@ async function verifyCustodyBootstrap(value, api, controller, requiredContexts,
|
|
|
56455
56565
|
// src/release-custody.ts
|
|
56456
56566
|
var RELEASE_CUSTODY_BRANCH = "mmi-release-state";
|
|
56457
56567
|
var RELEASE_CUSTODY_PATH = "release-custody.json";
|
|
56568
|
+
var HUB_RELEASE_CUSTODY_JOB = "release";
|
|
56458
56569
|
var ReleaseCustodyError = class extends Error {
|
|
56459
56570
|
constructor(message2) {
|
|
56460
56571
|
super("Release custody: " + message2);
|
|
@@ -56528,6 +56639,14 @@ function githubCustodyStore(repo, baseSha, api = defaultGitHubClient()) {
|
|
|
56528
56639
|
`repos/${repo}/actions/runs/${controller.runId}/attempts/${controller.runAttempt}`
|
|
56529
56640
|
);
|
|
56530
56641
|
return run.id === controller.runId && run.run_attempt === controller.runAttempt && run.path === HUB_RELEASE_WORKFLOW && run.status === "completed";
|
|
56642
|
+
},
|
|
56643
|
+
async jobCompleted(controller) {
|
|
56644
|
+
const jobs = await api.rest(
|
|
56645
|
+
"GET",
|
|
56646
|
+
`repos/${repo}/actions/runs/${controller.runId}/attempts/${controller.runAttempt}/jobs?per_page=100`
|
|
56647
|
+
);
|
|
56648
|
+
const job = (jobs?.jobs ?? []).find((row) => row.name === (controller.job ?? HUB_RELEASE_CUSTODY_JOB));
|
|
56649
|
+
return job?.status === "completed" && job.conclusion === "success";
|
|
56531
56650
|
}
|
|
56532
56651
|
};
|
|
56533
56652
|
}
|
|
@@ -56546,8 +56665,12 @@ var ReleaseCustodySession = class _ReleaseCustodySession {
|
|
|
56546
56665
|
poison;
|
|
56547
56666
|
static async acquire(store, controller, repo, initialize, prepare) {
|
|
56548
56667
|
const found = await store.read();
|
|
56549
|
-
|
|
56550
|
-
|
|
56668
|
+
const prior = found.state?.controller;
|
|
56669
|
+
if (prior) {
|
|
56670
|
+
const handoff = prior.runId === controller.runId && prior.runAttempt === controller.runAttempt;
|
|
56671
|
+
if (!(handoff ? await store.jobCompleted(prior) : await store.terminal(prior))) {
|
|
56672
|
+
throw new ReleaseCustodyError(handoff ? `previous controller ${prior.job ?? HUB_RELEASE_CUSTODY_JOB} job of run ${prior.runId} attempt ${prior.runAttempt} is not proven completed` : `previous controller run ${prior.runId} attempt ${prior.runAttempt} is not proven terminal`);
|
|
56673
|
+
}
|
|
56551
56674
|
}
|
|
56552
56675
|
let state = {
|
|
56553
56676
|
...found.state ?? { schema: "mmi-release-custody/v1", repo, precutId: (0, import_node_crypto21.randomUUID)(), effects: {}, ...await initialize() },
|
|
@@ -56845,7 +56968,7 @@ function withHubReleaseCustody(deps) {
|
|
|
56845
56968
|
if (!authority.ok || !authority.train || authority.authenticatedDelegation !== true) {
|
|
56846
56969
|
throw new ReleaseCustodyError("repository custody requires the server-verified owner-triggered train session");
|
|
56847
56970
|
}
|
|
56848
|
-
const controller = { ...runIdentity, token: (0, import_node_crypto21.randomUUID)() };
|
|
56971
|
+
const controller = { ...runIdentity, token: (0, import_node_crypto21.randomUUID)(), ...process.env.GITHUB_JOB ? { job: process.env.GITHUB_JOB } : {} };
|
|
56849
56972
|
const raw = localRaw(path2);
|
|
56850
56973
|
const requiredContexts = () => discoverRequiredCheckContexts(
|
|
56851
56974
|
deps,
|
|
@@ -61005,9 +61128,10 @@ async function preparePrCreate(input, deps = createPreparationDeps(input)) {
|
|
|
61005
61128
|
const reads = await Promise.allSettled([
|
|
61006
61129
|
deps.claims(refs.candidate),
|
|
61007
61130
|
refs.candidate ? deps.docs(refs.candidate) : Promise.resolve(void 0),
|
|
61008
|
-
observePolicy(deps, refs.candidate)
|
|
61131
|
+
observePolicy(deps, refs.candidate),
|
|
61132
|
+
refs.candidate ? deps.queueWaiver?.(refs.candidate) : Promise.resolve(void 0)
|
|
61009
61133
|
]);
|
|
61010
|
-
const [claims, docs, policy] = reads;
|
|
61134
|
+
const [claims, docs, policy, waiver] = reads;
|
|
61011
61135
|
if (claims.status === "fulfilled") {
|
|
61012
61136
|
observations.push(...claims.value.findings.length ? claims.value.findings.map((detail) => ({ check: "claims", state: "failed", detail })) : [{ check: "claims", state: "passed", detail: "issue and claim evidence read" }]);
|
|
61013
61137
|
} else observations.push({ check: "claims", state: "unavailable", detail: `issue/claim evidence unavailable (${rejectionReason(claims.reason)}); retry the read` });
|
|
@@ -61015,6 +61139,8 @@ async function preparePrCreate(input, deps = createPreparationDeps(input)) {
|
|
|
61015
61139
|
else if (docs.value) observations.push({ check: "docs", state: docs.value.state, detail: [docs.value.detail, docs.value.fix].filter(Boolean).join(" \u2014 ") });
|
|
61016
61140
|
if (policy.status === "rejected") observations.push({ check: "policy", state: "unavailable", detail: `committed test-policy observation unavailable (${rejectionReason(policy.reason)}); check policy validity and fetch full candidate history before retrying` });
|
|
61017
61141
|
else if (policy.value) observations.push(policy.value);
|
|
61142
|
+
if (waiver.status === "rejected") observations.push({ check: "queue", state: "skipped", detail: `the queue squash waiver placement was not checked (${rejectionReason(waiver.reason)}); this is non-blocking` });
|
|
61143
|
+
else if (waiver.value) observations.push(waiver.value);
|
|
61018
61144
|
const findings = observations.filter((item) => item.state === "failed" || item.state === "unavailable");
|
|
61019
61145
|
let attempted = false;
|
|
61020
61146
|
return {
|
|
@@ -61115,6 +61241,34 @@ function createPreparationDeps(input, io = {}) {
|
|
|
61115
61241
|
return {
|
|
61116
61242
|
candidate: readCandidate,
|
|
61117
61243
|
publish: (proof) => publishPreparedPrHead(proof, exec3),
|
|
61244
|
+
// #9831/#9968: publication happens only in commit(), after this read-only preparation, so the queue's
|
|
61245
|
+
// buried-waiver refusal is decided here — with the queue's own reader and setting reads — before an
|
|
61246
|
+
// absent remote head is pushed and a PR opened. A range or setting it cannot read is a skip (#9968).
|
|
61247
|
+
queueWaiver: async (candidate) => {
|
|
61248
|
+
const result = (state, detail) => ({ check: "queue", state, detail });
|
|
61249
|
+
if (!candidate.root) return void 0;
|
|
61250
|
+
const range = await exec3("git", ["-C", candidate.root, "log", "--reverse", "--format=%B%x00", `${candidate.baseSha}..${candidate.headSha}`], { timeout: GIT_TIMEOUT_MS }).then((read) => ({ log: read.stdout }), (error) => ({ reason: rejectionReason(error) }));
|
|
61251
|
+
if (!("log" in range)) return result("skipped", `candidate commits ${candidate.baseSha}..${candidate.headSha} could not be read (${range.reason}), so the queue squash waiver placement was not checked; this is non-blocking`);
|
|
61252
|
+
const messages = range.log.split("\0").filter((message2) => message2.trim()).map((message2) => {
|
|
61253
|
+
const [headline, ...body] = message2.trim().split("\n");
|
|
61254
|
+
return { headline, body: body.join("\n") };
|
|
61255
|
+
});
|
|
61256
|
+
const refusal = checkQueueSquashOverride("Candidate PR", "0", messages, candidate.root);
|
|
61257
|
+
if (!refusal) return void 0;
|
|
61258
|
+
const [owner, name] = candidate.repo.split("/");
|
|
61259
|
+
const setting = await (async () => {
|
|
61260
|
+
const metadata = await client.graphql(
|
|
61261
|
+
"query($owner:String!,$name:String!,$base:String!) { repository(owner:$owner,name:$name) { squashMergeCommitMessage mergeQueue(branch:$base) { configuration { mergeMethod } } } }",
|
|
61262
|
+
{ owner, name, base: candidate.base }
|
|
61263
|
+
);
|
|
61264
|
+
const rules = await client.restPaginate(`repos/${candidate.repo}/rules/branches/${encodeURIComponent(candidate.base)}?per_page=100`);
|
|
61265
|
+
const methods = [...new Set(rules.filter((rule) => rule.type === "merge_queue").map((rule) => rule.parameters?.merge_method))];
|
|
61266
|
+
const method = methods.length === 1 ? methods[0] : !methods.length ? metadata.repository.mergeQueue?.configuration?.mergeMethod : void 0;
|
|
61267
|
+
return method === "SQUASH" && metadata.repository.squashMergeCommitMessage === "COMMIT_MESSAGES";
|
|
61268
|
+
})().then((squash) => squash, (error) => rejectionReason(error));
|
|
61269
|
+
if (typeof setting === "string") return result("skipped", `the repository's queue squash-message setting could not be read (${setting}), so the queue squash waiver placement was not checked; this is non-blocking`);
|
|
61270
|
+
return setting ? result("failed", `${refusal.error} \u2014 ${refusal.preparation.nextAction}`) : void 0;
|
|
61271
|
+
},
|
|
61118
61272
|
// #9946: the retry needs the exact candidate objects. Fetch each ref on its own so a fork-only head
|
|
61119
61273
|
// that origin cannot resolve never costs the base fetch too, and never surface a fetch failure as the
|
|
61120
61274
|
// reason the policy read stayed unreadable.
|
|
@@ -61135,25 +61289,6 @@ function createPreparationDeps(input, io = {}) {
|
|
|
61135
61289
|
if (!await docs.refResolves(candidate.root, candidate.headSha) || !await docs.refResolves(candidate.root, candidate.baseSha)) {
|
|
61136
61290
|
return result("skipped", "exact remote candidate objects are not available locally; committed test policy was not checked");
|
|
61137
61291
|
}
|
|
61138
|
-
const log = (await exec3("git", ["-C", candidate.root, "log", "--reverse", "--format=%B%x00", `${candidate.baseSha}..${candidate.headSha}`], { timeout: GIT_TIMEOUT_MS })).stdout;
|
|
61139
|
-
const messages = log.split("\0").filter((message2) => message2.trim()).map((message2) => {
|
|
61140
|
-
const [headline, ...body] = message2.trim().split("\n");
|
|
61141
|
-
return { headline, body: body.join("\n") };
|
|
61142
|
-
});
|
|
61143
|
-
const refusal = checkQueueSquashOverride("Candidate PR", "0", messages, candidate.root);
|
|
61144
|
-
if (refusal) {
|
|
61145
|
-
const [owner, name] = candidate.repo.split("/");
|
|
61146
|
-
const metadata = await client.graphql(
|
|
61147
|
-
"query($owner:String!,$name:String!,$base:String!) { repository(owner:$owner,name:$name) { squashMergeCommitMessage mergeQueue(branch:$base) { configuration { mergeMethod } } } }",
|
|
61148
|
-
{ owner, name, base: candidate.base }
|
|
61149
|
-
);
|
|
61150
|
-
const rules = await client.restPaginate(`repos/${candidate.repo}/rules/branches/${encodeURIComponent(candidate.base)}?per_page=100`);
|
|
61151
|
-
const methods = [...new Set(rules.filter((rule) => rule.type === "merge_queue").map((rule) => rule.parameters?.merge_method))];
|
|
61152
|
-
const method = methods.length === 1 ? methods[0] : !methods.length ? metadata.repository.mergeQueue?.configuration?.mergeMethod : void 0;
|
|
61153
|
-
if (method === "SQUASH" && metadata.repository.squashMergeCommitMessage === "COMMIT_MESSAGES") {
|
|
61154
|
-
return result("failed", `${refusal.error} \u2014 ${refusal.preparation.nextAction}`);
|
|
61155
|
-
}
|
|
61156
|
-
}
|
|
61157
61292
|
let policy;
|
|
61158
61293
|
try {
|
|
61159
61294
|
policy = runTestPolicy(candidate.root, { candidate: { head: candidate.headSha, base: candidate.baseSha } });
|
package/package.json
CHANGED