mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-13 18:32:12 +03:00
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host. Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean. Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
91 lines
3.1 KiB
JavaScript
91 lines
3.1 KiB
JavaScript
#!/usr/bin/env node
|
|
// Refuse a pull request that targets its own head branch.
|
|
//
|
|
// WHY: PR #8912 has head == base == release/v3.8.50 — a PR from a branch to itself. It has no
|
|
// diff, it can never merge, and GitHub keeps it in the queue forever with a full check board
|
|
// attached. It survived because nothing looks wrong: the checks are green (there is nothing to
|
|
// check), the mergeability just reads "unknown", and it quietly costs review attention and CI
|
|
// minutes on every push to that branch.
|
|
//
|
|
// The check is one field comparison, which is the point — it is cheaper than the confusion.
|
|
//
|
|
// Usage (in CI, inside a pull_request job):
|
|
// HEAD_REF="$GITHUB_HEAD_REF" BASE_REF="$GITHUB_BASE_REF" \
|
|
// HEAD_SHA=... BASE_SHA=... node scripts/check/check-pr-self-target.mjs
|
|
// Exit: 0 when the PR is well-formed or there is no PR context, 1 when it targets itself.
|
|
|
|
import fs from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
/**
|
|
* Classify a PR's head/base pair.
|
|
*
|
|
* Both signals are checked because either alone can be absent: `*_REF` is empty for
|
|
* cross-fork events in some contexts, and the SHAs coincide on a freshly branched PR that is
|
|
* NOT self-targeting (branch cut, nothing pushed yet) — so an equal-SHA alone must not fail.
|
|
* Only an equal REF is conclusive; equal SHAs are reported as a warning.
|
|
*/
|
|
export function classifyPrTarget({ headRef, baseRef, headSha, baseSha } = {}) {
|
|
const hr = String(headRef ?? "").trim();
|
|
const br = String(baseRef ?? "").trim();
|
|
const hs = String(headSha ?? "").trim();
|
|
const bs = String(baseSha ?? "").trim();
|
|
|
|
if (!hr && !br) return { verdict: "no-pr-context" };
|
|
|
|
if (hr && br && hr === br) {
|
|
return {
|
|
verdict: "self-targeting",
|
|
reason: `head and base are the same branch (${hr}) — this PR has no diff and can never merge`,
|
|
};
|
|
}
|
|
|
|
if (hs && bs && hs === bs) {
|
|
// Legitimate right after cutting a branch: the tip has not moved yet. Not a failure.
|
|
return {
|
|
verdict: "empty-diff",
|
|
reason: `head and base point at the same commit (${hs.slice(0, 10)}) — nothing to review yet`,
|
|
};
|
|
}
|
|
|
|
return { verdict: "ok" };
|
|
}
|
|
|
|
function main() {
|
|
const r = classifyPrTarget({
|
|
headRef: process.env.HEAD_REF,
|
|
baseRef: process.env.BASE_REF,
|
|
headSha: process.env.HEAD_SHA,
|
|
baseSha: process.env.BASE_SHA,
|
|
});
|
|
|
|
if (r.verdict === "self-targeting") {
|
|
process.stderr.write(
|
|
`::error::PR targets its own branch — ${r.reason}.\n` +
|
|
`Close it, or repoint the base at the branch you actually want to merge into ` +
|
|
`(gh pr edit <N> --base <branch>, then VERIFY with gh pr view <N> --json baseRefName — ` +
|
|
`the edit fails silently).\n`
|
|
);
|
|
return 1;
|
|
}
|
|
|
|
if (r.verdict === "empty-diff") {
|
|
process.stdout.write(`::warning::${r.reason}.\n`);
|
|
return 0;
|
|
}
|
|
|
|
process.stdout.write(
|
|
r.verdict === "no-pr-context"
|
|
? "[pr-self-target] no PR context — skipping.\n"
|
|
: "[pr-self-target] OK — head and base differ.\n"
|
|
);
|
|
return 0;
|
|
}
|
|
|
|
if (
|
|
process.argv[1] &&
|
|
fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url))
|
|
) {
|
|
process.exit(main());
|
|
}
|